diff --git a/src/util/thread_pool_executor.cc b/src/util/thread_pool_executor.cc index b496d2e9..231c3921 100644 --- a/src/util/thread_pool_executor.cc +++ b/src/util/thread_pool_executor.cc @@ -1,23 +1,93 @@ /** -* src/util/thread_pool_executor.cc -* -* Copyright (c) 2021-2022 Bartek Kryza -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * src/util/thread_pool_executor.cc + * + * Copyright (c) 2021-2022 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "thread_pool_executor.h" namespace clanguml::util { +thread_pool_executor::thread_pool_executor() + : thread_pool_executor{0} +{ +} + +thread_pool_executor::thread_pool_executor(unsigned int pool_size) + : done_{false} +{ + if (pool_size == 0U) + pool_size = std::thread::hardware_concurrency(); + + for (auto i = 0U; i < pool_size; i++) { + threads_.push_back(std::thread{&thread_pool_executor::worker, this}); + } +} + +~thread_pool_executor::thread_pool_executor() { stop(); } + +std::future thread_pool_executor::add(std::function &&task) +{ + std::unique_lock l(tasks_mutex_); + + std::packaged_task ptask{std::move(task)}; + auto res = ptask.get_future(); + + tasks_.emplace_back(std::move(ptask)); + + l.unlock(); + tasks_cond_.notify_one(); + + return res; +} + +void thread_pool_executor::stop() +{ + done_ = true; + for (auto &thread : threads_) { + if (thread.joinable()) + thread.join(); + } +} + +void thread_pool_executor::worker() +{ + try { + while (!done_) { + auto task = get(); + + task(); + } + } + catch (std::runtime_error &e) { + } +} + +std::packaged_task thread_pool_executor::get() +{ + std::unique_lock l(tasks_mutex_); + + while (tasks_.empty()) { + if (done_) + throw std::runtime_error("Thread pool closing..."); + + tasks_cond_.wait_for(l, std::chrono::seconds(1)); + } + + auto res = std::move(tasks_.front()); + tasks_.pop_front(); + return res; +} } diff --git a/src/util/thread_pool_executor.h b/src/util/thread_pool_executor.h index 4a570c72..52e19fdf 100644 --- a/src/util/thread_pool_executor.h +++ b/src/util/thread_pool_executor.h @@ -25,78 +25,20 @@ namespace clanguml::util { class thread_pool_executor { public: - thread_pool_executor() - : thread_pool_executor{0} - { - } + thread_pool_executor(); - thread_pool_executor(unsigned int pool_size) - : done_{false} - { - if (pool_size == 0U) - pool_size = std::thread::hardware_concurrency(); + thread_pool_executor(unsigned int pool_size); - for (auto i = 0U; i < pool_size; i++) { - threads_.push_back( - std::thread{&thread_pool_executor::worker, this}); - } - } + ~thread_pool_executor(); - ~thread_pool_executor() { stop(); } + std::future add(std::function &&task); - std::future add(std::function &&task) - { - std::unique_lock l(tasks_mutex_); - - std::packaged_task ptask{std::move(task)}; - auto res = ptask.get_future(); - - tasks_.emplace_back(std::move(ptask)); - - l.unlock(); - tasks_cond_.notify_one(); - - return res; - } - - void stop() - { - done_ = true; - for (auto &thread : threads_) { - if (thread.joinable()) - thread.join(); - } - } + void stop(); private: - void worker() - { - try { - while (!done_) { - auto task = get(); + void worker(); - task(); - } - } - catch (std::runtime_error &e) { - } - } - - std::packaged_task get() - { - std::unique_lock l(tasks_mutex_); - - while (tasks_.empty()) { - if (done_) - throw std::runtime_error("Thread pool closing..."); - - tasks_cond_.wait_for(l, std::chrono::seconds(1)); - } - - auto res = std::move(tasks_.front()); - tasks_.pop_front(); - return res; - } + std::packaged_task get(); std::atomic_bool done_;