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_MUTEX_HPP
0028 #define BOOST_INTERPROCESS_DETAIL_POSIX_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/exceptions.hpp>
0044 #include <boost/interprocess/sync/posix/timepoint_to_timespec.hpp>
0045 #include <boost/interprocess/exceptions.hpp>
0046 #include <boost/interprocess/sync/posix/pthread_helpers.hpp>
0047 #include <boost/interprocess/detail/timed_utils.hpp>
0048
0049
0050 #ifndef BOOST_INTERPROCESS_POSIX_TIMEOUTS
0051 # include <boost/interprocess/detail/os_thread_functions.hpp>
0052 # include <boost/interprocess/sync/detail/common_algorithms.hpp>
0053 #endif
0054 #include <boost/assert.hpp>
0055
0056 namespace boost {
0057 namespace interprocess {
0058 namespace ipcdetail {
0059
0060 class posix_condition;
0061
0062 class posix_mutex
0063 {
0064 posix_mutex(const posix_mutex &);
0065 posix_mutex &operator=(const posix_mutex &);
0066 public:
0067
0068 posix_mutex();
0069 ~posix_mutex();
0070
0071 void lock();
0072 bool try_lock();
0073 template<class TimePoint> bool timed_lock(const TimePoint &abs_time);
0074
0075 template<class TimePoint> bool try_lock_until(const TimePoint &abs_time)
0076 { return this->timed_lock(abs_time); }
0077
0078 template<class Duration> bool try_lock_for(const Duration &dur)
0079 { return this->timed_lock(duration_to_ustime(dur)); }
0080
0081 void unlock();
0082
0083 friend class posix_condition;
0084
0085 private:
0086 pthread_mutex_t m_mut;
0087 };
0088
0089 inline posix_mutex::posix_mutex()
0090 {
0091 mutexattr_wrapper mut_attr;
0092 mutex_initializer mut(m_mut, mut_attr);
0093 mut.release();
0094 }
0095
0096 inline posix_mutex::~posix_mutex()
0097 {
0098 int res = pthread_mutex_destroy(&m_mut);
0099 BOOST_ASSERT(res == 0);(void)res;
0100 }
0101
0102 inline void posix_mutex::lock()
0103 {
0104 int res = pthread_mutex_lock(&m_mut);
0105 #ifdef BOOST_INTERPROCESS_POSIX_ROBUST_MUTEXES
0106 if (res == EOWNERDEAD)
0107 {
0108
0109
0110
0111 pthread_mutex_unlock(&m_mut);
0112 throw lock_exception(not_recoverable);
0113 }
0114 else if (res == ENOTRECOVERABLE)
0115 throw lock_exception(not_recoverable);
0116 #endif
0117 if (res != 0)
0118 throw lock_exception();
0119 }
0120
0121 inline bool posix_mutex::try_lock()
0122 {
0123 int res = pthread_mutex_trylock(&m_mut);
0124 #ifdef BOOST_INTERPROCESS_POSIX_ROBUST_MUTEXES
0125 if (res == EOWNERDEAD)
0126 {
0127
0128
0129
0130 pthread_mutex_unlock(&m_mut);
0131 throw lock_exception(not_recoverable);
0132 }
0133 else if (res == ENOTRECOVERABLE)
0134 throw lock_exception(not_recoverable);
0135 #endif
0136 if (!(res == 0 || res == EBUSY))
0137 throw lock_exception();
0138 return res == 0;
0139 }
0140
0141 template<class TimePoint>
0142 inline bool posix_mutex::timed_lock(const TimePoint &abs_time)
0143 {
0144 #ifdef BOOST_INTERPROCESS_POSIX_TIMEOUTS
0145
0146 if(ipcdetail::is_pos_infinity(abs_time)){
0147 this->lock();
0148 return true;
0149 }
0150 timespec ts = timepoint_to_timespec(abs_time);
0151 int res = pthread_mutex_timedlock(&m_mut, &ts);
0152 #ifdef BOOST_INTERPROCESS_POSIX_ROBUST_MUTEXES
0153 if (res == EOWNERDEAD)
0154 {
0155
0156
0157
0158 pthread_mutex_unlock(&m_mut);
0159 throw lock_exception(not_recoverable);
0160 }
0161 else if (res == ENOTRECOVERABLE)
0162 throw lock_exception(not_recoverable);
0163 #endif
0164 if (res != 0 && res != ETIMEDOUT)
0165 throw lock_exception();
0166 return res == 0;
0167
0168 #else
0169
0170 return ipcdetail::try_based_timed_lock(*this, abs_time);
0171
0172 #endif
0173 }
0174
0175 inline void posix_mutex::unlock()
0176 {
0177 int res = pthread_mutex_unlock(&m_mut);
0178 (void)res;
0179 BOOST_ASSERT(res == 0);
0180 }
0181
0182 }
0183 }
0184 }
0185
0186 #include <boost/interprocess/detail/config_end.hpp>
0187
0188 #endif