summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2012-05-21 02:18:46 -0400
committerMichael Sevakis <jethead71@rockbox.org>2012-05-21 02:28:13 -0400
commit0ebfb937aaa073282415e561f8d1f150813a00fd (patch)
treeace0d47f3ee55c289a4b645986615ff9a281a1df
parent5f2618c363467648d96ccbc82e14df7d2194a148 (diff)
downloadrockbox-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.h1
-rw-r--r--apps/buffering.c20
-rw-r--r--apps/playback.c3
-rw-r--r--apps/radio/radioart.c56
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';
+ }
}
}