Re: Compiling a GTK application on windows

On Thu, 2 Jun 2011 09:12:19 +0800
Gang Chen <gang chen cn gmail com> wrote:
> Glib::signal_idle().connect() is not thread safe? So I should use
> Glib::Dispatcher?

Glib::signal_idle()::connect() isn't thread safe (nor at present is
Glib::signal_idle()::connect_once()), so if using gtkmm you should use
Glib::Dispatcher.  A Dispatcher object can be emitted on by any thread,
as the Glib::Dispatcher::emit()/Glib::Dispatcher::operator()() methods
are thread safe - that is of course the purpose.  The other Dispatcher
methods generally are not, as they use libsigc++, so when actually
constructing new slots and connecting them to the Dispatcher, or
disconnecting them, this should be done in the thread in which the
Dispatcher objected is constructed, which is the thread in which the
slots will execute.

The other thing to note is that where a Dispatcher has been emitted on,
it must remain in existence until the connected slot(s) in question
have executed (but this is rather more obvious).

> Even if I only use libsigc++ in the main thread, shall I still use
> sigc::trackable?

sigc::trackable comprises a list of callbacks which are called when
its destructor executes, and these callbacks null any slots
representing one of its non-static methods. Every time a slot is created
representing a non-static method of a class deriving from trackable, a
new nulling callback is inserted in the list.  Every time a slot is
destroyed, the nulling callback is removed from the list (every slot
contains its own trackable).  The list is not protected by mutexes or
anything like that. Furthermore, when the nulling callbacks execute,
they execute in the thread in which the destructor of the trackable
object concerned executes.

The results are somewhat unintuitive.  The first thread which creates a
slot representing a non-static method of an object deriving from
trackable in effect not only "owns" the slot, but also "owns" the object
itself.  No other slot representing any of that object's methods may be
constructed by another thread, nor may the object be destroyed by
another thread, without external synchronisation, which because of the
interactions I have mentioned is quite difficult to do.

So using sigc::trackable in a multi-threaded program is OK, but you
need to make sure that any one object deriving from trackable is only
operated in one of the ways I have mentioned by one thread.  If you
restrict all such calls to the main GUI thread, and use boost::signal2
(or some other thread-safe signal/slot implementation) for the
remainder, and use Glib::Dispatcher or g_idle_add() for inter-thread
communication, you should be fine.

Unfortunately none of this is adequately documented, and in consequence
there are probably numerous thread-unsafe programs out there.


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