Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-13 08:10:30

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 // Parts of the pthread code come from Boost Threads code:
0012 //
0013 //////////////////////////////////////////////////////////////////////////////
0014 //
0015 // Copyright (C) 2001-2003
0016 // William E. Kempf
0017 //
0018 // Permission to use, copy, modify, distribute and sell this software
0019 // and its documentation for any purpose is hereby granted without fee,
0020 // provided that the above copyright notice appear in all copies and
0021 // that both that copyright notice and this permission notice appear
0022 // in supporting documentation.  William E. Kempf makes no representations
0023 // about the suitability of this software for any purpose.
0024 // It is provided "as is" without express or implied warranty.
0025 //////////////////////////////////////////////////////////////////////////////
0026 
0027 #ifndef BOOST_INTERPROCESS_DETAIL_SPIN_RECURSIVE_MUTEX_HPP
0028 #define BOOST_INTERPROCESS_DETAIL_SPIN_RECURSIVE_MUTEX_HPP
0029 
0030 #ifndef BOOST_CONFIG_HPP
0031 #  include <boost/config.hpp>
0032 #endif
0033 0034 ">#
0035 #if defined(BOOST_HAS_PRAGMA_ONCE)
0036 #  pragma once
0037 #endif
0038 
0039 #include <boost/interprocess/detail/config_begin.hpp>
0040 #include <boost/interprocess/detail/workaround.hpp>
0041 
0042 #include <boost/interprocess/detail/os_thread_functions.hpp>
0043 #include <boost/interprocess/exceptions.hpp>
0044 #include <boost/interprocess/detail/atomic.hpp>
0045 #include <boost/cstdint.hpp>
0046 #include <boost/interprocess/detail/os_thread_functions.hpp>
0047 #include <boost/interprocess/sync/spin/mutex.hpp>
0048 #include <boost/interprocess/timed_utils.hpp>
0049 #include <boost/assert.hpp>
0050 
0051 namespace boost {
0052 namespace interprocess {
0053 namespace ipcdetail {
0054 
0055 class spin_recursive_mutex
0056 {
0057    spin_recursive_mutex(const spin_recursive_mutex &);
0058    spin_recursive_mutex &operator=(const spin_recursive_mutex &);
0059    public:
0060 
0061    spin_recursive_mutex();
0062    ~spin_recursive_mutex();
0063 
0064    void lock();
0065    bool try_lock();
0066    template<class TimePoint>
0067    bool timed_lock(const TimePoint &abs_time);
0068 
0069    template<class TimePoint> bool try_lock_until(const TimePoint &abs_time)
0070    {  return this->timed_lock(abs_time);  }
0071 
0072    template<class Duration>  bool try_lock_for(const Duration &dur)
0073    {  return this->timed_lock(duration_to_ustime(dur)); }
0074 
0075    void unlock();
0076    void take_ownership();
0077    private:
0078    spin_mutex     m_mutex;
0079    unsigned int   m_nLockCount;
0080    volatile ipcdetail::OS_systemwide_thread_id_t   m_nOwner;
0081    volatile boost::uint32_t m_s;
0082 };
0083 
0084 inline spin_recursive_mutex::spin_recursive_mutex()
0085    : m_nLockCount(0), m_nOwner(ipcdetail::get_invalid_systemwide_thread_id()){}
0086 
0087 inline spin_recursive_mutex::~spin_recursive_mutex(){}
0088 
0089 inline void spin_recursive_mutex::lock()
0090 {
0091    typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0092    const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0093    handle_t old_id;
0094    ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0095    if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)){
0096       if((unsigned int)(m_nLockCount+1) == 0){
0097          //Overflow, throw an exception
0098          throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
0099       }
0100       ++m_nLockCount;
0101    }
0102    else{
0103       m_mutex.lock();
0104       ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0105       m_nLockCount = 1;
0106    }
0107 }
0108 
0109 inline bool spin_recursive_mutex::try_lock()
0110 {
0111    typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0112    handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0113    handle_t old_id;
0114    ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0115    if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)) {  // we own it
0116       if((unsigned int)(m_nLockCount+1) == 0){
0117          //Overflow, throw an exception
0118          throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
0119       }
0120       ++m_nLockCount;
0121       return true;
0122    }
0123    if(m_mutex.try_lock()){
0124       ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0125       m_nLockCount = 1;
0126       return true;
0127    }
0128    return false;
0129 }
0130 
0131 template<class TimePoint>
0132 inline bool spin_recursive_mutex::timed_lock(const TimePoint &abs_time)
0133 {
0134    typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0135    const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0136    handle_t old_id;
0137    ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0138    if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)) {  // we own it
0139       if((unsigned int)(m_nLockCount+1) == 0){
0140          //Overflow, throw an exception
0141          throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
0142       }
0143       ++m_nLockCount;
0144       return true;
0145    }
0146    //m_mutex supports abs_time so no need to check it
0147    if(m_mutex.timed_lock(abs_time)){
0148       ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0149       m_nLockCount = 1;
0150       return true;
0151    }
0152    return false;
0153 }
0154 
0155 inline void spin_recursive_mutex::unlock()
0156 {
0157    typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0158    handle_t old_id;
0159    ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0160    const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0161    (void)old_id;
0162    (void)thr_id;
0163    BOOST_ASSERT(ipcdetail::equal_systemwide_thread_id(thr_id, old_id));
0164    --m_nLockCount;
0165    if(!m_nLockCount){
0166       const handle_t new_id(ipcdetail::get_invalid_systemwide_thread_id());
0167       ipcdetail::systemwide_thread_id_copy(new_id, m_nOwner);
0168       m_mutex.unlock();
0169    }
0170 }
0171 
0172 inline void spin_recursive_mutex::take_ownership()
0173 {
0174    typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0175    this->m_nLockCount = 1;
0176    const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0177    ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0178 }
0179 
0180 }  //namespace ipcdetail {
0181 }  //namespace interprocess {
0182 }  //namespace boost {
0183 
0184 #include <boost/interprocess/detail/config_end.hpp>
0185 
0186 #endif   //BOOST_INTERPROCESS_DETAIL_SPIN_RECURSIVE_MUTEX_HPP