Re: glibmm thread safety [was: Re: Adding custom GDK events]



On Sunday 14 January 2007 23:37, Daniel Elstner wrote:
> Am Sonntag, den 14.01.2007, 00:36 +0000 schrieb Chris Vine:
[snip]
> > It also detects if, between the
> > dispatcher being emitted and the main loop executing the slot (an
> > indeterminate period of time), the Dispatcher object has ceased to exist,
> > but that is a much less significant issue.
>
> Hmm, this one is actually more interesting to me.  I reckon this
> situation could only occur if if a receiving thread instantiated more
> than one Dispatcher object, right?  Because otherwise the pipe() should
> have been closed already.  The safe route seems to be to make sure that
> the Dispatcher objects live as least as long as the main loop runs.
> Alternatively, have the receiving thread wait for some token that
> signals the very last invocation of the Dispatcher slot.

My implementation has a static pipe, and an object count is not kept for the 
purpose of closing the pipe when all objects have been destroyed.  Once the 
two file descriptors for the pipe are committed, they are committed.  
Glib::Dispatcher also uses a static pipe I think, but even if it closes the 
pipe when the last Dispatcher is destroyed (does it?) then the problem could 
still arise.  A particular program may (and usually will) have multiple 
Glib::Dispatcher objects sharing the static pipe and each object keeps its 
own slot.  After signalling one of them from a worker thread it is always 
possible that before the slot maintained by the Dispatcher object is executed 
by the main loop the particular object concerned has gone out of scope.  
Unlikely no doubt, but clearly not impossible since there is more than one 
thread of execution.

As well as a static pipe, my implemention also has a mutex-protected static 
std::set object which keeps a record comprising the address of each 
Dispatcher-like object in existence (the constructor inserts its address in 
the set and the destructor removes it).  I am not sure how Glib::Dispatcher 
indicates which Dispatcher object's slot is to be invoked, but my 
implementation does it by having the emission of the notification send the 
address of the notifying object over the static pipe.  Before the static pipe 
calls the relevant slot held by the notifying object via the address sent 
over the pipe it checks that a notifying object of that address still exists.

This works provided that the notifying objects are only constructed and 
destroyed in the main loop thread.  Unlike Glib::Dispatcher, my 
implementation does not have this restriction but it is documented that 
further synchronisation may be required IF they are constructed or destroyed 
in other threads and object lifetime cannot be guaranteed.

I originally developed this independently of Glib::Dispatcher so it could be 
used in unwrapped GTK+ (although it does rely on libsigc++).

Chris




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