summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-04-09 19:05:41 +0200
committerwm4 <wm4@nowhere>2014-04-09 19:05:41 +0200
commit80392efaeadf968f233b4bfad87cd30ce635b1dc (patch)
tree56b288a2a9546f259fa3e96fcad56a7382db4dc4
parente7a5124b36c872768a3af5ec8eef345902c56524 (diff)
downloadmpv-80392efaeadf968f233b4bfad87cd30ce635b1dc.tar.bz2
mpv-80392efaeadf968f233b4bfad87cd30ce635b1dc.tar.xz
cache: no short reads in read_buffer
Until now, cache_read() (which calls read_buffer()) could return short reads. This was a simplification allowed by the stream interface. But for cache resizing, it will be more practical to make read_buffer() do a full read.
-rw-r--r--stream/cache.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/stream/cache.c b/stream/cache.c
index 42d412801f..bcb5bea086 100644
--- a/stream/cache.c
+++ b/stream/cache.c
@@ -183,26 +183,31 @@ static void cache_drop_contents(struct priv *s)
static size_t read_buffer(struct priv *s, unsigned char *dst,
size_t dst_size, int64_t pos)
{
- if (pos >= s->max_filepos || pos < s->min_filepos)
- return 0;
- int64_t newb = s->max_filepos - pos; // new bytes in the buffer
+ size_t read = 0;
+ while (read < dst_size) {
+ if (pos >= s->max_filepos || pos < s->min_filepos)
+ break;
+ int64_t newb = s->max_filepos - pos; // new bytes in the buffer
- pos = pos - s->offset; // file pos to buffer memory pos
- if (pos < 0) {
- pos += s->buffer_size;
- } else if (pos >= s->buffer_size) {
- pos -= s->buffer_size;
- }
+ int64_t bpos = pos - s->offset; // file pos to buffer memory pos
+ if (bpos < 0) {
+ bpos += s->buffer_size;
+ } else if (bpos >= s->buffer_size) {
+ bpos -= s->buffer_size;
+ }
- if (newb > s->buffer_size - pos)
- newb = s->buffer_size - pos; // handle wrap...
+ if (newb > s->buffer_size - bpos)
+ newb = s->buffer_size - bpos; // handle wrap...
- newb = MPMIN(newb, dst_size);
+ newb = MPMIN(newb, dst_size - read);
- assert(newb >= 0 && newb <= dst_size);
- assert(pos >= 0 && pos + newb <= s->buffer_size);
- memcpy(&dst[0], &s->buffer[pos], newb);
- return newb;
+ assert(newb >= 0 && read + newb <= dst_size);
+ assert(bpos >= 0 && bpos + newb <= s->buffer_size);
+ memcpy(&dst[read], &s->buffer[bpos], newb);
+ read += newb;
+ pos += newb;
+ }
+ return read;
}
// Runs in the main thread