Commit c5f289da authored by Rémi Denis-Courmont's avatar 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.
parent 8762b941
...@@ -196,9 +196,8 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex) ...@@ -196,9 +196,8 @@ void vlc_mutex_unlock (vlc_mutex_t *p_mutex)
/*** Condition variables ***/ /*** Condition variables ***/
enum 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_MONOTONIC,
VLC_CLOCK_REALTIME,
}; };
static void vlc_cond_init_common(vlc_cond_t *wait, unsigned clock) static void vlc_cond_init_common(vlc_cond_t *wait, unsigned clock)
...@@ -243,7 +242,7 @@ static LONG InterlockedDecrementNonZero(LONG volatile *dst) ...@@ -243,7 +242,7 @@ static LONG InterlockedDecrementNonZero(LONG volatile *dst)
void vlc_cond_signal(vlc_cond_t *wait) void vlc_cond_signal(vlc_cond_t *wait)
{ {
if (!wait->clock) if (wait->semaphore == NULL)
return; return;
if (InterlockedDecrementNonZero(&wait->waiters) > 0) if (InterlockedDecrementNonZero(&wait->waiters) > 0)
...@@ -252,7 +251,7 @@ void vlc_cond_signal(vlc_cond_t *wait) ...@@ -252,7 +251,7 @@ void vlc_cond_signal(vlc_cond_t *wait)
void vlc_cond_broadcast(vlc_cond_t *wait) void vlc_cond_broadcast(vlc_cond_t *wait)
{ {
if (!wait->clock) if (wait->semaphore == NULL)
return; return;
LONG waiters = InterlockedExchange(&wait->waiters, 0); LONG waiters = InterlockedExchange(&wait->waiters, 0);
...@@ -266,15 +265,17 @@ void vlc_cond_wait(vlc_cond_t *wait, vlc_mutex_t *lock) ...@@ -266,15 +265,17 @@ void vlc_cond_wait(vlc_cond_t *wait, vlc_mutex_t *lock)
vlc_testcancel(); vlc_testcancel();
if (!wait->clock) if (wait->semaphore == NULL)
{ /* FIXME FIXME FIXME */ { /* FIXME FIXME FIXME */
msleep (50000); vlc_mutex_unlock(lock);
return; 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); vlc_mutex_lock(lock);
if (result == WAIT_IO_COMPLETION) if (result == WAIT_IO_COMPLETION)
...@@ -290,17 +291,14 @@ int vlc_cond_timedwait(vlc_cond_t *wait, vlc_mutex_t *lock, mtime_t deadline) ...@@ -290,17 +291,14 @@ int vlc_cond_timedwait(vlc_cond_t *wait, vlc_mutex_t *lock, mtime_t deadline)
switch (wait->clock) switch (wait->clock)
{ {
case VLC_CLOCK_MONOTONIC:
total = mdate();
break;
case VLC_CLOCK_REALTIME: /* FIXME? sub-second precision */ case VLC_CLOCK_REALTIME: /* FIXME? sub-second precision */
total = CLOCK_FREQ * time(NULL); total = CLOCK_FREQ * time(NULL);
break; break;
case VLC_CLOCK_MONOTONIC:
total = mdate();
break;
default: default:
assert(!wait->clock); vlc_assert_unreachable();
/* FIXME FIXME FIXME */
msleep(50000);
return 0;
} }
total = (deadline - total) / 1000; total = (deadline - total) / 1000;
...@@ -309,9 +307,17 @@ int vlc_cond_timedwait(vlc_cond_t *wait, vlc_mutex_t *lock, mtime_t deadline) ...@@ -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; DWORD delay = (total > 0x7fffffff) ? 0x7fffffff : total;
InterlockedIncrement(&wait->waiters); if (wait->semaphore == NULL)
vlc_mutex_unlock(lock); { /* FIXME FIXME FIXME */
result = vlc_WaitForSingleObject(wait->semaphore, delay); 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); vlc_mutex_lock(lock);
if (result == WAIT_IO_COMPLETION) if (result == WAIT_IO_COMPLETION)
......
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