Changeset 707279b40c386c8a16e1f894db2141a93f647a96

Show
Ignore:
Timestamp:
05/08/08 21:08:13 (2 months ago)
Author:
Rémi Denis-Courmont <rem@videolan.org>
git-committer:
Rémi Denis-Courmont <rem@videolan.org> 1210273693 +0300
git-parent:

[4c35dd214785bd12d7cf7b8489ae838cfb6cd633]

git-author:
Rémi Denis-Courmont <rem@videolan.org> 1210273655 +0300
Message:

Merge vlc_threads.h and vlc_threads_funcs.h

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/vlc_common.h

    re66ff92 r707279b  
    931931#include "vlc_objects.h" 
    932932#include "vlc_mtime.h" 
    933 #include "vlc_threads_funcs.h" 
    934933#include "vlc_modules.h" 
    935934#include "vlc_main.h" 
  • include/vlc_threads.h

    rde2b458 r707279b  
    113113 *****************************************************************************/ 
    114114 
    115 #if defined( WIN32 ) || defined( UNDER_CE ) 
     115#if defined (LIBVLC_USE_PTHREAD) 
     116typedef pthread_t       vlc_thread_t; 
     117typedef pthread_mutex_t vlc_mutex_t; 
     118typedef pthread_cond_t  vlc_cond_t; 
     119typedef pthread_key_t   vlc_threadvar_t; 
     120 
     121#elif defined( WIN32 ) || defined( UNDER_CE ) 
    116122typedef struct 
    117123{ 
     
    160166} vlc_threadvar_t; 
    161167 
    162  
     168#endif 
     169 
     170#if defined( WIN32 ) && !defined ETIMEDOUT 
     171#  define ETIMEDOUT 10060 /* This is the value in winsock.h. */ 
     172#endif 
     173 
     174/***************************************************************************** 
     175 * Function definitions 
     176 *****************************************************************************/ 
     177VLC_EXPORT( int,  vlc_mutex_init,    ( vlc_mutex_t * ) ); 
     178VLC_EXPORT( int,  vlc_mutex_init_recursive, ( vlc_mutex_t * ) ); 
     179VLC_EXPORT( void,  __vlc_mutex_destroy, ( const char *, int, vlc_mutex_t * ) ); 
     180VLC_EXPORT( int,  __vlc_cond_init,     ( vlc_cond_t * ) ); 
     181VLC_EXPORT( void,  __vlc_cond_destroy,  ( const char *, int, vlc_cond_t * ) ); 
     182VLC_EXPORT( int, __vlc_threadvar_create, (vlc_threadvar_t * ) ); 
     183VLC_EXPORT( int,  __vlc_thread_create, ( vlc_object_t *, const char *, int, const char *, void * ( * ) ( void * ), int, bool ) ); 
     184VLC_EXPORT( int,  __vlc_thread_set_priority, ( vlc_object_t *, const char *, int, int ) ); 
     185VLC_EXPORT( void, __vlc_thread_ready,  ( vlc_object_t * ) ); 
     186VLC_EXPORT( void, __vlc_thread_join,   ( vlc_object_t *, const char *, int ) ); 
     187 
     188/***************************************************************************** 
     189 * vlc_mutex_lock: lock a mutex 
     190 *****************************************************************************/ 
     191#define vlc_mutex_lock( P_MUTEX )                                           \ 
     192    __vlc_mutex_lock( __FILE__, __LINE__, P_MUTEX ) 
     193 
     194#if defined(LIBVLC_USE_PTHREAD) 
     195VLC_EXPORT(void, vlc_pthread_fatal, (const char *action, int error, const char *file, unsigned line)); 
     196 
     197# define VLC_THREAD_ASSERT( action ) \ 
     198    if (val) \ 
     199        vlc_pthread_fatal (action, val, psz_file, i_line) 
    163200#else 
    164 typedef pthread_t       vlc_thread_t; 
    165 typedef pthread_mutex_t vlc_mutex_t; 
    166 typedef pthread_cond_t  vlc_cond_t; 
    167 typedef pthread_key_t   vlc_threadvar_t; 
    168  
    169 #endif 
     201# define VLC_THREAD_ASSERT (void)0 
     202#endif 
     203 
     204static inline void __vlc_mutex_lock( const char * psz_file, int i_line, 
     205                                    vlc_mutex_t * p_mutex ) 
     206
     207#if defined(LIBVLC_USE_PTHREAD) 
     208#   define vlc_assert_locked( m ) \ 
     209           assert (pthread_mutex_lock (m) == EDEADLK) 
     210    int val = pthread_mutex_lock( p_mutex ); 
     211    VLC_THREAD_ASSERT ("locking mutex"); 
     212 
     213#elif defined( UNDER_CE ) 
     214    VLC_UNUSED( psz_file); VLC_UNUSED( i_line ); 
     215 
     216    EnterCriticalSection( &p_mutex->csection ); 
     217 
     218#elif defined( WIN32 ) 
     219    VLC_UNUSED( psz_file); VLC_UNUSED( i_line ); 
     220 
     221    WaitForSingleObject( *p_mutex, INFINITE ); 
     222 
     223#elif defined( HAVE_KERNEL_SCHEDULER_H ) 
     224    acquire_sem( p_mutex->lock ); 
     225 
     226#endif 
     227
     228 
     229#ifndef vlc_assert_locked 
     230# define vlc_assert_locked( m ) (void)0 
     231#endif 
     232 
     233/***************************************************************************** 
     234 * vlc_mutex_unlock: unlock a mutex 
     235 *****************************************************************************/ 
     236#define vlc_mutex_unlock( P_MUTEX )                                         \ 
     237    __vlc_mutex_unlock( __FILE__, __LINE__, P_MUTEX ) 
     238 
     239static inline void __vlc_mutex_unlock( const char * psz_file, int i_line, 
     240                                      vlc_mutex_t *p_mutex ) 
     241
     242#if defined(LIBVLC_USE_PTHREAD) 
     243    int val = pthread_mutex_unlock( p_mutex ); 
     244    VLC_THREAD_ASSERT ("unlocking mutex"); 
     245 
     246#elif defined( UNDER_CE ) 
     247    VLC_UNUSED( psz_file); VLC_UNUSED( i_line ); 
     248 
     249    LeaveCriticalSection( &p_mutex->csection ); 
     250 
     251#elif defined( WIN32 ) 
     252    VLC_UNUSED( psz_file); VLC_UNUSED( i_line ); 
     253 
     254    ReleaseMutex( *p_mutex ); 
     255 
     256#elif defined( HAVE_KERNEL_SCHEDULER_H ) 
     257    release_sem( p_mutex->lock ); 
     258 
     259#endif 
     260
     261 
     262/***************************************************************************** 
     263 * vlc_mutex_destroy: destroy a mutex 
     264 *****************************************************************************/ 
     265#define vlc_mutex_destroy( P_MUTEX )                                        \ 
     266    __vlc_mutex_destroy( __FILE__, __LINE__, P_MUTEX ) 
     267 
     268/***************************************************************************** 
     269 * vlc_cond_init: initialize a condition 
     270 *****************************************************************************/ 
     271#define vlc_cond_init( P_THIS, P_COND )                                     \ 
     272    __vlc_cond_init( P_COND ) 
     273 
     274/***************************************************************************** 
     275 * vlc_cond_signal: start a thread on condition completion 
     276 *****************************************************************************/ 
     277#define vlc_cond_signal( P_COND )                                           \ 
     278    __vlc_cond_signal( __FILE__, __LINE__, P_COND ) 
     279 
     280static inline void __vlc_cond_signal( const char * psz_file, int i_line, 
     281                                      vlc_cond_t *p_condvar ) 
     282
     283#if defined(LIBVLC_USE_PTHREAD) 
     284    int val = pthread_cond_signal( p_condvar ); 
     285    VLC_THREAD_ASSERT ("signaling condition variable"); 
     286 
     287#elif defined( UNDER_CE ) || defined( WIN32 ) 
     288    VLC_UNUSED( psz_file); VLC_UNUSED( i_line ); 
     289 
     290    /* Release one waiting thread if one is available. */ 
     291    /* For this trick to work properly, the vlc_cond_signal must be surrounded 
     292     * by a mutex. This will prevent another thread from stealing the signal */ 
     293    /* PulseEvent() only works if none of the waiting threads is suspended. 
     294     * This is particularily problematic under a debug session. 
     295     * as documented in http://support.microsoft.com/kb/q173260/ */ 
     296    PulseEvent( p_condvar->event ); 
     297 
     298#elif defined( HAVE_KERNEL_SCHEDULER_H ) 
     299    while( p_condvar->thread != -1 ) 
     300    { 
     301        thread_info info; 
     302        if( get_thread_info(p_condvar->thread, &info) == B_BAD_VALUE ) 
     303            return; 
     304 
     305        if( info.state != B_THREAD_SUSPENDED ) 
     306        { 
     307            /* The  waiting thread is not suspended so it could 
     308             * have been interrupted beetwen the unlock and the 
     309             * suspend_thread line. That is why we sleep a little 
     310             * before retesting p_condver->thread. */ 
     311            snooze( 10000 ); 
     312        } 
     313        else 
     314        { 
     315            /* Ok, we have to wake up that thread */ 
     316            resume_thread( p_condvar->thread ); 
     317        } 
     318    } 
     319 
     320#endif 
     321
     322 
     323/***************************************************************************** 
     324 * vlc_cond_wait: wait until condition completion 
     325 *****************************************************************************/ 
     326#define vlc_cond_wait( P_COND, P_MUTEX )                                     \ 
     327    __vlc_cond_wait( __FILE__, __LINE__, P_COND, P_MUTEX  ) 
     328 
     329static inline void __vlc_cond_wait( const char * psz_file, int i_line, 
     330                                    vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex ) 
     331
     332#if defined(LIBVLC_USE_PTHREAD) 
     333    int val = pthread_cond_wait( p_condvar, p_mutex ); 
     334    VLC_THREAD_ASSERT ("waiting on condition"); 
     335 
     336#elif defined( UNDER_CE ) 
     337    p_condvar->i_waiting_threads++; 
     338    LeaveCriticalSection( &p_mutex->csection ); 
     339    WaitForSingleObject( p_condvar->event, INFINITE ); 
     340    p_condvar->i_waiting_threads--; 
     341 
     342    /* Reacquire the mutex before returning. */ 
     343    vlc_mutex_lock( p_mutex ); 
     344 
     345#elif defined( WIN32 ) 
     346    VLC_UNUSED( psz_file); VLC_UNUSED( i_line ); 
     347 
     348    /* Increase our wait count */ 
     349    p_condvar->i_waiting_threads++; 
     350    SignalObjectAndWait( *p_mutex, p_condvar->event, INFINITE, FALSE ); 
     351    p_condvar->i_waiting_threads--; 
     352 
     353    /* Reacquire the mutex before returning. */ 
     354    vlc_mutex_lock( p_mutex ); 
     355 
     356#elif defined( HAVE_KERNEL_SCHEDULER_H ) 
     357    /* The p_condvar->thread var is initialized before the unlock because 
     358     * it enables to identify when the thread is interrupted beetwen the 
     359     * unlock line and the suspend_thread line */ 
     360    p_condvar->thread = find_thread( NULL ); 
     361    vlc_mutex_unlock( p_mutex ); 
     362    suspend_thread( p_condvar->thread ); 
     363    p_condvar->thread = -1; 
     364 
     365    vlc_mutex_lock( p_mutex ); 
     366 
     367#endif 
     368
     369 
     370 
     371/***************************************************************************** 
     372 * vlc_cond_timedwait: wait until condition completion or expiration 
     373 ***************************************************************************** 
     374 * Returns 0 if object signaled, an error code in case of timeout or error. 
     375 *****************************************************************************/ 
     376#define vlc_cond_timedwait( P_COND, P_MUTEX, DEADLINE )                      \ 
     377    __vlc_cond_timedwait( __FILE__, __LINE__, P_COND, P_MUTEX, DEADLINE  ) 
     378 
     379static inline int __vlc_cond_timedwait( const char * psz_file, int i_line, 
     380                                        vlc_cond_t *p_condvar, 
     381                                        vlc_mutex_t *p_mutex, 
     382                                        mtime_t deadline ) 
     383
     384#if defined(LIBVLC_USE_PTHREAD) 
     385    lldiv_t d = lldiv( deadline, 1000000 ); 
     386    struct timespec ts = { d.quot, d.rem * 1000 }; 
     387 
     388    int val = pthread_cond_timedwait (p_condvar, p_mutex, &ts); 
     389    if (val == ETIMEDOUT) 
     390        return ETIMEDOUT; /* this error is perfectly normal */ 
     391    VLC_THREAD_ASSERT ("timed-waiting on condition"); 
     392 
     393#elif defined( UNDER_CE ) 
     394    mtime_t delay_ms = (deadline - mdate())/1000; 
     395 
     396    DWORD result; 
     397    if( delay_ms < 0 ) 
     398        delay_ms = 0; 
     399 
     400    p_condvar->i_waiting_threads++; 
     401    LeaveCriticalSection( &p_mutex->csection ); 
     402    result = WaitForSingleObject( p_condvar->event, delay_ms ); 
     403    p_condvar->i_waiting_threads--; 
     404 
     405    /* Reacquire the mutex before returning. */ 
     406    vlc_mutex_lock( p_mutex ); 
     407 
     408    if(result == WAIT_TIMEOUT) 
     409       return ETIMEDOUT; /* this error is perfectly normal */ 
     410 
     411#elif defined( WIN32 ) 
     412    VLC_UNUSED( psz_file); VLC_UNUSED( i_line ); 
     413 
     414    DWORD result; 
     415 
     416    mtime_t delay_ms = (deadline - mdate())/1000; 
     417    if( delay_ms < 0 ) 
     418        delay_ms = 0; 
     419 
     420    /* Increase our wait count */ 
     421    p_condvar->i_waiting_threads++; 
     422    result = SignalObjectAndWait( *p_mutex, p_condvar->event, 
     423                                  delay_ms, FALSE ); 
     424    p_condvar->i_waiting_threads--; 
     425 
     426    /* Reacquire the mutex before returning. */ 
     427    vlc_mutex_lock( p_mutex ); 
     428    if(result == WAIT_TIMEOUT) 
     429       return ETIMEDOUT; /* this error is perfectly normal */ 
     430 
     431#elif defined( HAVE_KERNEL_SCHEDULER_H ) 
     432#   error Unimplemented 
     433 
     434#endif 
     435 
     436    return 0; 
     437
     438 
     439/***************************************************************************** 
     440 * vlc_cond_destroy: destroy a condition 
     441 *****************************************************************************/ 
     442#define vlc_cond_destroy( P_COND )                                          \ 
     443    __vlc_cond_destroy( __FILE__, __LINE__, P_COND ) 
     444 
     445/***************************************************************************** 
     446 * vlc_threadvar_create: create a thread-local variable 
     447 *****************************************************************************/ 
     448#define vlc_threadvar_create( PTHIS, P_TLS )                                 \ 
     449   __vlc_threadvar_create( P_TLS ) 
     450 
     451/***************************************************************************** 
     452 * vlc_threadvar_set: create: set the value of a thread-local variable 
     453 *****************************************************************************/ 
     454static inline int vlc_threadvar_set( vlc_threadvar_t * p_tls, void *p_value ) 
     455
     456    int i_ret; 
     457 
     458#if defined(LIBVLC_USE_PTHREAD) 
     459    i_ret = pthread_setspecific( *p_tls, p_value ); 
     460 
     461#elif defined( HAVE_KERNEL_SCHEDULER_H ) 
     462    i_ret = EINVAL; 
     463 
     464#elif defined( UNDER_CE ) || defined( WIN32 ) 
     465    i_ret = TlsSetValue( *p_tls, p_value ) ? EINVAL : 0; 
     466 
     467#endif 
     468 
     469    return i_ret; 
     470
     471 
     472/***************************************************************************** 
     473 * vlc_threadvar_get: create: get the value of a thread-local variable 
     474 *****************************************************************************/ 
     475static inline void* vlc_threadvar_get( vlc_threadvar_t * p_tls ) 
     476
     477    void *p_ret; 
     478 
     479#if defined(LIBVLC_USE_PTHREAD) 
     480    p_ret = pthread_getspecific( *p_tls ); 
     481 
     482#elif defined( HAVE_KERNEL_SCHEDULER_H ) 
     483    p_ret = NULL; 
     484 
     485#elif defined( UNDER_CE ) || defined( WIN32 ) 
     486    p_ret = TlsGetValue( *p_tls ); 
     487 
     488#endif 
     489 
     490    return p_ret; 
     491
     492 
     493# if defined (_POSIX_SPIN_LOCKS) && ((_POSIX_SPIN_LOCKS - 0) > 0) 
     494typedef pthread_spinlock_t vlc_spinlock_t; 
     495 
     496/** 
     497 * Initializes a spinlock. 
     498 */ 
     499static inline int vlc_spin_init (vlc_spinlock_t *spin) 
     500
     501    return pthread_spin_init (spin, PTHREAD_PROCESS_PRIVATE); 
     502
     503 
     504/** 
     505 * Acquires a spinlock. 
     506 */ 
     507static inline void vlc_spin_lock (vlc_spinlock_t *spin) 
     508
     509    pthread_spin_lock (spin); 
     510
     511 
     512/** 
     513 * Releases a spinlock. 
     514 */ 
     515static inline void vlc_spin_unlock (vlc_spinlock_t *spin) 
     516
     517    pthread_spin_unlock (spin); 
     518
     519 
     520/** 
     521 * Deinitializes a spinlock. 
     522 */ 
     523static inline void vlc_spin_destroy (vlc_spinlock_t *spin) 
     524
     525    pthread_spin_destroy (spin); 
     526
     527 
     528#elif defined( WIN32 ) 
     529 
     530typedef CRITICAL_SECTION vlc_spinlock_t; 
     531 
     532/** 
     533 * Initializes a spinlock. 
     534 */ 
     535static inline int vlc_spin_init (vlc_spinlock_t *spin) 
     536
     537    return !InitializeCriticalSectionAndSpinCount(spin, 4000); 
     538
     539 
     540/** 
     541 * Acquires a spinlock. 
     542 */ 
     543static inline void vlc_spin_lock (vlc_spinlock_t *spin) 
     544
     545    EnterCriticalSection(spin); 
     546
     547 
     548/** 
     549 * Releases a spinlock. 
     550 */ 
     551static inline void vlc_spin_unlock (vlc_spinlock_t *spin) 
     552
     553    LeaveCriticalSection(spin); 
     554
     555 
     556/** 
     557 * Deinitializes a spinlock. 
     558 */ 
     559static inline void vlc_spin_destroy (vlc_spinlock_t *spin) 
     560
     561    DeleteCriticalSection(spin); 
     562
     563 
     564#else 
     565 
     566/* Fallback to plain mutexes if spinlocks are not available */ 
     567typedef vlc_mutex_t vlc_spinlock_t; 
     568 
     569static inline int vlc_spin_init (vlc_spinlock_t *spin) 
     570
     571    return vlc_mutex_init (spin); 
     572
     573 
     574# define vlc_spin_lock    vlc_mutex_lock 
     575# define vlc_spin_unlock  vlc_mutex_unlock 
     576# define vlc_spin_destroy vlc_mutex_destroy 
     577#endif 
     578 
     579/***************************************************************************** 
     580 * vlc_thread_create: create a thread 
     581 *****************************************************************************/ 
     582#define vlc_thread_create( P_THIS, PSZ_NAME, FUNC, PRIORITY, WAIT )         \ 
     583    __vlc_thread_create( VLC_OBJECT(P_THIS), __FILE__, __LINE__, PSZ_NAME, (void * ( * ) ( void * ))FUNC, PRIORITY, WAIT ) 
     584 
     585/***************************************************************************** 
     586 * vlc_thread_set_priority: set the priority of the calling thread 
     587 *****************************************************************************/ 
     588#define vlc_thread_set_priority( P_THIS, PRIORITY )                         \ 
     589    __vlc_thread_set_priority( VLC_OBJECT(P_THIS), __FILE__, __LINE__, PRIORITY ) 
     590 
     591/***************************************************************************** 
     592 * vlc_thread_ready: tell the parent thread we were successfully spawned 
     593 *****************************************************************************/ 
     594#define vlc_thread_ready( P_THIS )                                          \ 
     595    __vlc_thread_ready( VLC_OBJECT(P_THIS) ) 
     596 
     597/***************************************************************************** 
     598 * vlc_thread_join: wait until a thread exits 
     599 *****************************************************************************/ 
     600#define vlc_thread_join( P_THIS )                                           \ 
     601    __vlc_thread_join( VLC_OBJECT(P_THIS), __FILE__, __LINE__ ) 
    170602 
    171603#endif /* !_VLC_THREADS_H */ 
  • src/Makefile.am

    r0669643 r707279b  
    4848    ../include/vlc_plugin.h \ 
    4949    ../include/vlc_threads.h \ 
    50     ../include/vlc_threads_funcs.h \ 
    5150    ../include/vlc_variables.h \ 
    5251    $(NULL)