]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/thread/executors/scheduler.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / thread / executors / scheduler.hpp
1 // Copyright (C) 2014 Vicente J. Botet Escriba
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6
7 #ifndef BOOST_THREAD_EXECUTORS_SCHEDULER_HPP
8 #define BOOST_THREAD_EXECUTORS_SCHEDULER_HPP
9
10 #include <boost/thread/detail/config.hpp>
11 #include <boost/thread/executors/detail/scheduled_executor_base.hpp>
12
13 #include <boost/chrono/time_point.hpp>
14 #include <boost/chrono/duration.hpp>
15 #include <boost/chrono/system_clocks.hpp>
16
17 #include <boost/config/abi_prefix.hpp>
18
19 #if defined(BOOST_MSVC)
20 # pragma warning(push)
21 # pragma warning(disable: 4355) // 'this' : used in base member initializer list
22 #endif
23
24 namespace boost
25 {
26 namespace executors
27 {
28 /// Wraps the reference to an executor and a function to make a work that submit the function using the executor.
29 template <class Executor, class Function>
30 class resubmitter
31 {
32 public:
33 resubmitter(Executor& ex, Function funct) :
34 ex(ex),
35 funct(boost::move(funct))
36 {}
37
38 void operator()()
39 {
40 ex.submit(funct);
41 }
42
43 private:
44 Executor& ex;
45 Function funct;
46 };
47
48 /// resubmitter factory
49 template <class Executor, class Function>
50 resubmitter<Executor, typename decay<Function>::type>
51 resubmit(Executor& ex, BOOST_THREAD_FWD_REF(Function) funct) {
52 return resubmitter<Executor, typename decay<Function>::type >(ex, boost::move(funct));
53 }
54
55 /// Wraps references to a @c Scheduler and an @c Executor providing an @c Executor that
56 /// resubmit the function using the referenced Executor at a given @c time_point known at construction.
57 template <class Scheduler, class Executor>
58 class resubmit_at_executor
59 {
60 public:
61 typedef typename Scheduler::clock clock;
62 typedef typename Scheduler::work work;
63
64 template <class Duration>
65 resubmit_at_executor(Scheduler& sch, Executor& ex, chrono::time_point<clock, Duration> const& tp) :
66 sch(sch),
67 ex(ex),
68 tp(tp),
69 is_closed(false)
70 {
71 }
72
73 ~resubmit_at_executor()
74 {
75 close();
76 }
77
78 template <class Work>
79 void submit(BOOST_THREAD_FWD_REF(Work) w)
80 {
81 if (closed())
82 {
83 BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
84 }
85 sch.submit_at(resubmit(ex,boost::forward<Work>(w)), tp);
86 }
87
88 Executor& underlying_executor()
89 {
90 return ex;
91 }
92 Scheduler& underlying_scheduler()
93 {
94 return sch;
95 }
96
97 void close()
98 {
99 is_closed = true;
100 }
101
102 bool closed()
103 {
104 return is_closed || sch.closed() || ex.closed();
105 }
106
107 private:
108 Scheduler& sch;
109 Executor& ex;
110 typename clock::time_point tp;
111 bool is_closed;
112 };
113
114
115 /// Expression template helper storing a pair of references to an @c Scheduler and an @c Executor
116 /// It provides factory helper functions such as at/after that convert these a pair of @c Scheduler @c Executor
117 /// into an new @c Executor that submit the work using the referenced @c Executor at/after a specific time/duration
118 /// respectively, using the referenced @Scheduler.
119 template <class Scheduler, class Executor>
120 class scheduler_executor_wrapper
121 {
122 public:
123 typedef typename Scheduler::clock clock;
124 typedef typename Scheduler::work work;
125 typedef resubmit_at_executor<Scheduler, Executor> the_executor;
126
127 scheduler_executor_wrapper(Scheduler& sch, Executor& ex) :
128 sch(sch),
129 ex(ex)
130 {}
131
132 ~scheduler_executor_wrapper()
133 {
134 }
135
136 Executor& underlying_executor()
137 {
138 return ex;
139 }
140 Scheduler& underlying_scheduler()
141 {
142 return sch;
143 }
144
145 template <class Rep, class Period>
146 the_executor after(chrono::duration<Rep,Period> const& rel_time)
147 {
148 return at(clock::now() + rel_time );
149 }
150
151 template <class Duration>
152 the_executor at(chrono::time_point<clock,Duration> const& abs_time)
153 {
154 return the_executor(sch, ex, abs_time);
155 }
156
157 private:
158 Scheduler& sch;
159 Executor& ex;
160 }; //end class
161
162 /// Wraps a reference to a @c Scheduler providing an @c Executor that
163 /// run the function at a given @c time_point known at construction.
164 template <class Scheduler>
165 class at_executor
166 {
167 public:
168 typedef typename Scheduler::clock clock;
169 typedef typename Scheduler::work work;
170 typedef typename clock::time_point time_point;
171
172 template <class Duration>
173 at_executor(Scheduler& sch, chrono::time_point<clock,Duration> const& tp) :
174 sch(sch),
175 tp(tp),
176 is_closed(false)
177 {}
178
179 ~at_executor()
180 {
181 close();
182 }
183
184 Scheduler& underlying_scheduler()
185 {
186 return sch;
187 }
188
189 void close()
190 {
191 is_closed = true;
192 }
193
194 bool closed()
195 {
196 return is_closed || sch.closed();
197 }
198
199 template <class Work>
200 void submit(BOOST_THREAD_FWD_REF(Work) w)
201 {
202 if (closed())
203 {
204 BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
205 }
206 sch.submit_at(boost::forward<Work>(w), tp);
207 }
208
209 template <class Executor>
210 resubmit_at_executor<Scheduler, Executor> on(Executor& ex)
211 {
212 return resubmit_at_executor<Scheduler, Executor>(sch, ex, tp);
213 }
214
215 private:
216 Scheduler& sch;
217 time_point tp;
218 bool is_closed;
219 }; //end class
220
221 /// A @c Scheduler using a specific thread. Note that a Scheduler is not an Executor.
222 /// It provides factory helper functions such as at/after that convert a @c Scheduler into an @c Executor
223 /// that submit the work at/after a specific time/duration respectively.
224 template <class Clock = chrono::steady_clock>
225 class scheduler : public detail::scheduled_executor_base<Clock>
226 {
227 public:
228 typedef typename detail::scheduled_executor_base<Clock>::work work;
229
230 typedef Clock clock;
231
232 scheduler()
233 : super(),
234 thr(&super::loop, this) {}
235
236 ~scheduler()
237 {
238 this->close();
239 thr.interrupt();
240 thr.join();
241 }
242 template <class Ex>
243 scheduler_executor_wrapper<scheduler, Ex> on(Ex& ex)
244 {
245 return scheduler_executor_wrapper<scheduler, Ex>(*this, ex);
246 }
247
248 template <class Rep, class Period>
249 at_executor<scheduler> after(chrono::duration<Rep,Period> const& rel_time)
250 {
251 return at(rel_time + clock::now());
252 }
253
254 template <class Duration>
255 at_executor<scheduler> at(chrono::time_point<clock,Duration> const& tp)
256 {
257 return at_executor<scheduler>(*this, tp);
258 }
259
260 private:
261 typedef detail::scheduled_executor_base<Clock> super;
262 thread thr;
263 };
264
265
266 }
267 using executors::resubmitter;
268 using executors::resubmit;
269 using executors::resubmit_at_executor;
270 using executors::scheduler_executor_wrapper;
271 using executors::at_executor;
272 using executors::scheduler;
273 }
274
275 #if defined(BOOST_MSVC)
276 # pragma warning(pop)
277 #endif
278
279 #include <boost/config/abi_suffix.hpp>
280
281 #endif