vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Sun May 17 16:32:16 2015 +0300| [c5f289dada142fac691168bb713d47940a44336e] | 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=c5f289dada142fac691168bb713d47940a44336e --- 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 c30e67d..302e9a2 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) _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
