Re: gtk_object_destroy and floating objects




briot@gnat.com writes:

> Note: although I am getting to know the internals of gtk+, I am far from being
> an expert and this might be something I did not understand.
> 
> This comes from a bug report from a GtkAda user (Ada binding to gtk+).
> 
> Apparently, there can be a memory leak in gtk+ in one particular case.
> When one destroys an object that is still floating, its memory is not freed.
> I think this is currently expected, since the object was not sinked and its
> reference count is still 1 when gtk_object_destroy is called.
> However, this means that the memory will never be freed for the object.
> 
> Admittedly, this is a very small case, since widgets are expected to have a
> parent or be toplevel (and thus are no longer floating widgets, and the bug
> does not occur). However, I believe that a simple test like
> 
>   if (GTK_OBJECT_FLOATING (object)) {
>       UNSET_FLAGS (object, GTK_FLOATING);
>       object->ref_count --;
>   }
> 
> in gtk_object_destroy might help. Note that we can not use unref() since this
> would actually attempt to kill the object and the rest of gtk_object_destroy
> would raise an error...
> 
> Or maybe something like:
> 
>   if (GTK_OBJECT_FLOATING (object)) {
>      UNSET_FLAGS (object, GTK_FLOATING);
>      gtk_object_unref (GTK_OBJECT (object));
>      return;
>   }
> 
> would be cleaner (not tested though).

Is there any reason to believe that a object that is left floating 
will actually be destroyed? 

In general, I think your changes confuse two things which are
pretty much orthogonal - the destroyed state of the widget, and the
memory management for the widget.

I can't think of any good reason why gtk_object_destroy() should not
sink floating objects (except that the current behavior is tricky
enough without changing it, and breaking possibly working code). After all,
you are just asking that gtk_object_destroy() on a floating widget has
the same effect as:

 gtk_container_add (random_container, widget);
 gtk_object_destroy (widget);

But, I don't think it makes a lot of sense within in the way
float/sink works in GTK+, and I think that any code that ended up
relying on that behavior for gtk_object_destroy() would be poorly
thought out code. If you want to hold onto an object permanently after
creating it, you should ref/sink the object yourself and unref it at
the end.

In answer to your problem with GtkAda, I'd say that almost every
language binding for GTK+ should ref and sink objects immediately on
creation. The only reason that float/sink exists at all in GTK+ is
because C doesn't have reference counting or garbage collection for
its pointers, so if we want to make

 button = gtk_button_new ();
 gtk_container_add (GTK_CONTAINER (window), button);

not a leak, and not prematurely destroy button we have to do something
like float/sink. But languages bindings almost always have some sort
of proxy objects, and the proxy object can and should hold a normal
reference count to the GtkObject.

Regards,
                                        Owen



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