[vlc-devel] [PATCH] win32: in debug builds make sure the non-recursive locks are not reentrant
Steve Lhomme
robux4 at videolabs.io
Sun Jun 5 14:35:58 CEST 2016
Use a semaphore with a single token for non recursive locks
Use the same code as non-debug builds with recursive locks
--
hopefully fixes the make check header issue in https://patches.videolan.org/patch/13618/
---
include/vlc_threads.h | 4 ++++
src/win32/thread.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 53 insertions(+)
diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index 33b9b53..08b10f2 100644
--- a/include/vlc_threads.h
+++ b/include/vlc_threads.h
@@ -66,6 +66,10 @@ typedef struct
unsigned long contention;
};
CRITICAL_SECTION mutex;
+
+ /* non-recursive semaphore */
+ HANDLE hMutex;
+ unsigned long lock_thread_id;
};
} vlc_mutex_t;
#define VLC_STATIC_MUTEX { false, { { false, 0 } } }
diff --git a/src/win32/thread.c b/src/win32/thread.c
index 963a8d7..0fab5ad 100644
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -43,6 +43,12 @@
static vlc_mutex_t super_mutex;
static vlc_cond_t super_variable;
+#ifndef NDEBUG
+#define MUTEX_ALWAYS_RECURSIVE 0
+#else
+#define MUTEX_ALWAYS_RECURSIVE 1
+#endif
+
#define IS_INTERRUPTIBLE (!VLC_WINSTORE_APP || _WIN32_WINNT >= 0x0A00)
/*** Threads ***/
@@ -71,13 +77,20 @@ 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. */
+#if MUTEX_ALWAYS_RECURSIVE
InitializeCriticalSection (&p_mutex->mutex);
+#else
+ p_mutex->hMutex = CreateSemaphore( NULL, 1, 1, NULL );
+#endif
p_mutex->dynamic = true;
}
void vlc_mutex_init_recursive( vlc_mutex_t *p_mutex )
{
InitializeCriticalSection( &p_mutex->mutex );
+#if !MUTEX_ALWAYS_RECURSIVE
+ p_mutex->hMutex = INVALID_HANDLE_VALUE;
+#endif
p_mutex->dynamic = true;
}
@@ -85,6 +98,11 @@ void vlc_mutex_init_recursive( vlc_mutex_t *p_mutex )
void vlc_mutex_destroy (vlc_mutex_t *p_mutex)
{
assert (p_mutex->dynamic);
+#if !MUTEX_ALWAYS_RECURSIVE
+ if ( p_mutex->hMutex != INVALID_HANDLE_VALUE )
+ CloseHandle( p_mutex->hMutex );
+ else
+#endif
DeleteCriticalSection (&p_mutex->mutex);
}
@@ -108,6 +126,15 @@ void vlc_mutex_lock (vlc_mutex_t *p_mutex)
return;
}
+#if !MUTEX_ALWAYS_RECURSIVE
+ if ( p_mutex->hMutex != INVALID_HANDLE_VALUE )
+ {
+ assert(p_mutex->lock_thread_id != vlc_thread_id());
+ WaitForSingleObject( p_mutex->hMutex, INFINITE );
+ p_mutex->lock_thread_id = vlc_thread_id();
+ }
+ else
+#endif
EnterCriticalSection (&p_mutex->mutex);
}
@@ -128,6 +155,20 @@ int vlc_mutex_trylock (vlc_mutex_t *p_mutex)
return ret;
}
+#if !MUTEX_ALWAYS_RECURSIVE
+ if ( p_mutex->hMutex != INVALID_HANDLE_VALUE )
+ {
+ assert(p_mutex->lock_thread_id != vlc_thread_id());
+ if ( WaitForSingleObject( p_mutex->hMutex, 0 ) == WAIT_OBJECT_0 )
+ {
+ p_mutex->lock_thread_id = vlc_thread_id();
+ return 0;
+ }
+ else
+ return EBUSY;
+ }
+ else
+#endif
return TryEnterCriticalSection (&p_mutex->mutex) ? 0 : EBUSY;
}
@@ -146,6 +187,14 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
return;
}
+#if !MUTEX_ALWAYS_RECURSIVE
+ if ( p_mutex->hMutex != INVALID_HANDLE_VALUE )
+ {
+ p_mutex->lock_thread_id = 0;
+ ReleaseSemaphore( p_mutex->hMutex, 1, NULL );
+ }
+ else
+#endif
LeaveCriticalSection (&p_mutex->mutex);
}
--
2.7.0
More information about the vlc-devel
mailing list