+# define VLC_THREAD_ASSERT (void)0
+#endif
+
+static inline void __vlc_mutex_lock( const char * psz_file, int i_line,
+ vlc_mutex_t * p_mutex )
+{
+#if defined(LIBVLC_USE_PTHREAD)
+# define vlc_assert_locked( m ) \
+ assert (pthread_mutex_lock (m) == EDEADLK)
+ int val = pthread_mutex_lock( p_mutex );
+ VLC_THREAD_ASSERT ("locking mutex");
+
+#elif defined( UNDER_CE )
+ (void)psz_file; (void)i_line;
+
+ EnterCriticalSection( &p_mutex->csection );
+
+#elif defined( WIN32 )
+ (void)psz_file; (void)i_line;
+
+ WaitForSingleObject( *p_mutex, INFINITE );
+
+#elif defined( SYS_BEOS )
+ acquire_sem( p_mutex->lock );
+
+#endif
+}
+
+#ifndef vlc_assert_locked
+# define vlc_assert_locked( m ) (void)0
+#endif
+
+/*****************************************************************************
+ * vlc_mutex_unlock: unlock a mutex
+ *****************************************************************************/
+#define vlc_mutex_unlock( P_MUTEX ) \
+ __vlc_mutex_unlock( __FILE__, __LINE__, P_MUTEX )
+
+static inline void __vlc_mutex_unlock( const char * psz_file, int i_line,
+ vlc_mutex_t *p_mutex )
+{
+#if defined(LIBVLC_USE_PTHREAD)
+ int val = pthread_mutex_unlock( p_mutex );
+ VLC_THREAD_ASSERT ("unlocking mutex");
+
+#elif defined( UNDER_CE )
+ (void)psz_file; (void)i_line;
+
+ LeaveCriticalSection( &p_mutex->csection );
+
+#elif defined( WIN32 )
+ (void)psz_file; (void)i_line;
+
+ ReleaseMutex( *p_mutex );
+
+#elif defined( SYS_BEOS )
+ release_sem( p_mutex->lock );
+
+#endif
+}
+
+/*****************************************************************************
+ * vlc_mutex_destroy: destroy a mutex
+ *****************************************************************************/
+#define vlc_mutex_destroy( P_MUTEX ) \
+ __vlc_mutex_destroy( __FILE__, __LINE__, P_MUTEX )
+
+/*****************************************************************************
+ * vlc_cond_init: initialize a condition
+ *****************************************************************************/
+#define vlc_cond_init( P_THIS, P_COND ) \
+ __vlc_cond_init( P_COND )
+
+/*****************************************************************************
+ * vlc_cond_signal: start a thread on condition completion
+ *****************************************************************************/
+#define vlc_cond_signal( P_COND ) \
+ __vlc_cond_signal( __FILE__, __LINE__, P_COND )
+
+static inline void __vlc_cond_signal( const char * psz_file, int i_line,
+ vlc_cond_t *p_condvar )
+{
+#if defined(LIBVLC_USE_PTHREAD)
+ int val = pthread_cond_signal( p_condvar );
+ VLC_THREAD_ASSERT ("signaling condition variable");
+
+#elif defined( UNDER_CE ) || defined( WIN32 )
+ (void)psz_file; (void)i_line;
+
+ /* Release one waiting thread if one is available. */
+ /* For this trick to work properly, the vlc_cond_signal must be surrounded
+ * by a mutex. This will prevent another thread from stealing the signal */
+ /* PulseEvent() only works if none of the waiting threads is suspended.
+ * This is particularily problematic under a debug session.
+ * as documented in http://support.microsoft.com/kb/q173260/ */
+ PulseEvent( p_condvar->event );
+
+#elif defined( SYS_BEOS )
+ while( p_condvar->thread != -1 )
+ {
+ thread_info info;
+ if( get_thread_info(p_condvar->thread, &info) == B_BAD_VALUE )
+ return;
+
+ if( info.state != B_THREAD_SUSPENDED )
+ {
+ /* The waiting thread is not suspended so it could
+ * have been interrupted beetwen the unlock and the
+ * suspend_thread line. That is why we sleep a little
+ * before retesting p_condver->thread. */
+ snooze( 10000 );
+ }
+ else
+ {
+ /* Ok, we have to wake up that thread */
+ resume_thread( p_condvar->thread );
+ }
+ }
+
+#endif
+}
+
+/*****************************************************************************
+ * vlc_cond_wait: wait until condition completion
+ *****************************************************************************/
+#define vlc_cond_wait( P_COND, P_MUTEX ) \
+ __vlc_cond_wait( __FILE__, __LINE__, P_COND, P_MUTEX )
+
+static inline void __vlc_cond_wait( const char * psz_file, int i_line,
+ vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex )
+{
+#if defined(LIBVLC_USE_PTHREAD)
+ int val = pthread_cond_wait( p_condvar, p_mutex );
+ VLC_THREAD_ASSERT ("waiting on condition");
+
+#elif defined( UNDER_CE )
+ p_condvar->i_waiting_threads++;
+ LeaveCriticalSection( &p_mutex->csection );
+ WaitForSingleObject( p_condvar->event, INFINITE );
+ p_condvar->i_waiting_threads--;
+
+ /* Reacquire the mutex before returning. */
+ vlc_mutex_lock( p_mutex );
+
+#elif defined( WIN32 )
+ (void)psz_file; (void)i_line;
+
+ /* Increase our wait count */
+ p_condvar->i_waiting_threads++;
+ SignalObjectAndWait( *p_mutex, p_condvar->event, INFINITE, FALSE );
+ p_condvar->i_waiting_threads--;
+
+ /* Reacquire the mutex before returning. */
+ vlc_mutex_lock( p_mutex );
+
+#elif defined( SYS_BEOS )
+ /* The p_condvar->thread var is initialized before the unlock because
+ * it enables to identify when the thread is interrupted beetwen the
+ * unlock line and the suspend_thread line */
+ p_condvar->thread = find_thread( NULL );
+ vlc_mutex_unlock( p_mutex );
+ suspend_thread( p_condvar->thread );
+ p_condvar->thread = -1;
+
+ vlc_mutex_lock( p_mutex );
+
+#endif
+}
+
+
+/*****************************************************************************
+ * vlc_cond_timedwait: wait until condition completion or expiration
+ *****************************************************************************
+ * Returns 0 if object signaled, an error code in case of timeout or error.
+ *****************************************************************************/
+#define vlc_cond_timedwait( P_COND, P_MUTEX, DEADLINE ) \
+ __vlc_cond_timedwait( __FILE__, __LINE__, P_COND, P_MUTEX, DEADLINE )
+
+static inline int __vlc_cond_timedwait( const char * psz_file, int i_line,
+ vlc_cond_t *p_condvar,
+ vlc_mutex_t *p_mutex,
+ mtime_t deadline )
+{
+#if defined(LIBVLC_USE_PTHREAD)
+ lldiv_t d = lldiv( deadline, 1000000 );
+ struct timespec ts = { d.quot, d.rem * 1000 };
+
+ int val = pthread_cond_timedwait (p_condvar, p_mutex, &ts);
+ if (val == ETIMEDOUT)
+ return ETIMEDOUT; /* this error is perfectly normal */
+ VLC_THREAD_ASSERT ("timed-waiting on condition");
+
+#elif defined( UNDER_CE )
+ mtime_t delay_ms = (deadline - mdate())/1000;
+ DWORD result;
+ if( delay_ms < 0 )
+ delay_ms = 0;
+
+ p_condvar->i_waiting_threads++;
+ LeaveCriticalSection( &p_mutex->csection );
+ result = WaitForSingleObject( p_condvar->event, delay_ms );
+ p_condvar->i_waiting_threads--;
+
+ /* Reacquire the mutex before returning. */
+ vlc_mutex_lock( p_mutex );
+
+ if(result == WAIT_TIMEOUT)
+ return ETIMEDOUT; /* this error is perfectly normal */
+
+ (void)psz_file; (void)i_line;
+
+#elif defined( WIN32 )
+ mtime_t delay_ms = (deadline - mdate())/1000;
+ DWORD result;
+ if( delay_ms < 0 )
+ delay_ms = 0;
+
+ /* Increase our wait count */
+ p_condvar->i_waiting_threads++;
+ result = SignalObjectAndWait( *p_mutex, p_condvar->event,
+ delay_ms, FALSE );
+ p_condvar->i_waiting_threads--;
+
+ /* Reacquire the mutex before returning. */
+ vlc_mutex_lock( p_mutex );
+ if(result == WAIT_TIMEOUT)
+ return ETIMEDOUT; /* this error is perfectly normal */
+
+ (void)psz_file; (void)i_line;
+
+#elif defined( SYS_BEOS )
+# error Unimplemented
+
+#endif
+
+ return 0;
+}
+
+/*****************************************************************************
+ * vlc_cond_destroy: destroy a condition
+ *****************************************************************************/
+#define vlc_cond_destroy( P_COND ) \
+ __vlc_cond_destroy( __FILE__, __LINE__, P_COND )
+
+/*****************************************************************************
+ * vlc_threadvar_set: create: set the value of a thread-local variable
+ *****************************************************************************/
+static inline int vlc_threadvar_set( vlc_threadvar_t * p_tls, void *p_value )
+{
+ int i_ret;
+
+#if defined(LIBVLC_USE_PTHREAD)
+ i_ret = pthread_setspecific( *p_tls, p_value );
+
+#elif defined( SYS_BEOS )
+ i_ret = EINVAL;
+
+#elif defined( UNDER_CE ) || defined( WIN32 )
+ i_ret = TlsSetValue( *p_tls, p_value ) ? EINVAL : 0;
+
+#endif
+
+ return i_ret;
+}
+
+/*****************************************************************************
+ * vlc_threadvar_get: create: get the value of a thread-local variable
+ *****************************************************************************/
+static inline void* vlc_threadvar_get( vlc_threadvar_t * p_tls )
+{
+ void *p_ret;
+
+#if defined(LIBVLC_USE_PTHREAD)
+ p_ret = pthread_getspecific( *p_tls );
+
+#elif defined( SYS_BEOS )
+ p_ret = NULL;
+
+#elif defined( UNDER_CE ) || defined( WIN32 )
+ p_ret = TlsGetValue( *p_tls );