summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorTim Janik <timj@gimp.org>1998-02-02 18:44:28 +0000
committerTim Janik <timj@src.gnome.org>1998-02-02 18:44:28 +0000
commiteeaefdf04fd1972f1c9bcd98997f940efe372d83 (patch)
tree09edbde13a5d538f05dc59a4c76b979ab11ce2e6 /gtk
parent8822bde131bb324a231e0f668f0c02aa6b755d16 (diff)
downloadgtk+-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.c60
-rw-r--r--gtk/gtkmain.c27
-rw-r--r--gtk/gtkobject.c155
-rw-r--r--gtk/gtkobject.h17
-rw-r--r--gtk/gtkwidget.c29
-rw-r--r--gtk/gtkwidget.h8
-rw-r--r--gtk/testgtk.c1
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