summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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)
}
+static void initialize_slide_cache(void)
+{
+ int i= 0;
+ for (i = 0; i < SLIDE_CACHE_SIZE; i++) {
+ pf_sldcache.cache[i].hid = 0;
+ pf_sldcache.cache[i].index = 0;
+ pf_sldcache.cache[i].next = i + 1;
+ pf_sldcache.cache[i].prev = i - 1;
+ }
+ pf_sldcache.cache[0].prev = i - 1;
+ pf_sldcache.cache[i - 1].next = 0;
+
+ pf_sldcache.free = 0;
+ pf_sldcache.used = -1;
+ pf_sldcache.left_idx = -1;
+ pf_sldcache.right_idx = -1;
+ pf_sldcache.center_idx = -1;
+}
+
+
/*
* The following functions implement the linked-list-in-array used to manage
* the LRU cache of slides, and the list of free cache slots.
@@ -2206,20 +2226,30 @@ static bool create_pf_thread(void)
#define _SEEK_RIGHT_WHILE(start, cond) \
({ \
int ind_, next_ = (start); \
+ int i_ = 0; \
do { \
ind_ = next_; \
next_ = pf_sldcache.cache[ind_].next; \
- } while (next_ != pf_sldcache.used && (cond)); \
+ i_++; \
+ } while (next_ != pf_sldcache.used && (cond) && i_ < SLIDE_CACHE_SIZE); \
+ if (i_ >= SLIDE_CACHE_SIZE) \
+ /* TODO: Not supposed to happen */ \
+ ind_ = -1; \
ind_; \
})
#define _SEEK_LEFT_WHILE(start, cond) \
({ \
int ind_, next_ = (start); \
+ int i_ = 0; \
do { \
ind_ = next_; \
next_ = pf_sldcache.cache[ind_].prev; \
- } while (ind_ != pf_sldcache.used && (cond)); \
+ i_++; \
+ } while (ind_ != pf_sldcache.used && (cond) && i_ < SLIDE_CACHE_SIZE); \
+ if (i_ >= SLIDE_CACHE_SIZE) \
+ /* TODO: Not supposed to happen */ \
+ ind_ = -1; \
ind_; \
})
@@ -2463,6 +2493,8 @@ bool load_new_slide(void)
{
pf_sldcache.center_idx = _SEEK_RIGHT_WHILE(pf_sldcache.center_idx,
pf_sldcache.cache[next_].index <= center_index);
+ if (pf_sldcache.center_idx == -1)
+ goto fatal_fail;
prev = pf_sldcache.center_idx;
next = pf_sldcache.cache[pf_sldcache.center_idx].next;
@@ -2471,6 +2503,8 @@ bool load_new_slide(void)
{
pf_sldcache.center_idx = _SEEK_LEFT_WHILE(pf_sldcache.center_idx,
pf_sldcache.cache[next_].index >= center_index);
+ if (pf_sldcache.center_idx == -1)
+ goto fatal_fail;
next = pf_sldcache.center_idx;
prev = pf_sldcache.cache[pf_sldcache.center_idx].prev;
@@ -2517,6 +2551,8 @@ bool load_new_slide(void)
pf_sldcache.right_idx = _SEEK_RIGHT_WHILE(pf_sldcache.right_idx,
pf_sldcache.cache[ind_].index - 1 == pf_sldcache.cache[next_].index);
+ if (pf_sldcache.right_idx == -1 || pf_sldcache.left_idx == -1)
+ goto fatal_fail;
/* update indices */
@@ -2581,6 +2617,11 @@ fail_and_refree:
}
buf_ctx_unlock();
return false;
+fatal_fail:
+ free_all_slide_prio(0);
+ initialize_slide_cache();
+ buf_ctx_unlock();
+ return false;
}
@@ -2612,11 +2653,13 @@ static inline struct dim *surface(const int slide_index)
int i;
if ((i = pf_sldcache.used ) != -1)
{
+ int j = 0;
do {
if (pf_sldcache.cache[i].index == slide_index)
return get_slide(pf_sldcache.cache[i].hid);
i = pf_sldcache.cache[i].next;
- } while (i != pf_sldcache.used);
+ j++;
+ } while (i != pf_sldcache.used && j < SLIDE_CACHE_SIZE);
}
return get_slide(empty_slide_hid);
}
@@ -3810,23 +3853,7 @@ static int pictureflow_main(void)
return PLUGIN_ERROR;
}
- int i;
-
- /* initialize */
- for (i = 0; i < SLIDE_CACHE_SIZE; i++) {
- pf_sldcache.cache[i].hid = 0;
- pf_sldcache.cache[i].index = 0;
- pf_sldcache.cache[i].next = i + 1;
- pf_sldcache.cache[i].prev = i - 1;
- }
- pf_sldcache.cache[0].prev = i - 1;
- pf_sldcache.cache[i - 1].next = 0;
-
- pf_sldcache.free = 0;
- pf_sldcache.used = -1;
- pf_sldcache.left_idx = -1;
- pf_sldcache.right_idx = -1;
- pf_sldcache.center_idx = -1;
+ initialize_slide_cache();
buffer = LCD_BUF;