1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost 4 // Software License, Version 1.0. (See accompanying file 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 // 7 // See http://www.boost.org/libs/interprocess for documentation. 8 // 9 ////////////////////////////////////////////////////////////////////////////// 10 11 #ifndef BOOST_INTERPROCESS_CONDITION_HPP 12 #define BOOST_INTERPROCESS_CONDITION_HPP 13 14 #ifndef BOOST_CONFIG_HPP 15 # include <boost/config.hpp> 16 #endif 17 # 18 #if defined(BOOST_HAS_PRAGMA_ONCE) 19 # pragma once 20 #endif 21 22 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 23 24 #include <boost/interprocess/detail/config_begin.hpp> 25 #include <boost/interprocess/detail/workaround.hpp> 26 27 #include <boost/interprocess/detail/posix_time_types_wrk.hpp> 28 #include <boost/interprocess/sync/interprocess_mutex.hpp> 29 #include <boost/interprocess/sync/detail/locks.hpp> 30 #include <boost/interprocess/exceptions.hpp> 31 #include <boost/limits.hpp> 32 #include <boost/assert.hpp> 33 34 #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined(BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) 35 #include <boost/interprocess/sync/posix/condition.hpp> 36 #define BOOST_INTERPROCESS_USE_POSIX 37 //Experimental... 38 #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS) 39 #include <boost/interprocess/sync/windows/condition.hpp> 40 #define BOOST_INTERPROCESS_USE_WINDOWS 41 #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 42 #include <boost/interprocess/sync/spin/condition.hpp> 43 #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION 44 #endif 45 46 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED 47 48 //!\file 49 //!Describes process-shared variables interprocess_condition class 50 51 namespace boost { 52 53 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 54 55 namespace posix_time 56 { class ptime; } 57 58 #endif //#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 59 60 namespace interprocess { 61 62 class named_condition; 63 64 //!This class is a condition variable that can be placed in shared memory or 65 //!memory mapped files. 66 //!Destroys the object of type std::condition_variable_any 67 //! 68 //!Unlike std::condition_variable in C++11, it is NOT safe to invoke the destructor if all 69 //!threads have been only notified. It is required that they have exited their respective wait 70 //!functions. 71 class interprocess_condition 72 { 73 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 74 //Non-copyable 75 interprocess_condition(const interprocess_condition &); 76 interprocess_condition &operator=(const interprocess_condition &); 77 friend class named_condition; 78 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED 79 80 public: 81 //!Constructs a interprocess_condition. On error throws interprocess_exception. interprocess_condition()82 interprocess_condition() 83 {} 84 85 //!Destroys *this 86 //!liberating system resources. ~interprocess_condition()87 ~interprocess_condition() 88 {} 89 90 //!If there is a thread waiting on *this, change that 91 //!thread's state to ready. Otherwise there is no effect. notify_one()92 void notify_one() 93 { m_condition.notify_one(); } 94 95 //!Change the state of all threads waiting on *this to ready. 96 //!If there are no waiting threads, notify_all() has no effect. notify_all()97 void notify_all() 98 { m_condition.notify_all(); } 99 100 //!Releases the lock on the interprocess_mutex object associated with lock, blocks 101 //!the current thread of execution until readied by a call to 102 //!this->notify_one() or this->notify_all(), and then reacquires the lock. 103 template <typename L> wait(L & lock)104 void wait(L& lock) 105 { 106 ipcdetail::internal_mutex_lock<L> internal_lock(lock); 107 m_condition.wait(internal_lock); 108 } 109 110 //!The same as: 111 //!while (!pred()) wait(lock) 112 template <typename L, typename Pr> wait(L & lock,Pr pred)113 void wait(L& lock, Pr pred) 114 { 115 ipcdetail::internal_mutex_lock<L> internal_lock(lock); 116 m_condition.wait(internal_lock, pred); 117 } 118 119 //!Releases the lock on the interprocess_mutex object associated with lock, blocks 120 //!the current thread of execution until readied by a call to 121 //!this->notify_one() or this->notify_all(), or until time abs_time is reached, 122 //!and then reacquires the lock. 123 //!Returns: false if time abs_time is reached, otherwise true. 124 template <typename L> timed_wait(L & lock,const boost::posix_time::ptime & abs_time)125 bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time) 126 { 127 ipcdetail::internal_mutex_lock<L> internal_lock(lock); 128 return m_condition.timed_wait(internal_lock, abs_time); 129 } 130 131 //!The same as: while (!pred()) { 132 //! if (!timed_wait(lock, abs_time)) return pred(); 133 //! } return true; 134 template <typename L, typename Pr> timed_wait(L & lock,const boost::posix_time::ptime & abs_time,Pr pred)135 bool timed_wait(L& lock, const boost::posix_time::ptime &abs_time, Pr pred) 136 { 137 ipcdetail::internal_mutex_lock<L> internal_lock(lock); 138 return m_condition.timed_wait(internal_lock, abs_time, pred); 139 } 140 141 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 142 143 private: 144 #if defined (BOOST_INTERPROCESS_USE_GENERIC_EMULATION) 145 #undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION 146 ipcdetail::spin_condition m_condition; 147 #elif defined(BOOST_INTERPROCESS_USE_POSIX) 148 #undef BOOST_INTERPROCESS_USE_POSIX 149 ipcdetail::posix_condition m_condition; 150 #elif defined(BOOST_INTERPROCESS_USE_WINDOWS) 151 #undef BOOST_INTERPROCESS_USE_WINDOWS 152 ipcdetail::windows_condition m_condition; 153 #else 154 #error "Unknown platform for interprocess_mutex" 155 #endif 156 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED 157 }; 158 159 } //namespace interprocess 160 } // namespace boost 161 162 #include <boost/interprocess/detail/config_end.hpp> 163 164 #endif // BOOST_INTERPROCESS_CONDITION_HPP 165