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: 2012-10-10 23:21:24
#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):
Hi,
I don't know how the tool you are using has deduced such an issue.
The count_to_release parameter seems to be always > 0.
Please let me know if I'm missing something.
Either it is called with 1
{{{
for(generation_list::iterator it=generations.begin(),
end=generations.end();
it!=end;++it)
{
(*it)->release(1);
}
}}}
or with the contents of waiters.
{{{
void release_waiters()
{
release(detail::interlocked_read_acquire(&waiters));
}
}}}
This variable is initialized as follows
{{{
waiters(1),notified(false),references(0)
}}}
and updated by
{{{
void add_waiter()
{
BOOST_INTERLOCKED_INCREMENT(&waiters);
}
void remove_waiter()
{
BOOST_INTERLOCKED_DECREMENT(&waiters);
}
}}}
But remove_waiter is always called after add_waiter
{{{
entry_ptr get_wait_entry()
{
boost::lock_guard<boost::mutex>
internal_lock(internal_mutex);
if(!wake_sem)
{
wake_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX);
BOOST_ASSERT(wake_sem);
}
detail::interlocked_write_release(&total_count,total_count+1);
if(generations.empty() ||
generations.back()->is_notified())
{
entry_ptr new_entry(new list_entry(wake_sem));
generations.push_back(new_entry);
return new_entry;
}
else
{
generations.back()->add_waiter();
return generations.back();
}
}
struct entry_manager
{
entry_ptr const entry;
BOOST_THREAD_NO_COPYABLE(entry_manager)
entry_manager(entry_ptr const& entry_):
entry(entry_)
{}
~entry_manager()
{
entry->remove_waiter();
}
list_entry* operator->()
{
return entry.get();
}
};
protected:
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))
{
return false;
}
woken=entry->woken();
}
return woken;
}
}}}
Any deep explanation of on which circumstances this issue appear is
welcome.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/7461#comment:3> 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:10 UTC