[gs-cvs] rev 7739 - trunk/gs/src

ray at ghostscript.com ray at ghostscript.com
Fri Feb 23 15:03:23 PST 2007


Author: ray
Date: 2007-02-23 15:03:23 -0800 (Fri, 23 Feb 2007)
New Revision: 7739

Modified:
   trunk/gs/src/gsstate.c
   trunk/gs/src/gsstate.h
   trunk/gs/src/gxpcmap.c
Log:
Fix memory leak (PCL) due to extra gstate creation. PS did not leak thanks
to the Garbage Collector.

DETAILS:

If a pattern PaintProc did a gsave/grestore the grestore would detect that
the base graphics state did not have an underlying 'saved' graphics state
and would create one (due to the need for PostScript to always have two
graphics states on this graphics state stack/list). When gx_pattern_load
freed the graphics state it created, the (possible) underlying graphics
state would not get freed. Since the PostScript allocator (that supported
garbage collection) would locate and free the unconnected graphics state
this was not seen with PostScript.

The gs_state_free_chain function was created in case there are other clients
that need this function (pdfwrite ?)



Modified: trunk/gs/src/gsstate.c
===================================================================
--- trunk/gs/src/gsstate.c	2007-02-23 22:05:37 UTC (rev 7738)
+++ trunk/gs/src/gsstate.c	2007-02-23 23:03:23 UTC (rev 7739)
@@ -294,6 +294,20 @@
     return pgs->client_data;
 }
 
+/* Free the chain of gstates.*/
+int
+gs_state_free_chain(gs_state * pgs)
+{
+   gs_state *saved = pgs, *tmp; 
+
+   while(saved != 0) {
+       tmp = saved->saved;
+       gs_state_free(saved);
+       saved = tmp;
+   }
+   return 0;
+}
+
 /* Free a graphics state. */
 int
 gs_state_free(gs_state * pgs)

Modified: trunk/gs/src/gsstate.h
===================================================================
--- trunk/gs/src/gsstate.h	2007-02-23 22:05:37 UTC (rev 7738)
+++ trunk/gs/src/gsstate.h	2007-02-23 23:03:23 UTC (rev 7739)
@@ -32,6 +32,7 @@
 /* Initial allocation and freeing */
 gs_state *gs_state_alloc(gs_memory_t *);	/* 0 if fails */
 int gs_state_free(gs_state *);
+int gs_state_free_chain(gs_state *);
 
 /* Initialization, saving, restoring, and copying */
 int gs_gsave(gs_state *), gs_grestore(gs_state *), gs_grestoreall(gs_state *);

Modified: trunk/gs/src/gxpcmap.c
===================================================================
--- trunk/gs/src/gxpcmap.c	2007-02-23 22:05:37 UTC (rev 7738)
+++ trunk/gs/src/gxpcmap.c	2007-02-23 23:03:23 UTC (rev 7739)
@@ -684,8 +684,8 @@
     /* Free the bookkeeping structures, except for the bits and mask */
     /* data iff they are still needed. */
     dev_proc(adev, close_device)((gx_device *)adev);
-    /* Freeing the state will free the device. */
-    gs_state_free(saved);
+    /* Free the chain of gstates. Freeing the state will free the device. */
+    gs_state_free_chain(saved);
     return code;
 fail:
     gs_free_object(mem, adev, "gx_pattern_load");



More information about the gs-cvs mailing list