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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list