Thanks Tony for the thorough reply. I had just made sure that signals can
be (dis)connected by multiple threads in a thread-safe manner, but you are
right that there is much more to it. This will be hard to implement I
think, but I'll do my best!
One thing I don't quite grasp yet, is the following. Suppose one thread
disconnects a slot while another fires a signal connected to that slot. You
say that the implementation must make sure that the signal is not fired
after the disconnect-call returns. But won't this be undefined behaviour,
as there is no way of knowing which will grab the lock first?
Joren
On Fri, Feb 6, 2015 at 6:31 PM, Gottlob Frege
Ah, that's a nice one. I wonder why I haven't come across that benchmark myself.
I haven't yet made it thread safe, but I have been wondering about this. Does it have to implement the slot-calls (which can itself be
On Fri, Feb 6, 2015 at 3:15 AM, Joren Heit
wrote: thread-unsafe) in a safe manner to be considered thread-safe? Or does it only have to be safe with respect to its own data?
For thread safety, the tricky part, but the part you want is two-fold:
1. You do not want to hold a lock _while_ the slot is being called. In general, you never want to hold a lock while calling unknown code (ie virtual function, pointer to function, std::function,...), because you can't be sure whether that unknown code might grab a lock itself, call you back (ie disconnect from within the slot, etc), or whatever, which easily leads to hard to track deadlocks. 2. If I disconnect a slot, I don't want that slot to fire after the disconnection. Sounds simple, but with threads, what does "after" really mean? Particularly if one thread is calling disconnect while another thread is firing the signal? For our purposes, "after" means that the caller, using global flags or whatever, can't tell that the slot was called after the call to disconnect returned.
So 1 means no locks or synchronization, and 2 means you need a lock or synchronization.
The general way to handle this is by breaking #1, but breaking it as narrowly as possible - you still hold a lock while the slot is being called, but it is not a lock protecting the whole list of slots, it is a lock protecting the currently called slot only. So you can still add/remove slots to the signal, but if you attempt to remove the currently running slot, it needs to remove the slot from the list, but *if not the same thread as the slot thread* block until that slot is finished (otherwise the slot could see itself being called after disconnect).
And there are other complications (IIRC) like not using one mutex per slot (wasteful), etc.
Tony _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users