]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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_FILE_LOCK_HPP | |
12 | #define BOOST_INTERPROCESS_FILE_LOCK_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/exceptions.hpp> | |
25 | #include <boost/interprocess/detail/os_file_functions.hpp> | |
26 | #include <boost/interprocess/detail/os_thread_functions.hpp> | |
27 | #include <boost/interprocess/detail/posix_time_types_wrk.hpp> | |
28 | #include <boost/interprocess/sync/detail/common_algorithms.hpp> | |
29 | #include <boost/interprocess/sync/detail/locks.hpp> | |
30 | #include <boost/move/utility_core.hpp> | |
31 | ||
32 | //!\file | |
33 | //!Describes a class that wraps file locking capabilities. | |
34 | ||
35 | namespace boost { | |
36 | namespace interprocess { | |
37 | ||
38 | ||
39 | //!A file lock, is a mutual exclusion utility similar to a mutex using a | |
40 | //!file. A file lock has sharable and exclusive locking capabilities and | |
41 | //!can be used with scoped_lock and sharable_lock classes. | |
42 | //!A file lock can't guarantee synchronization between threads of the same | |
43 | //!process so just use file locks to synchronize threads from different processes. | |
44 | class file_lock | |
45 | { | |
46 | #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) | |
47 | //Non-copyable | |
48 | BOOST_MOVABLE_BUT_NOT_COPYABLE(file_lock) | |
49 | #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED | |
50 | ||
51 | public: | |
52 | //!Constructs an empty file mapping. | |
53 | //!Does not throw | |
54 | file_lock() | |
55 | : m_file_hnd(file_handle_t(ipcdetail::invalid_file())) | |
56 | {} | |
57 | ||
58 | //!Opens a file lock. Throws interprocess_exception if the file does not | |
59 | //!exist or there are no operating system resources. | |
60 | file_lock(const char *name); | |
61 | ||
62 | //!Moves the ownership of "moved"'s file mapping object to *this. | |
63 | //!After the call, "moved" does not represent any file mapping object. | |
64 | //!Does not throw | |
65 | file_lock(BOOST_RV_REF(file_lock) moved) | |
66 | : m_file_hnd(file_handle_t(ipcdetail::invalid_file())) | |
67 | { this->swap(moved); } | |
68 | ||
69 | //!Moves the ownership of "moved"'s file mapping to *this. | |
70 | //!After the call, "moved" does not represent any file mapping. | |
71 | //!Does not throw | |
72 | file_lock &operator=(BOOST_RV_REF(file_lock) moved) | |
73 | { | |
74 | file_lock tmp(boost::move(moved)); | |
75 | this->swap(tmp); | |
76 | return *this; | |
77 | } | |
78 | ||
79 | //!Closes a file lock. Does not throw. | |
80 | ~file_lock(); | |
81 | ||
82 | //!Swaps two file_locks. | |
83 | //!Does not throw. | |
84 | void swap(file_lock &other) | |
85 | { | |
86 | file_handle_t tmp = m_file_hnd; | |
87 | m_file_hnd = other.m_file_hnd; | |
88 | other.m_file_hnd = tmp; | |
89 | } | |
90 | ||
91 | //Exclusive locking | |
92 | ||
93 | //!Effects: The calling thread tries to obtain exclusive ownership of the mutex, | |
94 | //! and if another thread has exclusive, or sharable ownership of | |
95 | //! the mutex, it waits until it can obtain the ownership. | |
96 | //!Throws: interprocess_exception on error. | |
97 | void lock(); | |
98 | ||
99 | //!Effects: The calling thread tries to acquire exclusive ownership of the mutex | |
100 | //! without waiting. If no other thread has exclusive, or sharable | |
101 | //! ownership of the mutex this succeeds. | |
102 | //!Returns: If it can acquire exclusive ownership immediately returns true. | |
103 | //! If it has to wait, returns false. | |
104 | //!Throws: interprocess_exception on error. | |
105 | bool try_lock(); | |
106 | ||
107 | //!Effects: The calling thread tries to acquire exclusive ownership of the mutex | |
108 | //! waiting if necessary until no other thread has exclusive, or sharable | |
109 | //! ownership of the mutex or abs_time is reached. | |
110 | //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false. | |
111 | //!Throws: interprocess_exception on error. | |
112 | bool timed_lock(const boost::posix_time::ptime &abs_time); | |
113 | ||
114 | //!Precondition: The thread must have exclusive ownership of the mutex. | |
115 | //!Effects: The calling thread releases the exclusive ownership of the mutex. | |
116 | //!Throws: An exception derived from interprocess_exception on error. | |
117 | void unlock(); | |
118 | ||
119 | //Sharable locking | |
120 | ||
121 | //!Effects: The calling thread tries to obtain sharable ownership of the mutex, | |
122 | //! and if another thread has exclusive ownership of the mutex, waits until | |
123 | //! it can obtain the ownership. | |
124 | //!Throws: interprocess_exception on error. | |
125 | void lock_sharable(); | |
126 | ||
127 | //!Effects: The calling thread tries to acquire sharable ownership of the mutex | |
128 | //! without waiting. If no other thread has exclusive ownership of the | |
129 | //! mutex this succeeds. | |
130 | //!Returns: If it can acquire sharable ownership immediately returns true. If it | |
131 | //! has to wait, returns false. | |
132 | //!Throws: interprocess_exception on error. | |
133 | bool try_lock_sharable(); | |
134 | ||
135 | //!Effects: The calling thread tries to acquire sharable ownership of the mutex | |
136 | //! waiting if necessary until no other thread has exclusive ownership of | |
137 | //! the mutex or abs_time is reached. | |
138 | //!Returns: If acquires sharable ownership, returns true. Otherwise returns false. | |
139 | //!Throws: interprocess_exception on error. | |
140 | bool timed_lock_sharable(const boost::posix_time::ptime &abs_time); | |
141 | ||
142 | //!Precondition: The thread must have sharable ownership of the mutex. | |
143 | //!Effects: The calling thread releases the sharable ownership of the mutex. | |
144 | //!Throws: An exception derived from interprocess_exception on error. | |
145 | void unlock_sharable(); | |
146 | #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) | |
147 | private: | |
148 | file_handle_t m_file_hnd; | |
149 | ||
150 | #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED | |
151 | }; | |
152 | ||
153 | inline file_lock::file_lock(const char *name) | |
154 | { | |
155 | m_file_hnd = ipcdetail::open_existing_file(name, read_write); | |
156 | ||
157 | if(m_file_hnd == ipcdetail::invalid_file()){ | |
158 | error_info err(system_error_code()); | |
159 | throw interprocess_exception(err); | |
160 | } | |
161 | } | |
162 | ||
163 | inline file_lock::~file_lock() | |
164 | { | |
165 | if(m_file_hnd != ipcdetail::invalid_file()){ | |
166 | ipcdetail::close_file(m_file_hnd); | |
167 | m_file_hnd = ipcdetail::invalid_file(); | |
168 | } | |
169 | } | |
170 | ||
171 | inline void file_lock::lock() | |
172 | { | |
173 | if(!ipcdetail::acquire_file_lock(m_file_hnd)){ | |
174 | error_info err(system_error_code()); | |
175 | throw interprocess_exception(err); | |
176 | } | |
177 | } | |
178 | ||
179 | inline bool file_lock::try_lock() | |
180 | { | |
181 | bool result; | |
182 | if(!ipcdetail::try_acquire_file_lock(m_file_hnd, result)){ | |
183 | error_info err(system_error_code()); | |
184 | throw interprocess_exception(err); | |
185 | } | |
186 | return result; | |
187 | } | |
188 | ||
189 | inline bool file_lock::timed_lock(const boost::posix_time::ptime &abs_time) | |
190 | { return ipcdetail::try_based_timed_lock(*this, abs_time); } | |
191 | ||
192 | inline void file_lock::unlock() | |
193 | { | |
194 | if(!ipcdetail::release_file_lock(m_file_hnd)){ | |
195 | error_info err(system_error_code()); | |
196 | throw interprocess_exception(err); | |
197 | } | |
198 | } | |
199 | ||
200 | inline void file_lock::lock_sharable() | |
201 | { | |
202 | if(!ipcdetail::acquire_file_lock_sharable(m_file_hnd)){ | |
203 | error_info err(system_error_code()); | |
204 | throw interprocess_exception(err); | |
205 | } | |
206 | } | |
207 | ||
208 | inline bool file_lock::try_lock_sharable() | |
209 | { | |
210 | bool result; | |
211 | if(!ipcdetail::try_acquire_file_lock_sharable(m_file_hnd, result)){ | |
212 | error_info err(system_error_code()); | |
213 | throw interprocess_exception(err); | |
214 | } | |
215 | return result; | |
216 | } | |
217 | ||
218 | inline bool file_lock::timed_lock_sharable(const boost::posix_time::ptime &abs_time) | |
219 | { | |
220 | ipcdetail::lock_to_sharable<file_lock> lsh(*this); | |
221 | return ipcdetail::try_based_timed_lock(lsh, abs_time); | |
222 | } | |
223 | ||
224 | inline void file_lock::unlock_sharable() | |
225 | { | |
226 | if(!ipcdetail::release_file_lock_sharable(m_file_hnd)){ | |
227 | error_info err(system_error_code()); | |
228 | throw interprocess_exception(err); | |
229 | } | |
230 | } | |
231 | ||
232 | } //namespace interprocess { | |
233 | } //namespace boost { | |
234 | ||
235 | #include <boost/interprocess/detail/config_end.hpp> | |
236 | ||
237 | #endif //BOOST_INTERPROCESS_FILE_LOCK_HPP |