#include "libvlc.h"
#include <stdarg.h>
#include <assert.h>
+#include <limits.h>
static vlc_threadvar_t cancel_key;
#ifndef UNDER_CE
# define VLC_CANCEL_INIT { NULL, true, false }
#else
-# define VLC_CANCEL_INIT { NULL, NULL; true, false }
+# define VLC_CANCEL_INIT { NULL, NULL, true, false }
#endif
#ifdef UNDER_CE
}
/*** Mutexes ***/
-int vlc_mutex_init( vlc_mutex_t *p_mutex )
+void vlc_mutex_init( vlc_mutex_t *p_mutex )
{
/* This creates a recursive mutex. This is OK as fast mutexes have
* no defined behavior in case of recursive locking. */
InitializeCriticalSection (&p_mutex->mutex);
p_mutex->initialized = 1;
- return 0;
}
-int vlc_mutex_init_recursive( vlc_mutex_t *p_mutex )
+void vlc_mutex_init_recursive( vlc_mutex_t *p_mutex )
{
InitializeCriticalSection( &p_mutex->mutex );
p_mutex->initialized = 1;
- return 0;
}
}
/*** Condition variables ***/
-int vlc_cond_init( vlc_cond_t *p_condvar )
+void vlc_cond_init( vlc_cond_t *p_condvar )
{
/* Create a manual-reset event (manual reset is needed for broadcast). */
*p_condvar = CreateEvent (NULL, TRUE, FALSE, NULL);
- return *p_condvar ? 0 : ENOMEM;
+ if (!*p_condvar)
+ abort();
}
void vlc_cond_destroy (vlc_cond_t *p_condvar)
return (result == WAIT_OBJECT_0) ? 0 : ETIMEDOUT;
}
+/*** Read/write locks */
+/* SRW (Slim Read Write) locks are available in Vista+ only */
+void vlc_rwlock_init (vlc_rwlock_t *lock)
+{
+ vlc_mutex_init (&lock->mutex);
+ vlc_cond_init (&lock->read_wait);
+ vlc_cond_init (&lock->write_wait);
+ lock->readers = 0; /* active readers */
+ lock->writers = 0; /* waiting or active writers */
+ lock->writer = 0; /* ID of active writer */
+}
+
+/**
+ * Destroys an initialized unused read/write lock.
+ */
+void vlc_rwlock_destroy (vlc_rwlock_t *lock)
+{
+ vlc_cond_destroy (&lock->read_wait);
+ vlc_cond_destroy (&lock->write_wait);
+ vlc_mutex_destroy (&lock->mutex);
+}
+
+/**
+ * Acquires a read/write lock for reading. Recursion is allowed.
+ */
+void vlc_rwlock_rdlock (vlc_rwlock_t *lock)
+{
+ vlc_mutex_lock (&lock->mutex);
+ while (lock->writer != 0)
+ vlc_cond_wait (&lock->read_wait, &lock->mutex);
+ if (lock->readers == ULONG_MAX)
+ abort ();
+ lock->readers++;
+ vlc_mutex_unlock (&lock->mutex);
+}
+
+/**
+ * Acquires a read/write lock for writing. Recursion is not allowed.
+ */
+void vlc_rwlock_wrlock (vlc_rwlock_t *lock)
+{
+ vlc_mutex_lock (&lock->mutex);
+ if (lock->writers == ULONG_MAX)
+ abort ();
+ lock->writers++;
+ while ((lock->readers > 0) || (lock->writer != 0))
+ vlc_cond_wait (&lock->write_wait, &lock->mutex);
+ lock->writers--;
+ lock->writer = GetCurrentThreadId ();
+ vlc_mutex_unlock (&lock->mutex);
+}
+
+/**
+ * Releases a read/write lock.
+ */
+void vlc_rwlock_unlock (vlc_rwlock_t *lock)
+{
+ vlc_mutex_lock (&lock->mutex);
+ if (lock->readers > 0)
+ lock->readers--; /* Read unlock */
+ else
+ lock->writer = 0; /* Write unlock */
+
+ if (lock->writers > 0)
+ {
+ if (lock->readers == 0)
+ vlc_cond_signal (&lock->write_wait);
+ }
+ else
+ vlc_cond_broadcast (&lock->read_wait);
+ vlc_mutex_unlock (&lock->mutex);
+}
+
/*** Thread-specific variables (TLS) ***/
int vlc_threadvar_create (vlc_threadvar_t *p_tls, void (*destr) (void *))
{
/*** Threads ***/
+void vlc_threads_setup (libvlc_int_t *p_libvlc)
+{
+ (void) p_libvlc;
+}
+
static unsigned __stdcall vlc_entry (void *data)
{
vlc_cancel_t cancel_data = VLC_CANCEL_INIT;
}
va_end (ap);
}
+
+
+/*** Timers ***/
+static void CALLBACK vlc_timer_do (void *val, BOOLEAN timeout)
+{
+ vlc_timer_t *id = val;
+
+ assert (timeout);
+ id->func (id->data);
+}
+
+int vlc_timer_create (vlc_timer_t *id, void (*func) (void *), void *data)
+{
+ id->func = func;
+ id->data = data;
+ id->handle = INVALID_HANDLE_VALUE;
+ return 0;
+}
+
+void vlc_timer_destroy (vlc_timer_t *id)
+{
+ if (id->handle != INVALID_HANDLE_VALUE)
+ DeleteTimerQueueTimer (NULL, id->handle, NULL);
+}
+
+void vlc_timer_schedule (vlc_timer_t *id, bool absolute,
+ mtime_t value, mtime_t interval)
+{
+ if (id->handle != INVALID_HANDLE_VALUE)
+ {
+ DeleteTimerQueueTimer (NULL, id->handle, NULL);
+ id->handle = INVALID_HANDLE_VALUE;
+ }
+ if (value == 0)
+ return; /* Disarm */
+
+ if (absolute)
+ value -= mdate ();
+ value = (value + 999) / 1000;
+ interval = (interval + 999) / 1000;
+ if (!CreateTimerQueueTimer (&id->handle, NULL, vlc_timer_do, id, value,
+ interval, WT_EXECUTEDEFAULT))
+ abort ();
+}
+
+unsigned vlc_timer_getoverrun (const vlc_timer_t *id)
+{
+ (void)id;
+ return 0;
+}