Merge #18284: [0.19] scheduler: Workaround negative nsecs bug in boost's wait_until

ed0223ec59 scheduler: Workaround negative nsecs bug in boost's wait_until (Luke Dashjr)

Pull request description:

  Some boost versions have a bug that can cause a time prior to system boot (or wake from sleep) to throw an exception instead of return timeout
  See https://github.com/boostorg/thread/issues/308

  NOTE: This was addressed in master with a refactor (#18234), so this isn't a strict backport and needs full review.

  Fixes #18227

  Cleanly merges to 0.14+

ACKs for top commit:
  laanwj:
    ACK ed0223ec59
  gruve-p:
    ACK ed0223ec59

Tree-SHA512: 57edd0a22d7cf8f04b427e23d1ba10746a492638021d4438781b9d313dd0459418f64f0489be72d8e2286bbc8e8762d77e673868c25eb3bf4f0423a8fe8cdffa
This commit is contained in:
MarcoFalke
2020-08-28 08:23:03 +02:00

View File

@@ -63,8 +63,20 @@ void CScheduler::serviceQueue()
// Explicitly use a template here to avoid hitting that overload.
while (!shouldStop() && !taskQueue.empty()) {
boost::chrono::system_clock::time_point timeToWaitFor = taskQueue.begin()->first;
if (newTaskScheduled.wait_until<>(lock, timeToWaitFor) == boost::cv_status::timeout)
break; // Exit loop after timeout, it means we reached the time of the event
try {
if (newTaskScheduled.wait_until<>(lock, timeToWaitFor) == boost::cv_status::timeout) {
break; // Exit loop after timeout, it means we reached the time of the event
}
} catch (boost::thread_interrupted) {
// We need to make sure we don't ignore this, or the thread won't end
throw;
} catch (...) {
// Some boost versions have a bug that can cause a time prior to system boot (or wake from sleep) to throw an exception instead of return timeout
// See https://github.com/boostorg/thread/issues/308
// Check if the time has passed and, if so, break gracefully
if (timeToWaitFor <= boost::chrono::system_clock::now()) break;
throw;
}
}
#endif
// If there are multiple threads, the queue can empty while we're waiting (another