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>
19 #if defined(BOOST_MSVC)
20 # pragma warning(push)
21 # pragma warning(disable: 4355) // 'this' : used in base member initializer list
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>
33 resubmitter(Executor& ex, Function funct) :
35 funct(boost::move(funct))
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));
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
61 typedef typename Scheduler::clock clock;
62 typedef typename Scheduler::work work;
64 template <class Duration>
65 resubmit_at_executor(Scheduler& sch, Executor& ex, chrono::time_point<clock, Duration> const& tp) :
73 ~resubmit_at_executor()
79 void submit(BOOST_THREAD_FWD_REF(Work) w)
83 BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
85 sch.submit_at(resubmit(ex,boost::forward<Work>(w)), tp);
88 Executor& underlying_executor()
92 Scheduler& underlying_scheduler()
104 return is_closed || sch.closed() || ex.closed();
110 typename clock::time_point tp;
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
123 typedef typename Scheduler::clock clock;
124 typedef typename Scheduler::work work;
125 typedef resubmit_at_executor<Scheduler, Executor> the_executor;
127 scheduler_executor_wrapper(Scheduler& sch, Executor& ex) :
132 ~scheduler_executor_wrapper()
136 Executor& underlying_executor()
140 Scheduler& underlying_scheduler()
145 template <class Rep, class Period>
146 the_executor after(chrono::duration<Rep,Period> const& rel_time)
148 return at(clock::now() + rel_time );
151 template <class Duration>
152 the_executor at(chrono::time_point<clock,Duration> const& abs_time)
154 return the_executor(sch, ex, abs_time);
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>
168 typedef typename Scheduler::clock clock;
169 typedef typename Scheduler::work work;
170 typedef typename clock::time_point time_point;
172 template <class Duration>
173 at_executor(Scheduler& sch, chrono::time_point<clock,Duration> const& tp) :
184 Scheduler& underlying_scheduler()
196 return is_closed || sch.closed();
199 template <class Work>
200 void submit(BOOST_THREAD_FWD_REF(Work) w)
204 BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
206 sch.submit_at(boost::forward<Work>(w), tp);
209 template <class Executor>
210 resubmit_at_executor<Scheduler, Executor> on(Executor& ex)
212 return resubmit_at_executor<Scheduler, Executor>(sch, ex, tp);
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>
228 typedef typename detail::scheduled_executor_base<Clock>::work work;
234 thr(&super::loop, this) {}
243 scheduler_executor_wrapper<scheduler, Ex> on(Ex& ex)
245 return scheduler_executor_wrapper<scheduler, Ex>(*this, ex);
248 template <class Rep, class Period>
249 at_executor<scheduler> after(chrono::duration<Rep,Period> const& rel_time)
251 return at(rel_time + clock::now());
254 template <class Duration>
255 at_executor<scheduler> at(chrono::time_point<clock,Duration> const& tp)
257 return at_executor<scheduler>(*this, tp);
261 typedef detail::scheduled_executor_base<Clock> super;
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;
275 #if defined(BOOST_MSVC)
276 # pragma warning(pop)
279 #include <boost/config/abi_suffix.hpp>