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