[nautilus-actions] Fix reference count error in filter_selection
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Fix reference count error in filter_selection
- Date: Sat, 27 Feb 2010 23:19:15 +0000 (UTC)
commit 935ab82ee8c4a165a37d5a0db7bf0da8ad8e97c5
Author: Pierre Wieser <pwieser trychlos org>
Date: Fri Feb 26 22:53:58 2010 +0100
Fix reference count error in filter_selection
ChangeLog | 30 ++++++
src/api/na-object-api.h | 3 +-
src/core/na-factory-object.c | 12 +--
src/core/na-factory-object.h | 2 +-
src/core/na-object-action.c | 2 -
src/core/na-object-item.c | 7 +-
src/core/na-object-menu.c | 2 -
src/core/na-object-profile.c | 2 -
src/core/na-object.c | 2 +
src/core/na-pivot.c | 4 +-
src/nact/nact-assistant-export.c | 4 +-
src/nact/nact-iactions-list.c | 5 +-
src/nact/nact-main-menubar.c | 8 +-
src/test/init-dispose-diff.sh | 211 ++++++++++++++++++++++++++++++++------
14 files changed, 231 insertions(+), 63 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b49457e..6a8fc95 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,35 @@
2009-02-26 Pierre Wieser <pwieser trychlos org>
+ Fix references count mistakes in NACT.
+
+ * src/api/na-object-api.h (na_object_unref_selected_items):
+ New macro, more specifically targeting the tree selections.
+
+ * src/core/na-factory-object.c:
+ * src/core/na-factory-object.h (na_factory_object_finalize_instance):
+ Renamed as na_factory_object_finalize().
+
+ * src/core/na-object-action.c (instance_finalize):
+ * src/core/na-object-item.c (instance_finalize):
+ * src/core/na-object-menu.c (instance_finalize):
+ * src/core/na-object-profile.c (instance_finalize):
+ * src/core/na-object.c (instance_finalize):
+ Move na_object_unref_selected_items() to
+ na_object:na_factory_object_finalize.
+
+ * src/core/na-pivot.c (instance_dispose, reload_items):
+ Use non-recursive na_object_unref_items() macro.
+
+ * src/nact/nact-assistant-export.c (assist_prepare_confirm):
+ * src/nact/nact-iactions-list.c (free_items_callback):
+ * src/nact/nact-main-menubar.c (on_update_sensitivities):
+ Use recursive na_object_unref_selected_items() macro.
+
+ * src/nact/nact-iactions-list.c (filter_selection):
+ Unref the got object immediately (which was the actual bug).
+
+ * src/test/init-dispose-diff.sh: Fix and optimize.
+
Fix display of modification status in NACT.
* src/api/na-iduplicable.h:
diff --git a/src/api/na-object-api.h b/src/api/na-object-api.h
index 1a3c7ec..135c589 100644
--- a/src/api/na-object-api.h
+++ b/src/api/na-object-api.h
@@ -122,7 +122,8 @@ G_BEGIN_DECLS
#define na_object_get_items_count( obj ) na_object_item_get_items_count( NA_OBJECT_ITEM( obj ))
#define na_object_count_items( list, cm, ca, cp, brec ) na_object_item_count_items( list, ( cm ), ( ca ), ( cp ), ( brec ))
-#define na_object_unref_items( tree ) na_object_item_unref_items_rec( tree )
+#define na_object_unref_items( tree ) na_object_item_unref_items( tree )
+#define na_object_unref_selected_items( tree ) na_object_item_unref_items_rec( tree )
/* NAObjectAction
*/
diff --git a/src/core/na-factory-object.c b/src/core/na-factory-object.c
index 8661a66..0dafe06 100644
--- a/src/core/na-factory-object.c
+++ b/src/core/na-factory-object.c
@@ -534,13 +534,13 @@ na_factory_object_dump( const NAIFactoryObject *object )
}
/**
- * na_factory_object_finalize_instance:
+ * na_factory_object_finalize:
* @object: the #NAIFactoryObject being finalized.
*
* Clears all data associated with this @object.
*/
void
-na_factory_object_finalize_instance( NAIFactoryObject *object )
+na_factory_object_finalize( NAIFactoryObject *object )
{
free_data_boxed_list( object );
}
@@ -927,15 +927,11 @@ data_boxed_from_name( const NAIFactoryObject *object, const gchar *name )
static void
free_data_boxed_list( NAIFactoryObject *object )
{
- GList *list, *it;
+ GList *list;
list = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
- for( it = list ; it ; it = it->next ){
-
- g_object_unref( it->data );
- }
-
+ g_list_foreach( list, ( GFunc ) g_object_unref, NULL );
g_list_free( list );
g_object_set_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA, NULL );
diff --git a/src/core/na-factory-object.h b/src/core/na-factory-object.h
index a5ab315..20bd2e6 100644
--- a/src/core/na-factory-object.h
+++ b/src/core/na-factory-object.h
@@ -59,7 +59,7 @@ void na_factory_object_copy ( NAIFactoryObject *target, cons
gboolean na_factory_object_are_equal ( const NAIFactoryObject *a, const NAIFactoryObject *b );
gboolean na_factory_object_is_valid ( const NAIFactoryObject *object );
void na_factory_object_dump ( const NAIFactoryObject *object );
-void na_factory_object_finalize_instance( NAIFactoryObject *object );
+void na_factory_object_finalize ( NAIFactoryObject *object );
void na_factory_object_read_item ( NAIFactoryObject *object, const NAIFactoryProvider *reader, void *reader_data, GSList **messages );
guint na_factory_object_write_item ( NAIFactoryObject *object, const NAIFactoryProvider *writer, void *writer_data, GSList **messages );
diff --git a/src/core/na-object-action.c b/src/core/na-object-action.c
index 75b590c..e619694 100644
--- a/src/core/na-object-action.c
+++ b/src/core/na-object-action.c
@@ -249,8 +249,6 @@ instance_finalize( GObject *object )
g_free( self->private );
- na_factory_object_finalize_instance( NA_IFACTORY_OBJECT( object ));
-
/* chain call to parent class */
if( G_OBJECT_CLASS( st_parent_class )->finalize ){
G_OBJECT_CLASS( st_parent_class )->finalize( object );
diff --git a/src/core/na-object-item.c b/src/core/na-object-item.c
index f765f1c..e03532a 100644
--- a/src/core/na-object-item.c
+++ b/src/core/na-object-item.c
@@ -663,12 +663,7 @@ na_object_item_count_items( GList *items, gint *menus, gint *actions, gint *prof
void
na_object_item_unref_items( GList *items )
{
- GList *it;
-
- for( it = items ; it ; it = it->next ){
- g_object_unref( it->data );
- }
-
+ g_list_foreach( items, ( GFunc ) g_object_unref, NULL );
g_list_free( items );
}
diff --git a/src/core/na-object-menu.c b/src/core/na-object-menu.c
index efda2e0..a4c35c5 100644
--- a/src/core/na-object-menu.c
+++ b/src/core/na-object-menu.c
@@ -235,8 +235,6 @@ instance_finalize( GObject *object )
g_free( self->private );
- na_factory_object_finalize_instance( NA_IFACTORY_OBJECT( object ));
-
/* chain call to parent class */
if( G_OBJECT_CLASS( st_parent_class )->finalize ){
G_OBJECT_CLASS( st_parent_class )->finalize( object );
diff --git a/src/core/na-object-profile.c b/src/core/na-object-profile.c
index 17686bb..a82963a 100644
--- a/src/core/na-object-profile.c
+++ b/src/core/na-object-profile.c
@@ -262,8 +262,6 @@ instance_finalize( GObject *object )
g_free( self->private );
- na_factory_object_finalize_instance( NA_IFACTORY_OBJECT( object ));
-
/* chain call to parent class */
if( G_OBJECT_CLASS( st_parent_class )->finalize ){
G_OBJECT_CLASS( st_parent_class )->finalize( object );
diff --git a/src/core/na-object.c b/src/core/na-object.c
index 5d77ff3..dffad87 100644
--- a/src/core/na-object.c
+++ b/src/core/na-object.c
@@ -198,6 +198,8 @@ instance_finalize( GObject *object )
g_free( self->private );
+ na_factory_object_finalize( NA_IFACTORY_OBJECT( object ));
+
/* chain call to parent class */
if( G_OBJECT_CLASS( st_parent_class )->finalize ){
G_OBJECT_CLASS( st_parent_class )->finalize( object );
diff --git a/src/core/na-pivot.c b/src/core/na-pivot.c
index 1f89a3d..240fe2b 100644
--- a/src/core/na-pivot.c
+++ b/src/core/na-pivot.c
@@ -312,7 +312,7 @@ instance_dispose( GObject *object )
self->private->consumers = NULL;
/* release item tree */
- na_object_item_unref_items( self->private->tree );
+ na_object_unref_items( self->private->tree );
self->private->tree = NULL;
/* release the GConf monitoring */
@@ -545,7 +545,7 @@ na_pivot_load_items( NAPivot *pivot )
if( !pivot->private->dispose_has_run ){
- na_object_item_unref_items( pivot->private->tree );
+ na_object_unref_items( pivot->private->tree );
messages = NULL;
diff --git a/src/nact/nact-assistant-export.c b/src/nact/nact-assistant-export.c
index 67d0d4d..466b9db 100644
--- a/src/nact/nact-assistant-export.c
+++ b/src/nact/nact-assistant-export.c
@@ -663,7 +663,7 @@ assist_prepare_confirm( NactAssistantExport *window, GtkAssistant *assistant, Gt
text = tmp;
}
- na_object_unref_items( actions );
+ na_object_unref_selected_items( actions );
g_assert( window->private->uri && strlen( window->private->uri ));
@@ -736,7 +736,7 @@ assistant_apply( BaseAssistant *wnd, GtkAssistant *assistant )
}
}
- na_object_unref_items( actions );
+ na_object_unref_selected_items( actions );
}
static void
diff --git a/src/nact/nact-iactions-list.c b/src/nact/nact-iactions-list.c
index aa4b4b9..f5ac29c 100644
--- a/src/nact/nact-iactions-list.c
+++ b/src/nact/nact-iactions-list.c
@@ -291,7 +291,7 @@ free_items_callback( NactIActionsList *instance, GList *items )
g_debug( "nact_iactions_list_free_items_callback: selection=%p (%d items)",
( void * ) items, g_list_length( items ));
- na_object_unref_items( items );
+ na_object_unref_selected_items( items );
}
static void
@@ -931,6 +931,7 @@ filter_selection( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath
gtk_tree_model_get( model, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
g_return_val_if_fail( object, FALSE );
g_return_val_if_fail( NA_IS_OBJECT_ID( object ), FALSE );
+ g_object_unref( object );
/* if there is not yet any selection, then anything is allowed
*/
@@ -947,7 +948,6 @@ filter_selection( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath
*/
if( filter_selection_is_implicitely_selected( object )){
g_debug( "%s: implicitely selected item: selection not allowed", thisfn );
- g_object_unref( object );
return( FALSE );
}
@@ -960,7 +960,6 @@ filter_selection( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath
filter_selection_set_implicitely_selected_childs( object, !path_currently_selected );
}
- g_object_unref( object );
return( TRUE );
}
diff --git a/src/nact/nact-main-menubar.c b/src/nact/nact-main-menubar.c
index f2f9483..506bf0b 100644
--- a/src/nact/nact-main-menubar.c
+++ b/src/nact/nact-main-menubar.c
@@ -834,7 +834,7 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
/* about always enabled */
- na_object_unref_items( selected_items );
+ na_object_unref_selected_items( selected_items );
}
static void
@@ -1112,7 +1112,7 @@ on_copy_activated( GtkAction *gtk_action, NactMainWindow *window )
clipboard = nact_main_window_get_clipboard( window );
nact_clipboard_primary_set( clipboard, items, CLIPBOARD_MODE_COPY );
update_clipboard_counters( window );
- na_object_unref_items( items );
+ na_object_unref_selected_items( items );
g_signal_emit_by_name( window, MAIN_WINDOW_SIGNAL_UPDATE_ACTION_SENSITIVITIES, NULL );
}
@@ -1260,7 +1260,7 @@ on_duplicate_activated( GtkAction *gtk_action, NactMainWindow *window )
na_object_unref_items( dup );
}
- na_object_unref_items( items );
+ na_object_unref_selected_items( items );
}
/*
@@ -1402,7 +1402,7 @@ on_dump_selection_activated( GtkAction *action, NactMainWindow *window )
na_object_dump( it->data );
}
- na_object_unref_items( items );
+ na_object_unref_selected_items( items );
}
static void
diff --git a/src/test/init-dispose-diff.sh b/src/test/init-dispose-diff.sh
index 16162a8..8b3b882 100755
--- a/src/test/init-dispose-diff.sh
+++ b/src/test/init-dispose-diff.sh
@@ -4,9 +4,27 @@
# in our debug traces.
#
# $1 = input file (debug log)
+#
+#real 6m1.314s
+#user 0m27.317s
+#sys 1m28.583s
+
+function usage
+{
+ echo "Usage: $0 <logfile> [display_ok=true|false]" 1>&2
+}
if [ "$1" = "" ]; then
- echo "Usage: $0 <logfile>" 1>&2
+ usage
+ exit 1
+fi
+
+if [ "${2}" = "" ]; then
+ display_ok=1
+elif [ "${2}" = "false" ]; then
+ display_ok=0
+elif [ "${2}" != "true" ]; then
+ usage
exit 1
fi
@@ -15,18 +33,116 @@ tmp2=/tmp/$(basename $0).$$.2
tmp3=/tmp/$(basename $0).$$.3
\rm -f /tmp/$(basename $0).*
+echo ""
+
+function getftmp
+{
+ echo /tmp/$(basename $0).$$.${1}
+}
+
+function str_init
+{
+ typeset ftmp=$(getftmp ${1})
+ echo "" > ${ftmp}
+}
+
+function str_grep
+{
+ typeset ftmp=$(getftmp ${1})
+ grep -w $2 ${ftmp}
+}
+
+function str_add
+{
+ typeset ftmp=$(getftmp ${1})
+ echo ${2} >>${ftmp}
+}
+
+function count_init
+{
+ typeset ftmp=$(getftmp ${1})
+ echo "0">${ftmp}
+}
+
+function count_inc
+{
+ typeset ftmp=$(getftmp ${1})
+ typeset value=$(cat ${ftmp})
+ let value+=1
+ echo ${value}>${ftmp}
+}
+
+function count_display
+{
+ typeset ftmp=$(getftmp ${1})
+ cat ${ftmp}
+}
+
+function is_reused
+{
+ typeset fused=/tmp/$(basename $0).$$.reused
+ typeset triplet="${1}"
+ typeset -i count=0
+
+ typeset used_line="$(grep -w ${triplet} ${fused} 2>/dev/null)"
+ if [ "${used_line}" = "" ]; then
+ count=1
+ echo "${triplet} ${count}" >> ${fused}
+ else
+ count=$(echo ${used_line} | awk '{ print $2 }')
+ let count+=1
+ grep -v ${triplet} ${fused} > ${fused}.tmp
+ echo "${triplet} ${count}" >> ${fused}.tmp
+ mv ${fused}.tmp ${fused}
+ fi
+
+ echo ${count}
+}
# get in tmp1 just the list of instance_init/instance_dispose with line numbers
# it is kept in run order (line number order)
-grep -En 'instance_init|instance_dispose' ${1} | grep -v "base_window_instance_dispose: quitting main window" > ${tmp1}
+echo -n "Extracting and formatting relevant lines from ${1}"
+count100=0
+count500=0
+total=0
+grep -En 'instance_init|instance_dispose' ${1} | grep -v "quitting main window" | while read line; do
+ let total+=1
+ let count100+=1
+ if [ ${count100} -ge 100 ]; then
+ echo -n "."
+ count100=0
+ fi
+ let count500+=1
+ if [ ${count500} -ge 500 ]; then
+ echo -n " ${total}"
+ count500=0
+ fi
+ numline=$(echo ${line} | cut -d: -f1)
+ #echo "${numline} $(echo ${line} | cut -d' ' -f3-)" >> ${tmp1}
+ #numline=$(echo ${line} | awk '{ print $1 }')
+ fname=$(echo ${line} | awk '{ print $3 }' | sed 's/:$//')
+ address=$(echo ${line} | awk '{ print $4 }' | sed -e 's/.*=//' -e 's/,$//')
+ typename=$(echo ${line} | awk '{ print $5 }' | sed 's/[(),]*//g')
+ [ "${typename}" = "" ] && echo "warning: no type in line ${line}" 1>&2
+ prefix=$(echo ${fname} | sed 's/_instance.*$//')
+ nature=1:init
+ [ "$(echo ${fname} | grep init)" = "" ] && nature=2:disp
+ reused=$(is_reused ${address}-${prefix}-${nature})
+ #echo "address='${address}' fname='${fname}' object='${object}' typename='${typename}' numline='${numline}'" >> ${tmp3}
+ #echo -e "${numline}\t ${fname}\t ${address}\t ${typename}\t ${prefix}\t ${rang}" >> ${tmp3}
+ #echo "${numline} ${fname} ${address} ${typename} ${prefix} ${nature}" >> ${tmp3}
+ echo "${numline} ${fname} ${address} ${typename} ${prefix} ${nature} ${reused}" >> ${tmp1}
+done
+count=$(wc -l ${tmp1} | awk '{ print $1 }')
+echo " ${count} readen lines"
#cat ${tmp1}
#exit
# get in tmp2 the same run-ordered lines, just with line numbers as a separated field
-cat ${tmp1} | while read line; do
- numline=$(echo ${line} | cut -d: -f1)
- echo "${numline} $(echo ${line} | cut -d' ' -f3-)" >> ${tmp2}
-done
+#cat ${tmp1} | while read line; do
+# numline=$(echo ${line} | cut -d: -f1)
+# echo "${numline} $(echo ${line} | cut -d' ' -f3-)" >> ${tmp2}
+#done
#cat ${tmp2}
#exit
@@ -41,53 +157,88 @@ done
# while the instance_dispose use the type name of the derived class)
# 5: radical of function name (e.g. base_application)
# 6: an help for the sort
-cat ${tmp2} | while read line; do
- numline=$(echo ${line} | awk '{ print $1 }')
- fname=$(echo ${line} | awk '{ print $2 }' | sed 's/:$//')
- address=$(echo ${line} | awk '{ print $3}' | sed -e 's/.*=//' -e 's/,$//')
- typename=$(echo ${line} | awk '{ print $4 }' | sed 's/[(),]*//g')
- [ "${typename}" = "" ] && echo "warning: no type in line ${line}" 1>&2
- prefix=$(echo ${fname} | sed 's/_instance.*$//')
- nature=1:init
- [ "$(echo ${fname} | grep init)" = "" ] && nature=2:disp
- #echo "address='${address}' fname='${fname}' object='${object}' typename='${typename}' numline='${numline}'" >> ${tmp3}
- #echo -e "${numline}\t ${fname}\t ${address}\t ${typename}\t ${prefix}\t ${rang}" >> ${tmp3}
- #echo "${numline} ${fname} ${address} ${typename} ${prefix} ${nature}" >> ${tmp3}
- echo "${numline} ${fname} ${address} ${typename} ${prefix} ${nature}" >> ${tmp3}
-done
+#cat ${tmp2} | while read line; do
+# numline=$(echo ${line} | awk '{ print $1 }')
+# fname=$(echo ${line} | awk '{ print $2 }' | sed 's/:$//')
+# address=$(echo ${line} | awk '{ print $3}' | sed -e 's/.*=//' -e 's/,$//')
+# typename=$(echo ${line} | awk '{ print $4 }' | sed 's/[(),]*//g')
+# [ "${typename}" = "" ] && echo "warning: no type in line ${line}" 1>&2
+# prefix=$(echo ${fname} | sed 's/_instance.*$//')
+# nature=1:init
+# [ "$(echo ${fname} | grep init)" = "" ] && nature=2:disp
+# #echo "address='${address}' fname='${fname}' object='${object}' typename='${typename}' numline='${numline}'" >> ${tmp3}
+# #echo -e "${numline}\t ${fname}\t ${address}\t ${typename}\t ${prefix}\t ${rang}" >> ${tmp3}
+# #echo "${numline} ${fname} ${address} ${typename} ${prefix} ${nature}" >> ${tmp3}
+# echo "${numline} ${fname} ${address} ${typename} ${prefix} ${nature}" >> ${tmp3}
+#done
export LC_ALL=C
-sortparms="-k3,3 -k5,5 -k1,1n"
-#sortparms="-k3 -k5 -k6"
+
+# address, reused_count, function_prefix (should identify the class), line_number
+echo "Sorting..."
+sortparms="-k7,7n -k3,3 -k5,5 -k1,1n"
+cat ${tmp1} | sort ${sortparms} > ${tmp2}
+
#cat ${tmp3} | sort ${sortparms}
#exit
+echo "Apparying..."
line_init=""
-cat ${tmp3} | sort ${sortparms} | while read line; do
+count_init count_ok
+count_init count_undisposed
+count_init count_undisposed_bis
+count_init count_warns
+str_init list_undisposed
+cat ${tmp2} | while read line; do
nature=$(echo ${line} | awk '{ print $6 }')
if [ "${line_init}" = "" -a "${nature}" != "1:init" ]; then
echo "warning: unwaited line: ${line}"
+ count_inc count_warns
continue
fi
if [ "${line_init}" = "" ]; then
- adr_init=$(echo ${line} | awk '{ print $3 }')
+ addr_init=$(echo ${line} | awk '{ print $3 }')
app_init=$(echo ${line} | awk '{ print $5 }')
line_init="${line}"
else
- adr_dispose=$(echo ${line} | awk '{ print $3 }')
+ addr_dispose=$(echo ${line} | awk '{ print $3 }')
app_dispose=$(echo ${line} | awk '{ print $5 }')
line_dispose="${line}"
- if [ "${adr_dispose}" = "${adr_init}" ]; then
+ if [ "${addr_dispose}" = "${addr_init}" ]; then
numline_init=$(echo ${line_init} | awk '{ print $1 }')
numline_dispose=$(echo ${line_dispose} | awk '{ print $1 }')
type_init=$(echo ${line_init} | awk '{ print $4 }')
- echo "${type_init} ${adr_init} (${numline_init},${numline_dispose}): OK"
+ if [ ${display_ok} -eq 1 ]; then
+ echo "${type_init} ${addr_init} (${numline_init},${numline_dispose}): OK"
+ fi
+ count_inc count_ok
line_init=""
else
- echo "warning: not apparied line: ${line_init}"
- adr_init=${adr_dispose}
- app_init=${adr_dispose}
+ nature=$(echo ${line_dispose} | awk '{ print $6 }')
+ if [ "${nature}" = "1:init" ]; then
+ if [ "$(str_grep list_undisposed ${addr_init})" = "" ]; then
+ class=$(echo ${line_init} | awk '{ print $4 }')
+ num=$(echo ${line_init} | awk '{ print $1 }')
+ echo "- undisposed ${class} at ${addr_init} intialized at line ${num}"
+ str_add list_undisposed ${addr_init}
+ count_inc count_undisposed
+ else
+ echo "- do not record ${class} already counted"
+ count_inc count_undisposed_bis
+ fi
+ else
+ echo "warning: not apparied line: ${line_init}"
+ count_inc count_warns
+ fi
+ addr_init=${addr_dispose}
+ app_init=${addr_dispose}
line_init="${line_dispose}"
fi
fi
done
+
+echo ""
+echo "Objects are OK : $(count_display count_ok)"
+echo "Undisposed objects: $(count_display count_undisposed) (not re-counted lines: $(count_display count_undisposed_bis))"
+echo "Other warnings : $(count_display count_warns)"
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]