[vlc-devel] commit: Win32: emulate static mutexes with a boolean (fix: #2399) ( Rémi Denis-Courmont )
git version control
git at videolan.org
Wed Dec 30 14:56:42 CET 2009
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Dec 30 15:54:54 2009 +0200| [c72c34ea5c92d07f9aac4a86b5840cff213ad57b] | committer: Rémi Denis-Courmont
Win32: emulate static mutexes with a boolean (fix: #2399)
We use the same pattern as the variable callback lock: one mutex,
one condition variable and N boolean flags instead of N mutexes.
This is a bit slower but it shouldn't leak OS handles anymore.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c72c34ea5c92d07f9aac4a86b5840cff213ad57b
---
include/vlc_threads.h | 10 ++++++--
src/misc/w32thread.c | 53 +++++++++++++++++++++++++++++++++---------------
2 files changed, 43 insertions(+), 20 deletions(-)
diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index 1f69541..65a4eb4 100644
--- a/include/vlc_threads.h
+++ b/include/vlc_threads.h
@@ -124,10 +124,14 @@ typedef struct
typedef struct
{
- LONG initialized;
- CRITICAL_SECTION mutex;
+ bool dynamic;
+ union
+ {
+ bool locked;
+ CRITICAL_SECTION mutex;
+ };
} vlc_mutex_t;
-#define VLC_STATIC_MUTEX { 0, }
+#define VLC_STATIC_MUTEX { false, { false } }
typedef HANDLE vlc_cond_t;
typedef HANDLE vlc_sem_t;
diff --git a/src/misc/w32thread.c b/src/misc/w32thread.c
index ee83a9f..f4e247c 100644
--- a/src/misc/w32thread.c
+++ b/src/misc/w32thread.c
@@ -141,6 +141,7 @@ DWORD WaitForMultipleObjectsEx (DWORD nCount, const HANDLE *lpHandles,
#endif
static vlc_mutex_t super_mutex;
+static vlc_cond_t super_variable;
BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
{
@@ -151,11 +152,13 @@ BOOL WINAPI DllMain (HINSTANCE hinstDll, DWORD fdwReason, LPVOID lpvReserved)
{
case DLL_PROCESS_ATTACH:
vlc_mutex_init (&super_mutex);
+ vlc_cond_init (&super_variable);
vlc_threadvar_create (&cancel_key, free);
break;
case DLL_PROCESS_DETACH:
vlc_threadvar_delete( &cancel_key );
+ vlc_cond_destroy (&super_variable);
vlc_mutex_destroy (&super_mutex);
break;
}
@@ -168,57 +171,73 @@ void vlc_mutex_init( vlc_mutex_t *p_mutex )
/* This creates a recursive mutex. This is OK as fast mutexes have
* no defined behavior in case of recursive locking. */
InitializeCriticalSection (&p_mutex->mutex);
- p_mutex->initialized = 1;
+ p_mutex->dynamic = true;
}
void vlc_mutex_init_recursive( vlc_mutex_t *p_mutex )
{
InitializeCriticalSection( &p_mutex->mutex );
- p_mutex->initialized = 1;
+ p_mutex->dynamic = true;
}
void vlc_mutex_destroy (vlc_mutex_t *p_mutex)
{
- assert (InterlockedExchange (&p_mutex->initialized, -1) == 1);
+ assert (p_mutex->dynamic);
DeleteCriticalSection (&p_mutex->mutex);
}
void vlc_mutex_lock (vlc_mutex_t *p_mutex)
{
- if (InterlockedCompareExchange (&p_mutex->initialized, 0, 0) == 0)
- { /* ^^ We could also lock super_mutex all the time... sluggish */
+ if (!p_mutex->dynamic)
+ { /* static mutexes */
assert (p_mutex != &super_mutex); /* this one cannot be static */
vlc_mutex_lock (&super_mutex);
- if (InterlockedCompareExchange (&p_mutex->initialized, 0, 0) == 0)
- vlc_mutex_init (p_mutex);
- /* FIXME: destroy the mutex some time... */
+ while (p_mutex->locked)
+ vlc_cond_wait (&super_mutex, &super_variable);
+ p_mutex->locked = true;
vlc_mutex_unlock (&super_mutex);
+ return;
}
- assert (InterlockedExchange (&p_mutex->initialized, 1) == 1);
+
EnterCriticalSection (&p_mutex->mutex);
}
int vlc_mutex_trylock (vlc_mutex_t *p_mutex)
{
- if (InterlockedCompareExchange (&p_mutex->initialized, 0, 0) == 0)
- { /* ^^ We could also lock super_mutex all the time... sluggish */
- assert (p_mutex != &super_mutex); /* this one cannot be static */
+ if (!p_mutex->dynamic)
+ { /* static mutexes */
+ int ret = EBUSY;
+ assert (p_mutex != &super_mutex); /* this one cannot be static */
vlc_mutex_lock (&super_mutex);
- if (InterlockedCompareExchange (&p_mutex->initialized, 0, 0) == 0)
- vlc_mutex_init (p_mutex);
- /* FIXME: destroy the mutex some time... */
+ if (!p_mutex->locked)
+ {
+ p_mutex->locked = true;
+ ret = 0;
+ }
vlc_mutex_unlock (&super_mutex);
+ return ret;
}
- assert (InterlockedExchange (&p_mutex->initialized, 1) == 1);
+
return TryEnterCriticalSection (&p_mutex->mutex) ? 0 : EBUSY;
}
void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
{
- assert (InterlockedExchange (&p_mutex->initialized, 1) == 1);
+ if (!p_mutex->dynamic)
+ { /* static mutexes */
+ assert (p_mutex != &super_mutex); /* this one cannot be static */
+
+ vlc_mutex_lock (&super_mutex);
+ assert (p_mutex->locked);
+ p_mutex->locked = false;
+ vlc_cond_signal (&super_variable);
+ vlc_mutex_unlock (&super_mutex);
+ return;
+ }
+
LeaveCriticalSection (&p_mutex->mutex);
}
More information about the vlc-devel
mailing list