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