summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2019-09-20 16:43:17 +0200
committerwm4 <wm4@nowhere>2019-09-20 16:47:16 +0200
commit4fa8f33b92a44fe928817a81653f135402192cac (patch)
treefb4cd74997b4b6fb79116d9798574a32f0071037
parentf00af71d12a7d155d4d80f0879931c3f54c7ab9b (diff)
downloadmpv-4fa8f33b92a44fe928817a81653f135402192cac.tar.bz2
mpv-4fa8f33b92a44fe928817a81653f135402192cac.tar.xz
client API, vo_libmpv: document random deadlock problems
I guess trying to make DR work on libmpv was a mistake. I never observed such a deadlock, but it's looks like it's theoretically possible.
-rw-r--r--libmpv/render.h4
-rw-r--r--video/out/vo_libmpv.c16
2 files changed, 20 insertions, 0 deletions
diff --git a/libmpv/render.h b/libmpv/render.h
index 086b42d1b5..6d594e0c06 100644
--- a/libmpv/render.h
+++ b/libmpv/render.h
@@ -85,6 +85,10 @@ extern "C" {
* requirement always existed. Not honoring it will lead to UB (deadlocks,
* use of invalid pthread_t handles). This requirement might be removed in
* the future, but will require some considerable work internal to libmpv.
+ * You can avoid this issue by setting "vd-lavc-dr" to "no".
+ * - MPV_RENDER_PARAM_ADVANCED_CONTROL has some other libmpv-internal problems,
+ * which may result in random deadlocks (see top of vo_libmpv.c).
+ * You can probably avoid this issue by setting "vd-lavc-dr" to "no".
*
* libmpv functions which are safe to call from a render thread are:
* - functions marked with "Safe to be called from mpv render API threads."
diff --git a/video/out/vo_libmpv.c b/video/out/vo_libmpv.c
index 3f3127cb2a..b6c4d9fb06 100644
--- a/video/out/vo_libmpv.c
+++ b/video/out/vo_libmpv.c
@@ -45,6 +45,22 @@
* > mpv_render_context.update_lock
* And: render thread > VO (wait for present)
* VO > render thread (wait for present done, via timeout)
+ *
+ * Inherent locking bugs with advanced_control:
+ *
+ * In theory, it can deadlock on ctx->lock. Consider if the VO thread calls
+ * forget_frames(), which it does under ctx->lock (e.g. VOCTRL_RESET).
+ * If a frame was a DR image, dr_helper.c will call mp_dispatch_run().
+ * This in turn will call the wakeup callback set with
+ * mpv_render_context_set_update_callback(). The API user will eventually
+ * call mpv_render_context_update(), which performs the dispatch queue work
+ * queued by dr_helper.c.
+ * And then the function tries to acquire ctx->lock. This can deadlock
+ * under specific circumstances. It will _not_ deadlock if the queued work
+ * made the caller release the lock. However, if the caller made queue
+ * some more work (like freeing a second frame), and will keep the lock
+ * until it gets a reply. Both threads will wait on each other, and no
+ * progress can be made.
*/
struct vo_priv {