| 51 | } |
| 52 | |
| 53 | void UnboundedWorkQueue::Schedule(WorkFunction fn) { |
| 54 | // Enqueue a work item for the new thread's function, and wake up a |
| 55 | // cached thread to process it. |
| 56 | mutex_lock l(work_queue_mu_); |
| 57 | work_queue_.push_back(std::move(fn)); |
| 58 | work_queue_cv_.notify_one(); |
| 59 | // NOTE: The queue may be non-empty, so we must account for queued work when |
| 60 | // considering how many threads are free. |
| 61 | if (work_queue_.size() > num_idle_threads_) { |
| 62 | // Spawn a new physical thread to process the given function. |
| 63 | // NOTE: `PooledThreadFunc` will eventually increment `num_idle_threads_` |
| 64 | // at the beginning of its work loop. |
| 65 | Thread* new_thread = |
| 66 | env_->StartThread({}, thread_name_, [this]() { PooledThreadFunc(); }); |
| 67 | |
| 68 | mutex_lock l(thread_pool_mu_); |
| 69 | thread_pool_.emplace_back(new_thread); |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | void UnboundedWorkQueue::PooledThreadFunc() { |
| 74 | while (true) { |