File indexing completed on 2025-02-25 10:02:45
0001 #ifndef BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_QUEUE_BASE_HPP
0002 #define BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_QUEUE_BASE_HPP
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <boost/bind/bind.hpp>
0015
0016 #include <boost/thread/detail/config.hpp>
0017 #include <boost/thread/condition_variable.hpp>
0018 #include <boost/thread/detail/move.hpp>
0019 #include <boost/thread/mutex.hpp>
0020 #include <boost/thread/concurrent_queues/queue_op_status.hpp>
0021
0022 #include <boost/chrono/time_point.hpp>
0023 #include <boost/throw_exception.hpp>
0024
0025 #include <boost/config/abi_prefix.hpp>
0026
0027 namespace boost
0028 {
0029 namespace concurrent
0030 {
0031 namespace detail
0032 {
0033
0034 template <class ValueType, class Queue>
0035 class sync_queue_base
0036 {
0037 public:
0038 typedef ValueType value_type;
0039 typedef Queue underlying_queue_type;
0040 typedef typename Queue::size_type size_type;
0041 typedef queue_op_status op_status;
0042
0043
0044 BOOST_THREAD_NO_COPYABLE(sync_queue_base)
0045 inline sync_queue_base();
0046
0047
0048 inline ~sync_queue_base();
0049
0050
0051 inline bool empty() const;
0052 inline bool full() const;
0053 inline size_type size() const;
0054 inline bool closed() const;
0055
0056
0057 inline void close();
0058
0059 inline underlying_queue_type underlying_queue() {
0060 lock_guard<mutex> lk(mtx_);
0061 return boost::move(data_);
0062 }
0063
0064 protected:
0065 mutable mutex mtx_;
0066 condition_variable cond_;
0067 underlying_queue_type data_;
0068 bool closed_;
0069
0070 inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
0071 {
0072 return data_.empty();
0073 }
0074 inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
0075 {
0076 return data_.empty();
0077 }
0078
0079 inline size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
0080 {
0081 return data_.size();
0082 }
0083 inline bool closed(unique_lock<mutex>& lk) const;
0084 inline bool closed(lock_guard<mutex>& lk) const;
0085
0086 inline void throw_if_closed(unique_lock<mutex>&);
0087 inline void throw_if_closed(lock_guard<mutex>&);
0088
0089 inline bool not_empty_or_closed(unique_lock<mutex>& ) const;
0090
0091 inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
0092 template <class WClock, class Duration>
0093 queue_op_status wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp);
0094
0095 inline void notify_elem_added(unique_lock<mutex>& )
0096 {
0097 cond_.notify_all();
0098 }
0099 inline void notify_elem_added(lock_guard<mutex>& )
0100 {
0101 cond_.notify_all();
0102 }
0103
0104 };
0105
0106 template <class ValueType, class Queue>
0107 sync_queue_base<ValueType, Queue>::sync_queue_base() :
0108 data_(), closed_(false)
0109 {
0110 BOOST_ASSERT(data_.empty());
0111 }
0112
0113 template <class ValueType, class Queue>
0114 sync_queue_base<ValueType, Queue>::~sync_queue_base()
0115 {
0116 }
0117
0118 template <class ValueType, class Queue>
0119 void sync_queue_base<ValueType, Queue>::close()
0120 {
0121 {
0122 lock_guard<mutex> lk(mtx_);
0123 closed_ = true;
0124 }
0125 cond_.notify_all();
0126 }
0127
0128 template <class ValueType, class Queue>
0129 bool sync_queue_base<ValueType, Queue>::closed() const
0130 {
0131 lock_guard<mutex> lk(mtx_);
0132 return closed(lk);
0133 }
0134 template <class ValueType, class Queue>
0135 bool sync_queue_base<ValueType, Queue>::closed(unique_lock<mutex>&) const
0136 {
0137 return closed_;
0138 }
0139 template <class ValueType, class Queue>
0140 bool sync_queue_base<ValueType, Queue>::closed(lock_guard<mutex>&) const
0141 {
0142 return closed_;
0143 }
0144
0145 template <class ValueType, class Queue>
0146 bool sync_queue_base<ValueType, Queue>::empty() const
0147 {
0148 lock_guard<mutex> lk(mtx_);
0149 return empty(lk);
0150 }
0151 template <class ValueType, class Queue>
0152 bool sync_queue_base<ValueType, Queue>::full() const
0153 {
0154 return false;
0155 }
0156
0157 template <class ValueType, class Queue>
0158 typename sync_queue_base<ValueType, Queue>::size_type sync_queue_base<ValueType, Queue>::size() const
0159 {
0160 lock_guard<mutex> lk(mtx_);
0161 return size(lk);
0162 }
0163
0164 template <class ValueType, class Queue>
0165 void sync_queue_base<ValueType, Queue>::throw_if_closed(unique_lock<mutex>& lk)
0166 {
0167 if (closed(lk))
0168 {
0169 BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
0170 }
0171 }
0172 template <class ValueType, class Queue>
0173 void sync_queue_base<ValueType, Queue>::throw_if_closed(lock_guard<mutex>& lk)
0174 {
0175 if (closed(lk))
0176 {
0177 BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
0178 }
0179 }
0180
0181 template <class ValueType, class Queue>
0182 bool sync_queue_base<ValueType, Queue>::not_empty_or_closed(unique_lock<mutex>& ) const
0183 {
0184 return ! data_.empty() || closed_;
0185 }
0186
0187 template <class ValueType, class Queue>
0188 bool sync_queue_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
0189 {
0190 cond_.wait(lk, boost::bind(&sync_queue_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk)));
0191 if (! empty(lk)) return false;
0192 return true;
0193 }
0194
0195 template <class ValueType, class Queue>
0196 template <class WClock, class Duration>
0197 queue_op_status sync_queue_base<ValueType, Queue>::wait_until_not_empty_or_closed_until(unique_lock<mutex>& lk, chrono::time_point<WClock,Duration> const&tp)
0198 {
0199 if (! cond_.wait_until(lk, tp, boost::bind(&sync_queue_base<ValueType, Queue>::not_empty_or_closed, boost::ref(*this), boost::ref(lk))))
0200 return queue_op_status::timeout;
0201 if (! empty(lk)) return queue_op_status::success;
0202 return queue_op_status::closed;
0203 }
0204
0205 }
0206 }
0207 }
0208
0209 #include <boost/config/abi_suffix.hpp>
0210
0211 #endif