From 720a8d349602fbfb6c33ea2b2dc19da73c880ce9 Mon Sep 17 00:00:00 2001 From: Nicolas Pennequin Date: Tue, 16 Oct 2007 23:21:31 +0200 Subject: [PATCH] Replace yield_codec() with a call to queue_wait_w_tmo() This achieves the same purpose, but in a more elegant way. (suggested by jhMikeS) --- apps/buffering.c | 74 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/apps/buffering.c b/apps/buffering.c index fae876ae0..fceb8747c 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -355,30 +355,13 @@ static bool filebuf_is_lowdata(void) return BUF_USED < AUDIO_FILEBUF_CRITICAL; } -/* Yield to the codec thread for as long as possible if it is in need of data. - Return true if the caller should break to let the buffering thread process - new queue events */ -static bool yield_codec(void) -{ - yield(); - - if (!queue_empty(&buffering_queue)) - return true; - - while (pcmbuf_is_lowdata() && !filebuf_is_lowdata()) - { - sleep(2); - - if (!queue_empty(&buffering_queue)) - return true; - } - - return false; -} - -/* Buffer data for the given handle. Return the amount of data buffered - or -1 if the handle wasn't found */ -static ssize_t buffer_handle(int handle_id) +/* Buffer data for the given handle. Return when finished or when an event was + received on the buffering queue. + ev is where queue events will be received. If buffering wasn't interrupted, + ev->id == SYS_TIMEOUT. + Return value is the amount of data buffered, or -1 if the handle wasn't found +*/ +static ssize_t buffer_handle(int handle_id, struct queue_event *ev) { DEBUGF("buffer_handle(%d)\n", handle_id); struct memory_handle *h = find_handle(handle_id); @@ -447,9 +430,20 @@ static ssize_t buffer_handle(int handle_id) /* DEBUGF("buffer_handle(%d): buffered %ld bytes. done: %ld. remaining: %ld.\n", h->id, rc, h->available, h->filerem); */ - /* Stop buffering if new queue events have arrived */ - if (yield_codec()) + /* Sleep a bit and stop buffering if new queue events have arrived */ + queue_wait_w_tmo(&buffering_queue, ev, 10); + + if (ev->id == Q_BUFFER_HANDLE && (int)ev->data == handle_id) { + /* Don't stop buffering if the request is to buffer the same file */ + LOGFQUEUE("buffering < Q_BUFFER_HANDLE"); + DEBUGF("buffer_handle: continuing buffering of handle %d\n", + handle_id); + } + else if (ev->id != SYS_TIMEOUT) { + /* An event was received, break the loop so it can be treated */ + DEBUGF("buffer_handle: event received, interrupting buffering\n"); break; + } } if (h->filerem == 0) { @@ -556,13 +550,15 @@ static void shrink_handle(int handle_id) /* Fill the buffer by buffering as much data as possible for handles that still have data left to buffer */ -static void fill_buffer(void) +static void fill_buffer(struct queue_event *ev) { DEBUGF("fill buffer()\n"); struct memory_handle *m = first_handle; while (m) { if (m->filerem > 0) { - buffer_handle(m->id); + buffer_handle(m->id, ev); + if (ev->id != SYS_TIMEOUT) + return; } m = m->next; } @@ -652,10 +648,10 @@ management functions for all the actual handle management work. /* Reserve space in the buffer for a file. - filename: name of the file to open - offset: offset at which to start buffering the file, useful when the first - (offset-1) bytes of the file aren't needed. - return value: <0 if the file cannot be opened, or one file already + filename : name of the file to open + offset : offset at which to start buffering the file, useful when the first + (offset-1) bytes of the file aren't needed. + returns : <0 if the file cannot be opened, or one file already queued to be opened, otherwise the handle for the file in the buffer */ int bufopen(char *file, size_t offset, enum data_type type) @@ -964,12 +960,15 @@ void buffering_thread(void) register_ata_idle_func(ata_fillbuffer_callback); #endif +next_event: switch (ev.id) { case Q_BUFFER_HANDLE: LOGFQUEUE("buffering < Q_BUFFER_HANDLE"); queue_reply(&buffering_queue, 1); - buffer_handle((int)ev.data); + buffer_handle((int)ev.data, &ev); + /* ev is now an event received by buffer_handle() */ + goto next_event; break; case Q_RESET_HANDLE: @@ -986,8 +985,10 @@ void buffering_thread(void) if (!ata_disk_is_active()) break; #endif - if (num_handles > 0 && data_rem() > 0) - fill_buffer(); + if (num_handles > 0 && data_rem() > 0) { + fill_buffer(&ev); + goto next_event; + } break; #endif /* MEM > 8 */ @@ -1031,7 +1032,8 @@ void buffering_thread(void) { DEBUGF("%ld bytes left to buffer and the buffer is low\n", (long)data_rem()); - fill_buffer(); + fill_buffer(&ev); + goto next_event; } } } -- 2.11.4.GIT