diff options
author | Tim Janik <timj@gimp.org> | 1998-02-02 18:44:28 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 1998-02-02 18:44:28 +0000 |
commit | eeaefdf04fd1972f1c9bcd98997f940efe372d83 (patch) | |
tree | 09edbde13a5d538f05dc59a4c76b979ab11ce2e6 /gtk | |
parent | 8822bde131bb324a231e0f668f0c02aa6b755d16 (diff) | |
download | gtk+-eeaefdf04fd1972f1c9bcd98997f940efe372d83.tar.gz |
fixed a bad, bad referencing bug that could caused unreferencing of
Mon Feb 2 04:15:08 1998 Tim Janik <timj@gimp.org>
* gtk/gtkmain.c (gtk_propagate_event): fixed a bad, bad referencing
bug that could caused unreferencing of finalized objects.
* gtk/testgtk.c: destroy fileselection on "OK" (this triggered the
above mentioned bug).
* gtk/gtkwidget.h:
* gtk/gtkwidget.c:
* gtk/gtkobject.h:
* gtk/gtkobject.c:
implemented and object reference tracer (gtk_trace_referencing) which
is activated if GTK_TRACE_OBJECTS is defined (currently per default).
in gdb: set the static variable `gtk_trace_object' to point to the
object that you want to have reference traced.
* gtk/gtkfileselection.c: few cleanups.
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtkfilesel.c | 60 | ||||
-rw-r--r-- | gtk/gtkmain.c | 27 | ||||
-rw-r--r-- | gtk/gtkobject.c | 155 | ||||
-rw-r--r-- | gtk/gtkobject.h | 17 | ||||
-rw-r--r-- | gtk/gtkwidget.c | 29 | ||||
-rw-r--r-- | gtk/gtkwidget.h | 8 | ||||
-rw-r--r-- | gtk/testgtk.c | 1 |
7 files changed, 178 insertions, 119 deletions
diff --git a/gtk/gtkfilesel.c b/gtk/gtkfilesel.c index cc3d829f0c..8a9d123ad6 100644 --- a/gtk/gtkfilesel.c +++ b/gtk/gtkfilesel.c @@ -582,17 +582,21 @@ gtk_file_selection_destroy (GtkObject *object) if (filesel->fileop_dialog) gtk_widget_destroy (filesel->fileop_dialog); - if (filesel->history_list) { - list = filesel->history_list; - while (list) { - callback_arg = list->data; - g_free (callback_arg->directory); - list = list->next; - } - g_list_free (filesel->history_list); - } + if (filesel->history_list) + { + list = filesel->history_list; + while (list) + { + callback_arg = list->data; + g_free (callback_arg->directory); + list = list->next; + } + g_list_free (filesel->history_list); + filesel->history_list = NULL; + } cmpl_free_state (filesel->cmpl_state); + filesel->cmpl_state = NULL; if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -1098,28 +1102,28 @@ gtk_file_selection_file_button (GtkWidget *widget, g_return_if_fail (GTK_IS_CLIST (widget)); - fs = GTK_FILE_SELECTION (user_data); + fs = user_data; g_return_if_fail (fs != NULL); g_return_if_fail (GTK_IS_FILE_SELECTION (fs)); filename = gtk_clist_get_row_data (GTK_CLIST (fs->file_list), row); - if (bevent && filename) { - - switch (bevent->type) - { - case GDK_BUTTON_PRESS: - gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename); - break; - - case GDK_2BUTTON_PRESS: - gtk_button_clicked (GTK_BUTTON (fs->ok_button)); - break; - - default: - break; - } - } + if (bevent && filename) + { + switch (bevent->type) + { + case GDK_BUTTON_PRESS: + gtk_entry_set_text (GTK_ENTRY (fs->selection_entry), filename); + break; + + case GDK_2BUTTON_PRESS: + gtk_button_clicked (GTK_BUTTON (fs->ok_button)); + break; + + default: + break; + } + } } static void @@ -1487,8 +1491,8 @@ cmpl_free_dir_sent_list(GList* dp0) static void cmpl_free_state (CompletionState* cmpl_state) { - cmpl_free_dir_list(cmpl_state->directory_storage); - cmpl_free_dir_sent_list(cmpl_state->directory_sent_storage); + cmpl_free_dir_list (cmpl_state->directory_storage); + cmpl_free_dir_sent_list (cmpl_state->directory_sent_storage); if (cmpl_state->user_dir_name_buffer) g_free (cmpl_state->user_dir_name_buffer); diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index e77b1a26c3..a879c64ae9 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -1118,38 +1118,47 @@ gtk_propagate_event (GtkWidget *widget, GdkEvent *event) { GtkWidget *parent; + GtkWidget *tmp; gint handled_event; g_return_if_fail (widget != NULL); g_return_if_fail (event != NULL); handled_event = FALSE; - + gtk_widget_ref (widget); + if ((event->type == GDK_KEY_PRESS) || (event->type == GDK_KEY_RELEASE)) { + /* Only send key events to window widgets. * The window widget will in turn pass the * key event on to the currently focused widget * for that window. */ parent = gtk_widget_get_ancestor (widget, gtk_window_get_type ()); - if (parent && GTK_WIDGET_IS_SENSITIVE (parent) - && gtk_widget_event (parent, event)) - return; + handled_event = (parent && + GTK_WIDGET_IS_SENSITIVE (parent) && + gtk_widget_event (parent, event)); } /* Other events get propagated up the widget tree * so that parents can see the button and motion * events of the children. */ - while (!handled_event && widget) + tmp = widget; + while (!handled_event && tmp) { - parent = widget->parent; - handled_event = (!GTK_WIDGET_IS_SENSITIVE (widget) || - gtk_widget_event (widget, event)); - widget = parent; + gtk_widget_ref (tmp); + handled_event = (GTK_OBJECT_DESTROYED (tmp) || + !GTK_WIDGET_IS_SENSITIVE (tmp) || + gtk_widget_event (tmp, event)); + parent = tmp->parent; + gtk_widget_unref (tmp); + tmp = parent; } + + gtk_widget_unref (widget); } diff --git a/gtk/gtkobject.c b/gtk/gtkobject.c index a3fb3f8726..cb4e76999a 100644 --- a/gtk/gtkobject.c +++ b/gtk/gtkobject.c @@ -22,7 +22,6 @@ #include "gtkobject.h" #include "gtksignal.h" -#define GTK_OBJECT_DEBUG 1 #define OBJECT_DATA_ID_CHUNK 1024 @@ -93,19 +92,18 @@ static GHashTable *arg_info_ht = NULL; static const char *user_data_key = "user_data"; -#ifdef GTK_OBJECT_DEBUG -static int obj_count = 0; +static gint obj_count = 0; static GSList *living_objs = NULL; + static void gtk_object_debug (void) { - if (1) { GSList *node; - printf ("living objects (%d):\n", obj_count); + printf ("living objects (%d):\n", g_slist_length (living_objs)); for (node = living_objs; node; node = node->next) { GtkObject *obj; @@ -117,9 +115,8 @@ gtk_object_debug (void) GTK_OBJECT_FLOATING (obj)? "floating" : ""); } } - printf ("%d living objects\n", obj_count); + printf ("living objects count = %d\n", obj_count); } -#endif GTK_OBJECT_DEBUG /***************************************** * gtk_object_init_type: @@ -147,9 +144,9 @@ gtk_object_init_type () object_type = gtk_type_unique (0, &object_info); g_assert (object_type == GTK_TYPE_OBJECT); -#ifdef GTK_OBJECT_DEBUG +#ifdef GTK_TRACE_OBJECTS ATEXIT (gtk_object_debug); -#endif GTK_OBJECT_DEBUG +#endif /* GTK_TRACE_OBJECTS */ } GtkType @@ -205,9 +202,7 @@ gtk_object_real_destroy (GtkObject *object) g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_OBJECT (object)); - /* FIXME: gtk_signal_handlers_destroy (object); */ - - /* object->klass = gtk_type_class (gtk_destroyed_get_type ()); */ + gtk_signal_handlers_destroy (object); } /***************************************** @@ -226,10 +221,10 @@ gtk_object_init (GtkObject *object) object->ref_count = 1; object->object_data = NULL; -#ifdef GTK_OBJECT_DEBUG +#ifdef GTK_TRACE_OBJECTS obj_count++; living_objs = g_slist_prepend (living_objs, object); -#endif GTK_OBJECT_DEBUG +#endif /* GTK_TRACE_OBJECTS */ } /***************************************** @@ -386,59 +381,6 @@ gtk_object_class_add_user_signal (GtkObjectClass *class, } /***************************************** - * gtk_object_ref: - * - * arguments: - * - * results: - *****************************************/ - -void -gtk_object_ref (GtkObject *object) -{ - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_OBJECT (object)); - - object->ref_count += 1; -} - -/***************************************** - * gtk_object_unref: - * - * arguments: - * - * results: - *****************************************/ - -void -gtk_object_unref (GtkObject *object) -{ - g_return_if_fail (object != NULL); - g_return_if_fail (GTK_IS_OBJECT (object)); - - if (object->ref_count == 1) - gtk_object_destroy (object); - - if (object->ref_count > 0) - object->ref_count -= 1; - - if (object->ref_count == 0) - { - obj_count--; - -#ifdef GTK_OBJECT_DEBUG - g_assert (g_slist_find (living_objs, object)); - living_objs = g_slist_remove (living_objs, object); - /* - fprintf (stderr, "finalizing %p %s\n", object, gtk_type_name (object->klass->type)); - */ -#endif GTK_OBJECT_DEBUG - - object->klass->finalize (object); - } -} - -/***************************************** * gtk_object_finalize: * * arguments: @@ -1495,3 +1437,82 @@ gtk_object_collect_args (guint *nargs, return args; } + + + +#undef gtk_object_ref +#undef gtk_object_unref + +void +gtk_object_ref (GtkObject *object) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + + object->ref_count += 1; +} + +void +gtk_object_unref (GtkObject *object) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + + if (object->ref_count == 1) + gtk_object_destroy (object); + + if (object->ref_count > 0) + object->ref_count -= 1; + + if (object->ref_count == 0) + { + g_assert (g_slist_find (living_objs, object)); + living_objs = g_slist_remove (living_objs, object); + object->klass->finalize (object); + obj_count--; + } +} + +static GtkObject *gtk_trace_object = NULL; + +void +gtk_trace_referencing (gpointer *o, + const gchar *func, + guint local_frame, + guint line, + gboolean do_ref) +{ + gboolean exists; + GtkObject *object = (GtkObject*) o; + + g_return_if_fail (object != NULL); + g_return_if_fail (GTK_IS_OBJECT (object)); + + exists = (g_slist_find (living_objs, object) != NULL); + + if (exists && + (object == gtk_trace_object || + gtk_trace_object == (void*)42)) + printf ("trace: object_%s: (%s:%p)->ref_count=%d%s (%s_f%02d:%d)\n", + do_ref ? "ref" : "unref", + gtk_type_name (GTK_OBJECT_TYPE (object)), + object, + object->ref_count, + do_ref ? " + 1" : " - 1 ", + func, + local_frame, + line); + + if (!exists) + printf ("trace: object_%s(%p): no such object! (%s_f%02d:%d)\n", + do_ref ? "ref" : "unref", + object, + func, + local_frame, + line); + + if (do_ref) + gtk_object_ref (object); + else + gtk_object_unref (object); +} diff --git a/gtk/gtkobject.h b/gtk/gtkobject.h index 958f7893f1..50c911d76e 100644 --- a/gtk/gtkobject.h +++ b/gtk/gtkobject.h @@ -18,6 +18,8 @@ #ifndef __GTK_OBJECT_H__ #define __GTK_OBJECT_H__ +#define GTK_TRACE_OBJECTS 1 + #include <gtk/gtkenums.h> #include <gtk/gtktypeutils.h> @@ -199,10 +201,9 @@ GtkObject* gtk_object_new (guint type, GtkObject* gtk_object_newv (guint type, guint nargs, GtkArg *args); - +void gtk_object_sink (GtkObject *object); void gtk_object_ref (GtkObject *object); void gtk_object_unref (GtkObject *object); -void gtk_object_sink (GtkObject *object); void gtk_object_weakref (GtkObject *object, GtkDestroyNotify notify, @@ -289,6 +290,18 @@ GtkObject* gtk_object_check_cast (GtkObject *obj, GtkObjectClass* gtk_object_check_class_cast (GtkObjectClass *klass, GtkType cast_type); +void gtk_trace_referencing (gpointer *object, + const gchar *func, + guint local_frame, + guint line, + gboolean do_ref); + +#if defined (GTK_TRACE_OBJECTS) && defined (__GNUC__) +# define gtk_object_ref(o) G_STMT_START{static guint f=0;gtk_trace_referencing((gpointer)o,__PRETTY_FUNCTION__,++f,__LINE__, 1);f--;}G_STMT_END +# define gtk_object_unref(o) G_STMT_START{static guint f=0;gtk_trace_referencing((gpointer)o,__PRETTY_FUNCTION__,++f,__LINE__, 0);f--;}G_STMT_END +#endif /* GTK_TRACE_OBJECTS && __GNUC__ */ + + #ifdef __cplusplus } diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 3b06d385c8..df2724af04 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -953,18 +953,6 @@ gtk_widget_new (guint type, return GTK_WIDGET (obj); } -void -gtk_widget_ref (GtkWidget *widget) -{ - gtk_object_ref (GTK_OBJECT (widget)); -} - -void -gtk_widget_unref (GtkWidget *widget) -{ - gtk_object_unref (GTK_OBJECT (widget)); -} - /***************************************** * gtk_widget_newv: * @@ -3830,3 +3818,20 @@ gtk_widget_dnd_data_set (GtkWidget *widget, gdk_window_dnd_data_set (widget->window, event, data, data_numbytes); } + +#undef gtk_widget_ref +#undef gtk_widget_unref + + +void +gtk_widget_ref (GtkWidget *widget) +{ + gtk_object_ref (GTK_OBJECT (widget)); +} + +void +gtk_widget_unref (GtkWidget *widget) +{ + gtk_object_unref (GTK_OBJECT (widget)); +} + diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index 17a9cdaf15..9874e10e7d 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -351,9 +351,9 @@ GtkWidget* gtk_widget_new (guint type, GtkWidget* gtk_widget_newv (guint type, guint nargs, GtkArg *args); +void gtk_widget_sink (GtkWidget *widget); void gtk_widget_ref (GtkWidget *widget); void gtk_widget_unref (GtkWidget *widget); -void gtk_widget_sink (GtkWidget *widget); void gtk_widget_destroy (GtkWidget *widget); void gtk_widget_destroyed (GtkWidget *widget, GtkWidget **widget_pointer); @@ -509,6 +509,12 @@ void gtk_widget_dnd_data_set (GtkWidget *widget, gpointer data, gulong data_numbytes); +#if defined (GTK_TRACE_OBJECTS) && defined (__GNUC__) +# define gtk_widget_ref gtk_object_ref +# define gtk_widget_unref gtk_object_unref +#endif /* GTK_TRACE_OBJECTS && __GNUC__ */ + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gtk/testgtk.c b/gtk/testgtk.c index 6869f30965..620178f3d6 100644 --- a/gtk/testgtk.c +++ b/gtk/testgtk.c @@ -1972,6 +1972,7 @@ file_selection_ok (GtkWidget *w, GtkFileSelection *fs) { g_print ("%s\n", gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs))); + gtk_widget_destroy (fs); } void |