diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2021-11-17 22:34:57 +0100 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2021-11-17 22:34:57 +0100 |
| commit | 6232d13f5321b87ddf12a1aa36b4545da45f173d (patch) | |
| tree | 23f3316470a14136debd9d02f9e920ca2b06f4cc /src/task_runner_thread.cc | |
Travel3: Simple image and video display site
Reads the images and videos from filesystem and builds a site in
memroy.
Diffstat (limited to 'src/task_runner_thread.cc')
| -rw-r--r-- | src/task_runner_thread.cc | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/task_runner_thread.cc b/src/task_runner_thread.cc new file mode 100644 index 0000000..6e1a06f --- /dev/null +++ b/src/task_runner_thread.cc @@ -0,0 +1,73 @@ +#include "common.hh" + +#include <algorithm> +#include <condition_variable> +#include <deque> +#include <mutex> +#include <thread> + +#include "task_runner.hh" + +namespace { + +class TaskRunnerThread : public TaskRunner { +public: + explicit TaskRunnerThread(size_t threads) + : threads_(std::max<size_t>(1, threads)) { + thread_ = std::make_unique<std::thread[]>(threads_); + for (size_t i = 0; i < threads_; ++i) + thread_[i] = std::thread(&TaskRunnerThread::thread, this); + } + + ~TaskRunnerThread() override { + { + std::lock_guard<std::mutex> lock(mutex_); + quit_ = true; + } + cond_.notify_all(); + for (size_t i = 0; i < threads_; ++i) + thread_[i].join(); + } + + void post(std::function<void()> callback) override { + { + std::lock_guard<std::mutex> lock(mutex_); + queue_.push_back(std::move(callback)); + } + cond_.notify_one(); + } + +private: + void thread() { + while (true) { + std::function<void()> callback; + while (true) { + std::unique_lock<std::mutex> 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<std::function<void()>> queue_; + std::unique_ptr<std::thread[]> thread_; +}; + +} // namespace + +std::unique_ptr<TaskRunner> TaskRunner::create(size_t threads) { + return std::make_unique<TaskRunnerThread>(threads); +} |
