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_NAMED_MUTEX_HPP |
12 | #define BOOST_INTERPROCESS_NAMED_MUTEX_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 | #include <boost/interprocess/detail/config_begin.hpp> |
23 | #include <boost/interprocess/detail/workaround.hpp> |
24 | #include <boost/interprocess/creation_tags.hpp> |
25 | #include <boost/interprocess/exceptions.hpp> |
26 | #include <boost/interprocess/timed_utils.hpp> |
27 | #include <boost/interprocess/detail/interprocess_tester.hpp> |
28 | #include <boost/interprocess/permissions.hpp> |
29 | |
30 | #if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USES_POSIX_SEMAPHORES) |
31 | #include <boost/interprocess/sync/posix/named_mutex.hpp> |
32 | #define BOOST_INTERPROCESS_NAMED_MUTEX_USE_POSIX |
33 | #elif !defined(BOOST_INTERPROCESS_FORCE_GENERIC_EMULATION) && defined (BOOST_INTERPROCESS_WINDOWS) |
34 | #include <boost/interprocess/sync/windows/named_mutex.hpp> |
35 | #define BOOST_INTERPROCESS_NAMED_MUTEX_USE_WINAPI |
36 | #else |
37 | #include <boost/interprocess/sync/shm/named_mutex.hpp> |
38 | #endif |
39 | |
40 | //!\file |
41 | //!Describes a named mutex class for inter-process synchronization |
42 | |
43 | namespace boost { |
44 | namespace interprocess { |
45 | |
46 | class named_condition; |
47 | |
48 | //!A mutex with a global name, so it can be found from different |
49 | //!processes. This mutex can't be placed in shared memory, and |
50 | //!each process should have it's own named_mutex. |
51 | class named_mutex |
52 | { |
53 | #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
54 | |
55 | //Non-copyable |
56 | named_mutex(); |
57 | named_mutex(const named_mutex &); |
58 | named_mutex &operator=(const named_mutex &); |
59 | friend class named_condition; |
60 | #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
61 | |
62 | public: |
63 | //!Creates a global mutex with a name. |
64 | //!Throws interprocess_exception on error. |
65 | named_mutex(create_only_t, const char *name, const permissions &perm = permissions()); |
66 | |
67 | //!Opens or creates a global mutex with a name. |
68 | //!If the mutex is created, this call is equivalent to |
69 | //!named_mutex(create_only_t, ... ) |
70 | //!If the mutex is already created, this call is equivalent |
71 | //!named_mutex(open_only_t, ... ) |
72 | //!Does not throw |
73 | named_mutex(open_or_create_t, const char *name, const permissions &perm = permissions()); |
74 | |
75 | //!Opens a global mutex with a name if that mutex is previously |
76 | //!created. If it is not previously created this function throws |
77 | //!interprocess_exception. |
78 | named_mutex(open_only_t, const char *name); |
79 | |
80 | #if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
81 | |
82 | //!Creates a global mutex with a name. |
83 | //!Throws interprocess_exception on error. |
84 | //! |
85 | //!Note: This function is only available on operating systems with |
86 | //! native wchar_t APIs (e.g. Windows). |
87 | named_mutex(create_only_t, const wchar_t *name, const permissions &perm = permissions()); |
88 | |
89 | //!Opens or creates a global mutex with a name. |
90 | //!If the mutex is created, this call is equivalent to |
91 | //!named_mutex(create_only_t, ... ) |
92 | //!If the mutex is already created, this call is equivalent |
93 | //!named_mutex(open_only_t, ... ) |
94 | //!Does not throw |
95 | //! |
96 | //!Note: This function is only available on operating systems with |
97 | //! native wchar_t APIs (e.g. Windows). |
98 | named_mutex(open_or_create_t, const wchar_t *name, const permissions &perm = permissions()); |
99 | |
100 | //!Opens a global mutex with a name if that mutex is previously |
101 | //!created. If it is not previously created this function throws |
102 | //!interprocess_exception. |
103 | //! |
104 | //!Note: This function is only available on operating systems with |
105 | //! native wchar_t APIs (e.g. Windows). |
106 | named_mutex(open_only_t, const wchar_t *name); |
107 | |
108 | #endif //defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
109 | |
110 | //!Destroys *this and indicates that the calling process is finished using |
111 | //!the resource. The destructor function will deallocate |
112 | //!any system resources allocated by the system for use by this process for |
113 | //!this resource. The resource can still be opened again calling |
114 | //!the open constructor overload. To erase the resource from the system |
115 | //!use remove(). |
116 | ~named_mutex(); |
117 | |
118 | //!Unlocks a previously locked |
119 | //!mutex. |
120 | void unlock(); |
121 | |
122 | //!Requires: The calling thread does not own the mutex. |
123 | //! |
124 | //!Locks the mutex, sleeps when the mutex is already locked. |
125 | //!Throws interprocess_exception if a severe error is found |
126 | //! |
127 | //!Note: A program may deadlock if the thread that has ownership calls |
128 | //! this function. If the implementation can detect the deadlock, |
129 | //! an exception could be thrown. |
130 | void lock(); |
131 | |
132 | //!Requires: The calling thread does not own the mutex. |
133 | //! |
134 | //!Tries to lock the mutex, returns false when the mutex |
135 | //!is already locked, returns true when success. |
136 | //!Throws interprocess_exception if a severe error is found |
137 | //! |
138 | //!Note: A program may deadlock if the thread that has ownership calls |
139 | //! this function. If the implementation can detect the deadlock, |
140 | //! an exception could be thrown. |
141 | bool try_lock(); |
142 | |
143 | //!Requires: The calling thread does not own the mutex. |
144 | //! |
145 | //!Tries to lock the the mutex until time abs_time, |
146 | //!Returns false when timeout expires, returns true when locks. |
147 | //!Throws interprocess_exception if a severe error is found |
148 | //! |
149 | //!Note: A program may deadlock if the thread that has ownership calls |
150 | //! this function. If the implementation can detect the deadlock, |
151 | //! an exception could be thrown. |
152 | template<class TimePoint> |
153 | bool timed_lock(const TimePoint &abs_time); |
154 | |
155 | //!Same as `timed_lock`, but this function is modeled after the |
156 | //!standard library interface. |
157 | template<class TimePoint> bool try_lock_until(const TimePoint &abs_time) |
158 | { return this->timed_lock(abs_time); } |
159 | |
160 | //!Same as `timed_lock`, but this function is modeled after the |
161 | //!standard library interface. |
162 | template<class Duration> bool try_lock_for(const Duration &dur) |
163 | { return this->timed_lock(ipcdetail::duration_to_ustime(dur)); } |
164 | |
165 | //!Erases a named mutex from the system. |
166 | //!Returns false on error. Never throws. |
167 | static bool remove(const char *name); |
168 | |
169 | #if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
170 | |
171 | //!Erases a named mutex from the system. |
172 | //!Returns false on error. Never throws. |
173 | //! |
174 | //!Note: This function is only available on operating systems with |
175 | //! native wchar_t APIs (e.g. Windows). |
176 | static bool remove(const wchar_t *name); |
177 | |
178 | #endif //defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
179 | |
180 | #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
181 | private: |
182 | friend class ipcdetail::interprocess_tester; |
183 | void dont_close_on_destruction(); |
184 | |
185 | public: |
186 | #if defined(BOOST_INTERPROCESS_NAMED_MUTEX_USE_POSIX) |
187 | typedef ipcdetail::posix_named_mutex internal_mutex_type; |
188 | #elif defined(BOOST_INTERPROCESS_NAMED_MUTEX_USE_WINAPI) |
189 | typedef ipcdetail::winapi_named_mutex internal_mutex_type; |
190 | #else |
191 | typedef ipcdetail::shm_named_mutex internal_mutex_type; |
192 | #endif |
193 | internal_mutex_type &internal_mutex() |
194 | { return m_mut; } |
195 | |
196 | internal_mutex_type m_mut; |
197 | |
198 | #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
199 | }; |
200 | |
201 | #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
202 | |
203 | inline named_mutex::named_mutex(create_only_t, const char *name, const permissions &perm) |
204 | : m_mut(create_only_t(), name, perm) |
205 | {} |
206 | |
207 | inline named_mutex::named_mutex(open_or_create_t, const char *name, const permissions &perm) |
208 | : m_mut(open_or_create_t(), name, perm) |
209 | {} |
210 | |
211 | inline named_mutex::named_mutex(open_only_t, const char *name) |
212 | : m_mut(open_only_t(), name) |
213 | {} |
214 | |
215 | #if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
216 | |
217 | inline named_mutex::named_mutex(create_only_t, const wchar_t *name, const permissions &perm) |
218 | : m_mut(create_only_t(), name, perm) |
219 | {} |
220 | |
221 | inline named_mutex::named_mutex(open_or_create_t, const wchar_t *name, const permissions &perm) |
222 | : m_mut(open_or_create_t(), name, perm) |
223 | {} |
224 | |
225 | inline named_mutex::named_mutex(open_only_t, const wchar_t *name) |
226 | : m_mut(open_only_t(), name) |
227 | {} |
228 | |
229 | #endif //defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
230 | |
231 | inline void named_mutex::dont_close_on_destruction() |
232 | { ipcdetail::interprocess_tester::dont_close_on_destruction(t&: m_mut); } |
233 | |
234 | inline named_mutex::~named_mutex() |
235 | {} |
236 | |
237 | inline void named_mutex::lock() |
238 | { m_mut.lock(); } |
239 | |
240 | inline void named_mutex::unlock() |
241 | { m_mut.unlock(); } |
242 | |
243 | inline bool named_mutex::try_lock() |
244 | { return m_mut.try_lock(); } |
245 | |
246 | template<class TimePoint> |
247 | inline bool named_mutex::timed_lock(const TimePoint &abs_time) |
248 | { return m_mut.timed_lock(abs_time); } |
249 | |
250 | inline bool named_mutex::remove(const char *name) |
251 | { return internal_mutex_type::remove(name); } |
252 | |
253 | #if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
254 | |
255 | inline bool named_mutex::remove(const wchar_t *name) |
256 | { return internal_mutex_type::remove(name); } |
257 | |
258 | #endif |
259 | |
260 | #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
261 | |
262 | } //namespace interprocess { |
263 | } //namespace boost { |
264 | |
265 | #include <boost/interprocess/detail/config_end.hpp> |
266 | |
267 | #endif //BOOST_INTERPROCESS_NAMED_MUTEX_HPP |
268 | |