From e20299c8ee762da80827eb26b86eebfdf45d30e8 Mon Sep 17 00:00:00 2001 From: Michael Glassford Date: Tue, 13 Jul 2004 14:36:59 +0000 Subject: [PATCH] Add promote() that throws exception if it fails. [SVN r23487] --- src/read_write_mutex.cpp | 91 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 2 deletions(-) diff --git a/src/read_write_mutex.cpp b/src/read_write_mutex.cpp index e0e4485c..d3f040da 100644 --- a/src/read_write_mutex.cpp +++ b/src/read_write_mutex.cpp @@ -442,6 +442,50 @@ bool read_write_mutex_impl::do_timed_demote_to_read_lock(const boost::xti return do_demote_to_read_lock_impl(); } +template +void read_write_mutex_impl::do_promote_to_write_lock() +{ + typename Mutex::scoped_lock l(m_prot); + BOOST_ASSERT(valid_read_lock(m_state)); + + if (m_state == 1) + { + //Convert from read lock to write lock + m_state = -1; + + //Lock promoted + BOOST_ASSERT(valid_write_lock(m_state)); + } + else if (m_state <= 0) + { + //Lock is write-locked or unlocked can't be promoted + throw lock_error(); + } + else if (m_state_waiting_promotion) + { + //Someone else is already trying to promote. Avoid deadlock by throwing exception. + throw lock_error(); + } + else BOOST_ASSERT_ELSE(m_state > 1 && !m_state_waiting_promotion) + { + ++m_num_waiting_writers; + m_state_waiting_promotion = true; + while (m_state > 1) + m_waiting_promotion.wait(l); + m_state_waiting_promotion = false; + --m_num_waiting_writers; + + BOOST_ASSERT(m_num_waiting_writers >= 0); + BOOST_ASSERT(m_state == 1); + + //Convert from read lock to write lock + m_state = -1; + + //Lock promoted + BOOST_ASSERT(valid_write_lock(m_state)); + } +} + template bool read_write_mutex_impl::do_try_promote_to_write_lock() { @@ -641,6 +685,11 @@ void read_write_mutex::do_demote_to_read_lock() m_impl.do_demote_to_read_lock(); } +void read_write_mutex::do_promote_to_write_lock() +{ + m_impl.do_promote_to_write_lock(); +} + bool read_write_mutex::locked() { return m_impl.locked(); @@ -692,6 +741,11 @@ bool try_read_write_mutex::do_try_demote_to_read_lock() return m_impl.do_try_demote_to_read_lock(); } +void try_read_write_mutex::do_promote_to_write_lock() +{ + m_impl.do_promote_to_write_lock(); +} + bool try_read_write_mutex::do_try_promote_to_write_lock() { return m_impl.do_try_promote_to_write_lock(); @@ -763,6 +817,11 @@ bool timed_read_write_mutex::do_timed_demote_to_read_lock(const xtime &xt) return m_impl.do_timed_demote_to_read_lock(xt); } +void timed_read_write_mutex::do_promote_to_write_lock() +{ + m_impl.do_promote_to_write_lock(); +} + bool timed_read_write_mutex::do_try_promote_to_write_lock() { return m_impl.do_try_promote_to_write_lock(); @@ -783,7 +842,7 @@ read_write_lock_state::read_write_lock_state timed_read_write_mutex::state() return m_impl.state(); } -//Explicit instantiations to catch syntax errors in templates +//Explicit instantiations of read/write locks to catch syntax errors in templates template class boost::detail::thread::scoped_read_write_lock; template class boost::detail::thread::scoped_read_write_lock; @@ -796,6 +855,34 @@ template class boost::detail::thread::scoped_try_read_write_lock; //template class boost::detail::thread::scoped_timed_read_write_lock; template class boost::detail::thread::scoped_timed_read_write_lock; + +//Explicit instantiations of read locks to catch syntax errors in templates + +template class boost::detail::thread::scoped_read_lock; +template class boost::detail::thread::scoped_read_lock; +template class boost::detail::thread::scoped_read_lock; + +//template class boost::detail::thread::scoped_try_read_lock; +template class boost::detail::thread::scoped_try_read_lock; +template class boost::detail::thread::scoped_try_read_lock; + +//template class boost::detail::thread::scoped_timed_read_lock; +//template class boost::detail::thread::scoped_timed_read_lock; +template class boost::detail::thread::scoped_timed_read_lock; + +//Explicit instantiations of write locks to catch syntax errors in templates + +template class boost::detail::thread::scoped_write_lock; +template class boost::detail::thread::scoped_write_lock; +template class boost::detail::thread::scoped_write_lock; + +//template class boost::detail::thread::scoped_try_write_lock; +template class boost::detail::thread::scoped_try_write_lock; +template class boost::detail::thread::scoped_try_write_lock; + +//template class boost::detail::thread::scoped_timed_write_lock; +//template class boost::detail::thread::scoped_timed_write_lock; +template class boost::detail::thread::scoped_timed_read_write_lock; } // namespace boost // Change Log: @@ -807,4 +894,4 @@ template class boost::detail::thread::scoped_timed_read_write_lock