summaryrefslogtreecommitdiff
path: root/boost/interprocess/sync/shm/named_condition.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/interprocess/sync/shm/named_condition.hpp')
-rw-r--r--boost/interprocess/sync/shm/named_condition.hpp235
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