I am looking at Boost's shared_ptr class, in particular its thread safety. There are several unknowns to me here but they are all related hence I have grouped them as one question.
Whilst looking at the code that I query in question 2 below, I tried to answer it for myself, but in the process of doing so found that I don't actually know how to pass a shared_ptr to a thread. This was my initial attempt:
void ThreadFunc(void* pP)
boost::shared_ptr<int>* pParam = (boost::shared_ptr<int>*)pP;
int main(int argc, char* argv)
boost::shared_ptr<int> pS(new int(100));
_beginthread( ThreadFunc, 0, (void*)&pS);
However I realised that if pS goes out of scope in main() before the thread starts, the thread will create a copy of a dead object. Boom.
How can we pass shared_ptr objects between threads? Do we need some sync object to ensure that main() waits for the thread to create its copy of the shared_ptr?
I am flumoxed by the following code:
// From boost_1_49_0\boost\smart_ptr\detail\sp_counted_base_w32.hpp
void release() // nothrow
if( BOOST_INTERLOCKED_DECREMENT( &use_count_ ) == 0 )
Suppose thread A and thread B both release at the same time. Thread A runs to BOOST_INTERLOCKED_DECREMEN
T(), but doesn't actually start executing it. It is then pre-empted by thread B which executes the complete method - it decrements use_count_, finds it is zero, then destroys the object.
Thread A then resumes. This is where I think there may be a problem.
a) It will access use_count_, which is part of the object which has been destroyed - surely this is an access violation?
b) Furthermore, what if another object has been allocated - it could be at the same memory location as that which we have just destroyed, hence we are now decrementing the use_count_ member of another object altogether!
c) If, after destruction, the current object just happens to have (randomly initialised) use_count_ as 1, thread A would decrement it and free the same memory again: boom!