Line data Source code
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 0 : inline file_lock::file_lock(const char *name) 154 : { 155 0 : m_file_hnd = ipcdetail::open_existing_file(name, read_write); 156 : 157 0 : if(m_file_hnd == ipcdetail::invalid_file()){ 158 0 : error_info err(system_error_code()); 159 0 : throw interprocess_exception(err); 160 : } 161 0 : } 162 : 163 0 : inline file_lock::~file_lock() 164 : { 165 0 : if(m_file_hnd != ipcdetail::invalid_file()){ 166 0 : ipcdetail::close_file(m_file_hnd); 167 0 : m_file_hnd = ipcdetail::invalid_file(); 168 : } 169 : } 170 : 171 0 : inline void file_lock::lock() 172 : { 173 0 : if(!ipcdetail::acquire_file_lock(m_file_hnd)){ 174 0 : error_info err(system_error_code()); 175 0 : throw interprocess_exception(err); 176 : } 177 0 : } 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 0 : inline void file_lock::unlock() 193 : { 194 0 : if(!ipcdetail::release_file_lock(m_file_hnd)){ 195 0 : error_info err(system_error_code()); 196 0 : throw interprocess_exception(err); 197 : } 198 0 : } 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