File indexing completed on 2025-01-18 09:38:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #ifndef BOOST_INTERPROCESS_DETAIL_POSIX_RECURSIVE_MUTEX_HPP
0028 #define BOOST_INTERPROCESS_DETAIL_POSIX_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 <pthread.h>
0042 #include <errno.h>
0043 #include <boost/interprocess/sync/posix/pthread_helpers.hpp>
0044 #include <boost/interprocess/sync/posix/timepoint_to_timespec.hpp>
0045 #include <boost/interprocess/detail/timed_utils.hpp>
0046 #include <boost/interprocess/exceptions.hpp>
0047 #ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
0048 # include <boost/interprocess/detail/os_thread_functions.hpp>
0049 # include <boost/interprocess/sync/detail/common_algorithms.hpp>
0050 #endif
0051 #include <boost/assert.hpp>
0052
0053 namespace boost {
0054 namespace interprocess {
0055 namespace ipcdetail {
0056
0057 class posix_recursive_mutex
0058 {
0059 posix_recursive_mutex(const posix_recursive_mutex &);
0060 posix_recursive_mutex &operator=(const posix_recursive_mutex &);
0061 public:
0062
0063 posix_recursive_mutex();
0064 ~posix_recursive_mutex();
0065
0066 void lock();
0067 bool try_lock();
0068 template<class TimePoint> bool timed_lock(const TimePoint &abs_time);
0069 void unlock();
0070
0071 private:
0072 pthread_mutex_t m_mut;
0073 };
0074
0075 inline posix_recursive_mutex::posix_recursive_mutex()
0076 {
0077 mutexattr_wrapper mut_attr(true);
0078 mutex_initializer mut(m_mut, mut_attr);
0079 mut.release();
0080 }
0081
0082 inline posix_recursive_mutex::~posix_recursive_mutex()
0083 {
0084 int res = pthread_mutex_destroy(&m_mut);
0085 BOOST_ASSERT(res == 0);(void)res;
0086 }
0087
0088 inline void posix_recursive_mutex::lock()
0089 {
0090 int res = pthread_mutex_lock(&m_mut);
0091 #ifdef BOOST_INTERPROCESS_POSIX_ROBUST_MUTEXES
0092 if (res == EOWNERDEAD)
0093 {
0094
0095
0096
0097 pthread_mutex_unlock(&m_mut);
0098 throw lock_exception(not_recoverable);
0099 }
0100 else if (res == ENOTRECOVERABLE)
0101 throw lock_exception(not_recoverable);
0102 #endif
0103 if (res != 0)
0104 throw lock_exception();
0105 }
0106
0107 inline bool posix_recursive_mutex::try_lock()
0108 {
0109 int res = pthread_mutex_trylock(&m_mut);
0110 #ifdef BOOST_INTERPROCESS_POSIX_ROBUST_MUTEXES
0111 if (res == EOWNERDEAD)
0112 {
0113
0114
0115
0116 pthread_mutex_unlock(&m_mut);
0117 throw lock_exception(not_recoverable);
0118 }
0119 else if (res == ENOTRECOVERABLE)
0120 throw lock_exception(not_recoverable);
0121 #endif
0122 if (!(res == 0 || res == EBUSY))
0123 throw lock_exception();
0124 return (res == 0);
0125 }
0126
0127 template<class TimePoint>
0128 inline bool posix_recursive_mutex::timed_lock(const TimePoint &abs_time)
0129 {
0130 #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
0131
0132 if(ipcdetail::is_pos_infinity(abs_time)){
0133 this->lock();
0134 return true;
0135 }
0136
0137 timespec ts = timepoint_to_timespec(abs_time);
0138 int res = pthread_mutex_timedlock(&m_mut, &ts);
0139 #ifdef BOOST_INTERPROCESS_POSIX_ROBUST_MUTEXES
0140 if (res == EOWNERDEAD)
0141 {
0142
0143
0144
0145 pthread_mutex_unlock(&m_mut);
0146 throw lock_exception(not_recoverable);
0147 }
0148 else if (res == ENOTRECOVERABLE)
0149 throw lock_exception(not_recoverable);
0150 #endif
0151 if (res != 0 && res != ETIMEDOUT)
0152 throw lock_exception();
0153 return res == 0;
0154
0155 #else
0156
0157 return ipcdetail::try_based_timed_lock(*this, abs_time);
0158
0159 #endif
0160 }
0161
0162 inline void posix_recursive_mutex::unlock()
0163 {
0164 int res = 0;
0165 res = pthread_mutex_unlock(&m_mut);
0166 BOOST_ASSERT(res == 0); (void)res;
0167 }
0168
0169 }
0170 }
0171 }
0172
0173 #include <boost/interprocess/detail/config_end.hpp>
0174
0175 #endif