summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-12-24 06:13:28 +0100
committerMartin Herkt <652892+lachs0r@users.noreply.github.com>2017-12-24 21:33:16 +0100
commit2a43060560a1c246943dccc77215542d6b507580 (patch)
treeeeb562cf8a3ba7a91c9b9ee89a05fdcb2f549286
parent5ffbe2ba8a9e86cb1203e11b14dfe77a6631fe3e (diff)
downloadmpv-2a43060560a1c246943dccc77215542d6b507580.tar.bz2
mpv-2a43060560a1c246943dccc77215542d6b507580.tar.xz
cache: propagate underlying stream seek errors in some cases
This just put the cache into an endless loop. This can happen simply if any seek call of the underlying stream returns an error.
-rw-r--r--stream/cache.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/stream/cache.c b/stream/cache.c
index e64aaf87ad..d91ae73b05 100644
--- a/stream/cache.c
+++ b/stream/cache.c
@@ -135,6 +135,8 @@ struct priv {
int64_t eof_pos;
+ bool read_seek_failed; // let a read fail because an async seek failed
+
int control; // requested STREAM_CTRL_... or CACHE_CTRL_...
void *control_arg; // temporary for executing STREAM_CTRLs
int control_res;
@@ -246,6 +248,8 @@ static bool cache_update_stream_position(struct priv *s)
{
int64_t read = s->read_filepos;
+ s->read_seek_failed = false;
+
if (needs_seek(s, read)) {
MP_VERBOSE(s, "Dropping cache at pos %"PRId64", "
"cached range: %"PRId64"-%"PRId64".\n", read,
@@ -256,8 +260,10 @@ static bool cache_update_stream_position(struct priv *s)
if (stream_tell(s->stream) != s->max_filepos && s->seekable) {
MP_VERBOSE(s, "Seeking underlying stream: %"PRId64" -> %"PRId64"\n",
stream_tell(s->stream), s->max_filepos);
- if (!stream_seek(s->stream, s->max_filepos))
+ if (!stream_seek(s->stream, s->max_filepos)) {
+ s->read_seek_failed = true;
return false;
+ }
}
return stream_tell(s->stream) == s->max_filepos;
@@ -600,6 +606,11 @@ static int cache_fill_buffer(struct stream *cache, char *buffer, int max_len)
s->idle = false;
if (!cache_wakeup_and_wait(s, &retry_time))
break;
+ if (s->read_seek_failed) {
+ MP_ERR(s, "error reading after async seek failed\n");
+ s->read_seek_failed = false;
+ break;
+ }
}
}