interprocess_upgradable_mutex.hpp

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

HPP
659
字号
////////////////////////////////////////////////////////////////////////////////// (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.////////////////////////////////////////////////////////////////////////////////#ifndef BOOST_INTERPROCESS_UPGRADABLE_MUTEX_HPP#define BOOST_INTERPROCESS_UPGRADABLE_MUTEX_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/scoped_lock.hpp>#include <boost/interprocess/sync/interprocess_mutex.hpp>#include <boost/interprocess/sync/interprocess_condition.hpp>#include <climits>//!\file//!Describes interprocess_upgradable_mutex classnamespace boost {namespace interprocess {//!Wraps a interprocess_upgradable_mutex that can be placed in shared memory and can be //!shared between processes. Allows timed lock triesclass interprocess_upgradable_mutex{   //Non-copyable   interprocess_upgradable_mutex(const interprocess_upgradable_mutex &);   interprocess_upgradable_mutex &operator=(const interprocess_upgradable_mutex &);   friend class interprocess_condition;   public:   //!Constructs the upgradable lock.   //!Throws interprocess_exception on error.   interprocess_upgradable_mutex();   //!Destroys the upgradable lock.   //!Does not throw.   ~interprocess_upgradable_mutex();   //Exclusive locking   //!Effects: The calling thread tries to obtain exclusive ownership of the mutex,   //!   and if another thread has exclusive, sharable or upgradable ownership of   //!   the mutex, it waits until it can obtain the ownership.   //!Throws: interprocess_exception on error.   void lock();   //!Effects: The calling thread tries to acquire exclusive ownership of the mutex   //!   without waiting. If no other thread has exclusive, sharable or upgradable   //!   ownership of the mutex this succeeds.   //!Returns: If it can acquire exclusive ownership immediately returns true.   //!   If it has to wait, returns false.   //!Throws: interprocess_exception on error.   bool try_lock();   //!Effects: The calling thread tries to acquire exclusive ownership of the mutex   //!   waiting if necessary until no other thread has has exclusive, sharable or   //!   upgradable ownership of the mutex or abs_time is reached.    //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.    //!Throws: interprocess_exception on error.   bool timed_lock(const boost::posix_time::ptime &abs_time);   //!Precondition: The thread must have exclusive ownership of the mutex.    //!Effects: The calling thread releases the exclusive ownership of the mutex.    //!Throws: An exception derived from interprocess_exception on error.   void unlock();   //Sharable locking   //!Effects: The calling thread tries to obtain sharable ownership of the mutex,   //!   and if another thread has exclusive or upgradable ownership of the mutex,   //!   waits until it can obtain the ownership.   //!Throws: interprocess_exception on error.   void lock_sharable();   //!Effects: The calling thread tries to acquire sharable ownership of the mutex   //!   without waiting. If no other thread has has exclusive or upgradable ownership   //!   of the mutex this succeeds.    //!Returns: If it can acquire sharable ownership immediately returns true. If it   //!   has to wait, returns false.    //!Throws: interprocess_exception on error.   bool try_lock_sharable();   //!Effects: The calling thread tries to acquire sharable ownership of the mutex   //!   waiting if necessary until no other thread has has exclusive or upgradable   //!   ownership of the mutex or abs_time is reached.    //!Returns: If acquires sharable ownership, returns true. Otherwise returns false.    //!Throws: interprocess_exception on error.   bool timed_lock_sharable(const boost::posix_time::ptime &abs_time);   //!Precondition: The thread must have sharable ownership of the mutex.    //!Effects: The calling thread releases the sharable ownership of the mutex.    //!Throws: An exception derived from interprocess_exception on error.   void unlock_sharable();   //Upgradable locking   //!Effects: The calling thread tries to obtain upgradable ownership of the mutex,   //!   and if another thread has exclusive or upgradable ownership of the mutex,   //!   waits until it can obtain the ownership.   //!Throws: interprocess_exception on error.   void lock_upgradable();   //!Effects: The calling thread tries to acquire upgradable ownership of the mutex   //!   without waiting. If no other thread has has exclusive or upgradable ownership   //!   of the mutex this succeeds.    //!Returns: If it can acquire upgradable ownership immediately returns true.   //!   If it has to wait, returns false.   //!Throws: interprocess_exception on error.   bool try_lock_upgradable();   //!Effects: The calling thread tries to acquire upgradable ownership of the mutex   //!   waiting if necessary until no other thread has has exclusive or upgradable   //!   ownership of the mutex or abs_time is reached.   //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.    //!Throws: interprocess_exception on error.   bool timed_lock_upgradable(const boost::posix_time::ptime &abs_time);   //!Precondition: The thread must have upgradable ownership of the mutex.    //!Effects: The calling thread releases the upgradable ownership of the mutex.    //!Throws: An exception derived from interprocess_exception on error.   void unlock_upgradable();   //Demotions   //!Precondition: The thread must have exclusive ownership of the mutex.    //!Effects: The thread atomically releases exclusive ownership and acquires   //!   upgradable ownership. This operation is non-blocking.    //!Throws: An exception derived from interprocess_exception on error.   void unlock_and_lock_upgradable();   //!Precondition: The thread must have exclusive ownership of the mutex.    //!Effects: The thread atomically releases exclusive ownership and acquires   //!   sharable ownership. This operation is non-blocking.    //!Throws: An exception derived from interprocess_exception on error.   void unlock_and_lock_sharable();   //!Precondition: The thread must have upgradable ownership of the mutex.    //!Effects: The thread atomically releases upgradable ownership and acquires   //!   sharable ownership. This operation is non-blocking.    //!Throws: An exception derived from interprocess_exception on error.   void unlock_upgradable_and_lock_sharable();   //Promotions   //!Precondition: The thread must have upgradable ownership of the mutex.    //!Effects: The thread atomically releases upgradable ownership and acquires   //!   exclusive ownership. This operation will block until all threads with   //!   sharable ownership release their sharable lock.    //!Throws: An exception derived from interprocess_exception on error.   void unlock_upgradable_and_lock();   //!Precondition: The thread must have upgradable ownership of the mutex.    //!Effects: The thread atomically releases upgradable ownership and tries to   //!   acquire exclusive ownership. This operation will fail if there are threads   //!   with sharable ownership, but it will maintain upgradable ownership.    //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.   //!Throws: An exception derived from interprocess_exception on error.   bool try_unlock_upgradable_and_lock();   //!Precondition: The thread must have upgradable ownership of the mutex.    //!Effects: The thread atomically releases upgradable ownership and tries to acquire   //!   exclusive ownership, waiting if necessary until abs_time. This operation will   //!   fail if there are threads with sharable ownership or timeout reaches, but it   //!   will maintain upgradable ownership.    //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.    //!Throws: An exception derived from interprocess_exception on error. */   bool timed_unlock_upgradable_and_lock(const boost::posix_time::ptime &abs_time);   //!Precondition: The thread must have sharable ownership of the mutex.    //!Effects: The thread atomically releases sharable ownership and tries to acquire   //!   exclusive ownership. This operation will fail if there are threads with sharable   //!   or upgradable ownership, but it will maintain sharable ownership.   //!Returns: If acquires exclusive ownership, returns true. Otherwise returns false.    //!Throws: An exception derived from interprocess_exception on error.   bool try_unlock_sharable_and_lock();   //!Precondition: The thread must have sharable ownership of the mutex.    //!Effects: The thread atomically releases sharable ownership and tries to acquire   //!   upgradable ownership. This operation will fail if there are threads with sharable   //!   or upgradable ownership, but it will maintain sharable ownership.    //!Returns: If acquires upgradable ownership, returns true. Otherwise returns false.    //!Throws: An exception derived from interprocess_exception on error.   bool try_unlock_sharable_and_lock_upgradable();   /// @cond   private:   typedef scoped_lock<interprocess_mutex> scoped_lock_t;   //Pack all the control data in a word to be able   //to use atomic instructions in the future   struct control_word_t   {      unsigned exclusive_in         : 1;      unsigned upgradable_in        : 1;      unsigned num_upr_shar         : sizeof(unsigned)*CHAR_BIT-2;   }                       m_ctrl;   interprocess_mutex      m_mut;   interprocess_condition  m_first_gate;   interprocess_condition  m_second_gate;   private:   //Rollback structures for exceptions or failure return values   struct exclusive_rollback   {      exclusive_rollback(control_word_t         &ctrl                        ,interprocess_condition &first_gate)         :  mp_ctrl(&ctrl), m_first_gate(first_gate)      {}      void release()      {  mp_ctrl = 0;   }      ~exclusive_rollback()      {         if(mp_ctrl){            mp_ctrl->exclusive_in = 0;            m_first_gate.notify_all();         }      }      control_word_t          *mp_ctrl;      interprocess_condition  &m_first_gate;   };   struct upgradable_to_exclusive_rollback   {      upgradable_to_exclusive_rollback(control_word_t         &ctrl)         :  mp_ctrl(&ctrl)      {}      void release()      {  mp_ctrl = 0;   }      ~upgradable_to_exclusive_rollback()      {         if(mp_ctrl){            //Recover upgradable lock            mp_ctrl->upgradable_in = 1;            ++mp_ctrl->num_upr_shar;               //Execute the second half of exclusive locking            mp_ctrl->exclusive_in = 0;         }      }      control_word_t          *mp_ctrl;   };   template<int Dummy>   struct base_constants_t   {      static const unsigned max_readers          = ~(unsigned(3) << (sizeof(unsigned)*CHAR_BIT-2));   };   typedef base_constants_t<0> constants;   /// @endcond};/// @condtemplate <int Dummy>const unsigned interprocess_upgradable_mutex::base_constants_t<Dummy>::max_readers;inline interprocess_upgradable_mutex::interprocess_upgradable_mutex(){   this->m_ctrl.exclusive_in  = 0;   this->m_ctrl.upgradable_in = 0;   this->m_ctrl.num_upr_shar   = 0;}inline interprocess_upgradable_mutex::~interprocess_upgradable_mutex(){}inline void interprocess_upgradable_mutex::lock(){   scoped_lock_t lock(m_mut);   //The exclusive lock must block in the first gate   //if an exclusive or upgradable lock has been acquired   while (this->m_ctrl.exclusive_in || this->m_ctrl.upgradable_in){      this->m_first_gate.wait(lock);   }   //Mark that exclusive lock has been acquired   this->m_ctrl.exclusive_in = 1;   //Prepare rollback   exclusive_rollback rollback(this->m_ctrl, this->m_first_gate);   //Now wait until all readers are gone   while (this->m_ctrl.num_upr_shar){      this->m_second_gate.wait(lock);   }   rollback.release();}inline bool interprocess_upgradable_mutex::try_lock(){   scoped_lock_t lock(m_mut, try_to_lock);   //If we can't lock or any has there is any exclusive, upgradable    //or sharable mark return false;   if(!lock.owns()       || this->m_ctrl.exclusive_in       || this->m_ctrl.num_upr_shar){      return false;   }   this->m_ctrl.exclusive_in = 1;   return true;}inline bool interprocess_upgradable_mutex::timed_lock   (const boost::posix_time::ptime &abs_time){   if(abs_time == boost::posix_time::pos_infin){      this->lock();      return true;   }   scoped_lock_t lock(m_mut, abs_time);   if(!lock.owns())   return false;

⌨️ 快捷键说明

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