SDL_syscond.c File Reference
`#include "../../SDL_internal.h"`
`#include "SDL_thread.h"`
Include dependency graph for SDL_syscond.c:

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 106 of file SDL_syscond.c.

{
if (!cond) {
return SDL_SetError("Passed a NULL condition variable");
}
/* If there are waiting threads not already signalled, then
signal the condition and wait for the thread to respond.
*/
SDL_LockMutex(cond->lock);
if (cond->waiting > cond->signals) {
int i, num_waiting;
num_waiting = (cond->waiting - cond->signals);
cond->signals = cond->waiting;
for (i = 0; i < num_waiting; ++i) {
SDL_SemPost(cond->wait_sem);
}
/* Now all released threads are blocked here, waiting for us.
Collect them all (and win fabulous prizes!) :-)
*/
SDL_UnlockMutex(cond->lock);
for (i = 0; i < num_waiting; ++i) {
SDL_SemWait(cond->wait_done);
}
} else {
SDL_UnlockMutex(cond->lock);
}
return 0;
}

References i, SDL_cond::lock, SDL_LockMutex, SDL_SemPost, SDL_SemWait, SDL_SetError, SDL_UnlockMutex, SDL_cond::signals, SDL_cond::wait_done, SDL_cond::wait_sem, and SDL_cond::waiting.

## 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 82 of file SDL_syscond.c.

{
if (!cond) {
return SDL_SetError("Passed a NULL condition variable");
}
/* If there are waiting threads not already signalled, then
signal the condition and wait for the thread to respond.
*/
SDL_LockMutex(cond->lock);
if (cond->waiting > cond->signals) {
++cond->signals;
SDL_SemPost(cond->wait_sem);
SDL_UnlockMutex(cond->lock);
SDL_SemWait(cond->wait_done);
} else {
SDL_UnlockMutex(cond->lock);
}
return 0;
}

References SDL_cond::lock, SDL_LockMutex, SDL_SemPost, SDL_SemWait, SDL_SetError, SDL_UnlockMutex, SDL_cond::signals, SDL_cond::wait_done, SDL_cond::wait_sem, and SDL_cond::waiting.

## 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 215 of file SDL_syscond.c.

{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}

References mutex, SDL_CondWaitTimeout(), and SDL_MUTEX_MAXWAIT.

## 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 160 of file SDL_syscond.c.

{
int retval;
if (!cond) {
return SDL_SetError("Passed a NULL condition variable");
}
/* Obtain the protection mutex, and increment the number of waiters.
This allows the signal mechanism to only perform a signal if there
are waiting threads.
*/
SDL_LockMutex(cond->lock);
++cond->waiting;
SDL_UnlockMutex(cond->lock);
/* Unlock the mutex, as is required by condition variable semantics */
SDL_UnlockMutex(mutex);
/* Wait for a signal */
if (ms == SDL_MUTEX_MAXWAIT) {
retval = SDL_SemWait(cond->wait_sem);
} else {
retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
}
/* Let the signaler know we have completed the wait, otherwise
the signaler can race ahead and get the condition semaphore
if we are stopped between the mutex unlock and semaphore wait,
giving a deadlock. See the following URL for details:
http://web.archive.org/web/20010914175514/http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html#Workshop
*/
SDL_LockMutex(cond->lock);
if (cond->signals > 0) {
/* If we timed out, we need to eat a condition signal */
if (retval > 0) {
SDL_SemWait(cond->wait_sem);
}
/* We always notify the signal thread that we are done */
SDL_SemPost(cond->wait_done);
/* Signal handshake complete */
--cond->signals;
}
--cond->waiting;
SDL_UnlockMutex(cond->lock);
/* Lock the mutex, as is required by condition variable semantics */
SDL_LockMutex(mutex);
return retval;
}

References SDL_cond::lock, mutex, retval, SDL_LockMutex, SDL_MUTEX_MAXWAIT, SDL_SemPost, SDL_SemWait, SDL_SemWaitTimeout, SDL_SetError, SDL_UnlockMutex, SDL_cond::signals, SDL_cond::wait_done, SDL_cond::wait_sem, and SDL_cond::waiting.

Referenced by SDL_CondWait().

## 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.c.

{
SDL_cond *cond;
cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
if (cond) {
cond->lock = SDL_CreateMutex();
cond->wait_sem = SDL_CreateSemaphore(0);
cond->wait_done = SDL_CreateSemaphore(0);
cond->waiting = cond->signals = 0;
if (!cond->lock || !cond->wait_sem || !cond->wait_done) {
SDL_DestroyCond(cond);
cond = NULL;
}
} else {
SDL_OutOfMemory();
}
return (cond);
}

References SDL_cond::lock, NULL, SDL_CreateMutex, SDL_CreateSemaphore, SDL_DestroyCond(), SDL_malloc, SDL_OutOfMemory, SDL_cond::signals, SDL_cond::wait_done, SDL_cond::wait_sem, and SDL_cond::waiting.

## SDL_DestroyCond()

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

Destroy a condition variable.

Definition at line 64 of file SDL_syscond.c.

{
if (cond) {
if (cond->wait_sem) {
SDL_DestroySemaphore(cond->wait_sem);
}
if (cond->wait_done) {
SDL_DestroySemaphore(cond->wait_done);
}
if (cond->lock) {
SDL_DestroyMutex(cond->lock);
}
SDL_free(cond);
}
}

References SDL_cond::lock, SDL_DestroyMutex, SDL_DestroySemaphore, SDL_free, SDL_cond::wait_done, and SDL_cond::wait_sem.

Referenced by SDL_CreateCond().

SDL_cond::lock
SDL_mutex * lock
Definition: SDL_syscond.c:33
SDL_CreateSemaphore
#define SDL_CreateSemaphore
Definition: SDL_dynapi_overrides.h:264
SDL_LockMutex
#define SDL_LockMutex
Definition: SDL_dynapi_overrides.h:260
NULL
#define NULL
Definition: begin_code.h:167
SDL_cond::wait_done
SDL_sem * wait_done
Definition: SDL_syscond.c:37
mutex
static SDL_mutex * mutex
Definition: testlock.c:23
SDL_CreateMutex
#define SDL_CreateMutex
Definition: SDL_dynapi_overrides.h:259
SDL_CondWaitTimeout
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
Definition: SDL_syscond.c:160
SDL_cond
Definition: SDL_syscond.c:31
SDL_SemPost
#define SDL_SemPost
Definition: SDL_dynapi_overrides.h:269
SDL_SemWaitTimeout
#define SDL_SemWaitTimeout
Definition: SDL_dynapi_overrides.h:268
SDL_DestroyCond
void SDL_DestroyCond(SDL_cond *cond)
Definition: SDL_syscond.c:64
retval
SDL_bool retval
Definition: testgamecontroller.c:65
SDL_cond::waiting
int waiting
Definition: SDL_syscond.c:34
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_MUTEX_MAXWAIT
#define SDL_MUTEX_MAXWAIT
Definition: SDL_mutex.h:49
SDL_cond::signals
int signals
Definition: SDL_syscond.c:35
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_SemWait
#define SDL_SemWait
Definition: SDL_dynapi_overrides.h:266
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_DestroyMutex
#define SDL_DestroyMutex
Definition: SDL_dynapi_overrides.h:263
SDL_DestroySemaphore
#define SDL_DestroySemaphore
Definition: SDL_dynapi_overrides.h:265
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
SDL_UnlockMutex
#define SDL_UnlockMutex
Definition: SDL_dynapi_overrides.h:262
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_cond::wait_sem
SDL_sem * wait_sem
Definition: SDL_syscond.c:36