Fixing data abort (pc in strchr). when scrolling a big playlist very fast.

Change-Id: Ibe00a11592a18d320682cce755e48ce701ff5b4a
Reviewed-on: http://gerrit.rockbox.org/281
Reviewed-by: Thomas Martitz <kugel@rockbox.org>
Tested-by: Thomas Martitz <kugel@rockbox.org>
This commit is contained in:
Purdea Andrei 2012-06-18 12:37:22 +03:00 committed by Thomas Martitz
parent b7937a729f
commit 323282f22d

View file

@ -175,12 +175,21 @@ static void playlist_buffer_load_entries(struct playlist_buffer *pb, int index,
pb->num_loaded = i;
}
/* playlist_buffer_load_entries_screen()
* This function is called when the currently selected item gets too close
* to the start or the end of the loaded part of the playlis, or when
* the list callback requests a playlist item that has not been loaded yet
*
* reference_track is either the currently selected track, or the track that
* has been requested by the callback, and has not been loaded yet.
*/
static void playlist_buffer_load_entries_screen(struct playlist_buffer * pb,
enum direction direction)
enum direction direction,
int reference_track)
{
if (direction == FORWARD)
{
int min_start = viewer.selected_track-2*screens[0].getnblines();
int min_start = reference_track-2*screens[0].getnblines();
while (min_start < 0)
min_start += viewer.num_tracks;
min_start %= viewer.num_tracks;
@ -188,7 +197,7 @@ static void playlist_buffer_load_entries_screen(struct playlist_buffer * pb,
}
else
{
int max_start = viewer.selected_track+2*screens[0].getnblines();
int max_start = reference_track+2*screens[0].getnblines();
max_start %= viewer.num_tracks;
playlist_buffer_load_entries(pb, max_start, BACKWARD);
}
@ -266,6 +275,31 @@ static struct playlist_entry * playlist_buffer_get_track(struct playlist_buffer
int index)
{
int buffer_index = playlist_buffer_get_index(pb, index);
/* Make sure that we are not returning an invalid pointer.
In some cases, when scrolling really fast, it could happen that a reqested track
has not been pre-loaded */
if (buffer_index < 0) {
playlist_buffer_load_entries_screen(&viewer.buffer,
pb->direction == FORWARD ? BACKWARD : FORWARD,
index);
} else if (buffer_index >= pb->num_loaded) {
playlist_buffer_load_entries_screen(&viewer.buffer,
pb->direction,
index);
}
buffer_index = playlist_buffer_get_index(pb, index);
if (buffer_index < 0 || buffer_index >= pb->num_loaded) {
/* This really shouldn't happen. If this happens, then
the name_buffer is probably too small to store enough
titles to fill the screen, and preload data in the short
direction.
If this happens then scrolling performance will probably
be quite low, but it's better then having Data Abort errors */
playlist_buffer_load_entries(pb, index, FORWARD);
buffer_index = playlist_buffer_get_index(pb, index);
}
return &(pb->tracks[buffer_index]);
}
@ -425,7 +459,8 @@ static bool update_playlist(bool force)
global_status.resume_offset = -1;
return false;
}
playlist_buffer_load_entries_screen(&viewer.buffer, FORWARD);
playlist_buffer_load_entries_screen(&viewer.buffer, FORWARD,
viewer.selected_track);
if (viewer.buffer.num_loaded <= 0)
{
global_status.resume_index = -1;
@ -679,7 +714,8 @@ enum playlist_viewer_result playlist_viewer_ex(const char* filename)
viewer.selected_track);
if (reload)
playlist_buffer_load_entries_screen(&viewer.buffer,
button == ACTION_STD_NEXT ? FORWARD : BACKWARD);
button == ACTION_STD_NEXT ? FORWARD : BACKWARD,
viewer.selected_track);
if (reload || viewer.moving_track >= 0)
gui_synclist_draw(&playlist_lists);
}