diff -ru cairo-1.2.6-8801-1-4/src/cairo.c cairo-1.2.6-more/src/cairo.c --- cairo-1.2.6-8801-1-4/src/cairo.c 2006-11-02 23:53:40.000000000 +0100 +++ cairo-1.2.6-more/src/cairo.c 2007-01-18 23:02:48.000000000 +0100 @@ -157,6 +157,8 @@ } slim_hidden_def (cairo_version_string); +CAIRO_MUTEX_DECLARE(cairo_refcount_mutex); + /** * cairo_create: * @target: target surface for the context @@ -225,13 +227,18 @@ if (cr == NULL) return NULL; - if (cr->ref_count == CAIRO_REF_COUNT_INVALID) + CAIRO_MUTEX_LOCK(cairo_refcount_mutex); + + if (cr->ref_count == CAIRO_REF_COUNT_INVALID) { + CAIRO_MUTEX_UNLOCK(cairo_refcount_mutex); return cr; + } assert (cr->ref_count > 0); cr->ref_count++; + CAIRO_MUTEX_UNLOCK(cairo_refcount_mutex); return cr; } @@ -249,14 +256,20 @@ if (cr == NULL) return; - if (cr->ref_count == CAIRO_REF_COUNT_INVALID) + CAIRO_MUTEX_LOCK(cairo_refcount_mutex); + + if (cr->ref_count == CAIRO_REF_COUNT_INVALID) { + CAIRO_MUTEX_UNLOCK(cairo_refcount_mutex); return; + } assert (cr->ref_count > 0); cr->ref_count--; - if (cr->ref_count) + if (cr->ref_count) { + CAIRO_MUTEX_UNLOCK(cairo_refcount_mutex); return; + } while (cr->gstate) { cairo_gstate_t *tmp = cr->gstate; @@ -268,6 +281,7 @@ _cairo_path_fixed_fini (&cr->path); free (cr); + CAIRO_MUTEX_UNLOCK(cairo_refcount_mutex); } slim_hidden_def (cairo_destroy); diff -ru cairo-1.2.6-8801-1-4/src/cairo-clip.c cairo-1.2.6-more/src/cairo-clip.c --- cairo-1.2.6-8801-1-4/src/cairo-clip.c 2006-11-02 23:53:40.000000000 +0100 +++ cairo-1.2.6-more/src/cairo-clip.c 2007-01-18 23:33:37.000000000 +0100 @@ -262,13 +262,17 @@ return CAIRO_STATUS_SUCCESS; } +CAIRO_MUTEX_DECLARE(cairo_clip_path_refcount_mutex); + static cairo_clip_path_t * _cairo_clip_path_reference (cairo_clip_path_t *clip_path) { if (clip_path == NULL) return NULL; + CAIRO_MUTEX_LOCK(cairo_clip_path_refcount_mutex); clip_path->ref_count++; + CAIRO_MUTEX_UNLOCK(cairo_clip_path_refcount_mutex); return clip_path; } @@ -279,13 +283,17 @@ if (clip_path == NULL) return; + CAIRO_MUTEX_LOCK(cairo_clip_path_refcount_mutex); clip_path->ref_count--; - if (clip_path->ref_count) + if (clip_path->ref_count) { + CAIRO_MUTEX_UNLOCK(cairo_clip_path_refcount_mutex); return; + } _cairo_path_fixed_fini (&clip_path->path); _cairo_clip_path_destroy (clip_path->prev); free (clip_path); + CAIRO_MUTEX_UNLOCK(cairo_clip_path_refcount_mutex); } static cairo_status_t diff -ru cairo-1.2.6-8801-1-4/src/cairo-font.c cairo-1.2.6-more/src/cairo-font.c --- cairo-1.2.6-8801-1-4/src/cairo-font.c 2006-11-01 03:27:38.000000000 +0100 +++ cairo-1.2.6-more/src/cairo-font.c 2007-01-19 00:29:46.000000000 +0100 @@ -44,6 +44,8 @@ */ static const cairo_font_face_backend_t _cairo_toy_font_face_backend; +CAIRO_MUTEX_DECLARE(cairo_font_face_refcount_mutex); + /* cairo_font_face_t */ const cairo_font_face_t _cairo_font_face_nil = { @@ -82,8 +84,12 @@ if (font_face == NULL) return NULL; - if (font_face->ref_count == CAIRO_REF_COUNT_INVALID) + CAIRO_MUTEX_LOCK(cairo_font_face_refcount_mutex); + + if (font_face->ref_count == CAIRO_REF_COUNT_INVALID) { + CAIRO_MUTEX_UNLOCK(cairo_font_face_refcount_mutex); return font_face; + } /* We would normally assert (font_face->ref_count >0) here but we * can't get away with that due to the zombie case as documented @@ -91,6 +97,7 @@ font_face->ref_count++; + CAIRO_MUTEX_UNLOCK(cairo_font_face_refcount_mutex); return font_face; } slim_hidden_def (cairo_font_face_reference); @@ -109,26 +116,39 @@ if (font_face == NULL) return; - if (font_face->ref_count == CAIRO_REF_COUNT_INVALID) + CAIRO_MUTEX_LOCK(cairo_font_face_refcount_mutex); + + if (font_face->ref_count == CAIRO_REF_COUNT_INVALID){ + CAIRO_MUTEX_UNLOCK(cairo_font_face_refcount_mutex); return; + } assert (font_face->ref_count > 0); - if (--(font_face->ref_count) > 0) + if (--(font_face->ref_count) > 0) { + CAIRO_MUTEX_UNLOCK(cairo_font_face_refcount_mutex); return; + } + + CAIRO_MUTEX_UNLOCK(cairo_font_face_refcount_mutex); font_face->backend->destroy (font_face); + CAIRO_MUTEX_LOCK(cairo_font_face_refcount_mutex); + /* We allow resurrection to deal with some memory management for the * FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t * need to effectively mutually reference each other */ - if (font_face->ref_count > 0) + if (font_face->ref_count > 0) { + CAIRO_MUTEX_UNLOCK(cairo_font_face_refcount_mutex); return; + } _cairo_user_data_array_fini (&font_face->user_data); free (font_face); + CAIRO_MUTEX_UNLOCK(cairo_font_face_refcount_mutex); } slim_hidden_def (cairo_font_face_destroy); @@ -427,6 +447,8 @@ font_matrix, ctm, options, scaled_font); } +CAIRO_MUTEX_DECLARE(cairo_unscaled_font_refcount_mutex); + static const cairo_font_face_backend_t _cairo_toy_font_face_backend = { CAIRO_FONT_TYPE_TOY, _cairo_toy_font_face_destroy, @@ -447,8 +469,12 @@ if (unscaled_font == NULL) return NULL; + CAIRO_MUTEX_LOCK(cairo_unscaled_font_refcount_mutex); + unscaled_font->ref_count++; + CAIRO_MUTEX_UNLOCK(cairo_unscaled_font_refcount_mutex); + return unscaled_font; } @@ -458,12 +484,17 @@ if (unscaled_font == NULL) return; - if (--(unscaled_font->ref_count) > 0) + CAIRO_MUTEX_LOCK(cairo_unscaled_font_refcount_mutex); + + if (--(unscaled_font->ref_count) > 0) { + CAIRO_MUTEX_UNLOCK(cairo_unscaled_font_refcount_mutex); return; + } unscaled_font->backend->destroy (unscaled_font); free (unscaled_font); + CAIRO_MUTEX_UNLOCK(cairo_unscaled_font_refcount_mutex); } void diff -ru cairo-1.2.6-8801-1-4/src/cairo-ft-font.c cairo-1.2.6-more/src/cairo-ft-font.c --- cairo-1.2.6-8801-1-4/src/cairo-ft-font.c 2006-11-01 23:40:12.000000000 +0100 +++ cairo-1.2.6-more/src/cairo-ft-font.c 2007-01-18 23:36:57.000000000 +0100 @@ -492,6 +492,8 @@ } } +CAIRO_MUTEX_DECLARE (cairo_ft_font_unscaled_lock_mutex); + static cairo_bool_t _has_unlocked_face (void *entry) { @@ -512,8 +514,11 @@ cairo_ft_unscaled_font_map_t *font_map; FT_Face face = NULL; + CAIRO_MUTEX_LOCK (cairo_ft_font_unscaled_lock_mutex); + if (unscaled->face) { unscaled->lock++; + CAIRO_MUTEX_UNLOCK (cairo_ft_font_unscaled_lock_mutex); return unscaled->face; } @@ -549,6 +554,7 @@ FAIL: _cairo_ft_unscaled_font_map_unlock (); + CAIRO_MUTEX_UNLOCK (cairo_ft_font_unscaled_lock_mutex); return face; } @@ -559,9 +565,13 @@ void _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled) { + CAIRO_MUTEX_LOCK (cairo_ft_font_unscaled_lock_mutex); + assert (unscaled->lock > 0); unscaled->lock--; + + CAIRO_MUTEX_UNLOCK (cairo_ft_font_unscaled_lock_mutex); } slim_hidden_def (cairo_ft_scaled_font_unlock_face); diff -ru cairo-1.2.6-8801-1-4/src/cairo-win32-surface.c cairo-1.2.6-more/src/cairo-win32-surface.c --- cairo-1.2.6-8801-1-4/src/cairo-win32-surface.c 2007-01-19 00:04:46.000000000 +0100 +++ cairo-1.2.6-more/src/cairo-win32-surface.c 2007-01-18 23:37:02.000000000 +0100 @@ -1183,6 +1183,12 @@ CRITICAL_SECTION cairo_pattern_refcount_mutex; CRITICAL_SECTION cairo_surface_refcount_mutex; +CRITICAL_SECTION cairo_refcount_mutex; +CRITICAL_SECTION cairo_clip_path_refcount_mutex; +CRITICAL_SECTION cairo_ft_font_unscaled_lock_mutex; +CRITICAL_SECTION cairo_font_face_refcount_mutex; +CRITICAL_SECTION cairo_unscaled_font_refcount_mutex; + static int _cairo_win32_initialized = 0; void @@ -1199,6 +1205,12 @@ InitializeCriticalSection (&cairo_pattern_refcount_mutex); InitializeCriticalSection (&cairo_surface_refcount_mutex); + InitializeCriticalSection (&cairo_refcount_mutex); + InitializeCriticalSection (&cairo_clip_path_refcount_mutex); + InitializeCriticalSection (&cairo_ft_font_unscaled_lock_mutex); + InitializeCriticalSection (&cairo_font_face_refcount_mutex); + InitializeCriticalSection (&cairo_unscaled_font_refcount_mutex); + _cairo_win32_initialized = 1; } @@ -1217,9 +1229,16 @@ DeleteCriticalSection (&cairo_toy_font_face_hash_table_mutex); DeleteCriticalSection (&cairo_scaled_font_map_mutex); DeleteCriticalSection (&cairo_ft_unscaled_font_map_mutex); + DeleteCriticalSection (&cairo_cache_refcount_mutex); DeleteCriticalSection (&cairo_pattern_refcount_mutex); DeleteCriticalSection (&cairo_surface_refcount_mutex); + + DeleteCriticalSection (&cairo_refcount_mutex); + DeleteCriticalSection (&cairo_clip_path_refcount_mutex); + DeleteCriticalSection (&cairo_ft_font_unscaled_lock_mutex); + DeleteCriticalSection (&cairo_font_face_refcount_mutex); + DeleteCriticalSection (&cairo_unscaled_font_refcount_mutex); break; } return TRUE;