VLC 4.0.0-dev
Loading...
Searching...
No Matches
vlc_threads.h
Go to the documentation of this file.
1/*****************************************************************************
2 * vlc_threads.h : threads implementation for the VideoLAN client
3 * This header provides portable declarations for mutexes & conditions
4 *****************************************************************************
5 * Copyright (C) 1999, 2002 VLC authors and VideoLAN
6 * Copyright © 2007-2016 Rémi Denis-Courmont
7 *
8 * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
9 * Samuel Hocevar <sam@via.ecp.fr>
10 * Gildas Bazin <gbazin@netcourrier.com>
11 * Christophe Massiot <massiot@via.ecp.fr>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU Lesser General Public License as published by
15 * the Free Software Foundation; either version 2.1 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 *****************************************************************************/
27
28#ifndef VLC_THREADS_H_
29#define VLC_THREADS_H_
30
31#ifndef __cplusplus
32#include <stdatomic.h>
33#endif
34
35#include <vlc_tick.h>
36
37/**
38 * \ingroup os
39 * \defgroup thread Threads and synchronization primitives
40 * @{
41 * \file
42 * Thread primitive declarations
43 */
44
45/**
46 * Issues an explicit deferred cancellation point.
47 *
48 * This has no effects if thread cancellation is disabled.
49 * This can be called when there is a rather slow non-sleeping operation.
50 * This is also used to force a cancellation point in a function that would
51 * otherwise <em>not always</em> be one (block_FifoGet() is an example).
52 */
53VLC_API void vlc_testcancel(void);
54
55#if defined (_WIN32)
56# include <process.h>
57# ifndef ETIMEDOUT
58# define ETIMEDOUT 10060 /* This is the value in winsock.h. */
59# endif
60
61typedef struct vlc_thread *vlc_thread_t;
62# define VLC_THREAD_CANCELED ((void*) UINTPTR_MAX)
63
64typedef struct vlc_threadvar *vlc_threadvar_t;
65typedef struct vlc_timer *vlc_timer_t;
66
67#elif defined (__OS2__)
68# include <errno.h>
69
70typedef struct vlc_thread *vlc_thread_t;
71#define VLC_THREAD_CANCELED ((void*) UINTPTR_MAX)
72
73typedef struct vlc_threadvar *vlc_threadvar_t;
74typedef struct vlc_timer *vlc_timer_t;
75
76# define pthread_sigmask sigprocmask
77
78#elif defined (__ANDROID__) /* pthreads subset without pthread_cancel() */
79# include <unistd.h>
80# include <pthread.h>
81# include <poll.h>
82# define LIBVLC_USE_PTHREAD_CLEANUP 1
83
84typedef struct vlc_thread *vlc_thread_t;
85#define VLC_THREAD_CANCELED ((void*) UINTPTR_MAX)
86typedef pthread_key_t vlc_threadvar_t;
87typedef struct vlc_timer *vlc_timer_t;
88
89#else /* POSIX threads */
90# include <unistd.h> /* _POSIX_SPIN_LOCKS */
91# include <pthread.h>
92
93/**
94 * Whether LibVLC threads are based on POSIX threads.
95 */
96# define LIBVLC_USE_PTHREAD 1
98/**
99 * Whether LibVLC thread cancellation is based on POSIX threads.
100 */
101# define LIBVLC_USE_PTHREAD_CLEANUP 1
103/**
104 * Thread handle.
105 */
106typedef struct
108 pthread_t handle;
110
111/**
112 * Return value of a canceled thread.
113 */
114#define VLC_THREAD_CANCELED PTHREAD_CANCELED
116/**
117 * Thread-local key handle.
118 *
119 * \ingroup threadvar
120 */
121typedef pthread_key_t vlc_threadvar_t;
123/**
124 * Threaded timer handle.
125 *
126 * \ingroup timer
127 */
128typedef struct vlc_timer *vlc_timer_t;
130#endif
131
132/**
133 * \defgroup mutex Mutual exclusion locks
134 * @{
135 */
136/**
137 * Mutex.
138 *
139 * Storage space for a mutual exclusion lock.
140 */
141typedef struct
143 union {
144#ifndef __cplusplus
145 struct {
146 atomic_uint value;
147 atomic_uint recursion;
148 atomic_ulong owner;
149 };
150#endif
151 struct {
152 unsigned int value;
153 unsigned int recursion;
154 unsigned long owner;
155 } dummy;
156 };
158
159/**
160 * Static initializer for (static) mutex.
161 *
162 * \note This only works in C code.
163 * In C++, consider using a global ::vlc::threads::mutex instance instead.
164 */
165#define VLC_STATIC_MUTEX { \
166 .value = 0, \
167 .recursion = 0, \
168 .owner = 0, \
169}
170
171/**
172 * Initializes a fast mutex.
173 *
174 * Recursive locking of a fast mutex is undefined behaviour. (In debug builds,
175 * recursive locking will cause an assertion failure.)
176 */
178
179/**
180 * Initializes a recursive mutex.
181 * \warning This is strongly discouraged. Please use normal mutexes.
182 */
184
185/**
186 * Acquires a mutex.
187 *
188 * If needed, this waits for any other thread to release it.
189 *
190 * \warning Beware of deadlocks when locking multiple mutexes at the same time,
191 * or when using mutexes from callbacks.
192 *
193 * \note This function is not a cancellation point.
194 */
196
197/**
198 * Tries to acquire a mutex.
199 *
200 * This function acquires the mutex if and only if it is not currently held by
201 * another thread. This function never sleeps and can be used in delay-critical
202 * code paths.
203 *
204 * \note This function is not a cancellation point.
205 *
206 * \warning If this function fails, then the mutex is held... by another
207 * thread. The calling thread must deal with the error appropriately. That
208 * typically implies postponing the operations that would have required the
209 * mutex. If the thread cannot defer those operations, then it must use
210 * vlc_mutex_lock(). If in doubt, use vlc_mutex_lock() instead.
211 *
212 * @return 0 if the mutex could be acquired, an error code otherwise.
213 */
215
216/**
217 * Releases a mutex.
218 *
219 * If the mutex is not held by the calling thread, the behaviour is undefined.
220 *
221 * \note This function is not a cancellation point.
222 */
224
225/**
226 * Checks if a mutex is locked.
227 *
228 * This function checks if the calling thread holds a given mutual exclusion
229 * lock. It has no side effects and is essentially intended for run-time
230 * debugging.
231 *
232 * @note To assert that the calling thread holds a lock, the helper macro
233 * vlc_mutex_assert() should be used instead of this function.
234 *
235 * @note While it is nominally possible to implement recursive lock semantics
236 * with this function, vlc_mutex_init_recursive() should be used instead to
237 * create a recursive mutex explicitly..
238 *
239 * @retval false the mutex is not locked by the calling thread
240 * @retval true the mutex is locked by the calling thread
241 */
243
244/**
245 * Asserts that a mutex is locked by the calling thread.
246 */
247#define vlc_mutex_assert(m) assert(vlc_mutex_held(m))
249/** @} */
250
251/**
252 * \defgroup condvar Condition variables
253 *
254 * The condition variable is the most common and generic mean for threads to
255 * wait for events triggered by other threads.
256 *
257 * See also POSIX @c pthread_cond_t .
258 * @{
259 */
260
261struct vlc_cond_waiter;
262
263/**
264 * Condition variable.
265 *
266 * Storage space for a thread condition variable.
267 */
268typedef struct
274/**
275 * Static initializer for (static) condition variable.
276 */
277#define VLC_STATIC_COND { NULL, VLC_STATIC_MUTEX }
279/**
280 * Initializes a condition variable.
281 */
283
284/**
285 * Wakes up one thread waiting on a condition variable.
286 *
287 * If any thread is currently waiting on the condition variable, at least one
288 * of those threads will be woken up. Otherwise, this function has no effects.
289 *
290 * \note This function is not a cancellation point.
291 */
293
294/**
295 * Wakes up all threads waiting on a condition variable.
296 *
297 * \note This function is not a cancellation point.
298 */
300
301/**
302 * Waits on a condition variable.
303 *
304 * The calling thread will be suspended until another thread calls
305 * vlc_cond_signal() or vlc_cond_broadcast() on the same condition variable,
306 * the thread is cancelled with vlc_cancel(), or the system causes a
307 * <em>spurious</em> unsolicited wake-up.
308 *
309 * A mutex is needed to wait on a condition variable. It must <b>not</b> be
310 * a recursive mutex. Although it is possible to use the same mutex for
311 * multiple condition, it is not valid to use different mutexes for the same
312 * condition variable at the same time from different threads.
313 *
314 * The canonical way to use a condition variable to wait for event foobar is:
315 @code
316 vlc_mutex_lock(&lock);
317
318 while (!foobar)
319 vlc_cond_wait(&wait, &lock);
320
321 // -- foobar is now true, do something about it here --
322
323 vlc_mutex_unlock(&lock);
324 @endcode
325 *
326 * \param cond condition variable to wait on
327 * \param mutex mutex which is unlocked while waiting,
328 * then locked again when waking up.
329 */
330VLC_API void vlc_cond_wait(vlc_cond_t *cond, vlc_mutex_t *mutex);
331
332/**
333 * Waits on a condition variable up to a certain date.
334 *
335 * This works like vlc_cond_wait() but with an additional time-out.
336 * The time-out is expressed as an absolute timestamp using the same arbitrary
337 * time reference as the vlc_tick_now() and vlc_tick_wait() functions.
338 *
339 * \param cond condition variable to wait on
340 * \param mutex mutex which is unlocked while waiting,
341 * then locked again when waking up
342 * \param deadline <b>absolute</b> timeout
343 *
344 * \return 0 if the condition was signaled, an error code in case of timeout.
345 */
347 vlc_tick_t deadline);
348
349/** @} */
350
351/**
352 * \defgroup semaphore Semaphores
353 *
354 * The semaphore is the simplest thread synchronization primitive, consisting
355 * of a simple counter.
356 *
357 * See also POSIX @c sem_t .
358 *
359 * @{
360 */
361/**
362 * Semaphore.
363 *
364 * Storage space for a thread-safe semaphore.
365 */
366typedef struct
368 union {
369#ifndef __cplusplus
370 atomic_uint value;
371#endif
372 int dummy;
373 };
374} vlc_sem_t;
375
376/**
377 * Initializes a semaphore.
378 *
379 * @param sem a semaphore to initialize
380 * @param count initial semaphore value (typically 0)
381 */
382VLC_API void vlc_sem_init(vlc_sem_t *sem, unsigned count);
383
384/**
385 * Increments the value of a semaphore.
386 *
387 * \note This function is not a cancellation point.
388 *
389 * \return 0 on success, EOVERFLOW in case of integer overflow.
390 */
392
393/**
394 * Waits on a semaphore.
395 *
396 * This function atomically waits for the semaphore to become non-zero then
397 * decrements it, and returns. If the semaphore is non-zero on entry, it is
398 * immediately decremented.
399 *
400 * \note This function may be a point of cancellation.
401 */
403
404/**
405 * Tries to decrement a semaphore.
406 *
407 * This function decrements the semaphore if its value is not zero.
408 *
409 * \param sem semaphore to decrement
410 *
411 * \retval 0 the semaphore was decremented
412 * \retval EAGAIN the semaphore was zero and could not be decremented
413 */
415
416/**
417 * Waits on a semaphore within a deadline.
418 *
419 * This function waits for the semaphore just like vlc_sem_wait(), but only
420 * up to a given deadline.
421 *
422 * \param sem semaphore to wait for
423 * \param deadline deadline to wait until
424 *
425 * \retval 0 the semaphore was decremented
426 * \retval ETIMEDOUT the deadline was reached
427 */
429
430/** @} */
431
432#ifndef __cplusplus
433/**
434 * \defgroup latch Latches
435 *
436 * The latch is a downward counter used to synchronise threads.
437 *
438 * @{
439 */
440/**
441 * Latch.
442 *
443 * Storage space for a thread-safe latch.
444 */
445typedef struct
447 atomic_size_t value;
448 atomic_uint ready;
450
451/**
452 * Initializes a latch.
453 *
454 * @param latch a latch instance
455 * @param value initial latch value (typically 1)
456 */
457VLC_API void vlc_latch_init(vlc_latch_t *latch, size_t value);
458
459/**
460 * Decrements the value of a latch.
461 *
462 * This function atomically decrements the value of a latch by the given
463 * quantity. If the result is zero, then any thread waiting on the latch is
464 * woken up.
465 *
466 * \warning If the result is (arithmetically) strictly negative, the behaviour
467 * is undefined.
468 *
469 * \param latch an initialized latch
470 * \param n quantity to subtract from the latch value (typically 1)
471 *
472 * \note This function is not a cancellation point.
473 */
474VLC_API void vlc_latch_count_down(vlc_latch_t *latch, size_t n);
475
476/**
477 * Decrements the value of a latch and waits on it.
478 *
479 * This function atomically decrements the value of a latch by the given
480 * quantity. Then, if the result of the subtraction is strictly positive,
481 * it waits until the value reaches zero.
482 *
483 * This function is equivalent to the succession of vlc_latch_count_down()
484 * then vlc_latch_wait(), and is only an optimisation to combine the two.
485 *
486 * \warning If the result is strictly negative, the behaviour is undefined.
487 *
488 * \param latch an initialized latch
489 * \param n number of times to decrement the value (typically 1)
490 *
491 * \note This function may be a cancellation point.
492 */
494
495/**
496 * Checks if a latch is ready.
497 *
498 * This function compares the value of a latch with zero.
499 *
500 * \retval false if the latch value is non-zero
501 * \retval true if the latch value equals zero
502 */
504
505/**
506 * Waits on a latch.
507 *
508 * This function waits until the value of the latch reaches zero.
509 *
510 * \note This function may be a point of cancellation.
511 */
513
514/** @} */
515
516/**
517 * One-time initialization.
518 *
519 * A one-time initialization object must always be initialized assigned to
520 * \ref VLC_STATIC_ONCE before use.
521 */
522typedef struct
524 atomic_uint value;
526
527/**
528 * Static initializer for one-time initialization.
529 */
530#define VLC_STATIC_ONCE { 0 }
532/**
533 * Begins a one-time initialization.
534 *
535 * This function checks if a one-time initialization has completed:
536 * - If this is the first time the function is called for the given one-time
537 * initialization object, it marks the beginning of the initialization and
538 * returns true. vlc_once_complete() must be called to mark the completion
539 * of the initialisation.
540 * - Otherwise, it waits until the initialization completes and returns false.
541 * - In particular, if the initialization has already completed, the function
542 * returns false immediately without actually waiting.
543 *
544 * The specified one-time initialization object must have been initialized
545 * with @ref VLC_STATIC_ONCE, which is a constant expression suitable as a
546 * static initializer.
547 *
548 * \warning If this function is called twice without an intervening call to
549 * vlc_once_complete(), a dead lock will occur.
550 *
551 * \param once one-time initialisation object
552 * \retval false on the first call (for the given object)
553 * \retval true on subsequent calls (for the given object)
554 */
555VLC_API bool vlc_once_begin(vlc_once_t *restrict once);
556
557static inline bool vlc_once_begin_inline(vlc_once_t *restrict once)
559 /* Fast path: check if already initialized */
560 if (unlikely(atomic_load_explicit(&once->value, memory_order_acquire) < 3))
561 return vlc_once_begin(once);
562 return true;
563}
564#define vlc_once_begin(once) vlc_once_begin_inline(once)
566/**
567 * Completes a one-time initialization.
568 *
569 * This function marks the end of an ongoing one-time initialization.
570 * If any thread is waiting for the completion of that initialization, its
571 * execution will be resumed.
572 *
573 * \warning The behavior is undefined if the one-time initialization object
574 * is uninitialized, if one-time initialization has not started, or
575 * if one-time initialization has already completed.
576 *
577 * \param once one-time initialisation object
578 */
579VLC_API void vlc_once_complete(vlc_once_t *restrict once);
580
581/**
582 * Executes a function one time.
583 *
584 * The first time this function is called with a given one-time initialization
585 * object, it executes the provided callback with the provided data pointer as
586 * sole parameter. Any further call with the same object will be a no-op.
587 *
588 * In the corner case that the first time execution is ongoing in another
589 * thread, then the function will wait for completion on the other thread
590 * (and then synchronize memory) before it returns.
591 * This ensures that, no matter what, the callback has been executed exactly
592 * once and its side effects are visible after the function returns.
593 *
594 * \param once a one-time initialization object
595 * \param cb callback to execute (the first time)
596 * \param opaque data pointer for the callback
597 */
598static inline void vlc_once(vlc_once_t *restrict once, void (*cb)(void *),
599 void *opaque)
600{
601 if (unlikely(!vlc_once_begin(once))) {
602 cb(opaque);
603 vlc_once_complete(once);
604 }
605}
606#endif
607
608/**
609 * \defgroup threadvar Thread-specific variables
610 * @{
611 */
612/**
613 * Allocates a thread-specific variable.
614 *
615 * @param key where to store the thread-specific variable handle
616 * @param destr a destruction callback. It is called whenever a thread exits
617 * and the thread-specific variable has a non-NULL value.
618 *
619 * @return 0 on success, a system error code otherwise.
620 * This function can actually fail: on most systems, there is a fixed limit to
621 * the number of thread-specific variables in a given process.
622 */
623VLC_API int vlc_threadvar_create(vlc_threadvar_t *key, void (*destr) (void *));
624
625/**
626 * Deallocates a thread-specific variable.
627 */
629
630/**
631 * Sets a thread-specific variable.
632
633 * \param key thread-local variable key (created with vlc_threadvar_create())
634 * \param value new value for the variable for the calling thread
635 * \return 0 on success, a system error code otherwise.
636 */
637VLC_API int vlc_threadvar_set(vlc_threadvar_t key, void *value);
638
639/**
640 * Gets the value of a thread-local variable for the calling thread.
641 * This function cannot fail.
642 *
643 * \return the value associated with the given variable for the calling
644 * or NULL if no value was set.
645 */
647
648/** @} */
649
650/**
651 * Creates and starts a new thread.
652 *
653 * The thread must be <i>joined</i> with vlc_join() to reclaim resources
654 * when it is not needed anymore.
655 *
656 * @param th storage space for the handle of the new thread (cannot be NULL)
657 * [OUT]
658 * @param entry entry point for the thread
659 * @param data data parameter given to the entry point
660 * @return 0 on success, a standard error code on error.
661 * @note In case of error, the value of *th is undefined.
662 */
663VLC_API int vlc_clone(vlc_thread_t *th, void *(*entry)(void *),
664 void *data) VLC_USED;
665
666#if defined(__GNUC__)
667static
668VLC_UNUSED_FUNC
669VLC_WARN_CALL("thread name too big")
670const char * vlc_thread_name_too_big( const char * thread_name )
671{
672 return thread_name;
673}
674
675# define check_name_length( thread_name ) \
676 ((__builtin_constant_p(__builtin_strlen(thread_name) > 15) && \
677 __builtin_strlen(thread_name) > 15) \
678 ? vlc_thread_name_too_big(thread_name): thread_name)
679#endif
680
681/**
682 * Set the thread name of the current thread.
683 *
684 * \param name the string to use as the thread name
685 *
686 * \note On Linux the name can be up to 16-byte long, including the terminating
687 * nul character. If larger, the name will be truncated.
688 */
689VLC_API void vlc_thread_set_name(const char *name);
690#if defined(check_name_length)
691# define vlc_thread_set_name(name) vlc_thread_set_name(check_name_length(name))
692#endif
693
694/**
695 * Marks a thread as cancelled.
696 *
697 * Next time the target thread reaches a cancellation point (while not having
698 * disabled cancellation), it will run its cancellation cleanup handler, the
699 * thread variable destructors, and terminate.
700 *
701 * vlc_join() must be used regardless of a thread being cancelled or not, to
702 * avoid leaking resources.
703 */
705
706/**
707 * Waits for a thread to complete (if needed), then destroys it.
708 *
709 * \note This is a cancellation point. In case of cancellation, the thread is
710 * <b>not</b> joined.
711
712 * \warning A thread cannot join itself (normally VLC will abort if this is
713 * attempted).
714 *
715 * @param th thread handle
716 * @param result [OUT] pointer to write the thread return value or NULL
717 */
718VLC_API void vlc_join(vlc_thread_t th, void **result);
719
720/**
721 * Disables thread cancellation.
722 *
723 * This functions saves the current cancellation state (enabled or disabled),
724 * then disables cancellation for the calling thread. It must be called before
725 * entering a piece of code that is not cancellation-safe, unless it can be
726 * proven that the calling thread will not be cancelled.
727 *
728 * \note This function is not a cancellation point.
729 *
730 * \return Previous cancellation state (opaque value for vlc_restorecancel()).
731 */
732VLC_API int vlc_savecancel(void);
733
734/**
735 * Restores the cancellation state.
736 *
737 * This function restores the cancellation state of the calling thread to
738 * a state previously saved by vlc_savecancel().
739 *
740 * \note This function is not a cancellation point.
741 *
742 * \param state previous state as returned by vlc_savecancel().
743 */
745
746typedef struct vlc_cleanup_t vlc_cleanup_t;
748/**
749 * Internal handler for thread cancellation.
750 *
751 * Do not call this function directly. Use wrapper macros instead:
752 * vlc_cleanup_push(), vlc_cleanup_pop().
753 */
755
756/**
757 * Thread identifier.
758 *
759 * This function returns a non-zero unique identifier of the calling thread.
760 * The identifier cannot change for the entire lifetime of the thread, and two
761 * concurrent threads cannot have the same identifier.
762 *
763 * The thread identifier has no defined semantics other than uniqueness,
764 * and no particular purposes within LibVLC.
765 * It is provided mainly for tracing and debugging.
766 *
767 * On some but not all supported platforms, the thread identifier is in fact
768 * the OS/kernel thread identifier (a.k.a. task PID), and is temporally unique
769 * not only within the process but across the entire system.
770 *
771 * \note
772 * The `main()` thread identifier is typically identical to the process
773 * identifier, but this is not portable.
774 *
775 * \return the thread identifier (cannot fail)
776 */
777VLC_API unsigned long vlc_thread_id(void) VLC_USED;
778
779/**
780 * Precision monotonic clock.
781 *
782 * In principles, the clock has a precision of 1 MHz. But the actual resolution
783 * may be much lower, especially when it comes to sleeping with vlc_tick_wait() or
784 * vlc_tick_sleep(). Most general-purpose operating systems provide a resolution of
785 * only 100 to 1000 Hz.
786 *
787 * \warning The origin date (time value "zero") is not specified. It is
788 * typically the time the kernel started, but this is platform-dependent.
789 * If you need wall clock time, use gettimeofday() instead.
790 *
791 * \return a timestamp in microseconds.
792 */
794
795/**
796 * Waits until a deadline.
797 *
798 * \param deadline timestamp to wait for (\ref vlc_tick_now())
799 *
800 * \note The deadline may be exceeded due to OS scheduling.
801 * \note This function is a cancellation point.
802 */
803VLC_API void vlc_tick_wait(vlc_tick_t deadline);
804
805/**
806 * Waits for an interval of time.
807 *
808 * \param delay how long to wait (in microseconds)
809 *
810 * \note The delay may be exceeded due to OS scheduling.
811 * \note This function is a cancellation point.
812 */
814
815#define VLC_HARD_MIN_SLEEP VLC_TICK_FROM_MS(10) /* 10 milliseconds = 1 tick at 100Hz */
816#define VLC_SOFT_MIN_SLEEP VLC_TICK_FROM_SEC(9) /* 9 seconds */
818#if defined(__GNUC__)
819
820/* Linux has 100, 250, 300 or 1000Hz
821 *
822 * HZ=100 by default on FreeBSD, but some architectures use a 1000Hz timer
823 */
824
825static
826VLC_UNUSED_FUNC
827VLC_ERROR_CALL("sorry, cannot sleep for such short a time")
828vlc_tick_t impossible_delay( vlc_tick_t delay )
829{
830 (void) delay;
831 return VLC_HARD_MIN_SLEEP;
832}
833
834static
835VLC_UNUSED_FUNC
836VLC_WARN_CALL("use proper event handling instead of short delay")
837vlc_tick_t harmful_delay( vlc_tick_t delay )
838{
839 return delay;
840}
841
842# define check_delay( d ) \
843 ((__builtin_constant_p(d < VLC_HARD_MIN_SLEEP) \
844 && (d < VLC_HARD_MIN_SLEEP)) \
845 ? impossible_delay(d) \
846 : ((__builtin_constant_p(d < VLC_SOFT_MIN_SLEEP) \
847 && (d < VLC_SOFT_MIN_SLEEP)) \
848 ? harmful_delay(d) \
849 : d))
850
851static
852VLC_UNUSED_FUNC
853VLC_ERROR_CALL("deadlines can not be constant")
854vlc_tick_t impossible_deadline( vlc_tick_t deadline )
855{
856 return deadline;
857}
858
859# define check_deadline( d ) \
860 (__builtin_constant_p(d) ? impossible_deadline(d) : d)
861#endif
862
863#if defined(check_delay)
864#define vlc_tick_sleep(d) vlc_tick_sleep(check_delay(d))
865#endif
866#if defined(check_deadline)
867#define vlc_tick_wait(d) vlc_tick_wait(check_deadline(d))
868#endif
869
870/**
871 * \defgroup timer Asynchronous/threaded timers
872 * @{
873 */
874/**
875 * Initializes an asynchronous timer.
876 *
877 * \param id pointer to timer to be initialized
878 * \param func function that the timer will call
879 * \param data parameter for the timer function
880 * \return 0 on success, a system error code otherwise.
881 *
882 * \warning Asynchronous timers are processed from an unspecified thread.
883 * \note Multiple occurrences of a single interval timer are serialized:
884 * they cannot run concurrently.
885 */
886VLC_API int vlc_timer_create(vlc_timer_t *id, void (*func)(void *), void *data)
888
889/**
890 * Destroys an initialized timer.
891 *
892 * If needed, the timer is first disarmed. Behaviour is undefined if the
893 * specified timer is not initialized.
894 *
895 * \warning This function <b>must</b> be called before the timer data can be
896 * freed and before the timer callback function can be unmapped/unloaded.
897 *
898 * \param timer timer to destroy
899 */
901
902#define VLC_TIMER_DISARM (0)
903#define VLC_TIMER_FIRE_ONCE (0)
905/**
906 * Arms or disarms an initialized timer.
907 *
908 * This functions overrides any previous call to itself.
909 *
910 * \note A timer can fire later than requested due to system scheduling
911 * limitations. An interval timer can fail to trigger sometimes, either because
912 * the system is busy or suspended, or because a previous iteration of the
913 * timer is still running. See also vlc_timer_getoverrun().
914 *
915 * \param timer initialized timer
916 * \param absolute the timer value origin is the same as vlc_tick_now() if true,
917 * the timer value is relative to now if false.
918 * \param value zero to disarm the timer, otherwise the initial time to wait
919 * before firing the timer.
920 * \param interval zero to fire the timer just once, otherwise the timer
921 * repetition interval.
922 */
923VLC_API void vlc_timer_schedule(vlc_timer_t timer, bool absolute,
924 vlc_tick_t value, vlc_tick_t interval);
925
926static inline void vlc_timer_disarm(vlc_timer_t timer)
928 vlc_timer_schedule( timer, false, VLC_TIMER_DISARM, 0 );
929}
930
931static inline void vlc_timer_schedule_asap(vlc_timer_t timer, vlc_tick_t interval)
933 vlc_timer_schedule(timer, false, 1, interval);
934}
935
936/**
937 * Fetches and resets the overrun counter for a timer.
938 *
939 * This functions returns the number of times that the interval timer should
940 * have fired, but the callback was not invoked due to scheduling problems.
941 * The call resets the counter to zero.
942 *
943 * \param timer initialized timer
944 * \return the timer overrun counter (typically zero)
945 */
947
948/** @} */
949
950/**
951 * Count CPUs.
952 *
953 * \return number of available (logical) CPUs.
954 */
955VLC_API unsigned vlc_GetCPUCount(void);
956
957#if defined (LIBVLC_USE_PTHREAD_CLEANUP)
958/**
959 * Registers a thread cancellation handler.
960 *
961 * This pushes a function to run if the thread is cancelled (or otherwise
962 * exits prematurely).
963 *
964 * If multiple procedures are registered,
965 * they are handled in last-in first-out order.
966 *
967 * \note Any call to vlc_cleanup_push() <b>must</b> paired with a call to
968 * vlc_cleanup_pop().
969 * \warning Branching into or out of the block between these two function calls
970 * is not allowed (read: it will likely crash the whole process).
971 *
972 * \param routine procedure to call if the thread ends
973 * \param arg argument for the procedure
974 */
975# define vlc_cleanup_push( routine, arg ) pthread_cleanup_push (routine, arg)
977/**
978 * Unregisters the last cancellation handler.
979 *
980 * This pops the cancellation handler that was last pushed with
981 * vlc_cleanup_push() in the calling thread.
982 */
983# define vlc_cleanup_pop( ) pthread_cleanup_pop (0)
985#else /* !LIBVLC_USE_PTHREAD_CLEANUP */
986struct vlc_cleanup_t
987{
988 vlc_cleanup_t *next;
989 void (*proc) (void *);
990 void *data;
991};
992
993# ifndef __cplusplus
994/* This macros opens a code block on purpose: It reduces the chance of
995 * not pairing the push and pop. It also matches the POSIX Thread internals.
996 * That way, Win32 developers will not accidentally break other platforms.
997 */
998# define vlc_cleanup_push( routine, arg ) \
999 do { \
1000 vlc_control_cancel(&(vlc_cleanup_t){ NULL, routine, arg })
1001
1002# define vlc_cleanup_pop( ) \
1003 vlc_control_cancel (NULL); \
1004 } while (0)
1005# else
1006# define vlc_cleanup_push(routine, arg) \
1007 static_assert(false, "don't use vlc_cleanup_push in portable C++ code")
1008# define vlc_cleanup_pop() \
1009 static_assert(false, "don't use vlc_cleanup_pop in portable C++ code")
1010# endif
1011
1012#endif /* !LIBVLC_USE_PTHREAD_CLEANUP */
1013
1014#ifdef __cplusplus
1015/**
1016 * Helper C++ class to lock a mutex.
1017 *
1018 * The mutex is locked when the object is created, and unlocked when the object
1019 * is destroyed.
1020 */
1021class vlc_mutex_locker
1022{
1023 private:
1025 public:
1026 vlc_mutex_locker (vlc_mutex_t *m) : lock (m)
1027 {
1029 }
1030
1031 ~vlc_mutex_locker (void)
1032 {
1034 }
1035};
1036
1037#endif
1038
1039enum
1040{
1045#ifdef _WIN32
1046 VLC_MTA_MUTEX,
1047#endif
1048 /* Insert new entry HERE */
1050};
1052/**
1053 * Internal handler for global mutexes.
1054 *
1055 * Do not use this function directly. Use helper macros instead:
1056 * vlc_global_lock(), vlc_global_unlock().
1057 */
1058VLC_API void vlc_global_mutex(unsigned, bool);
1059
1060/**
1061 * Acquires a global mutex.
1062 */
1063#define vlc_global_lock( n ) vlc_global_mutex(n, true)
1065/**
1066 * Releases a global mutex.
1067 */
1068#define vlc_global_unlock( n ) vlc_global_mutex(n, false)
1070/** @} */
1071
1072#endif /* !_VLC_THREADS_H */
size_t count
Definition core.c:403
#define VLC_USED
Definition fourcc_gen.c:32
#define VLC_API
Definition fourcc_gen.c:31
#define unlikely(p)
Predicted false condition.
Definition vlc_common.h:246
void vlc_cond_signal(vlc_cond_t *)
Wakes up one thread waiting on a condition variable.
Definition threads.c:193
int vlc_cond_timedwait(vlc_cond_t *cond, vlc_mutex_t *mutex, vlc_tick_t deadline)
Waits on a condition variable up to a certain date.
Definition threads.c:292
void vlc_cond_broadcast(vlc_cond_t *)
Wakes up all threads waiting on a condition variable.
Definition threads.c:220
void vlc_cond_wait(vlc_cond_t *cond, vlc_mutex_t *mutex)
Waits on a condition variable.
Definition threads.c:280
void vlc_cond_init(vlc_cond_t *)
Initializes a condition variable.
Definition threads.c:174
void vlc_latch_count_down(vlc_latch_t *latch, size_t n)
Decrements the value of a latch.
Definition threads.c:420
void vlc_latch_wait(vlc_latch_t *)
Waits on a latch.
Definition threads.c:437
void vlc_latch_count_down_and_wait(vlc_latch_t *latch, size_t n)
Decrements the value of a latch and waits on it.
Definition threads.c:425
bool vlc_latch_is_ready(const vlc_latch_t *latch)
Checks if a latch is ready.
Definition threads.c:431
void vlc_latch_init(vlc_latch_t *latch, size_t value)
Initializes a latch.
Definition threads.c:397
void vlc_mutex_unlock(vlc_mutex_t *)
Releases a mutex.
Definition threads.c:149
void vlc_mutex_init_recursive(vlc_mutex_t *)
Initializes a recursive mutex.
Definition threads.c:80
void vlc_mutex_init(vlc_mutex_t *)
Initializes a fast mutex.
Definition threads.c:75
void vlc_mutex_lock(vlc_mutex_t *)
Acquires a mutex.
Definition threads.c:95
bool vlc_mutex_held(const vlc_mutex_t *)
Checks if a mutex is locked.
Definition threads.c:85
int vlc_mutex_trylock(vlc_mutex_t *)
Tries to acquire a mutex.
Definition threads.c:115
int vlc_sem_timedwait(vlc_sem_t *sem, vlc_tick_t deadline)
Waits on a semaphore within a deadline.
Definition threads.c:360
int vlc_sem_trywait(vlc_sem_t *sem)
Tries to decrement a semaphore.
Definition threads.c:381
void vlc_sem_wait(vlc_sem_t *)
Waits on a semaphore.
Definition threads.c:344
void vlc_sem_init(vlc_sem_t *sem, unsigned count)
Initializes a semaphore.
Definition threads.c:323
int vlc_sem_post(vlc_sem_t *)
Increments the value of a semaphore.
Definition threads.c:328
void vlc_testcancel(void)
Issues an explicit deferred cancellation point.
Definition thread.c:180
void vlc_global_mutex(unsigned, bool)
Internal handler for global mutexes.
Definition threads.c:46
static void vlc_once(vlc_once_t *restrict once, void(*cb)(void *), void *opaque)
Executes a function one time.
Definition vlc_threads.h:599
void vlc_cancel(vlc_thread_t)
Marks a thread as cancelled.
Definition thread.c:156
void vlc_once_complete(vlc_once_t *restrict once)
Completes a one-time initialization.
Definition threads.c:521
void vlc_restorecancel(int state)
Restores the cancellation state.
Definition thread.c:172
unsigned long vlc_thread_id(void)
Thread identifier.
Definition thread.c:30
void vlc_tick_sleep(vlc_tick_t delay)
Waits for an interval of time.
Definition thread.c:222
void vlc_join(vlc_thread_t th, void **result)
Waits for a thread to complete (if needed), then destroys it.
Definition thread.c:146
#define vlc_once_begin(once)
Definition vlc_threads.h:565
int vlc_clone(vlc_thread_t *th, void *(*entry)(void *), void *data)
Creates and starts a new thread.
Definition thread.c:141
unsigned vlc_GetCPUCount(void)
Count CPUs.
Definition thread.c:239
vlc_tick_t vlc_tick_now(void)
Precision monotonic clock.
Definition thread.c:227
void vlc_control_cancel(vlc_cleanup_t *)
Internal handler for thread cancellation.
Definition missing.c:142
#define VLC_HARD_MIN_SLEEP
Definition vlc_threads.h:816
static bool vlc_once_begin_inline(vlc_once_t *restrict once)
Definition vlc_threads.h:558
void vlc_tick_wait(vlc_tick_t deadline)
Waits until a deadline.
Definition thread.c:215
int vlc_savecancel(void)
Disables thread cancellation.
Definition thread.c:162
struct vlc_cleanup_t vlc_cleanup_t
Definition vlc_threads.h:747
void vlc_thread_set_name(const char *name)
Set the thread name of the current thread.
Definition thread.c:28
@ VLC_MAX_MUTEX
Definition vlc_threads.h:1050
@ VLC_GCRYPT_MUTEX
Definition vlc_threads.h:1043
@ VLC_AVCODEC_MUTEX
Definition vlc_threads.h:1042
@ VLC_XLIB_MUTEX
Definition vlc_threads.h:1044
@ VLC_MOSAIC_MUTEX
Definition vlc_threads.h:1045
pthread_key_t vlc_threadvar_t
Thread-local key handle.
Definition vlc_threads.h:122
void * vlc_threadvar_get(vlc_threadvar_t)
Gets the value of a thread-local variable for the calling thread.
Definition thread.c:209
void vlc_threadvar_delete(vlc_threadvar_t *)
Deallocates a thread-specific variable.
Definition thread.c:199
int vlc_threadvar_set(vlc_threadvar_t key, void *value)
Sets a thread-specific variable.
Definition thread.c:204
int vlc_threadvar_create(vlc_threadvar_t *key, void(*destr)(void *))
Allocates a thread-specific variable.
Definition thread.c:194
void vlc_timer_schedule(vlc_timer_t timer, bool absolute, vlc_tick_t value, vlc_tick_t interval)
Arms or disarms an initialized timer.
Definition thread.c:839
struct vlc_timer * vlc_timer_t
Threaded timer handle.
Definition vlc_threads.h:129
static void vlc_timer_disarm(vlc_timer_t timer)
Definition vlc_threads.h:927
#define VLC_TIMER_DISARM
Definition vlc_threads.h:903
unsigned vlc_timer_getoverrun(vlc_timer_t timer)
Fetches and resets the overrun counter for a timer.
Definition thread.c:862
int vlc_timer_create(vlc_timer_t *id, void(*func)(void *), void *data)
Initializes an asynchronous timer.
Definition thread.c:806
static void vlc_timer_schedule_asap(vlc_timer_t timer, vlc_tick_t interval)
Definition vlc_threads.h:932
void vlc_timer_destroy(vlc_timer_t timer)
Destroys an initialized timer.
Definition thread.c:826
const char name[16]
Definition httpd.c:1298
vlc_mutex_t lock
Definition rand.c:33
static thread_local struct @83 state
Definition fourcc_gen.c:52
Condition variable.
Definition vlc_threads.h:270
struct vlc_cond_waiter * head
Definition vlc_threads.h:271
vlc_mutex_t lock
Definition vlc_threads.h:272
Definition threads.c:180
atomic_uint value
Definition threads.c:182
Latch.
Definition vlc_threads.h:447
atomic_uint ready
Definition vlc_threads.h:449
atomic_size_t value
Definition vlc_threads.h:448
Mutex.
Definition vlc_threads.h:143
atomic_uint recursion
Definition vlc_threads.h:148
unsigned int value
Definition vlc_threads.h:153
atomic_uint value
Definition vlc_threads.h:147
atomic_ulong owner
Definition vlc_threads.h:149
unsigned int recursion
Definition vlc_threads.h:154
unsigned long owner
Definition vlc_threads.h:155
One-time initialization.
Definition vlc_threads.h:524
atomic_uint value
Definition vlc_threads.h:525
Semaphore.
Definition vlc_threads.h:368
int dummy
Definition vlc_threads.h:373
atomic_uint value
Definition vlc_threads.h:371
Thread handle.
Definition vlc_threads.h:108
pthread_t handle
Definition vlc_threads.h:109
Definition thread.c:74
Definition thread.c:145
Definition thread.c:775
vlc_tick_t value
Definition timer.c:49
This file is a collection of common definitions and types.
int64_t vlc_tick_t
High precision date or time interval.
Definition vlc_tick.h:48