diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc index 4571c726ec4a..3723960a5c0c 100644 --- a/base/message_loop/message_loop.cc +++ b/base/message_loop/message_loop.cc @@ -454,6 +454,10 @@ void MessageLoop::ScheduleWork() { pump_->ScheduleWork(); } +TimeTicks MessageLoop::CapAtOneDay(TimeTicks next_run_time) { + return std::min(next_run_time, recent_time_ + TimeDelta::FromDays(1)); +} + bool MessageLoop::DoWork() { if (!task_execution_allowed_) return false; @@ -502,7 +506,7 @@ bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) { if (next_run_time > recent_time_) { recent_time_ = TimeTicks::Now(); // Get a better view of Now(); if (next_run_time > recent_time_) { - *next_delayed_work_time = next_run_time; + *next_delayed_work_time = CapAtOneDay(next_run_time); return false; } } @@ -510,8 +514,8 @@ bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) { PendingTask pending_task = incoming_task_queue_->delayed_tasks().Pop(); if (incoming_task_queue_->delayed_tasks().HasTasks()) { - *next_delayed_work_time = - incoming_task_queue_->delayed_tasks().Peek().delayed_run_time; + *next_delayed_work_time = CapAtOneDay( + incoming_task_queue_->delayed_tasks().Peek().delayed_run_time); } return DeferOrRunPendingTask(std::move(pending_task)); diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h index 6010333616eb..7c31a128b53d 100644 --- a/base/message_loop/message_loop.h +++ b/base/message_loop/message_loop.h @@ -263,6 +263,14 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate, // responsible for synchronizing ScheduleWork() calls. void ScheduleWork(); + // Returns |next_run_time| capped at 1 day from |recent_time_|. This is used + // to mitigate https://crbug.com/850450 where some platforms are unhappy with + // delays > 100,000,000 seconds. In practice, a diagnosis metric showed that + // no sleep > 1 hour ever completes (always interrupted by an earlier + // MessageLoop event) and 99% of completed sleeps are the ones scheduled for + // <= 1 second. Details @ https://crrev.com/c/1142589. + TimeTicks CapAtOneDay(TimeTicks next_run_time); + // MessagePump::Delegate methods: bool DoWork() override; bool DoDelayedWork(TimeTicks* next_delayed_work_time) override;