[gnome-shell] [StShadow] Add reference counting



commit e94244463093f607597b1ac8b764776e41c5c970
Author: Florian Müllner <fmuellner gnome org>
Date:   Wed Sep 1 11:16:31 2010 +0200

    [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 f353e65..29bcd08 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 53b1494..f5fe823 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 b6000ea..cd6e9cf 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;
     }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]