SDL 3.0
SDL_mutex.h
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21
22#ifndef SDL_mutex_h_
23#define SDL_mutex_h_
24
25/**
26 * \file SDL_mutex.h
27 *
28 * \brief Functions to provide thread synchronization primitives.
29 */
30
31#include <SDL3/SDL_stdinc.h>
32#include <SDL3/SDL_error.h>
33
34/******************************************************************************/
35/* Enable thread safety attributes only with clang.
36 * The attributes can be safely erased when compiling with other compilers.
37 *
38 * To enable analysis, set these environment variables before running cmake:
39 * export CC=clang
40 * export CFLAGS="-DSDL_THREAD_SAFETY_ANALYSIS -Wthread-safety"
41 */
42#if defined(SDL_THREAD_SAFETY_ANALYSIS) && \
43 defined(__clang__) && (!defined(SWIG))
44#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
45#else
46#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x) /* no-op */
47#endif
48
49#define SDL_CAPABILITY(x) \
50 SDL_THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
51
52#define SDL_SCOPED_CAPABILITY \
53 SDL_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
54
55#define SDL_GUARDED_BY(x) \
56 SDL_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
57
58#define SDL_PT_GUARDED_BY(x) \
59 SDL_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
60
61#define SDL_ACQUIRED_BEFORE(x) \
62 SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(x))
63
64#define SDL_ACQUIRED_AFTER(x) \
65 SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(x))
66
67#define SDL_REQUIRES(x) \
68 SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(x))
69
70#define SDL_REQUIRES_SHARED(x) \
71 SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(x))
72
73#define SDL_ACQUIRE(x) \
74 SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(x))
75
76#define SDL_ACQUIRE_SHARED(x) \
77 SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(x))
78
79#define SDL_RELEASE(x) \
80 SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_capability(x))
81
82#define SDL_RELEASE_SHARED(x) \
83 SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(x))
84
85#define SDL_RELEASE_GENERIC(x) \
86 SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(x))
87
88#define SDL_TRY_ACQUIRE(x, y) \
89 SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(x, y))
90
91#define SDL_TRY_ACQUIRE_SHARED(x, y) \
92 SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(x, y))
93
94#define SDL_EXCLUDES(x) \
95 SDL_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(x))
96
97#define SDL_ASSERT_CAPABILITY(x) \
98 SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
99
100#define SDL_ASSERT_SHARED_CAPABILITY(x) \
101 SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
102
103#define SDL_RETURN_CAPABILITY(x) \
104 SDL_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
105
106#define SDL_NO_THREAD_SAFETY_ANALYSIS \
107 SDL_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
108
109/******************************************************************************/
110
111
112#include <SDL3/SDL_begin_code.h>
113/* Set up for C function definitions, even when using C++ */
114#ifdef __cplusplus
115extern "C" {
116#endif
117
118/**
119 * Synchronization functions which can time out return this value
120 * if they time out.
121 */
122#define SDL_MUTEX_TIMEDOUT 1
123
124/**
125 * This is the timeout value which corresponds to never time out.
126 */
127#define SDL_MUTEX_MAXWAIT -1
128
129
130/**
131 * \name Mutex functions
132 */
133/* @{ */
134
135/* The SDL mutex structure, defined in SDL_sysmutex.c */
136struct SDL_Mutex;
137typedef struct SDL_Mutex SDL_Mutex;
138
139/**
140 * Create a new mutex.
141 *
142 * All newly-created mutexes begin in the _unlocked_ state.
143 *
144 * Calls to SDL_LockMutex() will not return while the mutex is locked by
145 * another thread. See SDL_TryLockMutex() to attempt to lock without blocking.
146 *
147 * SDL mutexes are reentrant.
148 *
149 * \returns the initialized and unlocked mutex or NULL on failure; call
150 * SDL_GetError() for more information.
151 *
152 * \since This function is available since SDL 3.0.0.
153 *
154 * \sa SDL_DestroyMutex
155 * \sa SDL_LockMutex
156 * \sa SDL_TryLockMutex
157 * \sa SDL_UnlockMutex
158 */
159extern DECLSPEC SDL_Mutex *SDLCALL SDL_CreateMutex(void);
160
161/**
162 * Lock the mutex.
163 *
164 * This will block until the mutex is available, which is to say it is in the
165 * unlocked state and the OS has chosen the caller as the next thread to lock
166 * it. Of all threads waiting to lock the mutex, only one may do so at a time.
167 *
168 * It is legal for the owning thread to lock an already-locked mutex. It must
169 * unlock it the same number of times before it is actually made available for
170 * other threads in the system (this is known as a "recursive mutex").
171 *
172 * \param mutex the mutex to lock
173 * \returns 0 on success or a negative error code on failure; call
174 * SDL_GetError() for more information.
175 *
176 * \since This function is available since SDL 3.0.0.
177 */
178extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_Mutex *mutex) SDL_ACQUIRE(mutex);
179
180/**
181 * Try to lock a mutex without blocking.
182 *
183 * This works just like SDL_LockMutex(), but if the mutex is not available,
184 * this function returns `SDL_MUTEX_TIMEDOUT` immediately.
185 *
186 * This technique is useful if you need exclusive access to a resource but
187 * don't want to wait for it, and will return to it to try again later.
188 *
189 * \param mutex the mutex to try to lock
190 * \returns 0, `SDL_MUTEX_TIMEDOUT`, or -1 on error; call SDL_GetError() for
191 * more information.
192 *
193 * \since This function is available since SDL 3.0.0.
194 *
195 * \sa SDL_CreateMutex
196 * \sa SDL_DestroyMutex
197 * \sa SDL_LockMutex
198 * \sa SDL_UnlockMutex
199 */
200extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_Mutex *mutex) SDL_TRY_ACQUIRE(0, mutex);
201
202/**
203 * Unlock the mutex.
204 *
205 * It is legal for the owning thread to lock an already-locked mutex. It must
206 * unlock it the same number of times before it is actually made available for
207 * other threads in the system (this is known as a "recursive mutex").
208 *
209 * It is illegal to unlock a mutex that has not been locked by the current
210 * thread, and doing so results in undefined behavior.
211 *
212 * \param mutex the mutex to unlock.
213 * \returns 0 on success or a negative error code on failure; call
214 * SDL_GetError() for more information.
215 *
216 * \since This function is available since SDL 3.0.0.
217 */
218extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_Mutex *mutex) SDL_RELEASE(mutex);
219
220/**
221 * Destroy a mutex created with SDL_CreateMutex().
222 *
223 * This function must be called on any mutex that is no longer needed. Failure
224 * to destroy a mutex will result in a system memory or resource leak. While
225 * it is safe to destroy a mutex that is _unlocked_, it is not safe to attempt
226 * to destroy a locked mutex, and may result in undefined behavior depending
227 * on the platform.
228 *
229 * \param mutex the mutex to destroy
230 *
231 * \since This function is available since SDL 3.0.0.
232 *
233 * \sa SDL_CreateMutex
234 * \sa SDL_LockMutex
235 * \sa SDL_TryLockMutex
236 * \sa SDL_UnlockMutex
237 */
238extern DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_Mutex *mutex);
239
240/* @} *//* Mutex functions */
241
242
243/**
244 * \name Read/write lock functions
245 */
246/* @{ */
247
248/* The SDL read/write lock structure, defined in SDL_sysrwlock.c */
249struct SDL_RWLock;
250typedef struct SDL_RWLock SDL_RWLock;
251
252/*
253 * Synchronization functions which can time out return this value
254 * if they time out.
255 */
256#define SDL_RWLOCK_TIMEDOUT SDL_MUTEX_TIMEDOUT
257
258
259/**
260 * Create a new read/write lock.
261 *
262 * A read/write lock is useful for situations where you have multiple threads
263 * trying to access a resource that is rarely updated. All threads requesting
264 * a read-only lock will be allowed to run in parallel; if a thread requests a
265 * write lock, it will be provided exclusive access. This makes it safe for
266 * multiple threads to use a resource at the same time if they promise not to
267 * change it, and when it has to be changed, the rwlock will serve as a
268 * gateway to make sure those changes can be made safely.
269 *
270 * In the right situation, a rwlock can be more efficient than a mutex, which
271 * only lets a single thread proceed at a time, even if it won't be modifying
272 * the data.
273 *
274 * All newly-created read/write locks begin in the _unlocked_ state.
275 *
276 * Calls to SDL_LockRWLockForReading() and SDL_LockRWLockForWriting will not
277 * return while the rwlock is locked _for writing_ by another thread. See
278 * SDL_TryLockRWLockForReading() and SDL_TryLockRWLockForWriting() to attempt
279 * to lock without blocking.
280 *
281 * SDL read/write locks are only recursive for read-only locks! They are not
282 * guaranteed to be fair, or provide access in a FIFO manner! They are not
283 * guaranteed to favor writers. You may not lock a rwlock for both read-only
284 * and write access at the same time from the same thread (so you can't
285 * promote your read-only lock to a write lock without unlocking first).
286 *
287 * \returns the initialized and unlocked read/write lock or NULL on failure;
288 * call SDL_GetError() for more information.
289 *
290 * \since This function is available since SDL 3.0.0.
291 *
292 * \sa SDL_DestroyRWLock
293 * \sa SDL_LockRWLockForReading
294 * \sa SDL_TryLockRWLockForReading
295 * \sa SDL_LockRWLockForWriting
296 * \sa SDL_TryLockRWLockForWriting
297 * \sa SDL_UnlockRWLock
298 */
299extern DECLSPEC SDL_RWLock *SDLCALL SDL_CreateRWLock(void);
300
301/**
302 * Lock the read/write lock for _read only_ operations.
303 *
304 * This will block until the rwlock is available, which is to say it is not
305 * locked for writing by any other thread. Of all threads waiting to lock the
306 * rwlock, all may do so at the same time as long as they are requesting
307 * read-only access; if a thread wants to lock for writing, only one may do so
308 * at a time, and no other threads, read-only or not, may hold the lock at the
309 * same time.
310 *
311 * It is legal for the owning thread to lock an already-locked rwlock for
312 * reading. It must unlock it the same number of times before it is actually
313 * made available for other threads in the system (this is known as a
314 * "recursive rwlock").
315 *
316 * Note that locking for writing is not recursive (this is only available to
317 * read-only locks).
318 *
319 * It is illegal to request a read-only lock from a thread that already holds
320 * the write lock. Doing so results in undefined behavior. Unlock the write
321 * lock before requesting a read-only lock. (But, of course, if you have the
322 * write lock, you don't need further locks to read in any case.)
323 *
324 * \param rwlock the read/write lock to lock
325 * \returns 0 on success or a negative error code on failure; call
326 * SDL_GetError() for more information.
327 *
328 * \since This function is available since SDL 3.0.0.
329 *
330 * \sa SDL_UnlockRWLock
331 */
333
334/**
335 * Lock the read/write lock for _write_ operations.
336 *
337 * This will block until the rwlock is available, which is to say it is not
338 * locked for reading or writing by any other thread. Only one thread may hold
339 * the lock when it requests write access; all other threads, whether they
340 * also want to write or only want read-only access, must wait until the
341 * writer thread has released the lock.
342 *
343 * It is illegal for the owning thread to lock an already-locked rwlock for
344 * writing (read-only may be locked recursively, writing can not). Doing so
345 * results in undefined behavior.
346 *
347 * It is illegal to request a write lock from a thread that already holds a
348 * read-only lock. Doing so results in undefined behavior. Unlock the
349 * read-only lock before requesting a write lock.
350 *
351 * \param rwlock the read/write lock to lock
352 * \returns 0 on success or a negative error code on failure; call
353 * SDL_GetError() for more information.
354 *
355 * \since This function is available since SDL 3.0.0.
356 *
357 * \sa SDL_UnlockRWLock
358 */
360
361/**
362 * Try to lock a read/write lock _for reading_ without blocking.
363 *
364 * This works just like SDL_LockRWLockForReading(), but if the rwlock is not
365 * available, then this function returns `SDL_RWLOCK_TIMEDOUT` immediately.
366 *
367 * This technique is useful if you need access to a resource but don't want to
368 * wait for it, and will return to it to try again later.
369 *
370 * Trying to lock for read-only access can succeed if other threads are
371 * holding read-only locks, as this won't prevent access.
372 *
373 * \param rwlock the rwlock to try to lock
374 * \returns 0, `SDL_RWLOCK_TIMEDOUT`, or -1 on error; call SDL_GetError() for
375 * more information.
376 *
377 * \since This function is available since SDL 3.0.0.
378 *
379 * \sa SDL_CreateRWLock
380 * \sa SDL_DestroyRWLock
381 * \sa SDL_TryLockRWLockForReading
382 * \sa SDL_UnlockRWLock
383 */
385
386/**
387 * Try to lock a read/write lock _for writing_ without blocking.
388 *
389 * This works just like SDL_LockRWLockForWriting(), but if the rwlock is not
390 * available, this function returns `SDL_RWLOCK_TIMEDOUT` immediately.
391 *
392 * This technique is useful if you need exclusive access to a resource but
393 * don't want to wait for it, and will return to it to try again later.
394 *
395 * It is illegal for the owning thread to lock an already-locked rwlock for
396 * writing (read-only may be locked recursively, writing can not). Doing so
397 * results in undefined behavior.
398 *
399 * It is illegal to request a write lock from a thread that already holds a
400 * read-only lock. Doing so results in undefined behavior. Unlock the
401 * read-only lock before requesting a write lock.
402 *
403 * \param rwlock the rwlock to try to lock
404 * \returns 0, `SDL_RWLOCK_TIMEDOUT`, or -1 on error; call SDL_GetError() for
405 * more information.
406 *
407 * \since This function is available since SDL 3.0.0.
408 *
409 * \sa SDL_CreateRWLock
410 * \sa SDL_DestroyRWLock
411 * \sa SDL_TryLockRWLockForWriting
412 * \sa SDL_UnlockRWLock
413 */
415
416/**
417 * Unlock the read/write lock.
418 *
419 * Use this function to unlock the rwlock, whether it was locked for read-only
420 * or write operations.
421 *
422 * It is legal for the owning thread to lock an already-locked read-only lock.
423 * It must unlock it the same number of times before it is actually made
424 * available for other threads in the system (this is known as a "recursive
425 * rwlock").
426 *
427 * It is illegal to unlock a rwlock that has not been locked by the current
428 * thread, and doing so results in undefined behavior.
429 *
430 * \param rwlock the rwlock to unlock.
431 * \returns 0 on success or a negative error code on failure; call
432 * SDL_GetError() for more information.
433 *
434 * \since This function is available since SDL 3.0.0.
435 */
437
438/**
439 * Destroy a read/write lock created with SDL_CreateRWLock().
440 *
441 * This function must be called on any read/write lock that is no longer
442 * needed. Failure to destroy a rwlock will result in a system memory or
443 * resource leak. While it is safe to destroy a rwlock that is _unlocked_, it
444 * is not safe to attempt to destroy a locked rwlock, and may result in
445 * undefined behavior depending on the platform.
446 *
447 * \param rwlock the rwlock to destroy
448 *
449 * \since This function is available since SDL 3.0.0.
450 *
451 * \sa SDL_CreateRWLock
452 * \sa SDL_LockRWLockForReading
453 * \sa SDL_LockRWLockForWriting
454 * \sa SDL_TryLockRWLockForReading
455 * \sa SDL_TryLockRWLockForWriting
456 * \sa SDL_UnlockRWLock
457 */
458extern DECLSPEC void SDLCALL SDL_DestroyRWLock(SDL_RWLock *rwlock);
459
460/* @} *//* Read/write lock functions */
461
462
463/**
464 * \name Semaphore functions
465 */
466/* @{ */
467
468/* The SDL semaphore structure, defined in SDL_syssem.c */
469struct SDL_Semaphore;
471
472/**
473 * Create a semaphore.
474 *
475 * This function creates a new semaphore and initializes it with the value
476 * `initial_value`. Each wait operation on the semaphore will atomically
477 * decrement the semaphore value and potentially block if the semaphore value
478 * is 0. Each post operation will atomically increment the semaphore value and
479 * wake waiting threads and allow them to retry the wait operation.
480 *
481 * \param initial_value the starting value of the semaphore
482 * \returns a new semaphore or NULL on failure; call SDL_GetError() for more
483 * information.
484 *
485 * \since This function is available since SDL 3.0.0.
486 *
487 * \sa SDL_DestroySemaphore
488 * \sa SDL_PostSemaphore
489 * \sa SDL_TryWaitSemaphore
490 * \sa SDL_GetSemaphoreValue
491 * \sa SDL_WaitSemaphore
492 * \sa SDL_WaitSemaphoreTimeout
493 */
494extern DECLSPEC SDL_Semaphore *SDLCALL SDL_CreateSemaphore(Uint32 initial_value);
495
496/**
497 * Destroy a semaphore.
498 *
499 * It is not safe to destroy a semaphore if there are threads currently
500 * waiting on it.
501 *
502 * \param sem the semaphore to destroy
503 *
504 * \since This function is available since SDL 3.0.0.
505 *
506 * \sa SDL_CreateSemaphore
507 * \sa SDL_PostSemaphore
508 * \sa SDL_TryWaitSemaphore
509 * \sa SDL_GetSemaphoreValue
510 * \sa SDL_WaitSemaphore
511 * \sa SDL_WaitSemaphoreTimeout
512 */
513extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_Semaphore *sem);
514
515/**
516 * Wait until a semaphore has a positive value and then decrements it.
517 *
518 * This function suspends the calling thread until either the semaphore
519 * pointed to by `sem` has a positive value or the call is interrupted by a
520 * signal or error. If the call is successful it will atomically decrement the
521 * semaphore value.
522 *
523 * This function is the equivalent of calling SDL_WaitSemaphoreTimeout() with
524 * a time length of `SDL_MUTEX_MAXWAIT`.
525 *
526 * \param sem the semaphore wait on
527 * \returns 0 on success or a negative error code on failure; call
528 * SDL_GetError() for more information.
529 *
530 * \since This function is available since SDL 3.0.0.
531 *
532 * \sa SDL_CreateSemaphore
533 * \sa SDL_DestroySemaphore
534 * \sa SDL_PostSemaphore
535 * \sa SDL_TryWaitSemaphore
536 * \sa SDL_GetSemaphoreValue
537 * \sa SDL_WaitSemaphore
538 * \sa SDL_WaitSemaphoreTimeout
539 */
540extern DECLSPEC int SDLCALL SDL_WaitSemaphore(SDL_Semaphore *sem);
541
542/**
543 * See if a semaphore has a positive value and decrement it if it does.
544 *
545 * This function checks to see if the semaphore pointed to by `sem` has a
546 * positive value and atomically decrements the semaphore value if it does. If
547 * the semaphore doesn't have a positive value, the function immediately
548 * returns SDL_MUTEX_TIMEDOUT.
549 *
550 * \param sem the semaphore to wait on
551 * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait would
552 * block, or a negative error code on failure; call SDL_GetError()
553 * for more information.
554 *
555 * \since This function is available since SDL 3.0.0.
556 *
557 * \sa SDL_CreateSemaphore
558 * \sa SDL_DestroySemaphore
559 * \sa SDL_PostSemaphore
560 * \sa SDL_GetSemaphoreValue
561 * \sa SDL_WaitSemaphore
562 * \sa SDL_WaitSemaphoreTimeout
563 */
564extern DECLSPEC int SDLCALL SDL_TryWaitSemaphore(SDL_Semaphore *sem);
565
566/**
567 * Wait until a semaphore has a positive value and then decrements it.
568 *
569 * This function suspends the calling thread until either the semaphore
570 * pointed to by `sem` has a positive value, the call is interrupted by a
571 * signal or error, or the specified time has elapsed. If the call is
572 * successful it will atomically decrement the semaphore value.
573 *
574 * \param sem the semaphore to wait on
575 * \param timeoutMS the length of the timeout, in milliseconds
576 * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not
577 * succeed in the allotted time, or a negative error code on failure;
578 * call SDL_GetError() for more information.
579 *
580 * \since This function is available since SDL 3.0.0.
581 *
582 * \sa SDL_CreateSemaphore
583 * \sa SDL_DestroySemaphore
584 * \sa SDL_PostSemaphore
585 * \sa SDL_TryWaitSemaphore
586 * \sa SDL_GetSemaphoreValue
587 * \sa SDL_WaitSemaphore
588 */
589extern DECLSPEC int SDLCALL SDL_WaitSemaphoreTimeout(SDL_Semaphore *sem, Sint32 timeoutMS);
590
591/**
592 * Atomically increment a semaphore's value and wake waiting threads.
593 *
594 * \param sem the semaphore to increment
595 * \returns 0 on success or a negative error code on failure; call
596 * SDL_GetError() for more information.
597 *
598 * \since This function is available since SDL 3.0.0.
599 *
600 * \sa SDL_CreateSemaphore
601 * \sa SDL_DestroySemaphore
602 * \sa SDL_TryWaitSemaphore
603 * \sa SDL_GetSemaphoreValue
604 * \sa SDL_WaitSemaphore
605 * \sa SDL_WaitSemaphoreTimeout
606 */
607extern DECLSPEC int SDLCALL SDL_PostSemaphore(SDL_Semaphore *sem);
608
609/**
610 * Get the current value of a semaphore.
611 *
612 * \param sem the semaphore to query
613 * \returns the current value of the semaphore.
614 *
615 * \since This function is available since SDL 3.0.0.
616 *
617 * \sa SDL_CreateSemaphore
618 */
619extern DECLSPEC Uint32 SDLCALL SDL_GetSemaphoreValue(SDL_Semaphore *sem);
620
621/* @} *//* Semaphore functions */
622
623
624/**
625 * \name Condition variable functions
626 */
627/* @{ */
628
629/* The SDL condition variable structure, defined in SDL_syscond.c */
630struct SDL_Condition;
632
633/**
634 * Create a condition variable.
635 *
636 * \returns a new condition variable or NULL on failure; call SDL_GetError()
637 * for more information.
638 *
639 * \since This function is available since SDL 3.0.0.
640 *
641 * \sa SDL_BroadcastCondition
642 * \sa SDL_SignalCondition
643 * \sa SDL_WaitCondition
644 * \sa SDL_WaitConditionTimeout
645 * \sa SDL_DestroyCondition
646 */
647extern DECLSPEC SDL_Condition *SDLCALL SDL_CreateCondition(void);
648
649/**
650 * Destroy a condition variable.
651 *
652 * \param cond the condition variable to destroy
653 *
654 * \since This function is available since SDL 3.0.0.
655 *
656 * \sa SDL_BroadcastCondition
657 * \sa SDL_SignalCondition
658 * \sa SDL_WaitCondition
659 * \sa SDL_WaitConditionTimeout
660 * \sa SDL_CreateCondition
661 */
662extern DECLSPEC void SDLCALL SDL_DestroyCondition(SDL_Condition *cond);
663
664/**
665 * Restart one of the threads that are waiting on the condition variable.
666 *
667 * \param cond the condition variable to signal
668 * \returns 0 on success or a negative error code on failure; call
669 * SDL_GetError() for more information.
670 *
671 * \since This function is available since SDL 3.0.0.
672 *
673 * \sa SDL_BroadcastCondition
674 * \sa SDL_WaitCondition
675 * \sa SDL_WaitConditionTimeout
676 * \sa SDL_CreateCondition
677 * \sa SDL_DestroyCondition
678 */
679extern DECLSPEC int SDLCALL SDL_SignalCondition(SDL_Condition *cond);
680
681/**
682 * Restart all threads that are waiting on the condition variable.
683 *
684 * \param cond the condition variable to signal
685 * \returns 0 on success or a negative error code on failure; call
686 * SDL_GetError() for more information.
687 *
688 * \since This function is available since SDL 3.0.0.
689 *
690 * \sa SDL_SignalCondition
691 * \sa SDL_WaitCondition
692 * \sa SDL_WaitConditionTimeout
693 * \sa SDL_CreateCondition
694 * \sa SDL_DestroyCondition
695 */
696extern DECLSPEC int SDLCALL SDL_BroadcastCondition(SDL_Condition *cond);
697
698/**
699 * Wait until a condition variable is signaled.
700 *
701 * This function unlocks the specified `mutex` and waits for another thread to
702 * call SDL_SignalCondition() or SDL_BroadcastCondition() on the condition
703 * variable `cond`. Once the condition variable is signaled, the mutex is
704 * re-locked and the function returns.
705 *
706 * The mutex must be locked before calling this function. Locking the mutex
707 * recursively (more than once) is not supported and leads to undefined
708 * behavior.
709 *
710 * This function is the equivalent of calling SDL_WaitConditionTimeout() with
711 * a time length of `SDL_MUTEX_MAXWAIT`.
712 *
713 * \param cond the condition variable to wait on
714 * \param mutex the mutex used to coordinate thread access
715 * \returns 0 when it is signaled or a negative error code on failure; call
716 * SDL_GetError() for more information.
717 *
718 * \since This function is available since SDL 3.0.0.
719 *
720 * \sa SDL_BroadcastCondition
721 * \sa SDL_SignalCondition
722 * \sa SDL_WaitConditionTimeout
723 * \sa SDL_CreateCondition
724 * \sa SDL_DestroyCondition
725 */
726extern DECLSPEC int SDLCALL SDL_WaitCondition(SDL_Condition *cond, SDL_Mutex *mutex);
727
728/**
729 * Wait until a condition variable is signaled or a certain time has passed.
730 *
731 * This function unlocks the specified `mutex` and waits for another thread to
732 * call SDL_SignalCondition() or SDL_BroadcastCondition() on the condition
733 * variable `cond`, or for the specified time to elapse. Once the condition
734 * variable is signaled or the time elapsed, the mutex is re-locked and the
735 * function returns.
736 *
737 * The mutex must be locked before calling this function. Locking the mutex
738 * recursively (more than once) is not supported and leads to undefined
739 * behavior.
740 *
741 * \param cond the condition variable to wait on
742 * \param mutex the mutex used to coordinate thread access
743 * \param timeoutMS the maximum time to wait, in milliseconds, or
744 * `SDL_MUTEX_MAXWAIT` to wait indefinitely
745 * \returns 0 if the condition variable is signaled, `SDL_MUTEX_TIMEDOUT` if
746 * the condition is not signaled in the allotted time, or a negative
747 * error code on failure; call SDL_GetError() for more information.
748 *
749 * \since This function is available since SDL 3.0.0.
750 *
751 * \sa SDL_BroadcastCondition
752 * \sa SDL_SignalCondition
753 * \sa SDL_WaitCondition
754 * \sa SDL_CreateCondition
755 * \sa SDL_DestroyCondition
756 */
757extern DECLSPEC int SDLCALL SDL_WaitConditionTimeout(SDL_Condition *cond,
758 SDL_Mutex *mutex, Sint32 timeoutMS);
759
760/* @} *//* Condition variable functions */
761
762
763/* Ends C function definitions when using C++ */
764#ifdef __cplusplus
765}
766#endif
767#include <SDL3/SDL_close_code.h>
768
769#endif /* SDL_mutex_h_ */
void SDL_DestroyRWLock(SDL_RWLock *rwlock)
int rwlock
Definition: SDL_mutex.h:384
#define SDL_ACQUIRE(x)
Definition: SDL_mutex.h:73
int SDL_TryLockMutex(SDL_Mutex *mutex) SDL_TRY_ACQUIRE(0
#define SDL_TRY_ACQUIRE(x, y)
Definition: SDL_mutex.h:88
SDL_RWLock * SDL_CreateRWLock(void)
void SDL_DestroySemaphore(SDL_Semaphore *sem)
#define SDL_TRY_ACQUIRE_SHARED(x, y)
Definition: SDL_mutex.h:91
#define SDL_ACQUIRE_SHARED(x)
Definition: SDL_mutex.h:76
int SDL_PostSemaphore(SDL_Semaphore *sem)
int SDL_WaitCondition(SDL_Condition *cond, SDL_Mutex *mutex)
int SDL_SignalCondition(SDL_Condition *cond)
int SDL_LockRWLockForWriting(SDL_RWLock *rwlock) SDL_ACQUIRE(rwlock)
struct SDL_Mutex SDL_Mutex
Definition: SDL_mutex.h:137
int SDL_TryLockRWLockForReading(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE_SHARED(0
SDL_Semaphore * SDL_CreateSemaphore(Uint32 initial_value)
int SDL_WaitSemaphoreTimeout(SDL_Semaphore *sem, Sint32 timeoutMS)
int SDL_TryWaitSemaphore(SDL_Semaphore *sem)
Uint32 SDL_GetSemaphoreValue(SDL_Semaphore *sem)
int SDL_LockRWLockForReading(SDL_RWLock *rwlock) SDL_ACQUIRE_SHARED(rwlock)
struct SDL_Semaphore SDL_Semaphore
Definition: SDL_mutex.h:470
int mutex
Definition: SDL_mutex.h:200
int SDL_WaitConditionTimeout(SDL_Condition *cond, SDL_Mutex *mutex, Sint32 timeoutMS)
int SDL_LockMutex(SDL_Mutex *mutex) SDL_ACQUIRE(mutex)
int SDL_UnlockMutex(SDL_Mutex *mutex) SDL_RELEASE(mutex)
int SDL_UnlockRWLock(SDL_RWLock *rwlock) SDL_RELEASE_SHARED(rwlock)
#define SDL_RELEASE_SHARED(x)
Definition: SDL_mutex.h:82
int SDL_BroadcastCondition(SDL_Condition *cond)
struct SDL_RWLock SDL_RWLock
Definition: SDL_mutex.h:250
void SDL_DestroyCondition(SDL_Condition *cond)
void SDL_DestroyMutex(SDL_Mutex *mutex)
SDL_Condition * SDL_CreateCondition(void)
#define SDL_RELEASE(x)
Definition: SDL_mutex.h:79
SDL_Mutex * SDL_CreateMutex(void)
int SDL_WaitSemaphore(SDL_Semaphore *sem)
int SDL_TryLockRWLockForWriting(SDL_RWLock *rwlock) SDL_TRY_ACQUIRE(0
struct SDL_Condition SDL_Condition
Definition: SDL_mutex.h:631
This is a general header that includes C language support.
int32_t Sint32
Definition: SDL_stdinc.h:165
uint32_t Uint32
Definition: SDL_stdinc.h:171