Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / interprocess / sync / shm / named_condition.hpp
index 9d7cd77..e2ff280 100644 (file)
@@ -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
 
 #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