mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-28 22:10:34 +00:00
w32thread: port fixes to pthread_cond_broadcast() from x264.
This commit is contained in:
parent
d8538f06e6
commit
8b03d7fe95
@ -115,9 +115,12 @@ static inline int pthread_mutex_unlock(pthread_mutex_t *m)
|
|||||||
/* for pre-Windows 6.0 platforms we need to define and use our own condition
|
/* for pre-Windows 6.0 platforms we need to define and use our own condition
|
||||||
* variable and api */
|
* variable and api */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
pthread_mutex_t mtx_broadcast;
|
||||||
pthread_mutex_t mtx_waiter_count;
|
pthread_mutex_t mtx_waiter_count;
|
||||||
volatile int waiter_count;
|
volatile int waiter_count;
|
||||||
HANDLE semaphore;
|
HANDLE semaphore;
|
||||||
|
HANDLE waiters_done;
|
||||||
|
int is_broadcast;
|
||||||
} win32_cond_t;
|
} win32_cond_t;
|
||||||
|
|
||||||
static void pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
|
static void pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
|
||||||
@ -136,8 +139,12 @@ static void pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
|
|||||||
win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
|
win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
|
||||||
if (!win32_cond->semaphore)
|
if (!win32_cond->semaphore)
|
||||||
return;
|
return;
|
||||||
|
win32_cond->waiters_done = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
if (!win32_cond->waiters_done)
|
||||||
|
return;
|
||||||
|
|
||||||
pthread_mutex_init(&win32_cond->mtx_waiter_count, NULL);
|
pthread_mutex_init(&win32_cond->mtx_waiter_count, NULL);
|
||||||
|
pthread_mutex_init(&win32_cond->mtx_broadcast, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pthread_cond_destroy(pthread_cond_t *cond)
|
static void pthread_cond_destroy(pthread_cond_t *cond)
|
||||||
@ -149,7 +156,9 @@ static void pthread_cond_destroy(pthread_cond_t *cond)
|
|||||||
|
|
||||||
/* non native condition variables */
|
/* non native condition variables */
|
||||||
CloseHandle(win32_cond->semaphore);
|
CloseHandle(win32_cond->semaphore);
|
||||||
|
CloseHandle(win32_cond->waiters_done);
|
||||||
pthread_mutex_destroy(&win32_cond->mtx_waiter_count);
|
pthread_mutex_destroy(&win32_cond->mtx_waiter_count);
|
||||||
|
pthread_mutex_destroy(&win32_cond->mtx_broadcast);
|
||||||
av_freep(&win32_cond);
|
av_freep(&win32_cond);
|
||||||
cond->ptr = NULL;
|
cond->ptr = NULL;
|
||||||
}
|
}
|
||||||
@ -157,41 +166,70 @@ static void pthread_cond_destroy(pthread_cond_t *cond)
|
|||||||
static void pthread_cond_broadcast(pthread_cond_t *cond)
|
static void pthread_cond_broadcast(pthread_cond_t *cond)
|
||||||
{
|
{
|
||||||
win32_cond_t *win32_cond = cond->ptr;
|
win32_cond_t *win32_cond = cond->ptr;
|
||||||
|
int have_waiter;
|
||||||
|
|
||||||
if (cond_broadcast) {
|
if (cond_broadcast) {
|
||||||
cond_broadcast(cond);
|
cond_broadcast(cond);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* non native condition variables */
|
/* non native condition variables */
|
||||||
|
pthread_mutex_lock(&win32_cond->mtx_broadcast);
|
||||||
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
||||||
|
have_waiter = 0;
|
||||||
|
|
||||||
if (win32_cond->waiter_count) {
|
if (win32_cond->waiter_count) {
|
||||||
ReleaseSemaphore(win32_cond->semaphore, win32_cond->waiter_count, NULL);
|
win32_cond->is_broadcast = 1;
|
||||||
win32_cond->waiter_count = 0;
|
have_waiter = 1;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
|
||||||
|
if (have_waiter) {
|
||||||
|
ReleaseSemaphore(win32_cond->semaphore, win32_cond->waiter_count, NULL);
|
||||||
|
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||||
|
WaitForSingleObject(win32_cond->waiters_done, INFINITE);
|
||||||
|
win32_cond->is_broadcast = 0;
|
||||||
|
} else
|
||||||
|
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||||
|
pthread_mutex_unlock(&win32_cond->mtx_broadcast);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
static void pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||||
{
|
{
|
||||||
win32_cond_t *win32_cond = cond->ptr;
|
win32_cond_t *win32_cond = cond->ptr;
|
||||||
|
int last_waiter;
|
||||||
if (cond_wait) {
|
if (cond_wait) {
|
||||||
cond_wait(cond, mutex, INFINITE);
|
cond_wait(cond, mutex, INFINITE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* non native condition variables */
|
/* 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);
|
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
||||||
win32_cond->waiter_count++;
|
win32_cond->waiter_count++;
|
||||||
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||||
|
|
||||||
|
// unlock the external mutex
|
||||||
pthread_mutex_unlock(mutex);
|
pthread_mutex_unlock(mutex);
|
||||||
WaitForSingleObject(win32_cond->semaphore, INFINITE);
|
WaitForSingleObject(win32_cond->semaphore, INFINITE);
|
||||||
pthread_mutex_lock(mutex);
|
|
||||||
|
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
||||||
|
win32_cond->waiter_count--;
|
||||||
|
last_waiter = !win32_cond->waiter_count && win32_cond->is_broadcast;
|
||||||
|
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||||
|
|
||||||
|
if (last_waiter)
|
||||||
|
SetEvent(win32_cond->waiters_done);
|
||||||
|
|
||||||
|
// lock the external mutex
|
||||||
|
return pthread_mutex_lock(mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pthread_cond_signal(pthread_cond_t *cond)
|
static void pthread_cond_signal(pthread_cond_t *cond)
|
||||||
{
|
{
|
||||||
win32_cond_t *win32_cond = cond->ptr;
|
win32_cond_t *win32_cond = cond->ptr;
|
||||||
|
int have_waiter;
|
||||||
if (cond_signal) {
|
if (cond_signal) {
|
||||||
cond_signal(cond);
|
cond_signal(cond);
|
||||||
return;
|
return;
|
||||||
@ -199,11 +237,11 @@ static void pthread_cond_signal(pthread_cond_t *cond)
|
|||||||
|
|
||||||
/* non-native condition variables */
|
/* non-native condition variables */
|
||||||
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
|
||||||
if (win32_cond->waiter_count) {
|
have_waiter = win32_cond->waiter_count;
|
||||||
ReleaseSemaphore(win32_cond->semaphore, 1, NULL);
|
|
||||||
win32_cond->waiter_count--;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
|
||||||
|
|
||||||
|
if (have_waiter)
|
||||||
|
ReleaseSemaphore(win32_cond->semaphore, 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void w32thread_init(void)
|
static void w32thread_init(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user