| 263 | } |
| 264 | |
| 265 | bool thread_pool_worker::wait_for_task(std::unique_lock<std::mutex>& lock) { |
| 266 | assert(lock.owns_lock()); |
| 267 | |
| 268 | if (!m_public_queue.empty() || m_abort) { |
| 269 | return true; |
| 270 | } |
| 271 | |
| 272 | lock.unlock(); |
| 273 | |
| 274 | m_parent_pool.mark_worker_idle(m_index); |
| 275 | |
| 276 | auto event_found = false; |
| 277 | const auto deadline = std::chrono::steady_clock::now() + m_max_idle_time; |
| 278 | |
| 279 | while (true) { |
| 280 | if (!m_semaphore.try_acquire_until(deadline)) { |
| 281 | if (std::chrono::steady_clock::now() <= deadline) { |
| 282 | continue; // handle spurious wake-ups |
| 283 | } else { |
| 284 | break; |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | if (!m_task_found_or_abort.load(std::memory_order_relaxed)) { |
| 289 | continue; |
| 290 | } |
| 291 | |
| 292 | lock.lock(); |
| 293 | if (m_public_queue.empty() && !m_abort) { |
| 294 | lock.unlock(); |
| 295 | continue; |
| 296 | } |
| 297 | |
| 298 | event_found = true; |
| 299 | break; |
| 300 | } |
| 301 | |
| 302 | if (!lock.owns_lock()) { |
| 303 | lock.lock(); |
| 304 | } |
| 305 | |
| 306 | if (!event_found || m_abort) { |
| 307 | m_idle = true; |
| 308 | lock.unlock(); |
| 309 | return false; |
| 310 | } |
| 311 | |
| 312 | assert(!m_public_queue.empty()); |
| 313 | m_parent_pool.mark_worker_active(m_index); |
| 314 | return true; |
| 315 | } |
| 316 | |
| 317 | bool thread_pool_worker::drain_queue_impl() { |
| 318 | auto aborted = false; |
nothing calls this directly
no test coverage detected