36#ifndef SIMPLE_POOL_HPP
37#define SIMPLE_POOL_HPP
39#include "simple_worker.hpp"
46#include "siddiqsoft/WaitableQueue.hpp"
47#include "siddiqsoft/RunOnEnd.hpp"
89 template <
typename T, u
int16_t N = 0>
90 requires std::is_move_constructible_v<T>
125 for (
auto& t : workers) {
130 for (
auto& t : workers) {
132 if (t.joinable()) t.join();
153 : callback(std::move(c))
157 workers.reserve((N > 0) ? N : std::thread::hardware_concurrency());
160 for (
unsigned i = 0; i < ((N > 0) ? N : std::thread::hardware_concurrency()); i++) {
162 workers.emplace_back([&](std::stop_token st) {
166 while (!st.stop_requested()) {
171 if (
auto item = getNextItem(); item.has_value() && !st.stop_requested() && callback) {
173 callback(std::move(*item));
176 catch (
const std::exception& ex) {
178 std::cerr << std::format(
"Ignoring Exception in simple_worker callback: {}", ex.what());
206 items.emplace(std::forward<T>(item));
209 queueCounter.fetch_add(1, std::memory_order_release);
213#if defined(NLOHMANN_JSON_VERSION_MAJOR)
231 auto toJson() const -> nlohmann::json
233 const auto sz = items.size();
234 return nlohmann::json {{
"_typver",
"siddiqsoft.asynchrony-lib.simple_pool/0.10"},
235 {
"workersSize", workers.size()},
237 {
"queueCounter", queueCounter.load(std::memory_order_acquire)},
245 std::atomic_uint64_t queueCounter {0};
249 std::atomic_uint64_t queueCounter {0};
254 std::vector<std::jthread> workers {};
257 std::function<void(T&&)> callback;
260 std::counting_semaphore<> signal {0};
263 siddiqsoft::WaitableQueue<T> items {};
282 return items.tryWaitItem(delta);
286#if defined(NLOHMANN_JSON_VERSION_MAJOR)
297 template <
typename T, u
int16_t N = 0>
298 static auto to_json(nlohmann::json& dest,
const siddiqsoft::simple_pool<T, N>& src) ->
void const
simple_pool & operator=(simple_pool &)=delete
Copy assignment operator (deleted - pools are not copyable).
void queue(T &&item)
Queue a work item for processing.
static constexpr std::chrono::milliseconds DEFAULT_WAIT_FOR_NEXT_ITEM_MS
Default wait interval for threads waiting on the semaphore.
simple_pool(std::function< void(T &&)> c)
Constructs a thread pool with N worker threads.
simple_pool(simple_pool &)=delete
Copy constructor (deleted - pools are not copyable).
simple_pool(simple_pool &&)=delete
Move constructor (deleted - pools are not movable).
simple_pool & operator=(simple_pool &&)=delete
Move assignment operator (deleted - pools are not movable).
~simple_pool()
Destructor - gracefully shuts down all worker threads.