File indexing completed on 2025-01-18 09:38:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_INTERPROCESS_POSIX_CONDITION_HPP
0012 #define BOOST_INTERPROCESS_POSIX_CONDITION_HPP
0013
0014 #ifndef BOOST_CONFIG_HPP
0015 # include <boost/config.hpp>
0016 #endif
0017 #
0018 #if defined(BOOST_HAS_PRAGMA_ONCE)
0019 # pragma once
0020 #endif
0021
0022 #include <boost/interprocess/detail/config_begin.hpp>
0023 #include <boost/interprocess/detail/workaround.hpp>
0024
0025 #include <boost/interprocess/sync/cv_status.hpp>
0026 #include <pthread.h>
0027 #include <errno.h>
0028 #include <boost/interprocess/sync/posix/pthread_helpers.hpp>
0029 #include <boost/interprocess/sync/posix/timepoint_to_timespec.hpp>
0030 #include <boost/interprocess/detail/timed_utils.hpp>
0031 #include <boost/interprocess/sync/posix/mutex.hpp>
0032 #include <boost/assert.hpp>
0033
0034 namespace boost {
0035 namespace interprocess {
0036 namespace ipcdetail {
0037
0038 class posix_condition
0039 {
0040
0041 posix_condition(const posix_condition &);
0042 posix_condition &operator=(const posix_condition &);
0043
0044 public:
0045
0046 posix_condition();
0047
0048
0049
0050 ~posix_condition();
0051
0052
0053
0054 void notify_one();
0055
0056
0057
0058 void notify_all();
0059
0060
0061
0062
0063 template <typename L>
0064 void wait(L& lock)
0065 {
0066 if (!lock)
0067 throw lock_exception();
0068 this->do_wait(*lock.mutex());
0069 }
0070
0071
0072
0073 template <typename L, typename Pr>
0074 void wait(L& lock, Pr pred)
0075 {
0076 if (!lock)
0077 throw lock_exception();
0078
0079 while (!pred())
0080 this->do_wait(*lock.mutex());
0081 }
0082
0083
0084
0085
0086
0087
0088 template <typename L, typename TimePoint>
0089 bool timed_wait(L& lock, const TimePoint &abs_time)
0090 {
0091 if (!lock)
0092 throw lock_exception();
0093
0094 if(ipcdetail::is_pos_infinity(abs_time)){
0095 this->wait(lock);
0096 return true;
0097 }
0098 return this->do_timed_wait(abs_time, *lock.mutex());
0099 }
0100
0101
0102
0103
0104 template <typename L, typename TimePoint, typename Pr>
0105 bool timed_wait(L& lock, const TimePoint &abs_time, Pr pred)
0106 {
0107 if (!lock)
0108 throw lock_exception();
0109
0110 if(ipcdetail::is_pos_infinity(abs_time)){
0111 this->wait(lock, pred);
0112 return true;
0113 }
0114 while (!pred()){
0115 if (!this->do_timed_wait(abs_time, *lock.mutex()))
0116 return pred();
0117 }
0118 return true;
0119 }
0120
0121
0122
0123 template <typename L, class TimePoint>
0124 cv_status wait_until(L& lock, const TimePoint &abs_time)
0125 { return this->timed_wait(lock, abs_time) ? cv_status::no_timeout : cv_status::timeout; }
0126
0127
0128
0129 template <typename L, class TimePoint, typename Pr>
0130 bool wait_until(L& lock, const TimePoint &abs_time, Pr pred)
0131 { return this->timed_wait(lock, abs_time, pred); }
0132
0133 template <typename L, class Duration>
0134 cv_status wait_for(L& lock, const Duration &dur)
0135 { return this->wait_until(lock, duration_to_ustime(dur)) ? cv_status::no_timeout : cv_status::timeout; }
0136
0137 template <typename L, class Duration, typename Pr>
0138 bool wait_for(L& lock, const Duration &dur, Pr pred)
0139 { return this->wait_until(lock, duration_to_ustime(dur), pred); }
0140
0141 void do_wait(posix_mutex &mut);
0142
0143 template<class TimePoint>
0144 bool do_timed_wait(const TimePoint &abs_time, posix_mutex &mut);
0145
0146 private:
0147 pthread_cond_t m_condition;
0148 };
0149
0150 inline posix_condition::posix_condition()
0151 {
0152 int res;
0153 pthread_condattr_t cond_attr;
0154 res = pthread_condattr_init(&cond_attr);
0155 if(res != 0){
0156 throw interprocess_exception("pthread_condattr_init failed");
0157 }
0158 res = pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
0159 if(res != 0){
0160 pthread_condattr_destroy(&cond_attr);
0161 throw interprocess_exception(res);
0162 }
0163 res = pthread_cond_init(&m_condition, &cond_attr);
0164 pthread_condattr_destroy(&cond_attr);
0165 if(res != 0){
0166 throw interprocess_exception(res);
0167 }
0168 }
0169
0170 inline posix_condition::~posix_condition()
0171 {
0172 int res = 0;
0173 res = pthread_cond_destroy(&m_condition);
0174 BOOST_ASSERT(res == 0); (void)res;
0175 }
0176
0177 inline void posix_condition::notify_one()
0178 {
0179 int res = 0;
0180 res = pthread_cond_signal(&m_condition);
0181 BOOST_ASSERT(res == 0); (void)res;
0182 }
0183
0184 inline void posix_condition::notify_all()
0185 {
0186 int res = 0;
0187 res = pthread_cond_broadcast(&m_condition);
0188 BOOST_ASSERT(res == 0); (void)res;
0189 }
0190
0191 inline void posix_condition::do_wait(posix_mutex &mut)
0192 {
0193 pthread_mutex_t* pmutex = &mut.m_mut;
0194 int res = 0;
0195 res = pthread_cond_wait(&m_condition, pmutex);
0196 BOOST_ASSERT(res == 0); (void)res;
0197 }
0198
0199 template<class TimePoint>
0200 inline bool posix_condition::do_timed_wait
0201 (const TimePoint &abs_time, posix_mutex &mut)
0202 {
0203 timespec ts = timepoint_to_timespec(abs_time);
0204 pthread_mutex_t* pmutex = &mut.m_mut;
0205 int res = 0;
0206 res = pthread_cond_timedwait(&m_condition, pmutex, &ts);
0207 BOOST_ASSERT(res == 0 || res == ETIMEDOUT);
0208
0209 return res != ETIMEDOUT;
0210 }
0211
0212 }
0213 }
0214 }
0215
0216 #include <boost/interprocess/detail/config_end.hpp>
0217
0218 #endif