[cairo-commit] 3 commits - src/cairo.c src/cairo-clip.c src/cairo-freed-pool-private.h src/cairo-mutex-list-private.h src/cairo-pattern.c

Andrea Canciani ranma42 at kemper.freedesktop.org
Tue Jul 5 01:01:31 PDT 2011


 src/cairo-clip.c               |    2 
 src/cairo-freed-pool-private.h |    6 +
 src/cairo-mutex-list-private.h |    1 
 src/cairo-pattern.c            |    4 -
 src/cairo.c                    |  151 +++++++++++++++++------------------------
 5 files changed, 71 insertions(+), 93 deletions(-)

New commits:
commit d7cc30eb0112010533d05b4579a12e7a2910b08d
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Sun Jul 3 19:22:34 2011 +0200

    Make error contexts static
    
    Dynamically creating error contexts requires locking and failure
    handling. The code logic can be simplified by statically defining all
    the possible error contexts.

diff --git a/src/cairo-mutex-list-private.h b/src/cairo-mutex-list-private.h
index 7d5ba02..4016f8e 100644
--- a/src/cairo-mutex-list-private.h
+++ b/src/cairo-mutex-list-private.h
@@ -40,7 +40,6 @@ CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_surface_cache_lock)
 
 CAIRO_MUTEX_DECLARE (_cairo_image_solid_cache_mutex)
 
-CAIRO_MUTEX_DECLARE (_cairo_error_mutex)
 CAIRO_MUTEX_DECLARE (_cairo_toy_font_face_mutex)
 CAIRO_MUTEX_DECLARE (_cairo_intern_string_mutex)
 CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex)
diff --git a/src/cairo.c b/src/cairo.c
index 3a4b2a4..8f16d6d 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -107,51 +107,71 @@
 #define INFINITY HUGE_VAL
 #endif
 
-static const cairo_t _cairo_nil = {
-  CAIRO_REFERENCE_COUNT_INVALID,	/* ref_count */
-  CAIRO_STATUS_NO_MEMORY,	/* status */
-  { 0, 0, 0, NULL },		/* user_data */
-  NULL,				/* gstate */
-  {{ 0 }, { 0 }},		/* gstate_tail */
-  NULL,				/* gstate_freelist */
-  {{				/* path */
-    { 0, 0 },			/* last_move_point */
-    { 0, 0 },			/* current point */
-    FALSE,			/* has_current_point */
-    TRUE,			/* needs_move_to */
-    FALSE,			/* has_extents */
-    FALSE,			/* has_curve_to */
-    TRUE,			/* stroke_is_rectilinear */
-    TRUE,			/* fill_is_rectilinear */
-    TRUE,			/* fill_maybe_region */
-    TRUE,			/* fill_is_empty */
-    { {0, 0}, {0, 0}},		/* extents */
-    {{{NULL,NULL}}}		/* link */
-  }}
-};
+#define DEFINE_NIL_CONTEXT(status)					\
+    {									\
+	CAIRO_REFERENCE_COUNT_INVALID,	/* ref_count */			\
+	status,				/* status */			\
+	{ 0, 0, 0, NULL },		/* user_data */			\
+	NULL,				/* gstate */			\
+	{{ 0 }, { 0 }},			/* gstate_tail */		\
+	NULL,				/* gstate_freelist */		\
+	{{				/* path */			\
+		{ 0, 0 },		/* last_move_point */		\
+		{ 0, 0 },		/* current point */		\
+		FALSE,			/* has_current_point */		\
+		TRUE,			/* needs_move_to */		\
+		FALSE,			/* has_extents */		\
+		FALSE,			/* has_curve_to */		\
+		TRUE,			/* stroke_is_rectilinear */	\
+		TRUE,			/* fill_is_rectilinear */	\
+		TRUE,			/* fill_maybe_region */		\
+		TRUE,			/* fill_is_empty */		\
+		{{0, 0}, {0, 0}},	/* extents */			\
+		{{{NULL,NULL}}}		/* link */			\
+	}}								\
+    }
 
-static const cairo_t _cairo_nil__null_pointer = {
-  CAIRO_REFERENCE_COUNT_INVALID,	/* ref_count */
-  CAIRO_STATUS_NULL_POINTER,	/* status */
-  { 0, 0, 0, NULL },		/* user_data */
-  NULL,				/* gstate */
-  {{ 0 }, { 0 }},		/* gstate_tail */
-  NULL,				/* gstate_freelist */
-  {{				/* path */
-    { 0, 0 },			/* last_move_point */
-    { 0, 0 },			/* current point */
-    FALSE,			/* has_current_point */
-    TRUE,			/* needs_move_to */
-    FALSE,			/* has_extents */
-    FALSE,			/* has_curve_to */
-    TRUE,			/* stroke_is_rectilinear */
-    TRUE,			/* fill_is_rectilinear */
-    TRUE,			/* fill_maybe_region */
-    TRUE,			/* fill_is_empty */
-    { {0, 0}, {0, 0}},		/* extents */
-    {{{NULL,NULL}}}		/* link */
-  }}
+static const cairo_t _cairo_nil[] = {
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_NO_MEMORY),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_RESTORE),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_POP_GROUP),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_NO_CURRENT_POINT),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_MATRIX),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_STATUS),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_NULL_POINTER),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_STRING),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_PATH_DATA),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_READ_ERROR),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_WRITE_ERROR),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_SURFACE_FINISHED),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_SURFACE_TYPE_MISMATCH),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_PATTERN_TYPE_MISMATCH),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_CONTENT),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_FORMAT),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_VISUAL),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_FILE_NOT_FOUND),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_DASH),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_DSC_COMMENT),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_INDEX),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_TEMP_FILE_ERROR),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_STRIDE),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_FONT_TYPE_MISMATCH),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_USER_FONT_IMMUTABLE),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_USER_FONT_ERROR),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_NEGATIVE_COUNT),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_CLUSTERS),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_SLANT),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_WEIGHT),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_SIZE),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_DEVICE_TYPE_MISMATCH),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_DEVICE_ERROR),
+    DEFINE_NIL_CONTEXT (CAIRO_STATUS_INVALID_MESH_CONSTRUCTION)
 };
+
+COMPILE_TIME_ASSERT (ARRAY_LENGTH (_cairo_nil) == CAIRO_STATUS_LAST_STATUS - 1);
+
 #include <assert.h>
 
 /**
@@ -180,9 +200,6 @@ _cairo_set_error (cairo_t *cr, cairo_status_t status)
 
 static freed_pool_t context_pool;
 
-/* XXX This should disappear in favour of a common pool of error objects. */
-static cairo_t *_cairo_nil__objects[CAIRO_STATUS_LAST_STATUS + 1];
-
 static cairo_t *
 _cairo_create_in_error (cairo_status_t status)
 {
@@ -190,29 +207,8 @@ _cairo_create_in_error (cairo_status_t status)
 
     assert (status != CAIRO_STATUS_SUCCESS);
 
-    /* special case OOM in order to avoid another allocation */
-    switch ((int) status) {
-    case CAIRO_STATUS_NO_MEMORY:
-	return (cairo_t *) &_cairo_nil;
-    case CAIRO_STATUS_NULL_POINTER:
-	return (cairo_t *) &_cairo_nil__null_pointer;
-    }
-
-    CAIRO_MUTEX_LOCK (_cairo_error_mutex);
-    cr = _cairo_nil__objects[status];
-    if (cr == NULL) {
-	cr = malloc (sizeof (cairo_t));
-	if (unlikely (cr == NULL)) {
-	    CAIRO_MUTEX_UNLOCK (_cairo_error_mutex);
-	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
-	    return (cairo_t *) &_cairo_nil;
-	}
-
-	*cr = _cairo_nil;
-	cr->status = status;
-	_cairo_nil__objects[status] = cr;
-    }
-    CAIRO_MUTEX_UNLOCK (_cairo_error_mutex);
+    cr = (cairo_t *) &_cairo_nil[status - CAIRO_STATUS_NO_MEMORY];
+    assert (status == cr->status);
 
     return cr;
 }
@@ -220,20 +216,6 @@ _cairo_create_in_error (cairo_status_t status)
 void
 _cairo_reset_static_data (void)
 {
-    int status;
-
-    CAIRO_MUTEX_LOCK (_cairo_error_mutex);
-    for (status = CAIRO_STATUS_SUCCESS;
-	 status <= CAIRO_STATUS_LAST_STATUS;
-	 status++)
-    {
-	if (_cairo_nil__objects[status] != NULL) {
-	    free (_cairo_nil__objects[status]);
-	    _cairo_nil__objects[status] = NULL;
-	}
-    }
-    CAIRO_MUTEX_UNLOCK (_cairo_error_mutex);
-
     _freed_pool_reset (&context_pool);
 }
 
commit ef659649d3acfb5f91996dd2bbdfd2a2833d9f38
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Sun Jul 3 18:19:07 2011 +0200

    Clean up context_pool upon static data reset
    
    In commit f46ba56d5b8c54be5f0379aca204c0ce05d0f58a the static context
    stash was replaced by a dynamic freed pool, which needs to be cleared
    upon resets.
    
    Fixes:
    cairo.c:181: warning: ‘context_pool’ defined but not used
    
    Reported-by: Uli Schlachter <psychon at znc.in>

diff --git a/src/cairo.c b/src/cairo.c
index 32a1f9c..3a4b2a4 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -233,6 +233,8 @@ _cairo_reset_static_data (void)
 	}
     }
     CAIRO_MUTEX_UNLOCK (_cairo_error_mutex);
+
+    _freed_pool_reset (&context_pool);
 }
 
 /**
commit fe3ca9c36f15403d8d93263acb758100836ad3cb
Author: Andrea Canciani <ranma42 at gmail.com>
Date:   Sun Jul 3 18:40:08 2011 +0200

    Remove conditional compilation of freed-pools
    
    Conditional compilation was needed to avoid warnings:
    cairo-clip.c:51: warning: ‘clip_path_pool’ defined but not used
    cairo.c:181: warning: ‘context_pool’ defined but not used
    
    They can be avoided by making sure that _freed_pool_reset(ptr)
    actually consumes its argument. This has the pleasant side-effect that
    forgetting to properly reset a freed-pool now results in a warning if
    atomic ops are disabled/not available.

diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index 9527c59..d78a17c 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -48,9 +48,7 @@
 #include "cairo-composite-rectangles-private.h"
 #include "cairo-region-private.h"
 
-#if HAS_FREED_POOL
 static freed_pool_t clip_path_pool;
-#endif
 
 static cairo_clip_path_t *
 _cairo_clip_path_create (cairo_clip_t *clip)
diff --git a/src/cairo-freed-pool-private.h b/src/cairo-freed-pool-private.h
index 0a4ab0e..f0549e6 100644
--- a/src/cairo-freed-pool-private.h
+++ b/src/cairo-freed-pool-private.h
@@ -118,11 +118,15 @@ _freed_pool_reset (freed_pool_t *pool);
 
 #else
 
+/* A warning about an unused freed-pool in a build without atomics
+ * enabled usually indicates a missing _freed_pool_reset() in the
+ * static reset function */
+
 typedef int freed_pool_t;
 
 #define _freed_pool_get(pool) NULL
 #define _freed_pool_put(pool, ptr) free(ptr)
-#define _freed_pool_reset(ptr)
+#define _freed_pool_reset(ptr) assert((ptr) != NULL)
 
 #endif
 
diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index 8531aa5..1e9326d 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -56,9 +56,7 @@
  * functions.
  */
 
-#if HAS_FREED_POOL
 static freed_pool_t freed_pattern_pool[5];
-#endif
 
 static const cairo_solid_pattern_t _cairo_pattern_nil = {
     { CAIRO_PATTERN_TYPE_SOLID,		/* type */
@@ -5160,12 +5158,10 @@ slim_hidden_def (cairo_mesh_pattern_get_control_point);
 void
 _cairo_pattern_reset_static_data (void)
 {
-#if HAS_FREED_POOL
     int i;
 
     for (i = 0; i < ARRAY_LENGTH (freed_pattern_pool); i++)
 	_freed_pool_reset (&freed_pattern_pool[i]);
-#endif
 
     _cairo_pattern_reset_solid_surface_cache ();
 }
diff --git a/src/cairo.c b/src/cairo.c
index 42afe26..32a1f9c 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -178,10 +178,7 @@ _cairo_set_error (cairo_t *cr, cairo_status_t status)
     _cairo_status_set_error (&cr->status, _cairo_error (status));
 }
 
-#if HAS_FREED_POOL
 static freed_pool_t context_pool;
-#endif
-
 
 /* XXX This should disappear in favour of a common pool of error objects. */
 static cairo_t *_cairo_nil__objects[CAIRO_STATUS_LAST_STATUS + 1];


More information about the cairo-commit mailing list