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.tar.gz
rockbox-6e8ee408bfbe2e59e399e395d5b1f78208987906.zip
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 f4316fe5af..1d1fca15ab 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -974,29 +974,33 @@ int bufadvance(int handle_id, off_t offset)
974 * actual amount of data available for reading. This function explicitly 974 * actual amount of data available for reading. This function explicitly
975 * does not check the validity of the input handle. It does do range checks 975 * does not check the validity of the input handle. It does do range checks
976 * on size and returns a valid (and explicit) amount of data for reading */ 976 * on size and returns a valid (and explicit) amount of data for reading */
977static size_t prep_bufdata(const struct memory_handle *h, size_t size, 977static struct memory_handle *prep_bufdata(int handle_id, size_t *size,
978 bool filechunk_limit) 978 bool filechunk_limit)
979{ 979{
980 struct memory_handle *h = find_handle(handle_id);
981 if (!h)
982 return NULL;
983
980 size_t avail = RINGBUF_SUB(h->widx, h->ridx); 984 size_t avail = RINGBUF_SUB(h->widx, h->ridx);
981 985
982 if (avail == 0 && h->filerem == 0) 986 if (avail == 0 && h->filerem == 0)
983 /* File is finished reading */ 987 /* File is finished reading */
984 return 0; 988 return 0;
985 989
986 if (size == 0 || size > avail + h->filerem) 990 if (*size == 0 || *size > avail + h->filerem)
987 size = avail + h->filerem; 991 *size = avail + h->filerem;
988 992
989 if (filechunk_limit && 993 if (filechunk_limit &&
990 h->type == TYPE_PACKET_AUDIO && size > BUFFERING_DEFAULT_FILECHUNK) 994 h->type == TYPE_PACKET_AUDIO && *size > BUFFERING_DEFAULT_FILECHUNK)
991 { 995 {
992 logf("data request > filechunk"); 996 logf("data request > filechunk");
993 /* If more than a filechunk is requested, provide no more than the 997 /* If more than a filechunk is requested, provide no more than the
994 amount of data on buffer or one file chunk, but without increasing 998 amount of data on buffer or one file chunk, but without increasing
995 "size", which would be bad. */ 999 "size", which would be bad. */
996 size = MIN(size, MAX(avail, BUFFERING_DEFAULT_FILECHUNK)); 1000 *size = MIN(*size, MAX(avail, BUFFERING_DEFAULT_FILECHUNK));
997 } 1001 }
998 1002
999 if (h->filerem > 0 && avail < size) 1003 if (h->filerem > 0 && avail < *size)
1000 { 1004 {
1001 /* Data isn't ready. Request buffering */ 1005 /* Data isn't ready. Request buffering */
1002 buf_request_buffer_handle(h->id); 1006 buf_request_buffer_handle(h->id);
@@ -1004,12 +1008,14 @@ static size_t prep_bufdata(const struct memory_handle *h, size_t size,
1004 do 1008 do
1005 { 1009 {
1006 sleep(1); 1010 sleep(1);
1011 h = find_handle(handle_id);
1007 avail = RINGBUF_SUB(h->widx, h->ridx); 1012 avail = RINGBUF_SUB(h->widx, h->ridx);
1008 } 1013 }
1009 while (h->filerem > 0 && avail < size); 1014 while (h->filerem > 0 && avail < *size);
1010 } 1015 }
1011 1016
1012 return MIN(size,avail); 1017 *size = MIN(*size,avail);
1018 return h;
1013} 1019}
1014 1020
1015/* Copy data from the given handle to the dest buffer. 1021/* 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,
1018*/ 1024*/
1019ssize_t bufread(int handle_id, size_t size, void *dest) 1025ssize_t bufread(int handle_id, size_t size, void *dest)
1020{ 1026{
1021 const struct memory_handle *h = find_handle(handle_id); 1027 const struct memory_handle *h;
1028
1029 h = prep_bufdata(handle_id, &size, false);
1022 if (!h) 1030 if (!h)
1023 return ERR_HANDLE_NOT_FOUND; 1031 return ERR_HANDLE_NOT_FOUND;
1024 1032
1025 size = prep_bufdata(h, size, false);
1026
1027 if (h->ridx + size > buffer_len) 1033 if (h->ridx + size > buffer_len)
1028 { 1034 {
1029 /* the data wraps around the end of the buffer */ 1035 /* the data wraps around the end of the buffer */
@@ -1050,12 +1056,12 @@ ssize_t bufread(int handle_id, size_t size, void *dest)
1050*/ 1056*/
1051ssize_t bufgetdata(int handle_id, size_t size, void **data) 1057ssize_t bufgetdata(int handle_id, size_t size, void **data)
1052{ 1058{
1053 const struct memory_handle *h = find_handle(handle_id); 1059 const struct memory_handle *h;
1060
1061 h = prep_bufdata(handle_id, &size, true);
1054 if (!h) 1062 if (!h)
1055 return ERR_HANDLE_NOT_FOUND; 1063 return ERR_HANDLE_NOT_FOUND;
1056 1064
1057 size = prep_bufdata(h, size, true);
1058
1059 if (h->ridx + size > buffer_len) 1065 if (h->ridx + size > buffer_len)
1060 { 1066 {
1061 /* the data wraps around the end of the buffer : 1067 /* the data wraps around the end of the buffer :