projects
/
ffmpeg.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
d8538f0
)
w32thread: port fixes to pthread_cond_broadcast() from x264.
author
Ronald S. Bultje
<rsbultje@gmail.com>
Wed, 7 Dec 2011 04:42:55 +0000
(20:42 -0800)
committer
Ronald S. Bultje
<rsbultje@gmail.com>
Wed, 7 Dec 2011 18:30:54 +0000
(10:30 -0800)
libavcodec/w32pthreads.h
patch
|
blob
|
history
diff --git
a/libavcodec/w32pthreads.h
b/libavcodec/w32pthreads.h
index
c015b87
..
2d1470c
100644
(file)
--- a/
libavcodec/w32pthreads.h
+++ b/
libavcodec/w32pthreads.h
@@
-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
* variable and api */
typedef struct {
/* for pre-Windows 6.0 platforms we need to define and use our own condition
* variable and api */
typedef struct {
+ pthread_mutex_t mtx_broadcast;
pthread_mutex_t mtx_waiter_count;
volatile int waiter_count;
HANDLE semaphore;
pthread_mutex_t mtx_waiter_count;
volatile int waiter_count;
HANDLE semaphore;
+ HANDLE waiters_done;
+ int is_broadcast;
} win32_cond_t;
static void pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
} win32_cond_t;
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);
if (!win32_cond->semaphore)
return;
win32_cond->semaphore = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
if (!win32_cond->semaphore)
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 */
CloseHandle(win32_cond->semaphore);
/* non native condition variables */
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);
cond->ptr = NULL;
}
av_freep(&win32_cond);
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)
{
win32_cond_t *win32_cond = cond->ptr;
static void pthread_cond_broadcast(pthread_cond_t *cond)
{
win32_cond_t *win32_cond = cond->ptr;
+ int have_waiter;
+
if (cond_broadcast) {
cond_broadcast(cond);
return;
}
/* non native condition variables */
if (cond_broadcast) {
cond_broadcast(cond);
return;
}
/* 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->waiter_count = 0
;
+
win32_cond->is_broadcast = 1
;
+
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)
{
win32_cond_t *win32_cond = cond->ptr;
}
static void pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
win32_cond_t *win32_cond = cond->ptr;
+ int last_waiter;
if (cond_wait) {
cond_wait(cond, mutex, INFINITE);
return;
}
/* non native condition variables */
if (cond_wait) {
cond_wait(cond, mutex, INFINITE);
return;
}
/* 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_lock(&win32_cond->mtx_waiter_count);
win32_cond->waiter_count++;
pthread_mutex_unlock(&win32_cond->mtx_waiter_count);
+ // unlock the external mutex
pthread_mutex_unlock(mutex);
WaitForSingleObject(win32_cond->semaphore, INFINITE);
pthread_mutex_unlock(mutex);
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)
{
win32_cond_t *win32_cond = cond->ptr;
}
static void pthread_cond_signal(pthread_cond_t *cond)
{
win32_cond_t *win32_cond = cond->ptr;
+ int have_waiter;
if (cond_signal) {
cond_signal(cond);
return;
if (cond_signal) {
cond_signal(cond);
return;
@@
-199,11
+237,11
@@
static void pthread_cond_signal(pthread_cond_t *cond)
/* non-native condition variables */
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
/* non-native condition variables */
pthread_mutex_lock(&win32_cond->mtx_waiter_count);
- if (win32_cond->waiter_count) {
- ReleaseSemaphore(win32_cond->semaphore, 1, NULL);
- win32_cond->waiter_count--;
- }
+ have_waiter = 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)