diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2012-05-21 02:18:46 -0400 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2012-05-21 02:28:13 -0400 |
commit | 0ebfb937aaa073282415e561f8d1f150813a00fd (patch) | |
tree | ace0d47f3ee55c289a4b645986615ff9a281a1df | |
parent | 5f2618c363467648d96ccbc82e14df7d2194a148 (diff) | |
download | rockbox-0ebfb937aaa073282415e561f8d1f150813a00fd.tar.gz rockbox-0ebfb937aaa073282415e561f8d1f150813a00fd.zip |
Fix some lockup caused by handles not being initialized to < 0...
...by default where they would be interpreted as valid but not actually
be which would cause calls to buffering while it was not initialized.
Add BUFFER_EVENT_BUFFER_RESET to inform users of buffering that the
buffer is being reinitialized. Basically, this wraps all the
functionality being provided by three events (...START_PLAYBACK,
RECORDING_EVENT_START, RECORDING_EVENT_STOP) into one for radioart.c,
the only user of those events (perhaps remove them?) and closes some
loopholes.
Change-Id: I99ec46b9b5fb4e36605db5944c60ed986163db3a
-rw-r--r-- | apps/appevents.h | 1 | ||||
-rw-r--r-- | apps/buffering.c | 20 | ||||
-rw-r--r-- | apps/playback.c | 3 | ||||
-rw-r--r-- | apps/radio/radioart.c | 56 |
4 files changed, 37 insertions, 43 deletions
diff --git a/apps/appevents.h b/apps/appevents.h index 5cb0ee57b2..a11e423a90 100644 --- a/apps/appevents.h +++ b/apps/appevents.h @@ -54,6 +54,7 @@ enum { BUFFER_EVENT_CLOSED, BUFFER_EVENT_MOVED, BUFFER_EVENT_FINISHED, + BUFFER_EVENT_BUFFER_RESET }; /** Generic GUI class events **/ diff --git a/apps/buffering.c b/apps/buffering.c index c47564b7e1..b5bf427079 100644 --- a/apps/buffering.c +++ b/apps/buffering.c @@ -389,7 +389,7 @@ static bool rm_handle(const struct memory_handle *h) NULL if the handle wasn't found */ static struct memory_handle *find_handle(int handle_id) { - if (handle_id < 0) + if (handle_id < 0 || !first_handle) return NULL; /* simple caching because most of the time the requested handle @@ -1748,12 +1748,22 @@ bool buffering_reset(char *buf, size_t buflen) thus buf and buflen must be a aligned to an integer multiple of the storage alignment */ - buflen -= GUARD_BUFSIZE; + if (buf) { + buflen -= MIN(buflen, GUARD_BUFSIZE); + + STORAGE_ALIGN_BUFFER(buf, buflen); - STORAGE_ALIGN_BUFFER(buf, buflen); + if (!buf || !buflen) + return false; + } else { + buflen = 0; + } - if (!buf || !buflen) - return false; + send_event(BUFFER_EVENT_BUFFER_RESET, NULL); + + /* If handles weren't closed above, just do it */ + while (num_handles != 0) + bufclose(first_handle->id); buffer = buf; buffer_len = buflen; diff --git a/apps/playback.c b/apps/playback.c index bd7dd813c9..21cc017aaf 100644 --- a/apps/playback.c +++ b/apps/playback.c @@ -3621,6 +3621,9 @@ unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size) audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops); buf = core_get_data(audiobuf_handle); + if (buffer_state == AUDIOBUF_STATE_INITIALIZED) + buffering_reset(NULL, 0); /* mark buffer invalid */ + if (talk_buf || buffer_state == AUDIOBUF_STATE_TRASHED || !talk_voice_required()) { diff --git a/apps/radio/radioart.c b/apps/radio/radioart.c index 07fab814dd..53ed863b3b 100644 --- a/apps/radio/radioart.c +++ b/apps/radio/radioart.c @@ -41,10 +41,9 @@ struct radioart { char name[MAX_FMPRESET_LEN+1]; }; +static char* buf; static struct radioart radioart[MAX_RADIOART_IMAGES]; -#ifdef HAVE_RECORDING -static bool allow_buffer_access = true; /* If we are recording dont touch the buffers! */ -#endif + static int find_oldest_image(void) { int i; @@ -101,12 +100,10 @@ int radio_get_art_hid(struct dim *requested_dim) int preset = radio_current_preset(); int free_idx = -1; const char* preset_name; - if (radio_scan_mode() || preset < 0) - return -1; -#ifdef HAVE_RECORDING - if (!allow_buffer_access) + + if (!buf || radio_scan_mode() || preset < 0) return -1; -#endif + preset_name = radio_get_preset_name(preset); for (int i=0; i<MAX_RADIOART_IMAGES; i++) { @@ -137,55 +134,38 @@ int radio_get_art_hid(struct dim *requested_dim) return -1; } -static void playback_restarting_handler(void *data) + +static void buffer_reset_handler(void *data) { - (void)data; - int i; - for(i=0;i<MAX_RADIOART_IMAGES;i++) + buf = NULL; + for(int i=0;i<MAX_RADIOART_IMAGES;i++) { if (radioart[i].handle >= 0) bufclose(radioart[i].handle); radioart[i].handle = -1; radioart[i].name[0] = '\0'; } -} -#ifdef HAVE_RECORDING -static void recording_started_handler(void *data) -{ - (void)data; - allow_buffer_access = false; - playback_restarting_handler(NULL); -} -static void recording_stopped_handler(void *data) -{ + (void)data; - allow_buffer_access = true; } -#endif void radioart_init(bool entering_screen) { - int i; if (entering_screen) { - for(i=0;i<MAX_RADIOART_IMAGES;i++) - { - radioart[i].handle = -1; - radioart[i].name[0] = '\0'; - } - add_event(PLAYBACK_EVENT_START_PLAYBACK, true, playback_restarting_handler); - /* grab control over buffering */ - char* buf; size_t bufsize; buf = audio_get_buffer(false, &bufsize); buffering_reset(buf, bufsize); + /* one-shot */ + add_event(BUFFER_EVENT_BUFFER_RESET, true, buffer_reset_handler); } - else + else /* init at startup */ { -#if defined(HAVE_RECORDING) - add_event(RECORDING_EVENT_START, false, recording_started_handler); - add_event(RECORDING_EVENT_STOP, false, recording_stopped_handler); -#endif + for(int i=0;i<MAX_RADIOART_IMAGES;i++) + { + radioart[i].handle = -1; + radioart[i].name[0] = '\0'; + } } } |