Commit 2d1f8dbe authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Implement thread semaphores

parent 745bd15f
......@@ -48,8 +48,7 @@
# include <stdlib.h> /* lldiv_t definition (only in C99) */
# include <unistd.h> /* _POSIX_SPIN_LOCKS */
# include <pthread.h>
/* Needed for pthread_cond_timedwait */
# include <errno.h>
# include <semaphore.h>
# include <time.h>
#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
{
......@@ -164,6 +165,11 @@ 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( 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 *) );
......
......@@ -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
......
......@@ -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.
*/
......
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment