diff options
-rw-r--r-- | apps/buffering.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/apps/buffering.c b/apps/buffering.c index 54c6c05baa..2f6623a936 100644 --- a/apps/buffering.c +++ b/apps/buffering.c | |||
@@ -560,6 +560,17 @@ fill_buffer : Call buffer_handle for all handles that have data to buffer | |||
560 | 560 | ||
561 | These functions are used by the buffering thread to manage buffer space. | 561 | These functions are used by the buffering thread to manage buffer space. |
562 | */ | 562 | */ |
563 | static size_t handle_size_available(const struct memory_handle *h) | ||
564 | { | ||
565 | /* Obtain proper distances from data start */ | ||
566 | size_t rd = ringbuf_sub(h->ridx, h->data); | ||
567 | size_t wr = ringbuf_sub(h->widx, h->data); | ||
568 | |||
569 | if (LIKELY(wr > rd)) | ||
570 | return wr - rd; | ||
571 | |||
572 | return 0; /* ridx is ahead of or equal to widx at this time */ | ||
573 | } | ||
563 | 574 | ||
564 | static void update_data_counters(struct data_counters *dc) | 575 | static void update_data_counters(struct data_counters *dc) |
565 | { | 576 | { |
@@ -582,6 +593,8 @@ static void update_data_counters(struct data_counters *dc) | |||
582 | m = first_handle; | 593 | m = first_handle; |
583 | while (m) { | 594 | while (m) { |
584 | buffered += m->available; | 595 | buffered += m->available; |
596 | /* wasted could come out larger than the buffer size if ridx's are | ||
597 | overlapping data ahead of their handles' buffered data */ | ||
585 | wasted += ringbuf_sub(m->ridx, m->data); | 598 | wasted += ringbuf_sub(m->ridx, m->data); |
586 | remaining += m->filerem; | 599 | remaining += m->filerem; |
587 | 600 | ||
@@ -589,7 +602,7 @@ static void update_data_counters(struct data_counters *dc) | |||
589 | is_useful = true; | 602 | is_useful = true; |
590 | 603 | ||
591 | if (is_useful) | 604 | if (is_useful) |
592 | useful += ringbuf_sub(m->widx, m->ridx); | 605 | useful += handle_size_available(m); |
593 | 606 | ||
594 | m = m->next; | 607 | m = m->next; |
595 | } | 608 | } |
@@ -795,7 +808,11 @@ static void shrink_handle(struct memory_handle *h) | |||
795 | } | 808 | } |
796 | } else { | 809 | } else { |
797 | /* only move the handle struct */ | 810 | /* only move the handle struct */ |
798 | delta = ringbuf_sub(h->ridx, h->data); | 811 | size_t rd = ringbuf_sub(h->ridx, h->data); |
812 | size_t wr = ringbuf_sub(h->widx, h->data); | ||
813 | |||
814 | /* ridx could be ahead of widx on a mini rebuffer */ | ||
815 | delta = MIN(rd, wr); | ||
799 | if (!move_handle(&h, &delta, 0, true)) | 816 | if (!move_handle(&h, &delta, 0, true)) |
800 | return; | 817 | return; |
801 | 818 | ||
@@ -1245,18 +1262,6 @@ int bufadvance(int handle_id, off_t offset) | |||
1245 | * actual amount of data available for reading. This function explicitly | 1262 | * actual amount of data available for reading. This function explicitly |
1246 | * does not check the validity of the input handle. It does do range checks | 1263 | * does not check the validity of the input handle. It does do range checks |
1247 | * on size and returns a valid (and explicit) amount of data for reading */ | 1264 | * on size and returns a valid (and explicit) amount of data for reading */ |
1248 | static size_t handle_size_available(const struct memory_handle *h) | ||
1249 | { | ||
1250 | /* Obtain proper distances from data start */ | ||
1251 | size_t rd = ringbuf_sub(h->ridx, h->data); | ||
1252 | size_t wr = ringbuf_sub(h->widx, h->data); | ||
1253 | |||
1254 | if (LIKELY(wr > rd)) | ||
1255 | return wr - rd; | ||
1256 | |||
1257 | return 0; /* ridx is ahead of or equal to widx at this time */ | ||
1258 | } | ||
1259 | |||
1260 | static struct memory_handle *prep_bufdata(int handle_id, size_t *size, | 1265 | static struct memory_handle *prep_bufdata(int handle_id, size_t *size, |
1261 | bool guardbuf_limit) | 1266 | bool guardbuf_limit) |
1262 | { | 1267 | { |