Browse Source

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>
tags/n0.10
Sergey Radionov Ronald S. Bultje 14 years ago
parent
commit
2003a29284
1 changed files with 11 additions and 5 deletions
  1. +11
    -5
      libavcodec/w32pthreads.h

+ 11
- 5
libavcodec/w32pthreads.h View File

@@ -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…
Cancel
Save