$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: andreas_m_huber (andreas_at_[hidden])
Date: 2002-01-03 18:31:28
Hello there
I had a quick look at the new Signals library and I'm having 
difficulties how to safely use it in an MT environment. For example, 
if not used _very_ carefully, the proposed boost::trackable baseclass 
seems to make otherwise inncocent-looking code vulnerable to race 
conditions.
Example (derived from the signals library documentation, does not 
compile):
struct Provider {
  Provider( const std::string & name ) : name( name ) {}
  boost::signal1< void, const std::string & > SomeSignal;
  void DoIt() { SomeSignal( name ); }
private:
  std::string name;
};
struct SomeSlot : public boost::trackable {
  // connects itself with the passed provider and relies on the
  // base class destructor to be disconnected
  SomeSlot( Provider & provider ) {
    provider.SomeSignal.connect(
      boost::bind( &SomeSlot::DoIt, this, _1 ) );
  }
  void DoIt( const std::string & );
private:
  // some Mutex protected members accessed by DoIt
};
Provider myProvider( "OK!" );
SomeSlot * pSlot = new SomeSlot( myProvider );
myProvider.DoIt(); // prints OK!
// here pSlot is handed to thread 2
delete pSlot; // executed by thread 2
myProvider.DoIt(); // executed by thread 1
The base class portion of an object is destructed after the derived 
class members, so the following could occur:
- thread 2 has already destructed the members of SomeSlot but has not 
yet destructed the boost::trackable base class.
- thread 1 fully executes myProvider.DoIt() before thread 2 has a 
chance to complete the destruction of the object (and thus 
remove the SomeSlot object from the slot list).
--> Thread 1 accesses the already destructed subobject(s) of SomeSlot.
I cannot see how to _easily_ avoid this problem if one solely relies 
on boost::trackable for connection management. 
I believe the same thing could happen even if manual connection 
management is used (although less likely): One thread makes a 
"call" through the signal while another thread disconnects the slot. 
It could AFAICT happen that the slot is called _after_ it has been 
disconnected (which of course could lead to all sorts of problems).
IMPORTANT: This is not meant as a critisism to the signals library or 
its designer. I (with my limited experience in multithreading) simply 
cannot figure out how to use the library safely in an MT environment.
Andreas