# 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
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;
#define VLC_STATIC_MUTEX { 0, }
typedef HANDLE vlc_cond_t;
+typedef HANDLE vlc_sem_t;
typedef struct
{
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 *) );
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.
*/
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)