]> git.sesse.net Git - vlc/blobdiff - src/misc/threads.c
* ./src/libvlc.c, ./include/main.h: the root of all objects is now
[vlc] / src / misc / threads.c
index b3ecf0f3a3942827dca9d49c05f6b331d1142f05..aba753da7a64062bee8faf2cef1ce708cd9913d7 100644 (file)
@@ -2,7 +2,7 @@
  * threads.c : threads implementation for the VideoLAN client
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001, 2002 VideoLAN
- * $Id: threads.c,v 1.17 2002/09/29 18:16:04 sam Exp $
+ * $Id: threads.c,v 1.18 2002/10/03 13:21:55 sam Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
 #define VLC_THREADS_READY          3
 
 /*****************************************************************************
- * Prototype for GPROF wrapper
- *****************************************************************************/
-#ifdef GPROF
-/* Wrapper function for profiling */
-static void *      vlc_thread_wrapper ( void *p_wrapper );
-
-#   ifdef WIN32
-
-#       define ITIMER_REAL 1
-#       define ITIMER_PROF 2
-
-struct itimerval
-{
-    struct timeval it_value;
-    struct timeval it_interval;
-};  
-
-int setitimer(int kind, const struct itimerval* itnew, struct itimerval* itold);
-#   endif /* WIN32 */
-
-typedef struct wrapper_t
-{
-    /* Data lock access */
-    vlc_mutex_t lock;
-    vlc_cond_t  wait;
-    
-    /* Data used to spawn the real thread */
-    vlc_thread_func_t func;
-    void *p_data;
-    
-    /* Profiling timer passed to the thread */
-    struct itimerval itimer;
-    
-} wrapper_t;
-
-#endif /* GPROF */
-
-/*****************************************************************************
- * Global mutexes for lazy initialization of the threads system
+ * Global mutex for lazy initialization of the threads system
  *****************************************************************************/
 static volatile int i_initializations = 0;
 
 #if defined( PTH_INIT_IN_PTH_H )
-    /* Unimplemented */
 #elif defined( ST_INIT_IN_ST_H )
-    /* Unimplemented */
 #elif defined( WIN32 )
-    /* Unimplemented */
 #elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
     static pthread_mutex_t once_mutex = PTHREAD_MUTEX_INITIALIZER;
 #elif defined( HAVE_CTHREADS_H )
-    /* Unimplemented */
 #elif defined( HAVE_KERNEL_SCHEDULER_H )
-    /* Unimplemented */
 #endif
 
 /*****************************************************************************
@@ -97,98 +54,102 @@ static volatile int i_initializations = 0;
 int __vlc_threads_init( vlc_object_t *p_this )
 {
     static volatile int i_status = VLC_THREADS_UNINITIALIZED;
-    int i_ret = 0;
 
+    libvlc_t *p_libvlc = (libvlc_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( PTH_INIT_IN_PTH_H )
-    /* Unimplemented */
 #elif defined( ST_INIT_IN_ST_H )
-    /* Unimplemented */
 #elif defined( WIN32 )
     HINSTANCE hInstLib;
 #elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
     pthread_mutex_lock( &once_mutex );
 #elif defined( HAVE_CTHREADS_H )
-    /* Unimplemented */
 #elif defined( HAVE_KERNEL_SCHEDULER_H )
-    /* Unimplemented */
 #endif
 
     if( i_status == VLC_THREADS_UNINITIALIZED )
     {
         i_status = VLC_THREADS_PENDING;
 
+        /* We should be safe now. Do all the initialization stuff we want. */
+        vlc_object_create( p_libvlc, VLC_OBJECT_ROOT );
+        p_libvlc->b_ready = VLC_FALSE;
+
 #if defined( PTH_INIT_IN_PTH_H )
         i_ret = pth_init();
+
 #elif defined( ST_INIT_IN_ST_H )
         i_ret = st_init();
+
 #elif defined( WIN32 )
-        /* dynamically get the address of SignalObjectAndWait */
+        /* Dynamically get the address of SignalObjectAndWait */
         if( GetVersion() < 0x80000000 )
         {
             /* We are running on NT/2K/XP, we can use SignalObjectAndWait */
             hInstLib = LoadLibrary( "kernel32" );
             if( hInstLib )
             {
-                p_this->p_vlc->SignalObjectAndWait =
+                p_libvlc->SignalObjectAndWait =
                     (SIGNALOBJECTANDWAIT)GetProcAddress( hInstLib,
                                                      "SignalObjectAndWait" );
             }
         }
         else
         {
-            p_this->p_vlc->SignalObjectAndWait = NULL;
+            p_libvlc->SignalObjectAndWait = NULL;
         }
 
-        p_this->p_vlc->b_fast_mutex = 0;
-        p_this->p_vlc->i_win9x_cv = 0;
+        p_libvlc->b_fast_mutex = 0;
+        p_libvlc->i_win9x_cv = 0;
 
 #elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
-        /* Unimplemented */
 #elif defined( HAVE_CTHREADS_H )
-        /* Unimplemented */
 #elif defined( HAVE_KERNEL_SCHEDULER_H )
-        /* Unimplemented */
 #endif
 
+        vlc_mutex_init( p_libvlc, &p_libvlc->global_lock );
+
         if( i_ret )
         {
             i_status = VLC_THREADS_ERROR;
         }
         else
         {
-            vlc_mutex_init( p_this, p_this->p_vlc->p_global_lock );
+            i_initializations++;
             i_status = VLC_THREADS_READY;
         }
     }
     else
     {
-        i_ret = ( i_status == VLC_THREADS_READY );
+        /* 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. */
 #if defined( PTH_INIT_IN_PTH_H )
-    /* Unimplemented */
+    while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
 #elif defined( ST_INIT_IN_ST_H )
-    /* Unimplemented */
+    while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
 #elif defined( WIN32 )
-    /* Unimplemented */
+    while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
 #elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
     pthread_mutex_unlock( &once_mutex );
-    return i_ret;
 #elif defined( HAVE_CTHREADS_H )
-    /* Unimplemented */
+    while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
 #elif defined( HAVE_KERNEL_SCHEDULER_H )
-    /* Unimplemented */
+    while( i_status == VLC_THREADS_PENDING ) msleep( THREAD_SLEEP );
 #endif
 
-    /* Wait until the other thread has initialized the thread library */
-    while( i_status == VLC_THREADS_PENDING )
+    if( i_status != VLC_THREADS_READY )
     {
-        msleep( THREAD_SLEEP );
+        return VLC_ETHREAD;
     }
 
-    return i_status == VLC_THREADS_READY;
+    return i_ret;
 }
 
 /*****************************************************************************
@@ -205,33 +166,66 @@ int __vlc_threads_end( vlc_object_t *p_this )
     {
         return pth_kill();
     }
-    return 0;
 
 #elif defined( ST_INIT_IN_ST_H )
     i_initializations--;
-    return 0;
 
 #elif defined( WIN32 )
     i_initializations--;
-    return 0;
 
 #elif defined( PTHREAD_COND_T_IN_PTHREAD_H )
     pthread_mutex_lock( &once_mutex );
     i_initializations--;
     pthread_mutex_unlock( &once_mutex );
-    return 0;
 
 #elif defined( HAVE_CTHREADS_H )
     i_initializations--;
-    return 0;
 
 #elif defined( HAVE_KERNEL_SCHEDULER_H )
     i_initializations--;
-    return 0;
 
 #endif
+    return VLC_SUCCESS;
 }
 
+/*****************************************************************************
+ * Prototype for GPROF wrapper
+ *****************************************************************************/
+#ifdef GPROF
+/* Wrapper function for profiling */
+static void *      vlc_thread_wrapper ( void *p_wrapper );
+
+#   ifdef WIN32
+
+#       define ITIMER_REAL 1
+#       define ITIMER_PROF 2
+
+struct itimerval
+{
+    struct timeval it_value;
+    struct timeval it_interval;
+};  
+
+int setitimer(int kind, const struct itimerval* itnew, struct itimerval* itold);
+#   endif /* WIN32 */
+
+typedef struct wrapper_t
+{
+    /* Data lock access */
+    vlc_mutex_t lock;
+    vlc_cond_t  wait;
+    
+    /* Data used to spawn the real thread */
+    vlc_thread_func_t func;
+    void *p_data;
+    
+    /* Profiling timer passed to the thread */
+    struct itimerval itimer;
+    
+} wrapper_t;
+
+#endif /* GPROF */
+
 /*****************************************************************************
  * vlc_mutex_init: initialize a mutex
  *****************************************************************************/