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
This commit is contained in:
Michael Sevakis 2017-12-09 23:26:05 -05:00
parent 8be40746b8
commit 6ee3b6feee

View file

@ -742,10 +742,10 @@ static bool close_handle(int handle_id)
/* Free buffer space by moving the handle struct right before the useful /* Free buffer space by moving the handle struct right before the useful
part of its data buffer or by moving all the data. */ part of its data buffer or by moving all the data. */
static void shrink_handle(struct memory_handle *h) static struct memory_handle * shrink_handle(struct memory_handle *h)
{ {
if (!h) if (!h)
return; return NULL;
if (h->type == TYPE_PACKET_AUDIO) { if (h->type == TYPE_PACKET_AUDIO) {
/* only move the handle struct */ /* only move the handle struct */
@ -756,14 +756,14 @@ static void shrink_handle(struct memory_handle *h)
/* The value of delta might change for alignment reasons */ /* The value of delta might change for alignment reasons */
if (!move_handle(&h, &delta, 0)) if (!move_handle(&h, &delta, 0))
return; return h;
h->data = ringbuf_add(h->data, delta); h->data = ringbuf_add(h->data, delta);
h->start += delta; h->start += delta;
} else { } else {
/* metadata handle: we can move all of it */ /* metadata handle: we can move all of it */
if (h->pinned || !HLIST_NEXT(h)) if (h->pinned || !HLIST_NEXT(h))
return; /* Pinned, last handle */ return h; /* Pinned, last handle */
size_t data_size = h->filesize - h->start; size_t data_size = h->filesize - h->start;
uintptr_t handle_distance = uintptr_t handle_distance =
@ -772,7 +772,7 @@ static void shrink_handle(struct memory_handle *h)
/* The value of delta might change for alignment reasons */ /* The value of delta might change for alignment reasons */
if (!move_handle(&h, &delta, data_size)) if (!move_handle(&h, &delta, data_size))
return; return h;
size_t olddata = h->data; size_t olddata = h->data;
h->data = ringbuf_add(h->data, delta); h->data = ringbuf_add(h->data, delta);
@ -799,6 +799,8 @@ static void shrink_handle(struct memory_handle *h)
break; break;
} }
} }
return h;
} }
/* Fill the buffer by buffering as much data as possible for handles that still /* Fill the buffer by buffering as much data as possible for handles that still
@ -809,8 +811,7 @@ static bool fill_buffer(void)
logf("fill_buffer()"); logf("fill_buffer()");
mutex_lock(&llist_mutex); mutex_lock(&llist_mutex);
struct memory_handle *m = HLIST_FIRST; struct memory_handle *m = shrink_handle(HLIST_FIRST);
shrink_handle(m);
mutex_unlock(&llist_mutex); mutex_unlock(&llist_mutex);
@ -1593,7 +1594,7 @@ static void shrink_buffer(void)
mutex_lock(&llist_mutex); mutex_lock(&llist_mutex);
for (struct memory_handle *h = HLIST_LAST; h; h = HLIST_PREV(h)) { for (struct memory_handle *h = HLIST_LAST; h; h = HLIST_PREV(h)) {
shrink_handle(h); h = shrink_handle(h);
} }
mutex_unlock(&llist_mutex); mutex_unlock(&llist_mutex);