Win32: use native Win32 functions directly for static mutexes
authorRémi Denis-Courmont <remi@remlab.net>
Thu, 18 Aug 2011 14:37:31 +0000 (17:37 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Thu, 18 Aug 2011 14:13:05 +0000 (17:13 +0300)
 * No recursion within the VLC threading functions.
 * No need to care about VLC cancellation.

src/win32/thread.c

index 17ca410..6831cbe 100644 (file)
@@ -61,8 +61,8 @@ struct vlc_thread
     void          *data;
 };
 
-static vlc_mutex_t super_mutex;
-static vlc_cond_t  super_variable;
+static CRITICAL_SECTION super_mutex;
+static HANDLE           super_cond;
 
 BOOL WINAPI DllMain (HINSTANCE, DWORD, LPVOID);
 
@@ -74,15 +74,17 @@ BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
     switch (fdwReason)
     {
         case DLL_PROCESS_ATTACH:
-            vlc_mutex_init (&super_mutex);
-            vlc_cond_init (&super_variable);
+            super_cond = CreateEvent (NULL, TRUE, FALSE, NULL);
+            if (unlikely(!super_cond))
+                return FALSE;
+            InitializeCriticalSection (&super_mutex);
             vlc_threadvar_create (&thread_key, NULL);
             break;
 
         case DLL_PROCESS_DETACH:
             vlc_threadvar_delete (&thread_key);
-            vlc_cond_destroy (&super_variable);
-            vlc_mutex_destroy (&super_mutex);
+            DeleteCriticalSection (&super_mutex);
+            CloseHandle (super_cond);
             break;
     }
     return TRUE;
@@ -173,20 +175,19 @@ void vlc_mutex_destroy (vlc_mutex_t *p_mutex)
 void vlc_mutex_lock (vlc_mutex_t *p_mutex)
 {
     if (!p_mutex->dynamic)
-    {   /* static mutexes */
-        int canc = vlc_savecancel ();
-        assert (p_mutex != &super_mutex); /* this one cannot be static */
-
-        vlc_mutex_lock (&super_mutex);
+    {   /* static mutexes (inefficient on Windows) */
+        EnterCriticalSection (&super_mutex);
         while (p_mutex->locked)
         {
             p_mutex->contention++;
-            vlc_cond_wait (&super_variable, &super_mutex);
+            LeaveCriticalSection (&super_mutex);
+            WaitForSingleObject (super_cond, INFINITE);
+            EnterCriticalSection (&super_mutex);
+            assert (p_mutex->contention > 0);
             p_mutex->contention--;
         }
         p_mutex->locked = true;
-        vlc_mutex_unlock (&super_mutex);
-        vlc_restorecancel (canc);
+        LeaveCriticalSection (&super_mutex);
         return;
     }
 
@@ -199,14 +200,13 @@ int vlc_mutex_trylock (vlc_mutex_t *p_mutex)
     {   /* static mutexes */
         int ret = EBUSY;
 
-        assert (p_mutex != &super_mutex); /* this one cannot be static */
-        vlc_mutex_lock (&super_mutex);
+        EnterCriticalSection (&super_mutex);
         if (!p_mutex->locked)
         {
             p_mutex->locked = true;
             ret = 0;
         }
-        vlc_mutex_unlock (&super_mutex);
+        LeaveCriticalSection (&super_mutex);
         return ret;
     }
 
@@ -217,14 +217,12 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
 {
     if (!p_mutex->dynamic)
     {   /* static mutexes */
-        assert (p_mutex != &super_mutex); /* this one cannot be static */
-
-        vlc_mutex_lock (&super_mutex);
+        EnterCriticalSection (&super_mutex);
         assert (p_mutex->locked);
         p_mutex->locked = false;
-        if (p_mutex->contention)
-            vlc_cond_broadcast (&super_variable);
-        vlc_mutex_unlock (&super_mutex);
+        if (p_mutex->contention > 0)
+            SetEvent (super_cond);
+        LeaveCriticalSection (&super_mutex);
         return;
     }
 
@@ -476,10 +474,10 @@ int vlc_threadvar_create (vlc_threadvar_t *p_tls, void (*destr) (void *))
     var->next = NULL;
     *p_tls = var;
 
-    vlc_mutex_lock (&super_mutex);
+    EnterCriticalSection (&super_mutex);
     var->prev = vlc_threadvar_last;
     vlc_threadvar_last = var;
-    vlc_mutex_unlock (&super_mutex);
+    LeaveCriticalSection (&super_mutex);
     return 0;
 }
 
@@ -487,14 +485,14 @@ void vlc_threadvar_delete (vlc_threadvar_t *p_tls)
 {
     struct vlc_threadvar *var = *p_tls;
 
-    vlc_mutex_lock (&super_mutex);
+    EnterCriticalSection (&super_mutex);
     if (var->prev != NULL)
         var->prev->next = var->next;
     else
         vlc_threadvar_last = var->next;
     if (var->next != NULL)
         var->next->prev = var->prev;
-    vlc_mutex_unlock (&super_mutex);
+    LeaveCriticalSection (&super_mutex);
 
     TlsFree (var->id);
     free (var);
@@ -522,19 +520,19 @@ static void vlc_thread_cleanup (struct vlc_thread *th)
 
 retry:
     /* TODO: use RW lock or something similar */
-    vlc_mutex_lock (&super_mutex);
+    EnterCriticalSection (&super_mutex);
     for (key = vlc_threadvar_last; key != NULL; key = key->prev)
     {
         void *value = vlc_threadvar_get (key);
         if (value != NULL && key->destroy != NULL)
         {
-            vlc_mutex_unlock (&super_mutex);
+            EnterCriticalSection (&super_mutex);
             vlc_threadvar_set (key, NULL);
             key->destroy (value);
             goto retry;
         }
     }
-    vlc_mutex_unlock (&super_mutex);
+    EnterCriticalSection (&super_mutex);
 
     if (th->detached)
     {