Commit 6e54f3fd authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Win32: use native Win32 functions directly for static mutexes

 * No recursion within the VLC threading functions.
 * No need to care about VLC cancellation.
parent ffe5a11f
...@@ -61,8 +61,8 @@ struct vlc_thread ...@@ -61,8 +61,8 @@ struct vlc_thread
void *data; void *data;
}; };
static vlc_mutex_t super_mutex; static CRITICAL_SECTION super_mutex;
static vlc_cond_t super_variable; static HANDLE super_cond;
BOOL WINAPI DllMain (HINSTANCE, DWORD, LPVOID); BOOL WINAPI DllMain (HINSTANCE, DWORD, LPVOID);
...@@ -74,15 +74,17 @@ BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved) ...@@ -74,15 +74,17 @@ BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
switch (fdwReason) switch (fdwReason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
vlc_mutex_init (&super_mutex); super_cond = CreateEvent (NULL, TRUE, FALSE, NULL);
vlc_cond_init (&super_variable); if (unlikely(!super_cond))
return FALSE;
InitializeCriticalSection (&super_mutex);
vlc_threadvar_create (&thread_key, NULL); vlc_threadvar_create (&thread_key, NULL);
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
vlc_threadvar_delete (&thread_key); vlc_threadvar_delete (&thread_key);
vlc_cond_destroy (&super_variable); DeleteCriticalSection (&super_mutex);
vlc_mutex_destroy (&super_mutex); CloseHandle (super_cond);
break; break;
} }
return TRUE; return TRUE;
...@@ -173,20 +175,19 @@ void vlc_mutex_destroy (vlc_mutex_t *p_mutex) ...@@ -173,20 +175,19 @@ void vlc_mutex_destroy (vlc_mutex_t *p_mutex)
void vlc_mutex_lock (vlc_mutex_t *p_mutex) void vlc_mutex_lock (vlc_mutex_t *p_mutex)
{ {
if (!p_mutex->dynamic) if (!p_mutex->dynamic)
{ /* static mutexes */ { /* static mutexes (inefficient on Windows) */
int canc = vlc_savecancel (); EnterCriticalSection (&super_mutex);
assert (p_mutex != &super_mutex); /* this one cannot be static */
vlc_mutex_lock (&super_mutex);
while (p_mutex->locked) while (p_mutex->locked)
{ {
p_mutex->contention++; 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->contention--;
} }
p_mutex->locked = true; p_mutex->locked = true;
vlc_mutex_unlock (&super_mutex); LeaveCriticalSection (&super_mutex);
vlc_restorecancel (canc);
return; return;
} }
...@@ -199,14 +200,13 @@ int vlc_mutex_trylock (vlc_mutex_t *p_mutex) ...@@ -199,14 +200,13 @@ int vlc_mutex_trylock (vlc_mutex_t *p_mutex)
{ /* static mutexes */ { /* static mutexes */
int ret = EBUSY; int ret = EBUSY;
assert (p_mutex != &super_mutex); /* this one cannot be static */ EnterCriticalSection (&super_mutex);
vlc_mutex_lock (&super_mutex);
if (!p_mutex->locked) if (!p_mutex->locked)
{ {
p_mutex->locked = true; p_mutex->locked = true;
ret = 0; ret = 0;
} }
vlc_mutex_unlock (&super_mutex); LeaveCriticalSection (&super_mutex);
return ret; return ret;
} }
...@@ -217,14 +217,12 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex) ...@@ -217,14 +217,12 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
{ {
if (!p_mutex->dynamic) if (!p_mutex->dynamic)
{ /* static mutexes */ { /* static mutexes */
assert (p_mutex != &super_mutex); /* this one cannot be static */ EnterCriticalSection (&super_mutex);
vlc_mutex_lock (&super_mutex);
assert (p_mutex->locked); assert (p_mutex->locked);
p_mutex->locked = false; p_mutex->locked = false;
if (p_mutex->contention) if (p_mutex->contention > 0)
vlc_cond_broadcast (&super_variable); SetEvent (super_cond);
vlc_mutex_unlock (&super_mutex); LeaveCriticalSection (&super_mutex);
return; return;
} }
...@@ -476,10 +474,10 @@ int vlc_threadvar_create (vlc_threadvar_t *p_tls, void (*destr) (void *)) ...@@ -476,10 +474,10 @@ int vlc_threadvar_create (vlc_threadvar_t *p_tls, void (*destr) (void *))
var->next = NULL; var->next = NULL;
*p_tls = var; *p_tls = var;
vlc_mutex_lock (&super_mutex); EnterCriticalSection (&super_mutex);
var->prev = vlc_threadvar_last; var->prev = vlc_threadvar_last;
vlc_threadvar_last = var; vlc_threadvar_last = var;
vlc_mutex_unlock (&super_mutex); LeaveCriticalSection (&super_mutex);
return 0; return 0;
} }
...@@ -487,14 +485,14 @@ void vlc_threadvar_delete (vlc_threadvar_t *p_tls) ...@@ -487,14 +485,14 @@ void vlc_threadvar_delete (vlc_threadvar_t *p_tls)
{ {
struct vlc_threadvar *var = *p_tls; struct vlc_threadvar *var = *p_tls;
vlc_mutex_lock (&super_mutex); EnterCriticalSection (&super_mutex);
if (var->prev != NULL) if (var->prev != NULL)
var->prev->next = var->next; var->prev->next = var->next;
else else
vlc_threadvar_last = var->next; vlc_threadvar_last = var->next;
if (var->next != NULL) if (var->next != NULL)
var->next->prev = var->prev; var->next->prev = var->prev;
vlc_mutex_unlock (&super_mutex); LeaveCriticalSection (&super_mutex);
TlsFree (var->id); TlsFree (var->id);
free (var); free (var);
...@@ -522,19 +520,19 @@ static void vlc_thread_cleanup (struct vlc_thread *th) ...@@ -522,19 +520,19 @@ static void vlc_thread_cleanup (struct vlc_thread *th)
retry: retry:
/* TODO: use RW lock or something similar */ /* 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) for (key = vlc_threadvar_last; key != NULL; key = key->prev)
{ {
void *value = vlc_threadvar_get (key); void *value = vlc_threadvar_get (key);
if (value != NULL && key->destroy != NULL) if (value != NULL && key->destroy != NULL)
{ {
vlc_mutex_unlock (&super_mutex); EnterCriticalSection (&super_mutex);
vlc_threadvar_set (key, NULL); vlc_threadvar_set (key, NULL);
key->destroy (value); key->destroy (value);
goto retry; goto retry;
} }
} }
vlc_mutex_unlock (&super_mutex); EnterCriticalSection (&super_mutex);
if (th->detached) if (th->detached)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment