summaryrefslogtreecommitdiff
path: root/apps/plugins/pictureflow/pictureflow.c
diff options
context:
space:
mode:
authorChristian Soffke <christian.soffke@gmail.com>2021-11-14 22:20:09 +0100
committerSolomon Peachy <pizza@shaftnet.org>2021-11-22 08:06:44 -0500
commitf9ce8720c4fa7e5fa53e3aed03653f359fec4125 (patch)
tree939d232140eb2c92e7ea29b05349dd34b097fa8e /apps/plugins/pictureflow/pictureflow.c
parent3f966b2aa45755cd7788ea71eeea6a5d64bb827f (diff)
downloadrockbox-f9ce8720c4fa7e5fa53e3aed03653f359fec4125.tar.gz
rockbox-f9ce8720c4fa7e5fa53e3aed03653f359fec4125.zip
Fix: PictureFlow crashes
- After appending albums, when memory had been borrowed from the buflib buffer by shifting memory up using buflib_buffer_out() in create_track_index(), memory was later not shifted down using buflib_buffer_in() (the latter was only called after displaying the track list). - The picture loading thread was able to allocate memory from the buflib pool while the main thread was moving the buffer around. Slide loading will now be paused before shifting operations, and continued afterwards. Change-Id: I1c92b6c931fd14ebb885be4bc275148039b76a9a
Diffstat (limited to 'apps/plugins/pictureflow/pictureflow.c')
-rw-r--r--apps/plugins/pictureflow/pictureflow.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c
index b5cef72732..d0c2c3ef6c 100644
--- a/apps/plugins/pictureflow/pictureflow.c
+++ b/apps/plugins/pictureflow/pictureflow.c
@@ -495,6 +495,15 @@ static struct pf_track_t pf_tracks;
495void reset_track_list(void); 495void reset_track_list(void);
496 496
497static bool thread_is_running; 497static bool thread_is_running;
498static bool wants_to_quit = false;
499
500/*
501 Prevent picture loading thread from allocating
502 buflib memory while the main thread may be
503 performing buffer-shifting operations.
504*/
505static struct mutex buf_ctx_mutex;
506static bool buf_ctx_locked = false;
498 507
499static int cover_animation_keyframe; 508static int cover_animation_keyframe;
500static int extra_fade; 509static int extra_fade;
@@ -537,6 +546,18 @@ static void draw_progressbar(int step, int count, char *msg);
537static void draw_splashscreen(unsigned char * buf_tmp, size_t buf_tmp_size); 546static void draw_splashscreen(unsigned char * buf_tmp, size_t buf_tmp_size);
538static void free_all_slide_prio(int prio); 547static void free_all_slide_prio(int prio);
539 548
549static inline void buf_ctx_lock(void)
550{
551 rb->mutex_lock(&buf_ctx_mutex);
552 buf_ctx_locked = true;
553}
554
555static inline void buf_ctx_unlock(void)
556{
557 rb->mutex_unlock(&buf_ctx_mutex);
558 buf_ctx_locked = false;
559}
560
540static bool check_database(bool prompt) 561static bool check_database(bool prompt)
541{ 562{
542 bool needwarn = true; 563 bool needwarn = true;
@@ -1590,6 +1611,7 @@ static int compare_tracks (const void *a_v, const void *b_v)
1590 */ 1611 */
1591static void create_track_index(const int slide_index) 1612static void create_track_index(const int slide_index)
1592{ 1613{
1614 buf_ctx_lock();
1593 char temp[MAX_PATH + 1]; 1615 char temp[MAX_PATH + 1];
1594 if ( slide_index == pf_tracks.cur_idx ) 1616 if ( slide_index == pf_tracks.cur_idx )
1595 return; 1617 return;
@@ -1736,6 +1758,18 @@ fail:
1736} 1758}
1737 1759
1738/** 1760/**
1761 Re-grow the buflib buffer by returning space borrowed
1762 for track list
1763*/
1764static inline void free_borrowed_tracks(void)
1765{
1766 rb->buflib_buffer_in(&buf_ctx, pf_tracks.borrowed);
1767 pf_tracks.borrowed = 0;
1768 pf_tracks.cur_idx = -1;
1769 buf_ctx_unlock();
1770}
1771
1772/**
1739 Determine filename of the album art for the given slide_index and 1773 Determine filename of the album art for the given slide_index and
1740 store the result in buf. 1774 store the result in buf.
1741 The algorithm looks for the first track of the given album uses 1775 The algorithm looks for the first track of the given album uses
@@ -2371,6 +2405,10 @@ static inline bool load_and_prepare_surface(const int slide_index,
2371*/ 2405*/
2372bool load_new_slide(void) 2406bool load_new_slide(void)
2373{ 2407{
2408 buf_ctx_lock();
2409 if (wants_to_quit)
2410 return false;
2411
2374 int i = -1; 2412 int i = -1;
2375 2413
2376 if (pf_sldcache.center_idx != -1) 2414 if (pf_sldcache.center_idx != -1)
@@ -2417,6 +2455,7 @@ bool load_new_slide(void)
2417 pf_sldcache.center_idx = i; 2455 pf_sldcache.center_idx = i;
2418 pf_sldcache.left_idx = i; 2456 pf_sldcache.left_idx = i;
2419 pf_sldcache.right_idx = i; 2457 pf_sldcache.right_idx = i;
2458 buf_ctx_unlock();
2420 return true; 2459 return true;
2421 } 2460 }
2422 } 2461 }
@@ -2447,25 +2486,33 @@ bool load_new_slide(void)
2447 if ((prio_l < prio_r || right >= number_of_slides) && left > 0) 2486 if ((prio_l < prio_r || right >= number_of_slides) && left > 0)
2448 { 2487 {
2449 if (pf_sldcache.free == -1 && !free_slide_prio(prio_l)) 2488 if (pf_sldcache.free == -1 && !free_slide_prio(prio_l))
2489 {
2490 buf_ctx_unlock();
2450 return false; 2491 return false;
2492 }
2451 2493
2452 i = lla_pop_head(&pf_sldcache.free); 2494 i = lla_pop_head(&pf_sldcache.free);
2453 if (load_and_prepare_surface(left - 1, i, prio_l)) 2495 if (load_and_prepare_surface(left - 1, i, prio_l))
2454 { 2496 {
2455 lla_insert_before(&pf_sldcache.used, i, pf_sldcache.left_idx); 2497 lla_insert_before(&pf_sldcache.used, i, pf_sldcache.left_idx);
2456 pf_sldcache.left_idx = i; 2498 pf_sldcache.left_idx = i;
2499 buf_ctx_unlock();
2457 return true; 2500 return true;
2458 } 2501 }
2459 } else if(right < number_of_slides - 1) 2502 } else if(right < number_of_slides - 1)
2460 { 2503 {
2461 if (pf_sldcache.free == -1 && !free_slide_prio(prio_r)) 2504 if (pf_sldcache.free == -1 && !free_slide_prio(prio_r))
2505 {
2506 buf_ctx_unlock();
2462 return false; 2507 return false;
2508 }
2463 2509
2464 i = lla_pop_head(&pf_sldcache.free); 2510 i = lla_pop_head(&pf_sldcache.free);
2465 if (load_and_prepare_surface(right + 1, i, prio_r)) 2511 if (load_and_prepare_surface(right + 1, i, prio_r))
2466 { 2512 {
2467 lla_insert_after(i, pf_sldcache.right_idx); 2513 lla_insert_after(i, pf_sldcache.right_idx);
2468 pf_sldcache.right_idx = i; 2514 pf_sldcache.right_idx = i;
2515 buf_ctx_unlock();
2469 return true; 2516 return true;
2470 } 2517 }
2471 } 2518 }
@@ -2480,6 +2527,7 @@ insert_first_slide:
2480 pf_sldcache.left_idx = i; 2527 pf_sldcache.left_idx = i;
2481 pf_sldcache.right_idx = i; 2528 pf_sldcache.right_idx = i;
2482 pf_sldcache.used = i; 2529 pf_sldcache.used = i;
2530 buf_ctx_unlock();
2483 return true; 2531 return true;
2484 } 2532 }
2485 } 2533 }
@@ -2488,6 +2536,7 @@ fail_and_refree:
2488 { 2536 {
2489 lla_insert_tail(&pf_sldcache.free, i); 2537 lla_insert_tail(&pf_sldcache.free, i);
2490 } 2538 }
2539 buf_ctx_unlock();
2491 return false; 2540 return false;
2492} 2541}
2493 2542
@@ -3004,6 +3053,10 @@ static void update_scroll_animation(void)
3004*/ 3053*/
3005static void cleanup(void) 3054static void cleanup(void)
3006{ 3055{
3056 wants_to_quit = true;
3057 if (buf_ctx_locked)
3058 buf_ctx_unlock();
3059
3007#ifdef HAVE_ADJUSTABLE_CPU_FREQ 3060#ifdef HAVE_ADJUSTABLE_CPU_FREQ
3008 rb->cpu_boost(false); 3061 rb->cpu_boost(false);
3009#endif 3062#endif
@@ -3552,6 +3605,8 @@ static int pictureflow_main(void)
3552#endif 3605#endif
3553 } 3606 }
3554 3607
3608 rb->mutex_init(&buf_ctx_mutex);
3609
3555 init_scroll_lines(); 3610 init_scroll_lines();
3556 init_reflect_table(); 3611 init_reflect_table();
3557 3612
@@ -3759,10 +3814,8 @@ static int pictureflow_main(void)
3759 case PF_BACK: 3814 case PF_BACK:
3760 if ( pf_state == pf_show_tracks ) 3815 if ( pf_state == pf_show_tracks )
3761 { 3816 {
3762 rb->buflib_buffer_in(&buf_ctx, pf_tracks.borrowed);
3763 pf_tracks.borrowed = 0;
3764 pf_tracks.cur_idx = -1;
3765 pf_state = pf_cover_out; 3817 pf_state = pf_cover_out;
3818 free_borrowed_tracks();
3766 } 3819 }
3767 if (pf_state == pf_idle || pf_state == pf_scrolling) 3820 if (pf_state == pf_idle || pf_state == pf_scrolling)
3768 return PLUGIN_OK; 3821 return PLUGIN_OK;
@@ -3803,6 +3856,7 @@ static int pictureflow_main(void)
3803 create_track_index(center_slide.slide_index); 3856 create_track_index(center_slide.slide_index);
3804 reset_track_list(); 3857 reset_track_list();
3805 start_playback(true); 3858 start_playback(true);
3859 free_borrowed_tracks();
3806 rb->splash(HZ*2, ID2P(LANG_ADDED_TO_PLAYLIST)); 3860 rb->splash(HZ*2, ID2P(LANG_ADDED_TO_PLAYLIST));
3807 } 3861 }
3808 else if( pf_state == pf_show_tracks ) { 3862 else if( pf_state == pf_show_tracks ) {