[libgda/LIBGDA_4.2] Fixed objects referencing in GdaTreeNode and GdaTreeManager
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda/LIBGDA_4.2] Fixed objects referencing in GdaTreeNode and GdaTreeManager
- Date: Wed, 25 May 2011 20:09:07 +0000 (UTC)
commit 168e0eb4ab4b56c7708cd1f5912a47a498a4cf08
Author: Vivien Malerba <malerba gnome-db org>
Date: Wed May 25 20:49:26 2011 +0200
Fixed objects referencing in GdaTreeNode and GdaTreeManager
libgda/gda-tree-manager.c | 38 ++++++++++++++++++++++++++++++++------
libgda/gda-tree-node.c | 2 +-
2 files changed, 33 insertions(+), 7 deletions(-)
---
diff --git a/libgda/gda-tree-manager.c b/libgda/gda-tree-manager.c
index 99571da..3296741 100644
--- a/libgda/gda-tree-manager.c
+++ b/libgda/gda-tree-manager.c
@@ -1,5 +1,5 @@
-/* GDA library
- * Copyright (C) 2009 - 2010 The GNOME Foundation.
+/*
+ * Copyright (C) 2009 - 2011 The GNOME Foundation.
*
* AUTHORS:
* Vivien Malerba <malerba gnome-db org>
@@ -31,7 +31,8 @@ typedef struct {
} AddedAttribute;
struct _GdaTreeManagerPrivate {
- GSList *sub_managers; /* list of GdaTreeManager structures */
+ GSList *sub_managers; /* list of GdaTreeManager structures, no ref held */
+ GSList *ref_managers; /* list of GdaTreeManager structures, ref held */
gboolean recursive;
GdaTreeManagerNodeFunc node_create_func;
@@ -112,6 +113,7 @@ gda_tree_manager_init (GdaTreeManager *manager, G_GNUC_UNUSED GdaTreeManagerClas
manager->priv = g_new0 (GdaTreeManagerPrivate, 1);
manager->priv->sub_managers = NULL;
+ manager->priv->ref_managers = NULL;
manager->priv->added_attributes = NULL;
}
@@ -124,8 +126,12 @@ gda_tree_manager_dispose (GObject *object)
if (manager->priv) {
if (manager->priv->sub_managers) {
- g_slist_foreach (manager->priv->sub_managers, (GFunc) g_object_unref, NULL);
g_slist_free (manager->priv->sub_managers);
+ manager->priv->sub_managers = NULL;
+ }
+ if (manager->priv->ref_managers) {
+ g_slist_foreach (manager->priv->ref_managers, (GFunc) g_object_unref, NULL);
+ g_slist_free (manager->priv->ref_managers);
}
if (manager->priv->added_attributes) {
GSList *list;
@@ -403,6 +409,19 @@ gda_tree_manager_create_node (GdaTreeManager *manager, GdaTreeNode *parent, cons
return node;
}
+static gboolean
+manager_is_sub_manager_of (GdaTreeManager *mgr, GdaTreeManager *sub)
+{
+ if (g_slist_find (mgr->priv->ref_managers, sub))
+ return TRUE;
+ GSList *list;
+ for (list = mgr->priv->sub_managers; list; list = list->next) {
+ if (manager_is_sub_manager_of (GDA_TREE_MANAGER (list->data), sub))
+ return TRUE;
+ }
+ return FALSE;
+}
+
/**
* gda_tree_manager_add_manager:
* @manager: a #GdaTreeManager object
@@ -413,7 +432,8 @@ gda_tree_manager_create_node (GdaTreeManager *manager, GdaTreeNode *parent, cons
* or several times in the same #GdaTree's structure.
*
* Please note that it's possible for @mgr and @sub to be the same object, but beware of the possible
- * infinite recursive behaviour in this case (depending on the actual implementation of the #GdaTreeManager)
+ * infinite recursive behaviour in this case when creating children nodes
+ * (depending on the actual implementation of the #GdaTreeManager).
*
* Since: 4.2
*/
@@ -424,9 +444,15 @@ gda_tree_manager_add_manager (GdaTreeManager *manager, GdaTreeManager *sub)
g_return_if_fail (GDA_IS_TREE_MANAGER (sub));
manager->priv->sub_managers = g_slist_append (manager->priv->sub_managers, sub);
- g_object_ref (sub);
+
+ /* determine if @sub should be ref'ed or not to avoid circular dependencies */
+ if ((sub != manager) && !manager_is_sub_manager_of (sub, manager)) {
+ manager->priv->ref_managers = g_slist_prepend (manager->priv->ref_managers, sub);
+ g_object_ref (sub);
+ }
}
+
/**
* gda_tree_manager_get_managers:
* @manager: a #GdaTreeManager object
diff --git a/libgda/gda-tree-node.c b/libgda/gda-tree-node.c
index da692d6..755edec 100644
--- a/libgda/gda-tree-node.c
+++ b/libgda/gda-tree-node.c
@@ -886,7 +886,7 @@ _gda_nodes_list_free (GdaTreeNodesList *nl)
if (nl->nodes) {
g_slist_foreach (nl->nodes, (GFunc) g_object_unref, NULL);
g_slist_free (nl->nodes);
- g_object_unref (nl->mgr);
}
+ g_object_unref (nl->mgr);
g_free (nl);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]