Re: gtk_object_unref
- From: Thomas Mailund <mailund mailund dk>
- To: GTK+ mailing list <gtk-list gnome org>
- Subject: Re: gtk_object_unref
- Date: 02 Oct 2001 12:02:30 +0930
On Tue, 2001-10-02 at 02:01, Jean-Christophe Berthon wrote:
> Hello everyone,
>
> I'm trying to use the gtk_object_ref and gtk_object_unref function.
>
> I have objects which are referencing shared points.
> Let say an object called A reference the point P. If P was not already
> created, I'm creating it.
> Then I add another object B which reference P also. As P is already created,
> I using gtk_object_ref on P.
>
> If I remove B then I unref P and if I remove A, I again unref P but I want
> him to be destroy. It is working but I get an unnicely warning message in my
> xterm saying that :
> Gtk-CRITICAL **: file gtkobject.c: line 1179 (gtk_object_unref): assertion
> `object->ref_count > 0' failed.
>
>
> So I went looking at the source code of gtk_object_unref and I found this
> piece code :
> void gtk_object_unref (GtkObject *object)
> {
> g_return_if_fail (object != NULL);
> g_return_if_fail (GTK_IS_OBJECT (object));
> g_return_if_fail (object->ref_count > 0);
>
> if (object->ref_count == 1)
> {
> gtk_object_destroy (object);
>
> g_return_if_fail (object->ref_count > 0);
> }
>
> object->ref_count -= 1;
>
> if (object->ref_count == 0)
> {
> object->klass->finalize (object);
> }
> }
>
> So when unref is called and there was only one last reference on the object,
> destroy is called. As destroy doesn't decremente ref_count it should be
> fine, but it seems not to work as I've done a printf of object->ref_count
> before calling unref and I got 1 before calling gtk_object_unref and 0
> after...
what you are not seeing is the inner workings of gtk_object_destroy,
which is a virtual function, that in this case in fact decrements the
ref-counter (otherwise you wouldn't get the return_if_fail message). A
window, for example, will in its destroy function call
gtk_container_unregister_toplevel, which contains a gtk_widget_unref
call, so destroying a window using unref will give you the warning you
describe. A button on the other hand can be destroyed using unref (see
the attached program).
My guess is that something in your program think it is holding a
reference to the object you are unref'ing, and decrements it during its
destroy handling, perhaps the canvas is ref'ing all items or something.
As a workaround, you could write a wrapper around the objects you want
to refcount, a wrapper that doesn't unref during destroy, and simply
destroy the "real" object when the wrapper is destroyed.
/mailund
--
Without order nothing can exist - without chaos nothing can evolve.
#include <gtk/gtk.h>
void
destroy (void)
{
g_print ("destroy...\n");
}
int
main (int argc, char *argv[])
{
GtkObject *obj;
gtk_init (&argc, &argv);
obj = GTK_OBJECT (gtk_button_new ());
gtk_signal_connect (obj, "destroy", GTK_SIGNAL_FUNC (destroy), 0);
// ref and unref
g_print ("refcount == %d\n", obj->ref_count);
gtk_object_ref(obj);
g_print ("refcount == %d\n", obj->ref_count);
gtk_object_unref(obj);
g_print ("refcount == %d\n", obj->ref_count);
// this destroys the object
gtk_object_unref(obj);
g_print ("refcount == %d\n", obj->ref_count);
obj = GTK_OBJECT (gtk_window_new (GTK_WINDOW_TOPLEVEL));
gtk_signal_connect (obj, "destroy", GTK_SIGNAL_FUNC (destroy), 0);
g_print ("refcount == %d\n", obj->ref_count);
gtk_object_ref(obj);
g_print ("refcount == %d\n", obj->ref_count);
gtk_object_unref(obj);
g_print ("refcount == %d\n", obj->ref_count);
// this destroys the object, but gives a warning
gtk_object_unref(obj);
g_print ("refcount == %d\n", obj->ref_count);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]