PageRenderTime 35ms CodeModel.GetById 19ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/interprocess/sync/file_lock.hpp

http://hadesmem.googlecode.com/
C++ Header | 305 lines | 182 code | 47 blank | 76 comment | 25 complexity | f117173d9dc5efd8f44787939f385bc6 MD5 | raw file
  1//////////////////////////////////////////////////////////////////////////////
  2//
  3// (C) Copyright Ion Gaztanaga 2005-2009. 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#if (defined _MSC_VER) && (_MSC_VER >= 1200)
 15#  pragma once
 16#endif
 17
 18#include <boost/interprocess/detail/config_begin.hpp>
 19#include <boost/interprocess/detail/workaround.hpp>
 20#include <boost/interprocess/exceptions.hpp>
 21#include <boost/interprocess/detail/os_file_functions.hpp>
 22#include <boost/interprocess/detail/os_thread_functions.hpp>
 23#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 24#include <boost/interprocess/detail/move.hpp>
 25
 26//!\file
 27//!Describes a class that wraps file locking capabilities.
 28
 29namespace boost {
 30namespace interprocess {
 31
 32
 33//!A file lock, is a mutual exclusion utility similar to a mutex using a
 34//!file. A file lock has sharable and exclusive locking capabilities and
 35//!can be used with scoped_lock and sharable_lock classes.
 36//!A file lock can't guarantee synchronization between threads of the same
 37//!process so just use file locks to synchronize threads from different processes.
 38class file_lock
 39{
 40   /// @cond
 41   //Non-copyable
 42   BOOST_INTERPROCESS_MOVABLE_BUT_NOT_COPYABLE(file_lock)
 43   /// @endcond
 44
 45   public:
 46   //!Constructs an empty file mapping.
 47   //!Does not throw
 48   file_lock()
 49      :  m_file_hnd(file_handle_t(detail::invalid_file()))
 50   {}
 51
 52   //!Opens a file lock. Throws interprocess_exception if the file does not
 53   //!exist or there are no operating system resources.
 54   file_lock(const char *name);
 55
 56   //!Moves the ownership of "moved"'s file mapping object to *this. 
 57   //!After the call, "moved" does not represent any file mapping object. 
 58   //!Does not throw
 59   file_lock(BOOST_INTERPROCESS_RV_REF(file_lock) moved)
 60      :  m_file_hnd(file_handle_t(detail::invalid_file()))
 61   {  this->swap(moved);   }
 62
 63   //!Moves the ownership of "moved"'s file mapping to *this.
 64   //!After the call, "moved" does not represent any file mapping. 
 65   //!Does not throw
 66   file_lock &operator=(BOOST_INTERPROCESS_RV_REF(file_lock) moved)
 67   {  
 68      file_lock tmp(boost::interprocess::move(moved));
 69      this->swap(tmp);
 70      return *this;  
 71   }
 72
 73   //!Closes a file lock. Does not throw.
 74   ~file_lock();
 75
 76   //!Swaps two file_locks.
 77   //!Does not throw.
 78   void swap(file_lock &other)
 79   {
 80      file_handle_t tmp = m_file_hnd;
 81      m_file_hnd = other.m_file_hnd;
 82      other.m_file_hnd = tmp;
 83   }
 84   
 85   //Exclusive locking
 86
 87   //!Effects: The calling thread tries to obtain exclusive ownership of the mutex,
 88   //!   and if another thread has exclusive, or sharable ownership of
 89   //!   the mutex, it waits until it can obtain the ownership.
 90   //!Throws: interprocess_exception on error.
 91   void lock();
 92
 93   //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
 94   //!   without waiting. If no other thread has exclusive, or sharable
 95   //!   ownership of the mutex this succeeds.
 96   //!Returns: If it can acquire exclusive ownership immediately returns true.
 97   //!   If it has to wait, returns false.
 98   //!Throws: interprocess_exception on error.
 99   bool try_lock();
100
101   //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
102   //!   waiting if necessary until no other thread has has exclusive, or sharable
103   //!   ownership of the mutex or abs_time is reached.
104   //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false. 
105   //!Throws: interprocess_exception on error.
106   bool timed_lock(const boost::posix_time::ptime &abs_time);
107
108   //!Precondition: The thread must have exclusive ownership of the mutex. 
109   //!Effects: The calling thread releases the exclusive ownership of the mutex. 
110   //!Throws: An exception derived from interprocess_exception on error.
111   void unlock();
112
113   //Sharable locking
114
115   //!Effects: The calling thread tries to obtain sharable ownership of the mutex,
116   //!   and if another thread has exclusive ownership of the mutex, waits until
117   //!   it can obtain the ownership.
118   //!Throws: interprocess_exception on error.
119   void lock_sharable();
120
121   //!Effects: The calling thread tries to acquire sharable ownership of the mutex
122   //!   without waiting. If no other thread has has exclusive ownership of the
123   //!   mutex this succeeds. 
124   //!Returns: If it can acquire sharable ownership immediately returns true. If it
125   //!   has to wait, returns false. 
126   //!Throws: interprocess_exception on error.
127   bool try_lock_sharable();
128
129   //!Effects: The calling thread tries to acquire sharable ownership of the mutex
130   //!   waiting if necessary until no other thread has has exclusive ownership of
131   //!   the mutex or abs_time is reached. 
132   //!Returns: If acquires sharable ownership, returns true. Otherwise returns false. 
133   //!Throws: interprocess_exception on error.
134   bool timed_lock_sharable(const boost::posix_time::ptime &abs_time);
135
136   //!Precondition: The thread must have sharable ownership of the mutex. 
137   //!Effects: The calling thread releases the sharable ownership of the mutex. 
138   //!Throws: An exception derived from interprocess_exception on error.
139   void unlock_sharable();
140   /// @cond
141   private:
142   file_handle_t m_file_hnd;
143
144   bool timed_acquire_file_lock
145      (file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time)
146   {
147      //Obtain current count and target time
148      boost::posix_time::ptime now = microsec_clock::universal_time();
149      using namespace boost::detail;
150
151      if(now >= abs_time) return false;
152
153      do{
154         if(!detail::try_acquire_file_lock(hnd, acquired))
155            return false;
156
157         if(acquired)
158            return true;
159         else{
160            now = microsec_clock::universal_time();
161
162            if(now >= abs_time){
163               acquired = false;
164               return true;
165            }
166            // relinquish current time slice
167            detail::thread_yield();
168         }
169      }while (true);
170   }
171
172   bool timed_acquire_file_lock_sharable
173      (file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time)
174   {  
175      //Obtain current count and target time
176      boost::posix_time::ptime now = microsec_clock::universal_time();
177      using namespace boost::detail;
178
179      if(now >= abs_time) return false;
180
181      do{
182         if(!detail::try_acquire_file_lock_sharable(hnd, acquired))
183            return false;
184
185         if(acquired)
186            return true;
187         else{
188            now = microsec_clock::universal_time();
189
190            if(now >= abs_time){
191               acquired = false;
192               return true;
193            }
194            // relinquish current time slice
195            detail::thread_yield();
196         }
197      }while (true);
198   }
199   /// @endcond
200};
201
202inline file_lock::file_lock(const char *name)
203{
204   m_file_hnd = detail::open_existing_file(name, read_write);
205
206   if(m_file_hnd == detail::invalid_file()){
207      error_info err(system_error_code());
208      throw interprocess_exception(err);
209   }
210}
211
212inline file_lock::~file_lock()
213{
214   if(m_file_hnd != detail::invalid_file()){
215      detail::close_file(m_file_hnd);
216      m_file_hnd = detail::invalid_file();
217   }
218}
219
220inline void file_lock::lock()
221{
222   if(!detail::acquire_file_lock(m_file_hnd)){
223      error_info err(system_error_code());
224      throw interprocess_exception(err);
225   }
226}
227
228inline bool file_lock::try_lock()
229{
230   bool result;
231   if(!detail::try_acquire_file_lock(m_file_hnd, result)){
232      error_info err(system_error_code());
233      throw interprocess_exception(err);
234   }
235   return result;
236}
237
238inline bool file_lock::timed_lock(const boost::posix_time::ptime &abs_time)
239{
240   if(abs_time == boost::posix_time::pos_infin){
241      this->lock();
242      return true;
243   }
244   bool result;
245   if(!this->timed_acquire_file_lock(m_file_hnd, result, abs_time)){
246      error_info err(system_error_code());
247      throw interprocess_exception(err);
248   }
249   return result;
250}
251
252inline void file_lock::unlock()
253{
254   if(!detail::release_file_lock(m_file_hnd)){
255      error_info err(system_error_code());
256      throw interprocess_exception(err);
257   }
258}
259
260inline void file_lock::lock_sharable()
261{
262   if(!detail::acquire_file_lock_sharable(m_file_hnd)){
263      error_info err(system_error_code());
264      throw interprocess_exception(err);
265   }
266}
267
268inline bool file_lock::try_lock_sharable()
269{
270   bool result;
271   if(!detail::try_acquire_file_lock_sharable(m_file_hnd, result)){
272      error_info err(system_error_code());
273      throw interprocess_exception(err);
274   }
275   return result;
276}
277
278inline bool file_lock::timed_lock_sharable(const boost::posix_time::ptime &abs_time)
279{
280   if(abs_time == boost::posix_time::pos_infin){
281      this->lock_sharable();
282      return true;
283   }
284   bool result;
285   if(!this->timed_acquire_file_lock_sharable(m_file_hnd, result, abs_time)){
286      error_info err(system_error_code());
287      throw interprocess_exception(err);
288   }
289   return result;
290}
291
292inline void file_lock::unlock_sharable()
293{
294   if(!detail::release_file_lock_sharable(m_file_hnd)){
295      error_info err(system_error_code());
296      throw interprocess_exception(err);
297   }
298}
299
300}  //namespace interprocess {
301}  //namespace boost {
302
303#include <boost/interprocess/detail/config_end.hpp>
304
305#endif   //BOOST_INTERPROCESS_FILE_LOCK_HPP