forked from lix-project/hydra
Fix potential race in dispatcher wakeup
This commit is contained in:
parent
6a1c950e94
commit
593850b956
|
@ -36,11 +36,14 @@ void State::dispatcher()
|
||||||
/* Sleep until we're woken up (either because a runnable build
|
/* Sleep until we're woken up (either because a runnable build
|
||||||
is added, or because a build finishes). */
|
is added, or because a build finishes). */
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(dispatcherMutex);
|
auto dispatcherWakeup_(dispatcherWakeup.lock());
|
||||||
|
if (!*dispatcherWakeup_) {
|
||||||
printMsg(lvlDebug, format("dispatcher sleeping for %1%s") %
|
printMsg(lvlDebug, format("dispatcher sleeping for %1%s") %
|
||||||
std::chrono::duration_cast<std::chrono::seconds>(sleepUntil - std::chrono::system_clock::now()).count());
|
std::chrono::duration_cast<std::chrono::seconds>(sleepUntil - std::chrono::system_clock::now()).count());
|
||||||
dispatcherWakeup.wait_until(lock, sleepUntil);
|
dispatcherWakeup_.wait_until(dispatcherWakeupCV, sleepUntil);
|
||||||
|
}
|
||||||
nrDispatcherWakeups++;
|
nrDispatcherWakeups++;
|
||||||
|
*dispatcherWakeup_ = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +170,9 @@ system_time State::doDispatch()
|
||||||
|
|
||||||
void State::wakeDispatcher()
|
void State::wakeDispatcher()
|
||||||
{
|
{
|
||||||
{ std::lock_guard<std::mutex> lock(dispatcherMutex); } // barrier
|
{
|
||||||
dispatcherWakeup.notify_one();
|
auto dispatcherWakeup_(dispatcherWakeup.lock());
|
||||||
|
*dispatcherWakeup_ = true;
|
||||||
|
}
|
||||||
|
dispatcherWakeupCV.notify_one();
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,8 +202,8 @@ private:
|
||||||
Sync<Runnable> runnable;
|
Sync<Runnable> runnable;
|
||||||
|
|
||||||
/* CV for waking up the dispatcher. */
|
/* CV for waking up the dispatcher. */
|
||||||
std::condition_variable dispatcherWakeup;
|
Sync<bool> dispatcherWakeup;
|
||||||
std::mutex dispatcherMutex;
|
std::condition_variable_any dispatcherWakeupCV;
|
||||||
|
|
||||||
/* PostgreSQL connection pool. */
|
/* PostgreSQL connection pool. */
|
||||||
Pool<Connection> dbPool;
|
Pool<Connection> dbPool;
|
||||||
|
|
|
@ -60,6 +60,14 @@ public:
|
||||||
assert(s);
|
assert(s);
|
||||||
return cv.wait_for(s->mutex, duration, pred);
|
return cv.wait_for(s->mutex, duration, pred);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class Clock, class Duration>
|
||||||
|
std::cv_status wait_until(std::condition_variable_any & cv,
|
||||||
|
const std::chrono::time_point<Clock, Duration> & duration)
|
||||||
|
{
|
||||||
|
assert(s);
|
||||||
|
return cv.wait_until(s->mutex, duration);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Lock lock() { return Lock(this); }
|
Lock lock() { return Lock(this); }
|
||||||
|
|
Loading…
Reference in a new issue