]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/thread/include/boost/thread/concurrent_queues/detail/sync_deque_base.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / thread / include / boost / thread / concurrent_queues / detail / sync_deque_base.hpp
1 #ifndef BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_DEQUE_BASE_HPP
2 #define BOOST_THREAD_CONCURRENT_QUEUES_DETAIL_SYNC_DEQUE_BASE_HPP
3
4 //////////////////////////////////////////////////////////////////////////////
5 //
6 // (C) Copyright Vicente J. Botet Escriba 2013-2014. Distributed under the Boost
7 // Software License, Version 1.0. (See accompanying file
8 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 // See http://www.boost.org/libs/thread for documentation.
11 //
12 //////////////////////////////////////////////////////////////////////////////
13
14 #include <boost/thread/detail/config.hpp>
15 #include <boost/thread/condition_variable.hpp>
16 #include <boost/thread/detail/move.hpp>
17 #include <boost/thread/mutex.hpp>
18 #include <boost/thread/concurrent_queues/queue_op_status.hpp>
19
20 #include <boost/chrono/duration.hpp>
21 #include <boost/chrono/time_point.hpp>
22 #include <boost/chrono/system_clocks.hpp>
23 #include <boost/throw_exception.hpp>
24
25 #include <boost/config/abi_prefix.hpp>
26
27 namespace boost
28 {
29 namespace concurrent
30 {
31 namespace detail
32 {
33
34 template <class ValueType, class Queue>
35 class sync_deque_base
36 {
37 public:
38 typedef ValueType value_type;
39 typedef Queue underlying_queue_type;
40 typedef typename Queue::size_type size_type;
41 typedef queue_op_status op_status;
42
43 typedef typename chrono::steady_clock clock;
44 typedef typename clock::duration duration;
45 typedef typename clock::time_point time_point;
46
47 // Constructors/Assignment/Destructors
48 BOOST_THREAD_NO_COPYABLE(sync_deque_base)
49 inline sync_deque_base();
50 //template <typename Range>
51 //inline explicit sync_deque(Range range);
52 inline ~sync_deque_base();
53
54 // Observers
55 inline bool empty() const;
56 inline bool full() const;
57 inline size_type size() const;
58 inline bool closed() const;
59
60 // Modifiers
61 inline void close();
62
63 inline underlying_queue_type underlying_queue() {
64 lock_guard<mutex> lk(mtx_);
65 return boost::move(data_);
66 }
67
68 protected:
69 mutable mutex mtx_;
70 condition_variable not_empty_;
71 underlying_queue_type data_;
72 bool closed_;
73
74 inline bool empty(unique_lock<mutex>& ) const BOOST_NOEXCEPT
75 {
76 return data_.empty();
77 }
78 inline bool empty(lock_guard<mutex>& ) const BOOST_NOEXCEPT
79 {
80 return data_.empty();
81 }
82
83 inline size_type size(lock_guard<mutex>& ) const BOOST_NOEXCEPT
84 {
85 return data_.size();
86 }
87 inline bool closed(unique_lock<mutex>& lk) const;
88 inline bool closed(lock_guard<mutex>& lk) const;
89
90 inline void throw_if_closed(unique_lock<mutex>&);
91 inline void throw_if_closed(lock_guard<mutex>&);
92
93 inline void wait_until_not_empty(unique_lock<mutex>& lk);
94 inline bool wait_until_not_empty_or_closed(unique_lock<mutex>& lk);
95 inline queue_op_status wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&);
96
97 inline void notify_not_empty_if_needed(unique_lock<mutex>& )
98 {
99 not_empty_.notify_one();
100 }
101 inline void notify_not_empty_if_needed(lock_guard<mutex>& )
102 {
103 not_empty_.notify_one();
104 }
105
106 };
107
108 template <class ValueType, class Queue>
109 sync_deque_base<ValueType, Queue>::sync_deque_base() :
110 data_(), closed_(false)
111 {
112 BOOST_ASSERT(data_.empty());
113 }
114
115 template <class ValueType, class Queue>
116 sync_deque_base<ValueType, Queue>::~sync_deque_base()
117 {
118 }
119
120 template <class ValueType, class Queue>
121 void sync_deque_base<ValueType, Queue>::close()
122 {
123 {
124 lock_guard<mutex> lk(mtx_);
125 closed_ = true;
126 }
127 not_empty_.notify_all();
128 }
129
130 template <class ValueType, class Queue>
131 bool sync_deque_base<ValueType, Queue>::closed() const
132 {
133 lock_guard<mutex> lk(mtx_);
134 return closed(lk);
135 }
136 template <class ValueType, class Queue>
137 bool sync_deque_base<ValueType, Queue>::closed(unique_lock<mutex>&) const
138 {
139 return closed_;
140 }
141 template <class ValueType, class Queue>
142 bool sync_deque_base<ValueType, Queue>::closed(lock_guard<mutex>&) const
143 {
144 return closed_;
145 }
146
147 template <class ValueType, class Queue>
148 bool sync_deque_base<ValueType, Queue>::empty() const
149 {
150 lock_guard<mutex> lk(mtx_);
151 return empty(lk);
152 }
153 template <class ValueType, class Queue>
154 bool sync_deque_base<ValueType, Queue>::full() const
155 {
156 return false;
157 }
158
159 template <class ValueType, class Queue>
160 typename sync_deque_base<ValueType, Queue>::size_type sync_deque_base<ValueType, Queue>::size() const
161 {
162 lock_guard<mutex> lk(mtx_);
163 return size(lk);
164 }
165
166 template <class ValueType, class Queue>
167 void sync_deque_base<ValueType, Queue>::throw_if_closed(unique_lock<mutex>& lk)
168 {
169 if (closed(lk))
170 {
171 BOOST_THROW_EXCEPTION( sync_deque_is_closed() );
172 }
173 }
174 template <class ValueType, class Queue>
175 void sync_deque_base<ValueType, Queue>::throw_if_closed(lock_guard<mutex>& lk)
176 {
177 if (closed(lk))
178 {
179 BOOST_THROW_EXCEPTION( sync_deque_is_closed() );
180 }
181 }
182
183 template <class ValueType, class Queue>
184 void sync_deque_base<ValueType, Queue>::wait_until_not_empty(unique_lock<mutex>& lk)
185 {
186 for (;;)
187 {
188 if (! empty(lk)) break;
189 throw_if_closed(lk);
190 not_empty_.wait(lk);
191 }
192 }
193 template <class ValueType, class Queue>
194 bool sync_deque_base<ValueType, Queue>::wait_until_not_empty_or_closed(unique_lock<mutex>& lk)
195 {
196 for (;;)
197 {
198 if (! empty(lk)) break;
199 if (closed(lk)) return true;
200 not_empty_.wait(lk);
201 }
202 return false;
203 }
204
205 template <class ValueType, class Queue>
206 queue_op_status sync_deque_base<ValueType, Queue>::wait_until_not_empty_until(unique_lock<mutex>& lk, time_point const&tp)
207 {
208 for (;;)
209 {
210 if (! empty(lk)) return queue_op_status::success;
211 throw_if_closed(lk);
212 if (not_empty_.wait_until(lk, tp) == cv_status::timeout ) return queue_op_status::timeout;
213 }
214 }
215
216
217 } // detail
218 } // concurrent
219 } // boost
220
221 #include <boost/config/abi_suffix.hpp>
222
223 #endif