diff options
author | wm4 <wm4@nowhere> | 2014-04-23 20:45:10 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-04-23 21:16:52 +0200 |
commit | 80ff94131b477ad9156f1c68da7b8588544fee33 (patch) | |
tree | a98ba8c3f4bcf96fc5ba0eb7c7de57a1ab87ab64 /misc/dispatch.c | |
parent | 29b726039821ff3f0435644c791412ed8a75319a (diff) | |
download | mpv-80ff94131b477ad9156f1c68da7b8588544fee33.tar.bz2 mpv-80ff94131b477ad9156f1c68da7b8588544fee33.tar.xz |
dispatch: implement timeout
Note that this mechanism is similarly "unreliable" as for example
pthread_cond_timedwait(). Trying to target the exact wait time will just
make it more complex.
The main use case for this is for threads which either use the dispatch
centrally and want mp_dispatch_queue_process to do a blocking wait for
new work, or threads which have to implement timers. For the former,
anything is fine, as long as they don't have to do active waiting for
new works. For the former, callers are better off recalculating their
deadline after every call.
Diffstat (limited to 'misc/dispatch.c')
-rw-r--r-- | misc/dispatch.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/misc/dispatch.c b/misc/dispatch.c index 53d1829e88..4a5972aff2 100644 --- a/misc/dispatch.c +++ b/misc/dispatch.c @@ -163,17 +163,17 @@ void mp_dispatch_run(struct mp_dispatch_queue *queue, // Process any outstanding dispatch items in the queue. This also handles // suspending or locking the target thread. -// The timeout specifies the maximum wait time, but the actual time spent in -// this function can be much higher if the suspending/locking functions are -// used, or if executing the dispatch items takes time. -// TODO: implement timeout +// The timeout specifies the minimum wait time. The actual time spent in this +// function can be much higher if the suspending/locking functions are used, or +// if executing the dispatch items takes time. On the other hand, this function +// can return much earlier than the timeout due to sporadic wakeups. void mp_dispatch_queue_process(struct mp_dispatch_queue *queue, double timeout) { pthread_mutex_lock(&queue->lock); queue->suspended = true; // Wake up thread which called mp_dispatch_suspend(). pthread_cond_broadcast(&queue->cond); - while (queue->head || queue->suspend_requested) { + while (queue->head || queue->suspend_requested || timeout > 0) { if (queue->head) { struct mp_dispatch_item *item = queue->head; queue->head = item->next; @@ -197,8 +197,13 @@ void mp_dispatch_queue_process(struct mp_dispatch_queue *queue, double timeout) pthread_cond_broadcast(&queue->cond); } } else { - pthread_cond_wait(&queue->cond, &queue->lock); + if (timeout > 0) { + mpthread_cond_timed_wait(&queue->cond, &queue->lock, timeout); + } else { + pthread_cond_wait(&queue->cond, &queue->lock); + } } + timeout = 0; } queue->suspended = false; pthread_mutex_unlock(&queue->lock); |