Commit 4db62d2a authored by Peter Marshall's avatar Peter Marshall Committed by Commit Bot

[platform] Only wait for positive time values in DelayedTaskQueue

We were hitting a DCHECK in WaitFor() when rel_time was negative. This
was caused when GetNext() recalculated the wait time for a delayed
task. In the first part of the loop we moved all delayed tasks which
have passed their deadline into the immediate task queue. At the
bottom of the loop we assume that all delayed tasks in the queue
have a deadline in the future, but this isn't always the case as we
use a new 'now' value for the calculation, and time could have elapsed.

Fix this by using one 'now' value for an iteration of the loop.

Bug: v8:9030
Change-Id: Ia49fb571f3c7c7d9f15c6a464ee0a9db814a7f03
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1535820
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60409}
parent 85017f04
......@@ -47,10 +47,11 @@ std::unique_ptr<Task> DelayedTaskQueue::GetNext() {
base::MutexGuard guard(&lock_);
for (;;) {
// Move delayed tasks that have hit their deadline to the main queue.
std::unique_ptr<Task> task = PopTaskFromDelayedQueue();
double now = MonotonicallyIncreasingTime();
std::unique_ptr<Task> task = PopTaskFromDelayedQueue(now);
while (task) {
task_queue_.push(std::move(task));
task = PopTaskFromDelayedQueue();
task = PopTaskFromDelayedQueue(now);
}
if (!task_queue_.empty()) {
std::unique_ptr<Task> result = std::move(task_queue_.front());
......@@ -65,7 +66,6 @@ std::unique_ptr<Task> DelayedTaskQueue::GetNext() {
if (task_queue_.empty() && !delayed_task_queue_.empty()) {
// Wait for the next delayed task or a newly posted task.
double now = MonotonicallyIncreasingTime();
double wait_in_seconds = delayed_task_queue_.begin()->first - now;
base::TimeDelta wait_delta = base::TimeDelta::FromMicroseconds(
base::TimeConstants::kMicrosecondsPerSecond * wait_in_seconds);
......@@ -82,12 +82,10 @@ std::unique_ptr<Task> DelayedTaskQueue::GetNext() {
}
// Gets the next task from the delayed queue for which the deadline has passed
// according to |time_function_|. Returns nullptr if no such task exists.
std::unique_ptr<Task> DelayedTaskQueue::PopTaskFromDelayedQueue() {
// according to |now|. Returns nullptr if no such task exists.
std::unique_ptr<Task> DelayedTaskQueue::PopTaskFromDelayedQueue(double now) {
if (delayed_task_queue_.empty()) return nullptr;
double now = MonotonicallyIncreasingTime();
auto it = delayed_task_queue_.begin();
if (it->first > now) return nullptr;
......
......@@ -50,7 +50,7 @@ class V8_PLATFORM_EXPORT DelayedTaskQueue {
void Terminate();
private:
std::unique_ptr<Task> PopTaskFromDelayedQueue();
std::unique_ptr<Task> PopTaskFromDelayedQueue(double now);
base::ConditionVariable queues_condition_var_;
base::Mutex lock_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment