From e94244463093f607597b1ac8b764776e41c5c970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 1 Sep 2010 11:16:31 +0200 Subject: [PATCH] [StShadow] Add reference counting If a shadow property is inherited from a parent, multiple StThemeNodes share a common StShadow. It would be possible to use st_shadow_copy() for this purpose, but proper reference counting is nicer. https://bugzilla.gnome.org/show_bug.cgi?id=624384 --- src/st/st-shadow.c | 41 +++++++++++++++++++++++------------------ src/st/st-shadow.h | 5 +++-- src/st/st-theme-node.c | 2 +- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/st/st-shadow.c b/src/st/st-shadow.c index f353e65cf..29bcd08c1 100644 --- a/src/st/st-shadow.c +++ b/src/st/st-shadow.c @@ -36,45 +36,50 @@ st_shadow_new (ClutterColor *color, shadow = g_slice_new (StShadow); - shadow->color = *color; - shadow->xoffset = xoffset; - shadow->yoffset = yoffset; - shadow->blur = blur; - shadow->spread = spread; + shadow->color = *color; + shadow->xoffset = xoffset; + shadow->yoffset = yoffset; + shadow->blur = blur; + shadow->spread = spread; + shadow->ref_count = 1; return shadow; } /** - * st_shadow_copy: + * st_shadow_ref: * @shadow: a #StShadow * - * Makes a copy of @shadow. + * Atomically increments the reference count of @shadow by one. * - * Returns: an allocated copy of @shadow - the result must be freed with - * st_shadow_free() when done + * Returns: the passed in #StShadow. */ StShadow * -st_shadow_copy (const StShadow *shadow) +st_shadow_ref (StShadow *shadow) { g_return_val_if_fail (shadow != NULL, NULL); + g_return_val_if_fail (shadow->ref_count > 0, shadow); - return g_slice_dup (StShadow, shadow); + g_atomic_int_add (&shadow->ref_count, 1); + return shadow; } /** - * st_shadow_free: + * st_shadow_unref: * @shadow: a #StShadow * - * Frees the shadow structure created with st_shadow_new() or - * st_shadow_copy() + * Atomically decrements the reference count of @shadow by one. + * If the reference count drops to 0, all memory allocated by the + * #StShadow is released. */ void -st_shadow_free (StShadow *shadow) +st_shadow_unref (StShadow *shadow) { g_return_if_fail (shadow != NULL); + g_return_if_fail (shadow->ref_count > 0); - g_slice_free (StShadow, shadow); + if (g_atomic_int_exchange_and_add (&shadow->ref_count, -1) - 1 == 0) + g_slice_free (StShadow, shadow); } /** @@ -144,8 +149,8 @@ st_shadow_get_type (void) if (G_UNLIKELY (_st_shadow_type == 0)) _st_shadow_type = g_boxed_type_register_static ("StShadow", - (GBoxedCopyFunc) st_shadow_copy, - (GBoxedFreeFunc) st_shadow_free); + (GBoxedCopyFunc) st_shadow_ref, + (GBoxedFreeFunc) st_shadow_unref); return _st_shadow_type; } diff --git a/src/st/st-shadow.h b/src/st/st-shadow.h index 53b149438..f5fe82332 100644 --- a/src/st/st-shadow.h +++ b/src/st/st-shadow.h @@ -29,6 +29,7 @@ struct _StShadow { gdouble yoffset; gdouble blur; gdouble spread; + volatile int ref_count; }; GType st_shadow_get_type (void) G_GNUC_CONST; @@ -38,8 +39,8 @@ StShadow *st_shadow_new (ClutterColor *color, gdouble yoffset, gdouble blur, gdouble spread); -StShadow *st_shadow_copy (const StShadow *shadow); -void st_shadow_free (StShadow *shadow); +StShadow *st_shadow_ref (StShadow *shadow); +void st_shadow_unref (StShadow *shadow); gboolean st_shadow_equal (StShadow *shadow, StShadow *other); diff --git a/src/st/st-theme-node.c b/src/st/st-theme-node.c index b6000ea37..cd6e9cf73 100644 --- a/src/st/st-theme-node.c +++ b/src/st/st-theme-node.c @@ -99,7 +99,7 @@ st_theme_node_finalize (GObject *object) if (node->shadow) { - st_shadow_free (node->shadow); + st_shadow_unref (node->shadow); node->shadow = NULL; }