45 boost::asio::steady_timer timer;
46 boost::asio::strand<boost::asio::any_io_executor> strand;
47 std::atomic_bool stopping{
true};
48 std::binary_semaphore semaphore{0};
50 Control(
auto& ctx) : timer(ctx), strand(boost::asio::make_strand(ctx))
55 std::shared_ptr<Control> control_;
64 Repeat(
auto& ctx) : control_(std::make_unique<Control>(ctx))
70 operator=(
Repeat const&) =
delete;
73 operator=(
Repeat&&) =
default;
90 template <std::invocable Action>
92 start(std::chrono::steady_clock::duration interval, Action&& action)
94 ASSERT(control_->stopping,
"Should be stopped before starting");
95 control_->stopping =
false;
96 startImpl(control_, interval, std::forward<Action>(action));
100 template <std::invocable Action>
102 startImpl(std::shared_ptr<Control> control, std::chrono::steady_clock::duration interval, Action&& action)
104 boost::asio::post(control->strand, [control, interval, action = std::forward<Action>(action)]()
mutable {
105 if (control->stopping) {
106 control->semaphore.release();
110 control->timer.expires_after(interval);
111 control->timer.async_wait(
112 [control, interval, action = std::forward<Action>(action)](
auto const& ec)
mutable {
113 if (ec or control->stopping) {
114 control->semaphore.release();
119 startImpl(std::move(control), interval, std::forward<Action>(action));