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
This commit is contained in:
parent
3f966b2aa4
commit
f9ce8720c4
1 changed files with 57 additions and 3 deletions
|
@ -495,6 +495,15 @@ static struct pf_track_t pf_tracks;
|
||||||
void reset_track_list(void);
|
void reset_track_list(void);
|
||||||
|
|
||||||
static bool thread_is_running;
|
static bool thread_is_running;
|
||||||
|
static bool wants_to_quit = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Prevent picture loading thread from allocating
|
||||||
|
buflib memory while the main thread may be
|
||||||
|
performing buffer-shifting operations.
|
||||||
|
*/
|
||||||
|
static struct mutex buf_ctx_mutex;
|
||||||
|
static bool buf_ctx_locked = false;
|
||||||
|
|
||||||
static int cover_animation_keyframe;
|
static int cover_animation_keyframe;
|
||||||
static int extra_fade;
|
static int extra_fade;
|
||||||
|
@ -537,6 +546,18 @@ static void draw_progressbar(int step, int count, char *msg);
|
||||||
static void draw_splashscreen(unsigned char * buf_tmp, size_t buf_tmp_size);
|
static void draw_splashscreen(unsigned char * buf_tmp, size_t buf_tmp_size);
|
||||||
static void free_all_slide_prio(int prio);
|
static void free_all_slide_prio(int prio);
|
||||||
|
|
||||||
|
static inline void buf_ctx_lock(void)
|
||||||
|
{
|
||||||
|
rb->mutex_lock(&buf_ctx_mutex);
|
||||||
|
buf_ctx_locked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void buf_ctx_unlock(void)
|
||||||
|
{
|
||||||
|
rb->mutex_unlock(&buf_ctx_mutex);
|
||||||
|
buf_ctx_locked = false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool check_database(bool prompt)
|
static bool check_database(bool prompt)
|
||||||
{
|
{
|
||||||
bool needwarn = true;
|
bool needwarn = true;
|
||||||
|
@ -1590,6 +1611,7 @@ static int compare_tracks (const void *a_v, const void *b_v)
|
||||||
*/
|
*/
|
||||||
static void create_track_index(const int slide_index)
|
static void create_track_index(const int slide_index)
|
||||||
{
|
{
|
||||||
|
buf_ctx_lock();
|
||||||
char temp[MAX_PATH + 1];
|
char temp[MAX_PATH + 1];
|
||||||
if ( slide_index == pf_tracks.cur_idx )
|
if ( slide_index == pf_tracks.cur_idx )
|
||||||
return;
|
return;
|
||||||
|
@ -1735,6 +1757,18 @@ fail:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Re-grow the buflib buffer by returning space borrowed
|
||||||
|
for track list
|
||||||
|
*/
|
||||||
|
static inline void free_borrowed_tracks(void)
|
||||||
|
{
|
||||||
|
rb->buflib_buffer_in(&buf_ctx, pf_tracks.borrowed);
|
||||||
|
pf_tracks.borrowed = 0;
|
||||||
|
pf_tracks.cur_idx = -1;
|
||||||
|
buf_ctx_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Determine filename of the album art for the given slide_index and
|
Determine filename of the album art for the given slide_index and
|
||||||
store the result in buf.
|
store the result in buf.
|
||||||
|
@ -2371,6 +2405,10 @@ static inline bool load_and_prepare_surface(const int slide_index,
|
||||||
*/
|
*/
|
||||||
bool load_new_slide(void)
|
bool load_new_slide(void)
|
||||||
{
|
{
|
||||||
|
buf_ctx_lock();
|
||||||
|
if (wants_to_quit)
|
||||||
|
return false;
|
||||||
|
|
||||||
int i = -1;
|
int i = -1;
|
||||||
|
|
||||||
if (pf_sldcache.center_idx != -1)
|
if (pf_sldcache.center_idx != -1)
|
||||||
|
@ -2417,6 +2455,7 @@ bool load_new_slide(void)
|
||||||
pf_sldcache.center_idx = i;
|
pf_sldcache.center_idx = i;
|
||||||
pf_sldcache.left_idx = i;
|
pf_sldcache.left_idx = i;
|
||||||
pf_sldcache.right_idx = i;
|
pf_sldcache.right_idx = i;
|
||||||
|
buf_ctx_unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2447,25 +2486,33 @@ bool load_new_slide(void)
|
||||||
if ((prio_l < prio_r || right >= number_of_slides) && left > 0)
|
if ((prio_l < prio_r || right >= number_of_slides) && left > 0)
|
||||||
{
|
{
|
||||||
if (pf_sldcache.free == -1 && !free_slide_prio(prio_l))
|
if (pf_sldcache.free == -1 && !free_slide_prio(prio_l))
|
||||||
|
{
|
||||||
|
buf_ctx_unlock();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
i = lla_pop_head(&pf_sldcache.free);
|
i = lla_pop_head(&pf_sldcache.free);
|
||||||
if (load_and_prepare_surface(left - 1, i, prio_l))
|
if (load_and_prepare_surface(left - 1, i, prio_l))
|
||||||
{
|
{
|
||||||
lla_insert_before(&pf_sldcache.used, i, pf_sldcache.left_idx);
|
lla_insert_before(&pf_sldcache.used, i, pf_sldcache.left_idx);
|
||||||
pf_sldcache.left_idx = i;
|
pf_sldcache.left_idx = i;
|
||||||
|
buf_ctx_unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if(right < number_of_slides - 1)
|
} else if(right < number_of_slides - 1)
|
||||||
{
|
{
|
||||||
if (pf_sldcache.free == -1 && !free_slide_prio(prio_r))
|
if (pf_sldcache.free == -1 && !free_slide_prio(prio_r))
|
||||||
|
{
|
||||||
|
buf_ctx_unlock();
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
i = lla_pop_head(&pf_sldcache.free);
|
i = lla_pop_head(&pf_sldcache.free);
|
||||||
if (load_and_prepare_surface(right + 1, i, prio_r))
|
if (load_and_prepare_surface(right + 1, i, prio_r))
|
||||||
{
|
{
|
||||||
lla_insert_after(i, pf_sldcache.right_idx);
|
lla_insert_after(i, pf_sldcache.right_idx);
|
||||||
pf_sldcache.right_idx = i;
|
pf_sldcache.right_idx = i;
|
||||||
|
buf_ctx_unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2480,6 +2527,7 @@ insert_first_slide:
|
||||||
pf_sldcache.left_idx = i;
|
pf_sldcache.left_idx = i;
|
||||||
pf_sldcache.right_idx = i;
|
pf_sldcache.right_idx = i;
|
||||||
pf_sldcache.used = i;
|
pf_sldcache.used = i;
|
||||||
|
buf_ctx_unlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2488,6 +2536,7 @@ fail_and_refree:
|
||||||
{
|
{
|
||||||
lla_insert_tail(&pf_sldcache.free, i);
|
lla_insert_tail(&pf_sldcache.free, i);
|
||||||
}
|
}
|
||||||
|
buf_ctx_unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3004,6 +3053,10 @@ static void update_scroll_animation(void)
|
||||||
*/
|
*/
|
||||||
static void cleanup(void)
|
static void cleanup(void)
|
||||||
{
|
{
|
||||||
|
wants_to_quit = true;
|
||||||
|
if (buf_ctx_locked)
|
||||||
|
buf_ctx_unlock();
|
||||||
|
|
||||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||||
rb->cpu_boost(false);
|
rb->cpu_boost(false);
|
||||||
#endif
|
#endif
|
||||||
|
@ -3552,6 +3605,8 @@ static int pictureflow_main(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rb->mutex_init(&buf_ctx_mutex);
|
||||||
|
|
||||||
init_scroll_lines();
|
init_scroll_lines();
|
||||||
init_reflect_table();
|
init_reflect_table();
|
||||||
|
|
||||||
|
@ -3759,10 +3814,8 @@ static int pictureflow_main(void)
|
||||||
case PF_BACK:
|
case PF_BACK:
|
||||||
if ( pf_state == pf_show_tracks )
|
if ( pf_state == pf_show_tracks )
|
||||||
{
|
{
|
||||||
rb->buflib_buffer_in(&buf_ctx, pf_tracks.borrowed);
|
|
||||||
pf_tracks.borrowed = 0;
|
|
||||||
pf_tracks.cur_idx = -1;
|
|
||||||
pf_state = pf_cover_out;
|
pf_state = pf_cover_out;
|
||||||
|
free_borrowed_tracks();
|
||||||
}
|
}
|
||||||
if (pf_state == pf_idle || pf_state == pf_scrolling)
|
if (pf_state == pf_idle || pf_state == pf_scrolling)
|
||||||
return PLUGIN_OK;
|
return PLUGIN_OK;
|
||||||
|
@ -3803,6 +3856,7 @@ static int pictureflow_main(void)
|
||||||
create_track_index(center_slide.slide_index);
|
create_track_index(center_slide.slide_index);
|
||||||
reset_track_list();
|
reset_track_list();
|
||||||
start_playback(true);
|
start_playback(true);
|
||||||
|
free_borrowed_tracks();
|
||||||
rb->splash(HZ*2, ID2P(LANG_ADDED_TO_PLAYLIST));
|
rb->splash(HZ*2, ID2P(LANG_ADDED_TO_PLAYLIST));
|
||||||
}
|
}
|
||||||
else if( pf_state == pf_show_tracks ) {
|
else if( pf_state == pf_show_tracks ) {
|
||||||
|
|
Loading…
Reference in a new issue