1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2005-2012. 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_POSIX_RECURSIVE_MUTEX_HPP 28 #define BOOST_INTERPROCESS_DETAIL_POSIX_RECURSIVE_MUTEX_HPP 29 30 #ifndef BOOST_CONFIG_HPP 31 # include <boost/config.hpp> 32 #endif 33 # 34 #if defined(BOOST_HAS_PRAGMA_ONCE) 35 # pragma once 36 #endif 37 38 #include <boost/interprocess/detail/config_begin.hpp> 39 #include <boost/interprocess/detail/workaround.hpp> 40 41 #include <pthread.h> 42 #include <errno.h> 43 #include <boost/interprocess/sync/posix/pthread_helpers.hpp> 44 #include <boost/interprocess/sync/posix/ptime_to_timespec.hpp> 45 #include <boost/interprocess/detail/posix_time_types_wrk.hpp> 46 #include <boost/interprocess/exceptions.hpp> 47 #ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS 48 # include <boost/interprocess/detail/os_thread_functions.hpp> 49 # include <boost/interprocess/sync/detail/common_algorithms.hpp> 50 #endif 51 #include <boost/assert.hpp> 52 53 namespace boost { 54 namespace interprocess { 55 namespace ipcdetail { 56 57 class posix_recursive_mutex 58 { 59 posix_recursive_mutex(const posix_recursive_mutex &); 60 posix_recursive_mutex &operator=(const posix_recursive_mutex &); 61 public: 62 63 posix_recursive_mutex(); 64 ~posix_recursive_mutex(); 65 66 void lock(); 67 bool try_lock(); 68 bool timed_lock(const boost::posix_time::ptime &abs_time); 69 void unlock(); 70 71 private: 72 pthread_mutex_t m_mut; 73 }; 74 posix_recursive_mutex()75inline posix_recursive_mutex::posix_recursive_mutex() 76 { 77 mutexattr_wrapper mut_attr(true); 78 mutex_initializer mut(m_mut, mut_attr); 79 mut.release(); 80 } 81 ~posix_recursive_mutex()82inline posix_recursive_mutex::~posix_recursive_mutex() 83 { 84 int res = pthread_mutex_destroy(&m_mut); 85 BOOST_ASSERT(res == 0);(void)res; 86 } 87 lock()88inline void posix_recursive_mutex::lock() 89 { 90 if (pthread_mutex_lock(&m_mut) != 0) 91 throw lock_exception(); 92 } 93 try_lock()94inline bool posix_recursive_mutex::try_lock() 95 { 96 int res = pthread_mutex_trylock(&m_mut); 97 if (!(res == 0 || res == EBUSY)) 98 throw lock_exception(); 99 return res == 0; 100 } 101 timed_lock(const boost::posix_time::ptime & abs_time)102inline bool posix_recursive_mutex::timed_lock(const boost::posix_time::ptime &abs_time) 103 { 104 #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS 105 //Posix does not support infinity absolute time so handle it here 106 if(abs_time.is_pos_infinity()){ 107 this->lock(); 108 return true; 109 } 110 111 timespec ts = ptime_to_timespec(abs_time); 112 int res = pthread_mutex_timedlock(&m_mut, &ts); 113 if (res != 0 && res != ETIMEDOUT) 114 throw lock_exception(); 115 return res == 0; 116 117 #else //BOOST_INTERPROCESS_POSIX_TIMEOUTS 118 119 return ipcdetail::try_based_timed_lock(*this, abs_time); 120 121 #endif //BOOST_INTERPROCESS_POSIX_TIMEOUTS 122 } 123 unlock()124inline void posix_recursive_mutex::unlock() 125 { 126 int res = 0; 127 res = pthread_mutex_unlock(&m_mut); 128 BOOST_ASSERT(res == 0); (void)res; 129 } 130 131 } //namespace ipcdetail { 132 } //namespace interprocess { 133 } //namespace boost { 134 135 #include <boost/interprocess/detail/config_end.hpp> 136 137 #endif //#ifndef BOOST_INTERPROCESS_DETAIL_POSIX_RECURSIVE_MUTEX_HPP 138