1 //////////////////////////////////////////////////////////////////////////////
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)
7 // See http://www.boost.org/libs/interprocess for documentation.
9 //////////////////////////////////////////////////////////////////////////////
11 // Parts of the pthread code come from Boost Threads code.
13 //////////////////////////////////////////////////////////////////////////////
15 #ifndef BOOST_INTERPROCESS_MUTEX_HPP
16 #define BOOST_INTERPROCESS_MUTEX_HPP
18 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
20 #ifndef BOOST_CONFIG_HPP
21 # include <boost/config.hpp>
24 #if defined(BOOST_HAS_PRAGMA_ONCE)
28 #include <boost/interprocess/detail/config_begin.hpp>
29 #include <boost/interprocess/exceptions.hpp>
30 #include <boost/interprocess/detail/workaround.hpp>
31 #include <boost/assert.hpp>
32 #include <boost/interprocess/sync/detail/common_algorithms.hpp>
34 #if !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_POSIX_PROCESS_SHARED)
35 #include <boost/interprocess/sync/posix/mutex.hpp>
36 #define BOOST_INTERPROCESS_MUTEX_USE_POSIX
37 #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS)
39 #define BOOST_INTERPROCESS_MUTEX_USE_WINAPI
40 #include <boost/interprocess/sync/windows/mutex.hpp>
43 #include <boost/interprocess/sync/spin/mutex.hpp>
45 namespace interprocess {
47 namespace robust_emulation_helpers {
55 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
58 //!Describes a mutex class that can be placed in memory shared by
62 namespace interprocess {
64 class interprocess_condition;
66 //!Wraps a interprocess_mutex that can be placed in shared memory and can be
67 //!shared between processes. Allows timed lock tries
68 class interprocess_mutex
70 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
72 interprocess_mutex(const interprocess_mutex &);
73 interprocess_mutex &operator=(const interprocess_mutex &);
74 friend class interprocess_condition;
77 #if defined(BOOST_INTERPROCESS_MUTEX_USE_POSIX)
78 typedef ipcdetail::posix_mutex internal_mutex_type;
79 #elif defined(BOOST_INTERPROCESS_MUTEX_USE_WINAPI)
80 typedef ipcdetail::winapi_mutex internal_mutex_type;
82 typedef ipcdetail::spin_mutex internal_mutex_type;
84 friend class ipcdetail::robust_emulation_helpers::mutex_traits<interprocess_mutex>;
85 void take_ownership(){ m_mutex.take_ownership(); }
89 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
93 //!Throws interprocess_exception on error.
96 //!Destructor. If any process uses the mutex after the destructor is called
97 //!the result is undefined. Does not throw.
98 ~interprocess_mutex();
100 //!Requires: The calling thread does not own the mutex.
102 //!Effects: The calling thread tries to obtain ownership of the mutex, and
103 //! if another thread has ownership of the mutex, it waits until it can
104 //! obtain the ownership. If a thread takes ownership of the mutex the
105 //! mutex must be unlocked by the same mutex.
106 //!Throws: interprocess_exception on error.
108 //!Note: A program may deadlock if the thread that has ownership calls
109 //! this function. If the implementation can detect the deadlock,
110 //! an exception could be thrown.
113 //!Requires: The calling thread does not own the mutex.
115 //!Effects: The calling thread tries to obtain ownership of the mutex, and
116 //! if another thread has ownership of the mutex returns immediately.
117 //!Returns: If the thread acquires ownership of the mutex, returns true, if
118 //! the another thread has ownership of the mutex, returns false.
119 //!Throws: interprocess_exception on error.
121 //!Note: A program may deadlock if the thread that has ownership calls
122 //! this function. If the implementation can detect the deadlock,
123 //! an exception could be thrown.
126 //!Requires: The calling thread does not own the mutex.
128 //!Effects: The calling thread will try to obtain exclusive ownership of the
129 //! mutex if it can do so in until the specified time is reached. If the
130 //! mutex supports recursive locking, the mutex must be unlocked the same
131 //! number of times it is locked.
132 //!Returns: If the thread acquires ownership of the mutex, returns true, if
133 //! the timeout expires returns false.
134 //!Throws: interprocess_exception on error.
136 //!Note: A program may deadlock if the thread that has ownership calls
137 //! this function. If the implementation can detect the deadlock,
138 //! an exception could be thrown.
139 template<class TimePoint>
140 bool timed_lock(const TimePoint &abs_time);
142 //!Same as `timed_lock`, but this function is modeled after the
143 //!standard library interface.
144 template<class TimePoint> bool try_lock_until(const TimePoint &abs_time)
145 { return this->timed_lock(abs_time); }
147 //!Same as `timed_lock`, but this function is modeled after the
148 //!standard library interface.
149 template<class Duration> bool try_lock_for(const Duration &dur)
150 { return this->timed_lock(ipcdetail::duration_to_ustime(dur)); }
152 //!Effects: The calling thread releases the exclusive ownership of the mutex.
153 //!Throws: interprocess_exception on error.
156 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
157 internal_mutex_type &internal_mutex()
160 const internal_mutex_type &internal_mutex() const
164 internal_mutex_type m_mutex;
165 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
168 } //namespace interprocess {
169 } //namespace boost {
173 namespace interprocess {
175 inline interprocess_mutex::interprocess_mutex(){}
177 inline interprocess_mutex::~interprocess_mutex(){}
179 inline void interprocess_mutex::lock()
180 { ipcdetail::timeout_when_locking_aware_lock(m_mutex); }
182 inline bool interprocess_mutex::try_lock()
183 { return m_mutex.try_lock(); }
185 template <class TimePoint>
186 inline bool interprocess_mutex::timed_lock(const TimePoint &abs_time)
187 { return m_mutex.timed_lock(abs_time); }
189 inline void interprocess_mutex::unlock()
190 { m_mutex.unlock(); }
192 } //namespace interprocess {
193 } //namespace boost {
195 #include <boost/interprocess/detail/config_end.hpp>
197 #endif //BOOST_INTERPROCESS_MUTEX_HPP