$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