summaryrefslogtreecommitdiffstats
path: root/chromium/base/message_loop/message_loop.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-11-20 15:06:40 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-11-22 11:48:58 +0000
commitdaa093eea7c773db06799a13bd7e4e2e2a9f8f14 (patch)
tree96cc5e7b9194c1b29eab927730bfa419e7111c25 /chromium/base/message_loop/message_loop.cc
parentbe59a35641616a4cf23c4a13fa0632624b021c1b (diff)
BASELINE: Update Chromium to 63.0.3239.58
Change-Id: Ia93b322a00ba4dd4004f3bcf1254063ba90e1605 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/base/message_loop/message_loop.cc')
-rw-r--r--chromium/base/message_loop/message_loop.cc216
1 files changed, 66 insertions, 150 deletions
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> 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<PendingTask&>(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