]> git.sesse.net Git - vlc/blobdiff - src/misc/threads.c
Warn when pl_Yield() is not used
[vlc] / src / misc / threads.c
index f81f67f9a55ab22782fec838e9f35fbcf5d0a965..0ab4efaf655d6adf018e6d092d1768270ce86d81 100644 (file)
@@ -73,7 +73,6 @@ static inline unsigned long vlc_threadid (void)
      return v.i;
 }
 
-
 /*****************************************************************************
  * vlc_thread_fatal: Report an error from the threading layer
  *****************************************************************************
@@ -114,9 +113,15 @@ void vlc_pthread_fatal (const char *action, int error,
     fflush (stderr);
     abort ();
 }
+#else
+void vlc_pthread_fatal (const char *action, int error,
+                        const char *file, unsigned line)
+{
+    (void)action; (void)error; (void)file; (void)line;
+    abort();
+}
 #endif
 
-
 /*****************************************************************************
  * vlc_threads_init: initialize threads system
  *****************************************************************************
@@ -145,7 +150,7 @@ int vlc_threads_init( void )
         }
 
         /* We should be safe now. Do all the initialization stuff we want. */
-        vlc_threadvar_create( p_root, &msg_context_global_key );
+        vlc_threadvar_create( &msg_context_global_key, msg_StackDestroy );
     }
     i_initializations++;
 
@@ -173,7 +178,10 @@ void vlc_threads_end( void )
     assert( i_initializations > 0 );
 
     if( i_initializations == 1 )
+    {
         vlc_object_release( p_root );
+        vlc_threadvar_delete( &msg_context_global_key );
+    }
     i_initializations--;
 
 #if defined( LIBVLC_USE_PTHREAD )
@@ -374,22 +382,35 @@ void __vlc_cond_destroy( const char * psz_file, int i_line, vlc_cond_t *p_condva
 /*****************************************************************************
  * vlc_tls_create: create a thread-local variable
  *****************************************************************************/
-int __vlc_threadvar_create( vlc_threadvar_t *p_tls )
+int vlc_threadvar_create( vlc_threadvar_t *p_tls, void (*destr) (void *) )
 {
-    int i_ret = -1;
+    int i_ret;
 
 #if defined( LIBVLC_USE_PTHREAD )
-    i_ret =  pthread_key_create( p_tls, NULL );
+    i_ret =  pthread_key_create( p_tls, destr );
 #elif defined( UNDER_CE )
+    i_ret = ENOSYS;
 #elif defined( WIN32 )
     *p_tls = TlsAlloc();
-    i_ret = (*p_tls == INVALID_HANDLE_VALUE) ? EAGAIN : 0;
+    i_ret = (*p_tls == TLS_OUT_OF_INDEXES) ? EAGAIN : 0;
 #else
 # error Unimplemented!
 #endif
     return i_ret;
 }
 
+void vlc_threadvar_delete (vlc_threadvar_t *p_tls)
+{
+#if defined( LIBVLC_USE_PTHREAD )
+    pthread_key_delete (*p_tls);
+#elif defined( UNDER_CE )
+#elif defined( WIN32 )
+    TlsFree (*p_tls);
+#else
+# error Unimplemented!
+#endif
+}
+
 /*****************************************************************************
  * vlc_thread_create: create a thread, inner version
  *****************************************************************************
@@ -450,27 +471,23 @@ int __vlc_thread_create( vlc_object_t *p_this, const char * psz_file, int i_line
          * memory leaks and the signal functions not working (see Microsoft
          * Knowledge Base, article 104641) */
 #if defined( UNDER_CE )
-        DWORD  threadId;
         HANDLE hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)func,
-                                      (LPVOID)p_data, CREATE_SUSPENDED,
-                      &threadId );
+                                       (LPVOID)p_data, CREATE_SUSPENDED,
+                                        NULL );
 #else
-        unsigned threadId;
-        uintptr_t hThread = _beginthreadex( NULL, 0,
-                        (LPTHREAD_START_ROUTINE)func,
-                                            (void*)p_data, CREATE_SUSPENDED,
-                        &threadId );
+        HANDLE hThread = (HANDLE)(uintptr_t)
+            _beginthreadex( NULL, 0, (LPTHREAD_START_ROUTINE)func,
+                            (void *)p_data, CREATE_SUSPENDED, NULL );
 #endif
-        p_priv->thread_id.id = (DWORD)threadId;
-        p_priv->thread_id.hThread = (HANDLE)hThread;
-        ResumeThread((HANDLE)hThread);
+        p_priv->thread_id = hThread;
+        ResumeThread(hThread);
     }
 
-    i_ret = ( p_priv->thread_id.hThread ? 0 : 1 );
+    i_ret = ( p_priv->thread_id ? 0 : errno );
 
     if( !i_ret && i_priority )
     {
-        if( !SetThreadPriority(p_priv->thread_id.hThread, i_priority) )
+        if( !SetThreadPriority(p_priv->thread_id, i_priority) )
         {
             msg_Warn( p_this, "couldn't set a faster priority" );
             i_priority = 0;
@@ -493,16 +510,9 @@ int __vlc_thread_create( vlc_object_t *p_this, const char * psz_file, int i_line
         }
 
         p_priv->b_thread = true;
-
-#if defined( WIN32 ) || defined( UNDER_CE )
-        msg_Dbg( p_this, "thread %u (%s) created at priority %d (%s:%d)",
-                 (unsigned int)p_priv->thread_id.id, psz_name, i_priority,
+        msg_Dbg( p_this, "thread %lu (%s) created at priority %d (%s:%d)",
+                 (unsigned long)p_priv->thread_id, psz_name, i_priority,
                  psz_file, i_line );
-#else
-        msg_Dbg( p_this, "thread %u (%s) created at priority %d (%s:%d)",
-                 (unsigned int)p_priv->thread_id, psz_name, i_priority,
-                 psz_file, i_line );
-#endif
     }
     else
     {
@@ -560,9 +570,9 @@ int __vlc_thread_set_priority( vlc_object_t *p_this, const char * psz_file,
 #elif defined( WIN32 ) || defined( UNDER_CE )
     VLC_UNUSED( psz_file); VLC_UNUSED( i_line );
 
-    if( !p_priv->thread_id.hThread )
-        p_priv->thread_id.hThread = GetCurrentThread();
-    if( !SetThreadPriority(p_priv->thread_id.hThread, i_priority) )
+    if( !p_priv->thread_id )
+        p_priv->thread_id = GetCurrentThread();
+    if( !SetThreadPriority(p_priv->thread_id, i_priority) )
     {
         msg_Warn( p_this, "couldn't set a faster priority" );
         return 1;
@@ -610,25 +620,20 @@ void __vlc_thread_join( vlc_object_t *p_this, const char * psz_file, int i_line
     ** to be on the safe side
     */
     if( ! DuplicateHandle(GetCurrentProcess(),
-            p_priv->thread_id.hThread,
+            p_priv->thread_id,
             GetCurrentProcess(),
             &hThread,
             0,
             FALSE,
             DUPLICATE_SAME_ACCESS) )
     {
-        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 = false;
-        return;
+        i_ret = GetLastError();
+        goto error;
     }
 
     WaitForSingleObject( hThread, INFINITE );
 
-    msg_Dbg( p_this, "thread %u joined (%s:%d)",
-             (unsigned int)p_priv->thread_id.id,
-             psz_file, i_line );
 #if defined( UNDER_CE )
     hmodule = GetModuleHandle( _T("COREDLL") );
 #else
@@ -665,6 +670,7 @@ void __vlc_thread_join( vlc_object_t *p_this, const char * psz_file, int i_line
                  (double)((user_time%(60*1000000))/1000000.0) );
     }
     CloseHandle( hThread );
+error:
 
 #elif defined( HAVE_KERNEL_SCHEDULER_H )
     int32_t exit_value;
@@ -675,12 +681,12 @@ void __vlc_thread_join( vlc_object_t *p_this, const char * psz_file, int i_line
     if( i_ret )
     {
         errno = i_ret;
-        msg_Err( p_this, "thread_join(%u) failed at %s:%d (%m)",
-                         (unsigned int)p_priv->thread_id, psz_file, i_line );
+        msg_Err( p_this, "thread_join(%lu) failed at %s:%d (%m)",
+                         (unsigned long)p_priv->thread_id, psz_file, i_line );
     }
     else
-        msg_Dbg( p_this, "thread %u joined (%s:%d)",
-                         (unsigned int)p_priv->thread_id, psz_file, i_line );
+        msg_Dbg( p_this, "thread %lu joined (%s:%d)",
+                         (unsigned long)p_priv->thread_id, psz_file, i_line );
 
     p_priv->b_thread = false;
 }