diff options
Diffstat (limited to 'boost/interprocess/sync/shm/named_condition.hpp')
-rw-r--r-- | boost/interprocess/sync/shm/named_condition.hpp | 235 |
1 files changed, 44 insertions, 191 deletions
diff --git a/boost/interprocess/sync/shm/named_condition.hpp b/boost/interprocess/sync/shm/named_condition.hpp index 9d7cd77e11..e2ff280b7b 100644 --- a/boost/interprocess/sync/shm/named_condition.hpp +++ b/boost/interprocess/sync/shm/named_condition.hpp @@ -1,6 +1,6 @@ ////////////////////////////////////////////////////////////////////////////// // -// (C) Copyright Ion Gaztanaga 2005-2011. Distributed under the Boost +// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // @@ -11,7 +11,7 @@ #ifndef BOOST_INTERPROCESS_SHM_NAMED_CONDITION_HPP #define BOOST_INTERPROCESS_SHM_NAMED_CONDITION_HPP -#if (defined _MSC_VER) && (_MSC_VER >= 1200) +#if defined(_MSC_VER) # pragma once #endif @@ -29,8 +29,11 @@ #include <boost/interprocess/sync/named_mutex.hpp> #include <boost/interprocess/permissions.hpp> #if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) -#include <boost/interprocess/sync/interprocess_mutex.hpp> -#include <boost/interprocess/sync/scoped_lock.hpp> + #include <boost/interprocess/sync/interprocess_mutex.hpp> + #include <boost/interprocess/sync/scoped_lock.hpp> + #include <boost/interprocess/sync/detail/condition_any_algorithm.hpp> +#else + #include <boost/interprocess/sync/detail/locks.hpp> #endif @@ -41,21 +44,21 @@ namespace boost { namespace interprocess { namespace ipcdetail { -/// @cond +#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) class interprocess_tester; -/// @endcond +#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED //! A global condition variable that can be created by name. //! This condition variable is designed to work with named_mutex and //! can't be placed in shared memory or memory mapped files. class shm_named_condition { - /// @cond + #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) //Non-copyable shm_named_condition(); shm_named_condition(const shm_named_condition &); shm_named_condition &operator=(const shm_named_condition &); - /// @endcond + #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED public: //!Creates a global condition with a name. //!If the condition can't be created throws interprocess_exception @@ -119,113 +122,44 @@ class shm_named_condition //!Returns false on error. Never throws. static bool remove(const char *name); - /// @cond + #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) private: - struct condition_holder + #if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) + class internal_condition_members { - interprocess_condition cond_; - //If named_mutex is implemented using semaphores - //we need to store an additional mutex - #if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) - interprocess_mutex mutex_; - #endif - }; + public: + typedef interprocess_mutex mutex_type; + typedef interprocess_condition condvar_type; - interprocess_condition *condition() const - { return &static_cast<condition_holder*>(m_shmem.get_user_address())->cond_; } + condvar_type& get_condvar() { return m_cond; } + mutex_type& get_mutex() { return m_mtx; } - template <class Lock> - class lock_inverter - { - Lock &l_; - public: - lock_inverter(Lock &l) - : l_(l) - {} - void lock() { l_.unlock(); } - void unlock() { l_.lock(); } + private: + mutex_type m_mtx; + condvar_type m_cond; }; - //If named mutex uses POSIX semaphores, then the shm based condition variable - //must use it's internal lock to wait, as sem_t does not store a pthread_mutex_t - //instance needed by pthread_mutex_cond_t - #if defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) - interprocess_mutex *mutex() const - { return &static_cast<condition_holder*>(m_shmem.get_user_address())->mutex_; } - - template <class Lock> - void do_wait(Lock& lock) - { - //shm_named_condition only works with named_mutex - BOOST_STATIC_ASSERT((is_convertible<typename Lock::mutex_type&, named_mutex&>::value == true)); - - //lock internal before unlocking external to avoid race with a notifier - scoped_lock<interprocess_mutex> internal_lock(*this->mutex()); - lock_inverter<Lock> inverted_lock(lock); - scoped_lock<lock_inverter<Lock> > external_unlock(inverted_lock); - - //unlock internal first to avoid deadlock with near simultaneous waits - scoped_lock<interprocess_mutex> internal_unlock; - internal_lock.swap(internal_unlock); - this->condition()->wait(internal_unlock); - } - - template <class Lock> - bool do_timed_wait(Lock& lock, const boost::posix_time::ptime &abs_time) - { - //shm_named_condition only works with named_mutex - BOOST_STATIC_ASSERT((is_convertible<typename Lock::mutex_type&, named_mutex&>::value == true)); - //lock internal before unlocking external to avoid race with a notifier - scoped_lock<interprocess_mutex> internal_lock(*this->mutex(), abs_time); - if(!internal_lock) return false; - lock_inverter<Lock> inverted_lock(lock); - scoped_lock<lock_inverter<Lock> > external_unlock(inverted_lock); - - //unlock internal first to avoid deadlock with near simultaneous waits - scoped_lock<interprocess_mutex> internal_unlock; - internal_lock.swap(internal_unlock); - return this->condition()->timed_wait(internal_unlock, abs_time); - } - #else //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) - template<class Lock> - class lock_wrapper - { - typedef void (lock_wrapper::*unspecified_bool_type)(); - public: - - typedef interprocess_mutex mutex_type; - - lock_wrapper(Lock &l) - : l_(l) - {} - - mutex_type* mutex() const - { return l_.mutex()->mutex(); } - - void lock() { l_.lock(); } - - void unlock() { l_.unlock(); } - - operator unspecified_bool_type() const - { return l_ ? &lock_wrapper::lock : 0; } - - private: - Lock &l_; - }; + typedef ipcdetail::condition_any_wrapper<internal_condition_members> internal_condition; + #else //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) + typedef interprocess_condition internal_condition; #endif //defined (BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) + internal_condition &internal_cond() + { return *static_cast<internal_condition*>(m_shmem.get_user_address()); } + friend class boost::interprocess::ipcdetail::interprocess_tester; void dont_close_on_destruction(); - managed_open_or_create_impl<shared_memory_object> m_shmem; + typedef ipcdetail::managed_open_or_create_impl<shared_memory_object, 0, true, false> open_create_impl_t; + open_create_impl_t m_shmem; template <class T, class Arg> friend class boost::interprocess::ipcdetail::named_creation_functor; - typedef boost::interprocess::ipcdetail::named_creation_functor<condition_holder> construct_func_t; - /// @endcond + typedef boost::interprocess::ipcdetail::named_creation_functor<internal_condition> construct_func_t; + #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED }; -/// @cond +#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) inline shm_named_condition::~shm_named_condition() {} @@ -233,9 +167,8 @@ inline shm_named_condition::~shm_named_condition() inline shm_named_condition::shm_named_condition(create_only_t, const char *name, const permissions &perm) : m_shmem (create_only ,name - ,sizeof(condition_holder) + - managed_open_or_create_impl<shared_memory_object>:: - ManagedOpenOrCreateUserOffset + ,sizeof(internal_condition) + + open_create_impl_t::ManagedOpenOrCreateUserOffset ,read_write ,0 ,construct_func_t(DoCreate) @@ -245,9 +178,8 @@ inline shm_named_condition::shm_named_condition(create_only_t, const char *name, inline shm_named_condition::shm_named_condition(open_or_create_t, const char *name, const permissions &perm) : m_shmem (open_or_create ,name - ,sizeof(condition_holder) + - managed_open_or_create_impl<shared_memory_object>:: - ManagedOpenOrCreateUserOffset + ,sizeof(internal_condition) + + open_create_impl_t::ManagedOpenOrCreateUserOffset ,read_write ,0 ,construct_func_t(DoOpenOrCreate) @@ -265,113 +197,34 @@ inline shm_named_condition::shm_named_condition(open_only_t, const char *name) inline void shm_named_condition::dont_close_on_destruction() { interprocess_tester::dont_close_on_destruction(m_shmem); } -#if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) - inline void shm_named_condition::notify_one() -{ - scoped_lock<interprocess_mutex> internal_lock(*this->mutex()); - this->condition()->notify_one(); -} +{ this->internal_cond().notify_one(); } inline void shm_named_condition::notify_all() -{ - scoped_lock<interprocess_mutex> internal_lock(*this->mutex()); - this->condition()->notify_all(); -} +{ this->internal_cond().notify_all(); } template <typename L> inline void shm_named_condition::wait(L& lock) -{ - if (!lock) - throw lock_exception(); - this->do_wait(lock); -} +{ this->internal_cond().wait(lock); } template <typename L, typename Pr> inline void shm_named_condition::wait(L& lock, Pr pred) -{ - if (!lock) - throw lock_exception(); - while (!pred()) - this->do_wait(lock); -} +{ this->internal_cond().wait(lock, pred); } template <typename L> inline bool shm_named_condition::timed_wait (L& lock, const boost::posix_time::ptime &abs_time) -{ - if(abs_time == boost::posix_time::pos_infin){ - this->wait(lock); - return true; - } - if (!lock) - throw lock_exception(); - return this->do_timed_wait(lock, abs_time); -} +{ return this->internal_cond().timed_wait(lock, abs_time); } template <typename L, typename Pr> inline bool shm_named_condition::timed_wait (L& lock, const boost::posix_time::ptime &abs_time, Pr pred) -{ - if(abs_time == boost::posix_time::pos_infin){ - this->wait(lock, pred); - return true; - } - if (!lock) - throw lock_exception(); - - while (!pred()){ - if(!this->do_timed_wait(lock, abs_time)){ - return pred(); - } - } - return true; -} - -#else - -inline void shm_named_condition::notify_one() -{ this->condition()->notify_one(); } - -inline void shm_named_condition::notify_all() -{ this->condition()->notify_all(); } - -template <typename L> -inline void shm_named_condition::wait(L& lock) -{ - lock_wrapper<L> newlock(lock); - this->condition()->wait(newlock); -} - -template <typename L, typename Pr> -inline void shm_named_condition::wait(L& lock, Pr pred) -{ - lock_wrapper<L> newlock(lock); - this->condition()->wait(newlock, pred); -} - -template <typename L> -inline bool shm_named_condition::timed_wait - (L& lock, const boost::posix_time::ptime &abs_time) -{ - lock_wrapper<L> newlock(lock); - return this->condition()->timed_wait(newlock, abs_time); -} - -template <typename L, typename Pr> -inline bool shm_named_condition::timed_wait - (L& lock, const boost::posix_time::ptime &abs_time, Pr pred) -{ - lock_wrapper<L> newlock(lock); - return this->condition()->timed_wait(newlock, abs_time, pred); -} - -#endif +{ return this->internal_cond().timed_wait(lock, abs_time, pred); } inline bool shm_named_condition::remove(const char *name) { return shared_memory_object::remove(name); } -/// @endcond +#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED } //namespace ipcdetail } //namespace interprocess |