[vlc-devel] [PATCH 1/2] win32: implement non-recursive locks
Steve Lhomme
robux4 at videolabs.io
Tue Jun 21 12:56:29 CEST 2016
locked & b_recursive are always accessed in the CriticalSection
--
simple rebase of https://patches.videolan.org/patch/13641/
---
include/vlc_threads.h | 12 +++++-------
src/win32/thread.c | 30 ++++++++++++++++++++++++------
2 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index 33b9b53..1fe22bf 100644
--- a/include/vlc_threads.h
+++ b/include/vlc_threads.h
@@ -57,18 +57,16 @@ typedef struct vlc_thread *vlc_thread_t;
# define LIBVLC_NEED_SLEEP
typedef struct
{
+ int locked;
+ bool b_recursive;
bool dynamic;
union
{
- struct
- {
- bool locked;
- unsigned long contention;
- };
- CRITICAL_SECTION mutex;
+ unsigned long contention; /* static */
+ CRITICAL_SECTION mutex; /* dynamic */
};
} vlc_mutex_t;
-#define VLC_STATIC_MUTEX { false, { { false, 0 } } }
+#define VLC_STATIC_MUTEX { 0, false, false, { 0 } }
#define LIBVLC_NEED_CONDVAR
#define LIBVLC_NEED_SEMAPHORE
#define LIBVLC_NEED_RWLOCK
diff --git a/src/win32/thread.c b/src/win32/thread.c
index 9eb3db7..8d53185 100644
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -96,15 +96,17 @@ static BOOL WINAPI SleepConditionVariableFallback(CONDITION_VARIABLE *cv,
/*** Mutexes ***/
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->locked = 0;
+ p_mutex->b_recursive = false;
p_mutex->dynamic = true;
}
void vlc_mutex_init_recursive( vlc_mutex_t *p_mutex )
{
InitializeCriticalSection( &p_mutex->mutex );
+ p_mutex->locked = 0;
+ p_mutex->b_recursive = true;
p_mutex->dynamic = true;
}
@@ -126,12 +128,14 @@ void vlc_mutex_lock (vlc_mutex_t *p_mutex)
SleepConditionVariableCS(&super_variable, &super_mutex, INFINITE);
p_mutex->contention--;
}
- p_mutex->locked = true;
+ p_mutex->locked = 1;
LeaveCriticalSection(&super_mutex);
return;
}
EnterCriticalSection (&p_mutex->mutex);
+ assert(!p_mutex->locked || p_mutex->b_recursive);
+ p_mutex->locked++;
}
int vlc_mutex_trylock (vlc_mutex_t *p_mutex)
@@ -143,14 +147,26 @@ int vlc_mutex_trylock (vlc_mutex_t *p_mutex)
EnterCriticalSection(&super_mutex);
if (!p_mutex->locked)
{
- p_mutex->locked = true;
+ p_mutex->locked = 1;
ret = 0;
}
LeaveCriticalSection(&super_mutex);
return ret;
}
- return TryEnterCriticalSection (&p_mutex->mutex) ? 0 : EBUSY;
+ int ret = TryEnterCriticalSection (&p_mutex->mutex);
+ if (ret == 0)
+ return EBUSY;
+
+ assert(!p_mutex->locked || p_mutex->b_recursive);
+ if (unlikely(p_mutex->locked && !p_mutex->b_recursive))
+ {
+ LeaveCriticalSection (&p_mutex->mutex);
+ return EDEADLK; /* we already had the non-recursive lock */
+ }
+
+ p_mutex->locked++;
+ return 0;
}
void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
@@ -159,13 +175,15 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
{ /* static mutexes */
EnterCriticalSection(&super_mutex);
assert (p_mutex->locked);
- p_mutex->locked = false;
+ p_mutex->locked = 0;
if (p_mutex->contention)
WakeAllConditionVariable(&super_variable);
LeaveCriticalSection(&super_mutex);
return;
}
+ p_mutex->locked--;
+ assert(p_mutex->locked >= 0);
LeaveCriticalSection (&p_mutex->mutex);
}
--
2.8.2
More information about the vlc-devel
mailing list