summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorBrandon Low <lostlogic@rockbox.org>2007-11-08 15:34:23 +0000
committerBrandon Low <lostlogic@rockbox.org>2007-11-08 15:34:23 +0000
commit6e8ee408bfbe2e59e399e395d5b1f78208987906 (patch)
treec4214d9101ae08aada93dde9256ac5585d4e5170 /apps
parentaf2e9cc6e9e2c2a5a673870874e554af734ab6b1 (diff)
downloadrockbox-6e8ee408bfbe2e59e399e395d5b1f78208987906.zip
rockbox-6e8ee408bfbe2e59e399e395d5b1f78208987906.tar.gz
rockbox-6e8ee408bfbe2e59e399e395d5b1f78208987906.tar.bz2
rockbox-6e8ee408bfbe2e59e399e395d5b1f78208987906.tar.xz
Fix some bad where a handle is held across a sleep. We should probably audit this in other places as well.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15533 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/buffering.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/apps/buffering.c b/apps/buffering.c
index f4316fe..1d1fca1 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -974,29 +974,33 @@ int bufadvance(int handle_id, off_t offset)
* actual amount of data available for reading. This function explicitly
* does not check the validity of the input handle. It does do range checks
* on size and returns a valid (and explicit) amount of data for reading */
-static size_t prep_bufdata(const struct memory_handle *h, size_t size,
- bool filechunk_limit)
+static struct memory_handle *prep_bufdata(int handle_id, size_t *size,
+ bool filechunk_limit)
{
+ struct memory_handle *h = find_handle(handle_id);
+ if (!h)
+ return NULL;
+
size_t avail = RINGBUF_SUB(h->widx, h->ridx);
if (avail == 0 && h->filerem == 0)
/* File is finished reading */
return 0;
- if (size == 0 || size > avail + h->filerem)
- size = avail + h->filerem;
+ if (*size == 0 || *size > avail + h->filerem)
+ *size = avail + h->filerem;
if (filechunk_limit &&
- h->type == TYPE_PACKET_AUDIO && size > BUFFERING_DEFAULT_FILECHUNK)
+ h->type == TYPE_PACKET_AUDIO && *size > BUFFERING_DEFAULT_FILECHUNK)
{
logf("data request > filechunk");
/* If more than a filechunk is requested, provide no more than the
amount of data on buffer or one file chunk, but without increasing
"size", which would be bad. */
- size = MIN(size, MAX(avail, BUFFERING_DEFAULT_FILECHUNK));
+ *size = MIN(*size, MAX(avail, BUFFERING_DEFAULT_FILECHUNK));
}
- if (h->filerem > 0 && avail < size)
+ if (h->filerem > 0 && avail < *size)
{
/* Data isn't ready. Request buffering */
buf_request_buffer_handle(h->id);
@@ -1004,12 +1008,14 @@ static size_t prep_bufdata(const struct memory_handle *h, size_t size,
do
{
sleep(1);
+ h = find_handle(handle_id);
avail = RINGBUF_SUB(h->widx, h->ridx);
}
- while (h->filerem > 0 && avail < size);
+ while (h->filerem > 0 && avail < *size);
}
- return MIN(size,avail);
+ *size = MIN(*size,avail);
+ return h;
}
/* Copy data from the given handle to the dest buffer.
@@ -1018,12 +1024,12 @@ static size_t prep_bufdata(const struct memory_handle *h, size_t size,
*/
ssize_t bufread(int handle_id, size_t size, void *dest)
{
- const struct memory_handle *h = find_handle(handle_id);
+ const struct memory_handle *h;
+
+ h = prep_bufdata(handle_id, &size, false);
if (!h)
return ERR_HANDLE_NOT_FOUND;
- size = prep_bufdata(h, size, false);
-
if (h->ridx + size > buffer_len)
{
/* the data wraps around the end of the buffer */
@@ -1050,12 +1056,12 @@ ssize_t bufread(int handle_id, size_t size, void *dest)
*/
ssize_t bufgetdata(int handle_id, size_t size, void **data)
{
- const struct memory_handle *h = find_handle(handle_id);
+ const struct memory_handle *h;
+
+ h = prep_bufdata(handle_id, &size, true);
if (!h)
return ERR_HANDLE_NOT_FOUND;
- size = prep_bufdata(h, size, true);
-
if (h->ridx + size > buffer_len)
{
/* the data wraps around the end of the buffer :