annotate DEPENDENCIES/generic/include/boost/thread/executors/scheduler.hpp @ 133:4acb5d8d80b6 tip

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