3838#include < string>
3939#include < thread>
4040#include < type_traits>
41- #include < variant>
4241#include < vector>
4342
4443#include < fmt/format.h>
@@ -62,9 +61,11 @@ template <typename LoggerPolicy, typename Policy>
6261class basic_worker_group final : public worker_group::impl, private Policy {
6362 public:
6463 template <typename ... Args>
65- basic_worker_group (logger& lgr, os_access const & os, char const * group_name,
66- size_t num_workers, size_t max_queue_len,
67- int niceness [[maybe_unused]], Args&&... args)
64+ basic_worker_group (
65+ logger& lgr, os_access const & os, char const * group_name,
66+ size_t num_workers,
67+ std::function<std::unique_ptr<thread_state>(size_t )> thread_state_factory,
68+ size_t max_queue_len, int niceness [[maybe_unused]], Args&&... args)
6869 : Policy(std::forward<Args>(args)...)
6970 , LOG_PROXY_INIT(lgr)
7071 , os_{os}
@@ -80,11 +81,12 @@ class basic_worker_group final : public worker_group::impl, private Policy {
8081 }
8182
8283 for (size_t i = 0 ; i < num_workers; ++i) {
83- workers_.emplace_back ([this , niceness, group_name, i] {
84- folly::setThreadName (fmt::format (" {}{}" , group_name, i + 1 ));
85- set_thread_niceness (niceness);
86- do_work (niceness > 10 );
87- });
84+ workers_.emplace_back (
85+ [this , niceness, group_name, i, state = thread_state_factory (i)] {
86+ folly::setThreadName (fmt::format (" {}{}" , group_name, i + 1 ));
87+ set_thread_niceness (niceness);
88+ do_work (*state, niceness > 10 );
89+ });
8890 }
8991
9092 check_set_affinity_from_enviroment (group_name);
@@ -146,19 +148,21 @@ class basic_worker_group final : public worker_group::impl, private Policy {
146148 *
147149 * \param job The job to add to the dispatcher.
148150 */
149- bool add_job (worker_group::job_t && job) override {
150- return add_job_impl (std::move (job));
151- }
151+ bool add_job (std::any&& job) override {
152+ if (running_) {
153+ {
154+ std::unique_lock lock (mx_);
155+ queue_.wait (lock, [this ] { return jobs_.size () < max_queue_len_; });
156+ jobs_.emplace (std::move (job));
157+ ++pending_;
158+ }
152159
153- /* *
154- * Add a new move-only job to the worker group
155- *
156- * The new job will be dispatched to the first available worker thread.
157- *
158- * \param job The job to add to the dispatcher.
159- */
160- bool add_moveonly_job (worker_group::moveonly_job_t && job) override {
161- return add_job_impl (std::move (job));
160+ cond_.notify_one ();
161+
162+ return true ;
163+ }
164+
165+ return false ;
162166 }
163167
164168 /* *
@@ -219,26 +223,7 @@ class basic_worker_group final : public worker_group::impl, private Policy {
219223 }
220224
221225 private:
222- using any_job_t =
223- std::variant<worker_group::job_t , worker_group::moveonly_job_t >;
224- using jobs_t = std::queue<any_job_t >;
225-
226- bool add_job_impl (any_job_t && job) {
227- if (running_) {
228- {
229- std::unique_lock lock (mx_);
230- queue_.wait (lock, [this ] { return jobs_.size () < max_queue_len_; });
231- jobs_.emplace (std::move (job));
232- ++pending_;
233- }
234-
235- cond_.notify_one ();
236-
237- return true ;
238- }
239-
240- return false ;
241- }
226+ using jobs_t = std::queue<std::any>;
242227
243228 void check_set_affinity_from_enviroment (char const * group_name) {
244229 if (auto var = os_.getenv (" DWARFS_WORKER_GROUP_AFFINITY" )) {
@@ -276,12 +261,12 @@ class basic_worker_group final : public worker_group::impl, private Policy {
276261 }
277262 }
278263
279- void do_work (bool is_background [[maybe_unused]]) {
264+ void do_work (thread_state& state, bool is_background [[maybe_unused]]) {
280265#ifdef _WIN32
281266 auto hthr = ::GetCurrentThread ();
282267#endif
283268 for (;;) {
284- any_job_t job;
269+ std::any job;
285270
286271 {
287272 std::unique_lock lock (mx_);
@@ -310,13 +295,7 @@ class basic_worker_group final : public worker_group::impl, private Policy {
310295 }
311296#endif
312297 try {
313- std::visit (
314- [](auto && j) {
315- static_assert (std::is_rvalue_reference_v<decltype (j)>);
316- auto job = std::forward<decltype (j)>(j);
317- job ();
318- },
319- std::move (job));
298+ state.apply (std::move (job));
320299 } catch (...) {
321300 LOG_FATAL << " exception thrown in worker thread: "
322301 << exception_str (std::current_exception ());
@@ -364,11 +343,22 @@ using default_worker_group = basic_worker_group<LoggerPolicy, no_policy>;
364343
365344} // namespace
366345
346+ worker_group::worker_group (
347+ logger& lgr, os_access const & os, char const * group_name,
348+ size_t num_workers,
349+ std::function<std::unique_ptr<thread_state>(size_t )> thread_state_factory,
350+ size_t max_queue_len, int niceness)
351+ : impl_{make_unique_logging_object<impl, default_worker_group,
352+ logger_policies>(
353+ lgr, os, group_name, num_workers, thread_state_factory, max_queue_len,
354+ niceness)} {}
355+
367356worker_group::worker_group (logger& lgr, os_access const & os,
368357 char const * group_name, size_t num_workers,
369358 size_t max_queue_len, int niceness)
370- : impl_{make_unique_logging_object<impl, default_worker_group,
371- logger_policies>(
372- lgr, os, group_name, num_workers, max_queue_len, niceness)} {}
359+ : worker_group(
360+ lgr, os, group_name, num_workers,
361+ [](size_t ) { return std::make_unique<basic_thread_state<>>(); },
362+ max_queue_len, niceness) {}
373363
374364} // namespace dwarfs::internal
0 commit comments