From: RĂ©mi Denis-Courmont Date: Sat, 12 Sep 2009 11:26:33 +0000 (+0300) Subject: Implement thread semaphores X-Git-Tag: 1.1.0-ff~3407 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=2d1f8dbe397b98397bd87078536cdf24b75402b3;p=vlc Implement thread semaphores --- diff --git a/include/vlc_threads.h b/include/vlc_threads.h index 7d65e4f10d..1f69541eb1 100644 --- a/include/vlc_threads.h +++ b/include/vlc_threads.h @@ -48,8 +48,7 @@ # include /* lldiv_t definition (only in C99) */ # include /* _POSIX_SPIN_LOCKS */ # include - /* Needed for pthread_cond_timedwait */ -# include +# include # include #endif @@ -107,6 +106,7 @@ typedef pthread_t vlc_thread_t; typedef pthread_mutex_t vlc_mutex_t; #define VLC_STATIC_MUTEX PTHREAD_MUTEX_INITIALIZER typedef pthread_cond_t vlc_cond_t; +typedef sem_t vlc_sem_t; typedef pthread_rwlock_t vlc_rwlock_t; typedef pthread_key_t vlc_threadvar_t; typedef struct vlc_timer *vlc_timer_t; @@ -130,6 +130,7 @@ typedef struct #define VLC_STATIC_MUTEX { 0, } typedef HANDLE vlc_cond_t; +typedef HANDLE vlc_sem_t; typedef struct { @@ -163,7 +164,12 @@ VLC_EXPORT( void, vlc_cond_destroy, ( vlc_cond_t * ) ); VLC_EXPORT( void, vlc_cond_signal, (vlc_cond_t *) ); VLC_EXPORT( void, vlc_cond_broadcast, (vlc_cond_t *) ); VLC_EXPORT( void, vlc_cond_wait, (vlc_cond_t *, vlc_mutex_t *) ); -VLC_EXPORT( int, vlc_cond_timedwait, (vlc_cond_t *, vlc_mutex_t *, mtime_t) ); +VLC_EXPORT( int, vlc_cond_timedwait, (vlc_cond_t *, vlc_mutex_t *, mtime_t) ); +VLC_EXPORT( void, vlc_sem_init, (vlc_sem_t *, unsigned) ); +VLC_EXPORT( void, vlc_sem_destroy, (vlc_sem_t *) ); +VLC_EXPORT( int, vlc_sem_post, (vlc_sem_t *) ); +VLC_EXPORT( void, vlc_sem_wait, (vlc_sem_t *) ); + VLC_EXPORT( void, vlc_rwlock_init, (vlc_rwlock_t *) ); VLC_EXPORT( void, vlc_rwlock_destroy, (vlc_rwlock_t *) ); VLC_EXPORT( void, vlc_rwlock_rdlock, (vlc_rwlock_t *) ); diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 2eeb208bb5..da2f4b65a0 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -463,6 +463,10 @@ vlc_cond_init vlc_cond_signal vlc_cond_timedwait vlc_cond_wait +vlc_sem_init +vlc_sem_destroy +vlc_sem_post +vlc_sem_wait vlc_control_cancel vlc_CPU vlc_error diff --git a/src/misc/pthread.c b/src/misc/pthread.c index 41c09d8e2f..ce604f427a 100644 --- a/src/misc/pthread.c +++ b/src/misc/pthread.c @@ -378,6 +378,48 @@ int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex, return val; } +/** + * Initializes a semaphore. + */ +void vlc_sem_init (vlc_sem_t *sem, unsigned value) +{ + if (sem_init (sem, 0, value)) + abort (); +} + +/** + * Destroys a semaphore. + */ +void vlc_sem_destroy (vlc_sem_t *sem) +{ + int val = sem_destroy (sem); + VLC_THREAD_ASSERT ("destroying semaphore"); +} + +/** + * Increments the value of a semaphore. + */ +int vlc_sem_post (vlc_sem_t *sem) +{ + int val = sem_post (sem); + if (val != EOVERFLOW) + VLC_THREAD_ASSERT ("unlocking semaphore"); + return val; +} + +/** + * Atomically wait for the semaphore to become non-zero (if needed), + * then decrements it. + */ +void vlc_sem_wait (vlc_sem_t *sem) +{ + int val; + do + val = sem_wait (sem); + while (val == EINTR); + VLC_THREAD_ASSERT ("locking semaphore"); +} + /** * Initializes a read/write lock. */ diff --git a/src/misc/w32thread.c b/src/misc/w32thread.c index 3669a945c9..ee83a9f48f 100644 --- a/src/misc/w32thread.c +++ b/src/misc/w32thread.c @@ -296,6 +296,37 @@ int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex, return (result == WAIT_OBJECT_0) ? 0 : ETIMEDOUT; } +/*** Semaphore ***/ +void vlc_sem_init (vlc_sem_t *sem, unsigned value) +{ + *sem = CreateSemaphore (NULL, value, 0x7fffffff, NULL); + if (*sem == NULL) + abort (); +} + +void vlc_sem_destroy (vlc_sem_t *sem) +{ + CloseHandle (*sem); +} + +int vlc_sem_post (vlc_sem_t *sem) +{ + ReleaseSemaphore (*sem, 1, NULL); + return 0; /* FIXME */ +} + +void vlc_sem_wait (vlc_sem_t *sem) +{ + DWORD result; + + do + { + vlc_testcancel (); + result = WaitForSingleObjectEx (*sem, INFINITE, TRUE); + } + while (result == WAIT_IO_COMPLETION); +} + /*** Read/write locks */ /* SRW (Slim Read Write) locks are available in Vista+ only */ void vlc_rwlock_init (vlc_rwlock_t *lock)