Re: [sigc] why is this simple test program not thread-safe?



On Fri, 07 Nov 2008 07:35:52 +0100
Paul Davis <paul linuxaudiosystems com> wrote:
> On Fri, 2008-11-07 at 00:20 +0000, Chris Vine wrote:
> 
> > 
> > You have a static (shared) signal object.  It couldn't be thread
> > safe, since it doesn't have any locking.  It is just like any other
> > class object with data members (ie which operates on non-local
> > data). sigc::signal<>::emit() will amongst other things access the
> > std::list object maintained by the signal object to call operator()
> > on the slot object the list object holds (the slot object
> > representing listener()).
> 
> this much i understood :) however, my assumption was that anything
> which manipulated the slot list would be thread-unsafe, but that
> read-only access (ie. traversing the list and invoking the slots
> contained therein) would be thread-safe to the extent that the code
> invoked by the slots is (in my real program and this test, that part
> is true). i do not understand why emit() would need to modify the
> list of slots in any way, and thus i don't see why it could not be
> thread-safe on the condition that the slot list is not modified
> during the "period in question".
> 
> it is certainly possible to have two threads traverse a std::list<>
> simultaneously without any issues at all - its not clear why emit has
> to do anything more than this. i'd really like to understand why it
> apparently does.

The C++ standard doesn't guarantee you can traverse a std::list<>
object simultaneously in two different threads, though, although
I agree usually you can. The signal_impl struct also has other data
members than just the slot list, and it has its own iterator type which
possibly causes something somewhere to keep state (it is a while since
I looked at it).

I cannot now even recall whether operator()() for any one slot is thread
safe as between different threads invoking that method on the same
slot (which your example does). There is no particular reason to think
it would not be, but I would want to look at the code before assuming
that it is. Slot creation and destruction is definitely problematic
though if the slot represents a method of an object derived from
sigc::trackable, as sigc::trackable is very much not thread safe - that
would be an issue if the sigc::signal<> object keeps its slot_base
objects by value, which I think it does, because every time a slot is
extracted from the std::list object copies are created and destroyed.
However, again that is not relevant to your example as you used global
functions as callbacks.

Basically I always assume that any class object which maintains data
members is not thread safe until I have looked at the code and found
that it is (or it is reliably documented as thread safe).

Chris



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