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



On Monday 15 January 2007 01:16, Daniel Elstner wrote:
> Am Sonntag, den 14.01.2007, 23:49 +0000 schrieb Chris Vine:
[snip]
> > You know glibmm better than me, but it seems to me that the same would
> > apply to that.  Glib::signal_idle().connect() will create the idle
> > source, and then call Glib::SignalIdle::connect() on it, which will
> > invoke g_source_attach(). The only thing I notice is that
> > Glib::SignalIdle::connect(), after the call to g_source_attach(), calls
> > Glib::SourceConnectionNode::install().  I do not know what that does, but
> > if it is important to dispatch of the slot in the main loop by the
> > relevant GMainContext object you could always put
> > LOCK_CONTEXT(context_)/UNLOCK_CONTEXT(context_) around it (or if it makes
> > sense to put the call to Glib::SourceConnectionNode::install() before the
> > call to g_source_attach(), put it before the call to g_source_attach()).
>
> inline
> void SourceConnectionNode::install(GSource* source)
> {
>   source_ = source;
> }
>
> It's trivial, and can be moved somewhere before the g_source_attach()
> without harm.  In fact, it should be moved, as it writes data that might
> be read by another thread.
>
> However, I can still see one possible show-stopper: sigc++.  Well,
> contrary to what I feared at first, explicitly copying a sigc::slot
> performs a deep copy.  In particular, this comment relieved me
> (note that sigc::slot_rep is a subclass of sigc::trackable):
>
> /* Don't copy the notification list.
>    The objects watching src don't need to be notified when the new
> object dies. */
> trackable::trackable(const trackable& /*src*/)
>
> : callback_list_(0)
>
> {}
>
> Now to the bad news.  Glib::signal_idle().connect() returns a
> sigc::connection object.
>
> connection::connection(slot_base& sl)
>
> : slot_(&sl)
>
> {
>   //Let the connection forget about the signal handler when the handler
> object dies:
>   slot_->add_destroy_notify_callback(this, &notify);
> }
>
> connection::~connection()
> {
>   if (slot_)
>     slot_->remove_destroy_notify_callback(this);
> }
>
> Doomed, I'd say.  At least the call to remove_destroy_notify_callback()
> after the GSource mutex has been unlocked is unavoidable with the
> current API.  Maybe we'll be able to play some tricks and put something
> entirely different into the sigc::connection object.  A special-purpose
> slot which holds a connection ID or something, and goes through the
> GMainLoop/GSource interface to destroy the callback slot.

Yes, I see.  Perhaps it could be dealt with by adding a new method such as 
SignalIdle::safe_connect() which does not return a sigc::connection object.  
In this kind of case you would never usually want to use a sigc::connection 
object - the callback would return false and the idle handler would 
automatically be disposed of (by the main program thread, which is OK).

Better still for this usage, perhaps there could be a 
SignalIdle::single_connect() method which returns nothing and which will 
disconnect the callback whatever it's return value once it has been executed 
(in other words, it expects a void return value from the callback).

Chris




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