diff --git a/include/boost/thread/tss.hpp b/include/boost/thread/tss.hpp index 769b0449..d6afe879 100644 --- a/include/boost/thread/tss.hpp +++ b/include/boost/thread/tss.hpp @@ -53,7 +53,7 @@ public: void cleanup(void* p); private: - int m_slot; + unsigned int m_slot; void init(boost::function1* pcleanup); }; @@ -78,9 +78,16 @@ class thread_specific_ptr : private noncopyable { public: thread_specific_ptr() - : m_tss(new(std::nothrow) boost::function1(boost::detail::tss_adapter(&thread_specific_ptr::cleanup))) { } + : m_tss(new boost::function1( + boost::detail::tss_adapter( + &thread_specific_ptr::cleanup))) + { + } thread_specific_ptr(void (*clean)(T*)) - : m_tss(new(std::nothrow) boost::function1(boost::detail::tss_adapter(clean))) { } + : m_tss(new boost::function1( + boost::detail::tss_adapter(clean))) + { + } ~thread_specific_ptr() { reset(); } T* get() const { return static_cast(m_tss.get()); } diff --git a/src/rw_mutex.cpp b/src/rw_mutex.cpp index 261b8ec1..0156191d 100644 --- a/src/rw_mutex.cpp +++ b/src/rw_mutex.cpp @@ -4,20 +4,20 @@ // // Notes: // -// This implementation is based on ACE's rw_lock_t implementation, with the added -// functionality of supporting different Scheduling Policies. +// This implementation is based on ACE's rw_lock_t implementation, with the +// added functionality of supporting different Scheduling Policies. // // The underlying implementation is shared by rw_mutex, try_rw_mutex, and // timed_rw_mutex. // -// The basic implementation strategy involves a mutex, m_prot which is locked during -// ANY rw_mutex operation, locking or unlocking. m_prot protects the invariants -// of the implementation. +// The basic implementation strategy involves a mutex, m_prot which is locked +// during ANY rw_mutex operation, locking or unlocking. m_prot protects the +// invariants of the implementation. // // The variable m_state takes the following values: // -1 - Exclusive locked // 0 - Unlocked -// 1 -> INT_MAX, shared locked, m_state == # of shared locks. +// 1 -> INT_MAX - shared locked, m_state == # of shared locks. // // Should a thread need to block for a shared or exclusive lock, two // member condition variables, m_waiting_readers and m_waiting_writers @@ -28,56 +28,56 @@ // m_num_waiting_readers and m_num_waiting_writers. // // -// This particular implementation cannot prevent self-deadlock w/o adding some means -// of identifying the thread(s) holding locks. +// This particular implementation cannot prevent self-deadlock w/o adding some +// means of identifying the thread(s) holding locks. -// A recursive_try_mutex used "under the hood" could be used to detect and prevent -// exclusive->exclusive self-deadlock since only the same thread would be able to -// obtain a second lock on this recursive mutex.... -/* -// for example, if rw_mutex_impl has an additional member: +// A recursive_try_mutex used "under the hood" could be used to detect and +// prevent exclusive->exclusive self-deadlock since only the same thread +// would be able to obtain a second lock on this recursive mutex.... // +// for example, if rw_mutex_impl has an additional member: +/* // struct rw_mutex_impl { // // ... // recursive_try_mutex m_self_detect; // } -// + template void rw_mutex_impl:: do_wrlock() { - // Lock our exclusive access. This protects internal state - Mutex::scoped_lock l(m_prot); +// Lock our exclusive access. This protects internal state +Mutex::scoped_lock l(m_prot); - if(m_state == -1) - { - recursive_try_mutex sl(m_self_detect); - if(sl.locked()) - { - // It is us that already held the lock! +if(m_state == -1) +{ + recursive_try_mutex sl(m_self_detect); + if(sl.locked()) + { + // It is us that already held the lock! - // Do something to hold the m_self_detect lock - // and bail out - } - else - { - // It is someone else. fall back to normal waiting. - } - } + // Do something to hold the m_self_detect lock + // and bail out + } + else + { + // It is someone else. fall back to normal waiting. + } +} - // Wait until no exclusive lock is held. - // - // Note: Scheduling priorities are enforced in the unlock() - // call. unlock will wake the proper thread. - while(m_state != 0) - { - m_num_waiting_writers++; - m_waiting_writers.wait(l); - m_num_waiting_writers--; - } - m_state = -1; +// Wait until no exclusive lock is held. +// +// Note: Scheduling priorities are enforced in the unlock() +// call. unlock will wake the proper thread. +while(m_state != 0) +{ + m_num_waiting_writers++; + m_waiting_writers.wait(l); + m_num_waiting_writers--; +} +m_state = -1; } @@ -92,16 +92,10 @@ do_wrlock() #include namespace boost { - namespace detail { namespace thread { - - - - +namespace detail { namespace thread { template -void -rw_mutex_impl:: -do_rdlock() +void rw_mutex_impl::do_rdlock() { // Lock our exclusive access. This protects internal state typename Mutex::scoped_lock l(m_prot); @@ -121,12 +115,8 @@ do_rdlock() m_state++; } - - template -void -rw_mutex_impl:: -do_wrlock() +void rw_mutex_impl::do_wrlock() { // Lock our exclusive access. This protects internal state typename Mutex::scoped_lock l(m_prot); @@ -144,13 +134,8 @@ do_wrlock() m_state = -1; } - - - template -bool -rw_mutex_impl:: -do_try_rdlock() +bool rw_mutex_impl::do_try_rdlock() { bool ret; // Lock our exclusive access. This protects internal state @@ -200,53 +185,44 @@ do_try_rdlock() return ret; } - /* - * * try_promote_rdlock - not yet in production.... * - * - * -template -bool -rw_mutex_impl:: -do_try_promote_rdlock() -{ - RWMutexImpl::scoped_lock l(m_prot); + template + bool rw_mutex_impl::do_try_promote_rdlock() + { + RWMutexImpl::scoped_lock l(m_prot); - if(m_state == -1) - { - // promoting a write-locked to a read lock is a serious error. - throw lock_error(); - } - else if(m_num_waiting_promotion > 0) - { - // Someone else is already trying to upgrade. Avoid deadlock by - // returning false. - return false; - } - else - { - while(m_state > 1) // While there are other readers - { - m_num_waiting_writers++; - m_num_waiting_promotion = 1; - m_waiting_promotion.wait(l); - m_num_waiting_promotion = 0; - m_num_waiting_writers--; - } - // We got the exclusive lock! - m_state == -1; - } -} + if(m_state == -1) + { + // promoting a write-locked to a read lock is a serious error. + throw lock_error(); + } + else if(m_num_waiting_promotion > 0) + { + // Someone else is already trying to upgrade. Avoid deadlock by + // returning false. + return false; + } + else + { + while(m_state > 1) // While there are other readers + { + m_num_waiting_writers++; + m_num_waiting_promotion = 1; + m_waiting_promotion.wait(l); + m_num_waiting_promotion = 0; + m_num_waiting_writers--; + } + // We got the exclusive lock! + m_state == -1; + } + } */ - template -bool -rw_mutex_impl:: -do_try_wrlock() +bool rw_mutex_impl::do_try_wrlock() { bool ret; @@ -269,16 +245,10 @@ do_try_wrlock() return ret; } - - - - template -bool -rw_mutex_impl:: -do_timed_rdlock(const boost::xtime &xt) +bool rw_mutex_impl::do_timed_rdlock(const boost::xtime &xt) { - // Lock our exclusive access. This protects internal state + // Lock our exclusive access. This protects internal state typename Mutex::scoped_timed_lock l(m_prot,xt); if(!l.locked()) return false; @@ -304,14 +274,8 @@ do_timed_rdlock(const boost::xtime &xt) return true; } - - - - template -bool -rw_mutex_impl:: -do_timed_wrlock(const boost::xtime &xt) +bool rw_mutex_impl::do_timed_wrlock(const boost::xtime &xt) { typename Mutex::scoped_timed_lock l(m_prot,xt); @@ -335,12 +299,9 @@ do_timed_wrlock(const boost::xtime &xt) m_state = -1; return true; } - template -void -rw_mutex_impl:: -do_rdunlock() +void rw_mutex_impl::do_rdunlock() { // Protect internal state. typename Mutex::scoped_lock l(m_prot); @@ -360,11 +321,8 @@ do_rdunlock() } } - template -void -rw_mutex_impl:: -do_wakeups() +void rw_mutex_impl::do_wakeups() { if( m_num_waiting_writers > 0 && m_num_waiting_readers > 0) @@ -413,11 +371,8 @@ do_wakeups() } } - template -void -rw_mutex_impl:: -do_wrunlock() +void rw_mutex_impl::do_wrunlock() { // Protect internal state. typename Mutex::scoped_lock l(m_prot); @@ -432,168 +387,99 @@ do_wrunlock() do_wakeups(); } - - } // namespace thread } // namespace detail - - - - -void -rw_mutex:: -do_rdlock() +void rw_mutex::do_rdlock() { m_impl.do_rdlock(); } - -void -rw_mutex:: -do_wrlock() +void rw_mutex::do_wrlock() { m_impl.do_wrlock(); } - -void -rw_mutex:: -do_rdunlock() +void rw_mutex::do_rdunlock() { m_impl.do_rdunlock(); } -void -rw_mutex:: -do_wrunlock() +void rw_mutex::do_wrunlock() { m_impl.do_wrunlock(); } -void -try_rw_mutex:: -do_rdlock() +void try_rw_mutex::do_rdlock() { m_impl.do_rdlock(); } - - - -void -try_rw_mutex:: -do_wrlock() +void try_rw_mutex::do_wrlock() { m_impl.do_wrlock(); } - -void -try_rw_mutex:: -do_wrunlock() +void try_rw_mutex::do_wrunlock() { m_impl.do_wrunlock(); } -void -try_rw_mutex:: -do_rdunlock() +void try_rw_mutex::do_rdunlock() { m_impl.do_rdunlock(); } -bool -try_rw_mutex:: -do_try_rdlock() +bool try_rw_mutex::do_try_rdlock() { return m_impl.do_try_rdlock(); } -bool -try_rw_mutex:: -do_try_wrlock() +bool try_rw_mutex::do_try_wrlock() { return m_impl.do_try_wrlock(); } - - - - - - -void -timed_rw_mutex:: -do_rdlock() +void timed_rw_mutex::do_rdlock() { m_impl.do_rdlock(); } - - - -void -timed_rw_mutex:: -do_wrlock() +void timed_rw_mutex::do_wrlock() { m_impl.do_wrlock(); } - - -void -timed_rw_mutex:: -do_rdunlock() +void timed_rw_mutex::do_rdunlock() { m_impl.do_rdunlock(); } -void -timed_rw_mutex:: -do_wrunlock() +void timed_rw_mutex::do_wrunlock() { m_impl.do_wrunlock(); } - - -bool -timed_rw_mutex:: -do_try_rdlock() +bool timed_rw_mutex::do_try_rdlock() { return m_impl.do_try_rdlock(); } - -bool -timed_rw_mutex:: -do_try_wrlock() +bool timed_rw_mutex::do_try_wrlock() { return m_impl.do_try_wrlock(); } - - -bool -timed_rw_mutex:: -do_timed_rdlock(const xtime &xt) +bool timed_rw_mutex::do_timed_rdlock(const xtime &xt) { return m_impl.do_timed_rdlock(xt); } - -bool -timed_rw_mutex:: -do_timed_wrlock(const xtime &xt) +bool timed_rw_mutex::do_timed_wrlock(const xtime &xt) { return m_impl.do_timed_wrlock(xt); } - - - - -} // namespace boost \ No newline at end of file +} // namespace boost diff --git a/src/thread.cpp b/src/thread.cpp index 1e07bfa3..6985b6bb 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -688,7 +688,7 @@ thread::thread(const thread& other) thread::~thread() { if (m_handle && static_cast(m_handle)->release()) - delete m_handle; + delete static_cast(m_handle); } thread& thread::operator=(const thread& other)