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 // Parts of the pthread code come from Boost Threads code. 12 // 13 ////////////////////////////////////////////////////////////////////////////// 14 15 #ifndef BOOST_INTERPROCESS_MUTEX_HPP 16 #define BOOST_INTERPROCESS_MUTEX_HPP 17 18 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 19 20 #ifndef BOOST_CONFIG_HPP 21 # include <boost/config.hpp> 22 #endif 23 # 24 #if defined(BOOST_HAS_PRAGMA_ONCE) 25 # pragma once 26 #endif 27 28 #include <boost/interprocess/detail/config_begin.hpp> 29 #include <boost/interprocess/exceptions.hpp> 30 #include <boost/interprocess/detail/workaround.hpp> 31 #include <boost/interprocess/detail/posix_time_types_wrk.hpp> 32 #include <boost/assert.hpp> 33 #include <boost/interprocess/sync/detail/common_algorithms.hpp> 34 35 36 #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_POSIX_PROCESS_SHARED) 37 #include <boost/interprocess/sync/posix/mutex.hpp> 38 #define BOOST_INTERPROCESS_USE_POSIX 39 //Experimental... 40 #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS) 41 #include <boost/interprocess/sync/windows/mutex.hpp> 42 #define BOOST_INTERPROCESS_USE_WINDOWS 43 #elif !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 44 #include <boost/interprocess/sync/spin/mutex.hpp> 45 #define BOOST_INTERPROCESS_USE_GENERIC_EMULATION 46 47 namespace boost { 48 namespace interprocess { 49 namespace ipcdetail{ 50 namespace robust_emulation_helpers { 51 52 template<class T> 53 class mutex_traits; 54 55 }}}} 56 57 #endif 58 59 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED 60 61 //!\file 62 //!Describes a mutex class that can be placed in memory shared by 63 //!several processes. 64 65 namespace boost { 66 namespace interprocess { 67 68 class interprocess_condition; 69 70 //!Wraps a interprocess_mutex that can be placed in shared memory and can be 71 //!shared between processes. Allows timed lock tries 72 class interprocess_mutex 73 { 74 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) 75 //Non-copyable 76 interprocess_mutex(const interprocess_mutex &); 77 interprocess_mutex &operator=(const interprocess_mutex &); 78 friend class interprocess_condition; 79 80 public: 81 #if defined(BOOST_INTERPROCESS_USE_GENERIC_EMULATION) 82 #undef BOOST_INTERPROCESS_USE_GENERIC_EMULATION 83 typedef ipcdetail::spin_mutex internal_mutex_type; 84 private: 85 friend class ipcdetail::robust_emulation_helpers::mutex_traits<interprocess_mutex>; take_ownership()86 void take_ownership(){ m_mutex.take_ownership(); } 87 public: 88 #elif defined(BOOST_INTERPROCESS_USE_POSIX) 89 #undef BOOST_INTERPROCESS_USE_POSIX 90 typedef ipcdetail::posix_mutex internal_mutex_type; 91 #elif defined(BOOST_INTERPROCESS_USE_WINDOWS) 92 #undef BOOST_INTERPROCESS_USE_WINDOWS 93 typedef ipcdetail::windows_mutex internal_mutex_type; 94 #else 95 #error "Unknown platform for interprocess_mutex" 96 #endif 97 98 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED 99 public: 100 101 //!Constructor. 102 //!Throws interprocess_exception on error. 103 interprocess_mutex(); 104 105 //!Destructor. If any process uses the mutex after the destructor is called 106 //!the result is undefined. Does not throw. 107 ~interprocess_mutex(); 108 109 //!Effects: The calling thread tries to obtain ownership of the mutex, and 110 //! if another thread has ownership of the mutex, it waits until it can 111 //! obtain the ownership. If a thread takes ownership of the mutex the 112 //! mutex must be unlocked by the same mutex. 113 //!Throws: interprocess_exception on error. 114 void lock(); 115 116 //!Effects: The calling thread tries to obtain ownership of the mutex, and 117 //! if another thread has ownership of the mutex returns immediately. 118 //!Returns: If the thread acquires ownership of the mutex, returns true, if 119 //! the another thread has ownership of the mutex, returns false. 120 //!Throws: interprocess_exception on error. 121 bool try_lock(); 122 123 //!Effects: The calling thread will try to obtain exclusive ownership of the 124 //! mutex if it can do so in until the specified time is reached. If the 125 //! mutex supports recursive locking, the mutex must be unlocked the same 126 //! number of times it is locked. 127 //!Returns: If the thread acquires ownership of the mutex, returns true, if 128 //! the timeout expires returns false. 129 //!Throws: interprocess_exception on error. 130 bool timed_lock(const boost::posix_time::ptime &abs_time); 131 132 //!Effects: The calling thread releases the exclusive ownership of the mutex. 133 //!Throws: interprocess_exception on error. 134 void unlock(); 135 136 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) internal_mutex()137 internal_mutex_type &internal_mutex() 138 { return m_mutex; } 139 internal_mutex() const140 const internal_mutex_type &internal_mutex() const 141 { return m_mutex; } 142 143 private: 144 internal_mutex_type m_mutex; 145 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED 146 }; 147 148 } //namespace interprocess { 149 } //namespace boost { 150 151 152 namespace boost { 153 namespace interprocess { 154 interprocess_mutex()155 inline interprocess_mutex::interprocess_mutex(){} 156 ~interprocess_mutex()157 inline interprocess_mutex::~interprocess_mutex(){} 158 lock()159 inline void interprocess_mutex::lock() 160 { ipcdetail::timeout_when_locking_aware_lock(m_mutex); } 161 try_lock()162 inline bool interprocess_mutex::try_lock() 163 { return m_mutex.try_lock(); } 164 timed_lock(const boost::posix_time::ptime & abs_time)165 inline bool interprocess_mutex::timed_lock(const boost::posix_time::ptime &abs_time) 166 { return m_mutex.timed_lock(abs_time); } 167 unlock()168 inline void interprocess_mutex::unlock() 169 { m_mutex.unlock(); } 170 171 } //namespace interprocess { 172 } //namespace boost { 173 174 #include <boost/interprocess/detail/config_end.hpp> 175 176 #endif //BOOST_INTERPROCESS_MUTEX_HPP 177