]> git.sesse.net Git - vlc/blobdiff - src/misc/threads.c
Simplify threading code a bit
[vlc] / src / misc / threads.c
index e547d0c5523c210a08468680857ff9d7deab2a02..9980e0df18932e5c3354621c1e502f858b7b5a65 100644 (file)
@@ -51,16 +51,13 @@ static vlc_object_t *p_root;
 #if defined( UNDER_CE )
 #elif defined( WIN32 )
 
-/* following is only available on NT/2000/XP and above */
-static SIGNALOBJECTANDWAIT pf_SignalObjectAndWait = NULL;
-
 /*
 ** On Windows NT/2K/XP we use a slow mutex implementation but which
 ** allows us to correctly implement condition variables.
 ** You can also use the faster Win9x implementation but you might
 ** experience problems with it.
 */
-static vlc_bool_t          b_fast_mutex = VLC_FALSE;
+static bool          b_fast_mutex = false;
 /*
 ** On Windows 9x/Me you can use a fast but incorrect condition variables
 ** implementation (more precisely there is a possibility for a race
@@ -149,7 +146,7 @@ int __vlc_threads_init( vlc_object_t *p_this )
     if( IsDebuggerPresent() )
     {
         /* SignalObjectAndWait() is problematic under a debugger */
-        b_fast_mutex = VLC_TRUE;
+        b_fast_mutex = true;
         i_win9x_cv = 1;
     }
 #elif defined( HAVE_KERNEL_SCHEDULER_H )
@@ -162,32 +159,10 @@ int __vlc_threads_init( vlc_object_t *p_this )
         i_status = VLC_THREADS_PENDING;
 
         /* We should be safe now. Do all the initialization stuff we want. */
-        p_libvlc_global->b_ready = VLC_FALSE;
-
-#if defined( UNDER_CE )
-        /* Nothing to initialize */
-
-#elif defined( WIN32 )
-        /* Dynamically get the address of SignalObjectAndWait */
-        if( GetVersion() < 0x80000000 )
-        {
-            HINSTANCE hInstLib;
-
-            /* We are running on NT/2K/XP, we can use SignalObjectAndWait */
-            hInstLib = LoadLibrary( "kernel32" );
-            if( hInstLib )
-            {
-                pf_SignalObjectAndWait =
-                    (SIGNALOBJECTANDWAIT)GetProcAddress( hInstLib,
-                                                     "SignalObjectAndWait" );
-            }
-        }
+        p_libvlc_global->b_ready = false;
 
-#elif defined( HAVE_KERNEL_SCHEDULER_H )
-#elif defined( LIBVLC_USE_PTHREAD )
-#endif
-
-        p_root = vlc_object_create( p_libvlc_global, VLC_OBJECT_GLOBAL );
+        p_root = vlc_custom_create( VLC_OBJECT(p_libvlc_global), 0,
+                                    VLC_OBJECT_GLOBAL, "global" );
         if( p_root == NULL )
             i_ret = VLC_ENOMEM;
 
@@ -278,13 +253,8 @@ int __vlc_mutex_init( vlc_mutex_t *p_mutex )
     return 0;
 
 #elif defined( WIN32 )
-    /* We use mutexes on WinNT/2K/XP because we can use the SignalObjectAndWait
-     * function and have a 100% correct vlc_cond_wait() implementation.
-     * As this function is not available on Win9x, we can use the faster
-     * CriticalSections */
-    if( pf_SignalObjectAndWait && !b_fast_mutex )
+    if( !b_fast_mutex )
     {
-        /* We are running on NT/2K/XP, we can use SignalObjectAndWait */
         p_mutex->mutex = CreateMutex( 0, FALSE, 0 );
         return ( p_mutex->mutex != NULL ? 0 : 1 );
     }
@@ -317,26 +287,22 @@ int __vlc_mutex_init( vlc_mutex_t *p_mutex )
     return B_OK;
 
 #elif defined( LIBVLC_USE_PTHREAD )
-# ifndef NDEBUG
-    {
-        /* Create error-checking mutex to detect problems more easily. */
-        pthread_mutexattr_t attr;
-        int                 i_result;
-
-        pthread_mutexattr_init( &attr );
-#   if defined(SYS_LINUX)
-        pthread_mutexattr_setkind_np( &attr, PTHREAD_MUTEX_ERRORCHECK_NP );
-#   else
-        pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK );
-#   endif
+    pthread_mutexattr_t attr;
+    int                 i_result;
 
-        i_result = pthread_mutex_init( &p_mutex->mutex, &attr );
-        pthread_mutexattr_destroy( &attr );
-        return( i_result );
-    }
-# endif /* NDEBUG */
-    return pthread_mutex_init( &p_mutex->mutex, NULL );
+    pthread_mutexattr_init( &attr );
 
+# ifndef NDEBUG
+    /* Create error-checking mutex to detect problems more easily. */
+#  if defined(SYS_LINUX)
+    pthread_mutexattr_setkind_np( &attr, PTHREAD_MUTEX_ERRORCHECK_NP );
+#  else
+    pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK );
+#  endif
+# endif
+    i_result = pthread_mutex_init( p_mutex, &attr );
+    pthread_mutexattr_destroy( &attr );
+    return i_result;
 #endif
 }
 
@@ -363,7 +329,7 @@ int __vlc_mutex_init_recursive( vlc_mutex_t *p_mutex )
 #   endif
 # endif
     pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
-    i_result = pthread_mutex_init( &p_mutex->mutex, &attr );
+    i_result = pthread_mutex_init( p_mutex, &attr );
     pthread_mutexattr_destroy( &attr );
     return( i_result );
 #else
@@ -397,7 +363,7 @@ void __vlc_mutex_destroy( const char * psz_file, int i_line, vlc_mutex_t *p_mute
     p_mutex->init = 0;
 
 #elif defined( LIBVLC_USE_PTHREAD )
-    int val = pthread_mutex_destroy( &p_mutex->mutex );
+    int val = pthread_mutex_destroy( p_mutex );
     VLC_THREAD_ASSERT ("destroying mutex");
 
 #endif
@@ -425,10 +391,8 @@ int __vlc_cond_init( vlc_cond_t *p_condvar )
 
     /* Misc init */
     p_condvar->i_win9x_cv = i_win9x_cv;
-    p_condvar->SignalObjectAndWait = pf_SignalObjectAndWait;
 
-    if( (p_condvar->SignalObjectAndWait && !b_fast_mutex)
-        || p_condvar->i_win9x_cv == 0 )
+    if( !b_fast_mutex || p_condvar->i_win9x_cv == 0 )
     {
         /* Create an auto-reset event. */
         p_condvar->event = CreateEvent( NULL,   /* no security */
@@ -490,7 +454,7 @@ int __vlc_cond_init( vlc_cond_t *p_condvar )
     pthread_condattr_setclock (&attr, CLOCK_MONOTONIC);
 # endif
 
-    ret = pthread_cond_init (&p_condvar->cond, &attr);
+    ret = pthread_cond_init (p_condvar, &attr);
     pthread_condattr_destroy (&attr);
     return ret;
 
@@ -525,7 +489,7 @@ void __vlc_cond_destroy( const char * psz_file, int i_line, vlc_cond_t *p_condva
     p_condvar->init = 0;
 
 #elif defined( LIBVLC_USE_PTHREAD )
-    int val = pthread_cond_destroy( &p_condvar->cond );
+    int val = pthread_cond_destroy( p_condvar );
     VLC_THREAD_ASSERT ("destroying condition");
 
 #endif
@@ -542,11 +506,11 @@ int __vlc_threadvar_create( vlc_threadvar_t *p_tls )
 # error Unimplemented!
 #elif defined( UNDER_CE ) || defined( WIN32 )
 #elif defined( WIN32 )
-    p_tls->handle = TlsAlloc();
-    i_ret = !( p_tls->handle == 0xFFFFFFFF );
+    *p_tls = TlsAlloc();
+    i_ret = (*p_tls == INVALID_HANDLE_VALUE) ? EAGAIN : 0;
 
 #elif defined( LIBVLC_USE_PTHREAD )
-    i_ret =  pthread_key_create( &p_tls->handle, NULL );
+    i_ret =  pthread_key_create( p_tls, NULL );
 #endif
     return i_ret;
 }
@@ -559,7 +523,7 @@ int __vlc_threadvar_create( vlc_threadvar_t *p_tls )
  *****************************************************************************/
 int __vlc_thread_create( vlc_object_t *p_this, const char * psz_file, int i_line,
                          const char *psz_name, void * ( *func ) ( void * ),
-                         int i_priority, vlc_bool_t b_wait )
+                         int i_priority, bool b_wait )
 {
     int i_ret;
     void *p_data = (void *)p_this;
@@ -657,7 +621,7 @@ int __vlc_thread_create( vlc_object_t *p_this, const char * psz_file, int i_line
             vlc_object_wait( p_this );
         }
 
-        p_priv->b_thread = VLC_TRUE;
+        p_priv->b_thread = true;
 
 #if defined( WIN32 ) || defined( UNDER_CE )
         msg_Dbg( p_this, "thread %u (%s) created at priority %d (%s:%d)",
@@ -779,7 +743,7 @@ void __vlc_thread_join( vlc_object_t *p_this, const char * psz_file, int i_line
         msg_Err( p_this, "thread_join(%u) failed at %s:%d (%u)",
                          (unsigned int)p_priv->thread_id.id,
              psz_file, i_line, (unsigned int)GetLastError() );
-        p_priv->b_thread = VLC_FALSE;
+        p_priv->b_thread = false;
         return;
     }
 
@@ -834,8 +798,12 @@ void __vlc_thread_join( vlc_object_t *p_this, const char * psz_file, int i_line
     i_ret = (B_OK == wait_for_thread( p_priv->thread_id, &exit_value ));
 
 #elif defined( LIBVLC_USE_PTHREAD )
-    i_ret = pthread_join( p_priv->thread_id, NULL );
-
+    /* Make sure we do return if we are calling vlc_thread_join()
+     * from the joined thread */
+    if (pthread_equal (pthread_self (), p_priv->thread_id))
+        i_ret = pthread_detach (p_priv->thread_id);
+    else
+        i_ret = pthread_join (p_priv->thread_id, NULL);
 #endif
 
     if( i_ret )
@@ -852,6 +820,6 @@ void __vlc_thread_join( vlc_object_t *p_this, const char * psz_file, int i_line
 
 #endif
 
-    p_priv->b_thread = VLC_FALSE;
+    p_priv->b_thread = false;
 }