| Index: base/message_loop/message_loop.cc
 | 
| diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
 | 
| index 8991ff3a86f4fd7cce39fd4f32c439aed6d7ede3..e078b1f5730af42f96c736ab5888c52608b0f045 100644
 | 
| --- a/base/message_loop/message_loop.cc
 | 
| +++ b/base/message_loop/message_loop.cc
 | 
| @@ -97,7 +97,11 @@ MessageLoop::~MessageLoop() {
 | 
|    // iOS just attaches to the loop, it doesn't Run it.
 | 
|    // TODO(stuartmorgan): Consider wiring up a Detach().
 | 
|  #if !defined(OS_IOS)
 | 
| -  DCHECK(!run_loop_);
 | 
| +  // 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_ && current() != this) ||
 | 
| +         !run_loop_client_->GetTopMostRunLoop());
 | 
|  #endif
 | 
|  
 | 
|  #if defined(OS_WIN)
 | 
| @@ -136,8 +140,6 @@ MessageLoop::~MessageLoop() {
 | 
|    // OK, now make it so that no one can find us.
 | 
|    if (current() == this)
 | 
|      GetTLSMessageLoop()->Set(nullptr);
 | 
| -
 | 
| -  RunLoop::ResetTLSState();
 | 
|  }
 | 
|  
 | 
|  // static
 | 
| @@ -216,20 +218,16 @@ void MessageLoop::RemoveDestructionObserver(
 | 
|  
 | 
|  void MessageLoop::QuitWhenIdle() {
 | 
|    DCHECK_EQ(this, current());
 | 
| -  if (run_loop_) {
 | 
| -    run_loop_->QuitWhenIdle();
 | 
| -  } else {
 | 
| -    NOTREACHED() << "Must be inside Run to call QuitWhenIdle";
 | 
| -  }
 | 
| +  DCHECK(run_loop_client_->GetTopMostRunLoop())
 | 
| +      << "Must be inside Run to call QuitWhenIdle";
 | 
| +  run_loop_client_->GetTopMostRunLoop()->QuitWhenIdle();
 | 
|  }
 | 
|  
 | 
|  void MessageLoop::QuitNow() {
 | 
|    DCHECK_EQ(this, current());
 | 
| -  if (run_loop_) {
 | 
| -    pump_->Quit();
 | 
| -  } else {
 | 
| -    NOTREACHED() << "Must be inside Run to call Quit";
 | 
| -  }
 | 
| +  DCHECK(run_loop_client_->GetTopMostRunLoop())
 | 
| +      << "Must be inside Run to call Quit";
 | 
| +  pump_->Quit();
 | 
|  }
 | 
|  
 | 
|  bool MessageLoop::IsType(Type type) const {
 | 
| @@ -247,7 +245,7 @@ Closure MessageLoop::QuitWhenIdleClosure() {
 | 
|  
 | 
|  void MessageLoop::SetNestableTasksAllowed(bool allowed) {
 | 
|    if (allowed) {
 | 
| -    CHECK(base::RunLoop::IsNestingAllowedOnCurrentThread());
 | 
| +    CHECK(RunLoop::IsNestingAllowedOnCurrentThread());
 | 
|  
 | 
|      // Kick the native pump just in case we enter a OS-driven nested message
 | 
|      // loop.
 | 
| @@ -302,7 +300,6 @@ MessageLoop::MessageLoop(Type type, MessagePumpFactoryCallback pump_factory)
 | 
|  #endif
 | 
|        nestable_tasks_allowed_(true),
 | 
|        pump_factory_(std::move(pump_factory)),
 | 
| -      run_loop_(nullptr),
 | 
|        current_pending_task_(nullptr),
 | 
|        incoming_task_queue_(new internal::IncomingTaskQueue(this)),
 | 
|        unbound_task_runner_(
 | 
| @@ -328,6 +325,8 @@ void MessageLoop::BindToCurrentThread() {
 | 
|    unbound_task_runner_ = nullptr;
 | 
|    SetThreadTaskRunnerHandle();
 | 
|    thread_id_ = PlatformThread::CurrentId();
 | 
| +
 | 
| +  run_loop_client_ = RunLoop::RegisterDelegateForCurrentThread(this);
 | 
|  }
 | 
|  
 | 
|  std::string MessageLoop::GetThreadName() const {
 | 
| @@ -354,6 +353,16 @@ void MessageLoop::ClearTaskRunnerForTesting() {
 | 
|    thread_task_runner_handle_.reset();
 | 
|  }
 | 
|  
 | 
| +void MessageLoop::Run() {
 | 
| +  DCHECK_EQ(this, current());
 | 
| +  pump_->Run(this);
 | 
| +}
 | 
| +
 | 
| +void MessageLoop::Quit() {
 | 
| +  DCHECK_EQ(this, current());
 | 
| +  QuitNow();
 | 
| +}
 | 
| +
 | 
|  void MessageLoop::SetThreadTaskRunnerHandle() {
 | 
|    DCHECK_EQ(this, current());
 | 
|    // Clear the previous thread task runner first, because only one can exist at
 | 
| @@ -362,14 +371,8 @@ void MessageLoop::SetThreadTaskRunnerHandle() {
 | 
|    thread_task_runner_handle_.reset(new ThreadTaskRunnerHandle(task_runner_));
 | 
|  }
 | 
|  
 | 
| -void MessageLoop::RunHandler() {
 | 
| -  DCHECK_EQ(this, current());
 | 
| -  DCHECK(run_loop_);
 | 
| -  pump_->Run(this);
 | 
| -}
 | 
| -
 | 
|  bool MessageLoop::ProcessNextDelayedNonNestableTask() {
 | 
| -  if (is_nested_)
 | 
| +  if (run_loop_client_->IsNested())
 | 
|      return false;
 | 
|  
 | 
|    if (deferred_non_nestable_work_queue_.empty())
 | 
| @@ -411,7 +414,7 @@ void MessageLoop::RunTask(PendingTask* pending_task) {
 | 
|  }
 | 
|  
 | 
|  bool MessageLoop::DeferOrRunPendingTask(PendingTask pending_task) {
 | 
| -  if (pending_task.nestable || !is_nested_) {
 | 
| +  if (pending_task.nestable || !run_loop_client_->IsNested()) {
 | 
|      RunTask(&pending_task);
 | 
|      // Show that we ran a task (Note: a new one might arrive as a
 | 
|      // consequence!).
 | 
| @@ -546,7 +549,7 @@ bool MessageLoop::DoIdleWork() {
 | 
|    if (ProcessNextDelayedNonNestableTask())
 | 
|      return true;
 | 
|  
 | 
| -  if (run_loop_->quit_when_idle_received_)
 | 
| +  if (run_loop_client_->GetTopMostRunLoop()->quit_when_idle_received_)
 | 
|      pump_->Quit();
 | 
|  
 | 
|    // When we return we will do a kernel wait for more tasks.
 | 
| 
 |