[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