1 // Copyright (C) 2014 Vicente J. Botet Escriba
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)
7 #ifndef BOOST_THREAD_EXECUTORS_SCHEDULER_HPP
8 #define BOOST_THREAD_EXECUTORS_SCHEDULER_HPP
10 #include <boost/thread/detail/config.hpp>
11 #include <boost/thread/executors/detail/scheduled_executor_base.hpp>
13 #include <boost/chrono/time_point.hpp>
14 #include <boost/chrono/duration.hpp>
15 #include <boost/chrono/system_clocks.hpp>
17 #include <boost/config/abi_prefix.hpp>
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>
28 resubmitter(Executor& ex, Function funct) :
30 funct(boost::move(funct))
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));
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
56 typedef typename Scheduler::clock clock;
57 typedef typename Scheduler::work work;
59 template <class Duration>
60 resubmit_at_executor(Scheduler& sch, Executor& ex, chrono::time_point<clock, Duration> const& tp) :
68 ~resubmit_at_executor()
74 void submit(BOOST_THREAD_FWD_REF(Work) w)
78 BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
80 sch.submit_at(resubmit(ex,boost::forward<Work>(w)), tp);
83 Executor& underlying_executor()
87 Scheduler& underlying_scheduler()
99 return is_closed || sch.closed() || ex.closed();
105 typename clock::time_point tp;
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
118 typedef typename Scheduler::clock clock;
119 typedef typename Scheduler::work work;
120 typedef resubmit_at_executor<Scheduler, Executor> the_executor;
122 scheduler_executor_wrapper(Scheduler& sch, Executor& ex) :
127 ~scheduler_executor_wrapper()
131 Executor& underlying_executor()
135 Scheduler& underlying_scheduler()
140 template <class Rep, class Period>
141 the_executor after(chrono::duration<Rep,Period> const& rel_time)
143 return at(clock::now() + rel_time );
146 template <class Duration>
147 the_executor at(chrono::time_point<clock,Duration> const& abs_time)
149 return the_executor(sch, ex, abs_time);
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>
163 typedef typename Scheduler::clock clock;
164 typedef typename Scheduler::work work;
165 typedef typename clock::time_point time_point;
167 template <class Duration>
168 at_executor(Scheduler& sch, chrono::time_point<clock,Duration> const& tp) :
179 Scheduler& underlying_scheduler()
191 return is_closed || sch.closed();
194 template <class Work>
195 void submit(BOOST_THREAD_FWD_REF(Work) w)
199 BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
201 sch.submit_at(boost::forward<Work>(w), tp);
204 template <class Executor>
205 resubmit_at_executor<Scheduler, Executor> on(Executor& ex)
207 return resubmit_at_executor<Scheduler, Executor>(sch, ex, tp);
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>
223 typedef typename detail::scheduled_executor_base<Clock>::work work;
229 thr(&super::loop, this) {}
237 scheduler_executor_wrapper<scheduler, Ex> on(Ex& ex)
239 return scheduler_executor_wrapper<scheduler, Ex>(*this, ex);
242 template <class Rep, class Period>
243 at_executor<scheduler> after(chrono::duration<Rep,Period> const& rel_time)
245 return at(rel_time + clock::now());
248 template <class Duration>
249 at_executor<scheduler> at(chrono::time_point<clock,Duration> const& tp)
251 return at_executor<scheduler>(*this, tp);
255 typedef detail::scheduled_executor_base<Clock> super;
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;
269 #include <boost/config/abi_suffix.hpp>