Re: closure floating



> > 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.)
> 
> this is equivalent to ref_count==0 at startup, or floating+every-ref-sinks
> as you say it. and it's exactly the behaviour we currently have in glib,
> however owens (havocs) argument is that its yet another referencing
> mechanism introduced, different from widgets which are floating initially,
> or plain structures that are just ref/unref.

Agreed, and closures really are plain structures here.  Since 
there will be 2 management systems (widgets and other) it is
best to keep the "widget" set as small as possible so that
you don't have to go read through the docs to figure out which
it obeys.  If it doesn't derive from GtkObject is should follow
glib.


> however - looking at owen's line of reasoning to have some functions
> taking closures do sinking and others not, and that this is unlikely
> to confuse normal users since closure usage is an advanced topic anyways -
> i fail to see that having the current closure behaviour, though it is yet
> another referencing scheme, will, in comparison, add more complexity.

I agree with you completely.  Aside from widgets, all other structures
really ought to obey the simplest scheme possible.   

 
> startup ref_count==0/floating+every-ref-sinks is at least fully
> predictable, no extra care has to be taken for connect vs. foreach,
> or with your foobar() variant. and we're unlikely to end up leaking
> while still catching errernerous user behaviour with ref_count!=0
> assertions.

Definitely.


Although I did think of other problems with the foobar example.

void foobar(int p, GClosure* c)
  {
    if (p) 
        g_signal_connect(sig,c); 
  }

This seems unlikely, but then is it?
It is a distinct possibility if you consider the case of
assertions.

void foobar(GtkWidget* w, GClosure* c)
  {
    /*...*/
    g_return_if_fail(w!=0);
    /*...*/
    g_signal_connect ....
  }

Under either owens or glib system this would be a problem.  One
solution to it could be 

void foobar(GtkWidget* w, GClosure* c)
  {
    g_cleanup_if_fail(0,w!=0);
    /* ... */
 
    gchar* c=g_strdup(gtk_widget_name);

    /* ... */
    g_cleanup_if_fail(1,some_error);

    /* ... */
    g_signal_connect ....

    /* ... */
    return;

    cleanup_1:
      g_free(c);
    cleanup_0:    
      g_closure_sink(c);
  }

(where sink means sink or ref/unref depending on the system.)

Okay, that is ugly.  Must have basic memories coming back to
haunt me!  :-(

--Karl






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