File size: 2,374 Bytes
cc372ac |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
//
// SPDX-FileCopyrightText: Hadad <hadad@linuxmail.org>
// SPDX-License-Identifier: Apache-2.0
//
#ifndef POCKET_TTS_THREAD_POOL_HPP
#define POCKET_TTS_THREAD_POOL_HPP
#include <atomic>
#include <condition_variable>
#include <functional>
#include <future>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>
#include <vector>
namespace pocket_tts_accelerator {
class ThreadPool {
public:
explicit ThreadPool(std::size_t number_of_threads);
~ThreadPool();
ThreadPool(const ThreadPool&) = delete;
ThreadPool& operator=(const ThreadPool&) = delete;
ThreadPool(ThreadPool&&) = delete;
ThreadPool& operator=(ThreadPool&&) = delete;
template<typename FunctionType, typename... ArgumentTypes>
auto submit_task(FunctionType&& function, ArgumentTypes&&... arguments)
-> std::future<typename std::invoke_result<FunctionType, ArgumentTypes...>::type>;
void shutdown();
bool is_running() const;
std::size_t get_pending_task_count() const;
std::size_t get_thread_count() const;
private:
void worker_thread_function();
std::vector<std::thread> worker_threads;
std::queue<std::function<void()>> task_queue;
mutable std::mutex queue_mutex;
std::condition_variable task_available_condition;
std::atomic<bool> should_stop;
std::atomic<bool> is_stopped;
std::size_t thread_count;
};
template<typename FunctionType, typename... ArgumentTypes>
auto ThreadPool::submit_task(FunctionType&& function, ArgumentTypes&&... arguments)
-> std::future<typename std::invoke_result<FunctionType, ArgumentTypes...>::type> {
using ReturnType = typename std::invoke_result<FunctionType, ArgumentTypes...>::type;
auto packaged_task = std::make_shared<std::packaged_task<ReturnType()>>(
std::bind(std::forward<FunctionType>(function), std::forward<ArgumentTypes>(arguments)...)
);
std::future<ReturnType> result_future = packaged_task->get_future();
{
std::unique_lock<std::mutex> lock(queue_mutex);
if (should_stop.load()) {
throw std::runtime_error("Cannot submit task to stopped thread pool");
}
task_queue.emplace([packaged_task]() {
(*packaged_task)();
});
}
task_available_condition.notify_one();
return result_future;
}
}
#endif |