diff options
author | Purdea Andrei <andrei@purdea.ro> | 2012-06-18 12:37:22 +0300 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2012-07-19 00:00:41 +0200 |
commit | 323282f22dc1b510ae4a7c5e1a6de192f7df73d0 (patch) | |
tree | 72515b78ceb323f212590821aa6b9a477f1e2fc6 | |
parent | b7937a729f948c41f6582d74dd275aed2aa4fa25 (diff) | |
download | rockbox-323282f22dc1b510ae4a7c5e1a6de192f7df73d0.tar.gz rockbox-323282f22dc1b510ae4a7c5e1a6de192f7df73d0.zip |
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>
-rw-r--r-- | apps/playlist_viewer.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c index 68732adcbc..5479ba43ba 100644 --- a/apps/playlist_viewer.c +++ b/apps/playlist_viewer.c | |||
@@ -175,12 +175,21 @@ static void playlist_buffer_load_entries(struct playlist_buffer *pb, int index, | |||
175 | pb->num_loaded = i; | 175 | pb->num_loaded = i; |
176 | } | 176 | } |
177 | 177 | ||
178 | /* playlist_buffer_load_entries_screen() | ||
179 | * This function is called when the currently selected item gets too close | ||
180 | * to the start or the end of the loaded part of the playlis, or when | ||
181 | * the list callback requests a playlist item that has not been loaded yet | ||
182 | * | ||
183 | * reference_track is either the currently selected track, or the track that | ||
184 | * has been requested by the callback, and has not been loaded yet. | ||
185 | */ | ||
178 | static void playlist_buffer_load_entries_screen(struct playlist_buffer * pb, | 186 | static void playlist_buffer_load_entries_screen(struct playlist_buffer * pb, |
179 | enum direction direction) | 187 | enum direction direction, |
188 | int reference_track) | ||
180 | { | 189 | { |
181 | if (direction == FORWARD) | 190 | if (direction == FORWARD) |
182 | { | 191 | { |
183 | int min_start = viewer.selected_track-2*screens[0].getnblines(); | 192 | int min_start = reference_track-2*screens[0].getnblines(); |
184 | while (min_start < 0) | 193 | while (min_start < 0) |
185 | min_start += viewer.num_tracks; | 194 | min_start += viewer.num_tracks; |
186 | min_start %= viewer.num_tracks; | 195 | min_start %= viewer.num_tracks; |
@@ -188,7 +197,7 @@ static void playlist_buffer_load_entries_screen(struct playlist_buffer * pb, | |||
188 | } | 197 | } |
189 | else | 198 | else |
190 | { | 199 | { |
191 | int max_start = viewer.selected_track+2*screens[0].getnblines(); | 200 | int max_start = reference_track+2*screens[0].getnblines(); |
192 | max_start %= viewer.num_tracks; | 201 | max_start %= viewer.num_tracks; |
193 | playlist_buffer_load_entries(pb, max_start, BACKWARD); | 202 | playlist_buffer_load_entries(pb, max_start, BACKWARD); |
194 | } | 203 | } |
@@ -266,6 +275,31 @@ static struct playlist_entry * playlist_buffer_get_track(struct playlist_buffer | |||
266 | int index) | 275 | int index) |
267 | { | 276 | { |
268 | int buffer_index = playlist_buffer_get_index(pb, index); | 277 | int buffer_index = playlist_buffer_get_index(pb, index); |
278 | /* Make sure that we are not returning an invalid pointer. | ||
279 | In some cases, when scrolling really fast, it could happen that a reqested track | ||
280 | has not been pre-loaded */ | ||
281 | if (buffer_index < 0) { | ||
282 | playlist_buffer_load_entries_screen(&viewer.buffer, | ||
283 | pb->direction == FORWARD ? BACKWARD : FORWARD, | ||
284 | index); | ||
285 | |||
286 | } else if (buffer_index >= pb->num_loaded) { | ||
287 | playlist_buffer_load_entries_screen(&viewer.buffer, | ||
288 | pb->direction, | ||
289 | index); | ||
290 | } | ||
291 | buffer_index = playlist_buffer_get_index(pb, index); | ||
292 | if (buffer_index < 0 || buffer_index >= pb->num_loaded) { | ||
293 | /* This really shouldn't happen. If this happens, then | ||
294 | the name_buffer is probably too small to store enough | ||
295 | titles to fill the screen, and preload data in the short | ||
296 | direction. | ||
297 | |||
298 | If this happens then scrolling performance will probably | ||
299 | be quite low, but it's better then having Data Abort errors */ | ||
300 | playlist_buffer_load_entries(pb, index, FORWARD); | ||
301 | buffer_index = playlist_buffer_get_index(pb, index); | ||
302 | } | ||
269 | return &(pb->tracks[buffer_index]); | 303 | return &(pb->tracks[buffer_index]); |
270 | } | 304 | } |
271 | 305 | ||
@@ -425,7 +459,8 @@ static bool update_playlist(bool force) | |||
425 | global_status.resume_offset = -1; | 459 | global_status.resume_offset = -1; |
426 | return false; | 460 | return false; |
427 | } | 461 | } |
428 | playlist_buffer_load_entries_screen(&viewer.buffer, FORWARD); | 462 | playlist_buffer_load_entries_screen(&viewer.buffer, FORWARD, |
463 | viewer.selected_track); | ||
429 | if (viewer.buffer.num_loaded <= 0) | 464 | if (viewer.buffer.num_loaded <= 0) |
430 | { | 465 | { |
431 | global_status.resume_index = -1; | 466 | global_status.resume_index = -1; |
@@ -679,7 +714,8 @@ enum playlist_viewer_result playlist_viewer_ex(const char* filename) | |||
679 | viewer.selected_track); | 714 | viewer.selected_track); |
680 | if (reload) | 715 | if (reload) |
681 | playlist_buffer_load_entries_screen(&viewer.buffer, | 716 | playlist_buffer_load_entries_screen(&viewer.buffer, |
682 | button == ACTION_STD_NEXT ? FORWARD : BACKWARD); | 717 | button == ACTION_STD_NEXT ? FORWARD : BACKWARD, |
718 | viewer.selected_track); | ||
683 | if (reload || viewer.moving_track >= 0) | 719 | if (reload || viewer.moving_track >= 0) |
684 | gui_synclist_draw(&playlist_lists); | 720 | gui_synclist_draw(&playlist_lists); |
685 | } | 721 | } |