mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-08 13:22:53 +02:00
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 <rsbultje@gmail.com>
This commit is contained in:
parent
021914e27f
commit
2003a29284
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user