Subject: Re: [Boost-bugs] [Boost C++ Libraries] #7461: detail::win32::ReleaseSemaphore may be called with count_to_release equal to 0
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-09-15 16:12:30
#7461: detail::win32::ReleaseSemaphore may be called with count_to_release equal
to 0
---------------------------------------------+----------------------
Reporter: Jesper Storm Bache <jsbache@â¦> | Owner: viboes
Type: Bugs | Status: assigned
Milestone: To Be Determined | Component: thread
Version: Boost 1.51.0 | Severity: Problem
Resolution: | Keywords:
---------------------------------------------+----------------------
Comment (by viboes):
I suspect that the following sequence is possible.
1. thread A call wait and it stands in [1] below. The value for waiters is
1.
2. thread B notify_all and after wake the waiters in [2] the scheduler
choose the ready thread A.
3. thread A ends the call to do_wait and the entry_manager destructor
calls. The value for waiters is 0. in [3] the scheduler choose the ready
thread B.
4. thread B calls release_waiters() in [4] which calls to release(0).
Current Code
{{{
template<typename lock_type>
bool do_wait(lock_type& lock,timeout abs_time)
{
relocker<lock_type> locker(lock);
entry_manager entry(get_wait_entry());
locker.unlock();
bool woken=false;
while(!woken)
{
if(!entry->wait(abs_time)) // [1]
{
return false;
}
woken=entry->woken();
}
return woken;
} // [3]
void notify_all() BOOST_NOEXCEPT
{
if(detail::interlocked_read_acquire(&total_count))
{
boost::lock_guard<boost::mutex>
internal_lock(internal_mutex);
if(!total_count)
{
return;
}
wake_waiters(total_count); // [2]
for(generation_list::iterator it=generations.begin(),
end=generations.end();
it!=end;++it)
{
(*it)->release_waiters(); [4]
}
generations.clear();
wake_sem=detail::win32::handle(0);
}
}
}}}
I suspect that the call to entry->remove_waiter() inside entry_manager()
must be protected
Could some one check if the following patch for
boost/thread/win32/condition_variable.hpp works
{{{
===================================================================
--- condition_variable.hpp (revision 85663)
+++ condition_variable.hpp (working copy)
@@ -191,18 +191,17 @@
struct entry_manager
{
entry_ptr const entry;
+ boost::mutex& internal_mutex;
BOOST_THREAD_NO_COPYABLE(entry_manager)
- entry_manager(entry_ptr const& entry_):
- entry(entry_)
+ entry_manager(entry_ptr const& entry_, boost::mutex&
mutex_):
+ entry(entry_), internal_mutex(mutex_)
{}
~entry_manager()
{
- //if(! entry->is_notified()) // several regression
#7657
- {
+ boost::lock_guard<boost::mutex>
internal_lock(internal_mutex);
entry->remove_waiter();
- }
}
list_entry* operator->()
@@ -218,7 +217,7 @@
{
relocker<lock_type> locker(lock);
- entry_manager entry(get_wait_entry());
+ entry_manager entry(get_wait_entry(), internal_mutex);
locker.unlock();
}}}
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/7461#comment:16> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:14 UTC