00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef VLC_THREADS_H_
00029 #define VLC_THREADS_H_
00030
00031
00032
00033
00034
00035
00036
00037 #if defined( UNDER_CE )
00038 #elif defined( WIN32 )
00039 # include <process.h>
00040
00041 #else
00042 # define LIBVLC_USE_PTHREAD 1
00043 # define LIBVLC_USE_PTHREAD_CANCEL 1
00044 # define _APPLE_C_SOURCE 1
00045
00046 # include <unistd.h>
00047 # include <pthread.h>
00048
00049
00050 # if defined (__APPLE__)
00051 # include <mach/semaphore.h>
00052 # include <mach/task.h>
00053 # else
00054 # include <semaphore.h>
00055 # endif
00056
00057 #endif
00058
00059
00060
00061
00062
00063
00064 #ifdef __APPLE__
00065 # define VLC_THREAD_PRIORITY_LOW 0
00066 # define VLC_THREAD_PRIORITY_INPUT 22
00067 # define VLC_THREAD_PRIORITY_AUDIO 22
00068 # define VLC_THREAD_PRIORITY_VIDEO 0
00069 # define VLC_THREAD_PRIORITY_OUTPUT 22
00070 # define VLC_THREAD_PRIORITY_HIGHEST 22
00071
00072 #elif defined(LIBVLC_USE_PTHREAD)
00073 # define VLC_THREAD_PRIORITY_LOW 0
00074 # define VLC_THREAD_PRIORITY_INPUT 10
00075 # define VLC_THREAD_PRIORITY_AUDIO 5
00076 # define VLC_THREAD_PRIORITY_VIDEO 0
00077 # define VLC_THREAD_PRIORITY_OUTPUT 15
00078 # define VLC_THREAD_PRIORITY_HIGHEST 20
00079
00080 #elif defined(WIN32) || defined(UNDER_CE)
00081
00082 # define VLC_THREAD_PRIORITY_LOW 0
00083 # define VLC_THREAD_PRIORITY_INPUT \
00084 THREAD_PRIORITY_ABOVE_NORMAL
00085 # define VLC_THREAD_PRIORITY_AUDIO \
00086 THREAD_PRIORITY_HIGHEST
00087 # define VLC_THREAD_PRIORITY_VIDEO 0
00088 # define VLC_THREAD_PRIORITY_OUTPUT \
00089 THREAD_PRIORITY_ABOVE_NORMAL
00090 # define VLC_THREAD_PRIORITY_HIGHEST \
00091 THREAD_PRIORITY_TIME_CRITICAL
00092
00093 #else
00094 # define VLC_THREAD_PRIORITY_LOW 0
00095 # define VLC_THREAD_PRIORITY_INPUT 0
00096 # define VLC_THREAD_PRIORITY_AUDIO 0
00097 # define VLC_THREAD_PRIORITY_VIDEO 0
00098 # define VLC_THREAD_PRIORITY_OUTPUT 0
00099 # define VLC_THREAD_PRIORITY_HIGHEST 0
00100
00101 #endif
00102
00103
00104
00105
00106
00107 #if defined (LIBVLC_USE_PTHREAD)
00108 typedef pthread_t vlc_thread_t;
00109 typedef pthread_mutex_t vlc_mutex_t;
00110 #define VLC_STATIC_MUTEX PTHREAD_MUTEX_INITIALIZER
00111 typedef pthread_cond_t vlc_cond_t;
00112 #define VLC_STATIC_COND PTHREAD_COND_INITIALIZER
00113 typedef pthread_rwlock_t vlc_rwlock_t;
00114 typedef pthread_key_t vlc_threadvar_t;
00115 typedef struct vlc_timer *vlc_timer_t;
00116
00117 #if defined (__APPLE__)
00118 typedef semaphore_t vlc_sem_t;
00119 #else
00120 typedef sem_t vlc_sem_t;
00121 #endif
00122
00123 #elif defined( WIN32 )
00124 #if !defined( UNDER_CE )
00125 typedef HANDLE vlc_thread_t;
00126 #else
00127 typedef struct
00128 {
00129 HANDLE handle;
00130 HANDLE cancel_event;
00131 } *vlc_thread_t;
00132 #endif
00133
00134 typedef struct
00135 {
00136 bool dynamic;
00137 union
00138 {
00139 struct
00140 {
00141 bool locked;
00142 unsigned long contention;
00143 };
00144 CRITICAL_SECTION mutex;
00145 };
00146 } vlc_mutex_t;
00147 #define VLC_STATIC_MUTEX { false, { { false, 0 } } }
00148
00149 typedef struct
00150 {
00151 HANDLE handle;
00152 unsigned clock;
00153 } vlc_cond_t;
00154
00155 typedef HANDLE vlc_sem_t;
00156
00157 typedef struct
00158 {
00159 vlc_mutex_t mutex;
00160 vlc_cond_t read_wait;
00161 vlc_cond_t write_wait;
00162 unsigned long readers;
00163 unsigned long writers;
00164 DWORD writer;
00165 } vlc_rwlock_t;
00166
00167 typedef DWORD vlc_threadvar_t;
00168 typedef struct vlc_timer *vlc_timer_t;
00169 #endif
00170
00171 #if defined( WIN32 ) && !defined ETIMEDOUT
00172 # define ETIMEDOUT 10060
00173 #endif
00174
00175
00176
00177
00178 VLC_EXPORT( void, vlc_mutex_init, ( vlc_mutex_t * ) );
00179 VLC_EXPORT( void, vlc_mutex_init_recursive, ( vlc_mutex_t * ) );
00180 VLC_EXPORT( void, vlc_mutex_destroy, ( vlc_mutex_t * ) );
00181 VLC_EXPORT( void, vlc_mutex_lock, ( vlc_mutex_t * ) );
00182 VLC_EXPORT( int, vlc_mutex_trylock, ( vlc_mutex_t * ) LIBVLC_USED );
00183 VLC_EXPORT( void, vlc_mutex_unlock, ( vlc_mutex_t * ) );
00184 VLC_EXPORT( void, vlc_cond_init, ( vlc_cond_t * ) );
00185 VLC_EXPORT( void, vlc_cond_init_daytime, ( vlc_cond_t * ) );
00186 VLC_EXPORT( void, vlc_cond_destroy, ( vlc_cond_t * ) );
00187 VLC_EXPORT( void, vlc_cond_signal, (vlc_cond_t *) );
00188 VLC_EXPORT( void, vlc_cond_broadcast, (vlc_cond_t *) );
00189 VLC_EXPORT( void, vlc_cond_wait, (vlc_cond_t *, vlc_mutex_t *) );
00190 VLC_EXPORT( int, vlc_cond_timedwait, (vlc_cond_t *, vlc_mutex_t *, mtime_t) );
00191 VLC_EXPORT( void, vlc_sem_init, (vlc_sem_t *, unsigned) );
00192 VLC_EXPORT( void, vlc_sem_destroy, (vlc_sem_t *) );
00193 VLC_EXPORT( int, vlc_sem_post, (vlc_sem_t *) );
00194 VLC_EXPORT( void, vlc_sem_wait, (vlc_sem_t *) );
00195
00196 VLC_EXPORT( void, vlc_rwlock_init, (vlc_rwlock_t *) );
00197 VLC_EXPORT( void, vlc_rwlock_destroy, (vlc_rwlock_t *) );
00198 VLC_EXPORT( void, vlc_rwlock_rdlock, (vlc_rwlock_t *) );
00199 VLC_EXPORT( void, vlc_rwlock_wrlock, (vlc_rwlock_t *) );
00200 VLC_EXPORT( void, vlc_rwlock_unlock, (vlc_rwlock_t *) );
00201 VLC_EXPORT( int, vlc_threadvar_create, (vlc_threadvar_t * , void (*) (void *) ) );
00202 VLC_EXPORT( void, vlc_threadvar_delete, (vlc_threadvar_t *) );
00203 VLC_EXPORT( int, vlc_threadvar_set, (vlc_threadvar_t, void *) );
00204 VLC_EXPORT( void *, vlc_threadvar_get, (vlc_threadvar_t) );
00205 VLC_EXPORT( int, vlc_thread_create, ( vlc_object_t *, const char *, int, const char *, void * ( * ) ( vlc_object_t * ), int ) LIBVLC_USED );
00206 VLC_EXPORT( int, vlc_thread_set_priority, ( vlc_object_t *, const char *, int, int ) );
00207 VLC_EXPORT( void, vlc_thread_join, ( vlc_object_t * ) );
00208
00209 VLC_EXPORT( int, vlc_clone, (vlc_thread_t *, void * (*) (void *), void *, int) LIBVLC_USED );
00210 VLC_EXPORT( void, vlc_cancel, (vlc_thread_t) );
00211 VLC_EXPORT( void, vlc_join, (vlc_thread_t, void **) );
00212 VLC_EXPORT (void, vlc_control_cancel, (int cmd, ...));
00213
00214 VLC_EXPORT( int, vlc_timer_create, (vlc_timer_t *, void (*) (void *), void *) LIBVLC_USED );
00215 VLC_EXPORT( void, vlc_timer_destroy, (vlc_timer_t) );
00216 VLC_EXPORT( void, vlc_timer_schedule, (vlc_timer_t, bool, mtime_t, mtime_t) );
00217 VLC_EXPORT( unsigned, vlc_timer_getoverrun, (vlc_timer_t) LIBVLC_USED );
00218
00219 #ifndef LIBVLC_USE_PTHREAD_CANCEL
00220 enum {
00221 VLC_CLEANUP_PUSH,
00222 VLC_CLEANUP_POP,
00223 };
00224 #endif
00225
00226 VLC_EXPORT( int, vlc_savecancel, (void) );
00227 VLC_EXPORT( void, vlc_restorecancel, (int state) );
00228 VLC_EXPORT( void, vlc_testcancel, (void) );
00229
00230 #if defined (LIBVLC_USE_PTHREAD_CANCEL)
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 # define vlc_cleanup_push( routine, arg ) pthread_cleanup_push (routine, arg)
00243
00244
00245
00246
00247
00248 # define vlc_cleanup_pop( ) pthread_cleanup_pop (0)
00249
00250
00251
00252
00253
00254 # define vlc_cleanup_run( ) pthread_cleanup_pop (1)
00255 #else
00256 typedef struct vlc_cleanup_t vlc_cleanup_t;
00257
00258 struct vlc_cleanup_t
00259 {
00260 vlc_cleanup_t *next;
00261 void (*proc) (void *);
00262 void *data;
00263 };
00264
00265
00266
00267
00268 # define vlc_cleanup_push( routine, arg ) \
00269 do { \
00270 vlc_cleanup_t vlc_cleanup_data = { NULL, routine, arg, }; \
00271 vlc_control_cancel (VLC_CLEANUP_PUSH, &vlc_cleanup_data)
00272
00273 # define vlc_cleanup_pop( ) \
00274 vlc_control_cancel (VLC_CLEANUP_POP); \
00275 } while (0)
00276
00277 # define vlc_cleanup_run( ) \
00278 vlc_control_cancel (VLC_CLEANUP_POP); \
00279 vlc_cleanup_data.proc (vlc_cleanup_data.data); \
00280 } while (0)
00281
00282 #endif
00283
00284 static inline void vlc_cleanup_lock (void *lock)
00285 {
00286 vlc_mutex_unlock ((vlc_mutex_t *)lock);
00287 }
00288 #define mutex_cleanup_push( lock ) vlc_cleanup_push (vlc_cleanup_lock, lock)
00289
00290 # if defined (_POSIX_SPIN_LOCKS) && ((_POSIX_SPIN_LOCKS - 0) > 0)
00291 typedef pthread_spinlock_t vlc_spinlock_t;
00292
00293
00294
00295
00296 static inline void vlc_spin_init (vlc_spinlock_t *spin)
00297 {
00298 if (pthread_spin_init (spin, PTHREAD_PROCESS_PRIVATE))
00299 abort ();
00300 }
00301
00302
00303
00304
00305 static inline void vlc_spin_lock (vlc_spinlock_t *spin)
00306 {
00307 pthread_spin_lock (spin);
00308 }
00309
00310
00311
00312
00313 static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
00314 {
00315 pthread_spin_unlock (spin);
00316 }
00317
00318
00319
00320
00321 static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
00322 {
00323 pthread_spin_destroy (spin);
00324 }
00325
00326 #elif defined (WIN32) && !defined (UNDER_CE)
00327
00328 typedef CRITICAL_SECTION vlc_spinlock_t;
00329
00330
00331
00332
00333 static inline void vlc_spin_init (vlc_spinlock_t *spin)
00334 {
00335 if (!InitializeCriticalSectionAndSpinCount(spin, 4000))
00336 abort ();
00337 }
00338
00339
00340
00341
00342 static inline void vlc_spin_lock (vlc_spinlock_t *spin)
00343 {
00344 EnterCriticalSection(spin);
00345 }
00346
00347
00348
00349
00350 static inline void vlc_spin_unlock (vlc_spinlock_t *spin)
00351 {
00352 LeaveCriticalSection(spin);
00353 }
00354
00355
00356
00357
00358 static inline void vlc_spin_destroy (vlc_spinlock_t *spin)
00359 {
00360 DeleteCriticalSection(spin);
00361 }
00362
00363 #else
00364
00365
00366 typedef vlc_mutex_t vlc_spinlock_t;
00367
00368 static inline void vlc_spin_init (vlc_spinlock_t *spin)
00369 {
00370 vlc_mutex_init (spin);
00371 }
00372
00373 # define vlc_spin_lock vlc_mutex_lock
00374 # define vlc_spin_unlock vlc_mutex_unlock
00375 # define vlc_spin_destroy vlc_mutex_destroy
00376 #endif
00377
00378
00379
00380
00381 #if defined (__APPLE__)
00382 # include <libkern/OSAtomic.h>
00383 #endif
00384 static inline void barrier (void)
00385 {
00386 #if defined (__GNUC__) && !defined (__APPLE__) && \
00387 ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
00388 __sync_synchronize ();
00389 #elif defined(__APPLE__)
00390 OSMemoryBarrier ();
00391 #elif defined(__powerpc__)
00392 asm volatile ("sync":::"memory");
00393 #elif 0 // defined(__i386__)
00394 asm volatile ("mfence":::"memory");
00395 #else
00396 vlc_spinlock_t spin;
00397 vlc_spin_init (&spin);
00398 vlc_spin_lock (&spin);
00399 vlc_spin_unlock (&spin);
00400 vlc_spin_destroy (&spin);
00401 #endif
00402 }
00403
00404
00405
00406
00407 #define vlc_thread_create( P_THIS, PSZ_NAME, FUNC, PRIORITY ) \
00408 vlc_thread_create( VLC_OBJECT(P_THIS), __FILE__, __LINE__, PSZ_NAME, FUNC, PRIORITY )
00409
00410
00411
00412
00413 #define vlc_thread_set_priority( P_THIS, PRIORITY ) \
00414 vlc_thread_set_priority( VLC_OBJECT(P_THIS), __FILE__, __LINE__, PRIORITY )
00415
00416
00417
00418
00419 #define vlc_thread_join( P_THIS ) \
00420 vlc_thread_join( VLC_OBJECT(P_THIS) )
00421
00422 #ifdef __cplusplus
00423
00424
00425
00426
00427
00428 class vlc_mutex_locker
00429 {
00430 private:
00431 vlc_mutex_t *lock;
00432 public:
00433 vlc_mutex_locker (vlc_mutex_t *m) : lock (m)
00434 {
00435 vlc_mutex_lock (lock);
00436 }
00437
00438 ~vlc_mutex_locker (void)
00439 {
00440 vlc_mutex_unlock (lock);
00441 }
00442 };
00443 #endif
00444
00445 enum {
00446 VLC_AVCODEC_MUTEX = 0,
00447 VLC_GCRYPT_MUTEX,
00448 VLC_XLIB_MUTEX,
00449
00450 VLC_MAX_MUTEX
00451 };
00452
00453 VLC_EXPORT( void, vlc_global_mutex, ( unsigned, bool ) );
00454 #define vlc_global_lock( n ) vlc_global_mutex( n, true )
00455 #define vlc_global_unlock( n ) vlc_global_mutex( n, false )
00456
00457 #endif