PageRenderTime 28ms CodeModel.GetById 2ms app.highlight 19ms RepoModel.GetById 5ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/interprocess/sync/emulation/recursive_mutex.hpp

http://hadesmem.googlecode.com/
C++ Header | 167 lines | 124 code | 15 blank | 28 comment | 14 complexity | 4d11859dbf87e2ea2995af25dfa86b3d MD5 | raw file
  1//////////////////////////////////////////////////////////////////////////////
  2//
  3// (C) Copyright Ion Gaztanaga 2005-2009. Distributed under the Boost
  4// Software License, Version 1.0. (See accompanying file
  5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6//
  7// See http://www.boost.org/libs/interprocess for documentation.
  8//
  9//////////////////////////////////////////////////////////////////////////////
 10//
 11// Parts of the pthread code come from Boost Threads code:
 12//
 13//////////////////////////////////////////////////////////////////////////////
 14//
 15// Copyright (C) 2001-2003
 16// William E. Kempf
 17//
 18// Permission to use, copy, modify, distribute and sell this software
 19// and its documentation for any purpose is hereby granted without fee,
 20// provided that the above copyright notice appear in all copies and
 21// that both that copyright notice and this permission notice appear
 22// in supporting documentation.  William E. Kempf makes no representations
 23// about the suitability of this software for any purpose.
 24// It is provided "as is" without express or implied warranty.
 25//////////////////////////////////////////////////////////////////////////////
 26
 27#ifndef BOOST_INTERPROCESS_DETAIL_EMULATION_RECURSIVE_MUTEX_HPP
 28#define BOOST_INTERPROCESS_DETAIL_EMULATION_RECURSIVE_MUTEX_HPP
 29
 30#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 31#include <boost/interprocess/detail/os_thread_functions.hpp>
 32#include <boost/interprocess/exceptions.hpp>
 33#include <boost/interprocess/detail/atomic.hpp>
 34#include <boost/cstdint.hpp>
 35#include <boost/interprocess/detail/os_thread_functions.hpp>
 36#include <boost/interprocess/sync/emulation/mutex.hpp>
 37#include <boost/assert.hpp>
 38
 39namespace boost {
 40namespace interprocess {
 41namespace detail {
 42
 43class emulation_recursive_mutex
 44{
 45   emulation_recursive_mutex(const emulation_recursive_mutex &);
 46   emulation_recursive_mutex &operator=(const emulation_recursive_mutex &);
 47   public:
 48
 49   emulation_recursive_mutex();
 50   ~emulation_recursive_mutex();
 51
 52   void lock();
 53   bool try_lock();
 54   bool timed_lock(const boost::posix_time::ptime &abs_time);
 55   void unlock();
 56   void take_ownership();
 57   private:
 58   emulation_mutex                     m_mutex;
 59   unsigned int                        m_nLockCount;
 60   volatile detail::OS_systemwide_thread_id_t   m_nOwner;
 61   volatile boost::uint32_t m_s;
 62};
 63
 64inline emulation_recursive_mutex::emulation_recursive_mutex() 
 65   : m_nLockCount(0), m_nOwner(detail::get_invalid_systemwide_thread_id()){}
 66
 67inline emulation_recursive_mutex::~emulation_recursive_mutex(){}
 68
 69inline void emulation_recursive_mutex::lock()
 70{
 71   typedef detail::OS_systemwide_thread_id_t handle_t;
 72   const handle_t thr_id(detail::get_current_systemwide_thread_id());
 73   handle_t old_id;
 74   detail::systemwide_thread_id_copy(m_nOwner, old_id);
 75   if(detail::equal_systemwide_thread_id(thr_id , old_id)){
 76      if((unsigned int)(m_nLockCount+1) == 0){
 77         //Overflow, throw an exception
 78         throw interprocess_exception("boost::interprocess::emulation_recursive_mutex recursive lock overflow");
 79      } 
 80      ++m_nLockCount;
 81   }
 82   else{
 83      m_mutex.lock();
 84      detail::systemwide_thread_id_copy(thr_id, m_nOwner);
 85      m_nLockCount = 1;
 86   }
 87}
 88
 89inline bool emulation_recursive_mutex::try_lock()
 90{
 91   typedef detail::OS_systemwide_thread_id_t handle_t;
 92   handle_t thr_id(detail::get_current_systemwide_thread_id());
 93   handle_t old_id;
 94   detail::systemwide_thread_id_copy(m_nOwner, old_id);
 95   if(detail::equal_systemwide_thread_id(thr_id , old_id)) {  // we own it
 96      if((unsigned int)(m_nLockCount+1) == 0){
 97         //Overflow, throw an exception
 98         throw interprocess_exception("boost::interprocess::emulation_recursive_mutex recursive lock overflow");
 99      } 
100      ++m_nLockCount;
101      return true;
102   }
103   if(m_mutex.try_lock()){
104      detail::systemwide_thread_id_copy(thr_id, m_nOwner);
105      m_nLockCount = 1;
106      return true;
107   }
108   return false;
109}
110
111inline bool emulation_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
112{
113   typedef detail::OS_systemwide_thread_id_t handle_t;
114   if(abs_time == boost::posix_time::pos_infin){
115      this->lock();
116      return true;
117   }
118   const handle_t thr_id(detail::get_current_systemwide_thread_id());
119   handle_t old_id;
120   detail::systemwide_thread_id_copy(m_nOwner, old_id);
121   if(detail::equal_systemwide_thread_id(thr_id , old_id)) {  // we own it
122      if((unsigned int)(m_nLockCount+1) == 0){
123         //Overflow, throw an exception
124         throw interprocess_exception("boost::interprocess::emulation_recursive_mutex recursive lock overflow");
125      } 
126      ++m_nLockCount;
127      return true;
128   }
129   if(m_mutex.timed_lock(abs_time)){
130      detail::systemwide_thread_id_copy(thr_id, m_nOwner);
131      m_nLockCount = 1;
132      return true;
133   }
134   return false;
135}
136
137inline void emulation_recursive_mutex::unlock()
138{
139   typedef detail::OS_systemwide_thread_id_t handle_t;
140   handle_t old_id;
141   detail::systemwide_thread_id_copy(m_nOwner, old_id);
142   const handle_t thr_id(detail::get_current_systemwide_thread_id());
143   (void)old_id;
144   (void)thr_id;
145   BOOST_ASSERT(detail::equal_systemwide_thread_id(thr_id, old_id));
146   --m_nLockCount;
147   if(!m_nLockCount){
148      const handle_t new_id(detail::get_invalid_systemwide_thread_id());
149      detail::systemwide_thread_id_copy(new_id, m_nOwner);
150      m_mutex.unlock();
151   }
152}
153
154inline void emulation_recursive_mutex::take_ownership()
155{
156   typedef detail::OS_systemwide_thread_id_t handle_t;
157   this->m_nLockCount = 1;
158   const handle_t thr_id(detail::get_current_systemwide_thread_id());
159   detail::systemwide_thread_id_copy
160      (thr_id, m_nOwner);
161}
162
163}  //namespace detail {
164}  //namespace interprocess {
165}  //namespace boost {
166
167#endif   //BOOST_INTERPROCESS_DETAIL_EMULATION_RECURSIVE_MUTEX_HPP