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