27 boost::asio::steady_timer timer;
28 boost::asio::strand<boost::asio::any_io_executor> strand;
29 std::atomic_bool stopping{
true};
30 std::binary_semaphore semaphore{0};
32 Control(
auto& ctx) : timer(ctx), strand(boost::asio::make_strand(ctx))
37 std::shared_ptr<Control> control_;
47 Repeat(
auto& ctx) : control_(std::make_unique<Control>(ctx))
53 operator=(
Repeat const&) =
delete;
56 operator=(
Repeat&&) =
default;
74 template <std::invocable Action>
76 start(std::chrono::steady_clock::duration interval, Action&& action)
78 ASSERT(control_->stopping,
"Should be stopped before starting");
79 control_->stopping =
false;
80 startImpl(control_, interval, std::forward<Action>(action));
84 template <std::invocable Action>
87 std::shared_ptr<Control> control,
88 std::chrono::steady_clock::duration interval,
93 control->strand, [control, interval, action = std::forward<Action>(action)]()
mutable {
94 if (control->stopping) {
95 control->semaphore.release();
99 control->timer.expires_after(interval);
100 control->timer.async_wait(
103 action = std::forward<Action>(action)](
auto const& ec)
mutable {
104 if (ec or control->stopping) {
105 control->semaphore.release();
110 startImpl(std::move(control), interval, std::forward<Action>(action));