SDL_syscond.cpp File Reference
`#include "../../SDL_internal.h"`
`#include "SDL_thread.h"`
`#include <chrono>`
`#include <condition_variable>`
`#include <ratio>`
`#include <system_error>`
`#include "SDL_sysmutex_c.h"`
Include dependency graph for SDL_syscond.cpp:

Go to the source code of this file.

## Data Structures

struct | SDL_cond

## Functions

SDL_cond * | SDL_CreateCond (void)
void | SDL_DestroyCond (SDL_cond *cond)
int | SDL_CondSignal (SDL_cond *cond)
int | SDL_CondBroadcast (SDL_cond *cond)
int | SDL_CondWaitTimeout (SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
int | SDL_CondWait (SDL_cond *cond, SDL_mutex *mutex)

## Function Documentation

## SDL_CondBroadcast()

int SDL_CondBroadcast | ( | SDL_cond * | cond | ) |

Restart all threads that are waiting on the condition variable.

Returns
  0 or -1 on error.

Definition at line 84 of file SDL_syscond.cpp.

References SDL_cond::cpp_cond, and SDL_SetError.

{
if (!cond) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
cond->cpp_cond.notify_all();
return 0;
}
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_cond::cpp_cond
std::condition_variable_any cpp_cond
Definition: SDL_syscond.cpp:36

## SDL_CondSignal()

int SDL_CondSignal | ( | SDL_cond * | cond | ) |

Restart one of the threads that are waiting on the condition variable.

Returns
  0 or -1 on error.

Definition at line 70 of file SDL_syscond.cpp.

References SDL_cond::cpp_cond, and SDL_SetError.

{
if (!cond) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
cond->cpp_cond.notify_one();
return 0;
}
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_cond::cpp_cond
std::condition_variable_any cpp_cond
Definition: SDL_syscond.cpp:36

## SDL_CondWait()

int SDL_CondWait | ( | SDL_cond * | cond,
|  | SDL_mutex * | mutex
| ) |  |

Wait on the condition variable, unlocking the provided mutex.

Warning
  The mutex must be locked before entering this function!

The mutex is re-locked once the condition variable is signaled.

Returns
  0 when it is signaled, or -1 on error.

Definition at line 159 of file SDL_syscond.cpp.

References SDL_CondWaitTimeout(), and SDL_MUTEX_MAXWAIT.

{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}
SDL_CondWaitTimeout
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
Definition: SDL_syscond.cpp:118
SDL_MUTEX_MAXWAIT
#define SDL_MUTEX_MAXWAIT
Definition: SDL_mutex.h:49

## SDL_CondWaitTimeout()

int SDL_CondWaitTimeout | ( | SDL_cond * | cond,
|  | SDL_mutex * | mutex,
|  | Uint32 | ms
| ) |  |

Waits for at most `ms` milliseconds, and returns 0 if the condition variable is signaled, SDL_MUTEX_TIMEDOUT if the condition is not signaled in the allotted time, and -1 on error.

Warning
  On some platforms this function is implemented by looping with a delay of 1 ms, and so should be avoided if possible.

Definition at line 118 of file SDL_syscond.cpp.

References SDL_cond::cpp_cond, SDL_mutex::cpp_mutex, SDL_MUTEX_MAXWAIT, SDL_MUTEX_TIMEDOUT, and SDL_SetError.

Referenced by SDL_CondWait().

{
if (!cond) {
SDL_SetError("Passed a NULL condition variable");
return -1;
}
if (!mutex) {
SDL_SetError("Passed a NULL mutex variable");
return -1;
}
try {
std::unique_lock<std::recursive_mutex> cpp_lock(mutex->cpp_mutex, std::adopt_lock_t());
if (ms == SDL_MUTEX_MAXWAIT) {
cond->cpp_cond.wait(
cpp_lock
);
cpp_lock.release();
return 0;
} else {
auto wait_result = cond->cpp_cond.wait_for(
cpp_lock,
std::chrono::duration<Uint32, std::milli>(ms)
);
cpp_lock.release();
if (wait_result == std::cv_status::timeout) {
return SDL_MUTEX_TIMEDOUT;
} else {
return 0;
}
}
} catch (std::system_error & ex) {
SDL_SetError("unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what());
return -1;
}
}
SDL_mutex::cpp_mutex
std::recursive_mutex cpp_mutex
Definition: SDL_sysmutex_c.h:27
SDL_MUTEX_TIMEDOUT
#define SDL_MUTEX_TIMEDOUT
Definition: SDL_mutex.h:44
SDL_MUTEX_MAXWAIT
#define SDL_MUTEX_MAXWAIT
Definition: SDL_mutex.h:49
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
timeout
GLbitfield GLuint64 timeout
Definition: SDL_opengl_glext.h:1483
SDL_cond::cpp_cond
std::condition_variable_any cpp_cond
Definition: SDL_syscond.cpp:36

## SDL_CreateCond()

SDL_cond* SDL_CreateCond | ( | void |  | ) |

Create a condition variable.

Typical use of condition variables:

Thread A: SDL_LockMutex(lock); while ( ! condition ) { SDL_CondWait(cond, lock); } SDL_UnlockMutex(lock);

Thread B: SDL_LockMutex(lock); ... condition = true; ... SDL_CondSignal(cond); SDL_UnlockMutex(lock);

There is some discussion whether to signal the condition variable with the mutex locked or not. There is some potential performance benefit to unlocking first on some platforms, but there are some potential race conditions depending on how your code is structured.

In general it's safer to signal the condition variable while the mutex is locked.

Definition at line 42 of file SDL_syscond.cpp.

References SDL_cond::cond, NULL, SDL_OutOfMemory, and SDL_SetError.

{
/* Allocate and initialize the condition variable */
try {
SDL_cond * cond = new SDL_cond;
return cond;
} catch (std::system_error & ex) {
SDL_SetError("unable to create a C++ condition variable: code=%d; %s", ex.code(), ex.what());
return NULL;
} catch (std::bad_alloc &) {
SDL_OutOfMemory();
return NULL;
}
}
SDL_cond
Definition: SDL_syscond.c:31
NULL
#define NULL
Definition: begin_code.h:164
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30

## SDL_DestroyCond()

void SDL_DestroyCond | ( | SDL_cond * | cond | ) |

Destroy a condition variable.

Definition at line 60 of file SDL_syscond.cpp.

References SDL_cond::cond.

{
if (cond) {
delete cond;
}
}