scoped_lock.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 470 行 · 第 1/2 页

HPP
470
字号
////////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost// Software License, Version 1.0. (See accompanying file// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)//// See http://www.boost.org/libs/interprocess for documentation.//////////////////////////////////////////////////////////////////////////////////// This interface is inspired by Howard Hinnant's lock proposal.// http://home.twcny.rr.com/hinnant/cpp_extensions/threads_move.html////////////////////////////////////////////////////////////////////////////////#ifndef BOOST_INTERPROCESS_SCOPED_LOCK_HPP#define BOOST_INTERPROCESS_SCOPED_LOCK_HPP#if (defined _MSC_VER) && (_MSC_VER >= 1200)#  pragma once#endif#include <boost/interprocess/detail/config_begin.hpp>#include <boost/interprocess/detail/workaround.hpp>#include <boost/interprocess/sync/lock_options.hpp>#include <boost/interprocess/exceptions.hpp>#include <boost/interprocess/detail/move.hpp>#include <boost/interprocess/detail/posix_time_types_wrk.hpp>//!\file//!Describes the scoped_lock class.namespace boost {namespace interprocess {template<class M>class sharable_lock;template<class M>class upgradable_lock;//!scoped_lock is meant to carry out the tasks for locking, unlocking, try-locking//!and timed-locking (recursive or not) for the Mutex. The Mutex need not supply all//!of this functionality. If the client of scoped_lock<Mutex> does not use//!functionality which the Mutex does not supply, no harm is done. Mutex ownership//!transfer is supported through the syntax of move semantics. Ownership transfer//!is allowed both by construction and assignment. The scoped_lock does not support//!copy semantics. A compile time error results if copy construction or copy//!assignment is attempted. Mutex ownership can also be moved from an//!upgradable_lock and sharable_lock via constructor. In this role, scoped_lock//!shares the same functionality as a write_lock.template <class Mutex>class scoped_lock{   /// @cond   private:   typedef scoped_lock<Mutex> this_type;   scoped_lock(scoped_lock const&);   scoped_lock& operator=  (scoped_lock const&);   typedef bool this_type::*unspecified_bool_type;   /// @endcond   public:   typedef Mutex mutex_type;   //!Effects: Default constructs a scoped_lock.   //!Postconditions: owns() == false and mutex() == 0.   scoped_lock()      : mp_mutex(0), m_locked(false)   {}   //!Effects: m.lock().   //!Postconditions: owns() == true and mutex() == &m.   //!Notes: The constructor will take ownership of the mutex. If another thread   //!   already owns the mutex, this thread will block until the mutex is released.   //!   Whether or not this constructor handles recursive locking depends upon the mutex.   explicit scoped_lock(mutex_type& m)      : mp_mutex(&m), m_locked(false)   {  mp_mutex->lock();   m_locked = true;  }   //!Postconditions: owns() == false, and mutex() == &m.   //!Notes: The constructor will not take ownership of the mutex. There is no effect   //!   required on the referenced mutex.   scoped_lock(mutex_type& m, detail::defer_lock_type)      : mp_mutex(&m), m_locked(false)   {}   //!Postconditions: owns() == true, and mutex() == &m.   //!Notes: The constructor will suppose that the mutex is already locked. There   //!   is no effect required on the referenced mutex.   scoped_lock(mutex_type& m, detail::accept_ownership_type)      : mp_mutex(&m), m_locked(true)   {}   //!Effects: m.try_lock().    //!Postconditions: mutex() == &m. owns() == the return value of the   //!   m.try_lock() executed within the constructor.   //!Notes: The constructor will take ownership of the mutex if it can do   //!   so without waiting. Whether or not this constructor handles recursive   //!   locking depends upon the mutex. If the mutex_type does not support try_lock,   //!   this constructor will fail at compile time if instantiated, but otherwise   //!   have no effect.   scoped_lock(mutex_type& m, detail::try_to_lock_type)      : mp_mutex(&m), m_locked(mp_mutex->try_lock())   {}   //!Effects: m.timed_lock(abs_time).    //!Postconditions: mutex() == &m. owns() == the return value of the   //!   m.timed_lock(abs_time) executed within the constructor.   //!Notes: The constructor will take ownership of the mutex if it can do   //!   it until abs_time is reached. Whether or not this constructor   //!   handles recursive locking depends upon the mutex. If the mutex_type   //!   does not support try_lock, this constructor will fail at compile   //!   time if instantiated, but otherwise have no effect.   scoped_lock(mutex_type& m, const boost::posix_time::ptime& abs_time)      : mp_mutex(&m), m_locked(mp_mutex->timed_lock(abs_time))   {}   //!Postconditions: mutex() == the value scop.mutex() had before the   //!   constructor executes. s1.mutex() == 0. owns() == the value of   //!   scop.owns() before the constructor executes. scop.owns().   //!Notes: If the scop scoped_lock owns the mutex, ownership is moved   //!   to thisscoped_lock with no blocking. If the scop scoped_lock does not   //!   own the mutex, then neither will this scoped_lock. Only a moved   //!   scoped_lock's will match this signature. An non-moved scoped_lock   //!   can be moved with the expression: "detail::move_impl(lock);". This   //!   constructor does not alter the state of the mutex, only potentially   //!   who owns it.   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE   scoped_lock(detail::moved_object<scoped_lock<Mutex> > scop)      : mp_mutex(0), m_locked(scop.get().owns())   {  mp_mutex = scop.get().release(); }   #else   scoped_lock(scoped_lock &&scop)      : mp_mutex(0), m_locked(scop.owns())   {  mp_mutex = scop.release(); }   #endif   //!Effects: If upgr.owns() then calls unlock_upgradable_and_lock() on the   //!   referenced mutex. upgr.release() is called.    //!Postconditions: mutex() == the value upgr.mutex() had before the construction.   //!   upgr.mutex() == 0. owns() == upgr.owns() before the construction.   //!   upgr.owns() == false after the construction.   //!Notes: If upgr is locked, this constructor will lock this scoped_lock while   //!   unlocking upgr. If upgr is unlocked, then this scoped_lock will be   //!   unlocked as well. Only a moved upgradable_lock's will match this   //!   signature. An non-moved upgradable_lock can be moved with   //!   the expression: "detail::move_impl(lock);" This constructor may block if   //!   other threads hold a sharable_lock on this mutex (sharable_lock's can   //!   share ownership with an upgradable_lock).   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE   scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr)      : mp_mutex(0), m_locked(false)   {      upgradable_lock<mutex_type> &u_lock = upgr.get();      if(u_lock.owns()){         u_lock.mutex()->unlock_upgradable_and_lock();         m_locked = true;      }      mp_mutex = u_lock.release();   }   #else   scoped_lock(upgradable_lock<Mutex> &&upgr)      : mp_mutex(0), m_locked(false)   {      upgradable_lock<mutex_type> &u_lock = upgr;      if(u_lock.owns()){         u_lock.mutex()->unlock_upgradable_and_lock();         m_locked = true;      }      mp_mutex = u_lock.release();   }   #endif   //!Effects: If upgr.owns() then calls try_unlock_upgradable_and_lock() on the   //!referenced mutex:   //!   a)if try_unlock_upgradable_and_lock() returns true then mutex() obtains   //!      the value from upgr.release() and owns() is set to true.    //!   b)if try_unlock_upgradable_and_lock() returns false then upgr is   //!      unaffected and this scoped_lock construction as the same effects as     //!      a default construction.    //!   c)Else upgr.owns() is false. mutex() obtains the value from upgr.release()   //!      and owns() is set to false    //!Notes: This construction will not block. It will try to obtain mutex   //!   ownership from upgr immediately, while changing the lock type from a   //!   "read lock" to a "write lock". If the "read lock" isn't held in the   //!   first place, the mutex merely changes type to an unlocked "write lock".   //!   If the "read lock" is held, then mutex transfer occurs only if it can   //!   do so in a non-blocking manner.*/   #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE   scoped_lock(detail::moved_object<upgradable_lock<Mutex> > upgr              ,detail::try_to_lock_type)      : mp_mutex(0), m_locked(false)   {      upgradable_lock<mutex_type> &u_lock = upgr.get();      if(u_lock.owns()){         if((m_locked = u_lock.mutex()->try_unlock_upgradable_and_lock()) == true){            mp_mutex = u_lock.release();         }      }      else{         u_lock.release();      }   }   #else   scoped_lock(upgradable_lock<Mutex> &&upgr              ,detail::try_to_lock_type)      : mp_mutex(0), m_locked(false)   {      upgradable_lock<mutex_type> &u_lock = upgr;      if(u_lock.owns()){         if((m_locked = u_lock.mutex()->try_unlock_upgradable_and_lock()) == true){            mp_mutex = u_lock.release();         }      }      else{         u_lock.release();      }   }   #endif   //!Effects: If upgr.owns() then calls timed_unlock_upgradable_and_lock(abs_time)   //!   on the referenced mutex:   //!   a)if timed_unlock_upgradable_and_lock(abs_time) returns true then mutex()   //!      obtains the value from upgr.release() and owns() is set to true.    //!   b)if timed_unlock_upgradable_and_lock(abs_time) returns false then upgr   //!      is unaffected and this scoped_lock construction as the same effects   //!      as a default construction.   //!   c)Else upgr.owns() is false. mutex() obtains the value from upgr.release()   //!      and owns() is set to false    //!Notes: This construction will not block. It will try to obtain mutex ownership   //!   from upgr immediately, while changing the lock type from a "read lock" to a   //!   "write lock". If the "read lock" isn't held in the first place, the mutex   //!   merely changes type to an unlocked "write lock". If the "read lock" is held,   //!   then mutex transfer occurs only if it can do so in a non-blocking manner.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?