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