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