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.
This commit is contained in:
Tim Janik 1998-02-02 18:44:28 +00:00 committed by Tim Janik
parent 8822bde131
commit eeaefdf04f
15 changed files with 297 additions and 118 deletions

View File

@ -1,5 +1,22 @@
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.
* gtk/gtkcolorsel.c:
* gtk/gtkcombo.c:
* gtk/gtkobject.c:

View File

@ -1,5 +1,22 @@
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.
* gtk/gtkcolorsel.c:
* gtk/gtkcombo.c:
* gtk/gtkobject.c:

View File

@ -1,5 +1,22 @@
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.
* gtk/gtkcolorsel.c:
* gtk/gtkcombo.c:
* gtk/gtkobject.c:

View File

@ -1,5 +1,22 @@
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.
* gtk/gtkcolorsel.c:
* gtk/gtkcombo.c:
* gtk/gtkobject.c:

View File

@ -1,5 +1,22 @@
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.
* gtk/gtkcolorsel.c:
* gtk/gtkcombo.c:
* gtk/gtkobject.c:

View File

@ -1,5 +1,22 @@
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.
* gtk/gtkcolorsel.c:
* gtk/gtkcombo.c:
* gtk/gtkobject.c:

View File

@ -1,5 +1,22 @@
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.
* gtk/gtkcolorsel.c:
* gtk/gtkcombo.c:
* gtk/gtkobject.c:

View File

@ -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;
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;
}
g_list_free (filesel->history_list);
}
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);

View File

@ -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);
}

View File

@ -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 */
}
/*****************************************
@ -385,59 +380,6 @@ gtk_object_class_add_user_signal (GtkObjectClass *class,
return signal_id;
}
/*****************************************
* 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:
*
@ -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);
}

View File

@ -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
}

View File

@ -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));
}

View File

@ -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 */

View File

@ -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

View File

@ -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