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
This commit is contained in:
Michael Sevakis 2012-05-21 02:18:46 -04:00
parent 5f2618c363
commit 0ebfb937aa
4 changed files with 39 additions and 45 deletions

View file

@ -54,6 +54,7 @@ enum {
BUFFER_EVENT_CLOSED, BUFFER_EVENT_CLOSED,
BUFFER_EVENT_MOVED, BUFFER_EVENT_MOVED,
BUFFER_EVENT_FINISHED, BUFFER_EVENT_FINISHED,
BUFFER_EVENT_BUFFER_RESET
}; };
/** Generic GUI class events **/ /** Generic GUI class events **/

View file

@ -389,7 +389,7 @@ static bool rm_handle(const struct memory_handle *h)
NULL if the handle wasn't found */ NULL if the handle wasn't found */
static struct memory_handle *find_handle(int handle_id) static struct memory_handle *find_handle(int handle_id)
{ {
if (handle_id < 0) if (handle_id < 0 || !first_handle)
return NULL; return NULL;
/* simple caching because most of the time the requested handle /* 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 thus buf and buflen must be a aligned to an integer multiple of
the storage alignment */ 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) if (!buf || !buflen)
return false; return false;
} else {
buflen = 0;
}
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 = buf;
buffer_len = buflen; buffer_len = buflen;

View file

@ -3621,6 +3621,9 @@ unsigned char * audio_get_buffer(bool talk_buf, size_t *buffer_size)
audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops); audiobuf_handle = core_alloc_maximum("audiobuf", &filebuflen, &ops);
buf = core_get_data(audiobuf_handle); 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 if (talk_buf || buffer_state == AUDIOBUF_STATE_TRASHED
|| !talk_voice_required()) || !talk_voice_required())
{ {

View file

@ -41,10 +41,9 @@ struct radioart {
char name[MAX_FMPRESET_LEN+1]; char name[MAX_FMPRESET_LEN+1];
}; };
static char* buf;
static struct radioart radioart[MAX_RADIOART_IMAGES]; 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) static int find_oldest_image(void)
{ {
int i; int i;
@ -101,12 +100,10 @@ int radio_get_art_hid(struct dim *requested_dim)
int preset = radio_current_preset(); int preset = radio_current_preset();
int free_idx = -1; int free_idx = -1;
const char* preset_name; const char* preset_name;
if (radio_scan_mode() || preset < 0)
if (!buf || radio_scan_mode() || preset < 0)
return -1; return -1;
#ifdef HAVE_RECORDING
if (!allow_buffer_access)
return -1;
#endif
preset_name = radio_get_preset_name(preset); preset_name = radio_get_preset_name(preset);
for (int i=0; i<MAX_RADIOART_IMAGES; i++) for (int i=0; i<MAX_RADIOART_IMAGES; i++)
{ {
@ -137,55 +134,38 @@ int radio_get_art_hid(struct dim *requested_dim)
return -1; return -1;
} }
static void playback_restarting_handler(void *data)
static void buffer_reset_handler(void *data)
{ {
(void)data; buf = NULL;
int i; for(int i=0;i<MAX_RADIOART_IMAGES;i++)
for(i=0;i<MAX_RADIOART_IMAGES;i++)
{ {
if (radioart[i].handle >= 0) if (radioart[i].handle >= 0)
bufclose(radioart[i].handle); bufclose(radioart[i].handle);
radioart[i].handle = -1; radioart[i].handle = -1;
radioart[i].name[0] = '\0'; radioart[i].name[0] = '\0';
} }
}
#ifdef HAVE_RECORDING
static void recording_started_handler(void *data)
{
(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) void radioart_init(bool entering_screen)
{ {
int i;
if (entering_screen) if (entering_screen)
{ {
for(i=0;i<MAX_RADIOART_IMAGES;i++) /* grab control over buffering */
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 /* init at startup */
{
for(int i=0;i<MAX_RADIOART_IMAGES;i++)
{ {
radioart[i].handle = -1; radioart[i].handle = -1;
radioart[i].name[0] = '\0'; 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);
}
else
{
#if defined(HAVE_RECORDING)
add_event(RECORDING_EVENT_START, false, recording_started_handler);
add_event(RECORDING_EVENT_STOP, false, recording_stopped_handler);
#endif
} }
} }