diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2017-12-09 23:26:05 -0500 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2017-12-09 23:45:53 -0500 |
commit | 6ee3b6feeea0430e153f0c8851c8c52d345b6fbc (patch) | |
tree | b9813f1267599dd440dd939ac6314248eea478dc /apps/buffering.c | |
parent | 8be40746b81c4fde8f990c13f1359ebbc88d048f (diff) | |
download | rockbox-6ee3b6feeea0430e153f0c8851c8c52d345b6fbc.tar.gz rockbox-6ee3b6feeea0430e153f0c8851c8c52d345b6fbc.zip |
buffering.c: Fix oopses with caching handle pointer
The location of the handle cannot be kept across calls to
shrink_handle() since it may move the structure. The error was
there in one place at the inception, corrected, then reintroduced.
Make shrink_handle() return the new location and use it, which
makes the side effects of the function clearer.
Change-Id: Icae6a0ad6f7bb0d6645b044cccfa4aef88db42ad
Diffstat (limited to 'apps/buffering.c')
-rw-r--r-- | apps/buffering.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/apps/buffering.c b/apps/buffering.c index 4b6a9d7f73..79262a2f13 100644 --- a/apps/buffering.c +++ b/apps/buffering.c | |||
@@ -742,10 +742,10 @@ static bool close_handle(int handle_id) | |||
742 | 742 | ||
743 | /* Free buffer space by moving the handle struct right before the useful | 743 | /* Free buffer space by moving the handle struct right before the useful |
744 | part of its data buffer or by moving all the data. */ | 744 | part of its data buffer or by moving all the data. */ |
745 | static void shrink_handle(struct memory_handle *h) | 745 | static struct memory_handle * shrink_handle(struct memory_handle *h) |
746 | { | 746 | { |
747 | if (!h) | 747 | if (!h) |
748 | return; | 748 | return NULL; |
749 | 749 | ||
750 | if (h->type == TYPE_PACKET_AUDIO) { | 750 | if (h->type == TYPE_PACKET_AUDIO) { |
751 | /* only move the handle struct */ | 751 | /* only move the handle struct */ |
@@ -756,14 +756,14 @@ static void shrink_handle(struct memory_handle *h) | |||
756 | 756 | ||
757 | /* The value of delta might change for alignment reasons */ | 757 | /* The value of delta might change for alignment reasons */ |
758 | if (!move_handle(&h, &delta, 0)) | 758 | if (!move_handle(&h, &delta, 0)) |
759 | return; | 759 | return h; |
760 | 760 | ||
761 | h->data = ringbuf_add(h->data, delta); | 761 | h->data = ringbuf_add(h->data, delta); |
762 | h->start += delta; | 762 | h->start += delta; |
763 | } else { | 763 | } else { |
764 | /* metadata handle: we can move all of it */ | 764 | /* metadata handle: we can move all of it */ |
765 | if (h->pinned || !HLIST_NEXT(h)) | 765 | if (h->pinned || !HLIST_NEXT(h)) |
766 | return; /* Pinned, last handle */ | 766 | return h; /* Pinned, last handle */ |
767 | 767 | ||
768 | size_t data_size = h->filesize - h->start; | 768 | size_t data_size = h->filesize - h->start; |
769 | uintptr_t handle_distance = | 769 | uintptr_t handle_distance = |
@@ -772,7 +772,7 @@ static void shrink_handle(struct memory_handle *h) | |||
772 | 772 | ||
773 | /* The value of delta might change for alignment reasons */ | 773 | /* The value of delta might change for alignment reasons */ |
774 | if (!move_handle(&h, &delta, data_size)) | 774 | if (!move_handle(&h, &delta, data_size)) |
775 | return; | 775 | return h; |
776 | 776 | ||
777 | size_t olddata = h->data; | 777 | size_t olddata = h->data; |
778 | h->data = ringbuf_add(h->data, delta); | 778 | h->data = ringbuf_add(h->data, delta); |
@@ -799,6 +799,8 @@ static void shrink_handle(struct memory_handle *h) | |||
799 | break; | 799 | break; |
800 | } | 800 | } |
801 | } | 801 | } |
802 | |||
803 | return h; | ||
802 | } | 804 | } |
803 | 805 | ||
804 | /* Fill the buffer by buffering as much data as possible for handles that still | 806 | /* Fill the buffer by buffering as much data as possible for handles that still |
@@ -809,8 +811,7 @@ static bool fill_buffer(void) | |||
809 | logf("fill_buffer()"); | 811 | logf("fill_buffer()"); |
810 | mutex_lock(&llist_mutex); | 812 | mutex_lock(&llist_mutex); |
811 | 813 | ||
812 | struct memory_handle *m = HLIST_FIRST; | 814 | struct memory_handle *m = shrink_handle(HLIST_FIRST); |
813 | shrink_handle(m); | ||
814 | 815 | ||
815 | mutex_unlock(&llist_mutex); | 816 | mutex_unlock(&llist_mutex); |
816 | 817 | ||
@@ -1593,7 +1594,7 @@ static void shrink_buffer(void) | |||
1593 | mutex_lock(&llist_mutex); | 1594 | mutex_lock(&llist_mutex); |
1594 | 1595 | ||
1595 | for (struct memory_handle *h = HLIST_LAST; h; h = HLIST_PREV(h)) { | 1596 | for (struct memory_handle *h = HLIST_LAST; h; h = HLIST_PREV(h)) { |
1596 | shrink_handle(h); | 1597 | h = shrink_handle(h); |
1597 | } | 1598 | } |
1598 | 1599 | ||
1599 | mutex_unlock(&llist_mutex); | 1600 | mutex_unlock(&llist_mutex); |