base: Remove MessageLoopProxy

BUG=465354

Review URL: https://codereview.chromium.org/1180153002

Cr-Commit-Position: refs/heads/master@{#335277}


CrOS-Libchrome-Original-Commit: b1f02993d46e10a58aeda7acc299350381046fa6
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index 4222c77..0eb24cf 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -170,7 +170,7 @@
   // Tell the incoming queue that we are dying.
   incoming_task_queue_->WillDestroyCurrentMessageLoop();
   incoming_task_queue_ = NULL;
-  message_loop_proxy_ = NULL;
+  task_runner_ = NULL;
 
   // OK, now make it so that no one can find us.
   lazy_tls_ptr.Pointer()->Set(NULL);
@@ -257,27 +257,27 @@
 void MessageLoop::PostTask(
     const tracked_objects::Location& from_here,
     const Closure& task) {
-  message_loop_proxy_->PostTask(from_here, task);
+  task_runner_->PostTask(from_here, task);
 }
 
 void MessageLoop::PostDelayedTask(
     const tracked_objects::Location& from_here,
     const Closure& task,
     TimeDelta delay) {
-  message_loop_proxy_->PostDelayedTask(from_here, task, delay);
+  task_runner_->PostDelayedTask(from_here, task, delay);
 }
 
 void MessageLoop::PostNonNestableTask(
     const tracked_objects::Location& from_here,
     const Closure& task) {
-  message_loop_proxy_->PostNonNestableTask(from_here, task);
+  task_runner_->PostNonNestableTask(from_here, task);
 }
 
 void MessageLoop::PostNonNestableDelayedTask(
     const tracked_objects::Location& from_here,
     const Closure& task,
     TimeDelta delay) {
-  message_loop_proxy_->PostNonNestableDelayedTask(from_here, task, delay);
+  task_runner_->PostNonNestableDelayedTask(from_here, task, delay);
 }
 
 void MessageLoop::Run() {
@@ -386,8 +386,7 @@
       message_histogram_(NULL),
       run_loop_(NULL),
       incoming_task_queue_(new internal::IncomingTaskQueue(this)),
-      message_loop_proxy_(
-          new internal::MessageLoopProxyImpl(incoming_task_queue_)) {
+      task_runner_(new internal::MessageLoopTaskRunner(incoming_task_queue_)) {
   // If type is TYPE_CUSTOM non-null pump_factory must be given.
   DCHECK_EQ(type_ == TYPE_CUSTOM, !pump_factory_.is_null());
 }
@@ -403,9 +402,8 @@
   lazy_tls_ptr.Pointer()->Set(this);
 
   incoming_task_queue_->StartScheduling();
-  message_loop_proxy_->BindToCurrentThread();
-  thread_task_runner_handle_.reset(
-      new ThreadTaskRunnerHandle(message_loop_proxy_));
+  task_runner_->BindToCurrentThread();
+  thread_task_runner_handle_.reset(new ThreadTaskRunnerHandle(task_runner_));
 }
 
 void MessageLoop::RunHandler() {
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index f2f89d0..9c635ee 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -16,8 +16,7 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_ptr.h"
 #include "base/message_loop/incoming_task_queue.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "base/message_loop/message_loop_proxy_impl.h"
+#include "base/message_loop/message_loop_task_runner.h"
 #include "base/message_loop/message_pump.h"
 #include "base/message_loop/timer_slack.h"
 #include "base/observer_list.h"
@@ -296,19 +295,10 @@
   }
   const std::string& thread_name() const { return thread_name_; }
 
-  // Gets the message loop proxy associated with this message loop.
-  //
-  // NOTE: Deprecated; prefer task_runner() and the TaskRunner interfaces
-  scoped_refptr<MessageLoopProxy> message_loop_proxy() {
-    return message_loop_proxy_;
-  }
-
   // Gets the TaskRunner associated with this message loop.
   // TODO(skyostil): Change this to return a const reference to a refptr
   // once the internal type matches what is being returned (crbug.com/465354).
-  scoped_refptr<SingleThreadTaskRunner> task_runner() {
-    return message_loop_proxy_;
-  }
+  scoped_refptr<SingleThreadTaskRunner> task_runner() { return task_runner_; }
 
   // Enables or disables the recursive task processing. This happens in the case
   // of recursive message loops. Some unwanted message loop may occurs when
@@ -531,8 +521,8 @@
 
   scoped_refptr<internal::IncomingTaskQueue> incoming_task_queue_;
 
-  // The message loop proxy associated with this message loop.
-  scoped_refptr<internal::MessageLoopProxyImpl> message_loop_proxy_;
+  // The task runner associated with this message loop.
+  scoped_refptr<internal::MessageLoopTaskRunner> task_runner_;
   scoped_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_;
 
   template <class T, class R> friend class base::subtle::DeleteHelperInternal;
diff --git a/base/message_loop/message_loop_proxy.cc b/base/message_loop/message_loop_proxy.cc
deleted file mode 100644
index e5f0142..0000000
--- a/base/message_loop/message_loop_proxy.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2012 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_proxy.h"
-
-#include "base/bind.h"
-
-namespace base {
-
-MessageLoopProxy::MessageLoopProxy() {
-}
-
-MessageLoopProxy::~MessageLoopProxy() {
-}
-
-}  // namespace base
diff --git a/base/message_loop/message_loop_proxy.h b/base/message_loop/message_loop_proxy.h
deleted file mode 100644
index d5ecc04..0000000
--- a/base/message_loop/message_loop_proxy.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_H_
-#define BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_H_
-
-#include "base/base_export.h"
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
-
-// MessageLoopProxy is deprecated. Code should prefer to depend on TaskRunner
-// (or the various specializations) for passing task runners around, and should
-// use ThreadTaskRunnerHandle::Get() to get the thread's associated task runner.
-//
-// See http://crbug.com/391045 for more details.
-// Example for these changes:
-//
-// base::MessageLoopProxy::current() -> base::ThreadTaskRunnerHandle::Get()
-// scoped_refptr<base::MessageLoopProxy> ->
-//     scoped_refptr<base::SingleThreadTaskRunner>
-// base::MessageLoopProxy -> base::SingleThreadTaskRunner
-
-namespace base {
-
-// This class provides a thread-safe refcounted interface to the Post* methods
-// of a message loop. This class can outlive the target message loop.
-// MessageLoopProxy objects are constructed automatically for all MessageLoops.
-// So, to access them, you can use any of the following:
-//   Thread::message_loop_proxy()
-//   MessageLoop::current()->message_loop_proxy()
-//   MessageLoopProxy::current()
-//
-// TODO(akalin): Now that we have the *TaskRunner interfaces, we can
-// merge this with MessageLoopProxyImpl.
-class BASE_EXPORT MessageLoopProxy : public SingleThreadTaskRunner {
- public:
-  // Gets the MessageLoopProxy for the current message loop, creating one if
-  // needed.
-  static scoped_refptr<MessageLoopProxy> current();
-
- protected:
-  MessageLoopProxy();
-  ~MessageLoopProxy() override;
-};
-
-}  // namespace base
-
-#endif  // BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_H_
diff --git a/base/message_loop/message_loop_proxy_impl_unittest.cc b/base/message_loop/message_loop_proxy_impl_unittest.cc
deleted file mode 100644
index fa25371..0000000
--- a/base/message_loop/message_loop_proxy_impl_unittest.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2012 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_proxy_impl.h"
-
-#include "base/bind.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "base/threading/thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/platform_test.h"
-
-namespace base {
-
-class MessageLoopProxyImplTest : public testing::Test {
- public:
-  void Release() const {
-    AssertOnIOThread();
-    Quit();
-  }
-
-  void Quit() const {
-    loop_.PostTask(FROM_HERE, MessageLoop::QuitWhenIdleClosure());
-  }
-
-  void AssertOnIOThread() const {
-    ASSERT_TRUE(io_thread_->message_loop_proxy()->BelongsToCurrentThread());
-    ASSERT_EQ(io_thread_->message_loop_proxy(),
-              MessageLoopProxy::current());
-  }
-
-  void AssertOnFileThread() const {
-    ASSERT_TRUE(file_thread_->message_loop_proxy()->BelongsToCurrentThread());
-    ASSERT_EQ(file_thread_->message_loop_proxy(),
-              MessageLoopProxy::current());
-  }
-
- protected:
-  void SetUp() override {
-    io_thread_.reset(new Thread("MessageLoopProxyImplTest_IO"));
-    file_thread_.reset(new Thread("MessageLoopProxyImplTest_File"));
-    io_thread_->Start();
-    file_thread_->Start();
-  }
-
-  void TearDown() override {
-    io_thread_->Stop();
-    file_thread_->Stop();
-  }
-
-  static void BasicFunction(MessageLoopProxyImplTest* test) {
-    test->AssertOnFileThread();
-    test->Quit();
-  }
-
-  static void AssertNotRun() {
-    FAIL() << "Callback Should not get executed.";
-  }
-
-  class DeletedOnFile {
-   public:
-    explicit DeletedOnFile(MessageLoopProxyImplTest* test) : test_(test) {}
-
-    ~DeletedOnFile() {
-      test_->AssertOnFileThread();
-      test_->Quit();
-    }
-
-   private:
-    MessageLoopProxyImplTest* test_;
-  };
-
-  scoped_ptr<Thread> io_thread_;
-  scoped_ptr<Thread> file_thread_;
-
- private:
-  mutable MessageLoop loop_;
-};
-
-TEST_F(MessageLoopProxyImplTest, Release) {
-  EXPECT_TRUE(io_thread_->message_loop_proxy()->ReleaseSoon(FROM_HERE, this));
-  MessageLoop::current()->Run();
-}
-
-TEST_F(MessageLoopProxyImplTest, Delete) {
-  DeletedOnFile* deleted_on_file = new DeletedOnFile(this);
-  EXPECT_TRUE(file_thread_->message_loop_proxy()->DeleteSoon(
-      FROM_HERE, deleted_on_file));
-  MessageLoop::current()->Run();
-}
-
-TEST_F(MessageLoopProxyImplTest, PostTask) {
-  EXPECT_TRUE(file_thread_->message_loop_proxy()->PostTask(
-      FROM_HERE, Bind(&MessageLoopProxyImplTest::BasicFunction,
-                            Unretained(this))));
-  MessageLoop::current()->Run();
-}
-
-TEST_F(MessageLoopProxyImplTest, PostTaskAfterThreadExits) {
-  scoped_ptr<Thread> test_thread(
-      new Thread("MessageLoopProxyImplTest_Dummy"));
-  test_thread->Start();
-  scoped_refptr<MessageLoopProxy> message_loop_proxy =
-      test_thread->message_loop_proxy();
-  test_thread->Stop();
-
-  bool ret = message_loop_proxy->PostTask(
-      FROM_HERE,
-      Bind(&MessageLoopProxyImplTest::AssertNotRun));
-  EXPECT_FALSE(ret);
-}
-
-TEST_F(MessageLoopProxyImplTest, PostTaskAfterThreadIsDeleted) {
-  scoped_refptr<MessageLoopProxy> message_loop_proxy;
-  {
-    scoped_ptr<Thread> test_thread(
-        new Thread("MessageLoopProxyImplTest_Dummy"));
-    test_thread->Start();
-    message_loop_proxy = test_thread->message_loop_proxy();
-  }
-  bool ret = message_loop_proxy->PostTask(
-      FROM_HERE,
-      Bind(&MessageLoopProxyImplTest::AssertNotRun));
-  EXPECT_FALSE(ret);
-}
-
-}  // namespace base
diff --git a/base/message_loop/message_loop_proxy_unittest.cc b/base/message_loop/message_loop_proxy_unittest.cc
deleted file mode 100644
index 0b0d9f8..0000000
--- a/base/message_loop/message_loop_proxy_unittest.cc
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright (c) 2012 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_proxy.h"
-
-#include "base/atomic_sequence_num.h"
-#include "base/bind.h"
-#include "base/debug/leak_annotations.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace base {
-
-namespace {
-
-class MessageLoopProxyTest : public testing::Test {
- public:
-  MessageLoopProxyTest()
-      : current_loop_(new MessageLoop()),
-        task_thread_("task_thread"),
-        thread_sync_(true, false) {
-  }
-
-  void DeleteCurrentMessageLoop() {
-    current_loop_.reset();
-  }
-
- protected:
-  void SetUp() override {
-    // Use SetUp() instead of the constructor to avoid posting a task to a
-    // partialy constructed object.
-    task_thread_.Start();
-
-    // Allow us to pause the |task_thread_|'s MessageLoop.
-    task_thread_.message_loop()->PostTask(
-        FROM_HERE,
-        Bind(&MessageLoopProxyTest::BlockTaskThreadHelper, Unretained(this)));
-  }
-
-  void TearDown() override {
-    // Make sure the |task_thread_| is not blocked, and stop the thread
-    // fully before destuction because its tasks may still depend on the
-    // |thread_sync_| event.
-    thread_sync_.Signal();
-    task_thread_.Stop();
-    DeleteCurrentMessageLoop();
-  }
-
-  // Make LoopRecorder threadsafe so that there is defined behavior even if a
-  // threading mistake sneaks into the PostTaskAndReplyRelay implementation.
-  class LoopRecorder : public RefCountedThreadSafe<LoopRecorder> {
-   public:
-    LoopRecorder(MessageLoop** run_on, MessageLoop** deleted_on,
-                 int* destruct_order)
-        : run_on_(run_on),
-          deleted_on_(deleted_on),
-          destruct_order_(destruct_order) {
-    }
-
-    void RecordRun() {
-      *run_on_ = MessageLoop::current();
-    }
-
-   private:
-    friend class RefCountedThreadSafe<LoopRecorder>;
-    ~LoopRecorder() {
-      *deleted_on_ = MessageLoop::current();
-      *destruct_order_ = g_order.GetNext();
-    }
-
-    MessageLoop** run_on_;
-    MessageLoop** deleted_on_;
-    int* destruct_order_;
-  };
-
-  static void RecordLoop(scoped_refptr<LoopRecorder> recorder) {
-    recorder->RecordRun();
-  }
-
-  static void RecordLoopAndQuit(scoped_refptr<LoopRecorder> recorder) {
-    recorder->RecordRun();
-    MessageLoop::current()->QuitWhenIdle();
-  }
-
-  void UnblockTaskThread() {
-    thread_sync_.Signal();
-  }
-
-  void BlockTaskThreadHelper() {
-    thread_sync_.Wait();
-  }
-
-  static StaticAtomicSequenceNumber g_order;
-
-  scoped_ptr<MessageLoop> current_loop_;
-  Thread task_thread_;
-
- private:
-  base::WaitableEvent thread_sync_;
-};
-
-StaticAtomicSequenceNumber MessageLoopProxyTest::g_order;
-
-TEST_F(MessageLoopProxyTest, PostTaskAndReply_Basic) {
-  MessageLoop* task_run_on = NULL;
-  MessageLoop* task_deleted_on = NULL;
-  int task_delete_order = -1;
-  MessageLoop* reply_run_on = NULL;
-  MessageLoop* reply_deleted_on = NULL;
-  int reply_delete_order = -1;
-
-  scoped_refptr<LoopRecorder> task_recoder =
-      new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
-  scoped_refptr<LoopRecorder> reply_recoder =
-      new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);
-
-  ASSERT_TRUE(task_thread_.message_loop_proxy()->PostTaskAndReply(
-      FROM_HERE,
-      Bind(&RecordLoop, task_recoder),
-      Bind(&RecordLoopAndQuit, reply_recoder)));
-
-  // Die if base::Bind doesn't retain a reference to the recorders.
-  task_recoder = NULL;
-  reply_recoder = NULL;
-  ASSERT_FALSE(task_deleted_on);
-  ASSERT_FALSE(reply_deleted_on);
-
-  UnblockTaskThread();
-  current_loop_->Run();
-
-  EXPECT_EQ(task_thread_.message_loop(), task_run_on);
-  EXPECT_EQ(current_loop_.get(), task_deleted_on);
-  EXPECT_EQ(current_loop_.get(), reply_run_on);
-  EXPECT_EQ(current_loop_.get(), reply_deleted_on);
-  EXPECT_LT(task_delete_order, reply_delete_order);
-}
-
-TEST_F(MessageLoopProxyTest, PostTaskAndReplyOnDeletedThreadDoesNotLeak) {
-  MessageLoop* task_run_on = NULL;
-  MessageLoop* task_deleted_on = NULL;
-  int task_delete_order = -1;
-  MessageLoop* reply_run_on = NULL;
-  MessageLoop* reply_deleted_on = NULL;
-  int reply_delete_order = -1;
-
-  scoped_refptr<LoopRecorder> task_recoder =
-      new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
-  scoped_refptr<LoopRecorder> reply_recoder =
-      new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);
-
-  // Grab a MessageLoopProxy to a dead MessageLoop.
-  scoped_refptr<MessageLoopProxy> task_loop_proxy =
-      task_thread_.message_loop_proxy();
-  UnblockTaskThread();
-  task_thread_.Stop();
-
-  ASSERT_FALSE(task_loop_proxy->PostTaskAndReply(
-      FROM_HERE,
-      Bind(&RecordLoop, task_recoder),
-      Bind(&RecordLoopAndQuit, reply_recoder)));
-
-  // The relay should have properly deleted its resources leaving us as the only
-  // reference.
-  EXPECT_EQ(task_delete_order, reply_delete_order);
-  ASSERT_TRUE(task_recoder->HasOneRef());
-  ASSERT_TRUE(reply_recoder->HasOneRef());
-
-  // Nothing should have run though.
-  EXPECT_FALSE(task_run_on);
-  EXPECT_FALSE(reply_run_on);
-}
-
-TEST_F(MessageLoopProxyTest, PostTaskAndReply_SameLoop) {
-  MessageLoop* task_run_on = NULL;
-  MessageLoop* task_deleted_on = NULL;
-  int task_delete_order = -1;
-  MessageLoop* reply_run_on = NULL;
-  MessageLoop* reply_deleted_on = NULL;
-  int reply_delete_order = -1;
-
-  scoped_refptr<LoopRecorder> task_recoder =
-      new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
-  scoped_refptr<LoopRecorder> reply_recoder =
-      new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);
-
-  // Enqueue the relay.
-  ASSERT_TRUE(current_loop_->message_loop_proxy()->PostTaskAndReply(
-      FROM_HERE,
-      Bind(&RecordLoop, task_recoder),
-      Bind(&RecordLoopAndQuit, reply_recoder)));
-
-  // Die if base::Bind doesn't retain a reference to the recorders.
-  task_recoder = NULL;
-  reply_recoder = NULL;
-  ASSERT_FALSE(task_deleted_on);
-  ASSERT_FALSE(reply_deleted_on);
-
-  current_loop_->Run();
-
-  EXPECT_EQ(current_loop_.get(), task_run_on);
-  EXPECT_EQ(current_loop_.get(), task_deleted_on);
-  EXPECT_EQ(current_loop_.get(), reply_run_on);
-  EXPECT_EQ(current_loop_.get(), reply_deleted_on);
-  EXPECT_LT(task_delete_order, reply_delete_order);
-}
-
-TEST_F(MessageLoopProxyTest, PostTaskAndReply_DeadReplyLoopDoesNotDelete) {
-  // Annotate the scope as having memory leaks to suppress heapchecker reports.
-  ANNOTATE_SCOPED_MEMORY_LEAK;
-  MessageLoop* task_run_on = NULL;
-  MessageLoop* task_deleted_on = NULL;
-  int task_delete_order = -1;
-  MessageLoop* reply_run_on = NULL;
-  MessageLoop* reply_deleted_on = NULL;
-  int reply_delete_order = -1;
-
-  scoped_refptr<LoopRecorder> task_recoder =
-      new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
-  scoped_refptr<LoopRecorder> reply_recoder =
-      new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);
-
-  // Enqueue the relay.
-  task_thread_.message_loop_proxy()->PostTaskAndReply(
-      FROM_HERE,
-      Bind(&RecordLoop, task_recoder),
-      Bind(&RecordLoopAndQuit, reply_recoder));
-
-  // Die if base::Bind doesn't retain a reference to the recorders.
-  task_recoder = NULL;
-  reply_recoder = NULL;
-  ASSERT_FALSE(task_deleted_on);
-  ASSERT_FALSE(reply_deleted_on);
-
-  UnblockTaskThread();
-
-  // Mercilessly whack the current loop before |reply| gets to run.
-  current_loop_.reset();
-
-  // This should ensure the relay has been run.  We need to record the
-  // MessageLoop pointer before stopping the thread because Thread::Stop() will
-  // NULL out its own pointer.
-  MessageLoop* task_loop = task_thread_.message_loop();
-  task_thread_.Stop();
-
-  EXPECT_EQ(task_loop, task_run_on);
-  ASSERT_FALSE(task_deleted_on);
-  EXPECT_FALSE(reply_run_on);
-  ASSERT_FALSE(reply_deleted_on);
-  EXPECT_EQ(task_delete_order, reply_delete_order);
-
-  // The PostTaskAndReplyRelay is leaked here.  Even if we had a reference to
-  // it, we cannot just delete it because PostTaskAndReplyRelay's destructor
-  // checks that MessageLoop::current() is the the same as when the
-  // PostTaskAndReplyRelay object was constructed.  However, this loop must have
-  // aleady been deleted in order to perform this test.  See
-  // http://crbug.com/86301.
-}
-
-}  // namespace
-
-}  // namespace base
diff --git a/base/message_loop/message_loop_proxy_impl.cc b/base/message_loop/message_loop_task_runner.cc
similarity index 62%
rename from base/message_loop/message_loop_proxy_impl.cc
rename to base/message_loop/message_loop_task_runner.cc
index 580620d..c9b5ffe 100644
--- a/base/message_loop/message_loop_proxy_impl.cc
+++ b/base/message_loop/message_loop_task_runner.cc
@@ -2,29 +2,27 @@
 // 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_proxy_impl.h"
+#include "base/message_loop/message_loop_task_runner.h"
 
 #include "base/location.h"
 #include "base/logging.h"
 #include "base/message_loop/incoming_task_queue.h"
-#include "base/message_loop/message_loop.h"
 
 namespace base {
 namespace internal {
 
-MessageLoopProxyImpl::MessageLoopProxyImpl(
+MessageLoopTaskRunner::MessageLoopTaskRunner(
     scoped_refptr<IncomingTaskQueue> incoming_queue)
-    : incoming_queue_(incoming_queue),
-      valid_thread_id_(kInvalidThreadId) {
+    : incoming_queue_(incoming_queue), valid_thread_id_(kInvalidThreadId) {
 }
 
-void MessageLoopProxyImpl::BindToCurrentThread() {
+void MessageLoopTaskRunner::BindToCurrentThread() {
   AutoLock lock(valid_thread_id_lock_);
   DCHECK_EQ(kInvalidThreadId, valid_thread_id_);
   valid_thread_id_ = PlatformThread::CurrentId();
 }
 
-bool MessageLoopProxyImpl::PostDelayedTask(
+bool MessageLoopTaskRunner::PostDelayedTask(
     const tracked_objects::Location& from_here,
     const base::Closure& task,
     base::TimeDelta delay) {
@@ -32,7 +30,7 @@
   return incoming_queue_->AddToIncomingQueue(from_here, task, delay, true);
 }
 
-bool MessageLoopProxyImpl::PostNonNestableDelayedTask(
+bool MessageLoopTaskRunner::PostNonNestableDelayedTask(
     const tracked_objects::Location& from_here,
     const base::Closure& task,
     base::TimeDelta delay) {
@@ -40,22 +38,14 @@
   return incoming_queue_->AddToIncomingQueue(from_here, task, delay, false);
 }
 
-bool MessageLoopProxyImpl::RunsTasksOnCurrentThread() const {
+bool MessageLoopTaskRunner::RunsTasksOnCurrentThread() const {
   AutoLock lock(valid_thread_id_lock_);
   return valid_thread_id_ == PlatformThread::CurrentId();
 }
 
-MessageLoopProxyImpl::~MessageLoopProxyImpl() {
+MessageLoopTaskRunner::~MessageLoopTaskRunner() {
 }
 
 }  // namespace internal
 
-scoped_refptr<MessageLoopProxy>
-MessageLoopProxy::current() {
-  MessageLoop* cur_loop = MessageLoop::current();
-  if (!cur_loop)
-    return NULL;
-  return cur_loop->message_loop_proxy();
-}
-
 }  // namespace base
diff --git a/base/message_loop/message_loop_proxy_impl.h b/base/message_loop/message_loop_task_runner.h
similarity index 60%
rename from base/message_loop/message_loop_proxy_impl.h
rename to base/message_loop/message_loop_task_runner.h
index fa611c2..dc2947d 100644
--- a/base/message_loop/message_loop_proxy_impl.h
+++ b/base/message_loop/message_loop_task_runner.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_IMPL_H_
-#define BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_IMPL_H_
+#ifndef BASE_MESSAGE_LOOP_MESSAGE_LOOP_TASK_RUNNER_H_
+#define BASE_MESSAGE_LOOP_MESSAGE_LOOP_TASK_RUNNER_H_
 
 #include "base/base_export.h"
 #include "base/memory/ref_counted.h"
-#include "base/message_loop/message_loop_proxy.h"
 #include "base/pending_task.h"
+#include "base/single_thread_task_runner.h"
 #include "base/synchronization/lock.h"
 #include "base/threading/platform_thread.h"
 
@@ -17,18 +17,18 @@
 
 class IncomingTaskQueue;
 
-// A stock implementation of MessageLoopProxy that is created and managed by a
-// MessageLoop. For now a MessageLoopProxyImpl can only be created as part of a
-// MessageLoop.
-class BASE_EXPORT MessageLoopProxyImpl : public MessageLoopProxy {
+// A stock implementation of SingleThreadTaskRunner that is created and managed
+// by a MessageLoop. For now a MessageLoopTaskRunner can only be created as
+// part of a MessageLoop.
+class BASE_EXPORT MessageLoopTaskRunner : public SingleThreadTaskRunner {
  public:
-  explicit MessageLoopProxyImpl(
+  explicit MessageLoopTaskRunner(
       scoped_refptr<IncomingTaskQueue> incoming_queue);
 
-  // Initialize this message loop proxy on the current thread.
+  // Initialize this message loop task runner on the current thread.
   void BindToCurrentThread();
 
-  // MessageLoopProxy implementation
+  // SingleThreadTaskRunner implementation
   bool PostDelayedTask(const tracked_objects::Location& from_here,
                        const base::Closure& task,
                        base::TimeDelta delay) override;
@@ -38,10 +38,10 @@
   bool RunsTasksOnCurrentThread() const override;
 
  private:
-  friend class RefCountedThreadSafe<MessageLoopProxyImpl>;
-  ~MessageLoopProxyImpl() override;
+  friend class RefCountedThreadSafe<MessageLoopTaskRunner>;
+  ~MessageLoopTaskRunner() override;
 
-  // THe incoming queue receiving all posted tasks.
+  // The incoming queue receiving all posted tasks.
   scoped_refptr<IncomingTaskQueue> incoming_queue_;
 
   // ID of the thread |this| was created on.  Could be accessed on multiple
@@ -49,10 +49,10 @@
   PlatformThreadId valid_thread_id_;
   mutable Lock valid_thread_id_lock_;
 
-  DISALLOW_COPY_AND_ASSIGN(MessageLoopProxyImpl);
+  DISALLOW_COPY_AND_ASSIGN(MessageLoopTaskRunner);
 };
 
 }  // namespace internal
 }  // namespace base
 
-#endif  // BASE_MESSAGE_LOOP_MESSAGE_LOOP_PROXY_IMPL_H_
+#endif  // BASE_MESSAGE_LOOP_MESSAGE_LOOP_TASK_RUNNER_H_
diff --git a/base/message_loop/message_loop_task_runner_unittest.cc b/base/message_loop/message_loop_task_runner_unittest.cc
new file mode 100644
index 0000000..caf88af
--- /dev/null
+++ b/base/message_loop/message_loop_task_runner_unittest.cc
@@ -0,0 +1,358 @@
+// Copyright (c) 2012 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_task_runner.h"
+
+#include "base/atomic_sequence_num.h"
+#include "base/bind.h"
+#include "base/debug/leak_annotations.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
+#include "base/message_loop/message_loop_task_runner.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/threading/thread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+
+namespace base {
+
+class MessageLoopTaskRunnerTest : public testing::Test {
+ public:
+  MessageLoopTaskRunnerTest()
+      : current_loop_(new MessageLoop()),
+        task_thread_("task_thread"),
+        thread_sync_(true, false) {}
+
+  void DeleteCurrentMessageLoop() { current_loop_.reset(); }
+
+ protected:
+  void SetUp() override {
+    // Use SetUp() instead of the constructor to avoid posting a task to a
+    // partialy constructed object.
+    task_thread_.Start();
+
+    // Allow us to pause the |task_thread_|'s MessageLoop.
+    task_thread_.message_loop()->PostTask(
+        FROM_HERE, Bind(&MessageLoopTaskRunnerTest::BlockTaskThreadHelper,
+                        Unretained(this)));
+  }
+
+  void TearDown() override {
+    // Make sure the |task_thread_| is not blocked, and stop the thread
+    // fully before destuction because its tasks may still depend on the
+    // |thread_sync_| event.
+    thread_sync_.Signal();
+    task_thread_.Stop();
+    DeleteCurrentMessageLoop();
+  }
+
+  // Make LoopRecorder threadsafe so that there is defined behavior even if a
+  // threading mistake sneaks into the PostTaskAndReplyRelay implementation.
+  class LoopRecorder : public RefCountedThreadSafe<LoopRecorder> {
+   public:
+    LoopRecorder(MessageLoop** run_on,
+                 MessageLoop** deleted_on,
+                 int* destruct_order)
+        : run_on_(run_on),
+          deleted_on_(deleted_on),
+          destruct_order_(destruct_order) {}
+
+    void RecordRun() { *run_on_ = MessageLoop::current(); }
+
+   private:
+    friend class RefCountedThreadSafe<LoopRecorder>;
+    ~LoopRecorder() {
+      *deleted_on_ = MessageLoop::current();
+      *destruct_order_ = g_order.GetNext();
+    }
+
+    MessageLoop** run_on_;
+    MessageLoop** deleted_on_;
+    int* destruct_order_;
+  };
+
+  static void RecordLoop(scoped_refptr<LoopRecorder> recorder) {
+    recorder->RecordRun();
+  }
+
+  static void RecordLoopAndQuit(scoped_refptr<LoopRecorder> recorder) {
+    recorder->RecordRun();
+    MessageLoop::current()->QuitWhenIdle();
+  }
+
+  void UnblockTaskThread() { thread_sync_.Signal(); }
+
+  void BlockTaskThreadHelper() { thread_sync_.Wait(); }
+
+  static StaticAtomicSequenceNumber g_order;
+
+  scoped_ptr<MessageLoop> current_loop_;
+  Thread task_thread_;
+
+ private:
+  base::WaitableEvent thread_sync_;
+};
+
+StaticAtomicSequenceNumber MessageLoopTaskRunnerTest::g_order;
+
+TEST_F(MessageLoopTaskRunnerTest, PostTaskAndReply_Basic) {
+  MessageLoop* task_run_on = NULL;
+  MessageLoop* task_deleted_on = NULL;
+  int task_delete_order = -1;
+  MessageLoop* reply_run_on = NULL;
+  MessageLoop* reply_deleted_on = NULL;
+  int reply_delete_order = -1;
+
+  scoped_refptr<LoopRecorder> task_recoder =
+      new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
+  scoped_refptr<LoopRecorder> reply_recoder =
+      new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);
+
+  ASSERT_TRUE(task_thread_.task_runner()->PostTaskAndReply(
+      FROM_HERE, Bind(&RecordLoop, task_recoder),
+      Bind(&RecordLoopAndQuit, reply_recoder)));
+
+  // Die if base::Bind doesn't retain a reference to the recorders.
+  task_recoder = NULL;
+  reply_recoder = NULL;
+  ASSERT_FALSE(task_deleted_on);
+  ASSERT_FALSE(reply_deleted_on);
+
+  UnblockTaskThread();
+  current_loop_->Run();
+
+  EXPECT_EQ(task_thread_.message_loop(), task_run_on);
+  EXPECT_EQ(current_loop_.get(), task_deleted_on);
+  EXPECT_EQ(current_loop_.get(), reply_run_on);
+  EXPECT_EQ(current_loop_.get(), reply_deleted_on);
+  EXPECT_LT(task_delete_order, reply_delete_order);
+}
+
+TEST_F(MessageLoopTaskRunnerTest, PostTaskAndReplyOnDeletedThreadDoesNotLeak) {
+  MessageLoop* task_run_on = NULL;
+  MessageLoop* task_deleted_on = NULL;
+  int task_delete_order = -1;
+  MessageLoop* reply_run_on = NULL;
+  MessageLoop* reply_deleted_on = NULL;
+  int reply_delete_order = -1;
+
+  scoped_refptr<LoopRecorder> task_recoder =
+      new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
+  scoped_refptr<LoopRecorder> reply_recoder =
+      new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);
+
+  // Grab a task runner to a dead MessageLoop.
+  scoped_refptr<SingleThreadTaskRunner> task_runner =
+      task_thread_.task_runner();
+  UnblockTaskThread();
+  task_thread_.Stop();
+
+  ASSERT_FALSE(
+      task_runner->PostTaskAndReply(FROM_HERE, Bind(&RecordLoop, task_recoder),
+                                    Bind(&RecordLoopAndQuit, reply_recoder)));
+
+  // The relay should have properly deleted its resources leaving us as the only
+  // reference.
+  EXPECT_EQ(task_delete_order, reply_delete_order);
+  ASSERT_TRUE(task_recoder->HasOneRef());
+  ASSERT_TRUE(reply_recoder->HasOneRef());
+
+  // Nothing should have run though.
+  EXPECT_FALSE(task_run_on);
+  EXPECT_FALSE(reply_run_on);
+}
+
+TEST_F(MessageLoopTaskRunnerTest, PostTaskAndReply_SameLoop) {
+  MessageLoop* task_run_on = NULL;
+  MessageLoop* task_deleted_on = NULL;
+  int task_delete_order = -1;
+  MessageLoop* reply_run_on = NULL;
+  MessageLoop* reply_deleted_on = NULL;
+  int reply_delete_order = -1;
+
+  scoped_refptr<LoopRecorder> task_recoder =
+      new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
+  scoped_refptr<LoopRecorder> reply_recoder =
+      new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);
+
+  // Enqueue the relay.
+  ASSERT_TRUE(current_loop_->task_runner()->PostTaskAndReply(
+      FROM_HERE, Bind(&RecordLoop, task_recoder),
+      Bind(&RecordLoopAndQuit, reply_recoder)));
+
+  // Die if base::Bind doesn't retain a reference to the recorders.
+  task_recoder = NULL;
+  reply_recoder = NULL;
+  ASSERT_FALSE(task_deleted_on);
+  ASSERT_FALSE(reply_deleted_on);
+
+  current_loop_->Run();
+
+  EXPECT_EQ(current_loop_.get(), task_run_on);
+  EXPECT_EQ(current_loop_.get(), task_deleted_on);
+  EXPECT_EQ(current_loop_.get(), reply_run_on);
+  EXPECT_EQ(current_loop_.get(), reply_deleted_on);
+  EXPECT_LT(task_delete_order, reply_delete_order);
+}
+
+TEST_F(MessageLoopTaskRunnerTest, PostTaskAndReply_DeadReplyLoopDoesNotDelete) {
+  // Annotate the scope as having memory leaks to suppress heapchecker reports.
+  ANNOTATE_SCOPED_MEMORY_LEAK;
+  MessageLoop* task_run_on = NULL;
+  MessageLoop* task_deleted_on = NULL;
+  int task_delete_order = -1;
+  MessageLoop* reply_run_on = NULL;
+  MessageLoop* reply_deleted_on = NULL;
+  int reply_delete_order = -1;
+
+  scoped_refptr<LoopRecorder> task_recoder =
+      new LoopRecorder(&task_run_on, &task_deleted_on, &task_delete_order);
+  scoped_refptr<LoopRecorder> reply_recoder =
+      new LoopRecorder(&reply_run_on, &reply_deleted_on, &reply_delete_order);
+
+  // Enqueue the relay.
+  task_thread_.task_runner()->PostTaskAndReply(
+      FROM_HERE, Bind(&RecordLoop, task_recoder),
+      Bind(&RecordLoopAndQuit, reply_recoder));
+
+  // Die if base::Bind doesn't retain a reference to the recorders.
+  task_recoder = NULL;
+  reply_recoder = NULL;
+  ASSERT_FALSE(task_deleted_on);
+  ASSERT_FALSE(reply_deleted_on);
+
+  UnblockTaskThread();
+
+  // Mercilessly whack the current loop before |reply| gets to run.
+  current_loop_.reset();
+
+  // This should ensure the relay has been run.  We need to record the
+  // MessageLoop pointer before stopping the thread because Thread::Stop() will
+  // NULL out its own pointer.
+  MessageLoop* task_loop = task_thread_.message_loop();
+  task_thread_.Stop();
+
+  EXPECT_EQ(task_loop, task_run_on);
+  ASSERT_FALSE(task_deleted_on);
+  EXPECT_FALSE(reply_run_on);
+  ASSERT_FALSE(reply_deleted_on);
+  EXPECT_EQ(task_delete_order, reply_delete_order);
+
+  // The PostTaskAndReplyRelay is leaked here.  Even if we had a reference to
+  // it, we cannot just delete it because PostTaskAndReplyRelay's destructor
+  // checks that MessageLoop::current() is the the same as when the
+  // PostTaskAndReplyRelay object was constructed.  However, this loop must have
+  // aleady been deleted in order to perform this test.  See
+  // http://crbug.com/86301.
+}
+
+class MessageLoopTaskRunnerThreadingTest : public testing::Test {
+ public:
+  void Release() const {
+    AssertOnIOThread();
+    Quit();
+  }
+
+  void Quit() const {
+    loop_.PostTask(FROM_HERE, MessageLoop::QuitWhenIdleClosure());
+  }
+
+  void AssertOnIOThread() const {
+    ASSERT_TRUE(io_thread_->task_runner()->BelongsToCurrentThread());
+    ASSERT_EQ(io_thread_->task_runner(), ThreadTaskRunnerHandle::Get());
+  }
+
+  void AssertOnFileThread() const {
+    ASSERT_TRUE(file_thread_->task_runner()->BelongsToCurrentThread());
+    ASSERT_EQ(file_thread_->task_runner(), ThreadTaskRunnerHandle::Get());
+  }
+
+ protected:
+  void SetUp() override {
+    io_thread_.reset(new Thread("MessageLoopTaskRunnerThreadingTest_IO"));
+    file_thread_.reset(new Thread("MessageLoopTaskRunnerThreadingTest_File"));
+    io_thread_->Start();
+    file_thread_->Start();
+  }
+
+  void TearDown() override {
+    io_thread_->Stop();
+    file_thread_->Stop();
+  }
+
+  static void BasicFunction(MessageLoopTaskRunnerThreadingTest* test) {
+    test->AssertOnFileThread();
+    test->Quit();
+  }
+
+  static void AssertNotRun() { FAIL() << "Callback Should not get executed."; }
+
+  class DeletedOnFile {
+   public:
+    explicit DeletedOnFile(MessageLoopTaskRunnerThreadingTest* test)
+        : test_(test) {}
+
+    ~DeletedOnFile() {
+      test_->AssertOnFileThread();
+      test_->Quit();
+    }
+
+   private:
+    MessageLoopTaskRunnerThreadingTest* test_;
+  };
+
+  scoped_ptr<Thread> io_thread_;
+  scoped_ptr<Thread> file_thread_;
+
+ private:
+  mutable MessageLoop loop_;
+};
+
+TEST_F(MessageLoopTaskRunnerThreadingTest, Release) {
+  EXPECT_TRUE(io_thread_->task_runner()->ReleaseSoon(FROM_HERE, this));
+  MessageLoop::current()->Run();
+}
+
+TEST_F(MessageLoopTaskRunnerThreadingTest, Delete) {
+  DeletedOnFile* deleted_on_file = new DeletedOnFile(this);
+  EXPECT_TRUE(
+      file_thread_->task_runner()->DeleteSoon(FROM_HERE, deleted_on_file));
+  MessageLoop::current()->Run();
+}
+
+TEST_F(MessageLoopTaskRunnerThreadingTest, PostTask) {
+  EXPECT_TRUE(file_thread_->task_runner()->PostTask(
+      FROM_HERE, Bind(&MessageLoopTaskRunnerThreadingTest::BasicFunction,
+                      Unretained(this))));
+  MessageLoop::current()->Run();
+}
+
+TEST_F(MessageLoopTaskRunnerThreadingTest, PostTaskAfterThreadExits) {
+  scoped_ptr<Thread> test_thread(
+      new Thread("MessageLoopTaskRunnerThreadingTest_Dummy"));
+  test_thread->Start();
+  scoped_refptr<SingleThreadTaskRunner> task_runner =
+      test_thread->task_runner();
+  test_thread->Stop();
+
+  bool ret = task_runner->PostTask(
+      FROM_HERE, Bind(&MessageLoopTaskRunnerThreadingTest::AssertNotRun));
+  EXPECT_FALSE(ret);
+}
+
+TEST_F(MessageLoopTaskRunnerThreadingTest, PostTaskAfterThreadIsDeleted) {
+  scoped_refptr<SingleThreadTaskRunner> task_runner;
+  {
+    scoped_ptr<Thread> test_thread(
+        new Thread("MessageLoopTaskRunnerThreadingTest_Dummy"));
+    test_thread->Start();
+    task_runner = test_thread->task_runner();
+  }
+  bool ret = task_runner->PostTask(
+      FROM_HERE, Bind(&MessageLoopTaskRunnerThreadingTest::AssertNotRun));
+  EXPECT_FALSE(ret);
+}
+
+}  // namespace base
diff --git a/base/message_loop/message_loop_unittest.cc b/base/message_loop/message_loop_unittest.cc
index ddde6bb..48c82c4 100644
--- a/base/message_loop/message_loop_unittest.cc
+++ b/base/message_loop/message_loop_unittest.cc
@@ -10,7 +10,6 @@
 #include "base/logging.h"
 #include "base/memory/ref_counted.h"
 #include "base/message_loop/message_loop.h"
-#include "base/message_loop/message_loop_proxy_impl.h"
 #include "base/message_loop/message_loop_test.h"
 #include "base/pending_task.h"
 #include "base/posix/eintr_wrapper.h"