[nautilus-actions] Check reference counts at load time



commit 526a913fc924dff4ba553f5ab3d7b1ac0fc1b09f
Author: Pierre Wieser <pwieser trychlos org>
Date:   Fri Oct 9 00:44:54 2009 +0200

    Check reference counts at load time

 ChangeLog                       |   24 ++++++++++++
 src/common/na-object-api.h      |    1 -
 src/common/na-object-item-fn.h  |    5 +--
 src/common/na-object-item.c     |   31 ----------------
 src/nact/nact-tree-model.c      |   75 ++++++++++++++++++++------------------
 src/runtime/na-object-api.h     |    1 +
 src/runtime/na-object-id.c      |    5 +++
 src/runtime/na-object-item-fn.h |    3 +-
 src/runtime/na-object-item.c    |   37 ++++++++++++++++++-
 src/runtime/na-object.c         |    9 ++---
 10 files changed, 111 insertions(+), 80 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 69cfa32..021568a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,29 @@
 2009-10-08 Pierre Wieser <pwieser trychlos org>
 
+	* src/common/na-object-api.h (na_object_remove_item):
+	Moved to runtime library.
+
+	* src/common/na-object-item-fn.h:
+	* src/common/na-object-item.c (na_object_item_remove_item):
+	Moved to runtime library.
+
+	* src/nact/nact-tree-model.c (fill_tree_store):
+	Rewrite duplication code to get reference counts equal to 1 in the store.
+	Install parent pointer in childs.
+
+	* src/runtime/na-object-api.h (na_object_remove_item):
+	Moved from common library.
+
+	* src/runtime/na-object-id.c (instance_dispose):
+	Remove itself from parent if any.
+
+	* src/runtime/na-object-item-fn.h:
+	* src/runtime/na-object-item.c (na_object_item_remove_item):
+	Moved from common library.
+
+	* src/runtime/na-object.c:
+	Remove useless debug traces.
+
 	Items loaded from an IO provider but not recorded in the hierarchical
 	tree are yet displayed, at the end of the tree.
 
diff --git a/src/common/na-object-api.h b/src/common/na-object-api.h
index 637f272..fe4bf46 100644
--- a/src/common/na-object-api.h
+++ b/src/common/na-object-api.h
@@ -73,7 +73,6 @@ G_BEGIN_DECLS
  */
 #define na_object_insert_item( object, item, before ) \
 													na_object_item_insert_item( NA_OBJECT_ITEM( object ), NA_OBJECT( item ), ( NAObject * ) before )
-#define na_object_remove_item( object, item )		na_object_item_remove_item( NA_OBJECT_ITEM( object ), NA_OBJECT( item ))
 
 G_END_DECLS
 
diff --git a/src/common/na-object-item-fn.h b/src/common/na-object-item-fn.h
index 7a13d0a..2439cb1 100644
--- a/src/common/na-object-item-fn.h
+++ b/src/common/na-object-item-fn.h
@@ -49,10 +49,9 @@
 
 G_BEGIN_DECLS
 
-GdkPixbuf     *na_object_item_get_pixbuf( const NAObjectItem *item, GtkWidget *widget );
+GdkPixbuf     *na_object_item_get_pixbuf( const NAObjectItem *object, GtkWidget *widget );
 
-void           na_object_item_insert_item( NAObjectItem *item, const NAObject *object, const NAObject *before );
-void           na_object_item_remove_item( NAObjectItem *item, const NAObject *object );
+void           na_object_item_insert_item( NAObjectItem *object, const NAObject *item, const NAObject *before );
 
 void           na_object_item_count_items( GList *items, gint *menus, gint *actions, gint *profiles, gboolean recurse );
 
diff --git a/src/common/na-object-item.c b/src/common/na-object-item.c
index f4d503e..03d068b 100644
--- a/src/common/na-object-item.c
+++ b/src/common/na-object-item.c
@@ -130,37 +130,6 @@ na_object_item_insert_item( NAObjectItem *item, const NAObject *object, const NA
 }
 
 /**
- * na_object_item_remove_item:
- * @item: the #NAObjectItem from which the subitem must be removed.
- * @object: a #NAObject to be removed from the list of subitems.
- *
- * Removes an @object from the list of subitems of @item.
- *
- * Doesn't modify the reference count on @object.
- */
-void
-na_object_item_remove_item( NAObjectItem *item, const NAObject *object )
-{
-	g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
-	g_return_if_fail( NA_IS_OBJECT( object ));
-
-	if( !item->private->dispose_has_run ){
-
-		if( g_list_find( item->private->items, ( gconstpointer ) object )){
-			item->private->items = g_list_remove( item->private->items, ( gconstpointer ) object );
-
-			/* don't understand why !?
-			 * it appears as if embedded actions and menus would have one sur-ref
-			 * that profiles don't have
-			 */
-			if( NA_IS_OBJECT_ITEM( object )){
-				g_object_unref(( gpointer ) object );
-			}
-		}
-	}
-}
-
-/**
  * na_object_item_count_items:
  * @items: a list if #NAObject to be counted.
  * @menus: will be set to the count of menus.
diff --git a/src/nact/nact-tree-model.c b/src/nact/nact-tree-model.c
index 3fbbea1..a6869c5 100644
--- a/src/nact/nact-tree-model.c
+++ b/src/nact/nact-tree-model.c
@@ -167,7 +167,7 @@ static void           instance_finalize( GObject *application );
 
 static NactTreeModel *tree_model_new( BaseWindow *window, GtkTreeView *treeview );
 
-static void           fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview, GList *items, gboolean only_actions, GtkTreeIter *parent );
+static void           fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview, NAObject *object, gboolean only_actions, GtkTreeIter *parent );
 static void           remove_if_exists( NactTreeModel *model, GtkTreeModel *store, const NAObject *object );
 
 static GList         *add_parent( GList *parents, GtkTreeModel *store, GtkTreeIter *obj_iter );
@@ -658,6 +658,8 @@ nact_tree_model_fill( NactTreeModel *model, GList *items, gboolean only_actions)
 {
 	static const gchar *thisfn = "nact_tree_model_fill";
 	GtkTreeStore *ts_model;
+	GList *it;
+	NAObject *duplicate;
 
 	g_debug( "%s: model=%p, items=%p (%d items), only_actions=%s",
 			thisfn, ( void * ) model, ( void * ) items, g_list_length( items ), only_actions ? "True":"False" );
@@ -668,55 +670,54 @@ nact_tree_model_fill( NactTreeModel *model, GList *items, gboolean only_actions)
 		model->private->only_actions = only_actions;
 		ts_model = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
 		gtk_tree_store_clear( ts_model );
-		fill_tree_store( ts_model, model->private->treeview, items, only_actions, NULL );
+
+		for( it = items ; it ; it = it->next ){
+			duplicate = na_object_duplicate( it->data );
+			fill_tree_store( ts_model, model->private->treeview, duplicate, only_actions, NULL );
+			na_object_unref( duplicate );
+		}
 	}
 }
 
 static void
 fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview,
-					GList *items, gboolean only_actions, GtkTreeIter *parent )
+					NAObject *object, gboolean only_actions, GtkTreeIter *parent )
 {
-	/*static const gchar *thisfn = "nact_tree_model_fill_tree_store";*/
+	static const gchar *thisfn = "nact_tree_model_fill_tree_store";
 	GList *subitems, *it;
-	NAObject *object;
-	NAObject *duplicate;
 	GtkTreeIter iter;
 
-	for( it = items ; it ; it = it->next ){
-		object = NA_OBJECT( it->data );
-		/*g_debug( "%s: object=%p(%s)", thisfn
-				, ( void * ) object, G_OBJECT_TYPE_NAME( object ));*/
-
-		if( NA_IS_OBJECT_MENU( object )){
-			duplicate = object;
-			if( !only_actions ){
-				duplicate = parent ? g_object_ref( object ) : na_object_duplicate( object );
-				/*g_debug( "%s: appending duplicate=%p (%s)", thisfn, ( void * ) duplicate, G_OBJECT_TYPE_NAME( duplicate ));*/
-				append_item( model, treeview, parent, &iter, duplicate );
-				g_object_unref( duplicate );
-			}
-			subitems = na_object_get_items_list( duplicate );
-			fill_tree_store( model, treeview, subitems, only_actions, only_actions ? NULL : &iter );
+	g_debug( "%s: object=%p (%s, ref_count=%d)", thisfn,
+			( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
+
+	if( NA_IS_OBJECT_MENU( object )){
+		if( !only_actions ){
+			append_item( model, treeview, parent, &iter, object );
+		}
+		subitems = na_object_get_items_list( object );
+		for( it = subitems ; it ; it = it->next ){
+			fill_tree_store( model, treeview, it->data, only_actions, only_actions ? NULL : &iter );
+			na_object_append_item( object, it->data );
+			na_object_set_parent( it->data, object );
 		}
+	}
 
-		if( NA_IS_OBJECT_ACTION( object )){
-			duplicate = parent ? g_object_ref( object ) : na_object_duplicate( object );
-			/*g_debug( "%s: appending duplicate=%p (%s)", thisfn, ( void * ) duplicate, G_OBJECT_TYPE_NAME( duplicate ));*/
-			append_item( model, treeview, parent, &iter, duplicate );
-			g_object_unref( duplicate );
-			if( !only_actions ){
-				subitems = na_object_get_items_list( duplicate );
-				fill_tree_store( model, treeview, subitems, only_actions, &iter );
+	if( NA_IS_OBJECT_ACTION( object )){
+		g_return_if_fail( na_object_get_items_count( object ) >= 1 );
+		append_item( model, treeview, parent, &iter, object );
+		if( !only_actions ){
+			subitems = na_object_get_items_list( object );
+			for( it = subitems ; it ; it = it->next ){
+				fill_tree_store( model, treeview, it->data, only_actions, &iter );
+				na_object_append_item( object, it->data );
+				na_object_set_parent( it->data, object );
 			}
-			g_return_if_fail( NA_IS_OBJECT_ACTION( duplicate ));
-			g_return_if_fail( na_object_get_items_count( duplicate ) >= 1 );
 		}
+	}
 
-		if( NA_IS_OBJECT_PROFILE( object )){
-			g_assert( !only_actions );
-			/*g_debug( "%s: appending object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));*/
-			append_item( model, treeview, parent, &iter, object );
-		}
+	if( NA_IS_OBJECT_PROFILE( object )){
+		g_assert( !only_actions );
+		append_item( model, treeview, parent, &iter, object );
 	}
 }
 
@@ -1054,6 +1055,8 @@ iter_on_store_item( NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *iter
 	 * unchanged in dump_store
 	 */
 	g_object_unref( object );
+	g_debug( "nact_tree_model_iter_on_store_item: object=%p (%s, ref_count=%d)",
+			( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
 
 	path = gtk_tree_model_get_path( store, iter );
 
diff --git a/src/runtime/na-object-api.h b/src/runtime/na-object-api.h
index 8c8963b..6944c09 100644
--- a/src/runtime/na-object-api.h
+++ b/src/runtime/na-object-api.h
@@ -98,6 +98,7 @@ G_BEGIN_DECLS
 #define na_object_set_items_list( object, list )	na_object_item_set_items_list( NA_OBJECT_ITEM( object ), list )
 
 #define na_object_append_item( object, item )		na_object_item_append_item( NA_OBJECT_ITEM( object ), NA_OBJECT( item ))
+#define na_object_remove_item( object, item )		na_object_item_remove_item( NA_OBJECT_ITEM( object ), NA_OBJECT( item ))
 
 G_END_DECLS
 
diff --git a/src/runtime/na-object-id.c b/src/runtime/na-object-id.c
index 73c8f8e..ffa6a68 100644
--- a/src/runtime/na-object-id.c
+++ b/src/runtime/na-object-id.c
@@ -238,6 +238,11 @@ instance_dispose( GObject *object )
 
 	if( !self->private->dispose_has_run ){
 
+		if( self->private->parent ){
+			na_object_remove_item( self->private->parent, object );
+			self->private->parent = NULL;
+		}
+
 		self->private->dispose_has_run = TRUE;
 
 		/* chain up to the parent class */
diff --git a/src/runtime/na-object-item-fn.h b/src/runtime/na-object-item-fn.h
index 9481503..f1a3840 100644
--- a/src/runtime/na-object-item-fn.h
+++ b/src/runtime/na-object-item-fn.h
@@ -63,7 +63,8 @@ void           na_object_item_set_enabled( NAObjectItem *item, gboolean enabled
 void           na_object_item_set_provider( NAObjectItem *item, const NAIIOProvider *provider );
 void           na_object_item_set_items_list( NAObjectItem *item, GList *items );
 
-void           na_object_item_append_item( NAObjectItem *item, const NAObject *object );
+void           na_object_item_append_item( NAObjectItem *object, const NAObject *item );
+void           na_object_item_remove_item( NAObjectItem *object, const NAObject *item );
 
 G_END_DECLS
 
diff --git a/src/runtime/na-object-item.c b/src/runtime/na-object-item.c
index 51284e5..47ab924 100644
--- a/src/runtime/na-object-item.c
+++ b/src/runtime/na-object-item.c
@@ -599,11 +599,17 @@ na_object_item_set_provider( NAObjectItem *item, const NAIIOProvider *provider )
 void
 na_object_item_set_items_list( NAObjectItem *item, GList *items )
 {
+	GList *is;
+
 	g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
 
 	if( !item->private->dispose_has_run ){
 
 		item->private->items = items;
+
+		for( is = items ; is ; is = is->next ){
+			na_object_set_parent( is->data, item );
+		}
 	}
 }
 
@@ -630,6 +636,27 @@ na_object_item_append_item( NAObjectItem *item, const NAObject *object )
 	}
 }
 
+/**
+ * na_object_item_remove_item:
+ * @item: the #NAObjectItem from which the subitem must be removed.
+ * @object: a #NAObject to be removed from the list of subitems.
+ *
+ * Removes an @object from the list of subitems of @item.
+ *
+ * Doesn't modify the reference count on @object.
+ */
+void
+na_object_item_remove_item( NAObjectItem *item, const NAObject *object )
+{
+	g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
+	g_return_if_fail( NA_IS_OBJECT( object ));
+
+	if( !item->private->dispose_has_run ){
+
+		item->private->items = g_list_remove( item->private->items, ( gconstpointer ) object );
+	}
+}
+
 static void
 object_dump( const NAObject *item )
 {
@@ -844,15 +871,21 @@ object_ref( NAObject *object )
 	}
 }
 
+/*
+ * if we 'dispose' ic->data during the loop, the the 'ic->next' pointer
+ * is no more valid for the next iteration, so we have to keep its value
+ * before actually unref the data
+ */
 static void
 object_unref( NAObject *object )
 {
-	GList *childs, *ic;
+	GList *childs, *ic, *icnext;
 
 	childs = object_get_childs( object );
-	for( ic = childs ; ic ; ic = ic->next ){
+	for( ic = childs ; ic ; ic = icnext ){
 		/*g_debug( "na_object_item_object_unref: object=%p (%s, ref_count=%d)",
 				( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );*/
+		icnext = ic->next;
 		na_object_unref( ic->data );
 	}
 }
diff --git a/src/runtime/na-object.c b/src/runtime/na-object.c
index cb16fef..2964652 100644
--- a/src/runtime/na-object.c
+++ b/src/runtime/na-object.c
@@ -434,18 +434,15 @@ na_object_object_ref( NAObject *object )
 void
 na_object_object_unref( NAObject *object )
 {
+	g_debug( "na_object_object_unref: object=%p (%s, ref_count=%d)",
+			( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
+
 	g_return_if_fail( NA_IS_OBJECT( object ));
 
 	if( !object->private->dispose_has_run ){
 
-		g_debug( "na_object_object_unref: object=%p (%s, ref_count=%d)",
-				( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
-
 		v_unref( object );
 
-		g_debug( "na_object_object_unref: unreffing %p (%s, ref_count=%d)",
-				( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
-
 		g_object_unref( object );
 	}
 }



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