* Global mutex for lazy initialization of the threads system
*****************************************************************************/
static volatile unsigned i_initializations = 0;
-static volatile int i_status = VLC_THREADS_UNINITIALIZED;
-static vlc_object_t *p_root;
#if defined( UNDER_CE )
#elif defined( WIN32 )
-
-/*
-** On Windows 9x/Me you can use a fast but incorrect condition variables
-** implementation (more precisely there is a possibility for a race
-** condition to happen).
-** However it is possible to use slower alternatives which are more robust.
-** Currently you can choose between implementation 0 (which is the
-** fastest but slightly incorrect), 1 (default) and 2.
-*/
-static int i_win9x_cv = 1;
-
#elif defined( HAVE_KERNEL_SCHEDULER_H )
#elif defined( LIBVLC_USE_PTHREAD )
static pthread_mutex_t once_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
+/**
+ * Global process-wide VLC object.
+ * Contains inter-instance data, such as the module cache and global mutexes.
+ */
+static libvlc_global_data_t *p_root;
+
+libvlc_global_data_t *vlc_global( void )
+{
+ assert( i_initializations > 0 );
+ return p_root;
+}
+
+
vlc_threadvar_t msg_context_global_key;
#if defined(LIBVLC_USE_PTHREAD)
* keep the library really thread-safe. Some architectures don't support this
* and thus do not guarantee the complete reentrancy.
*****************************************************************************/
-int __vlc_threads_init( vlc_object_t *p_this )
+int vlc_threads_init( void )
{
- libvlc_global_data_t *p_libvlc_global = (libvlc_global_data_t *)p_this;
int i_ret = VLC_SUCCESS;
/* If we have lazy mutex initialization, use it. Otherwise, we just
* hope nothing wrong happens. */
#if defined( UNDER_CE )
#elif defined( WIN32 )
- if( IsDebuggerPresent() )
- {
- /* SignalObjectAndWait() is problematic under a debugger */
- i_win9x_cv = 1;
- }
#elif defined( HAVE_KERNEL_SCHEDULER_H )
#elif defined( LIBVLC_USE_PTHREAD )
pthread_mutex_lock( &once_mutex );
#endif
- if( i_status == VLC_THREADS_UNINITIALIZED )
+ if( i_initializations == 0 )
{
- i_status = VLC_THREADS_PENDING;
-
- /* We should be safe now. Do all the initialization stuff we want. */
- p_libvlc_global->b_ready = false;
-
- p_root = vlc_custom_create( VLC_OBJECT(p_libvlc_global), 0,
- VLC_OBJECT_GLOBAL, "global" );
+ p_root = vlc_custom_create( NULL, sizeof( *p_root ),
+ VLC_OBJECT_GENERIC, "root" );
if( p_root == NULL )
- i_ret = VLC_ENOMEM;
-
- if( i_ret )
{
- i_status = VLC_THREADS_ERROR;
- }
- else
- {
- i_initializations++;
- i_status = VLC_THREADS_READY;
+ i_ret = VLC_ENOMEM;
+ goto out;
}
+ /* We should be safe now. Do all the initialization stuff we want. */
vlc_threadvar_create( p_root, &msg_context_global_key );
}
- else
- {
- /* Just increment the initialization count */
- i_initializations++;
- }
+ i_initializations++;
- /* If we have lazy mutex initialization support, unlock the mutex;
- * otherwize, do a naive wait loop. */
+out:
+ /* If we have lazy mutex initialization support, unlock the mutex.
+ * Otherwize, we are screwed. */
#if defined( UNDER_CE )
- while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
#elif defined( WIN32 )
- while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
#elif defined( HAVE_KERNEL_SCHEDULER_H )
- while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
#elif defined( LIBVLC_USE_PTHREAD )
pthread_mutex_unlock( &once_mutex );
#endif
- if( i_status != VLC_THREADS_READY )
- {
- return VLC_ETHREAD;
- }
-
return i_ret;
}
*****************************************************************************
* FIXME: This function is far from being threadsafe.
*****************************************************************************/
-int __vlc_threads_end( vlc_object_t *p_this )
+void vlc_threads_end( void )
{
- (void)p_this;
#if defined( UNDER_CE )
#elif defined( WIN32 )
#elif defined( HAVE_KERNEL_SCHEDULER_H )
pthread_mutex_lock( &once_mutex );
#endif
- if( i_initializations == 0 )
- return VLC_EGENERIC;
+ assert( i_initializations > 0 );
- i_initializations--;
- if( i_initializations == 0 )
- {
- i_status = VLC_THREADS_UNINITIALIZED;
+ if( i_initializations == 1 )
vlc_object_release( p_root );
- }
+ i_initializations--;
#if defined( UNDER_CE )
#elif defined( WIN32 )
#elif defined( LIBVLC_USE_PTHREAD )
pthread_mutex_unlock( &once_mutex );
#endif
- return VLC_SUCCESS;
}
#ifdef __linux__
/*****************************************************************************
* vlc_mutex_init: initialize a mutex
*****************************************************************************/
-int __vlc_mutex_init( vlc_mutex_t *p_mutex )
+int vlc_mutex_init( vlc_mutex_t *p_mutex )
{
#if defined( UNDER_CE )
InitializeCriticalSection( &p_mutex->csection );
return 0;
#elif defined( WIN32 )
- p_mutex->mutex = CreateMutex( 0, FALSE, 0 );
- return ( p_mutex->mutex != NULL ? 0 : 1 );
+ *p_mutex = CreateMutex( 0, FALSE, 0 );
+ return (*p_mutex != NULL) ? 0 : ENOMEM;
#elif defined( HAVE_KERNEL_SCHEDULER_H )
/* check the arguments and whether it's already been initialized */
/*****************************************************************************
* vlc_mutex_init: initialize a recursive mutex (Do not use)
*****************************************************************************/
-int __vlc_mutex_init_recursive( vlc_mutex_t *p_mutex )
+int vlc_mutex_init_recursive( vlc_mutex_t *p_mutex )
{
#if defined( WIN32 )
/* Create mutex returns a recursive mutex */
- p_mutex->mutex = CreateMutex( 0, FALSE, 0 );
- return ( p_mutex->mutex != NULL ? 0 : 1 );
+ *p_mutex = CreateMutex( 0, FALSE, 0 );
+ return (*p_mutex != NULL) ? 0 : ENOMEM;
#elif defined( LIBVLC_USE_PTHREAD )
pthread_mutexattr_t attr;
int i_result;
#elif defined( WIN32 )
VLC_UNUSED( psz_file); VLC_UNUSED( i_line );
- if( p_mutex->mutex )
- CloseHandle( p_mutex->mutex );
- else
- DeleteCriticalSection( &p_mutex->csection );
+ CloseHandle( *p_mutex );
#elif defined( HAVE_KERNEL_SCHEDULER_H )
if( p_mutex->init == 9999 )
*****************************************************************************/
int __vlc_cond_init( vlc_cond_t *p_condvar )
{
-#if defined( UNDER_CE )
- /* Initialize counter */
- p_condvar->i_waiting_threads = 0;
-
- /* Create an auto-reset event. */
- p_condvar->event = CreateEvent( NULL, /* no security */
- FALSE, /* auto-reset event */
- FALSE, /* start non-signaled */
- NULL ); /* unnamed */
- return !p_condvar->event;
-
-#elif defined( WIN32 )
+#if defined( UNDER_CE ) || defined( WIN32 )
/* Initialize counter */
p_condvar->i_waiting_threads = 0;
- /* Misc init */
- p_condvar->i_win9x_cv = i_win9x_cv;
-
/* Create an auto-reset event. */
p_condvar->event = CreateEvent( NULL, /* no security */
FALSE, /* auto-reset event */
FALSE, /* start non-signaled */
NULL ); /* unnamed */
-
- p_condvar->semaphore = NULL;
return !p_condvar->event;
#elif defined( HAVE_KERNEL_SCHEDULER_H )
*****************************************************************************/
void __vlc_cond_destroy( const char * psz_file, int i_line, vlc_cond_t *p_condvar )
{
-#if defined( UNDER_CE )
+#if defined( UNDER_CE ) || defined( WIN32 )
VLC_UNUSED( psz_file); VLC_UNUSED( i_line );
CloseHandle( p_condvar->event );
-#elif defined( WIN32 )
- VLC_UNUSED( psz_file); VLC_UNUSED( i_line );
-
- if( !p_condvar->semaphore )
- CloseHandle( p_condvar->event );
- else
- {
- CloseHandle( p_condvar->event );
- CloseHandle( p_condvar->semaphore );
- }
-
- if( p_condvar->semaphore != NULL )
- DeleteCriticalSection( &p_condvar->csection );
-
#elif defined( HAVE_KERNEL_SCHEDULER_H )
p_condvar->init = 0;
#if defined( HAVE_KERNEL_SCHEDULER_H )
# error Unimplemented!
-#elif defined( UNDER_CE ) || defined( WIN32 )
+#elif defined( UNDER_CE )
#elif defined( WIN32 )
*p_tls = TlsAlloc();
i_ret = (*p_tls == INVALID_HANDLE_VALUE) ? EAGAIN : 0;
{
int i_ret;
void *p_data = (void *)p_this;
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
vlc_mutex_lock( &p_this->object_lock );
int __vlc_thread_set_priority( vlc_object_t *p_this, const char * psz_file,
int i_line, int i_priority )
{
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
#if defined( WIN32 ) || defined( UNDER_CE )
VLC_UNUSED( psz_file); VLC_UNUSED( i_line );
*****************************************************************************/
void __vlc_thread_join( vlc_object_t *p_this, const char * psz_file, int i_line )
{
- vlc_object_internals_t *p_priv = p_this->p_internals;
+ vlc_object_internals_t *p_priv = vlc_internals( p_this );
#if defined( UNDER_CE ) || defined( WIN32 )
HMODULE hmodule;
user_ft.dwLowDateTime) / 10;
msg_Dbg( p_this, "thread times: "
- "real "I64Fd"m%fs, kernel "I64Fd"m%fs, user "I64Fd"m%fs",
+ "real %"PRId64"m%fs, kernel %"PRId64"m%fs, user %"PRId64"m%fs",
real_time/60/1000000,
(double)((real_time%(60*1000000))/1000000.0),
kernel_time/60/1000000,