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:
parent
b7937a729f
commit
323282f22d
1 changed files with 41 additions and 5 deletions
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue