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