diff options
Diffstat (limited to 'apps/buffering.c')
-rw-r--r-- | apps/buffering.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/apps/buffering.c b/apps/buffering.c index 8d41324190..4516959cab 100644 --- a/apps/buffering.c +++ b/apps/buffering.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <stdlib.h> | 25 | #include <stdlib.h> |
26 | #include <ctype.h> | 26 | #include <ctype.h> |
27 | #include <inttypes.h> | 27 | #include <inttypes.h> |
28 | #define assert(a) | ||
29 | |||
28 | #include "buffering.h" | 30 | #include "buffering.h" |
29 | 31 | ||
30 | #include "storage.h" | 32 | #include "storage.h" |
@@ -611,6 +613,16 @@ static inline bool buffer_is_low(void) | |||
611 | return data_counters.useful < (conf_watermark / 2); | 613 | return data_counters.useful < (conf_watermark / 2); |
612 | } | 614 | } |
613 | 615 | ||
616 | static uintptr_t beyond_handle(struct memory_handle *h) | ||
617 | { | ||
618 | /* | ||
619 | * the last handle on the chain must leave at least one byte | ||
620 | * between itself and the first handle, to avoid overflowing the | ||
621 | * ring by advancing buf_widx up to buf_ridx | ||
622 | */ | ||
623 | return h->next != 0 ? ringbuf_offset(h->next) : ringbuf_sub(buf_ridx, 1); | ||
624 | } | ||
625 | |||
614 | /* Buffer data for the given handle. | 626 | /* Buffer data for the given handle. |
615 | Return whether or not the buffering should continue explicitly. */ | 627 | Return whether or not the buffering should continue explicitly. */ |
616 | static bool buffer_handle(int handle_id) | 628 | static bool buffer_handle(int handle_id) |
@@ -669,10 +681,10 @@ static bool buffer_handle(int handle_id) | |||
669 | buffer_len - h->widx); | 681 | buffer_len - h->widx); |
670 | 682 | ||
671 | ssize_t overlap; | 683 | ssize_t overlap; |
672 | uintptr_t next_handle = ringbuf_offset(h->next); | 684 | uintptr_t next_handle = beyond_handle(h); |
673 | 685 | ||
674 | /* stop copying if it would overwrite the reading position */ | 686 | /* stop copying if it would overwrite the reading position */ |
675 | if (ringbuf_add_cross(h->widx, copy_n, buf_ridx) >= 0) | 687 | if (h->widx == next_handle || ringbuf_add_cross(h->widx, copy_n, buf_ridx) >= 0) |
676 | return false; | 688 | return false; |
677 | 689 | ||
678 | /* FIXME: This would overwrite the next handle | 690 | /* FIXME: This would overwrite the next handle |
@@ -789,8 +801,7 @@ static void rebuffer_handle(int handle_id, size_t newpos) | |||
789 | LOGFQUEUE("buffering >| Q_RESET_HANDLE %d", handle_id); | 801 | LOGFQUEUE("buffering >| Q_RESET_HANDLE %d", handle_id); |
790 | queue_send(&buffering_queue, Q_RESET_HANDLE, handle_id); | 802 | queue_send(&buffering_queue, Q_RESET_HANDLE, handle_id); |
791 | 803 | ||
792 | uintptr_t next = ringbuf_offset(h->next); | 804 | if (ringbuf_sub(beyond_handle(h), h->data) < h->filesize - newpos) |
793 | if (ringbuf_sub(next, h->data) < h->filesize - newpos) | ||
794 | { | 805 | { |
795 | /* There isn't enough space to rebuffer all of the track from its new | 806 | /* There isn't enough space to rebuffer all of the track from its new |
796 | offset, so we ask the user to free some */ | 807 | offset, so we ask the user to free some */ |