summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-11-10 10:23:49 +0100
committerwm4 <wm4@nowhere>2017-11-10 10:23:49 +0100
commitf123cc4c9b34e7ce3d4a890ac851a5d6e2703278 (patch)
tree70fbb9a22695e93851f66555cee7a0019e6778f7
parentd3bc93cf2e28c346c80f8545cfe765dadf821ae0 (diff)
downloadmpv-f123cc4c9b34e7ce3d4a890ac851a5d6e2703278.tar.bz2
mpv-f123cc4c9b34e7ce3d4a890ac851a5d6e2703278.tar.xz
demux: fix a race condition with async seeking
demux_add_packet() must completely ignore any packets that are added while a queued seek is not initiated yet. The main issue is that after setting in->seeking==true, the central lock is released, and it can take "a while" until it's reacquired on the demux thread and the seek is actually initiated. During that time, packets could be read and added, that have nothing to do with the new state.
-rw-r--r--demux/demux.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/demux/demux.c b/demux/demux.c
index 7f34fa0fc9..6b9897ce7d 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -1050,8 +1050,8 @@ void demux_add_packet(struct sh_stream *stream, demux_packet_t *dp)
struct demux_queue *queue = ds->queue;
- bool drop = ds->refreshing;
- if (ds->refreshing) {
+ bool drop = !ds->selected || in->seeking;
+ if (!drop && ds->refreshing) {
// Resume reading once the old position was reached (i.e. we start
// returning packets where we left off before the refresh).
// If it's the same position, drop, but continue normally next time.
@@ -1063,9 +1063,10 @@ void demux_add_packet(struct sh_stream *stream, demux_packet_t *dp)
ds->refreshing = false; // should not happen
MP_WARN(in, "stream %d: demux refreshing failed\n", ds->index);
}
+ drop = true;
}
- if (!ds->selected || in->seeking || drop) {
+ if (drop) {
pthread_mutex_unlock(&in->lock);
talloc_free(dp);
return;