util/thread_pool.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // SPDX-License-Identifier: BSD-3-Clause | ||
| 2 | #include "chrono_batch_render/util/thread_pool.h" | ||
| 3 | |||
| 4 | #include <algorithm> | ||
| 5 | #include <utility> | ||
| 6 | |||
| 7 | namespace chrono::batch_render { | ||
| 8 | |||
| 9 | 373 | ThreadPool::~ThreadPool() { | |
| 10 | 373 | std::deque<Job> dropped; | |
| 11 | 373 | { | |
| 12 | 373 | const std::lock_guard lock(m_mutex); | |
| 13 | 373 | m_stopping = true; | |
| 14 | 373 | dropped.swap(m_jobs); | |
| 15 | 373 | } | |
| 16 | 373 | m_ready.notify_all(); | |
| 17 | 488 | for (std::thread& thread : m_threads) { | |
| 18 | 115 | thread.join(); | |
| 19 | } | ||
| 20 | 373 | } | |
| 21 | |||
| 22 | 1183 | void ThreadPool::Add(const void* key, std::function<void()> job) { | |
| 23 | 1183 | { | |
| 24 | 1183 | const std::lock_guard lock(m_mutex); | |
| 25 | 1183 | if (m_threads.empty()) { | |
| 26 | 183 | for (unsigned i = 0; i < m_size; ++i) { | |
| 27 | 274 | m_threads.emplace_back([this] { Run(); }); | |
| 28 | } | ||
| 29 | } | ||
| 30 | 1183 | m_jobs.push_back({key, std::move(job)}); | |
| 31 | 1183 | } | |
| 32 | 1183 | m_ready.notify_one(); | |
| 33 | 2366 | } | |
| 34 | |||
| 35 | 1343 | std::function<void()> ThreadPool::Take(const void* key) { | |
| 36 | 1343 | const std::lock_guard lock(m_mutex); | |
| 37 | 1343 | const auto found = std::ranges::find(m_jobs, key, &Job::key); | |
| 38 | 1343 | if (found == m_jobs.end()) { | |
| 39 | 1209 | return {}; | |
| 40 | } | ||
| 41 | |||
| 42 | 134 | std::function<void()> taken = std::move(found->run); | |
| 43 | 134 | m_jobs.erase(found); | |
| 44 | 134 | return taken; | |
| 45 | 134 | } | |
| 46 | |||
| 47 | 1124 | bool ThreadPool::Cancel(const void* key) { | |
| 48 | 1124 | return bool(Take(key)); | |
| 49 | } | ||
| 50 | |||
| 51 | 137 | void ThreadPool::Run() { | |
| 52 | 2235 | for (;;) { | |
| 53 | 1186 | Job job; | |
| 54 | 1186 | { | |
| 55 | 1186 | std::unique_lock lock(m_mutex); | |
| 56 | 2669 | m_ready.wait(lock, [this] { return m_stopping || !m_jobs.empty(); }); | |
| 57 | 1164 | if (m_stopping) { | |
| 58 | 115 | return; | |
| 59 | } | ||
| 60 | 1049 | job = std::move(m_jobs.front()); | |
| 61 | 1049 | m_jobs.pop_front(); | |
| 62 | 115 | } | |
| 63 | 1049 | job.run(); | |
| 64 | 1164 | } | |
| 65 | } | ||
| 66 | |||
| 67 | } | ||
| 68 |