46 boost::asio::steady_timer timer;
47 boost::asio::strand<boost::asio::any_io_executor> strand;
48 std::atomic_bool stopping{
true};
49 std::binary_semaphore semaphore{0};
51 Control(
auto& ctx) : timer(ctx), strand(boost::asio::make_strand(ctx))
56 std::shared_ptr<Control> control_;
66 Repeat(
auto& ctx) : control_(std::make_unique<Control>(ctx))
72 operator=(
Repeat const&) =
delete;
75 operator=(
Repeat&&) =
default;
93 template <std::invocable Action>
95 start(std::chrono::steady_clock::duration interval, Action&& action)
97 ASSERT(control_->stopping,
"Should be stopped before starting");
98 control_->stopping =
false;
99 startImpl(control_, interval, std::forward<Action>(action));
103 template <std::invocable Action>
106 std::shared_ptr<Control> control,
107 std::chrono::steady_clock::duration interval,
112 control->strand, [control, interval, action = std::forward<Action>(action)]()
mutable {
113 if (control->stopping) {
114 control->semaphore.release();
118 control->timer.expires_after(interval);
119 control->timer.async_wait(
122 action = std::forward<Action>(action)](
auto const& ec)
mutable {
123 if (ec or control->stopping) {
124 control->semaphore.release();
129 startImpl(std::move(control), interval, std::forward<Action>(action));