summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-09-06 00:16:15 +0200
committerwm4 <wm4@nowhere>2014-09-06 00:16:15 +0200
commit197f18402ed1e38e8e151a912e416e0b86d277d2 (patch)
tree033fd17f6e10a696fec71c1137d343f145206f9b
parentbdf49d137e5fc63f22ddbb54f4d585719cdd2e5d (diff)
downloadmpv-197f18402ed1e38e8e151a912e416e0b86d277d2.tar.bz2
mpv-197f18402ed1e38e8e151a912e416e0b86d277d2.tar.xz
sub: fix possible deadlock with --no-sub-ass and similar
This is a deadlock caused by a lock order issue: sub/osd.c locks the OSD first, then the subtitle decoder lock. player/sub.c does the reverse. Fix this by discussing away the requirement for locking (see below), which allows us to drop the broken sub lock. sub_get_text() still acquires and releases the sub decoder lock, but it's not held at the same time as the OSD lock anymore, so it should be fine. Originally, the sub lock was acquired because sub_get_text() returns a pointer to a mutable string. We simply declare that it's ok to call it unlocked, as long as only 1 thread accesses it, which works out fine in this case.
-rw-r--r--player/sub.c7
-rw-r--r--sub/dec_sub.c2
2 files changed, 3 insertions, 6 deletions
diff --git a/player/sub.c b/player/sub.c
index a4b4baddc8..0de6c2bbf1 100644
--- a/player/sub.c
+++ b/player/sub.c
@@ -144,15 +144,10 @@ static void update_subtitle(struct MPContext *mpctx, int order)
// Handle displaying subtitles on terminal; never done for secondary subs
if (order == 0) {
- if (!state.render_bitmap_subs || !mpctx->video_out) {
- sub_lock(dec_sub);
+ if (!state.render_bitmap_subs || !mpctx->video_out)
set_osd_subtitle(mpctx, sub_get_text(dec_sub, curpts_s));
- sub_unlock(dec_sub);
- }
} else if (order == 1) {
- sub_lock(dec_sub);
osd_set_text(mpctx->osd, obj, sub_get_text(dec_sub, curpts_s));
- sub_unlock(dec_sub);
}
}
diff --git a/sub/dec_sub.c b/sub/dec_sub.c
index 79884576b0..cc608c3ca5 100644
--- a/sub/dec_sub.c
+++ b/sub/dec_sub.c
@@ -531,6 +531,8 @@ bool sub_has_get_text(struct dec_sub *sub)
}
// See sub_get_bitmaps() for locking requirements.
+// It can be called unlocked too, but then only 1 thread must call this function
+// at a time (unless exclusive access is guaranteed).
char *sub_get_text(struct dec_sub *sub, double pts)
{
pthread_mutex_lock(&sub->lock);