Back to home page

EIC code displayed by LXR

 
 

    


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

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 #if defined(BOOST_HAS_PRAGMA_ONCE)
0035 #  pragma once
0036 #endif
0037 
0038 #include <boost/interprocess/detail/config_begin.hpp>
0039 #include <boost/interprocess/detail/workaround.hpp>
0040 
0041 #include <boost/interprocess/detail/os_thread_functions.hpp>
0042 #include <boost/interprocess/exceptions.hpp>
0043 #include <boost/interprocess/detail/atomic.hpp>
0044 #include <boost/cstdint.hpp>
0045 #include <boost/interprocess/detail/os_thread_functions.hpp>
0046 #include <boost/interprocess/sync/spin/mutex.hpp>
0047 #include <boost/interprocess/timed_utils.hpp>
0048 #include <boost/assert.hpp>
0049 
0050 namespace boost {
0051 namespace interprocess {
0052 namespace ipcdetail {
0053 
0054 class spin_recursive_mutex
0055 {
0056    spin_recursive_mutex(const spin_recursive_mutex &);
0057    spin_recursive_mutex &operator=(const spin_recursive_mutex &);
0058    public:
0059 
0060    spin_recursive_mutex();
0061    ~spin_recursive_mutex();
0062 
0063    void lock();
0064    bool try_lock();
0065    template<class TimePoint>
0066    bool timed_lock(const TimePoint &abs_time);
0067 
0068    template<class TimePoint> bool try_lock_until(const TimePoint &abs_time)
0069    {  return this->timed_lock(abs_time);  }
0070 
0071    template<class Duration>  bool try_lock_for(const Duration &dur)
0072    {  return this->timed_lock(duration_to_ustime(dur)); }
0073 
0074    void unlock();
0075    void take_ownership();
0076    private:
0077    spin_mutex     m_mutex;
0078    unsigned int   m_nLockCount;
0079    volatile ipcdetail::OS_systemwide_thread_id_t   m_nOwner;
0080    volatile boost::uint32_t m_s;
0081 };
0082 
0083 inline spin_recursive_mutex::spin_recursive_mutex()
0084    : m_nLockCount(0), m_nOwner(ipcdetail::get_invalid_systemwide_thread_id()){}
0085 
0086 inline spin_recursive_mutex::~spin_recursive_mutex(){}
0087 
0088 inline void spin_recursive_mutex::lock()
0089 {
0090    typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0091    const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0092    handle_t old_id;
0093    ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0094    if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)){
0095       if((unsigned int)(m_nLockCount+1) == 0){
0096          //Overflow, throw an exception
0097          throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
0098       }
0099       ++m_nLockCount;
0100    }
0101    else{
0102       m_mutex.lock();
0103       ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0104       m_nLockCount = 1;
0105    }
0106 }
0107 
0108 inline bool spin_recursive_mutex::try_lock()
0109 {
0110    typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0111    handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0112    handle_t old_id;
0113    ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0114    if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)) {  // we own it
0115       if((unsigned int)(m_nLockCount+1) == 0){
0116          //Overflow, throw an exception
0117          throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
0118       }
0119       ++m_nLockCount;
0120       return true;
0121    }
0122    if(m_mutex.try_lock()){
0123       ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0124       m_nLockCount = 1;
0125       return true;
0126    }
0127    return false;
0128 }
0129 
0130 template<class TimePoint>
0131 inline bool spin_recursive_mutex::timed_lock(const TimePoint &abs_time)
0132 {
0133    typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0134    const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0135    handle_t old_id;
0136    ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0137    if(ipcdetail::equal_systemwide_thread_id(thr_id , old_id)) {  // we own it
0138       if((unsigned int)(m_nLockCount+1) == 0){
0139          //Overflow, throw an exception
0140          throw interprocess_exception("boost::interprocess::spin_recursive_mutex recursive lock overflow");
0141       }
0142       ++m_nLockCount;
0143       return true;
0144    }
0145    //m_mutex supports abs_time so no need to check it
0146    if(m_mutex.timed_lock(abs_time)){
0147       ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0148       m_nLockCount = 1;
0149       return true;
0150    }
0151    return false;
0152 }
0153 
0154 inline void spin_recursive_mutex::unlock()
0155 {
0156    typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0157    handle_t old_id;
0158    ipcdetail::systemwide_thread_id_copy(m_nOwner, old_id);
0159    const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0160    (void)old_id;
0161    (void)thr_id;
0162    BOOST_ASSERT(ipcdetail::equal_systemwide_thread_id(thr_id, old_id));
0163    --m_nLockCount;
0164    if(!m_nLockCount){
0165       const handle_t new_id(ipcdetail::get_invalid_systemwide_thread_id());
0166       ipcdetail::systemwide_thread_id_copy(new_id, m_nOwner);
0167       m_mutex.unlock();
0168    }
0169 }
0170 
0171 inline void spin_recursive_mutex::take_ownership()
0172 {
0173    typedef ipcdetail::OS_systemwide_thread_id_t handle_t;
0174    this->m_nLockCount = 1;
0175    const handle_t thr_id(ipcdetail::get_current_systemwide_thread_id());
0176    ipcdetail::systemwide_thread_id_copy(thr_id, m_nOwner);
0177 }
0178 
0179 }  //namespace ipcdetail {
0180 }  //namespace interprocess {
0181 }  //namespace boost {
0182 
0183 #include <boost/interprocess/detail/config_end.hpp>
0184 
0185 #endif   //BOOST_INTERPROCESS_DETAIL_SPIN_RECURSIVE_MUTEX_HPP