home *** CD-ROM | disk | FTP | other *** search
/ mail.altrad.com / 2015.02.mail.altrad.com.tar / mail.altrad.com / TEST / vlc-2-0-5-win32.exe / sdk / include / vlc / plugins / vlc_threads.h < prev    next >
C/C++ Source or Header  |  2012-12-12  |  16KB  |  559 lines

  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-2008 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. /**
  32.  * \file
  33.  * This file defines structures and functions for handling threads in vlc
  34.  *
  35.  */
  36.  
  37. #if defined( UNDER_CE )
  38. #elif defined( WIN32 )
  39. #   include <process.h>                                         /* Win32 API */
  40.  
  41. #elif defined( __OS2__ )                                        /* OS/2 API  */
  42. #   include <errno.h>
  43.  
  44. #   define pthread_sigmask  sigprocmask
  45.  
  46. #else                                         /* pthreads (like Linux & BSD) */
  47. #   define LIBVLC_USE_PTHREAD 1
  48. #   define LIBVLC_USE_PTHREAD_CANCEL 1
  49. #   define _APPLE_C_SOURCE    1 /* Proper pthread semantics on OSX */
  50.  
  51. #   include <unistd.h> /* _POSIX_SPIN_LOCKS */
  52. #   include <pthread.h>
  53.  
  54. /* Unnamed POSIX semaphores not supported on Mac OS X, use Mach semaphores instead */
  55. #   if defined (__APPLE__)
  56. #      include <mach/semaphore.h>
  57. #      include <mach/task.h>
  58. #   else
  59. #      include <semaphore.h>
  60. #   endif
  61.  
  62. #endif
  63.  
  64. /*****************************************************************************
  65.  * Constants
  66.  *****************************************************************************/
  67.  
  68. /* Thread priorities */
  69. #ifdef __APPLE__
  70. #   define VLC_THREAD_PRIORITY_LOW      0
  71. #   define VLC_THREAD_PRIORITY_INPUT   22
  72. #   define VLC_THREAD_PRIORITY_AUDIO   22
  73. #   define VLC_THREAD_PRIORITY_VIDEO    0
  74. #   define VLC_THREAD_PRIORITY_OUTPUT  22
  75. #   define VLC_THREAD_PRIORITY_HIGHEST 22
  76.  
  77. #elif defined(LIBVLC_USE_PTHREAD)
  78. #   define VLC_THREAD_PRIORITY_LOW      0
  79. #   define VLC_THREAD_PRIORITY_INPUT   10
  80. #   define VLC_THREAD_PRIORITY_AUDIO    5
  81. #   define VLC_THREAD_PRIORITY_VIDEO    0
  82. #   define VLC_THREAD_PRIORITY_OUTPUT  15
  83. #   define VLC_THREAD_PRIORITY_HIGHEST 20
  84.  
  85. #elif defined(WIN32) || defined(UNDER_CE)
  86. /* Define different priorities for WinNT/2K/XP and Win9x/Me */
  87. #   define VLC_THREAD_PRIORITY_LOW 0
  88. #   define VLC_THREAD_PRIORITY_INPUT \
  89.         THREAD_PRIORITY_ABOVE_NORMAL
  90. #   define VLC_THREAD_PRIORITY_AUDIO \
  91.         THREAD_PRIORITY_HIGHEST
  92. #   define VLC_THREAD_PRIORITY_VIDEO 0
  93. #   define VLC_THREAD_PRIORITY_OUTPUT \
  94.         THREAD_PRIORITY_ABOVE_NORMAL
  95. #   define VLC_THREAD_PRIORITY_HIGHEST \
  96.         THREAD_PRIORITY_TIME_CRITICAL
  97.  
  98. #elif defined(__OS2__)
  99. #   define VLC_THREAD_PRIORITY_LOW      0
  100. #   define VLC_THREAD_PRIORITY_INPUT    MAKESHORT( PRTYD_MAXIMUM / 2, PRTYC_REGULAR )
  101. #   define VLC_THREAD_PRIORITY_AUDIO    MAKESHORT( PRTYD_MAXIMUM, PRTYC_REGULAR )
  102. #   define VLC_THREAD_PRIORITY_VIDEO    0
  103. #   define VLC_THREAD_PRIORITY_OUTPUT   MAKESHORT( PRTYD_MAXIMUM / 2, PRTYC_REGULAR )
  104. #   define VLC_THREAD_PRIORITY_HIGHEST  MAKESHORT( 0, PRTYC_TIMECRITICAL )
  105.  
  106. #else
  107. #   define VLC_THREAD_PRIORITY_LOW 0
  108. #   define VLC_THREAD_PRIORITY_INPUT 0
  109. #   define VLC_THREAD_PRIORITY_AUDIO 0
  110. #   define VLC_THREAD_PRIORITY_VIDEO 0
  111. #   define VLC_THREAD_PRIORITY_OUTPUT 0
  112. #   define VLC_THREAD_PRIORITY_HIGHEST 0
  113.  
  114. #endif
  115.  
  116. /*****************************************************************************
  117.  * Type definitions
  118.  *****************************************************************************/
  119.  
  120. #if defined (LIBVLC_USE_PTHREAD)
  121. typedef pthread_t       vlc_thread_t;
  122. typedef pthread_mutex_t vlc_mutex_t;
  123. #define VLC_STATIC_MUTEX PTHREAD_MUTEX_INITIALIZER
  124. typedef pthread_cond_t  vlc_cond_t;
  125. #define VLC_STATIC_COND  PTHREAD_COND_INITIALIZER
  126. typedef pthread_rwlock_t vlc_rwlock_t;
  127. #define VLC_STATIC_RWLOCK PTHREAD_RWLOCK_INITIALIZER
  128. typedef pthread_key_t   vlc_threadvar_t;
  129. typedef struct vlc_timer *vlc_timer_t;
  130.  
  131. #if defined (__APPLE__)
  132. typedef semaphore_t     vlc_sem_t;
  133. #else
  134. typedef sem_t           vlc_sem_t;
  135. #endif
  136.  
  137. #elif defined( WIN32 )
  138. typedef struct vlc_thread *vlc_thread_t;
  139.  
  140. typedef struct
  141. {
  142.     bool dynamic;
  143.     union
  144.     {
  145.         struct
  146.         {
  147.             bool locked;
  148.             unsigned long contention;
  149.         };
  150.         CRITICAL_SECTION mutex;
  151.     };
  152. } vlc_mutex_t;
  153. #define VLC_STATIC_MUTEX { false, { { false, 0 } } }
  154.  
  155. typedef struct
  156. {
  157.     HANDLE   handle;
  158.     unsigned clock;
  159. } vlc_cond_t;
  160. #define VLC_STATIC_COND { 0, 0 }
  161.  
  162. typedef HANDLE  vlc_sem_t;
  163.  
  164. typedef struct
  165. {
  166.     vlc_mutex_t   mutex;
  167.     vlc_cond_t    wait;
  168.     unsigned long readers;
  169.     unsigned long writers;
  170.     DWORD         writer;
  171. } vlc_rwlock_t;
  172. #define VLC_STATIC_RWLOCK \
  173.     { VLC_STATIC_MUTEX, VLC_STATIC_COND, 0, 0, 0 }
  174.  
  175. typedef struct vlc_threadvar *vlc_threadvar_t;
  176. typedef struct vlc_timer *vlc_timer_t;
  177.  
  178. #elif defined( __OS2__ )
  179. typedef struct vlc_thread *vlc_thread_t;
  180.  
  181. typedef struct
  182. {
  183.     bool dynamic;
  184.     union
  185.     {
  186.         struct
  187.         {
  188.             bool locked;
  189.             unsigned long contention;
  190.         };
  191.         HMTX hmtx;
  192.     };
  193. } vlc_mutex_t;
  194.  
  195. #define VLC_STATIC_MUTEX { false, { { false, 0 } } }
  196.  
  197. typedef struct
  198. {
  199.     HEV      hev;
  200.     unsigned clock;
  201. } vlc_cond_t;
  202.  
  203. #define VLC_STATIC_COND { 0, 0 }
  204.  
  205. typedef struct
  206. {
  207.     HEV  hev;
  208.     HMTX wait_mutex;
  209.     HMTX count_mutex;
  210.     int  count;
  211. } vlc_sem_t;
  212.  
  213. typedef struct
  214. {
  215.     vlc_mutex_t   mutex;
  216.     vlc_cond_t    wait;
  217.     unsigned long readers;
  218.     unsigned long writers;
  219.     int           writer;
  220. } vlc_rwlock_t;
  221. #define VLC_STATIC_RWLOCK \
  222.     { VLC_STATIC_MUTEX, VLC_STATIC_COND, 0, 0, 0 }
  223.  
  224. typedef struct vlc_threadvar *vlc_threadvar_t;
  225. typedef struct vlc_timer *vlc_timer_t;
  226.  
  227. #endif
  228.  
  229. #if defined( WIN32 ) && !defined ETIMEDOUT
  230. #  define ETIMEDOUT 10060 /* This is the value in winsock.h. */
  231. #endif
  232.  
  233. /*****************************************************************************
  234.  * Function definitions
  235.  *****************************************************************************/
  236. VLC_API void vlc_mutex_init( vlc_mutex_t * );
  237. VLC_API void vlc_mutex_init_recursive( vlc_mutex_t * );
  238. VLC_API void vlc_mutex_destroy( vlc_mutex_t * );
  239. VLC_API void vlc_mutex_lock( vlc_mutex_t * );
  240. VLC_API int vlc_mutex_trylock( vlc_mutex_t * ) VLC_USED;
  241. VLC_API void vlc_mutex_unlock( vlc_mutex_t * );
  242. VLC_API void vlc_cond_init( vlc_cond_t * );
  243. VLC_API void vlc_cond_init_daytime( vlc_cond_t * );
  244. VLC_API void vlc_cond_destroy( vlc_cond_t * );
  245. VLC_API void vlc_cond_signal(vlc_cond_t *);
  246. VLC_API void vlc_cond_broadcast(vlc_cond_t *);
  247. VLC_API void vlc_cond_wait(vlc_cond_t *, vlc_mutex_t *);
  248. VLC_API int vlc_cond_timedwait(vlc_cond_t *, vlc_mutex_t *, mtime_t);
  249. VLC_API void vlc_sem_init(vlc_sem_t *, unsigned);
  250. VLC_API void vlc_sem_destroy(vlc_sem_t *);
  251. VLC_API int vlc_sem_post(vlc_sem_t *);
  252. VLC_API void vlc_sem_wait(vlc_sem_t *);
  253.  
  254. VLC_API void vlc_rwlock_init(vlc_rwlock_t *);
  255. VLC_API void vlc_rwlock_destroy(vlc_rwlock_t *);
  256. VLC_API void vlc_rwlock_rdlock(vlc_rwlock_t *);
  257. VLC_API void vlc_rwlock_wrlock(vlc_rwlock_t *);
  258. VLC_API void vlc_rwlock_unlock(vlc_rwlock_t *);
  259. VLC_API int vlc_threadvar_create(vlc_threadvar_t * , void (*) (void *) );
  260. VLC_API void vlc_threadvar_delete(vlc_threadvar_t *);
  261. VLC_API int vlc_threadvar_set(vlc_threadvar_t, void *);
  262. VLC_API void * vlc_threadvar_get(vlc_threadvar_t);
  263.  
  264. VLC_API int vlc_clone(vlc_thread_t *, void * (*) (void *), void *, int) VLC_USED;
  265. VLC_API void vlc_cancel(vlc_thread_t);
  266. VLC_API void vlc_join(vlc_thread_t, void **);
  267. VLC_API void vlc_control_cancel (int cmd, ...);
  268.  
  269. VLC_API mtime_t mdate(void);
  270. VLC_API void mwait(mtime_t deadline);
  271. VLC_API void msleep(mtime_t delay);
  272.  
  273. #define VLC_HARD_MIN_SLEEP   10000 /* 10 milliseconds = 1 tick at 100Hz */
  274. #define VLC_SOFT_MIN_SLEEP 9000000 /* 9 seconds */
  275.  
  276. #if VLC_GCC_VERSION(4,3)
  277. /* Linux has 100, 250, 300 or 1000Hz
  278.  *
  279.  * HZ=100 by default on FreeBSD, but some architectures use a 1000Hz timer
  280.  */
  281.  
  282. static
  283. __attribute__((unused))
  284. __attribute__((noinline))
  285. __attribute__((error("sorry, cannot sleep for such short a time")))
  286. mtime_t impossible_delay( mtime_t delay )
  287. {
  288.     (void) delay;
  289.     return VLC_HARD_MIN_SLEEP;
  290. }
  291.  
  292. static
  293. __attribute__((unused))
  294. __attribute__((noinline))
  295. __attribute__((warning("use proper event handling instead of short delay")))
  296. mtime_t harmful_delay( mtime_t delay )
  297. {
  298.     return delay;
  299. }
  300.  
  301. # define check_delay( d ) \
  302.     ((__builtin_constant_p(d < VLC_HARD_MIN_SLEEP) \
  303.    && (d < VLC_HARD_MIN_SLEEP)) \
  304.        ? impossible_delay(d) \
  305.        : ((__builtin_constant_p(d < VLC_SOFT_MIN_SLEEP) \
  306.        && (d < VLC_SOFT_MIN_SLEEP)) \
  307.            ? harmful_delay(d) \
  308.            : d))
  309.  
  310. static
  311. __attribute__((unused))
  312. __attribute__((noinline))
  313. __attribute__((error("deadlines can not be constant")))
  314. mtime_t impossible_deadline( mtime_t deadline )
  315. {
  316.     return deadline;
  317. }
  318.  
  319. # define check_deadline( d ) \
  320.     (__builtin_constant_p(d) ? impossible_deadline(d) : d)
  321. #else
  322. # define check_delay(d) (d)
  323. # define check_deadline(d) (d)
  324. #endif
  325.  
  326. #define msleep(d) msleep(check_delay(d))
  327. #define mwait(d) mwait(check_deadline(d))
  328.  
  329. VLC_API int vlc_timer_create(vlc_timer_t *, void (*) (void *), void *) VLC_USED;
  330. VLC_API void vlc_timer_destroy(vlc_timer_t);
  331. VLC_API void vlc_timer_schedule(vlc_timer_t, bool, mtime_t, mtime_t);
  332. VLC_API unsigned vlc_timer_getoverrun(vlc_timer_t) VLC_USED;
  333.  
  334. VLC_API unsigned vlc_GetCPUCount(void);
  335.  
  336. #ifndef LIBVLC_USE_PTHREAD_CANCEL
  337. enum {
  338.     VLC_CLEANUP_PUSH,
  339.     VLC_CLEANUP_POP,
  340. };
  341. #endif
  342.  
  343. VLC_API int vlc_savecancel(void);
  344. VLC_API void vlc_restorecancel(int state);
  345. VLC_API void vlc_testcancel(void);
  346.  
  347. #if defined (LIBVLC_USE_PTHREAD_CANCEL)
  348. /**
  349.  * Registers a new procedure to run if the thread is cancelled (or otherwise
  350.  * exits prematurely). Any call to vlc_cleanup_push() <b>must</b> paired with a
  351.  * call to either vlc_cleanup_pop() or vlc_cleanup_run(). Branching into or out
  352.  * of the block between these two function calls is not allowed (read: it will
  353.  * likely crash the whole process). If multiple procedures are registered,
  354.  * they are handled in last-in first-out order.
  355.  *
  356.  * @param routine procedure to call if the thread ends
  357.  * @param arg argument for the procedure
  358.  */
  359. # define vlc_cleanup_push( routine, arg ) pthread_cleanup_push (routine, arg)
  360.  
  361. /**
  362.  * Removes a cleanup procedure that was previously registered with
  363.  * vlc_cleanup_push().
  364.  */
  365. # define vlc_cleanup_pop( ) pthread_cleanup_pop (0)
  366.  
  367. /**
  368.  * Removes a cleanup procedure that was previously registered with
  369.  * vlc_cleanup_push(), and executes it.
  370.  */
  371. # define vlc_cleanup_run( ) pthread_cleanup_pop (1)
  372. #else
  373. typedef struct vlc_cleanup_t vlc_cleanup_t;
  374.  
  375. struct vlc_cleanup_t
  376. {
  377.     vlc_cleanup_t *next;
  378.     void         (*proc) (void *);
  379.     void          *data;
  380. };
  381.  
  382. /* This macros opens a code block on purpose. This is needed for multiple
  383.  * calls within a single function. This also prevent Win32 developers from
  384.  * writing code that would break on POSIX (POSIX opens a block as well). */
  385. # define vlc_cleanup_push( routine, arg ) \
  386.     do { \
  387.         vlc_cleanup_t vlc_cleanup_data = { NULL, routine, arg, }; \
  388.         vlc_control_cancel (VLC_CLEANUP_PUSH, &vlc_cleanup_data)
  389.  
  390. # define vlc_cleanup_pop( ) \
  391.         vlc_control_cancel (VLC_CLEANUP_POP); \
  392.     } while (0)
  393.  
  394. # define vlc_cleanup_run( ) \
  395.         vlc_control_cancel (VLC_CLEANUP_POP); \
  396.         vlc_cleanup_data.proc (vlc_cleanup_data.data); \
  397.     } while (0)
  398.  
  399. #endif /* LIBVLC_USE_PTHREAD_CANCEL */
  400.  
  401. static inline void vlc_cleanup_lock (void *lock)
  402. {
  403.     vlc_mutex_unlock ((vlc_mutex_t *)lock);
  404. }
  405. #define mutex_cleanup_push( lock ) vlc_cleanup_push (vlc_cleanup_lock, lock)
  406.  
  407. # if defined (_POSIX_SPIN_LOCKS) && ((_POSIX_SPIN_LOCKS - 0) > 0)
  408. typedef pthread_spinlock_t vlc_spinlock_t;
  409.  
  410. /**
  411.  * Initializes a spinlock.
  412.  */
  413. static inline void vlc_spin_init (vlc_spinlock_t *spin)
  414. {
  415.     if (pthread_spin_init (spin, PTHREAD_PROCESS_PRIVATE))
  416.         abort ();
  417. }
  418.  
  419. /**
  420.  * Acquires a spinlock.
  421.  */
  422. static inline void vlc_spin_lock (vlc_spinlock_t *spin)
  423. {
  424.     pthread_spin_lock (spin);
  425. }
  426.  
  427. /**
  428.  * Releases a spinlock.
  429.  */
  430. static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
  431. {
  432.     pthread_spin_unlock (spin);
  433. }
  434.  
  435. /**
  436.  * Deinitializes a spinlock.
  437.  */
  438. static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
  439. {
  440.     pthread_spin_destroy (spin);
  441. }
  442.  
  443. #elif defined (WIN32) && !defined (UNDER_CE)
  444.  
  445. typedef CRITICAL_SECTION vlc_spinlock_t;
  446.  
  447. /**
  448.  * Initializes a spinlock.
  449.  */
  450. static inline void vlc_spin_init (vlc_spinlock_t *spin)
  451. {
  452.     if (!InitializeCriticalSectionAndSpinCount(spin, 4000))
  453.         abort ();
  454. }
  455.  
  456. /**
  457.  * Acquires a spinlock.
  458.  */
  459. static inline void vlc_spin_lock (vlc_spinlock_t *spin)
  460. {
  461.     EnterCriticalSection(spin);
  462. }
  463.  
  464. /**
  465.  * Releases a spinlock.
  466.  */
  467. static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
  468. {
  469.     LeaveCriticalSection(spin);
  470. }
  471.  
  472. /**
  473.  * Deinitializes a spinlock.
  474.  */
  475. static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
  476. {
  477.     DeleteCriticalSection(spin);
  478. }
  479.  
  480. #else
  481.  
  482. /* Fallback to plain mutexes if spinlocks are not available */
  483. typedef vlc_mutex_t vlc_spinlock_t;
  484.  
  485. static inline void vlc_spin_init (vlc_spinlock_t *spin)
  486. {
  487.     vlc_mutex_init (spin);
  488. }
  489.  
  490. # define vlc_spin_lock    vlc_mutex_lock
  491. # define vlc_spin_unlock  vlc_mutex_unlock
  492. # define vlc_spin_destroy vlc_mutex_destroy
  493. #endif
  494.  
  495. /**
  496.  * Issues a full memory barrier.
  497.  */
  498. #if defined (__APPLE__)
  499. # include <libkern/OSAtomic.h> /* OSMemoryBarrier() */
  500. #endif
  501. static inline void barrier (void)
  502. {
  503. #if defined (__GNUC__) && !defined (__APPLE__) && \
  504.             ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
  505.     __sync_synchronize ();
  506. #elif defined(__APPLE__)
  507.     OSMemoryBarrier ();
  508. #elif defined(__powerpc__)
  509.     asm volatile ("sync":::"memory");
  510. #elif 0 // defined(__i386__) /*  Requires SSE2 support */
  511.     asm volatile ("mfence":::"memory");
  512. #else
  513.     vlc_spinlock_t spin;
  514.     vlc_spin_init (&spin);
  515.     vlc_spin_lock (&spin);
  516.     vlc_spin_unlock (&spin);
  517.     vlc_spin_destroy (&spin);
  518. #endif
  519. }
  520.  
  521. #ifdef __cplusplus
  522. /**
  523.  * Helper C++ class to lock a mutex.
  524.  * The mutex is locked when the object is created, and unlocked when the object
  525.  * is destroyed.
  526.  */
  527. class vlc_mutex_locker
  528. {
  529.     private:
  530.         vlc_mutex_t *lock;
  531.     public:
  532.         vlc_mutex_locker (vlc_mutex_t *m) : lock (m)
  533.         {
  534.             vlc_mutex_lock (lock);
  535.         }
  536.  
  537.         ~vlc_mutex_locker (void)
  538.         {
  539.             vlc_mutex_unlock (lock);
  540.         }
  541. };
  542. #endif
  543.  
  544. enum {
  545.    VLC_AVCODEC_MUTEX = 0,
  546.    VLC_GCRYPT_MUTEX,
  547.    VLC_XLIB_MUTEX,
  548.    VLC_MOSAIC_MUTEX,
  549.    VLC_HIGHLIGHT_MUTEX,
  550.    /* Insert new entry HERE */
  551.    VLC_MAX_MUTEX
  552. };
  553.  
  554. VLC_API void vlc_global_mutex( unsigned, bool );
  555. #define vlc_global_lock( n ) vlc_global_mutex( n, true )
  556. #define vlc_global_unlock( n ) vlc_global_mutex( n, false )
  557.  
  558. #endif /* !_VLC_THREADS_H */
  559.