[vlc-devel] commit: Implement thread semaphores ( Rémi Denis-Courmont )
git version control
git at videolan.org
Sat Sep 12 13:28:07 CEST 2009
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Sep 12 14:26:33 2009 +0300| [2d1f8dbe397b98397bd87078536cdf24b75402b3] | committer: Rémi Denis-Courmont
Implement thread semaphores
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2d1f8dbe397b98397bd87078536cdf24b75402b3
---
include/vlc_threads.h | 12 +++++++++---
src/libvlccore.sym | 4 ++++
src/misc/pthread.c | 42 ++++++++++++++++++++++++++++++++++++++++++
src/misc/w32thread.c | 31 +++++++++++++++++++++++++++++++
4 files changed, 86 insertions(+), 3 deletions(-)
diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index 7d65e4f..1f69541 100644
--- a/include/vlc_threads.h
+++ b/include/vlc_threads.h
@@ -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
{
@@ -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 2eeb208..da2f4b6 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 41c09d8..ce604f4 100644
--- a/src/misc/pthread.c
+++ b/src/misc/pthread.c
@@ -379,6 +379,48 @@ int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
}
/**
+ * 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.
*/
void vlc_rwlock_init (vlc_rwlock_t *lock)
diff --git a/src/misc/w32thread.c b/src/misc/w32thread.c
index 3669a94..ee83a9f 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)
More information about the vlc-devel
mailing list