Glib ref-counting question



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     |
\-------------------------------------------------------------------/




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