[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