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

alexcher at ghostscript.com alexcher at ghostscript.com
Mon Sep 3 06:19:12 PDT 2007


Author: alexcher
Date: 2007-09-03 06:19:11 -0700 (Mon, 03 Sep 2007)
New Revision: 8227

Modified:
   trunk/gs/src/gsclipsr.c
   trunk/gs/src/gsstate.c
Log:
Fix reference counting logic for clip stack elements. The reference counter
now shows the number of gstates that point to a given element directly or
indirectly. Bug 689429.

DIFFERENCES:
None


Modified: trunk/gs/src/gsclipsr.c
===================================================================
--- trunk/gs/src/gsclipsr.c	2007-08-31 20:53:42 UTC (rev 8226)
+++ trunk/gs/src/gsclipsr.c	2007-09-03 13:19:11 UTC (rev 8227)
@@ -26,23 +26,19 @@
 private_st_clip_stack();
 
 /*
- * When we free a clip stack entry, free the associated clip path,
- * and iterate down the list.  We do this iteratively so that we don't
- * take a level of recursion for each node on the list.
+ * When we free a clip stack entry and the associated clip path.
  */
 private void
 rc_free_clip_stack(gs_memory_t * mem, void *vstack, client_name_t cname)
 {
     gx_clip_stack_t *stack = (gx_clip_stack_t *)vstack;
-    gx_clip_stack_t *next;
 
-    do {
-	gx_clip_path *pcpath = stack->clip_path;
+    if (stack->rc.ref_count <= 1 ) {
+        gx_clip_path *pcpath = stack->clip_path;
 
-	next = stack->next;
 	gs_free_object(stack->rc.memory, stack, cname);
 	gx_cpath_free(pcpath, "rc_free_clip_stack");
-    } while ((stack = next) != 0 && !--(stack->rc.ref_count));
+    }
 }
 
 /* clipsave */

Modified: trunk/gs/src/gsstate.c
===================================================================
--- trunk/gs/src/gsstate.c	2007-08-31 20:53:42 UTC (rev 8226)
+++ trunk/gs/src/gsstate.c	2007-09-03 13:19:11 UTC (rev 8227)
@@ -45,6 +45,7 @@
 private void gstate_free_contents(gs_state *);
 private int gstate_copy(gs_state *, const gs_state *,
 			gs_state_copy_reason_t, client_name_t);
+private void clip_stack_rc_adjust(gx_clip_stack_t *cs, int delta, client_name_t cname);
 
 /*
  * Graphics state storage management is complicated.  There are many
@@ -490,7 +491,7 @@
 
     pgs->view_clip = 0;
     pnew = gstate_clone(pgs, mem, "gs_gstate", copy_for_gstate);
-    rc_increment(pnew->clip_stack);
+    clip_stack_rc_adjust(pnew->clip_stack, 1, "gs_state_copy");
     rc_increment(pnew->dfilter_stack);
     pgs->view_clip = view_clip;
     if (pnew == 0)
@@ -948,6 +949,21 @@
     return 0;
 }
 
+
+/* Adjust reference counters for the whole clip stack */
+/* accessible from the given point */
+private void
+clip_stack_rc_adjust(gx_clip_stack_t *cs, int delta, client_name_t cname)
+{
+    gx_clip_stack_t *p = cs;  
+
+    while(p) {
+        gx_clip_stack_t *q = p;
+        p = p->next;  
+        rc_adjust(q, delta, cname);
+    }
+}
+
 /* Release the composite parts of a graphics state, */
 /* but not the state itself. */
 private void
@@ -957,7 +973,7 @@
     const char *const cname = "gstate_free_contents";
 
     rc_decrement(pgs->device, cname);
-    rc_decrement(pgs->clip_stack, cname);
+    clip_stack_rc_adjust(pgs->clip_stack, -1, cname);
     rc_decrement(pgs->dfilter_stack, cname);
     cs_adjust_counts(pgs, -1);
     if (pgs->client_data != 0)
@@ -1009,11 +1025,12 @@
     *parts.ccolor = *pfrom->ccolor;
     *parts.dev_color = *pfrom->dev_color;
     /* Handle references from gstate object. */
-#define RCCOPY(element)\
-    rc_pre_assign(pto->element, pfrom->element, cname)
-    RCCOPY(device);
-    RCCOPY(clip_stack);
-    RCCOPY(dfilter_stack);
+    rc_pre_assign(pto->device, pfrom->device, cname);
+    rc_pre_assign(pto->dfilter_stack, pfrom->dfilter_stack, cname);
+    if (pto->clip_stack != pfrom->clip_stack) {
+        clip_stack_rc_adjust(pfrom->clip_stack, 1, cname);
+        clip_stack_rc_adjust(pto->clip_stack, -1, cname);
+    }
     {
 	struct gx_pattern_cache_s *pcache = pto->pattern_cache;
 	void *pdata = pto->client_data;
@@ -1038,7 +1055,6 @@
     }
     GSTATE_ASSIGN_PARTS(pto, &parts);
     cs_adjust_counts(pto, 1);
-#undef RCCOPY
     pto->show_gstate =
 	(pfrom->show_gstate == pfrom ? pto : 0);
     return 0;



More information about the gs-cvs mailing list