Re: closure floating



> On 16 Jan 2001, Owen Taylor wrote:
> 
> > Tim Janik <timj gtk org> writes:
> 
> > I'm of the opinion that setting a closure in a persistant manner -
> > g_signal_connect_closure(), g_timeout_set_closure(), whatever can sink
> > the closure. This is much like gtk_container_add(). But simply
> > _using_ a closure for, say, gtk_container_foreach_closure() -
> > as an argument to a function call should not not sink the closure.
> > 
> > The operation of 'sink' basically represents transfer of ownershop -
> > but an operation like g_signal_closure_foreach() should not
> > retain a refcount to the closure and thus cannot become
> > the owner of the closure.
> 
> unfortunately i'm not sure users will find it intuitive that
> signal_connect() takes over the ownership as timeout_set_clousre,
> but _foreach not doing so.
> from a simple usage level, they probably want to be able to use
> g_cclosure_new() inlined in all of those function calls, don't
> you think? (and if they still do, while _foreach doesn't sink,
> we'll silently leak closures all over the place)

The simplest solution is don't have a floating state for closures.
(Or rather any ref sinks them, thus there is no sink operation.)
Once you create them the first time you use them they are destroyed
unless you reference them yourself.  (This is equivalent to everything
sinks.)

That means it you want to use a closure multiple times
simply write

    closure = g_cclosure_new (func, data, dnotify);
    g_closure_ref(closure);
    gtk_container_foreach (container, closure);
    /* closure is already finalized at this point */
    gtk_container_foreach (container, closure);

Anything else would hinder usability while causing unnecessary
memory leaks.  After all how is the user supposed to know if
after they passed it whether it got passed to a foreach() or
a connect()?

  void foobar(int p, GClosure*); /* does this eat the closure or not
                                  or does that depend on p??? */

Simple rule, if you create it and want to keep it, reference it!
Second if they forgot the ref in the foreach case assuming they
didn't create another closure in between, it will fail the
assertion that ref!=0 when it goes to use it.

--Karl





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