Re: closure floating

Karl Nelson <kenelson ece ucdavis edu> writes:

> > 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()?

It would be customary, when writing documentation for a
function, to mention whether the function keeps a pointer to
its arguments after it returns. This usually is just a little
bit useful when determining code flow.

Of course, if the function makes temporary signal connections
to the closure then disconnects them, then it would need
to take special precautions or, at a minimum, mention in the
docs that the closure will be sunk.

Just as if a GTK+ function on a widget temporarily added it to
a container widget and removed it, that would be a VERY important
thing to document.
>   void foobar(int p, GClosure*); /* does this eat the closure or not
>                                   or does that depend on p??? */

You should never create a function whose memory management behavior
depends on its arguments. Period.

With the current behavior, you would be just as messed up if the
function was:

  void foobar(int p, GClosure*)
     if (p)
       /* use and temporarily ref the closure */

Because that might or it might not cause the closure to be destroyed.

Let me point out again:

 Closures are not mostly for programs programming GTK+ in C

C programmers are going to hit closures fairly infrequently, and
when they do, it is most important that they behave like other
objects in GTK+ that they understand. Not that they can be
manipulated in as few lines as possible.


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