diff options
author | Christian Soffke <christian.soffke@gmail.com> | 2021-11-26 21:08:49 +0100 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2021-12-03 23:51:12 -0500 |
commit | 2bd0d5738f1b29640eec2a916d7b57fe3cf5eaab (patch) | |
tree | 78735292ee3c10e414914829c9f44ee28c3264ac /apps | |
parent | 09e1cd489f2316e2a2714436674fc4b97c8f9c49 (diff) | |
download | rockbox-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.c | 67 |
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 | ||
2201 | static 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; |
2620 | fatal_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 | ||