Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:32

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