Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:01:11

0001 // Copyright (C) 2014 Vicente J. Botet Escriba
0002 //
0003 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 //
0006 
0007 #ifndef BOOST_THREAD_EXECUTORS_SCHEDULER_HPP
0008 #define BOOST_THREAD_EXECUTORS_SCHEDULER_HPP
0009 
0010 #include <boost/thread/detail/config.hpp>
0011 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined BOOST_THREAD_PROVIDES_EXECUTORS && defined BOOST_THREAD_USES_MOVE
0012 #include <boost/thread/executors/detail/scheduled_executor_base.hpp>
0013 
0014 #include <boost/chrono/time_point.hpp>
0015 #include <boost/chrono/duration.hpp>
0016 #include <boost/chrono/system_clocks.hpp>
0017 
0018 #include <boost/config/abi_prefix.hpp>
0019 
0020 #if defined(BOOST_MSVC)
0021 # pragma warning(push)
0022 # pragma warning(disable: 4355) // 'this' : used in base member initializer list
0023 #endif
0024 
0025 namespace boost
0026 {
0027   namespace executors
0028   {
0029     /// Wraps the reference to an executor and a function to make a work that submit the function using the executor.
0030     template <class Executor, class Function>
0031     class resubmitter
0032     {
0033     public:
0034       resubmitter(Executor& ex, Function funct) :
0035         ex(ex),
0036         funct(boost::move(funct))
0037       {}
0038 
0039       void operator()()
0040       {
0041         ex.submit(funct);
0042       }
0043 
0044     private:
0045       Executor&   ex;
0046       Function funct;
0047     };
0048 
0049     /// resubmitter factory
0050     template <class Executor, class Function>
0051     resubmitter<Executor, typename decay<Function>::type>
0052     resubmit(Executor& ex, BOOST_THREAD_FWD_REF(Function) funct) {
0053       return resubmitter<Executor, typename decay<Function>::type >(ex, boost::move(funct));
0054     }
0055 
0056     /// Wraps references to a @c Scheduler and an @c Executor providing an @c Executor that
0057     /// resubmit the function using the referenced Executor at a given @c time_point known at construction.
0058     template <class Scheduler, class Executor>
0059     class resubmit_at_executor
0060     {
0061     public:
0062       typedef typename Scheduler::clock clock;
0063       typedef typename Scheduler::work work;
0064 
0065       template <class Duration>
0066       resubmit_at_executor(Scheduler& sch, Executor& ex, chrono::time_point<clock, Duration> const& tp) :
0067         sch(sch),
0068         ex(ex),
0069         tp(tp),
0070         is_closed(false)
0071       {
0072       }
0073 
0074       ~resubmit_at_executor()
0075       {
0076         close();
0077       }
0078 
0079       template <class Work>
0080       void submit(BOOST_THREAD_FWD_REF(Work) w)
0081       {
0082         if (closed())
0083         {
0084           BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
0085         }
0086         sch.submit_at(resubmit(ex,boost::forward<Work>(w)), tp);
0087       }
0088 
0089       Executor& underlying_executor()
0090       {
0091           return ex;
0092       }
0093       Scheduler& underlying_scheduler()
0094       {
0095           return sch;
0096       }
0097 
0098       void close()
0099       {
0100         is_closed = true;
0101       }
0102 
0103       bool closed()
0104       {
0105         return is_closed || sch.closed() || ex.closed();
0106       }
0107 
0108     private:
0109       Scheduler&  sch;
0110       Executor&   ex;
0111       typename clock::time_point  tp;
0112       bool  is_closed;
0113     };
0114 
0115 
0116     /// Expression template helper storing a pair of references to an @c Scheduler and an @c Executor
0117     /// It provides factory helper functions such as at/after that convert these a pair of @c Scheduler @c Executor
0118     /// into an new @c Executor that submit the work using the referenced @c Executor at/after a specific time/duration
0119     /// respectively, using the referenced @Scheduler.
0120     template <class Scheduler, class Executor>
0121     class scheduler_executor_wrapper
0122     {
0123     public:
0124       typedef typename Scheduler::clock clock;
0125       typedef typename Scheduler::work work;
0126       typedef resubmit_at_executor<Scheduler, Executor> the_executor;
0127 
0128       scheduler_executor_wrapper(Scheduler& sch, Executor& ex) :
0129           sch(sch),
0130           ex(ex)
0131       {}
0132 
0133       ~scheduler_executor_wrapper()
0134       {
0135       }
0136 
0137       Executor& underlying_executor()
0138       {
0139           return ex;
0140       }
0141       Scheduler& underlying_scheduler()
0142       {
0143           return sch;
0144       }
0145 
0146       template <class Rep, class Period>
0147       the_executor after(chrono::duration<Rep,Period> const& rel_time)
0148       {
0149         return at(clock::now() + rel_time );
0150       }
0151 
0152       template <class Duration>
0153       the_executor at(chrono::time_point<clock,Duration> const& abs_time)
0154       {
0155         return the_executor(sch, ex, abs_time);
0156       }
0157 
0158     private:
0159       Scheduler& sch;
0160       Executor& ex;
0161     }; //end class
0162 
0163     /// Wraps a reference to a @c Scheduler providing an @c Executor that
0164     /// run the function at a given @c time_point known at construction.
0165     template <class Scheduler>
0166     class at_executor
0167     {
0168     public:
0169       typedef typename Scheduler::clock clock;
0170       typedef typename Scheduler::work work;
0171       typedef typename clock::time_point time_point;
0172 
0173       template <class Duration>
0174       at_executor(Scheduler& sch, chrono::time_point<clock,Duration> const& tp) :
0175           sch(sch),
0176           tp(tp),
0177           is_closed(false)
0178       {}
0179 
0180       ~at_executor()
0181       {
0182         close();
0183       }
0184 
0185       Scheduler& underlying_scheduler()
0186       {
0187           return sch;
0188       }
0189 
0190       void close()
0191       {
0192         is_closed = true;
0193       }
0194 
0195       bool closed()
0196       {
0197         return is_closed || sch.closed();
0198       }
0199 
0200       template <class Work>
0201       void submit(BOOST_THREAD_FWD_REF(Work) w)
0202       {
0203         if (closed())
0204         {
0205           BOOST_THROW_EXCEPTION( sync_queue_is_closed() );
0206         }
0207         sch.submit_at(boost::forward<Work>(w), tp);
0208       }
0209 
0210       template <class Executor>
0211       resubmit_at_executor<Scheduler, Executor> on(Executor& ex)
0212       {
0213         return resubmit_at_executor<Scheduler, Executor>(sch, ex, tp);
0214       }
0215 
0216     private:
0217       Scheduler& sch;
0218       time_point  tp;
0219       bool  is_closed;
0220     }; //end class
0221 
0222     /// A @c Scheduler using a specific thread. Note that a Scheduler is not an Executor.
0223     /// It provides factory helper functions such as at/after that convert a @c Scheduler into an @c Executor
0224     /// that submit the work at/after a specific time/duration respectively.
0225     template <class Clock = chrono::steady_clock>
0226     class scheduler : public detail::scheduled_executor_base<Clock>
0227     {
0228     public:
0229       typedef typename detail::scheduled_executor_base<Clock>::work work;
0230 
0231       typedef Clock clock;
0232 
0233       scheduler()
0234         : super(),
0235           thr(&super::loop, this) {}
0236 
0237       ~scheduler()
0238       {
0239         this->close();
0240         thr.interrupt();
0241         thr.join();
0242       }
0243       template <class Ex>
0244       scheduler_executor_wrapper<scheduler, Ex> on(Ex& ex)
0245       {
0246         return scheduler_executor_wrapper<scheduler, Ex>(*this, ex);
0247       }
0248 
0249       template <class Rep, class Period>
0250       at_executor<scheduler> after(chrono::duration<Rep,Period> const& rel_time)
0251       {
0252         return at(rel_time + clock::now());
0253       }
0254 
0255       template <class Duration>
0256       at_executor<scheduler> at(chrono::time_point<clock,Duration> const& tp)
0257       {
0258         return at_executor<scheduler>(*this, tp);
0259       }
0260 
0261     private:
0262       typedef detail::scheduled_executor_base<Clock> super;
0263       thread thr;
0264     };
0265 
0266 
0267   }
0268   using executors::resubmitter;
0269   using executors::resubmit;
0270   using executors::resubmit_at_executor;
0271   using executors::scheduler_executor_wrapper;
0272   using executors::at_executor;
0273   using executors::scheduler;
0274 }
0275 
0276 #if defined(BOOST_MSVC)
0277 # pragma warning(pop)
0278 #endif
0279 
0280 #include <boost/config/abi_suffix.hpp>
0281 
0282 #endif
0283 #endif