1
mirror of https://github.com/mpv-player/mpv synced 2024-11-14 22:48:35 +01:00

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.
This commit is contained in:
wm4 2019-09-20 16:43:17 +02:00
parent f00af71d12
commit 4fa8f33b92
2 changed files with 20 additions and 0 deletions

View File

@ -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."

View File

@ -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 {