vlc_threads.h
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:12k
源码类别:

midi

开发平台:

Unix_Linux

  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 the VideoLAN team
  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
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2 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 General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; if not, write to the Free Software
  25.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  26.  *****************************************************************************/
  27. #ifndef VLC_THREADS_H_
  28. #define VLC_THREADS_H_
  29. /**
  30.  * file
  31.  * This file defines structures and functions for handling threads in vlc
  32.  *
  33.  */
  34. #if defined( UNDER_CE )
  35. #   include <errno.h>                                           /* WinCE API */
  36. #elif defined( WIN32 )
  37. #   include <process.h>                                         /* Win32 API */
  38. #   include <errno.h>
  39. #else                                         /* pthreads (like Linux & BSD) */
  40. #   define LIBVLC_USE_PTHREAD 1
  41. #   define LIBVLC_USE_PTHREAD_CANCEL 1
  42. #   define _APPLE_C_SOURCE    1 /* Proper pthread semantics on OSX */
  43. #   include <stdlib.h> /* lldiv_t definition (only in C99) */
  44. #   include <unistd.h> /* _POSIX_SPIN_LOCKS */
  45. #   include <pthread.h>
  46.     /* Needed for pthread_cond_timedwait */
  47. #   include <errno.h>
  48. #   include <time.h>
  49. #endif
  50. /*****************************************************************************
  51.  * Constants
  52.  *****************************************************************************/
  53. /* Thread priorities */
  54. #ifdef __APPLE__
  55. #   define VLC_THREAD_PRIORITY_LOW      0
  56. #   define VLC_THREAD_PRIORITY_INPUT   22
  57. #   define VLC_THREAD_PRIORITY_AUDIO   22
  58. #   define VLC_THREAD_PRIORITY_VIDEO    0
  59. #   define VLC_THREAD_PRIORITY_OUTPUT  22
  60. #   define VLC_THREAD_PRIORITY_HIGHEST 22
  61. #elif defined(LIBVLC_USE_PTHREAD)
  62. #   define VLC_THREAD_PRIORITY_LOW      0
  63. #   define VLC_THREAD_PRIORITY_INPUT   10
  64. #   define VLC_THREAD_PRIORITY_AUDIO    5
  65. #   define VLC_THREAD_PRIORITY_VIDEO    0
  66. #   define VLC_THREAD_PRIORITY_OUTPUT  15
  67. #   define VLC_THREAD_PRIORITY_HIGHEST 20
  68. #elif defined(WIN32) || defined(UNDER_CE)
  69. /* Define different priorities for WinNT/2K/XP and Win9x/Me */
  70. #   define VLC_THREAD_PRIORITY_LOW 0
  71. #   define VLC_THREAD_PRIORITY_INPUT 
  72.         THREAD_PRIORITY_ABOVE_NORMAL
  73. #   define VLC_THREAD_PRIORITY_AUDIO 
  74.         THREAD_PRIORITY_HIGHEST
  75. #   define VLC_THREAD_PRIORITY_VIDEO 0
  76. #   define VLC_THREAD_PRIORITY_OUTPUT 
  77.         THREAD_PRIORITY_ABOVE_NORMAL
  78. #   define VLC_THREAD_PRIORITY_HIGHEST 
  79.         THREAD_PRIORITY_TIME_CRITICAL
  80. #else
  81. #   define VLC_THREAD_PRIORITY_LOW 0
  82. #   define VLC_THREAD_PRIORITY_INPUT 0
  83. #   define VLC_THREAD_PRIORITY_AUDIO 0
  84. #   define VLC_THREAD_PRIORITY_VIDEO 0
  85. #   define VLC_THREAD_PRIORITY_OUTPUT 0
  86. #   define VLC_THREAD_PRIORITY_HIGHEST 0
  87. #endif
  88. /*****************************************************************************
  89.  * Type definitions
  90.  *****************************************************************************/
  91. #if defined (LIBVLC_USE_PTHREAD)
  92. typedef pthread_t       vlc_thread_t;
  93. typedef pthread_mutex_t vlc_mutex_t;
  94. #define VLC_STATIC_MUTEX PTHREAD_MUTEX_INITIALIZER
  95. typedef pthread_cond_t  vlc_cond_t;
  96. typedef pthread_key_t   vlc_threadvar_t;
  97. #elif defined( WIN32 )
  98. typedef struct
  99. {
  100.     HANDLE handle;
  101.     void  *(*entry) (void *);
  102.     void  *data;
  103. #if defined( UNDER_CE )
  104.     HANDLE cancel_event;
  105. #endif
  106. } *vlc_thread_t;
  107. typedef struct
  108. {
  109.     LONG initialized;
  110.     CRITICAL_SECTION mutex;
  111. } vlc_mutex_t;
  112. #define VLC_STATIC_MUTEX { 0, }
  113. typedef HANDLE  vlc_cond_t;
  114. typedef DWORD   vlc_threadvar_t;
  115. #endif
  116. #if defined( WIN32 ) && !defined ETIMEDOUT
  117. #  define ETIMEDOUT 10060 /* This is the value in winsock.h. */
  118. #endif
  119. /*****************************************************************************
  120.  * Function definitions
  121.  *****************************************************************************/
  122. VLC_EXPORT( int,  vlc_mutex_init,    ( vlc_mutex_t * ) );
  123. VLC_EXPORT( int,  vlc_mutex_init_recursive, ( vlc_mutex_t * ) );
  124. VLC_EXPORT( void, vlc_mutex_destroy, ( vlc_mutex_t * ) );
  125. VLC_EXPORT( void, vlc_mutex_lock, ( vlc_mutex_t * ) );
  126. VLC_EXPORT( int, vlc_mutex_trylock, ( vlc_mutex_t * ) );
  127. VLC_EXPORT( void, vlc_mutex_unlock, ( vlc_mutex_t * ) );
  128. VLC_EXPORT( int,  vlc_cond_init,     ( vlc_cond_t * ) );
  129. VLC_EXPORT( void, vlc_cond_destroy,  ( vlc_cond_t * ) );
  130. VLC_EXPORT( void, vlc_cond_signal, (vlc_cond_t *) );
  131. VLC_EXPORT( void, vlc_cond_broadcast, (vlc_cond_t *) );
  132. VLC_EXPORT( void, vlc_cond_wait, (vlc_cond_t *, vlc_mutex_t *) );
  133. VLC_EXPORT( int, vlc_cond_timedwait, (vlc_cond_t *, vlc_mutex_t *, mtime_t) );
  134. VLC_EXPORT( int, vlc_threadvar_create, (vlc_threadvar_t * , void (*) (void *) ) );
  135. VLC_EXPORT( void, vlc_threadvar_delete, (vlc_threadvar_t *) );
  136. VLC_EXPORT( int, vlc_threadvar_set, (vlc_threadvar_t, void *) );
  137. VLC_EXPORT( void *, vlc_threadvar_get, (vlc_threadvar_t) );
  138. VLC_EXPORT( int,  vlc_thread_create, ( vlc_object_t *, const char *, int, const char *, void * ( * ) ( vlc_object_t * ), int ) );
  139. VLC_EXPORT( int,  __vlc_thread_set_priority, ( vlc_object_t *, const char *, int, int ) );
  140. VLC_EXPORT( void, __vlc_thread_join,   ( vlc_object_t * ) );
  141. VLC_EXPORT( int, vlc_clone, (vlc_thread_t *, void * (*) (void *), void *, int) );
  142. VLC_EXPORT( void, vlc_cancel, (vlc_thread_t) );
  143. VLC_EXPORT( void, vlc_join, (vlc_thread_t, void **) );
  144. VLC_EXPORT (void, vlc_control_cancel, (int cmd, ...));
  145. #ifndef LIBVLC_USE_PTHREAD_CANCEL
  146. enum {
  147.     VLC_DO_CANCEL,
  148.     VLC_CLEANUP_PUSH,
  149.     VLC_CLEANUP_POP,
  150. };
  151. #endif
  152. VLC_EXPORT( int, vlc_savecancel, (void) );
  153. VLC_EXPORT( void, vlc_restorecancel, (int state) );
  154. VLC_EXPORT( void, vlc_testcancel, (void) );
  155. #if defined (LIBVLC_USE_PTHREAD_CANCEL)
  156. /**
  157.  * Registers a new procedure to run if the thread is cancelled (or otherwise
  158.  * exits prematurely). Any call to vlc_cleanup_push() <b>must</b> paired with a
  159.  * call to either vlc_cleanup_pop() or vlc_cleanup_run(). Branching into or out
  160.  * of the block between these two function calls is not allowed (read: it will
  161.  * likely crash the whole process). If multiple procedures are registered,
  162.  * they are handled in last-in first-out order.
  163.  *
  164.  * @param routine procedure to call if the thread ends
  165.  * @param arg argument for the procedure
  166.  */
  167. # define vlc_cleanup_push( routine, arg ) pthread_cleanup_push (routine, arg)
  168. /**
  169.  * Removes a cleanup procedure that was previously registered with
  170.  * vlc_cleanup_push().
  171.  */
  172. # define vlc_cleanup_pop( ) pthread_cleanup_pop (0)
  173. /**
  174.  * Removes a cleanup procedure that was previously registered with
  175.  * vlc_cleanup_push(), and executes it.
  176.  */
  177. # define vlc_cleanup_run( ) pthread_cleanup_pop (1)
  178. #else
  179. typedef struct vlc_cleanup_t vlc_cleanup_t;
  180. struct vlc_cleanup_t
  181. {
  182.     vlc_cleanup_t *next;
  183.     void         (*proc) (void *);
  184.     void          *data;
  185. };
  186. /* This macros opens a code block on purpose. This is needed for multiple
  187.  * calls within a single function. This also prevent Win32 developers from
  188.  * writing code that would break on POSIX (POSIX opens a block as well). */
  189. # define vlc_cleanup_push( routine, arg ) 
  190.     do { 
  191.         vlc_cleanup_t vlc_cleanup_data = { NULL, routine, arg, }; 
  192.         vlc_control_cancel (VLC_CLEANUP_PUSH, &vlc_cleanup_data)
  193. # define vlc_cleanup_pop( ) 
  194.         vlc_control_cancel (VLC_CLEANUP_POP); 
  195.     } while (0)
  196. # define vlc_cleanup_run( ) 
  197.         vlc_control_cancel (VLC_CLEANUP_POP); 
  198.         vlc_cleanup_data.proc (vlc_cleanup_data.data); 
  199.     } while (0)
  200. #endif /* LIBVLC_USE_PTHREAD_CANCEL */
  201. static inline void vlc_cleanup_lock (void *lock)
  202. {
  203.     vlc_mutex_unlock ((vlc_mutex_t *)lock);
  204. }
  205. #define mutex_cleanup_push( lock ) vlc_cleanup_push (vlc_cleanup_lock, lock)
  206. # if defined (_POSIX_SPIN_LOCKS) && ((_POSIX_SPIN_LOCKS - 0) > 0)
  207. typedef pthread_spinlock_t vlc_spinlock_t;
  208. /**
  209.  * Initializes a spinlock.
  210.  */
  211. static inline int vlc_spin_init (vlc_spinlock_t *spin)
  212. {
  213.     return pthread_spin_init (spin, PTHREAD_PROCESS_PRIVATE);
  214. }
  215. /**
  216.  * Acquires a spinlock.
  217.  */
  218. static inline void vlc_spin_lock (vlc_spinlock_t *spin)
  219. {
  220.     pthread_spin_lock (spin);
  221. }
  222. /**
  223.  * Releases a spinlock.
  224.  */
  225. static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
  226. {
  227.     pthread_spin_unlock (spin);
  228. }
  229. /**
  230.  * Deinitializes a spinlock.
  231.  */
  232. static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
  233. {
  234.     pthread_spin_destroy (spin);
  235. }
  236. #elif defined( WIN32 )
  237. typedef CRITICAL_SECTION vlc_spinlock_t;
  238. /**
  239.  * Initializes a spinlock.
  240.  */
  241. static inline int vlc_spin_init (vlc_spinlock_t *spin)
  242. {
  243. #ifdef UNDER_CE
  244.     InitializeCriticalSection(spin);
  245.     return 0;
  246. #else
  247.     return !InitializeCriticalSectionAndSpinCount(spin, 4000);
  248. #endif
  249. }
  250. /**
  251.  * Acquires a spinlock.
  252.  */
  253. static inline void vlc_spin_lock (vlc_spinlock_t *spin)
  254. {
  255.     EnterCriticalSection(spin);
  256. }
  257. /**
  258.  * Releases a spinlock.
  259.  */
  260. static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
  261. {
  262.     LeaveCriticalSection(spin);
  263. }
  264. /**
  265.  * Deinitializes a spinlock.
  266.  */
  267. static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
  268. {
  269.     DeleteCriticalSection(spin);
  270. }
  271. #else
  272. /* Fallback to plain mutexes if spinlocks are not available */
  273. typedef vlc_mutex_t vlc_spinlock_t;
  274. static inline int vlc_spin_init (vlc_spinlock_t *spin)
  275. {
  276.     return vlc_mutex_init (spin);
  277. }
  278. # define vlc_spin_lock    vlc_mutex_lock
  279. # define vlc_spin_unlock  vlc_mutex_unlock
  280. # define vlc_spin_destroy vlc_mutex_destroy
  281. #endif
  282. /**
  283.  * Issues a full memory barrier.
  284.  */
  285. #if defined (__APPLE__)
  286. # include <libkern/OSAtomic.h> /* OSMemoryBarrier() */
  287. #endif
  288. static inline void barrier (void)
  289. {
  290. #if defined (__GNUC__) && !defined (__APPLE__) && 
  291.             ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
  292.     __sync_synchronize ();
  293. #elif defined(__APPLE__)
  294.     OSMemoryBarrier ();
  295. #elif defined(__powerpc__)
  296.     asm volatile ("sync":::"memory");
  297. #elif 0 // defined(__i386__) /*  Requires SSE2 support */
  298.     asm volatile ("mfence":::"memory");
  299. #else
  300.     vlc_spinlock_t spin;
  301.     vlc_spin_init (&spin);
  302.     vlc_spin_lock (&spin);
  303.     vlc_spin_unlock (&spin);
  304.     vlc_spin_destroy (&spin);
  305. #endif
  306. }
  307. /*****************************************************************************
  308.  * vlc_thread_create: create a thread
  309.  *****************************************************************************/
  310. #define vlc_thread_create( P_THIS, PSZ_NAME, FUNC, PRIORITY )         
  311.     vlc_thread_create( VLC_OBJECT(P_THIS), __FILE__, __LINE__, PSZ_NAME, FUNC, PRIORITY )
  312. /*****************************************************************************
  313.  * vlc_thread_set_priority: set the priority of the calling thread
  314.  *****************************************************************************/
  315. #define vlc_thread_set_priority( P_THIS, PRIORITY )                         
  316.     __vlc_thread_set_priority( VLC_OBJECT(P_THIS), __FILE__, __LINE__, PRIORITY )
  317. /*****************************************************************************
  318.  * vlc_thread_join: wait until a thread exits
  319.  *****************************************************************************/
  320. #define vlc_thread_join( P_THIS )                                           
  321.     __vlc_thread_join( VLC_OBJECT(P_THIS) )
  322. #ifdef __cplusplus
  323. /**
  324.  * Helper C++ class to lock a mutex.
  325.  * The mutex is locked when the object is created, and unlocked when the object
  326.  * is destroyed.
  327.  */
  328. class vlc_mutex_locker
  329. {
  330.     private:
  331.         vlc_mutex_t *lock;
  332.     public:
  333.         vlc_mutex_locker (vlc_mutex_t *m) : lock (m)
  334.         {
  335.             vlc_mutex_lock (lock);
  336.         }
  337.         ~vlc_mutex_locker (void)
  338.         {
  339.             vlc_mutex_unlock (lock);
  340.         }
  341. };
  342. #endif
  343. #endif /* !_VLC_THREADS_H */