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 + -
显示快捷键?