From 22796d8d5fd362111b7aa431d229aa2ffc91aedd Mon Sep 17 00:00:00 2001
From: yzshen <yzshen@chromium.org>
Date: Thu, 4 Sep 2014 21:42:58 -0700
Subject: Fix a DCHECK violation in ipc_perftests

We only allow one MessageLoop instance alive at any given time on a thread. If
we use IPCTestBase::set_message_loop(), we need to do it in two steps: first set
the message loop to NULL, and then set it to a newly-created message loop.

Therefore, I changed the interface of IPCTestBase to make it a little
more friendly.

BUG=None

TEST=ipc_perftests should not crash in debug build.

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

Cr-Commit-Position: refs/heads/master@{#293439}
---
 ipc/ipc_perftests.cc |  4 ++--
 ipc/ipc_test_base.cc | 24 +++++++++++-------------
 ipc/ipc_test_base.h  | 20 ++++++++------------
 3 files changed, 21 insertions(+), 27 deletions(-)

(limited to 'ipc')

diff --git a/ipc/ipc_perftests.cc b/ipc/ipc_perftests.cc
index dd08cf7..08a8d70 100644
--- a/ipc/ipc_perftests.cc
+++ b/ipc/ipc_perftests.cc
@@ -281,8 +281,8 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(PerformanceClient) {
 }
 
 TEST_F(IPCChannelPerfTest, ChannelProxyPingPong) {
-  set_message_loop(make_scoped_ptr(new base::MessageLoop()));
-  Init("PerformanceClient");
+  InitWithCustomMessageLoop("PerformanceClient",
+                            make_scoped_ptr(new base::MessageLoop()));
 
   base::TestIOThread io_thread(base::TestIOThread::kAutoStart);
 
diff --git a/ipc/ipc_test_base.cc b/ipc/ipc_test_base.cc
index 7adb1a4..80ddd2d 100644
--- a/ipc/ipc_test_base.cc
+++ b/ipc/ipc_test_base.cc
@@ -29,24 +29,26 @@ IPCTestBase::IPCTestBase()
 IPCTestBase::~IPCTestBase() {
 }
 
-void IPCTestBase::SetUp() {
-  MultiProcessTest::SetUp();
-
-  // Construct a fresh Message loop for the duration of each test.
-  DCHECK(!message_loop_.get());
-  message_loop_.reset(new base::MessageLoopForIO());
-}
-
 void IPCTestBase::TearDown() {
-  DCHECK(message_loop_.get());
   message_loop_.reset();
   MultiProcessTest::TearDown();
 }
 
 void IPCTestBase::Init(const std::string& test_client_name) {
+  InitWithCustomMessageLoop(
+      test_client_name,
+      scoped_ptr<base::MessageLoop>(new base::MessageLoopForIO()));
+}
+
+void IPCTestBase::InitWithCustomMessageLoop(
+    const std::string& test_client_name,
+    scoped_ptr<base::MessageLoop> message_loop) {
   DCHECK(!test_client_name.empty());
   DCHECK(test_client_name_.empty());
+  DCHECK(!message_loop_);
+
   test_client_name_ = test_client_name;
+  message_loop_ = message_loop.Pass();
 }
 
 void IPCTestBase::CreateChannel(IPC::Listener* listener) {
@@ -133,7 +135,3 @@ bool IPCTestBase::WaitForClientShutdown() {
 scoped_refptr<base::TaskRunner> IPCTestBase::task_runner() {
   return message_loop_->message_loop_proxy();
 }
-
-void IPCTestBase::set_message_loop(scoped_ptr<base::MessageLoop> loop) {
-  message_loop_ = loop.Pass();
-}
diff --git a/ipc/ipc_test_base.h b/ipc/ipc_test_base.h
index c304001..ff34945 100644
--- a/ipc/ipc_test_base.h
+++ b/ipc/ipc_test_base.h
@@ -33,11 +33,17 @@ class IPCTestBase : public base::MultiProcessTest {
   IPCTestBase();
   virtual ~IPCTestBase();
 
-  virtual void SetUp() OVERRIDE;
   virtual void TearDown() OVERRIDE;
 
-  // Initializes the test to use the given client.
+  // Initializes the test to use the given client and creates an IO message loop
+  // on the current thread.
   void Init(const std::string& test_client_name);
+  // Some tests create separate thread for IO message loop and run non-IO
+  // message loop on the main thread. As IPCTestBase creates IO message loop by
+  // default, such tests need to provide a custom message loop for the main
+  // thread.
+  void InitWithCustomMessageLoop(const std::string& test_client_name,
+                                 scoped_ptr<base::MessageLoop> message_loop);
 
   // Creates a channel with the given listener and connects to the channel
   // (returning true if successful), respectively. Use these to use a channel
@@ -89,16 +95,6 @@ class IPCTestBase : public base::MultiProcessTest {
   const base::ProcessHandle& client_process() const { return client_process_; }
   scoped_refptr<base::TaskRunner> task_runner();
 
-  // Some tests creates separate thread for IO message loop and Run
-  // non-IO message loop on the main thread. As IPCTestBase creates IO
-  // message loop by default, such tests might want to replace it with
-  // non-IO one using set_message_loop().
-  //
-  // The replacement should be done at the beginning of the test.
-  // You should be careful not to replace "live" message loop that has
-  // started running.
-  void set_message_loop(scoped_ptr<base::MessageLoop> loop);
-
  private:
   std::string test_client_name_;
   scoped_ptr<base::MessageLoop> message_loop_;
-- 
cgit v1.1