summaryrefslogtreecommitdiffstats
path: root/misc
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2018-05-19 17:06:00 +0200
committerwm4 <wm4@nowhere>2018-05-24 19:56:35 +0200
commit29a51900c6047798244afaca271618caeeeeeee8 (patch)
tree3e73ce26d1eab368df29731b2880c0bd0b46c37f /misc
parentd33e5972b38c1a8d1ed2c19095a94c70c33881c3 (diff)
downloadmpv-29a51900c6047798244afaca271618caeeeeeee8.tar.bz2
mpv-29a51900c6047798244afaca271618caeeeeeee8.tar.xz
player: some further cleanup of the mp_cancel crap
Alway give each demuxer its own mp_cancel instance. This makes management of the mp_cancel things much easier. Also, instead of having add/remove functions for mp_cancel slaves, replace them with a simpler to use set_parent function. Remove cancel_and_free_demuxer(), which had mpctx as parameter only to check an assumption. With this commit, demuxers have their own mp_cancel, so add demux_cancel_and_free() which makes use of it.
Diffstat (limited to 'misc')
-rw-r--r--misc/thread_tools.c39
-rw-r--r--misc/thread_tools.h14
2 files changed, 23 insertions, 30 deletions
diff --git a/misc/thread_tools.c b/misc/thread_tools.c
index ecf6bc2381..91b774eb93 100644
--- a/misc/thread_tools.c
+++ b/misc/thread_tools.c
@@ -105,12 +105,7 @@ static void cancel_destroy(void *p)
assert(!c->slaves.head); // API user error
- // We can access c->parent without synchronization, because:
- // - since c is being destroyed, nobody can explicitly remove it as slave
- // at the same time
- // - c->parent needs to stay valid as long as the slave exists
- if (c->parent)
- mp_cancel_remove_slave(c->parent, c);
+ mp_cancel_set_parent(c, NULL);
if (c->wakeup_pipe[0] >= 0) {
close(c->wakeup_pipe[0]);
@@ -225,25 +220,25 @@ void mp_cancel_set_cb(struct mp_cancel *c, void (*cb)(void *ctx), void *ctx)
pthread_mutex_unlock(&c->lock);
}
-void mp_cancel_add_slave(struct mp_cancel *c, struct mp_cancel *slave)
-{
- pthread_mutex_lock(&c->lock);
- assert(!slave->parent);
- slave->parent = c;
- LL_APPEND(siblings, &c->slaves, slave);
- retrigger_locked(c);
- pthread_mutex_unlock(&c->lock);
-}
-
-void mp_cancel_remove_slave(struct mp_cancel *c, struct mp_cancel *slave)
+void mp_cancel_set_parent(struct mp_cancel *slave, struct mp_cancel *parent)
{
- pthread_mutex_lock(&c->lock);
+ // We can access c->parent without synchronization, because:
+ // - concurrent mp_cancel_set_parent() calls to slave are not allowed
+ // - slave->parent needs to stay valid as long as the slave exists
+ if (slave->parent == parent)
+ return;
if (slave->parent) {
- assert(slave->parent == c);
- slave->parent = NULL;
- LL_REMOVE(siblings, &c->slaves, slave);
+ pthread_mutex_lock(&slave->parent->lock);
+ LL_REMOVE(siblings, &slave->parent->slaves, slave);
+ pthread_mutex_unlock(&slave->parent->lock);
+ }
+ slave->parent = parent;
+ if (slave->parent) {
+ pthread_mutex_lock(&slave->parent->lock);
+ LL_APPEND(siblings, &slave->parent->slaves, slave);
+ retrigger_locked(slave->parent);
+ pthread_mutex_unlock(&slave->parent->lock);
}
- pthread_mutex_unlock(&c->lock);
}
int mp_cancel_get_fd(struct mp_cancel *c)
diff --git a/misc/thread_tools.h b/misc/thread_tools.h
index 2198181e6c..89d84ce0b6 100644
--- a/misc/thread_tools.h
+++ b/misc/thread_tools.h
@@ -67,14 +67,12 @@ void mp_cancel_reset(struct mp_cancel *c);
// There is only one callback. Create a slave mp_cancel to get a private one.
void mp_cancel_set_cb(struct mp_cancel *c, void (*cb)(void *ctx), void *ctx);
-// If c gets triggered, automatically trigger slave. Trying to add a slave more
-// than once or to multiple parents is undefined behavior.
-// The parent mp_cancel must remain valid until the slave is manually removed
-// or destroyed. Destroying a mp_cancel that still has slaves is an error.
-void mp_cancel_add_slave(struct mp_cancel *c, struct mp_cancel *slave);
-
-// Undo mp_cancel_add_slave(). Ignores never added slaves for easier cleanup.
-void mp_cancel_remove_slave(struct mp_cancel *c, struct mp_cancel *slave);
+// If parent gets triggered, automatically trigger slave. There is only 1
+// parent; setting NULL clears the parent. Freeing slave also automatically
+// ends the parent link, but the parent mp_cancel must remain valid until the
+// slave is manually removed or destroyed. Destroying a mp_cancel that still
+// has slaves is an error.
+void mp_cancel_set_parent(struct mp_cancel *slave, struct mp_cancel *parent);
// win32 "Event" HANDLE that indicates the current mp_cancel state.
void *mp_cancel_get_event(struct mp_cancel *c);