Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 08:17:17

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/interprocess for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 
0011 #ifndef BOOST_INTERPROCESS_FILE_LOCK_HPP
0012 #define BOOST_INTERPROCESS_FILE_LOCK_HPP
0013 
0014 #ifndef BOOST_CONFIG_HPP
0015 #  include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 #  pragma once
0020 #endif
0021 
0022 #include <boost/interprocess/detail/config_begin.hpp>
0023 #include <boost/interprocess/detail/workaround.hpp>
0024 #include <boost/interprocess/exceptions.hpp>
0025 #include <boost/interprocess/timed_utils.hpp>
0026 #include <boost/interprocess/detail/os_file_functions.hpp>
0027 #include <boost/interprocess/detail/os_thread_functions.hpp>
0028 #include <boost/interprocess/sync/detail/common_algorithms.hpp>
0029 #include <boost/interprocess/sync/detail/locks.hpp>
0030 #include <boost/move/utility_core.hpp>
0031 
0032 //!\file
0033 //!Describes a class that wraps file locking capabilities.
0034 
0035 namespace boost {
0036 namespace interprocess {
0037 
0038 
0039 //!A file lock, is a mutual exclusion utility similar to a mutex using a
0040 //!file. A file lock has sharable and exclusive locking capabilities and
0041 //!can be used with scoped_lock and sharable_lock classes.
0042 //!A file lock can't guarantee synchronization between threads of the same
0043 //!process so just use file locks to synchronize threads from different processes.
0044 class file_lock
0045 {
0046    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0047    //Non-copyable
0048    BOOST_MOVABLE_BUT_NOT_COPYABLE(file_lock)
0049    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0050 
0051    public:
0052    //!Constructs an empty file mapping.
0053    //!Does not throw
0054    file_lock() BOOST_NOEXCEPT
0055       :  m_file_hnd(file_handle_t(ipcdetail::invalid_file()))
0056    {}
0057 
0058    //!Opens a file lock. Throws interprocess_exception if the file does not
0059    //!exist or there are no operating system resources.
0060    file_lock(const char *name);
0061 
0062    #if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0063    //!Opens a file lock. Throws interprocess_exception if the file does not
0064    //!exist or there are no operating system resources.
0065    //! 
0066    //!Note: This function is only available on operating systems with
0067    //!      native wchar_t APIs (e.g. Windows).
0068    file_lock(const wchar_t *name);
0069    #endif
0070 
0071    //!Moves the ownership of "moved"'s file mapping object to *this.
0072    //!After the call, "moved" does not represent any file mapping object.
0073    //!Does not throw
0074    file_lock(BOOST_RV_REF(file_lock) moved) BOOST_NOEXCEPT
0075       :  m_file_hnd(file_handle_t(ipcdetail::invalid_file()))
0076    {  this->swap(moved);   }
0077 
0078    //!Moves the ownership of "moved"'s file mapping to *this.
0079    //!After the call, "moved" does not represent any file mapping.
0080    //!Does not throw
0081    file_lock &operator=(BOOST_RV_REF(file_lock) moved) BOOST_NOEXCEPT
0082    {
0083       file_lock tmp(boost::move(moved));
0084       this->swap(tmp);
0085       return *this;
0086    }
0087 
0088    //!Closes a file lock. Does not throw.
0089    ~file_lock();
0090 
0091    //!Swaps two file_locks.
0092    //!Does not throw.
0093    void swap(file_lock &other) BOOST_NOEXCEPT
0094    {
0095       file_handle_t tmp = m_file_hnd;
0096       m_file_hnd = other.m_file_hnd;
0097       other.m_file_hnd = tmp;
0098    }
0099 
0100    //Exclusive locking
0101 
0102    //!Requires: The calling thread does not own the mutex.
0103    //!
0104    //!Effects: The calling thread tries to obtain exclusive ownership of the mutex,
0105    //!   and if another thread has exclusive, or sharable ownership of
0106    //!   the mutex, it waits until it can obtain the ownership.
0107    //!Throws: interprocess_exception on error.
0108    //!
0109    //!Note: A program may deadlock if the thread that has ownership calls 
0110    //!   this function. If the implementation can detect the deadlock,
0111    //!   an exception could be thrown.
0112    void lock();
0113 
0114    //!Requires: The calling thread does not own the mutex.
0115    //!
0116    //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
0117    //!   without waiting. If no other thread has exclusive, or sharable
0118    //!   ownership of the mutex this succeeds.
0119    //!Returns: If it can acquire exclusive ownership immediately returns true.
0120    //!   If it has to wait, returns false.
0121    //!Throws: interprocess_exception on error.
0122    //! 
0123    //!Note: A program may deadlock if the thread that has ownership calls 
0124    //!   this function. If the implementation can detect the deadlock,
0125    //!   an exception could be thrown.
0126    bool try_lock();
0127 
0128    //!Requires: The calling thread does not own the mutex.
0129    //!
0130    //!Effects: The calling thread tries to acquire exclusive ownership of the mutex
0131    //!   waiting if necessary until no other thread has exclusive, or sharable
0132    //!   ownership of the mutex or abs_time is reached.
0133    //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.
0134    //!Throws: interprocess_exception on error.
0135    //! 
0136    //!Note: A program may deadlock if the thread that has ownership calls 
0137    //!   this function. If the implementation can detect the deadlock,
0138    //!   an exception could be thrown.
0139    template<class TimePoint>
0140    bool timed_lock(const TimePoint &abs_time);
0141 
0142    //!Same as `timed_lock`, but this function is modeled after the
0143    //!standard library interface.
0144    template<class TimePoint> bool try_lock_until(const TimePoint &abs_time)
0145    {  return this->timed_lock(abs_time);  }
0146 
0147    //!Same as `timed_lock`, but this function is modeled after the
0148    //!standard library interface.
0149    template<class Duration>  bool try_lock_for(const Duration &dur)
0150    {  return this->timed_lock(ipcdetail::duration_to_ustime(dur)); }
0151 
0152    //!Precondition: The thread must have exclusive ownership of the mutex.
0153    //!Effects: The calling thread releases the exclusive ownership of the mutex.
0154    //!Throws: An exception derived from interprocess_exception on error.
0155    void unlock();
0156 
0157    //Sharable locking
0158 
0159    //!Requires: The calling thread does not own the mutex.
0160    //!
0161    //!Effects: The calling thread tries to obtain sharable ownership of the mutex,
0162    //!   and if another thread has exclusive ownership of the mutex, waits until
0163    //!   it can obtain the ownership.
0164    //!Throws: interprocess_exception on error.
0165    //!
0166    //!Note: A program may deadlock if the thread that owns a mutex object calls 
0167    //!   this function. If the implementation can detect the deadlock,
0168    //!   an exception could be thrown.
0169    void lock_sharable();
0170 
0171    //!Same as `lock_sharable` but with a std-compatible interface
0172    //! 
0173    void lock_shared()
0174    {  this->lock_sharable();  }
0175 
0176    //!Effects: The calling thread tries to acquire sharable ownership of the mutex
0177    //!   without waiting. If no other thread has exclusive ownership of the
0178    //!   mutex this succeeds.
0179    //!Returns: If it can acquire sharable ownership immediately returns true. If it
0180    //!   has to wait, returns false.
0181    //!Throws: interprocess_exception on error.
0182    bool try_lock_sharable();
0183 
0184    //!Same as `try_lock_sharable` but with a std-compatible interface
0185    //! 
0186    bool try_lock_shared()
0187    {  return this->try_lock_sharable();  }
0188 
0189    //!Effects: The calling thread tries to acquire sharable ownership of the mutex
0190    //!   waiting if necessary until no other thread has exclusive ownership of
0191    //!   the mutex or abs_time is reached.
0192    //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.
0193    //!Throws: interprocess_exception on error.
0194    template<class TimePoint>
0195    bool timed_lock_sharable(const TimePoint &abs_time);
0196 
0197    //!Same as `timed_lock_sharable`, but this function is modeled after the
0198    //!standard library interface.
0199    template<class TimePoint> bool try_lock_shared_until(const TimePoint &abs_time)
0200    {  return this->timed_lock_sharable(abs_time);  }
0201 
0202    //!Same as `timed_lock_sharable`, but this function is modeled after the
0203    //!standard library interface.
0204    template<class Duration>  bool try_lock_shared_for(const Duration &dur)
0205    {  return this->timed_lock_sharable(ipcdetail::duration_to_ustime(dur)); }
0206 
0207    //!Precondition: The thread must have sharable ownership of the mutex.
0208    //!Effects: The calling thread releases the sharable ownership of the mutex.
0209    //!Throws: An exception derived from interprocess_exception on error.
0210    void unlock_sharable();
0211 
0212    //!Same as `unlock_sharable` but with a std-compatible interface
0213    //! 
0214    void unlock_shared()
0215    {  this->unlock_sharable();  }
0216 
0217    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0218    private:
0219    file_handle_t m_file_hnd;
0220 
0221    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0222 };
0223 
0224 inline file_lock::file_lock(const char *name)
0225 {
0226    m_file_hnd = ipcdetail::open_existing_file(name, read_write);
0227 
0228    if(m_file_hnd == ipcdetail::invalid_file()){
0229       error_info err(system_error_code());
0230       throw interprocess_exception(err);
0231    }
0232 }
0233 
0234 #if defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0235 
0236 inline file_lock::file_lock(const wchar_t *name)
0237 {
0238    m_file_hnd = ipcdetail::open_existing_file(name, read_write);
0239 
0240    if(m_file_hnd == ipcdetail::invalid_file()){
0241       error_info err(system_error_code());
0242       throw interprocess_exception(err);
0243    }
0244 }
0245 
0246 #endif //defined(BOOST_INTERPROCESS_WCHAR_NAMED_RESOURCES) || defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0247 
0248 inline file_lock::~file_lock()
0249 {
0250    if(m_file_hnd != ipcdetail::invalid_file()){
0251       ipcdetail::close_file(m_file_hnd);
0252       m_file_hnd = ipcdetail::invalid_file();
0253    }
0254 }
0255 
0256 inline void file_lock::lock()
0257 {
0258    if(!ipcdetail::acquire_file_lock(m_file_hnd)){
0259       error_info err(system_error_code());
0260       throw interprocess_exception(err);
0261    }
0262 }
0263 
0264 inline bool file_lock::try_lock()
0265 {
0266    bool result;
0267    if(!ipcdetail::try_acquire_file_lock(m_file_hnd, result)){
0268       error_info err(system_error_code());
0269       throw interprocess_exception(err);
0270    }
0271    return result;
0272 }
0273 
0274 template<class TimePoint>
0275 inline bool file_lock::timed_lock(const TimePoint &abs_time)
0276 {  return ipcdetail::try_based_timed_lock(*this, abs_time);   }
0277 
0278 inline void file_lock::unlock()
0279 {
0280    if(!ipcdetail::release_file_lock(m_file_hnd)){
0281       error_info err(system_error_code());
0282       throw interprocess_exception(err);
0283    }
0284 }
0285 
0286 inline void file_lock::lock_sharable()
0287 {
0288    if(!ipcdetail::acquire_file_lock_sharable(m_file_hnd)){
0289       error_info err(system_error_code());
0290       throw interprocess_exception(err);
0291    }
0292 }
0293 
0294 inline bool file_lock::try_lock_sharable()
0295 {
0296    bool result;
0297    if(!ipcdetail::try_acquire_file_lock_sharable(m_file_hnd, result)){
0298       error_info err(system_error_code());
0299       throw interprocess_exception(err);
0300    }
0301    return result;
0302 }
0303 
0304 template<class TimePoint>
0305 inline bool file_lock::timed_lock_sharable(const TimePoint &abs_time)
0306 {
0307    ipcdetail::lock_to_sharable<file_lock> lsh(*this);
0308    return ipcdetail::try_based_timed_lock(lsh, abs_time);
0309 }
0310 
0311 inline void file_lock::unlock_sharable()
0312 {
0313    if(!ipcdetail::release_file_lock_sharable(m_file_hnd)){
0314       error_info err(system_error_code());
0315       throw interprocess_exception(err);
0316    }
0317 }
0318 
0319 }  //namespace interprocess {
0320 }  //namespace boost {
0321 
0322 #include <boost/interprocess/detail/config_end.hpp>
0323 
0324 #endif   //BOOST_INTERPROCESS_FILE_LOCK_HPP