24#include <system_error>
41 worker_count_ = value;
48 registration_ = value;
55 workers_ = std::move(value);
62 scheduler_ = std::move(value);
76 on_task_error_ = std::move(value);
114 return on_task_error_;
120 thread_config workers_;
121 thread_config scheduler_;
147 : config_(
std::move(config)),
148 impl_(
std::make_unique<detail::scheduled_pool_backend>(
155 throw std::system_error(configured.error(),
"scheduled_pool worker configuration");
162 throw std::system_error(configured.error(),
"scheduled_pool scheduler configuration");
167 : config_(std::move(other.config_)), impl_(std::move(other.impl_)),
168 stopped_(other.stopped_.load(std::memory_order_acquire))
170 other.stopped_.store(
true, std::memory_order_release);
179 config_ = std::move(other.config_);
180 impl_ = std::move(other.impl_);
181 stopped_.store(other.stopped_.load(std::memory_order_acquire), std::memory_order_release);
182 other.stopped_.store(
true, std::memory_order_release);
214 template <
typename Rep,
typename Period,
typename F>
218 if (stopped_.load(std::memory_order_acquire))
219 return unexpected(std::make_error_code(std::errc::operation_canceled));
223 auto native_delay = detail::checked_duration_cast<detail::scheduled_pool_backend::duration>(delay);
226 auto handle = impl_->schedule_after(native_delay.value(), wrap_task(std::forward<F>(function)));
227 if (handle.is_cancelled())
228 return unexpected(std::make_error_code(std::errc::operation_canceled));
238 template <
typename F>
242 if (stopped_.load(std::memory_order_acquire))
243 return unexpected(std::make_error_code(std::errc::operation_canceled));
247 auto handle = impl_->schedule_at(time, wrap_task(std::forward<F>(function)));
248 if (handle.is_cancelled())
249 return unexpected(std::make_error_code(std::errc::operation_canceled));
260 template <
typename Rep,
typename Period,
typename F>
264 if (stopped_.load(std::memory_order_acquire))
265 return unexpected(std::make_error_code(std::errc::operation_canceled));
266 auto const native_interval = detail::checked_duration_cast<detail::scheduled_pool_backend::duration>(interval);
267 if (!native_interval)
269 if (native_interval.value() <= detail::scheduled_pool_backend::duration::zero())
270 return unexpected(std::make_error_code(std::errc::invalid_argument));
274 auto handle = impl_->schedule_periodic(native_interval.value(), wrap_task(std::forward<F>(function)));
275 if (handle.is_cancelled())
276 return unexpected(std::make_error_code(std::errc::operation_canceled));
287 template <
typename InitialRep,
typename InitialPeriod,
typename IntervalRep,
typename IntervalPeriod,
typename F>
290 std::chrono::duration<IntervalRep, IntervalPeriod> interval, F&& function)
293 if (stopped_.load(std::memory_order_acquire))
294 return unexpected(std::make_error_code(std::errc::operation_canceled));
295 auto const native_interval = detail::checked_duration_cast<detail::scheduled_pool_backend::duration>(interval);
296 if (!native_interval)
298 if (native_interval.value() <= detail::scheduled_pool_backend::duration::zero())
299 return unexpected(std::make_error_code(std::errc::invalid_argument));
300 auto const native_delay = detail::checked_duration_cast<detail::scheduled_pool_backend::duration>(initial_delay);
306 auto handle = impl_->schedule_periodic_after(native_delay.value(), native_interval.value(),
307 wrap_task(std::forward<F>(function)));
308 if (handle.is_cancelled())
309 return unexpected(std::make_error_code(std::errc::operation_canceled));
334 stopped_.store(
true, std::memory_order_release);
343 return impl_ ? impl_->scheduled_count() : 0;
348 dispose_impl() noexcept
354 if (!impl_->is_current_context())
358 impl_->shutdown(policy);
367 auto* backend = impl_.release();
371 [backend, policy]()
noexcept
373 std::unique_ptr<detail::scheduled_pool_backend> owner(backend);
376 owner->shutdown(policy);
390 template <
typename F>
392 wrap_task(F&& function)
394 using function_type = std::decay_t<F>;
396 return [function = function_type(std::forward<F>(function)), callback = std::move(callback)]()
mutable
400 std::invoke(function);
418 scheduled_pool_config config_{};
419 std::unique_ptr<detail::scheduled_pool_backend> impl_;
420 std::atomic<bool> stopped_{
false };
Builder-style configuration for scheduled_pool.
auto get_shutdown_policy() const noexcept -> shutdown_policy
Return configured shutdown policy.
auto get_registration() const noexcept -> worker_registration
Return configured worker registration mode.
auto get_worker_config() const noexcept -> thread_config const &
Return worker-thread configuration.
auto get_error_callback() const noexcept -> error_callback const &
Return configured asynchronous error callback.
auto get_scheduler_config() const noexcept -> thread_config const &
Return scheduler-thread configuration.
auto get_worker_count() const noexcept -> worker_count
Return configured worker count.
auto set_worker_count(worker_count value) noexcept -> scheduled_pool_config &
Set number of worker threads executing scheduled callbacks.
auto set_shutdown_policy(shutdown_policy value) noexcept -> scheduled_pool_config &
Set shutdown behavior for pending scheduled tasks.
auto set_scheduler_config(thread_config value) -> scheduled_pool_config &
Set configuration applied to the scheduler coordination thread.
auto set_error_callback(error_callback value) -> scheduled_pool_config &
Set callback invoked when scheduled callbacks throw.
auto set_worker_config(thread_config value) -> scheduled_pool_config &
Set configuration applied to worker threads.
auto set_registration(worker_registration value) noexcept -> scheduled_pool_config &
Configure registry registration behavior for scheduler workers.
Scheduler that executes delayed and periodic tasks on worker threads.
scheduled_pool(scheduled_pool &&other) noexcept
auto schedule_after(std::chrono::duration< Rep, Period > delay, F &&function) -> result< scheduled_task >
Schedule a one-shot task to run after a delay.
auto schedule_periodic_after(std::chrono::duration< InitialRep, InitialPeriod > initial_delay, std::chrono::duration< IntervalRep, IntervalPeriod > interval, F &&function) -> result< scheduled_task >
Schedule a periodic task with initial delay.
scheduled_pool()
Construct with default scheduler configuration.
auto scheduled_count() const -> std::size_t
Return count of tasks currently tracked by the scheduler backend.
auto shutdown() -> result< void >
Shutdown using configured shutdown policy.
scheduled_pool(scheduled_pool const &)=delete
static auto create(scheduled_pool_config config={}) -> result< scheduled_pool >
Create a scheduled pool without exceptions.
auto schedule_periodic(std::chrono::duration< Rep, Period > interval, F &&function) -> result< scheduled_task >
Schedule a periodic task.
auto shutdown(shutdown_policy policy) -> result< void >
Shutdown with explicit policy.
~scheduled_pool()
Shutdown scheduler and workers according to configured policy.
scheduled_pool(scheduled_pool_config config)
Construct from full configuration.
scheduled_pool(worker_count count)
Construct with explicit worker count.
auto operator=(scheduled_pool const &) -> scheduled_pool &=delete
auto operator=(scheduled_pool &&other) noexcept -> scheduled_pool &
auto schedule_at(std::chrono::steady_clock::time_point time, F &&function) -> result< scheduled_task >
Schedule a one-shot task at an absolute time point.
Portable thread configuration bundle.
Value type for pool worker count.
static constexpr auto automatic() noexcept -> worker_count
Create automatic worker count.
constexpr auto to_native(shutdown_policy policy) noexcept -> shutdown_policy_backend
auto has_thread_configuration(thread_config const &config) noexcept -> bool
auto try_result(Function &&function) -> decltype(std::forward< Function >(function)())
auto global_registry() -> thread_registry &
shutdown_policy
Defines how pools handle pending work during shutdown.
@ drain
Finish queued work before returning from shutdown.
std::function< void(task_error const &)> error_callback
Callback signature for asynchronous task error reporting.
worker_registration
Controls whether pool workers are registered in a thread registry.
@ disabled
Do not register workers in the global registry.
Cancellable handle returned by scheduled task APIs.
Portable pool shutdown behavior.
static auto capture(std::string description={}) -> task_error
Capture failure context for the current exception state.
Portable task failure reporting.
Portable thread startup and runtime configuration.
Worker-thread count configuration for pool types.
Worker registration behavior for pool-managed threads.