summaryrefslogtreecommitdiffstats
path: root/chromium/base/message_loop/message_loop.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-13 15:05:36 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-14 10:33:47 +0000
commite684a3455bcc29a6e3e66a004e352dea4e1141e7 (patch)
treed55b4003bde34d7d05f558f02cfd82b2a66a7aac /chromium/base/message_loop/message_loop.cc
parent2b94bfe47ccb6c08047959d1c26e392919550e86 (diff)
BASELINE: Update Chromium to 72.0.3626.110 and Ninja to 1.9.0
Change-Id: Ic57220b00ecc929a893c91f5cc552f5d3e99e922 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/base/message_loop/message_loop.cc')
-rw-r--r--chromium/base/message_loop/message_loop.cc573
1 files changed, 118 insertions, 455 deletions
diff --git a/chromium/base/message_loop/message_loop.cc b/chromium/base/message_loop/message_loop.cc
index ff55a15ce0f..dcc9f8d1163 100644
--- a/chromium/base/message_loop/message_loop.cc
+++ b/chromium/base/message_loop/message_loop.cc
@@ -1,25 +1,34 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
+// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/message_loop/message_loop.h"
#include <algorithm>
+#include <atomic>
#include <utility>
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/compiler_specific.h"
#include "base/debug/task_annotator.h"
+#include "base/feature_list.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop_impl.h"
#include "base/message_loop/message_loop_task_runner.h"
#include "base/message_loop/message_pump_default.h"
#include "base/message_loop/message_pump_for_io.h"
#include "base/message_loop/message_pump_for_ui.h"
#include "base/message_loop/sequenced_task_source.h"
+#include "base/optional.h"
#include "base/run_loop.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/task/sequence_manager/sequence_manager.h"
+#include "base/task/sequence_manager/sequence_manager_impl.h"
+#include "base/task/sequence_manager/task_queue.h"
#include "base/threading/thread_id_name_manager.h"
+#include "base/threading/thread_restrictions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
@@ -39,96 +48,15 @@ std::unique_ptr<MessagePump> ReturnPump(std::unique_ptr<MessagePump> pump) {
} // namespace
-class MessageLoop::Controller : public SequencedTaskSource::Observer {
- public:
- // Constructs a MessageLoopController which controls |message_loop|, notifying
- // |task_annotator_| when tasks are queued scheduling work on |message_loop|
- // as fits. |message_loop| and |task_annotator_| will not be used after
- // DisconnectFromParent() returns.
- Controller(MessageLoop* message_loop);
-
- ~Controller() override;
-
- // SequencedTaskSource::Observer:
- void WillQueueTask(PendingTask* task) final;
- void DidQueueTask(bool was_empty) final;
-
- void StartScheduling();
-
- // Disconnects |message_loop_| from this Controller instance (DidQueueTask()
- // will no-op from this point forward).
- void DisconnectFromParent();
-
- // Shares this Controller's TaskAnnotator with MessageLoop as TaskAnnotator
- // requires DidQueueTask(x)/RunTask(x) to be invoked on the same TaskAnnotator
- // instance.
- debug::TaskAnnotator& task_annotator() { return task_annotator_; }
-
- private:
- // A TaskAnnotator which is owned by this Controller to be able to use it
- // without locking |message_loop_lock_|. It cannot be owned by MessageLoop
- // because this Controller cannot access |message_loop_| safely without the
- // lock. Note: the TaskAnnotator API itself is thread-safe.
- debug::TaskAnnotator task_annotator_;
-
- // Lock that serializes |message_loop_->ScheduleWork()| and access to all
- // members below.
- base::Lock message_loop_lock_;
-
- // Points to this Controller's outer MessageLoop instance. Null after
- // DisconnectFromParent().
- MessageLoop* message_loop_;
-
- // False until StartScheduling() is called.
- bool is_ready_for_scheduling_ = false;
-
- // True if DidQueueTask() has been called before StartScheduling(); letting it
- // know whether it needs to ScheduleWork() right away or not.
- bool pending_schedule_work_ = false;
-
- DISALLOW_COPY_AND_ASSIGN(Controller);
-};
-
-MessageLoop::Controller::Controller(MessageLoop* message_loop)
- : message_loop_(message_loop) {}
-
-MessageLoop::Controller::~Controller() {
- DCHECK(!message_loop_)
- << "DisconnectFromParent() needs to be invoked before destruction.";
-}
-
-void MessageLoop::Controller::WillQueueTask(PendingTask* task) {
- task_annotator_.WillQueueTask("MessageLoop::PostTask", task);
-}
-
-void MessageLoop::Controller::DidQueueTask(bool was_empty) {
- // Avoid locking if we don't need to schedule.
- if (!was_empty)
- return;
-
- AutoLock auto_lock(message_loop_lock_);
-
- if (message_loop_ && is_ready_for_scheduling_)
- message_loop_->ScheduleWork();
- else
- pending_schedule_work_ = true;
-}
-
-void MessageLoop::Controller::StartScheduling() {
- AutoLock lock(message_loop_lock_);
- DCHECK(message_loop_);
- DCHECK(!is_ready_for_scheduling_);
- is_ready_for_scheduling_ = true;
- if (pending_schedule_work_)
- message_loop_->ScheduleWork();
-}
-
-void MessageLoop::Controller::DisconnectFromParent() {
- AutoLock lock(message_loop_lock_);
- message_loop_ = nullptr;
-}
-
-//------------------------------------------------------------------------------
+// Unfortunately since we're not on C++17 we're required to provide an out of
+// line definition.
+constexpr MessageLoop::Type MessageLoop::TYPE_DEFAULT;
+constexpr MessageLoop::Type MessageLoop::TYPE_UI;
+constexpr MessageLoop::Type MessageLoop::TYPE_CUSTOM;
+constexpr MessageLoop::Type MessageLoop::TYPE_IO;
+#if defined(OS_ANDROID)
+constexpr MessageLoop::Type MessageLoop::TYPE_JAVA;
+#endif
MessageLoop::MessageLoop(Type type)
: MessageLoop(type, MessagePumpFactoryCallback()) {
@@ -141,28 +69,6 @@ MessageLoop::MessageLoop(std::unique_ptr<MessagePump> pump)
}
MessageLoop::~MessageLoop() {
- // If |pump_| is non-null, this message loop has been bound and should be the
- // current one on this thread. Otherwise, this loop is being destructed before
- // it was bound to a thread, so a different message loop (or no loop at all)
- // may be current.
- DCHECK((pump_ && MessageLoopCurrent::IsBoundToCurrentThreadInternal(this)) ||
- (!pump_ && !MessageLoopCurrent::IsBoundToCurrentThreadInternal(this)));
-
- // iOS just attaches to the loop, it doesn't Run it.
- // TODO(stuartmorgan): Consider wiring up a Detach().
-#if !defined(OS_IOS)
- // There should be no active RunLoops on this thread, unless this MessageLoop
- // isn't bound to the current thread (see other condition at the top of this
- // method).
- DCHECK(
- (!pump_ && !MessageLoopCurrent::IsBoundToCurrentThreadInternal(this)) ||
- !RunLoop::IsRunningOnCurrentThread());
-#endif // !defined(OS_IOS)
-
-#if defined(OS_WIN)
- if (in_high_res_mode_)
- Time::ActivateHighResolutionTimer(false);
-#endif
// Clean up any unprocessed tasks, but take care: deleting a task could
// result in the addition of more tasks (e.g., via DeleteSoon). We set a
// limit on the number of times we will allow a deleted task to generate more
@@ -171,45 +77,30 @@ MessageLoop::~MessageLoop() {
// is being stubborn. Inspect the queues to see who is left.
bool tasks_remain;
for (int i = 0; i < 100; ++i) {
- DeletePendingTasks();
+ backend_->DeletePendingTasks();
// If we end up with empty queues, then break out of the loop.
- tasks_remain = sequenced_task_source_->HasTasks();
+ tasks_remain = backend_->HasTasks();
if (!tasks_remain)
break;
}
DCHECK(!tasks_remain);
- // Let interested parties have one last shot at accessing this.
- for (auto& observer : destruction_observers_)
- observer.WillDestroyCurrentMessageLoop();
-
- thread_task_runner_handle_.reset();
-
- // Detach this instance's Controller from |this|. After this point,
- // |underlying_task_runner_| may still receive tasks and notify the controller
- // but the controller will no-op (and not use this MessageLoop after free).
- // |underlying_task_runner_| being ref-counted and potentially kept alive by
- // many SingleThreadTaskRunner refs, the best we can do is tell it to shutdown
- // after which it will start returning false to PostTasks that happen-after
- // this point (note that invoking Shutdown() first would not remove the need
- // to DisconnectFromParent() since the controller is invoked *after* a task is
- // enqueued and the incoming queue's lock is released (see
- // MessageLoopTaskRunner::AddToIncomingQueue()).
- // Details : while an "in-progress post tasks" refcount in Controller in lieu
- // of |message_loop_lock_| would be an option to handle the "pending post
- // tasks on shutdown" case, |message_loop_lock_| would still be required to
- // serialize ScheduleWork() call and as such that optimization isn't worth it.
- message_loop_controller_->DisconnectFromParent();
- underlying_task_runner_->Shutdown();
-
- // OK, now make it so that no one can find us.
- if (MessageLoopCurrent::IsBoundToCurrentThreadInternal(this))
- MessageLoopCurrent::UnbindFromCurrentThreadInternal(this);
-}
+ // If |pump_| is non-null, this message loop has been bound and should be the
+ // current one on this thread. Otherwise, this loop is being destructed before
+ // it was bound to a thread, so a different message loop (or no loop at all)
+ // may be current.
+ DCHECK((pump_ && IsBoundToCurrentThread()) ||
+ (!pump_ && !IsBoundToCurrentThread()));
-// static
-MessageLoopCurrent MessageLoop::current() {
- return MessageLoopCurrent::Get();
+// iOS just attaches to the loop, it doesn't Run it.
+// TODO(stuartmorgan): Consider wiring up a Detach().
+#if !defined(OS_IOS)
+ // There should be no active RunLoops on this thread, unless this MessageLoop
+ // isn't bound to the current thread (see other condition at the top of this
+ // method).
+ DCHECK((!pump_ && !IsBoundToCurrentThread()) ||
+ !RunLoop::IsRunningOnCurrentThread());
+#endif // !defined(OS_IOS)
}
// static
@@ -239,11 +130,11 @@ std::unique_ptr<MessagePump> MessageLoop::CreateMessagePumpForType(Type type) {
}
if (type == MessageLoop::TYPE_IO)
- return std::unique_ptr<MessagePump>(new MessagePumpForIO());
+ return std::make_unique<MessagePumpForIO>();
#if defined(OS_ANDROID)
if (type == MessageLoop::TYPE_JAVA)
- return std::unique_ptr<MessagePump>(new MessagePumpForUI());
+ return std::make_unique<MessagePumpForUI>();
#endif
DCHECK_EQ(MessageLoop::TYPE_DEFAULT, type);
@@ -264,34 +155,24 @@ bool MessageLoop::IsType(Type type) const {
// implementation detail. http://crbug.com/703346
void MessageLoop::AddTaskObserver(TaskObserver* task_observer) {
DCHECK_CALLED_ON_VALID_THREAD(bound_thread_checker_);
- task_observers_.push_back(task_observer);
+ backend_->AddTaskObserver(task_observer);
}
void MessageLoop::RemoveTaskObserver(TaskObserver* task_observer) {
DCHECK_CALLED_ON_VALID_THREAD(bound_thread_checker_);
- auto it =
- std::find(task_observers_.begin(), task_observers_.end(), task_observer);
- DCHECK(it != task_observers_.end());
- task_observers_.erase(it);
+ backend_->RemoveTaskObserver(task_observer);
}
-void MessageLoop::SetAddQueueTimeToTasks(bool enable) {
- DCHECK_CALLED_ON_VALID_THREAD(bound_thread_checker_);
- underlying_task_runner_->SetAddQueueTimeToTasks(enable);
+bool MessageLoop::IsBoundToCurrentThread() const {
+ return backend_->IsBoundToCurrentThread();
}
bool MessageLoop::IsIdleForTesting() {
- // Have unprocessed tasks? (this reloads the work queue if necessary)
- if (sequenced_task_source_->HasTasks())
- return false;
-
- // Have unprocessed deferred tasks which can be processed at this run-level?
- if (pending_task_queue_.deferred_tasks().HasTasks() &&
- !RunLoop::IsNestedOnCurrentThread()) {
- return false;
- }
+ return backend_->IsIdleForTesting();
+}
- return true;
+MessageLoopBase* MessageLoop::GetMessageLoopBase() {
+ return backend_.get();
}
//------------------------------------------------------------------------------
@@ -303,16 +184,26 @@ std::unique_ptr<MessageLoop> MessageLoop::CreateUnbound(
return WrapUnique(new MessageLoop(type, std::move(pump_factory)));
}
+const Feature kMessageLoopUsesSequenceManager{"MessageLoopUsesSequenceManager",
+ FEATURE_DISABLED_BY_DEFAULT};
+
MessageLoop::MessageLoop(Type type, MessagePumpFactoryCallback pump_factory)
- : MessageLoopCurrent(this),
+ : MessageLoop(type,
+ std::move(pump_factory),
+ FeatureList::IsEnabled(kMessageLoopUsesSequenceManager)
+ ? BackendType::SEQUENCE_MANAGER
+ : BackendType::MESSAGE_LOOP_IMPL) {}
+
+MessageLoop::MessageLoop(Type type,
+ MessagePumpFactoryCallback pump_factory,
+ BackendType backend_type)
+ : pump_(nullptr),
+ backend_(backend_type == BackendType::MESSAGE_LOOP_IMPL
+ ? CreateMessageLoopImpl(type)
+ : CreateSequenceManager(type)),
+ default_task_queue_(CreateDefaultTaskQueue(backend_type)),
type_(type),
- pump_factory_(std::move(pump_factory)),
- message_loop_controller_(
- new Controller(this)), // Ownership transferred on the next line.
- underlying_task_runner_(MakeRefCounted<internal::MessageLoopTaskRunner>(
- WrapUnique(message_loop_controller_))),
- sequenced_task_source_(underlying_task_runner_.get()),
- task_runner_(underlying_task_runner_) {
+ pump_factory_(std::move(pump_factory)) {
// If type is TYPE_CUSTOM non-null pump_factory must be given.
DCHECK(type_ != TYPE_CUSTOM || !pump_factory_.is_null());
@@ -320,284 +211,80 @@ MessageLoop::MessageLoop(Type type, MessagePumpFactoryCallback pump_factory)
DETACH_FROM_THREAD(bound_thread_checker_);
}
+std::unique_ptr<MessageLoopBase> MessageLoop::CreateMessageLoopImpl(
+ MessageLoop::Type type) {
+ return std::make_unique<MessageLoopImpl>(type);
+}
+
+std::unique_ptr<MessageLoopBase> MessageLoop::CreateSequenceManager(
+ MessageLoop::Type type) {
+ std::unique_ptr<sequence_manager::internal::SequenceManagerImpl> manager =
+ sequence_manager::internal::SequenceManagerImpl::CreateUnboundWithPump(
+ type);
+ // std::move() for nacl, it doesn't properly handle returning unique_ptr
+ // for subtypes.
+ return std::move(manager);
+}
+
+scoped_refptr<sequence_manager::TaskQueue> MessageLoop::CreateDefaultTaskQueue(
+ BackendType backend_type) {
+ if (backend_type == BackendType::MESSAGE_LOOP_IMPL)
+ return nullptr;
+ sequence_manager::internal::SequenceManagerImpl* manager =
+ static_cast<sequence_manager::internal::SequenceManagerImpl*>(
+ backend_.get());
+ scoped_refptr<sequence_manager::TaskQueue> default_task_queue =
+ manager->CreateTaskQueueWithType<sequence_manager::TaskQueue>(
+ sequence_manager::TaskQueue::Spec("default_tq"));
+ manager->SetTaskRunner(default_task_queue->task_runner());
+ return default_task_queue;
+}
+
void MessageLoop::BindToCurrentThread() {
DCHECK_CALLED_ON_VALID_THREAD(bound_thread_checker_);
+ thread_id_ = PlatformThread::CurrentId();
DCHECK(!pump_);
- if (!pump_factory_.is_null())
- pump_ = std::move(pump_factory_).Run();
- else
- pump_ = CreateMessagePumpForType(type_);
+
+ std::unique_ptr<MessagePump> pump = CreateMessagePump();
+ pump_ = pump.get();
DCHECK(!MessageLoopCurrent::IsSet())
<< "should only have one message loop per thread";
- MessageLoopCurrent::BindToCurrentThreadInternal(this);
- underlying_task_runner_->BindToCurrentThread();
- message_loop_controller_->StartScheduling();
- SetThreadTaskRunnerHandle();
- thread_id_ = PlatformThread::CurrentId();
-
- scoped_set_sequence_local_storage_map_for_current_thread_ = std::make_unique<
- internal::ScopedSetSequenceLocalStorageMapForCurrentThread>(
- &sequence_local_storage_map_);
-
- RunLoop::RegisterDelegateForCurrentThread(this);
+ backend_->BindToCurrentThread(std::move(pump));
#if defined(OS_ANDROID)
// On Android, attach to the native loop when there is one.
if (type_ == TYPE_UI || type_ == TYPE_JAVA)
- static_cast<MessagePumpForUI*>(pump_.get())->Attach(this);
+ backend_->AttachToMessagePump();
#endif
}
-std::string MessageLoop::GetThreadName() const {
- DCHECK_NE(kInvalidThreadId, thread_id_)
- << "GetThreadName() must only be called after BindToCurrentThread()'s "
- << "side-effects have been synchronized with this thread.";
- return ThreadIdNameManager::GetInstance()->GetName(thread_id_);
-}
-
-void MessageLoop::SetTaskRunner(
- scoped_refptr<SingleThreadTaskRunner> task_runner) {
- DCHECK(task_runner);
- if (thread_id_ == kInvalidThreadId) {
- // ThreadTaskRunnerHandle will be set during BindToCurrentThread().
- task_runner_ = std::move(task_runner);
- } else {
- // Once MessageLoop is bound, |task_runner_| may only be altered on the
- // bound thread.
- DCHECK_CALLED_ON_VALID_THREAD(bound_thread_checker_);
- DCHECK(task_runner->BelongsToCurrentThread());
- task_runner_ = std::move(task_runner);
- SetThreadTaskRunnerHandle();
- }
-}
-
-void MessageLoop::Run(bool application_tasks_allowed) {
- DCHECK_CALLED_ON_VALID_THREAD(bound_thread_checker_);
- if (application_tasks_allowed && !task_execution_allowed_) {
- // Allow nested task execution as explicitly requested.
- DCHECK(RunLoop::IsNestedOnCurrentThread());
- task_execution_allowed_ = true;
- pump_->Run(this);
- task_execution_allowed_ = false;
+std::unique_ptr<MessagePump> MessageLoop::CreateMessagePump() {
+ if (!pump_factory_.is_null()) {
+ return std::move(pump_factory_).Run();
} else {
- pump_->Run(this);
- }
-}
-
-void MessageLoop::Quit() {
- DCHECK_CALLED_ON_VALID_THREAD(bound_thread_checker_);
- pump_->Quit();
-}
-
-void MessageLoop::EnsureWorkScheduled() {
- DCHECK_CALLED_ON_VALID_THREAD(bound_thread_checker_);
- if (sequenced_task_source_->HasTasks())
- pump_->ScheduleWork();
-}
-
-void MessageLoop::SetThreadTaskRunnerHandle() {
- DCHECK_CALLED_ON_VALID_THREAD(bound_thread_checker_);
- // Clear the previous thread task runner first, because only one can exist at
- // a time.
- thread_task_runner_handle_.reset();
- thread_task_runner_handle_.reset(new ThreadTaskRunnerHandle(task_runner_));
-}
-
-bool MessageLoop::ProcessNextDelayedNonNestableTask() {
- if (RunLoop::IsNestedOnCurrentThread())
- return false;
-
- while (pending_task_queue_.deferred_tasks().HasTasks()) {
- PendingTask pending_task = pending_task_queue_.deferred_tasks().Pop();
- if (!pending_task.task.IsCancelled()) {
- RunTask(&pending_task);
- return true;
- }
- }
-
- return false;
-}
-
-void MessageLoop::RunTask(PendingTask* pending_task) {
- DCHECK(task_execution_allowed_);
-
- // Execute the task and assume the worst: It is probably not reentrant.
- task_execution_allowed_ = false;
-
- TRACE_TASK_EXECUTION("MessageLoop::RunTask", *pending_task);
-
- for (TaskObserver* task_observer : task_observers_)
- task_observer->WillProcessTask(*pending_task);
- message_loop_controller_->task_annotator().RunTask("MessageLoop::PostTask",
- pending_task);
- for (TaskObserver* task_observer : task_observers_)
- task_observer->DidProcessTask(*pending_task);
-
- task_execution_allowed_ = true;
-}
-
-bool MessageLoop::DeferOrRunPendingTask(PendingTask pending_task) {
- if (pending_task.nestable == Nestable::kNestable ||
- !RunLoop::IsNestedOnCurrentThread()) {
- RunTask(&pending_task);
- // Show that we ran a task (Note: a new one might arrive as a
- // consequence!).
- return true;
- }
-
- // We couldn't run the task now because we're in a nested run loop
- // and the task isn't nestable.
- pending_task_queue_.deferred_tasks().Push(std::move(pending_task));
- return false;
-}
-
-void MessageLoop::DeletePendingTasks() {
- // Delete all currently pending tasks but not tasks potentially posted from
- // their destructors. See ~MessageLoop() for the full logic mitigating against
- // infite loops when clearing pending tasks. The ScopedClosureRunner below
- // will be bound to a task posted at the end of the queue. After it is posted,
- // tasks will be deleted one by one, when the bound ScopedClosureRunner is
- // deleted and sets |deleted_all_originally_pending|, we know we've deleted
- // all originally pending tasks.
- bool deleted_all_originally_pending = false;
- ScopedClosureRunner capture_deleted_all_originally_pending(BindOnce(
- [](bool* deleted_all_originally_pending) {
- *deleted_all_originally_pending = true;
- },
- Unretained(&deleted_all_originally_pending)));
- sequenced_task_source_->InjectTask(
- BindOnce([](ScopedClosureRunner) {},
- std::move(capture_deleted_all_originally_pending)));
-
- while (!deleted_all_originally_pending) {
- PendingTask pending_task = sequenced_task_source_->TakeTask();
-
- // New delayed tasks should be deleted after older ones.
- if (!pending_task.delayed_run_time.is_null())
- pending_task_queue_.delayed_tasks().Push(std::move(pending_task));
+ return CreateMessagePumpForType(type_);
}
-
- pending_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.
- pending_task_queue_.delayed_tasks().Clear();
-}
-
-void MessageLoop::ScheduleWork() {
- pump_->ScheduleWork();
}
-TimeTicks MessageLoop::CapAtOneDay(TimeTicks next_run_time) {
- return std::min(next_run_time, recent_time_ + TimeDelta::FromDays(1));
+void MessageLoop::SetTimerSlack(TimerSlack timer_slack) {
+ backend_->SetTimerSlack(timer_slack);
}
-bool MessageLoop::DoWork() {
- if (!task_execution_allowed_)
- return false;
-
- // Execute oldest task.
- while (sequenced_task_source_->HasTasks()) {
- PendingTask pending_task = sequenced_task_source_->TakeTask();
- if (pending_task.task.IsCancelled())
- continue;
-
- if (!pending_task.delayed_run_time.is_null()) {
- int sequence_num = pending_task.sequence_num;
- TimeTicks delayed_run_time = pending_task.delayed_run_time;
- pending_task_queue_.delayed_tasks().Push(std::move(pending_task));
- // If we changed the topmost task, then it is time to reschedule.
- if (pending_task_queue_.delayed_tasks().Peek().sequence_num ==
- sequence_num) {
- pump_->ScheduleDelayedWork(delayed_run_time);
- }
- } else if (DeferOrRunPendingTask(std::move(pending_task))) {
- return true;
- }
- }
-
- // Nothing happened.
- return false;
+std::string MessageLoop::GetThreadName() const {
+ return backend_->GetThreadName();
}
-bool MessageLoop::DoDelayedWork(TimeTicks* next_delayed_work_time) {
- if (!task_execution_allowed_ ||
- !pending_task_queue_.delayed_tasks().HasTasks()) {
- *next_delayed_work_time = TimeTicks();
- return false;
- }
-
- // When we "fall behind", there will be a lot of tasks in the delayed work
- // queue that are ready to run. To increase efficiency when we fall behind,
- // we will only call Time::Now() intermittently, and then process all tasks
- // that are ready to run before calling it again. As a result, the more we
- // 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 =
- pending_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_) {
- *next_delayed_work_time = CapAtOneDay(next_run_time);
- return false;
- }
- }
-
- PendingTask pending_task = pending_task_queue_.delayed_tasks().Pop();
-
- if (pending_task_queue_.delayed_tasks().HasTasks()) {
- *next_delayed_work_time = CapAtOneDay(
- pending_task_queue_.delayed_tasks().Peek().delayed_run_time);
- }
-
- return DeferOrRunPendingTask(std::move(pending_task));
+scoped_refptr<SingleThreadTaskRunner> MessageLoop::task_runner() const {
+ return backend_->GetTaskRunner();
}
-bool MessageLoop::DoIdleWork() {
- if (ProcessNextDelayedNonNestableTask())
- return true;
-
-#if defined(OS_WIN)
- bool need_high_res_timers = false;
-#endif
-
- // Do not report idle metrics if about to quit the loop and/or in a nested
- // loop where |!task_execution_allowed_|. In the former case, the loop isn't
- // going to sleep and in the latter case DoDelayedWork() will not actually do
- // the work this is prepping for.
- if (ShouldQuitWhenIdle()) {
- pump_->Quit();
- } else if (task_execution_allowed_) {
- // Only track idle metrics in MessageLoopForUI to avoid too much contention
- // logging the histogram (https://crbug.com/860801) -- there's typically
- // only one UI thread per process and, for practical purposes, restricting
- // the MessageLoop diagnostic metrics to it yields similar information.
- if (type_ == TYPE_UI)
- pending_task_queue_.ReportMetricsOnIdle();
-
-#if defined(OS_WIN)
- // On Windows we activate the high resolution timer so that the wait
- // _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.
- need_high_res_timers = pending_task_queue_.HasPendingHighResolutionTasks();
-#endif
- }
-
-#if defined(OS_WIN)
- if (in_high_res_mode_ != need_high_res_timers) {
- in_high_res_mode_ = need_high_res_timers;
- Time::ActivateHighResolutionTimer(in_high_res_mode_);
- }
-#endif
-
- // When we return we will do a kernel wait for more tasks.
- return false;
+void MessageLoop::SetTaskRunner(
+ scoped_refptr<SingleThreadTaskRunner> task_runner) {
+ DCHECK(task_runner);
+ backend_->SetTaskRunner(task_runner);
}
#if !defined(OS_NACL)
@@ -613,56 +300,32 @@ MessageLoopForUI::MessageLoopForUI(Type type) : MessageLoop(type) {
#endif
}
-// static
-MessageLoopCurrentForUI MessageLoopForUI::current() {
- return MessageLoopCurrentForUI::Get();
-}
-
-// static
-bool MessageLoopForUI::IsCurrent() {
- return MessageLoopCurrentForUI::IsSet();
-}
-
#if defined(OS_IOS)
void MessageLoopForUI::Attach() {
- static_cast<MessagePumpUIApplication*>(pump_.get())->Attach(this);
+ backend_->AttachToMessagePump();
}
#endif // defined(OS_IOS)
#if defined(OS_ANDROID)
void MessageLoopForUI::Abort() {
- static_cast<MessagePumpForUI*>(pump_.get())->Abort();
+ static_cast<MessagePumpForUI*>(pump_)->Abort();
}
bool MessageLoopForUI::IsAborted() {
- return static_cast<MessagePumpForUI*>(pump_.get())->IsAborted();
+ return static_cast<MessagePumpForUI*>(pump_)->IsAborted();
}
void MessageLoopForUI::QuitWhenIdle(base::OnceClosure callback) {
- static_cast<MessagePumpForUI*>(pump_.get())
- ->QuitWhenIdle(std::move(callback));
+ static_cast<MessagePumpForUI*>(pump_)->QuitWhenIdle(std::move(callback));
}
#endif // defined(OS_ANDROID)
#if defined(OS_WIN)
void MessageLoopForUI::EnableWmQuit() {
- static_cast<MessagePumpForUI*>(pump_.get())->EnableWmQuit();
+ static_cast<MessagePumpForUI*>(pump_)->EnableWmQuit();
}
#endif // defined(OS_WIN)
#endif // !defined(OS_NACL)
-//------------------------------------------------------------------------------
-// MessageLoopForIO
-
-// static
-MessageLoopCurrentForIO MessageLoopForIO::current() {
- return MessageLoopCurrentForIO::Get();
-}
-
-// static
-bool MessageLoopForIO::IsCurrent() {
- return MessageLoopCurrentForIO::IsSet();
-}
-
} // namespace base