summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorChristian Soffke <christian.soffke@gmail.com>2021-11-26 21:08:49 +0100
committerWilliam Wilgus <me.theuser@yahoo.com>2021-12-03 23:51:12 -0500
commit2bd0d5738f1b29640eec2a916d7b57fe3cf5eaab (patch)
tree78735292ee3c10e414914829c9f44ee28c3264ac /apps
parent09e1cd489f2316e2a2714436674fc4b97c8f9c49 (diff)
downloadrockbox-2bd0d5738f1b29640eec2a916d7b57fe3cf5eaab.tar.gz
rockbox-2bd0d5738f1b29640eec2a916d7b57fe3cf5eaab.zip
PictureFlow: Preliminary fix for infinite loop
Supposed to prevent situations where PictureFlow enters into an infinite loop while unsuccessfully looking for a slide cache slot. Technically more of a bandaid than a fix at this point, since it masks behavior that shouldn't occur in the first place, but at least it will make the issue essentially unnoticeable by the user for the time being. Change-Id: I8a9b30448949dd53f624eae918484b740b4f873e
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/pictureflow/pictureflow.c67
1 files changed, 47 insertions, 20 deletions
diff --git a/apps/plugins/pictureflow/pictureflow.c b/apps/plugins/pictureflow/pictureflow.c
index 6db28f3aa1..db04f6b89a 100644
--- a/apps/plugins/pictureflow/pictureflow.c
+++ b/apps/plugins/pictureflow/pictureflow.c
@@ -2198,6 +2198,26 @@ static bool create_pf_thread(void)
2198} 2198}
2199 2199
2200 2200
2201static void initialize_slide_cache(void)
2202{
2203 int i= 0;
2204 for (i = 0; i < SLIDE_CACHE_SIZE; i++) {
2205 pf_sldcache.cache[i].hid = 0;
2206 pf_sldcache.cache[i].index = 0;
2207 pf_sldcache.cache[i].next = i + 1;
2208 pf_sldcache.cache[i].prev = i - 1;
2209 }
2210 pf_sldcache.cache[0].prev = i - 1;
2211 pf_sldcache.cache[i - 1].next = 0;
2212
2213 pf_sldcache.free = 0;
2214 pf_sldcache.used = -1;
2215 pf_sldcache.left_idx = -1;
2216 pf_sldcache.right_idx = -1;
2217 pf_sldcache.center_idx = -1;
2218}
2219
2220
2201/* 2221/*
2202 * The following functions implement the linked-list-in-array used to manage 2222 * The following functions implement the linked-list-in-array used to manage
2203 * the LRU cache of slides, and the list of free cache slots. 2223 * the LRU cache of slides, and the list of free cache slots.
@@ -2206,20 +2226,30 @@ static bool create_pf_thread(void)
2206#define _SEEK_RIGHT_WHILE(start, cond) \ 2226#define _SEEK_RIGHT_WHILE(start, cond) \
2207({ \ 2227({ \
2208 int ind_, next_ = (start); \ 2228 int ind_, next_ = (start); \
2229 int i_ = 0; \
2209 do { \ 2230 do { \
2210 ind_ = next_; \ 2231 ind_ = next_; \
2211 next_ = pf_sldcache.cache[ind_].next; \ 2232 next_ = pf_sldcache.cache[ind_].next; \
2212 } while (next_ != pf_sldcache.used && (cond)); \ 2233 i_++; \
2234 } while (next_ != pf_sldcache.used && (cond) && i_ < SLIDE_CACHE_SIZE); \
2235 if (i_ >= SLIDE_CACHE_SIZE) \
2236 /* TODO: Not supposed to happen */ \
2237 ind_ = -1; \
2213 ind_; \ 2238 ind_; \
2214}) 2239})
2215 2240
2216#define _SEEK_LEFT_WHILE(start, cond) \ 2241#define _SEEK_LEFT_WHILE(start, cond) \
2217({ \ 2242({ \
2218 int ind_, next_ = (start); \ 2243 int ind_, next_ = (start); \
2244 int i_ = 0; \
2219 do { \ 2245 do { \
2220 ind_ = next_; \ 2246 ind_ = next_; \
2221 next_ = pf_sldcache.cache[ind_].prev; \ 2247 next_ = pf_sldcache.cache[ind_].prev; \
2222 } while (ind_ != pf_sldcache.used && (cond)); \ 2248 i_++; \
2249 } while (ind_ != pf_sldcache.used && (cond) && i_ < SLIDE_CACHE_SIZE); \
2250 if (i_ >= SLIDE_CACHE_SIZE) \
2251 /* TODO: Not supposed to happen */ \
2252 ind_ = -1; \
2223 ind_; \ 2253 ind_; \
2224}) 2254})
2225 2255
@@ -2463,6 +2493,8 @@ bool load_new_slide(void)
2463 { 2493 {
2464 pf_sldcache.center_idx = _SEEK_RIGHT_WHILE(pf_sldcache.center_idx, 2494 pf_sldcache.center_idx = _SEEK_RIGHT_WHILE(pf_sldcache.center_idx,
2465 pf_sldcache.cache[next_].index <= center_index); 2495 pf_sldcache.cache[next_].index <= center_index);
2496 if (pf_sldcache.center_idx == -1)
2497 goto fatal_fail;
2466 2498
2467 prev = pf_sldcache.center_idx; 2499 prev = pf_sldcache.center_idx;
2468 next = pf_sldcache.cache[pf_sldcache.center_idx].next; 2500 next = pf_sldcache.cache[pf_sldcache.center_idx].next;
@@ -2471,6 +2503,8 @@ bool load_new_slide(void)
2471 { 2503 {
2472 pf_sldcache.center_idx = _SEEK_LEFT_WHILE(pf_sldcache.center_idx, 2504 pf_sldcache.center_idx = _SEEK_LEFT_WHILE(pf_sldcache.center_idx,
2473 pf_sldcache.cache[next_].index >= center_index); 2505 pf_sldcache.cache[next_].index >= center_index);
2506 if (pf_sldcache.center_idx == -1)
2507 goto fatal_fail;
2474 2508
2475 next = pf_sldcache.center_idx; 2509 next = pf_sldcache.center_idx;
2476 prev = pf_sldcache.cache[pf_sldcache.center_idx].prev; 2510 prev = pf_sldcache.cache[pf_sldcache.center_idx].prev;
@@ -2517,6 +2551,8 @@ bool load_new_slide(void)
2517 2551
2518 pf_sldcache.right_idx = _SEEK_RIGHT_WHILE(pf_sldcache.right_idx, 2552 pf_sldcache.right_idx = _SEEK_RIGHT_WHILE(pf_sldcache.right_idx,
2519 pf_sldcache.cache[ind_].index - 1 == pf_sldcache.cache[next_].index); 2553 pf_sldcache.cache[ind_].index - 1 == pf_sldcache.cache[next_].index);
2554 if (pf_sldcache.right_idx == -1 || pf_sldcache.left_idx == -1)
2555 goto fatal_fail;
2520 2556
2521 2557
2522 /* update indices */ 2558 /* update indices */
@@ -2581,6 +2617,11 @@ fail_and_refree:
2581 } 2617 }
2582 buf_ctx_unlock(); 2618 buf_ctx_unlock();
2583 return false; 2619 return false;
2620fatal_fail:
2621 free_all_slide_prio(0);
2622 initialize_slide_cache();
2623 buf_ctx_unlock();
2624 return false;
2584} 2625}
2585 2626
2586 2627
@@ -2612,11 +2653,13 @@ static inline struct dim *surface(const int slide_index)
2612 int i; 2653 int i;
2613 if ((i = pf_sldcache.used ) != -1) 2654 if ((i = pf_sldcache.used ) != -1)
2614 { 2655 {
2656 int j = 0;
2615 do { 2657 do {
2616 if (pf_sldcache.cache[i].index == slide_index) 2658 if (pf_sldcache.cache[i].index == slide_index)
2617 return get_slide(pf_sldcache.cache[i].hid); 2659 return get_slide(pf_sldcache.cache[i].hid);
2618 i = pf_sldcache.cache[i].next; 2660 i = pf_sldcache.cache[i].next;
2619 } while (i != pf_sldcache.used); 2661 j++;
2662 } while (i != pf_sldcache.used && j < SLIDE_CACHE_SIZE);
2620 } 2663 }
2621 return get_slide(empty_slide_hid); 2664 return get_slide(empty_slide_hid);
2622} 2665}
@@ -3810,23 +3853,7 @@ static int pictureflow_main(void)
3810 return PLUGIN_ERROR; 3853 return PLUGIN_ERROR;
3811 } 3854 }
3812 3855
3813 int i; 3856 initialize_slide_cache();
3814
3815 /* initialize */
3816 for (i = 0; i < SLIDE_CACHE_SIZE; i++) {
3817 pf_sldcache.cache[i].hid = 0;
3818 pf_sldcache.cache[i].index = 0;
3819 pf_sldcache.cache[i].next = i + 1;
3820 pf_sldcache.cache[i].prev = i - 1;
3821 }
3822 pf_sldcache.cache[0].prev = i - 1;
3823 pf_sldcache.cache[i - 1].next = 0;
3824
3825 pf_sldcache.free = 0;
3826 pf_sldcache.used = -1;
3827 pf_sldcache.left_idx = -1;
3828 pf_sldcache.right_idx = -1;
3829 pf_sldcache.center_idx = -1;
3830 3857
3831 buffer = LCD_BUF; 3858 buffer = LCD_BUF;
3832 3859