[glib/wip/free: 4/6] add g_type_set_qdata_full



commit 778467378119bae4a9d1c612155b36f96f86914f
Author: Dan Winship <danw gnome org>
Date:   Wed Aug 29 10:22:13 2012 -0400

    add g_type_set_qdata_full

 gobject/gtype.c |   74 +++++++++++++++++++++++++++++++++++++++++-------------
 gobject/gtype.h |    5 +++
 2 files changed, 61 insertions(+), 18 deletions(-)
---
diff --git a/gobject/gtype.c b/gobject/gtype.c
index 6c62bc2..fb6ec1e 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -198,7 +198,8 @@ static inline gpointer                      type_get_qdata_L                (TypeNode     
          *node,
                                                                         GQuark                  quark);
 static inline void                     type_set_qdata_W                (TypeNode               *node,
                                                                         GQuark                  quark,
-                                                                        gpointer                data);
+                                                                        gpointer                data,
+                                                                         GDestroyNotify          destroy);
 static IFaceHolder*                    type_iface_peek_holder_L        (TypeNode               *iface,
                                                                         GType                   
instance_type);
 static gboolean                         type_iface_vtable_base_init_Wm  (TypeNode               *iface,
@@ -266,9 +267,9 @@ struct _TypeNode
 #define        IFACE_NODE_N_PREREQUISITES(node)        ((node)->n_prerequisites)
 #define        IFACE_NODE_PREREQUISITES(node)          ((node)->prerequisites)
 #define        iface_node_get_holders_L(node)          ((IFaceHolder*) type_get_qdata_L ((node), 
static_quark_iface_holder))
-#define        iface_node_set_holders_W(node, holders) (type_set_qdata_W ((node), static_quark_iface_holder, 
(holders)))
+#define        iface_node_set_holders_W(node, holders) (type_set_qdata_W ((node), static_quark_iface_holder, 
(holders), NULL))
 #define        iface_node_get_dependants_array_L(n)    ((GType*) type_get_qdata_L ((n), 
static_quark_dependants_array))
-#define        iface_node_set_dependants_array_W(n,d)  (type_set_qdata_W ((n), 
static_quark_dependants_array, (d)))
+#define        iface_node_set_dependants_array_W(n,d)  (type_set_qdata_W ((n), 
static_quark_dependants_array, (d), NULL))
 #define        TYPE_ID_MASK                            ((GType) ((1 << G_TYPE_FUNDAMENTAL_SHIFT) - 1))
 
 #define NODE_IS_ANCESTOR(ancestor, node)                                                    \
@@ -3610,8 +3611,9 @@ struct _GData
 };
 struct _QData
 {
-  GQuark   quark;
-  gpointer data;
+  GQuark         quark;
+  gpointer       data;
+  GDestroyNotify destroy;
 };
 
 static inline gpointer
@@ -3653,7 +3655,7 @@ type_get_qdata_L (TypeNode *node,
  * @quark: a #GQuark id to identify the data
  *
  * Obtains data which has previously been attached to @type
- * with g_type_set_qdata().
+ * with g_type_set_qdata() or g_type_set_qdata_full().
  *
  * Note that this does not take subtyping into account; data
  * attached to one type with g_type_set_qdata() cannot
@@ -3684,9 +3686,10 @@ g_type_get_qdata (GType  type,
 }
 
 static inline void
-type_set_qdata_W (TypeNode *node,
-                 GQuark    quark,
-                 gpointer  data)
+type_set_qdata_W (TypeNode       *node,
+                 GQuark          quark,
+                 gpointer        data,
+                  GDestroyNotify  destroy)
 {
   GData *gdata;
   QData *qdata;
@@ -3702,7 +3705,10 @@ type_set_qdata_W (TypeNode *node,
   for (i = 0; i < gdata->n_qdatas; i++)
     if (qdata[i].quark == quark)
       {
+        if (qdata[i].destroy)
+          qdata[i].destroy (qdata[i].data);
        qdata[i].data = data;
+       qdata[i].destroy = destroy;
        return;
       }
   
@@ -3716,20 +3722,26 @@ type_set_qdata_W (TypeNode *node,
   g_memmove (qdata + i + 1, qdata + i, sizeof (qdata[0]) * (gdata->n_qdatas - i - 1));
   qdata[i].quark = quark;
   qdata[i].data = data;
+  qdata[i].destroy = destroy;
 }
 
 /**
- * g_type_set_qdata:
+ * g_type_set_qdata_full:
  * @type: a #GType
  * @quark: a #GQuark id to identify the data
  * @data: the data
+ * @destroy: #GDestroyNotify for @data
  *
- * Attaches arbitrary data to a type.
+ * Attaches arbitrary data to a type, and frees it when the type is
+ * freed or the data is changed.
+ *
+ * Since: 2.34
  */
 void
-g_type_set_qdata (GType    type,
-                 GQuark   quark,
-                 gpointer data)
+g_type_set_qdata_full (GType            type,
+                       GQuark           quark,
+                       gpointer         data,
+                       GDestroyNotify   destroy)
 {
   TypeNode *node;
   
@@ -3739,13 +3751,29 @@ g_type_set_qdata (GType    type,
   if (node)
     {
       G_WRITE_LOCK (&type_rw_lock);
-      type_set_qdata_W (node, quark, data);
+      type_set_qdata_W (node, quark, data, destroy);
       G_WRITE_UNLOCK (&type_rw_lock);
     }
   else
     g_return_if_fail (node != NULL);
 }
 
+/**
+ * g_type_set_qdata:
+ * @type: a #GType
+ * @quark: a #GQuark id to identify the data
+ * @data: the data
+ *
+ * Attaches arbitrary data to a type.
+ */
+void
+g_type_set_qdata (GType    type,
+                 GQuark   quark,
+                 gpointer data)
+{
+  g_type_set_qdata_full (type, quark, data, NULL);
+}
+
 static void
 type_add_flags_W (TypeNode  *node,
                  GTypeFlags flags)
@@ -3759,7 +3787,7 @@ type_add_flags_W (TypeNode  *node,
     g_warning ("tagging type `%s' as abstract after class initialization", NODE_NAME (node));
   dflags = GPOINTER_TO_UINT (type_get_qdata_L (node, static_quark_type_flags));
   dflags |= flags;
-  type_set_qdata_W (node, static_quark_type_flags, GUINT_TO_POINTER (dflags));
+  type_set_qdata_W (node, static_quark_type_flags, GUINT_TO_POINTER (dflags), NULL);
 }
 
 /**
@@ -4871,8 +4899,18 @@ g_type_cleanup (void)
       g_free (node->data);
 
       if (node->global_gdata != NULL)
-        g_free (node->global_gdata->qdatas);
-      g_free (node->global_gdata);
+        {
+          QData *qdatas = node->global_gdata->qdatas;
+          int i;
+
+          for (i = 0; i < node->global_gdata->n_qdatas; i++)
+            {
+              if (qdatas[i].destroy)
+                qdatas[i].destroy (qdatas[i].data);
+            }
+          g_free (qdatas);
+          g_free (node->global_gdata);
+        }
 
       g_free (node->prerequisites);
 
diff --git a/gobject/gtype.h b/gobject/gtype.h
index 14206ed..a8269bb 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -698,6 +698,11 @@ GType*                g_type_interfaces              (GType            type,
 void                  g_type_set_qdata               (GType            type,
                                                      GQuark           quark,
                                                      gpointer         data);
+GLIB_AVAILABLE_IN_2_34
+void                  g_type_set_qdata_full          (GType            type,
+                                                     GQuark           quark,
+                                                     gpointer         data,
+                                                      GDestroyNotify   destroy);
 gpointer              g_type_get_qdata               (GType            type,
                                                      GQuark           quark);
 void                 g_type_query                   (GType            type,


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