From 7584edc737ebb5277801a9e6b51eb5531fdf84d2 Mon Sep 17 00:00:00 2001 From: Michael Vrhel Date: Wed, 21 Jan 2015 13:20:36 -0800 Subject: Fix issue in display list Cache The commit fc05b51c2b198dcc5553f6de1b8fb0e22e7d28ae cleaned up a few issues in the display list cache but it introduced issues when multiple threads are using the lists. In particular one thread could be using a list at the tail of the cache list, while another thread is adding one to the cache, and removing the entry at the tail. The solution is to make sure the ref count of the list is incremented when someone is using the list and making sure that it gets decremented when they are done with the list. --- platform/windows/mupdfwinrt/Cache.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'platform/windows/mupdfwinrt/Cache.cpp') diff --git a/platform/windows/mupdfwinrt/Cache.cpp b/platform/windows/mupdfwinrt/Cache.cpp index d2567bc2..d5108a7c 100644 --- a/platform/windows/mupdfwinrt/Cache.cpp +++ b/platform/windows/mupdfwinrt/Cache.cpp @@ -48,7 +48,10 @@ void Cache::Add(int value, int width_in, int height_in, fz_display_list *dlist, tail = prev_entry; - /* Decrement the caches rc of this list */ + /* Decrement the caches rc of this list. It is gone from cache but + may still be in use by other threads, when threads are done they + should decrement and it should be freed at that time. See + ReleaseDisplayLists in muctx class */ fz_drop_display_list(mu_ctx, curr_entry->dlist); delete curr_entry; size--; @@ -75,6 +78,8 @@ void Cache::Add(int value, int width_in, int height_in, fz_display_list *dlist, head = new_entry; } size++; + /* Everytime we add an entry, we are also using it. Increment rc. See above */ + fz_keep_display_list(mu_ctx, dlist); } fz_display_list* Cache::Use(int value, int *width_out, int *height_out, fz_context *mu_ctx) @@ -109,6 +114,9 @@ fz_display_list* Cache::Use(int value, int *width_out, int *height_out, fz_conte } *width_out = curr_entry->width; *height_out = curr_entry->height; + /* We must increment our reference to this one to ensure it is not + freed when removed from the cache. See above comments */ + fz_keep_display_list(mu_ctx, curr_entry->dlist); return curr_entry->dlist; } else -- cgit v1.2.3