diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2011-02-10 05:56:21 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2011-02-10 05:56:21 +0000 |
commit | 88d91faba5df82e70abfd95b60c96b4a0bd53744 (patch) | |
tree | 98bfd167a0f7a88d50d0fe9c65e066d28a57cb47 /apps/buffering.c | |
parent | 2007d67bce9b4345ea7f842300dd406cf85c32df (diff) | |
download | rockbox-88d91faba5df82e70abfd95b60c96b4a0bd53744.tar.gz rockbox-88d91faba5df82e70abfd95b60c96b4a0bd53744.zip |
buffering: Don't execute move-handle-ony case if handle is of metadata type (atomic) and must be kept fully buffered. Manage handle corruption guard and handle buffering with one set of logic which allows reading of the maximum amount of data without overflow. 'FIXME' regarding handle corruption guard is really part of expected operation when thread that does the handle closing hasn't yet performed the delegated task before rebuffering starts.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29270 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/buffering.c')
-rw-r--r-- | apps/buffering.c | 38 |
1 files changed, 17 insertions, 21 deletions
diff --git a/apps/buffering.c b/apps/buffering.c index 1482d6790b..14db47bb91 100644 --- a/apps/buffering.c +++ b/apps/buffering.c | |||
@@ -666,31 +666,25 @@ static bool buffer_handle(int handle_id) | |||
666 | while (h->filerem > 0 && !stop) | 666 | while (h->filerem > 0 && !stop) |
667 | { | 667 | { |
668 | /* max amount to copy */ | 668 | /* max amount to copy */ |
669 | size_t copy_n = MIN( MIN(h->filerem, BUFFERING_DEFAULT_FILECHUNK), | 669 | ssize_t copy_n = MIN( MIN(h->filerem, BUFFERING_DEFAULT_FILECHUNK), |
670 | buffer_len - h->widx); | 670 | buffer_len - h->widx); |
671 | uintptr_t offset = h->next ? ringbuf_offset(h->next) : buf_ridx; | ||
672 | ssize_t overlap = ringbuf_add_cross(h->widx, copy_n, offset); | ||
671 | 673 | ||
672 | ssize_t overlap; | 674 | if (!h->next) |
673 | uintptr_t next_handle = ringbuf_offset(h->next); | 675 | overlap++; /* sub one more below to avoid buffer overflow */ |
674 | 676 | ||
675 | /* stop copying if it would overwrite the reading position */ | 677 | if (overlap > 0) |
676 | if (ringbuf_add_cross(h->widx, copy_n, buf_ridx) >= 0) | ||
677 | return false; | ||
678 | |||
679 | /* FIXME: This would overwrite the next handle | ||
680 | * If this is true, then there's a handle even though we have still | ||
681 | * data to buffer. This should NEVER EVER happen! (but it does :( ) */ | ||
682 | if (h->next && (overlap | ||
683 | = ringbuf_add_cross(h->widx, copy_n, next_handle)) > 0) | ||
684 | { | 678 | { |
685 | /* stop buffering data for now and post-pone buffering the rest */ | 679 | /* read only up to available space and stop if it would overwrite |
680 | the reading position or the next handle */ | ||
686 | stop = true; | 681 | stop = true; |
687 | DEBUGF( "%s(): Preventing handle corruption: h1.id:%d h2.id:%d" | ||
688 | " copy_n:%lu overlap:%ld h1.filerem:%lu\n", __func__, | ||
689 | h->id, h->next->id, (unsigned long)copy_n, (long)overlap, | ||
690 | (unsigned long)h->filerem); | ||
691 | copy_n -= overlap; | 682 | copy_n -= overlap; |
692 | } | 683 | } |
693 | 684 | ||
685 | if (copy_n <= 0) | ||
686 | return false; /* no space for read */ | ||
687 | |||
694 | /* rc is the actual amount read */ | 688 | /* rc is the actual amount read */ |
695 | int rc = read(h->fd, &buffer[h->widx], copy_n); | 689 | int rc = read(h->fd, &buffer[h->widx], copy_n); |
696 | 690 | ||
@@ -830,12 +824,14 @@ static void shrink_handle(struct memory_handle *h) | |||
830 | if (!h) | 824 | if (!h) |
831 | return; | 825 | return; |
832 | 826 | ||
833 | if (h->next && h->filerem == 0 && | 827 | if (h->type == TYPE_ID3 || h->type == TYPE_CUESHEET || |
834 | (h->type == TYPE_ID3 || h->type == TYPE_CUESHEET || | 828 | h->type == TYPE_BITMAP || h->type == TYPE_CODEC || |
835 | h->type == TYPE_BITMAP || h->type == TYPE_CODEC || | 829 | h->type == TYPE_ATOMIC_AUDIO) |
836 | h->type == TYPE_ATOMIC_AUDIO)) | ||
837 | { | 830 | { |
838 | /* metadata handle: we can move all of it */ | 831 | /* metadata handle: we can move all of it */ |
832 | if (!h->next || h->filerem != 0) | ||
833 | return; /* Last handle or not finished loading */ | ||
834 | |||
839 | uintptr_t handle_distance = | 835 | uintptr_t handle_distance = |
840 | ringbuf_sub(ringbuf_offset(h->next), h->data); | 836 | ringbuf_sub(ringbuf_offset(h->next), h->data); |
841 | delta = handle_distance - h->available; | 837 | delta = handle_distance - h->available; |