$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: SourceForge.net (noreply_at_[hidden])
Date: 2006-08-11 09:32:27
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_at_[hidden]
https://lists.sourceforge.net/lists/listinfo/boost-bugs