#include "common.hh" #include #include #include #include #include #include "task_runner.hh" namespace { class TaskRunnerThread : public TaskRunner { public: explicit TaskRunnerThread(size_t threads) : threads_(std::max(1, threads)) { thread_ = std::make_unique(threads_); for (size_t i = 0; i < threads_; ++i) thread_[i] = std::thread(&TaskRunnerThread::thread, this); } ~TaskRunnerThread() override { { std::lock_guard lock(mutex_); quit_ = true; } cond_.notify_all(); for (size_t i = 0; i < threads_; ++i) thread_[i].join(); } void post(std::function callback) override { { std::lock_guard lock(mutex_); queue_.push_back(std::move(callback)); } cond_.notify_one(); } private: void thread() { while (true) { std::function callback; while (true) { std::unique_lock lock(mutex_); if (queue_.empty()) { if (quit_) return; cond_.wait(lock); } else { callback = std::move(queue_.front()); queue_.pop_front(); break; } } callback(); } } size_t const threads_; bool quit_{false}; std::condition_variable cond_; std::mutex mutex_; std::deque> queue_; std::unique_ptr thread_; }; } // namespace std::unique_ptr TaskRunner::create(size_t threads) { return std::make_unique(threads); }