summaryrefslogtreecommitdiffstats
path: root/misc
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-03-05 21:05:14 +0100
committerwm4 <wm4@nowhere>2020-03-05 22:00:50 +0100
commit50177aaa3b2040cc76d59b2e19687d9016641c39 (patch)
tree24c35a06ce2456cd0200e3c9c343280e6d8fff38 /misc
parentc1ff54e2e4ec3e93f20afac99f085fd632cbcc4e (diff)
downloadmpv-50177aaa3b2040cc76d59b2e19687d9016641c39.tar.bz2
mpv-50177aaa3b2040cc76d59b2e19687d9016641c39.tar.xz
dispatch: add strange mechanism for making worker threads responsive
This is probably a sin for the sake of user experience. See a following commit that wires up f_decoder_wrapper with it.
Diffstat (limited to 'misc')
-rw-r--r--misc/dispatch.c25
-rw-r--r--misc/dispatch.h3
2 files changed, 26 insertions, 2 deletions
diff --git a/misc/dispatch.c b/misc/dispatch.c
index 1102c564ae..0c3c574afa 100644
--- a/misc/dispatch.c
+++ b/misc/dispatch.c
@@ -30,6 +30,8 @@ struct mp_dispatch_queue {
pthread_cond_t cond;
void (*wakeup_fn)(void *wakeup_ctx);
void *wakeup_ctx;
+ void (*onlock_fn)(void *onlock_ctx);
+ void *onlock_ctx;
// Time at which mp_dispatch_queue_process() should return.
int64_t wait;
// Make mp_dispatch_queue_process() exit if it's idle.
@@ -94,8 +96,9 @@ struct mp_dispatch_queue *mp_dispatch_create(void *ta_parent)
// the wakeup_fn could for example write a byte into a "wakeup" pipe in order
// to unblock the select(). The wakeup_fn is called from the dispatch queue
// when there are new dispatch items, and the target thread should then enter
-// mp_dispatch_queue_process() as soon as possible. Note that wakeup_fn is
-// called under no lock, so you might have to do synchronization yourself.
+// mp_dispatch_queue_process() as soon as possible.
+// Note that this setter does not do internal synchronization, so you must set
+// it before other threads see it.
void mp_dispatch_set_wakeup_fn(struct mp_dispatch_queue *queue,
void (*wakeup_fn)(void *wakeup_ctx),
void *wakeup_ctx)
@@ -104,6 +107,22 @@ void mp_dispatch_set_wakeup_fn(struct mp_dispatch_queue *queue,
queue->wakeup_ctx = wakeup_ctx;
}
+// Set a function that will be called by mp_dispatch_lock() if the target thread
+// is not calling mp_dispatch_queue_process() right now. This is an obscure,
+// optional mechanism to make a worker thread react to external events more
+// quickly. The idea is that the callback will make the worker thread to stop
+// doing whatever (e.g. by setting a flag), and call mp_dispatch_queue_process()
+// in order to let mp_dispatch_lock() calls continue sooner.
+// Like wakeup_fn, this setter does no internal synchronization, and you must
+// not access the dispatch queue itself from the callback.
+void mp_dispatch_set_onlock_fn(struct mp_dispatch_queue *queue,
+ void (*onlock_fn)(void *onlock_ctx),
+ void *onlock_ctx)
+{
+ queue->onlock_fn = onlock_fn;
+ queue->onlock_ctx = onlock_ctx;
+}
+
static void mp_dispatch_append(struct mp_dispatch_queue *queue,
struct mp_dispatch_item *item)
{
@@ -356,6 +375,8 @@ void mp_dispatch_lock(struct mp_dispatch_queue *queue)
// And now wait until the target thread gets "trapped" within the
// mp_dispatch_queue_process() call, which will mean we get exclusive
// access to the target's thread state.
+ if (queue->onlock_fn)
+ queue->onlock_fn(queue->onlock_ctx);
while (!queue->in_process) {
pthread_mutex_unlock(&queue->lock);
if (queue->wakeup_fn)
diff --git a/misc/dispatch.h b/misc/dispatch.h
index 3367018390..fbf826037b 100644
--- a/misc/dispatch.h
+++ b/misc/dispatch.h
@@ -10,6 +10,9 @@ struct mp_dispatch_queue *mp_dispatch_create(void *talloc_parent);
void mp_dispatch_set_wakeup_fn(struct mp_dispatch_queue *queue,
void (*wakeup_fn)(void *wakeup_ctx),
void *wakeup_ctx);
+void mp_dispatch_set_onlock_fn(struct mp_dispatch_queue *queue,
+ void (*onlock_fn)(void *onlock_ctx),
+ void *onlock_ctx);
void mp_dispatch_enqueue(struct mp_dispatch_queue *queue,
mp_dispatch_fn fn, void *fn_data);
void mp_dispatch_enqueue_autofree(struct mp_dispatch_queue *queue,