7 #include <boost/asio/steady_timer.hpp> 8 #include <boost/fiber/condition_variable.hpp> 9 #include "util/asio/io_context.h" 17 enum {ALARMED = 0x1, SHUTDOWN = 0x2};
20 using timer_t = ::boost::asio::steady_timer;
21 using duration_t = timer_t::duration;
22 using error_code = boost::system::error_code;
35 template<
typename Func>
void Start(Func&& f) {
37 RunInternal(std::forward<Func>(f));
47 template<
typename Func>
void RunInternal(Func&& f) {
48 timer_.async_wait([
this, f = std::forward<Func>(f)] (
const error_code& ec)
mutable {
49 if (ec == boost::asio::error::operation_aborted || (state_ & SHUTDOWN)) {
53 duration_t real_d = timer_t::clock_type::now() - last_;
56 int ticks = std::max<int>(1, real_d / d_);
61 timer_.expires_at(last_ + d_);
62 RunInternal(std::forward<Func>(f));
67 state_ &= ~uint8_t(ALARMED);
72 timer_t::time_point last_;
87 uint32_t skip_run_margin;
89 Options() : skip_run_margin(0) {}
95 ~PeriodicWorkerTask() { Cancel(); }
97 template<
typename Func>
void Start(Func&& f) {
98 pt_.Start([
this, f = PackagedTask(std::forward<Func>(f))] (
int ticks) {
100 std::thread(f).detach();
108 bool IsHanging()
const {
return is_hanging_; }
111 template<
typename Func>
auto PackagedTask(Func&& f) {
112 return [
this, f = std::forward<Func>(f)]() {
120 bool AllowRunning() {
122 return is_running_.compare_exchange_strong(val,
true);
125 void ResetErrorState();
127 void HandleSkipRun();
129 std::atomic_bool is_running_{
false};
131 ::boost::fibers::mutex m_;
132 ::boost::fibers::condition_variable_any cond_;
136 bool is_hanging_ =
false;
137 unsigned number_skips_ = 0;