|
Boost-Commit : |
From: anthony_at_[hidden]
Date: 2008-06-03 16:56:39
Author: anthonyw
Date: 2008-06-03 16:56:39 EDT (Tue, 03 Jun 2008)
New Revision: 46094
URL: http://svn.boost.org/trac/boost/changeset/46094
Log:
basic_condition_variable::lock_entry extracted to basic_cv_lock_entry in order to try and eliminate problems on Borland compiler
Text files modified:
trunk/boost/thread/win32/condition_variable.hpp | 145 +++++++++++++++++++++++++--------------
1 files changed, 92 insertions(+), 53 deletions(-)
Modified: trunk/boost/thread/win32/condition_variable.hpp
==============================================================================
--- trunk/boost/thread/win32/condition_variable.hpp (original)
+++ trunk/boost/thread/win32/condition_variable.hpp 2008-06-03 16:56:39 EDT (Tue, 03 Jun 2008)
@@ -23,35 +23,96 @@
{
namespace detail
{
+ class basic_cv_list_entry;
+ void intrusive_ptr_add_ref(basic_cv_list_entry * p);
+ void intrusive_ptr_release(basic_cv_list_entry * p);
+
+ class basic_cv_list_entry
+ {
+ private:
+ detail::win32::handle_manager semaphore;
+ detail::win32::handle_manager wake_sem;
+ long waiters;
+ bool notified;
+ long references;
+
+ basic_cv_list_entry(basic_cv_list_entry&);
+ void operator=(basic_cv_list_entry&);
+
+ public:
+ explicit basic_cv_list_entry(detail::win32::handle_manager const& wake_sem_):
+ semaphore(detail::win32::create_anonymous_semaphore(0,LONG_MAX)),
+ wake_sem(wake_sem_.duplicate()),
+ waiters(1),notified(false),references(0)
+ {}
+
+ static bool no_waiters(boost::intrusive_ptr<basic_cv_list_entry> const& entry)
+ {
+ return !detail::interlocked_read_acquire(&entry->waiters);
+ }
+
+ void add_waiter()
+ {
+ BOOST_INTERLOCKED_INCREMENT(&waiters);
+ }
+
+ void remove_waiter()
+ {
+ BOOST_INTERLOCKED_DECREMENT(&waiters);
+ }
+
+ void release(unsigned count_to_release)
+ {
+ notified=true;
+ detail::win32::ReleaseSemaphore(semaphore,count_to_release,0);
+ }
+
+ void release_waiters()
+ {
+ release(detail::interlocked_read_acquire(&waiters));
+ }
+
+ bool is_notified() const
+ {
+ return notified;
+ }
+
+ bool wait(timeout wait_until)
+ {
+ return this_thread::interruptible_wait(semaphore,wait_until);
+ }
+
+ bool woken()
+ {
+ unsigned long const woken_result=detail::win32::WaitForSingleObject(wake_sem,0);
+ BOOST_ASSERT((woken_result==detail::win32::timeout) || (woken_result==0));
+ return woken_result==0;
+ }
+
+ friend void intrusive_ptr_add_ref(basic_cv_list_entry * p);
+ friend void intrusive_ptr_release(basic_cv_list_entry * p);
+ };
+
+ inline void intrusive_ptr_add_ref(basic_cv_list_entry * p)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&p->references);
+ }
+
+ inline void intrusive_ptr_release(basic_cv_list_entry * p)
+ {
+ if(!BOOST_INTERLOCKED_DECREMENT(&p->references))
+ {
+ delete p;
+ }
+ }
+
class basic_condition_variable
{
boost::mutex internal_mutex;
long total_count;
unsigned active_generation_count;
- struct list_entry
- {
- detail::win32::handle_manager semaphore;
- detail::win32::handle_manager wake_sem;
- long waiters;
- bool notified;
- long references;
-
- list_entry():
- semaphore(detail::win32::create_anonymous_semaphore(0,LONG_MAX)),
- wake_sem(0),
- waiters(1),notified(false),references(0)
- {}
-
- void release(unsigned count_to_release)
- {
- notified=true;
- detail::win32::ReleaseSemaphore(semaphore,count_to_release,0);
- }
- };
-
- friend void intrusive_ptr_add_ref(list_entry * p);
- friend void intrusive_ptr_release(list_entry * p);
+ typedef basic_cv_list_entry list_entry;
typedef boost::intrusive_ptr<list_entry> entry_ptr;
typedef std::vector<entry_ptr> generation_list;
@@ -104,16 +165,15 @@
}
detail::interlocked_write_release(&total_count,total_count+1);
- if(generations.empty() || generations.back()->notified)
+ if(generations.empty() || generations.back()->is_notified())
{
- entry_ptr new_entry(new list_entry);
- new_entry->wake_sem=wake_sem.duplicate();
+ entry_ptr new_entry(new list_entry(wake_sem));
generations.push_back(new_entry);
return new_entry;
}
else
{
- BOOST_INTERLOCKED_INCREMENT(&generations.back()->waiters);
+ generations.back()->add_waiter();
return generations.back();
}
}
@@ -128,7 +188,7 @@
~entry_manager()
{
- BOOST_INTERLOCKED_DECREMENT(&entry->waiters);
+ entry->remove_waiter();
}
list_entry* operator->()
@@ -155,15 +215,12 @@
bool woken=false;
while(!woken)
{
- if(!this_thread::interruptible_wait(entry->semaphore,wait_until))
+ if(!entry->wait(wait_until))
{
return false;
}
- unsigned long const woken_result=detail::win32::WaitForSingleObject(entry->wake_sem,0);
- BOOST_ASSERT(woken_result==detail::win32::timeout || woken_result==0);
-
- woken=(woken_result==0);
+ woken=entry->woken();
}
return woken;
}
@@ -182,10 +239,6 @@
basic_condition_variable(const basic_condition_variable& other);
basic_condition_variable& operator=(const basic_condition_variable& other);
- static bool no_waiters(entry_ptr const& entry)
- {
- return !detail::interlocked_read_acquire(&entry->waiters);
- }
public:
basic_condition_variable():
total_count(0),active_generation_count(0),wake_sem(0)
@@ -211,7 +264,7 @@
{
(*it)->release(1);
}
- generations.erase(std::remove_if(generations.begin(),generations.end(),no_waiters),generations.end());
+ generations.erase(std::remove_if(generations.begin(),generations.end(),&basic_cv_list_entry::no_waiters),generations.end());
}
}
@@ -229,7 +282,7 @@
end=generations.end();
it!=end;++it)
{
- (*it)->release(detail::interlocked_read_acquire(&(*it)->waiters));
+ (*it)->release_waiters();
}
generations.clear();
wake_sem=detail::win32::handle(0);
@@ -237,20 +290,6 @@
}
};
- inline void intrusive_ptr_add_ref(basic_condition_variable::list_entry * p)
- {
- BOOST_INTERLOCKED_INCREMENT(&p->references);
- }
-
- inline void intrusive_ptr_release(basic_condition_variable::list_entry * p)
- {
- if(!BOOST_INTERLOCKED_DECREMENT(&p->references))
- {
- delete p;
- }
- }
-
-
}
class condition_variable:
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk