Module: libav Branch: master Commit: 2003a29284660255016b1ec4bd5dfb8d53e6a852
Author: Sergey Radionov <rsa...@gmail.com> Committer: Ronald S. Bultje <rsbul...@gmail.com> Date: Wed Dec 21 09:08:56 2011 +0700 w32threads: wait for the waked thread in pthread_cond_signal. This fixes a deadlock VLC triggered with multithreaded decoding. The wait forces one of the current waiters to wake and not the thread which calls pthread_cond_signal() itself. Signed-off-by: Ronald S. Bultje <rsbul...@gmail.com> --- libavcodec/w32pthreads.h | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-) diff --git a/libavcodec/w32pthreads.h b/libavcodec/w32pthreads.h index 2d1470c..3cdbc2c 100644 --- a/libavcodec/w32pthreads.h +++ b/libavcodec/w32pthreads.h @@ -139,7 +139,7 @@ static void pthread_cond_init(pthread_cond_t *cond, const void *unused_attr) win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL); if (!win32_cond->semaphore) return; - win32_cond->waiters_done = CreateEvent(NULL, FALSE, FALSE, NULL); + win32_cond->waiters_done = CreateEvent(NULL, TRUE, FALSE, NULL); if (!win32_cond->waiters_done) return; @@ -204,11 +204,10 @@ static void pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) /* non native condition variables */ pthread_mutex_lock(&win32_cond->mtx_broadcast); - pthread_mutex_unlock(&win32_cond->mtx_broadcast); - pthread_mutex_lock(&win32_cond->mtx_waiter_count); win32_cond->waiter_count++; pthread_mutex_unlock(&win32_cond->mtx_waiter_count); + pthread_mutex_unlock(&win32_cond->mtx_broadcast); // unlock the external mutex pthread_mutex_unlock(mutex); @@ -216,7 +215,7 @@ static void pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) pthread_mutex_lock(&win32_cond->mtx_waiter_count); win32_cond->waiter_count--; - last_waiter = !win32_cond->waiter_count && win32_cond->is_broadcast; + last_waiter = !win32_cond->waiter_count || !win32_cond->is_broadcast; pthread_mutex_unlock(&win32_cond->mtx_waiter_count); if (last_waiter) @@ -235,13 +234,20 @@ static void pthread_cond_signal(pthread_cond_t *cond) return; } + pthread_mutex_lock(&win32_cond->mtx_broadcast); + /* non-native condition variables */ pthread_mutex_lock(&win32_cond->mtx_waiter_count); have_waiter = win32_cond->waiter_count; pthread_mutex_unlock(&win32_cond->mtx_waiter_count); - if (have_waiter) + if (have_waiter) { ReleaseSemaphore(win32_cond->semaphore, 1, NULL); + WaitForSingleObject(win32_cond->waiters_done, INFINITE); + ResetEvent(win32_cond->waiters_done); + } + + pthread_mutex_unlock(&win32_cond->mtx_broadcast); } static void w32thread_init(void) _______________________________________________ libav-commits mailing list libav-commits@libav.org https://lists.libav.org/mailman/listinfo/libav-commits