[libvirt] [libvirt-glib 02/13] Add GVirConfigObject::doc property

Christophe Fergeau cfergeau at redhat.com
Mon Nov 28 15:32:08 UTC 2011


It will be used to refcount the xml data and make sure we only
free it when all references have went away.
---
 libvirt-gconfig/libvirt-gconfig-object.c |   63 ++++++++++++++++++------------
 1 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c
index edbaf57..de760dd 100644
--- a/libvirt-gconfig/libvirt-gconfig-object.c
+++ b/libvirt-gconfig/libvirt-gconfig-object.c
@@ -30,6 +30,7 @@
 #include "libvirt-gconfig/libvirt-gconfig.h"
 #include "libvirt-gconfig/libvirt-gconfig-helpers-private.h"
 #include "libvirt-gconfig/libvirt-gconfig-object-private.h"
+#include "libvirt-gconfig/libvirt-gconfig-xml-doc.h"
 
 
 //extern gboolean debugFlag;
@@ -44,6 +45,7 @@ struct _GVirConfigObjectPrivate
 {
     gchar *schema;
 
+    GVirConfigXmlDoc *doc;
     xmlNodePtr node;
 };
 
@@ -52,7 +54,8 @@ G_DEFINE_ABSTRACT_TYPE(GVirConfigObject, gvir_config_object, G_TYPE_OBJECT);
 enum {
     PROP_0,
     PROP_SCHEMA,
-    PROP_NODE
+    PROP_NODE,
+    PROP_DOC
 };
 
 
@@ -73,8 +76,8 @@ static void gvir_config_object_get_property(GObject *object,
                                             GValue *value,
                                             GParamSpec *pspec)
 {
-    GVirConfigObject *conn = GVIR_CONFIG_OBJECT(object);
-    GVirConfigObjectPrivate *priv = conn->priv;
+    GVirConfigObject *obj = GVIR_CONFIG_OBJECT(object);
+    GVirConfigObjectPrivate *priv = obj->priv;
 
     switch (prop_id) {
     case PROP_SCHEMA:
@@ -82,7 +85,11 @@ static void gvir_config_object_get_property(GObject *object,
         break;
 
     case PROP_NODE:
-        g_value_set_pointer(value, gvir_config_object_get_xml_node(conn));
+        g_value_set_pointer(value, gvir_config_object_get_xml_node(obj));
+        break;
+
+    case PROP_DOC:
+        g_value_set_object(value, obj->priv->doc);
         break;
 
     default:
@@ -95,8 +102,8 @@ static void gvir_config_object_set_property(GObject *object,
                                             const GValue *value,
                                             GParamSpec *pspec)
 {
-    GVirConfigObject *conn = GVIR_CONFIG_OBJECT(object);
-    GVirConfigObjectPrivate *priv = conn->priv;
+    GVirConfigObject *obj = GVIR_CONFIG_OBJECT(object);
+    GVirConfigObjectPrivate *priv = obj->priv;
 
     switch (prop_id) {
     case PROP_SCHEMA:
@@ -104,17 +111,13 @@ static void gvir_config_object_set_property(GObject *object,
         priv->schema = g_value_dup_string(value);
         break;
 
-    case PROP_NODE: {
-        xmlNodePtr node;
-        node = g_value_get_pointer(value);
-        if ((priv->node != NULL)
-             && (priv->node->doc != NULL)
-             && (priv->node->doc != node->doc)) {
-            xmlFreeDoc(priv->node->doc);
-        }
-        priv->node = node;
+    case PROP_NODE:
+        priv->node =g_value_get_pointer(value);
+        break;
+
+    case PROP_DOC:
+        obj->priv->doc = g_value_dup_object(value);
         break;
-    }
 
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
@@ -131,12 +134,14 @@ static void gvir_config_object_finalize(GObject *object)
 
     g_free(priv->schema);
 
-    /* FIXME: all objects describing a given XML document will share the
-     * same document so we can't destroy it here like this, we need some
-     * refcounting to know when to destroy it.
-     */
-    if (priv->node)
-        xmlFreeDoc(priv->node->doc);
+    if (priv->doc != NULL) {
+        g_object_unref(G_OBJECT(priv->doc));
+        priv->node = NULL; /* node belongs to doc, make sure not to free it */
+    }
+    if (priv->node != NULL) {
+        g_assert(priv->node->doc == NULL);
+        xmlFreeNode(priv->node);
+    }
 
     G_OBJECT_CLASS(gvir_config_object_parent_class)->finalize(object);
 }
@@ -159,9 +164,7 @@ static void gvir_config_object_class_init(GVirConfigObjectClass *klass)
                                                         G_PARAM_READABLE |
                                                         G_PARAM_WRITABLE |
                                                         G_PARAM_CONSTRUCT_ONLY |
-                                                        G_PARAM_STATIC_NAME |
-                                                        G_PARAM_STATIC_NICK |
-                                                        G_PARAM_STATIC_BLURB));
+                                                        G_PARAM_STATIC_STRINGS));
 
     g_object_class_install_property(object_class,
                                     PROP_NODE,
@@ -172,6 +175,16 @@ static void gvir_config_object_class_init(GVirConfigObjectClass *klass)
                                                         G_PARAM_CONSTRUCT_ONLY |
                                                         G_PARAM_STATIC_STRINGS));
 
+    g_object_class_install_property(object_class,
+                                    PROP_DOC,
+                                    g_param_spec_object("doc",
+                                                        "XML Doc",
+                                                        "The XML doc this config object corresponds to",
+                                                        GVIR_TYPE_CONFIG_XML_DOC,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_STATIC_STRINGS));
+
     g_type_class_add_private(klass, sizeof(GVirConfigObjectPrivate));
 }
 
-- 
1.7.7.3




More information about the libvir-list mailing list