Pushing to the queue may take a long time when the `std::vector` needs
to allocate more memory. We should wake up the `Finisher` thread only
right before unlocking the `finisher_mutex` to reduce lock contention,
because it is the more likely that the mutex can really be acquired
when the thread really wakes up.
This imitates how commit
cc7ec3e18d191575c did it - it refactored only
one of the `queue()` overloads, leaving less-than-optimal copies of
this piece code in all other overloads.
Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
auto queue(T &ls) -> decltype(std::distance(ls.begin(), ls.end()), void()) {
{
const std::lock_guard l{finisher_lock};
- if (finisher_queue.empty() && !finisher_running) {
- finisher_cond.notify_all();
- }
+ const bool should_notify = finisher_queue.empty() && !finisher_running;
for (Context *i : ls) {
finisher_queue.push_back(std::make_pair(i, 0));
}
+ if (should_notify) {
+ finisher_cond.notify_all();
+ }
}
if (logger)
logger->inc(l_finisher_queue_len, ls.size());