summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2017-12-09 23:26:05 -0500
committerMichael Sevakis <jethead71@rockbox.org>2017-12-09 23:45:53 -0500
commit6ee3b6feeea0430e153f0c8851c8c52d345b6fbc (patch)
treeb9813f1267599dd440dd939ac6314248eea478dc
parent8be40746b81c4fde8f990c13f1359ebbc88d048f (diff)
downloadrockbox-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
-rw-r--r--apps/buffering.c17
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. */
745static void shrink_handle(struct memory_handle *h) 745static 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);