12#include <rpp/schedulers/fwd.hpp>
18namespace rpp::schedulers::details
20 inline thread_local time_point s_last_now_time{};
22 inline rpp::schedulers::time_point now()
24 return s_last_now_time = clock_type::now();
27 inline bool sleep_until(
const time_point timepoint)
29 if (timepoint <= details::s_last_now_time)
32 const auto now = clock_type::now();
33 std::this_thread::sleep_for(timepoint - now);
34 details::s_last_now_time = std::max(now, timepoint);
35 return timepoint > now;
43 std::optional<time_point> immediate_scheduling_while_condition(duration duration,
44 const std::predicate
auto& condition,
45 constraint::schedulable_delay_from_this_timepoint_fn<Handler, Args...>
auto&& fn,
47 Args&&... args)
noexcept
49 auto timepoint = NowStrategy::now() + duration;
52 if (handler.is_disposed())
55 if (sleep_until(timepoint) && handler.is_disposed())
60 if (
const auto duration_from_timepoint = fn(handler, args...))
61 timepoint += duration_from_timepoint->value;
67 handler.on_error(std::current_exception());
80 std::optional<time_point> immediate_scheduling_while_condition(duration duration,
81 const std::predicate
auto& condition,
82 constraint::schedulable_delay_from_now_fn<Handler, Args...>
auto&& fn,
84 Args&&... args)
noexcept
88 if (handler.is_disposed())
91 if (duration > duration::zero())
93 std::this_thread::sleep_for(duration);
95 if (handler.is_disposed())
101 if (
const auto new_duration = fn(handler, args...))
102 duration = new_duration->value;
108 handler.on_error(std::current_exception());
113 return NowStrategy::now() + duration;
121 std::optional<time_point> immediate_scheduling_while_condition(duration duration,
122 const std::predicate
auto& condition,
123 constraint::schedulable_delay_to_fn<Handler, Args...>
auto&& fn,
125 Args&&... args)
noexcept
127 std::optional<time_point> timepoint{};
130 if (handler.is_disposed())
133 if (!timepoint.has_value())
135 if (duration > duration::zero())
137 std::this_thread::sleep_for(duration);
139 if (handler.is_disposed())
143 else if (sleep_until(timepoint.value()) && handler.is_disposed())
148 if (
const auto new_timepoint = fn(handler, args...))
149 timepoint = new_timepoint->value;
155 handler.on_error(std::current_exception());