From daa093eea7c773db06799a13bd7e4e2e2a9f8f14 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Mon, 20 Nov 2017 15:06:40 +0100 Subject: BASELINE: Update Chromium to 63.0.3239.58 Change-Id: Ia93b322a00ba4dd4004f3bcf1254063ba90e1605 Reviewed-by: Alexandru Croitor --- chromium/base/message_loop/message_loop.cc | 216 +++++++++-------------------- 1 file changed, 66 insertions(+), 150 deletions(-) (limited to 'chromium/base/message_loop/message_loop.cc') diff --git a/chromium/base/message_loop/message_loop.cc b/chromium/base/message_loop/message_loop.cc index 67b9e225617..f60fd180641 100644 --- a/chromium/base/message_loop/message_loop.cc +++ b/chromium/base/message_loop/message_loop.cc @@ -118,16 +118,15 @@ MessageLoop::~MessageLoop() { // tasks. Normally, we should only pass through this loop once or twice. If // we end up hitting the loop limit, then it is probably due to one task that // is being stubborn. Inspect the queues to see who is left. - bool did_work; + bool tasks_remain; for (int i = 0; i < 100; ++i) { DeletePendingTasks(); - ReloadWorkQueue(); // If we end up with empty queues, then break out of the loop. - did_work = DeletePendingTasks(); - if (!did_work) + tasks_remain = incoming_task_queue_->triage_tasks().HasTasks(); + if (!tasks_remain) break; } - DCHECK(!did_work); + DCHECK(!tasks_remain); // Let interested parties have one last shot at accessing this. for (auto& observer : destruction_observers_) @@ -239,11 +238,11 @@ void MessageLoop::SetNestableTasksAllowed(bool allowed) { // loop that does not go through RunLoop::Run(). pump_->ScheduleWork(); } - nestable_tasks_allowed_ = allowed; + task_execution_allowed_ = allowed; } bool MessageLoop::NestableTasksAllowed() const { - return nestable_tasks_allowed_ || run_loop_client_->ProcessingTasksAllowed(); + return task_execution_allowed_; } // TODO(gab): Migrate TaskObservers to RunLoop as part of separating concerns @@ -278,18 +277,11 @@ std::unique_ptr MessageLoop::CreateUnbound( MessageLoop::MessageLoop(Type type, MessagePumpFactoryCallback pump_factory) : type_(type), -#if defined(OS_WIN) - pending_high_res_tasks_(0), - in_high_res_mode_(false), -#endif - nestable_tasks_allowed_(true), pump_factory_(std::move(pump_factory)), - current_pending_task_(nullptr), incoming_task_queue_(new internal::IncomingTaskQueue(this)), unbound_task_runner_( new internal::MessageLoopTaskRunner(incoming_task_queue_)), - task_runner_(unbound_task_runner_), - thread_id_(kInvalidThreadId) { + task_runner_(unbound_task_runner_) { // If type is TYPE_CUSTOM non-null pump_factory must be given. DCHECK(type_ != TYPE_CUSTOM || !pump_factory_.is_null()); } @@ -341,9 +333,17 @@ void MessageLoop::ClearTaskRunnerForTesting() { thread_task_runner_handle_.reset(); } -void MessageLoop::Run() { +void MessageLoop::Run(bool application_tasks_allowed) { DCHECK_EQ(this, current()); - pump_->Run(this); + if (application_tasks_allowed && !task_execution_allowed_) { + // Allow nested task execution as explicitly requested. + DCHECK(run_loop_client_->IsNested()); + task_execution_allowed_ = true; + pump_->Run(this); + task_execution_allowed_ = false; + } else { + pump_->Run(this); + } } void MessageLoop::Quit() { @@ -353,8 +353,7 @@ void MessageLoop::Quit() { void MessageLoop::EnsureWorkScheduled() { DCHECK_EQ(this, current()); - ReloadWorkQueue(); - if (!work_queue_.empty()) + if (incoming_task_queue_->triage_tasks().HasTasks()) pump_->ScheduleWork(); } @@ -370,50 +369,40 @@ bool MessageLoop::ProcessNextDelayedNonNestableTask() { if (run_loop_client_->IsNested()) return false; - while (!deferred_non_nestable_work_queue_.empty()) { - PendingTask pending_task = - std::move(deferred_non_nestable_work_queue_.front()); - deferred_non_nestable_work_queue_.pop(); - + while (incoming_task_queue_->deferred_tasks().HasTasks()) { + PendingTask pending_task = incoming_task_queue_->deferred_tasks().Pop(); if (!pending_task.task.IsCancelled()) { RunTask(&pending_task); return true; } - -#if defined(OS_WIN) - DecrementHighResTaskCountIfNeeded(pending_task); -#endif } return false; } void MessageLoop::RunTask(PendingTask* pending_task) { - DCHECK(NestableTasksAllowed()); + DCHECK(task_execution_allowed_); current_pending_task_ = pending_task; -#if defined(OS_WIN) - DecrementHighResTaskCountIfNeeded(*pending_task); -#endif - // Execute the task and assume the worst: It is probably not reentrant. - nestable_tasks_allowed_ = false; + task_execution_allowed_ = false; TRACE_TASK_EXECUTION("MessageLoop::RunTask", *pending_task); for (auto& observer : task_observers_) observer.WillProcessTask(*pending_task); - task_annotator_.RunTask("MessageLoop::PostTask", pending_task); + incoming_task_queue_->RunTask(pending_task); for (auto& observer : task_observers_) observer.DidProcessTask(*pending_task); - nestable_tasks_allowed_ = true; + task_execution_allowed_ = true; current_pending_task_ = nullptr; } bool MessageLoop::DeferOrRunPendingTask(PendingTask pending_task) { - if (pending_task.nestable || !run_loop_client_->IsNested()) { + if (pending_task.nestable == Nestable::kNestable || + !run_loop_client_->IsNested()) { RunTask(&pending_task); // Show that we ran a task (Note: a new one might arrive as a // consequence!). @@ -422,71 +411,17 @@ bool MessageLoop::DeferOrRunPendingTask(PendingTask pending_task) { // We couldn't run the task now because we're in a nested run loop // and the task isn't nestable. - deferred_non_nestable_work_queue_.push(std::move(pending_task)); - return false; -} - -void MessageLoop::AddToDelayedWorkQueue(PendingTask pending_task) { - // Move to the delayed work queue. - delayed_work_queue_.push(std::move(pending_task)); -} - -bool MessageLoop::SweepDelayedWorkQueueAndReturnTrueIfStillHasWork() { - while (!delayed_work_queue_.empty()) { - const PendingTask& pending_task = delayed_work_queue_.top(); - if (!pending_task.task.IsCancelled()) - return true; - -#if defined(OS_WIN) - DecrementHighResTaskCountIfNeeded(pending_task); -#endif - delayed_work_queue_.pop(); - } + incoming_task_queue_->deferred_tasks().Push(std::move(pending_task)); return false; } -bool MessageLoop::DeletePendingTasks() { - bool did_work = !work_queue_.empty(); - while (!work_queue_.empty()) { - PendingTask pending_task = std::move(work_queue_.front()); - work_queue_.pop(); - if (!pending_task.delayed_run_time.is_null()) { - // We want to delete delayed tasks in the same order in which they would - // normally be deleted in case of any funny dependencies between delayed - // tasks. - AddToDelayedWorkQueue(std::move(pending_task)); - } - } - did_work |= !deferred_non_nestable_work_queue_.empty(); - while (!deferred_non_nestable_work_queue_.empty()) { - deferred_non_nestable_work_queue_.pop(); - } - did_work |= !delayed_work_queue_.empty(); - - // Historically, we always delete the task regardless of valgrind status. It's - // not completely clear why we want to leak them in the loops above. This - // code is replicating legacy behavior, and should not be considered - // absolutely "correct" behavior. See TODO above about deleting all tasks - // when it's safe. - while (!delayed_work_queue_.empty()) { - delayed_work_queue_.pop(); - } - return did_work; -} - -void MessageLoop::ReloadWorkQueue() { - // We can improve performance of our loading tasks from the incoming queue to - // |*work_queue| by waiting until the last minute (|*work_queue| is empty) to - // load. That reduces the number of locks-per-task significantly when our - // queues get large. - if (work_queue_.empty()) { -#if defined(OS_WIN) - pending_high_res_tasks_ += - incoming_task_queue_->ReloadWorkQueue(&work_queue_); -#else - incoming_task_queue_->ReloadWorkQueue(&work_queue_); -#endif - } +void MessageLoop::DeletePendingTasks() { + incoming_task_queue_->triage_tasks().Clear(); + incoming_task_queue_->deferred_tasks().Clear(); + // TODO(robliao): Determine if we can move delayed task destruction before + // deferred tasks to maintain the MessagePump DoWork, DoDelayedWork, and + // DoIdleWork processing order. + incoming_task_queue_->delayed_tasks().Clear(); } void MessageLoop::ScheduleWork() { @@ -494,37 +429,27 @@ void MessageLoop::ScheduleWork() { } bool MessageLoop::DoWork() { - if (!NestableTasksAllowed()) { - // Task can't be executed right now. + if (!task_execution_allowed_) return false; - } - - for (;;) { - ReloadWorkQueue(); - if (work_queue_.empty()) - break; - // Execute oldest task. - do { - PendingTask pending_task = std::move(work_queue_.front()); - work_queue_.pop(); + // Execute oldest task. + while (incoming_task_queue_->triage_tasks().HasTasks()) { + PendingTask pending_task = incoming_task_queue_->triage_tasks().Pop(); + if (pending_task.task.IsCancelled()) + continue; - if (pending_task.task.IsCancelled()) { -#if defined(OS_WIN) - DecrementHighResTaskCountIfNeeded(pending_task); -#endif - } else if (!pending_task.delayed_run_time.is_null()) { - int sequence_num = pending_task.sequence_num; - TimeTicks delayed_run_time = pending_task.delayed_run_time; - AddToDelayedWorkQueue(std::move(pending_task)); - // If we changed the topmost task, then it is time to reschedule. - if (delayed_work_queue_.top().sequence_num == sequence_num) - pump_->ScheduleDelayedWork(delayed_run_time); - } else { - if (DeferOrRunPendingTask(std::move(pending_task))) - return true; + if (!pending_task.delayed_run_time.is_null()) { + int sequence_num = pending_task.sequence_num; + TimeTicks delayed_run_time = pending_task.delayed_run_time; + incoming_task_queue_->delayed_tasks().Push(std::move(pending_task)); + // If we changed the topmost task, then it is time to reschedule. + if (incoming_task_queue_->delayed_tasks().Peek().sequence_num == + sequence_num) { + pump_->ScheduleDelayedWork(delayed_run_time); } - } while (!work_queue_.empty()); + } else if (DeferOrRunPendingTask(std::move(pending_task))) { + return true; + } } // Nothing happened. @@ -532,8 +457,8 @@ bool MessageLoop::DoWork() { } bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) { - if (!NestableTasksAllowed() || - !SweepDelayedWorkQueueAndReturnTrueIfStillHasWork()) { + if (!task_execution_allowed_ || + !incoming_task_queue_->delayed_tasks().HasTasks()) { recent_time_ = *next_delayed_work_time = TimeTicks(); return false; } @@ -545,7 +470,8 @@ bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) { // fall behind (and have a lot of ready-to-run delayed tasks), the more // efficient we'll be at handling the tasks. - TimeTicks next_run_time = delayed_work_queue_.top().delayed_run_time; + TimeTicks next_run_time = + incoming_task_queue_->delayed_tasks().Peek().delayed_run_time; if (next_run_time > recent_time_) { recent_time_ = TimeTicks::Now(); // Get a better view of Now(); if (next_run_time > recent_time_) { @@ -554,12 +480,12 @@ bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) { } } - PendingTask pending_task = - std::move(const_cast(delayed_work_queue_.top())); - delayed_work_queue_.pop(); + PendingTask pending_task = incoming_task_queue_->delayed_tasks().Pop(); - if (SweepDelayedWorkQueueAndReturnTrueIfStillHasWork()) - *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time; + if (incoming_task_queue_->delayed_tasks().HasTasks()) { + *next_delayed_work_time = + incoming_task_queue_->delayed_tasks().Peek().delayed_run_time; + } return DeferOrRunPendingTask(std::move(pending_task)); } @@ -577,7 +503,7 @@ bool MessageLoop::DoIdleWork() { // _if_ triggered by the timer happens with good resolution. If we don't // do this the default resolution is 15ms which might not be acceptable // for some tasks. - bool high_res = pending_high_res_tasks_ > 0; + bool high_res = incoming_task_queue_->HasPendingHighResolutionTasks(); if (high_res != in_high_res_mode_) { in_high_res_mode_ = high_res; Time::ActivateHighResolutionTimer(in_high_res_mode_); @@ -586,16 +512,6 @@ bool MessageLoop::DoIdleWork() { return false; } -#if defined(OS_WIN) -void MessageLoop::DecrementHighResTaskCountIfNeeded( - const PendingTask& pending_task) { - if (!pending_task.is_high_res) - return; - --pending_high_res_tasks_; - DCHECK_GE(pending_high_res_tasks_, 0); -} -#endif - #if !defined(OS_NACL) //------------------------------------------------------------------------------ // MessageLoopForUI @@ -683,13 +599,13 @@ bool MessageLoopForIO::WatchFileDescriptor(int fd, #if defined(OS_FUCHSIA) // Additional watch API for native platform resources. -bool MessageLoopForIO::WatchMxHandle(mx_handle_t handle, +bool MessageLoopForIO::WatchZxHandle(zx_handle_t handle, bool persistent, - mx_signals_t signals, - MxHandleWatchController* controller, - MxHandleWatcher* delegate) { + zx_signals_t signals, + ZxHandleWatchController* controller, + ZxHandleWatcher* delegate) { return ToPumpIO(pump_.get()) - ->WatchMxHandle(handle, persistent, signals, controller, delegate); + ->WatchZxHandle(handle, persistent, signals, controller, delegate); } #endif -- cgit v1.2.3