| 380 | } |
| 381 | |
| 382 | void thread_pool_worker::ensure_worker_active(bool first_enqueuer, std::unique_lock<std::mutex>& lock) { |
| 383 | assert(lock.owns_lock()); |
| 384 | |
| 385 | if (!m_idle) { |
| 386 | lock.unlock(); |
| 387 | |
| 388 | if (first_enqueuer) { |
| 389 | m_semaphore.release(); |
| 390 | } |
| 391 | |
| 392 | return; |
| 393 | } |
| 394 | |
| 395 | auto stale_worker = std::move(m_thread); |
| 396 | m_thread = thread( |
| 397 | m_worker_name, |
| 398 | [this] { |
| 399 | work_loop(); |
| 400 | }, |
| 401 | m_thread_started_callback, |
| 402 | m_thread_terminated_callback); |
| 403 | |
| 404 | m_idle = false; |
| 405 | lock.unlock(); |
| 406 | |
| 407 | if (stale_worker.joinable()) { |
| 408 | stale_worker.join(); |
| 409 | } |
| 410 | } |
| 411 | |
| 412 | void thread_pool_worker::enqueue_foreign(concurrencpp::task& task) { |
| 413 | std::unique_lock<std::mutex> lock(m_lock); |