[Boost-bugs] [ boost-Bugs-1538697 ] Possible problem with condition releasing

Bugs item #1538697, was opened at 2006-08-11 13:32 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=107586&aid=1538697&group_id=7586 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: threads Group: None Status: Open Resolution: None Priority: 5 Submitted By: David Vest (davevest) Assigned to: Mike Glassford (glassfordm) Summary: Possible problem with condition releasing Initial Comment: I think this is a bug but since I have only just started using the threads library it could be a misunderstanding on my part. Since the actual application is quite complex I've created an imaginary scenario that shows the problem. Scenario: A single 'throttle' manager that only lets three threads at a time perform some work. When a thread wants to work it must successfully addRef and when it has finished it releases. Problem: If all available 'slots' are used I am using a condition in the addRef to wait for a release before continuing. Therefore I would expect that after the wait I can successfully assert that a slot is available. However, sometimes this does not appear to be true and I can only assume that sometimes the condition is not working properly. Work around: In CThrottle::release remove the 'unlock' so that the notify_one occurs while the method still has a lock on the m_mutexChangeState. Have I misunderstood how condition is supposed to work? Thanks, Dave. The code: #include <boost\thread\thread.hpp> #include <boost\thread\recursive_mutex.hpp> #include <boost/thread/condition.hpp> #include <boost/shared_ptr.hpp> #include <windows.h> #include <crtdbg.h> #include <vector> class CThrottle { int m_nThrottle; public: CThrottle() : m_nThrottle(0) {} void addRef() { boost::mutex::scoped_lock lockIncrement ( m_mutexIncrement ); boost::recursive_mutex::scoped_lock lockChangeState( m_mutexChangeState ); if ( !isAllowed() ) m_condition.wait( lockChangeState ); _ASSERT( isAllowed() ); // PROBLEM ++m_nThrottle; } void release() { boost::recursive_mutex::scoped_lock lockChangeState( m_mutexChangeState ); --m_nThrottle; lockChangeState.unlock(); m_condition.notify_one(); } bool isAllowed() { boost::recursive_mutex::scoped_lock lockChangeState( m_mutexChangeState ); return m_nThrottle < 3; } private: boost::mutex m_mutexIncrement; boost::recursive_mutex m_mutexChangeState; boost::condition m_condition; }; class CTestThread { public: CTestThread( CThrottle * pThrottle ) : m_pThrottle( pThrottle ) {} void operator()() { m_pThrottle->addRef(); std::cout << "Do something\n"; m_pThrottle->release(); } CThrottle * m_pThrottle; }; typedef boost::shared_ptr<CTestThread> _TestThreadPtr; int main(int argc, _TCHAR* argv[]) { CThrottle * pThrottle = new CThrottle(); boost::thread_group groupThreads; std::vector<_TestThreadPtr> list; for( int n=0; n < 10000; ++n ) { _TestThreadPtr ptrTest( new CTestThread ( pThrottle ) ); groupThreads.create_thread( *ptrTest.get() ); list.push_back( ptrTest ); } groupThreads.join_all(); delete pThrottle; return 0; } ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=107586&aid=1538697&group_id=7586 ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Boost-bugs mailing list Boost-bugs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/boost-bugs
participants (1)
-
SourceForge.net