SDL  2.0
SDL_mutex.h File Reference
#include "SDL_stdinc.h"
#include "SDL_error.h"
#include "begin_code.h"
#include "close_code.h"
+ Include dependency graph for SDL_mutex.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define SDL_MUTEX_TIMEDOUT   1
 
#define SDL_MUTEX_MAXWAIT   (~(Uint32)0)
 

Functions

Semaphore functions
SDL_sem * SDL_CreateSemaphore (Uint32 initial_value)
 
void SDL_DestroySemaphore (SDL_sem *sem)
 
int SDL_SemWait (SDL_sem *sem)
 
int SDL_SemTryWait (SDL_sem *sem)
 
int SDL_SemWaitTimeout (SDL_sem *sem, Uint32 ms)
 
int SDL_SemPost (SDL_sem *sem)
 
Uint32 SDL_SemValue (SDL_sem *sem)
 
Condition variable functions
SDL_condSDL_CreateCond (void)
 
void SDL_DestroyCond (SDL_cond *cond)
 
int SDL_CondSignal (SDL_cond *cond)
 
int SDL_CondBroadcast (SDL_cond *cond)
 
int SDL_CondWait (SDL_cond *cond, SDL_mutex *mutex)
 
int SDL_CondWaitTimeout (SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
 

Mutex functions

#define SDL_mutexP(m)   SDL_LockMutex(m)
 
#define SDL_mutexV(m)   SDL_UnlockMutex(m)
 
SDL_mutexSDL_CreateMutex (void)
 
int SDL_LockMutex (SDL_mutex *mutex)
 
int SDL_TryLockMutex (SDL_mutex *mutex)
 
int SDL_UnlockMutex (SDL_mutex *mutex)
 
void SDL_DestroyMutex (SDL_mutex *mutex)
 

Detailed Description

Functions to provide thread synchronization primitives.

Definition in file SDL_mutex.h.

Macro Definition Documentation

◆ SDL_MUTEX_MAXWAIT

#define SDL_MUTEX_MAXWAIT   (~(Uint32)0)

This is the timeout value which corresponds to never time out.

Definition at line 49 of file SDL_mutex.h.

Referenced by SDL_CondWait(), SDL_CondWaitTimeout(), SDL_SemWait(), SDL_SemWaitTimeout(), and SDL_TimerThread().

◆ SDL_MUTEX_TIMEDOUT

#define SDL_MUTEX_TIMEDOUT   1

Synchronization functions which can time out return this value if they time out.

Definition at line 44 of file SDL_mutex.h.

Referenced by SDL_CondWaitTimeout(), SDL_SemTryWait(), SDL_SemWaitTimeout(), SDL_TryLockMutex(), and TestWaitTimeout().

◆ SDL_mutexP

#define SDL_mutexP (   m)    SDL_LockMutex(m)

Lock the mutex.

Returns
0, or -1 on error.

Definition at line 71 of file SDL_mutex.h.

◆ SDL_mutexV

#define SDL_mutexV (   m)    SDL_UnlockMutex(m)

Unlock the mutex.

Returns
0, or -1 on error.
Warning
It is an error to unlock a mutex that has not been locked by the current thread, and doing so results in undefined behavior.

Definition at line 89 of file SDL_mutex.h.

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.

References SDL_cond::cond, SDL_cond::cpp_cond, i, SDL_cond::lock, retval, 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.

107 {
108  if (!cond) {
109  return SDL_SetError("Passed a NULL condition variable");
110  }
111 
112  /* If there are waiting threads not already signalled, then
113  signal the condition and wait for the thread to respond.
114  */
115  SDL_LockMutex(cond->lock);
116  if (cond->waiting > cond->signals) {
117  int i, num_waiting;
118 
119  num_waiting = (cond->waiting - cond->signals);
120  cond->signals = cond->waiting;
121  for (i = 0; i < num_waiting; ++i) {
122  SDL_SemPost(cond->wait_sem);
123  }
124  /* Now all released threads are blocked here, waiting for us.
125  Collect them all (and win fabulous prizes!) :-)
126  */
127  SDL_UnlockMutex(cond->lock);
128  for (i = 0; i < num_waiting; ++i) {
129  SDL_SemWait(cond->wait_done);
130  }
131  } else {
132  SDL_UnlockMutex(cond->lock);
133  }
134 
135  return 0;
136 }
#define SDL_LockMutex
SDL_mutex * lock
Definition: SDL_syscond.c:33
int waiting
Definition: SDL_syscond.c:34
#define SDL_SemPost
int signals
Definition: SDL_syscond.c:35
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
#define SDL_SetError
SDL_sem * wait_done
Definition: SDL_syscond.c:37
#define SDL_SemWait
SDL_sem * wait_sem
Definition: SDL_syscond.c:36
#define SDL_UnlockMutex

◆ 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.

References SDL_cond::cond, SDL_cond::cpp_cond, SDL_cond::lock, retval, 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.

83 {
84  if (!cond) {
85  return SDL_SetError("Passed a NULL condition variable");
86  }
87 
88  /* If there are waiting threads not already signalled, then
89  signal the condition and wait for the thread to respond.
90  */
91  SDL_LockMutex(cond->lock);
92  if (cond->waiting > cond->signals) {
93  ++cond->signals;
94  SDL_SemPost(cond->wait_sem);
95  SDL_UnlockMutex(cond->lock);
96  SDL_SemWait(cond->wait_done);
97  } else {
98  SDL_UnlockMutex(cond->lock);
99  }
100 
101  return 0;
102 }
#define SDL_LockMutex
SDL_mutex * lock
Definition: SDL_syscond.c:33
int waiting
Definition: SDL_syscond.c:34
#define SDL_SemPost
int signals
Definition: SDL_syscond.c:35
#define SDL_SetError
SDL_sem * wait_done
Definition: SDL_syscond.c:37
#define SDL_SemWait
SDL_sem * wait_sem
Definition: SDL_syscond.c:36
#define SDL_UnlockMutex

◆ 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.

References SDL_cond::cond, SDL_mutex::id, SDL_CondWaitTimeout(), SDL_MUTEX_MAXWAIT, and SDL_SetError.

216 {
217  return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
218 }
#define SDL_MUTEX_MAXWAIT
Definition: SDL_mutex.h:49
int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
Definition: SDL_syscond.c:160

◆ 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.

References SDL_cond::cond, SDL_cond::cpp_cond, SDL_mutex::cpp_mutex, SDL_mutex::id, SDL_cond::lock, NULL, retval, SDL_LockMutex, SDL_MUTEX_MAXWAIT, SDL_MUTEX_TIMEDOUT, 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().

161 {
162  int retval;
163 
164  if (!cond) {
165  return SDL_SetError("Passed a NULL condition variable");
166  }
167 
168  /* Obtain the protection mutex, and increment the number of waiters.
169  This allows the signal mechanism to only perform a signal if there
170  are waiting threads.
171  */
172  SDL_LockMutex(cond->lock);
173  ++cond->waiting;
174  SDL_UnlockMutex(cond->lock);
175 
176  /* Unlock the mutex, as is required by condition variable semantics */
177  SDL_UnlockMutex(mutex);
178 
179  /* Wait for a signal */
180  if (ms == SDL_MUTEX_MAXWAIT) {
181  retval = SDL_SemWait(cond->wait_sem);
182  } else {
183  retval = SDL_SemWaitTimeout(cond->wait_sem, ms);
184  }
185 
186  /* Let the signaler know we have completed the wait, otherwise
187  the signaler can race ahead and get the condition semaphore
188  if we are stopped between the mutex unlock and semaphore wait,
189  giving a deadlock. See the following URL for details:
190  http://web.archive.org/web/20010914175514/http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html#Workshop
191  */
192  SDL_LockMutex(cond->lock);
193  if (cond->signals > 0) {
194  /* If we timed out, we need to eat a condition signal */
195  if (retval > 0) {
196  SDL_SemWait(cond->wait_sem);
197  }
198  /* We always notify the signal thread that we are done */
199  SDL_SemPost(cond->wait_done);
200 
201  /* Signal handshake complete */
202  --cond->signals;
203  }
204  --cond->waiting;
205  SDL_UnlockMutex(cond->lock);
206 
207  /* Lock the mutex, as is required by condition variable semantics */
208  SDL_LockMutex(mutex);
209 
210  return retval;
211 }
#define SDL_LockMutex
SDL_mutex * lock
Definition: SDL_syscond.c:33
int waiting
Definition: SDL_syscond.c:34
#define SDL_SemPost
SDL_bool retval
#define SDL_SemWaitTimeout
#define SDL_MUTEX_MAXWAIT
Definition: SDL_mutex.h:49
int signals
Definition: SDL_syscond.c:35
#define SDL_SetError
SDL_sem * wait_done
Definition: SDL_syscond.c:37
#define SDL_SemWait
SDL_sem * wait_sem
Definition: SDL_syscond.c:36
#define SDL_UnlockMutex

◆ 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.

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

43 {
44  SDL_cond *cond;
45 
46  cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond));
47  if (cond) {
48  cond->lock = SDL_CreateMutex();
49  cond->wait_sem = SDL_CreateSemaphore(0);
50  cond->wait_done = SDL_CreateSemaphore(0);
51  cond->waiting = cond->signals = 0;
52  if (!cond->lock || !cond->wait_sem || !cond->wait_done) {
53  SDL_DestroyCond(cond);
54  cond = NULL;
55  }
56  } else {
58  }
59  return (cond);
60 }
#define SDL_CreateSemaphore
SDL_mutex * lock
Definition: SDL_syscond.c:33
#define SDL_CreateMutex
int waiting
Definition: SDL_syscond.c:34
int signals
Definition: SDL_syscond.c:35
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_sem * wait_done
Definition: SDL_syscond.c:37
SDL_sem * wait_sem
Definition: SDL_syscond.c:36
#define SDL_malloc
void SDL_DestroyCond(SDL_cond *cond)
Definition: SDL_syscond.c:64

◆ SDL_CreateMutex()

SDL_mutex* SDL_CreateMutex ( void  )

Create a mutex, initialized unlocked.

Definition at line 38 of file SDL_sysmutex.c.

References SDL_mutex::id, mutex, NULL, SDL_mutex::owner, SDL_mutex::recursive, SDL_calloc, SDL_CreateSemaphore, SDL_free, SDL_malloc, SDL_OutOfMemory, SDL_SetError, and SDL_mutex::sem.

39 {
41 
42  /* Allocate mutex memory */
43  mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
44  if (mutex) {
45  /* Create the mutex semaphore, with initial value 1 */
46  mutex->sem = SDL_CreateSemaphore(1);
47  mutex->recursive = 0;
48  mutex->owner = 0;
49  if (!mutex->sem) {
50  SDL_free(mutex);
51  mutex = NULL;
52  }
53  } else {
55  }
56  return mutex;
57 }
#define SDL_CreateSemaphore
static SDL_mutex * mutex
Definition: testlock.c:23
#define SDL_free
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_threadID owner
Definition: SDL_sysmutex.c:32
#define SDL_malloc
int recursive
Definition: SDL_sysmutex.c:31
SDL_sem * sem
Definition: SDL_sysmutex.c:33

◆ SDL_CreateSemaphore()

SDL_sem* SDL_CreateSemaphore ( Uint32  initial_value)

Create a semaphore, initialized with value, returns NULL on failure.

Definition at line 85 of file SDL_syssem.c.

References NULL, SDL_CreateCond, SDL_CreateMutex, SDL_DestroySemaphore(), SDL_free, SDL_malloc, SDL_OutOfMemory, SDL_SetError, and SDL_sem::sem.

86 {
87  SDL_sem *sem;
88 
89  sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
90  if (!sem) {
92  return NULL;
93  }
94  sem->count = initial_value;
95  sem->waiters_count = 0;
96 
97  sem->count_lock = SDL_CreateMutex();
98  sem->count_nonzero = SDL_CreateCond();
99  if (!sem->count_lock || !sem->count_nonzero) {
101  return NULL;
102  }
103 
104  return sem;
105 }
#define SDL_CreateMutex
static SDL_sem * sem
Definition: testsem.c:23
#define SDL_CreateCond
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_malloc
void SDL_DestroySemaphore(SDL_sem *sem)
Definition: SDL_syssem.c:111

◆ SDL_DestroyCond()

void SDL_DestroyCond ( SDL_cond cond)

Destroy a condition variable.

Definition at line 64 of file SDL_syscond.c.

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

Referenced by SDL_CreateCond().

65 {
66  if (cond) {
67  if (cond->wait_sem) {
69  }
70  if (cond->wait_done) {
72  }
73  if (cond->lock) {
74  SDL_DestroyMutex(cond->lock);
75  }
76  SDL_free(cond);
77  }
78 }
SDL_mutex * lock
Definition: SDL_syscond.c:33
#define SDL_free
#define SDL_DestroyMutex
SDL_sem * wait_done
Definition: SDL_syscond.c:37
#define SDL_DestroySemaphore
SDL_sem * wait_sem
Definition: SDL_syscond.c:36

◆ SDL_DestroyMutex()

void SDL_DestroyMutex ( SDL_mutex mutex)

Destroy a mutex.

Definition at line 61 of file SDL_sysmutex.c.

References SDL_mutex::id, mutex, SDL_DestroySemaphore, SDL_free, and SDL_mutex::sem.

62 {
63  if (mutex) {
64  if (mutex->sem) {
65  SDL_DestroySemaphore(mutex->sem);
66  }
67  SDL_free(mutex);
68  }
69 }
#define SDL_free
#define SDL_DestroySemaphore
SDL_sem * sem
Definition: SDL_sysmutex.c:33

◆ SDL_DestroySemaphore()

void SDL_DestroySemaphore ( SDL_sem *  sem)

Destroy a semaphore.

Definition at line 111 of file SDL_syssem.c.

References SDL_CondSignal, SDL_Delay, SDL_DestroyCond, SDL_DestroyMutex, SDL_free, SDL_LockMutex, and SDL_UnlockMutex.

Referenced by SDL_CreateSemaphore().

112 {
113  if (sem) {
114  sem->count = 0xFFFFFFFF;
115  while (sem->waiters_count > 0) {
116  SDL_CondSignal(sem->count_nonzero);
117  SDL_Delay(10);
118  }
119  SDL_DestroyCond(sem->count_nonzero);
120  if (sem->count_lock) {
121  SDL_LockMutex(sem->count_lock);
122  SDL_UnlockMutex(sem->count_lock);
123  SDL_DestroyMutex(sem->count_lock);
124  }
125  SDL_free(sem);
126  }
127 }
#define SDL_LockMutex
#define SDL_DestroyCond
#define SDL_CondSignal
static SDL_sem * sem
Definition: testsem.c:23
#define SDL_free
#define SDL_Delay
#define SDL_DestroyMutex
#define SDL_UnlockMutex

◆ SDL_LockMutex()

int SDL_LockMutex ( SDL_mutex mutex)

Definition at line 73 of file SDL_sysmutex.c.

References SDL_mutex::id, NULL, SDL_mutex::owner, SDL_mutex::recursive, SDL_SemWait, SDL_SetError, SDL_ThreadID, and SDL_mutex::sem.

74 {
75 #if SDL_THREADS_DISABLED
76  return 0;
77 #else
78  SDL_threadID this_thread;
79 
80  if (mutex == NULL) {
81  return SDL_SetError("Passed a NULL mutex");
82  }
83 
84  this_thread = SDL_ThreadID();
85  if (mutex->owner == this_thread) {
86  ++mutex->recursive;
87  } else {
88  /* The order of operations is important.
89  We set the locking thread id after we obtain the lock
90  so unlocks from other threads will fail.
91  */
92  SDL_SemWait(mutex->sem);
93  mutex->owner = this_thread;
94  mutex->recursive = 0;
95  }
96 
97  return 0;
98 #endif /* SDL_THREADS_DISABLED */
99 }
#define SDL_ThreadID
#define NULL
Definition: begin_code.h:164
#define SDL_SetError
SDL_threadID owner
Definition: SDL_sysmutex.c:32
#define SDL_SemWait
int recursive
Definition: SDL_sysmutex.c:31
SDL_sem * sem
Definition: SDL_sysmutex.c:33
unsigned long SDL_threadID
Definition: SDL_thread.h:49

◆ SDL_SemPost()

int SDL_SemPost ( SDL_sem *  sem)

Atomically increases the semaphore's count (not blocking).

Returns
0, or -1 on error.

Definition at line 200 of file SDL_syssem.c.

References retval, SDL_CondSignal, SDL_LockMutex, SDL_SetError, and SDL_UnlockMutex.

201 {
202  if (!sem) {
203  return SDL_SetError("Passed a NULL semaphore");
204  }
205 
206  SDL_LockMutex(sem->count_lock);
207  if (sem->waiters_count > 0) {
208  SDL_CondSignal(sem->count_nonzero);
209  }
210  ++sem->count;
211  SDL_UnlockMutex(sem->count_lock);
212 
213  return 0;
214 }
#define SDL_LockMutex
#define SDL_CondSignal
static SDL_sem * sem
Definition: testsem.c:23
#define SDL_SetError
#define SDL_UnlockMutex

◆ SDL_SemTryWait()

int SDL_SemTryWait ( SDL_sem *  sem)

Non-blocking variant of SDL_SemWait().

Returns
0 if the wait succeeds, SDL_MUTEX_TIMEDOUT if the wait would block, and -1 on error.

Definition at line 130 of file SDL_syssem.c.

References retval, SDL_LockMutex, SDL_MUTEX_TIMEDOUT, SDL_SetError, and SDL_UnlockMutex.

Referenced by SDL_SemWaitTimeout().

131 {
132  int retval;
133 
134  if (!sem) {
135  return SDL_SetError("Passed a NULL semaphore");
136  }
137 
138  retval = SDL_MUTEX_TIMEDOUT;
139  SDL_LockMutex(sem->count_lock);
140  if (sem->count > 0) {
141  --sem->count;
142  retval = 0;
143  }
144  SDL_UnlockMutex(sem->count_lock);
145 
146  return retval;
147 }
#define SDL_LockMutex
static SDL_sem * sem
Definition: testsem.c:23
#define SDL_MUTEX_TIMEDOUT
Definition: SDL_mutex.h:44
SDL_bool retval
#define SDL_SetError
#define SDL_UnlockMutex

◆ SDL_SemValue()

Uint32 SDL_SemValue ( SDL_sem *  sem)

Returns the current count of the semaphore.

Definition at line 186 of file SDL_syssem.c.

References SDL_LockMutex, and SDL_UnlockMutex.

187 {
188  Uint32 value;
189 
190  value = 0;
191  if (sem) {
192  SDL_LockMutex(sem->count_lock);
193  value = sem->count;
194  SDL_UnlockMutex(sem->count_lock);
195  }
196  return value;
197 }
#define SDL_LockMutex
uint32_t Uint32
Definition: SDL_stdinc.h:181
static SDL_sem * sem
Definition: testsem.c:23
GLsizei const GLfloat * value
#define SDL_UnlockMutex

◆ SDL_SemWait()

int SDL_SemWait ( SDL_sem *  sem)

This function suspends the calling thread until the semaphore pointed to by sem has a positive count. It then atomically decreases the semaphore count.

Definition at line 180 of file SDL_syssem.c.

References retval, SDL_MUTEX_MAXWAIT, SDL_SemWaitTimeout(), and SDL_SetError.

Referenced by SDL_SemWaitTimeout().

181 {
183 }
static SDL_sem * sem
Definition: testsem.c:23
#define SDL_MUTEX_MAXWAIT
Definition: SDL_mutex.h:49
int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
Definition: SDL_syssem.c:150

◆ SDL_SemWaitTimeout()

int SDL_SemWaitTimeout ( SDL_sem *  sem,
Uint32  ms 
)

Variant of SDL_SemWait() with a timeout in milliseconds.

Returns
0 if the wait succeeds, SDL_MUTEX_TIMEDOUT if the wait does not succeed 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 150 of file SDL_syssem.c.

References NULL, retval, SDL_CondWaitTimeout, SDL_Delay, SDL_GetTicks(), SDL_LockMutex, SDL_MUTEX_MAXWAIT, SDL_MUTEX_TIMEDOUT, SDL_SemTryWait(), SDL_SemWait(), SDL_SetError, SDL_TICKS_PASSED, and SDL_UnlockMutex.

Referenced by SDL_SemWait().

151 {
152  int retval;
153 
154  if (!sem) {
155  return SDL_SetError("Passed a NULL semaphore");
156  }
157 
158  /* A timeout of 0 is an easy case */
159  if (timeout == 0) {
160  return SDL_SemTryWait(sem);
161  }
162 
163  SDL_LockMutex(sem->count_lock);
164  ++sem->waiters_count;
165  retval = 0;
166  while ((sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT)) {
167  retval = SDL_CondWaitTimeout(sem->count_nonzero,
168  sem->count_lock, timeout);
169  }
170  --sem->waiters_count;
171  if (retval == 0) {
172  --sem->count;
173  }
174  SDL_UnlockMutex(sem->count_lock);
175 
176  return retval;
177 }
#define SDL_LockMutex
static SDL_sem * sem
Definition: testsem.c:23
#define SDL_MUTEX_TIMEDOUT
Definition: SDL_mutex.h:44
SDL_bool retval
#define SDL_CondWaitTimeout
int SDL_SemTryWait(SDL_sem *sem)
Definition: SDL_syssem.c:130
#define SDL_SetError
GLbitfield GLuint64 timeout
#define SDL_UnlockMutex

◆ SDL_TryLockMutex()

int SDL_TryLockMutex ( SDL_mutex mutex)

Try to lock the mutex

Returns
0, SDL_MUTEX_TIMEDOUT, or -1 on error

Definition at line 103 of file SDL_sysmutex.c.

References SDL_mutex::cpp_mutex, SDL_mutex::id, NULL, SDL_mutex::owner, SDL_mutex::recursive, retval, SDL_MUTEX_TIMEDOUT, SDL_SemWait, SDL_SetError, SDL_ThreadID, and SDL_mutex::sem.

104 {
105 #if SDL_THREADS_DISABLED
106  return 0;
107 #else
108  int retval = 0;
109  SDL_threadID this_thread;
110 
111  if (mutex == NULL) {
112  return SDL_SetError("Passed a NULL mutex");
113  }
114 
115  this_thread = SDL_ThreadID();
116  if (mutex->owner == this_thread) {
117  ++mutex->recursive;
118  } else {
119  /* The order of operations is important.
120  We set the locking thread id after we obtain the lock
121  so unlocks from other threads will fail.
122  */
123  retval = SDL_SemWait(mutex->sem);
124  if (retval == 0) {
125  mutex->owner = this_thread;
126  mutex->recursive = 0;
127  }
128  }
129 
130  return retval;
131 #endif /* SDL_THREADS_DISABLED */
132 }
#define SDL_ThreadID
SDL_bool retval
#define NULL
Definition: begin_code.h:164
#define SDL_SetError
SDL_threadID owner
Definition: SDL_sysmutex.c:32
#define SDL_SemWait
int recursive
Definition: SDL_sysmutex.c:31
SDL_sem * sem
Definition: SDL_sysmutex.c:33
unsigned long SDL_threadID
Definition: SDL_thread.h:49

◆ SDL_UnlockMutex()

int SDL_UnlockMutex ( SDL_mutex mutex)

Definition at line 159 of file SDL_sysmutex.c.

References SDL_mutex::id, NULL, SDL_mutex::owner, SDL_mutex::recursive, and SDL_SetError.

160 {
161  if (mutex == NULL) {
162  return SDL_SetError("Passed a NULL mutex");
163  }
164 
165 #if FAKE_RECURSIVE_MUTEX
166  /* We can only unlock the mutex if we own it */
167  if (pthread_self() == mutex->owner) {
168  if (mutex->recursive) {
169  --mutex->recursive;
170  } else {
171  /* The order of operations is important.
172  First reset the owner so another thread doesn't lock
173  the mutex and set the ownership before we reset it,
174  then release the lock semaphore.
175  */
176  mutex->owner = 0;
177  pthread_mutex_unlock(&mutex->id);
178  }
179  } else {
180  return SDL_SetError("mutex not owned by this thread");
181  }
182 
183 #else
184  if (pthread_mutex_unlock(&mutex->id) != 0) {
185  return SDL_SetError("pthread_mutex_unlock() failed");
186  }
187 #endif /* FAKE_RECURSIVE_MUTEX */
188 
189  return 0;
190 }
#define NULL
Definition: begin_code.h:164
#define SDL_SetError
SDL_threadID owner
Definition: SDL_sysmutex.c:32
int recursive
Definition: SDL_sysmutex.c:31
pthread_mutex_t id
Definition: SDL_sysmutex.c:35