Opened 19 years ago
Closed 18 years ago
#210 closed Bugs (Invalid)
smart_ptr thread safe exception
Reported by: | adasilva | Owned by: | Peter Dimov |
---|---|---|---|
Milestone: | Component: | smart_ptr | |
Version: | None | Severity: | |
Keywords: | Cc: |
Description
Hi, Environment : WindowsXP boost 1_30_0 VC++6.0SP5 Context : I am running tests on lot of allocations/assigns between two smart pointers shared by two threads. Bug : I receive a "bad_weak_ptr" exception in the method sp_counted_base::add_ref() : void add_ref() { #if defined(BOOST_HAS_THREADS) mutex_type::scoped_lock lock(mtx_); #endif if(use_count_ == 0 && weak_count_ != 0) boost::throw_exception(boost::bad_weak_ptr()); ++use_count_; ++weak_count_; } Test program is like : #include "boost/shared_ptr.hpp" class CTest { public: CTest( ) { } virtual ~CTest( ) { } void dump( ) { // do nothing. } }; typedef boost::shared_ptr< CTest > CTestPtr; CTestPtr ptr1; CTestPtr ptr2; // The class AThread is just a little wrapper around // the "_beginthreadex" function call, // it allows run/cancel/kill on threaded functions. void thfn1( AThread *threadwrapper, void * ) { // Loop until the "threadwrapper" is cancelled. while( !threadwrapper->isCanceled( ) ) { // Dummy work to access // concurrently the smart pointers... ptr1 = CTestPtr( new CTest ); ptr1 = CTestPtr( new CTest ); ptr1 = CTestPtr( new CTest ); CTestPtr p1( ptr1 ); CTestPtr p2( ptr2 ); CTestPtr p3( ptr1 ); CTestPtr p4( ptr1 ); ptr1 = CTestPtr( new CTest ); ptr1 = CTestPtr( new CTest ); ptr1 = CTestPtr( new CTest ); ptr1->dump( ); ::Sleep( rand( ) % 10 ); } } void thfn2( AThread *threadwrapper, void * ) { // Loop until the "threadwrapper" is cancelled. while( !threadwrapper->isCanceled( ) ) { ptr2 = ptr1; ::Sleep( rand( ) % 5 ); ptr2 = CTestPtr( new CTest ); ptr2 = CTestPtr( new CTest ); ptr2 = CTestPtr( new CTest ); CTestPtr p1( ptr2 ); CTestPtr p2( ptr2 ); CTestPtr p3( ptr2 ); CTestPtr p4( ptr2 ); ptr2 = CTestPtr( new CTest ); ptr2 = CTestPtr( new CTest ); ptr2 = CTestPtr( new CTest ); ::Sleep( rand( ) % 15 ); ptr1 = ptr2; } } int main( int argc, char* argv[ ] ) { // You can chage the amount of threads // to throw the exception. const int nThreads = 12; AThread *tab[ nThreads ]; // Create an array of threads. for( int i = 0; i < nThreads; i+=2 ) { tab[ i ] = new AThread( thfn1 ); tab[ i + 1 ] = new AThread( thfn2 ); } // Start all the threads. for( i = 0; i < nThreads; ++i ) { tab[ i ]->run( ); } // Sleep during 5 minutes. ::Sleep( 300000 ); // Ask the threads to cancel. for( i = 0; i < nThreads; ++i ) { tab[ i ]->cancel( ); tab[ i ]->join( ); delete tab[ i ]; } return 0; } I can give you a little project to test it.
Note:
See TracTickets
for help on using tickets.