Re: closure threading issues



Tim Janik <timj gtk org> writes:

> On 30 Mar 2001, Owen Taylor wrote:
> 
> > 
> > I think the conceptual answer to this is really simple:
> > 
> >  - Class closures, and their associated data are associated with the 
> >    signal, which is associated with the class.
> >  - The class won't be unloaded until the object is finalized
> >  - The object won't be finalized until the call is finished.
> > 
> > So class closures don't need refcounting during invocation, and
> > since I don't think class closures should be mutating themselves
> > during invocation, they don't need locking either.
> 
> as every other closure, class closures need to mutate the in_marshal
> flag to decide about pre and post notify callback invocation, also
> for overridable class closures i don't think we can skip
> reference counting.
> skipping reference counting for class closures isn't a viable approach
> btw, unless class closure invocation wouldn't use g_closure_invoke().
> 
> i don't think i really understand how you imagine things to work...
> all i know is that our current setup is likely to break with class
> closures being used in two different threads.

Well, if that's the case, then, well, we need to fix our current
setup:

 - The point of the marshal guards is so that weak referenced data
   that the closure holds a pointer to can be strongly referenced
   during the invocation.

 - If you have weakly referenced data, then it the only reasonable
   thing to do is that when that data is destroyed, to remove
   the closure so that it doesn't get invoked in the future.

 - A class closure, by its very nature, must be set when the 
   class is initialized and not removed until the class is
   finalized.

 - Hence a class closure cannot have weakly referenced data.
 
 - Hence marshal guards are not useful for class closures

If you want to keep changes to the current code as small as
possible, here's a suggestion:

 - Upon installation of a class closure, set the in_marshal
   flag and pre-invoke

 - Upon class finalization, unset the in_marshal flag and
   post-invoke.

That deals with the in_marshal case. All that's left for mutation is
the ref-counting.

One possibility would be to add atomic increment/decrement macros to
GLib - not hard to find and useful for other things as well.  The
other possibility is to add a flag to GClosure -
refcount_upon_invocation.

Regards,
                                        Owen





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