From 7584edc737ebb5277801a9e6b51eb5531fdf84d2 Mon Sep 17 00:00:00 2001
From: Michael Vrhel <michael.vrhel@artifex.com>
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/gsview/mudocument.cs | 39 +++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

(limited to 'platform/windows/gsview')

diff --git a/platform/windows/gsview/mudocument.cs b/platform/windows/gsview/mudocument.cs
index 3087d3d0..e41de6e3 100644
--- a/platform/windows/gsview/mudocument.cs
+++ b/platform/windows/gsview/mudocument.cs
@@ -159,6 +159,11 @@ namespace gsview
 		private static extern IntPtr mCreateDisplayListText64(IntPtr ctx, int page_num,
 				ref int page_width, ref int page_height, ref IntPtr text, ref int length);
 
+		[DllImport("mupdfnet64.dll", EntryPoint = "mReleaseLists", CharSet = CharSet.Auto,
+			CallingConvention = CallingConvention.StdCall)]
+		private static extern void mReleaseLists64(IntPtr ctx, IntPtr dlist,
+			IntPtr annot_dlist);
+
 		[DllImport("mupdfnet64.dll", EntryPoint = "mRenderPageMT", CharSet = CharSet.Auto,
 			CallingConvention = CallingConvention.StdCall)]
 		private static extern int mRenderPageMT64(IntPtr ctx, IntPtr dlist,
@@ -308,6 +313,11 @@ namespace gsview
 		private static extern IntPtr mCreateDisplayListText32(IntPtr ctx, int page_num,
 				ref int page_width, ref int page_height, ref IntPtr text, ref int length);
 
+		[DllImport("mupdfnet32.dll", EntryPoint = "mReleaseLists", CharSet = CharSet.Auto,
+			CallingConvention = CallingConvention.StdCall)]
+		private static extern void mReleaseLists32(IntPtr ctx, IntPtr dlist,
+			IntPtr annot_dlist);
+
 		[DllImport("mupdfnet32.dll", EntryPoint = "mRenderPageMT", CharSet = CharSet.Auto,
 			CallingConvention = CallingConvention.StdCall)]
 		private static extern int mRenderPageMT32(IntPtr ctx, IntPtr dlist,
@@ -805,6 +815,33 @@ namespace gsview
 			return output;
 		}
 
+		private void tc_mReleaseLists(IntPtr ctx, IntPtr dlist, IntPtr annot_dlist)
+		{
+			int output;
+			try
+			{
+				if (is64bit)
+					mReleaseLists64(ctx, dlist, annot_dlist);
+				else
+					mReleaseLists32(ctx, dlist, annot_dlist);
+			}
+			catch (DllNotFoundException)
+			{
+				/* DLL not found */
+				String err = "DllNotFoundException: MuPDF DLL not found 16";
+				mupdfDLLProblemMain(this, err);
+				return;
+			}
+			catch (BadImageFormatException)
+			{
+				/* Using 32 bit with 64 or vice versa */
+				String err = "BadImageFormatException: Incorrect MuPDF DLL";
+				mupdfDLLProblemMain(this, err);
+				return;
+			}
+			return;
+		}
+
 		private int tc_mRenderPageMT(IntPtr ctx, IntPtr dlist, IntPtr annot_dlist,
 			int page_width, int page_height, Byte[] bmp_data, int bmp_width, 
 			int bmp_height, double scale, bool flipy)
@@ -1417,6 +1454,8 @@ namespace gsview
 				}
 				code = tc_mRenderPageMT(mu_object, dlist, annot_dlist, page_width, 
 					page_height, bmp_data, bmp_width, bmp_height, scale, flipy);
+				/* We are done with the display lists */
+				tc_mReleaseLists(mu_object, dlist, annot_dlist);
 			} 
 			else
  			{
-- 
cgit v1.2.3