diff options
author | wm4 <wm4@nowhere> | 2017-11-10 10:23:49 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2017-11-10 10:23:49 +0100 |
commit | f123cc4c9b34e7ce3d4a890ac851a5d6e2703278 (patch) | |
tree | 70fbb9a22695e93851f66555cee7a0019e6778f7 /demux | |
parent | d3bc93cf2e28c346c80f8545cfe765dadf821ae0 (diff) | |
download | mpv-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.
Diffstat (limited to 'demux')
-rw-r--r-- | demux/demux.c | 7 |
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; |