Re: Glib ref-counting question
- From: "Padraig O'Briain" <Padraig Obriain ireland sun com>
- To: gtk-list gnome org, gnome-devel-list gnome org, loban earthling net
- Subject: Re: Glib ref-counting question
- Date: Tue, 23 Jan 2001 11:11:40 +0000 (GMT)
I do not know the answer to your question but I thought I would investigate a
little.
I guessed that the input functions described in Havoc Pennington's book
GTK+/Gnome Application Development were probably implemented using the same
functions g_io_channel_* that you are using. I looked at the code in the
directory gtk+/gdk.
In gdkevents.c I found gdk_input_add_full(). This function is similar to your
foo_open() in that it calls g_io_channel_unix_new() and g_io_add_watch_full().
It then calls g_io_channel_unref(). This looks similar to object sinking in
GTK+.
If you do something similar you should get the ref count to zero.
Padraig
> Delivered-To: gtk-list gnome org
> Subject: Glib ref-counting question
> To: gtk-list gnome org, gnome-devel-list gnome org
> Mime-Version: 1.0
> X-BeenThere: gtk-list gnome org
> X-Loop: gtk-list gnome org
> X-Mailman-Version: 2.0beta5
> List-Id: General discussion of GTK+ <gtk-list.gnome.org>
>
> Hi, I have a programming strategy question. Consider the following code
> bite which represents something that I have:
>
> /*************************************/
>
> struct Foo {
> GIOChannel iochannel
> // others
> }
>
> Foo*
> foo_new(int id)
> {
> Foo* foo = g_new0(Foo, 1);
> // stuff
> return foo;
> }
>
> gboolean
> foo_open(int id)
> {
> foo->iochannel = g_io_channel_unix_new(id); // L1
> g_io_add_watch(foo->iochannel, G_IO_IN, G_IO_FUNC(foo_read),
> foo); // L2
> g_io_add_watch(foo->iochannel, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
> G_IO_FUNC(foo_error), foo); // L3
> }
>
> void
> foo_close(Foo* foo)
> {
> g_io_channel_close(foo->iochannel); // L4
> foo->iochannel = NULL;
> }
>
> gboolean
> foo_read(GIOChannel* iochannel, GIOCondition cond, Foo* foo)
> {
> GIOError error = g_io_channel_read( ... );
> if (error == G_IO_ERROR_NONE || G_IO_ERROR_AGAIN) {
> // stuff
> return TRUE;
> } else {
> foo_close(foo); // L5
> return FALSE; // L6
>
> gboolean
> foo_error(GIOChannel* iochannel, GIOCondition cond, Foo* foo)
> {
> // stuff
> foo_close(foo); // L7
> return FALSE; // L8
> }
>
> /*************************************/
>
> The problem is that the iochannel is not not freed when foo_close() is
> called. Because the g_io_channel_close does just one g_io_channel_unref,
> but the ref-count is 3, so it goes down to only 2 (or 1 if foo_close()
> is called from foo_read() or foo_error() becase they return FALSE, hence
> removing the watch and thus unreffing one more time).
>
> What should I do to ensure the iochannel is freed in foo_close()? Should
> I put this after L4:
>
> g_source_remove_by_user_data(foo);
>
> But that only unrefs once, and the refcount might still be > 0. And the
> ref count is a private field. So what should I do?
>
> Thanx in advance for any help.
>
> /-------------------------------------------------------------------\
> | LOBAN AMAAN RAHMAN <-- anagram of --> AHA! AN ABNORMAL MAN! |
> | loban earthling net, loban caltech edu, http://i.am/loban |
> \-------------------------------------------------------------------/
>
> _______________________________________________
> gtk-list mailing list
> gtk-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtk-list
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]