[vlc-commits] win32: fix missing unlock/lock with static condition variables
Rémi Denis-Courmont
git at videolan.org
Sun May 17 16:04:24 CEST 2015
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun May 17 16:32:16 2015 +0300| [15f97d29d2f84b13eab70c85bc46040f79370575] | committer: Rémi Denis-Courmont
win32: fix missing unlock/lock with static condition variables
The mutex needs to be unlocked while the thread sleeps. Otherwise, a
deadlock may occur in case of contention for the mutex.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=15f97d29d2f84b13eab70c85bc46040f79370575
---
src/win32/thread.c | 48 +++++++++++++++++++++++++++---------------------
1 file changed, 27 insertions(+), 21 deletions(-)
diff --git a/src/win32/thread.c b/src/win32/thread.c
index d1e66a4..cc3ac3d 100644
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -196,9 +196,8 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
/*** Condition variables ***/
enum
{
- VLC_CLOCK_STATIC=0, /* must be zero for VLC_STATIC_COND */
+ VLC_CLOCK_REALTIME=0, /* must be zero for VLC_STATIC_COND */
VLC_CLOCK_MONOTONIC,
- VLC_CLOCK_REALTIME,
};
static void vlc_cond_init_common(vlc_cond_t *wait, unsigned clock)
@@ -243,7 +242,7 @@ static LONG InterlockedDecrementNonZero(LONG volatile *dst)
void vlc_cond_signal(vlc_cond_t *wait)
{
- if (!wait->clock)
+ if (wait->semaphore == NULL)
return;
if (InterlockedDecrementNonZero(&wait->waiters) > 0)
@@ -252,7 +251,7 @@ void vlc_cond_signal(vlc_cond_t *wait)
void vlc_cond_broadcast(vlc_cond_t *wait)
{
- if (!wait->clock)
+ if (wait->semaphore == NULL)
return;
LONG waiters = InterlockedExchange(&wait->waiters, 0);
@@ -266,15 +265,17 @@ void vlc_cond_wait(vlc_cond_t *wait, vlc_mutex_t *lock)
vlc_testcancel();
- if (!wait->clock)
+ if (wait->semaphore == NULL)
{ /* FIXME FIXME FIXME */
- msleep (50000);
- return;
+ vlc_mutex_unlock(lock);
+ result = SleepEx(50, TRUE);
+ }
+ else
+ {
+ InterlockedIncrement(&wait->waiters);
+ vlc_mutex_unlock(lock);
+ result = vlc_WaitForSingleObject(wait->semaphore, INFINITE);
}
-
- InterlockedIncrement(&wait->waiters);
- vlc_mutex_unlock(lock);
- result = vlc_WaitForSingleObject(wait->semaphore, INFINITE);
vlc_mutex_lock(lock);
if (result == WAIT_IO_COMPLETION)
@@ -290,17 +291,14 @@ int vlc_cond_timedwait(vlc_cond_t *wait, vlc_mutex_t *lock, mtime_t deadline)
switch (wait->clock)
{
- case VLC_CLOCK_MONOTONIC:
- total = mdate();
- break;
case VLC_CLOCK_REALTIME: /* FIXME? sub-second precision */
total = CLOCK_FREQ * time(NULL);
break;
+ case VLC_CLOCK_MONOTONIC:
+ total = mdate();
+ break;
default:
- assert(!wait->clock);
- /* FIXME FIXME FIXME */
- msleep(50000);
- return 0;
+ vlc_assert_unreachable();
}
total = (deadline - total) / 1000;
@@ -309,9 +307,17 @@ int vlc_cond_timedwait(vlc_cond_t *wait, vlc_mutex_t *lock, mtime_t deadline)
DWORD delay = (total > 0x7fffffff) ? 0x7fffffff : total;
- InterlockedIncrement(&wait->waiters);
- vlc_mutex_unlock(lock);
- result = vlc_WaitForSingleObject(wait->semaphore, delay);
+ if (wait->semaphore == NULL)
+ { /* FIXME FIXME FIXME */
+ vlc_mutex_unlock(lock);
+ result = SleepEx((delay > 50) ? 50 : delay, TRUE);
+ }
+ else
+ {
+ InterlockedIncrement(&wait->waiters);
+ vlc_mutex_unlock(lock);
+ result = vlc_WaitForSingleObject(wait->semaphore, delay);
+ }
vlc_mutex_lock(lock);
if (result == WAIT_IO_COMPLETION)
More information about the vlc-commits
mailing list