EDK: Make ConnectionManagerTest not use base::MessageLoop/RunLoop.
Also add a QuitNow() method to mojo::platform::MessageLoop. I guess we
do need it.
R=vardhan@google.com
Review URL: https://codereview.chromium.org/1465203003 .
diff --git a/mojo/edk/base_edk/platform_message_loop_impl.cc b/mojo/edk/base_edk/platform_message_loop_impl.cc
index d8752ce..717d634 100644
--- a/mojo/edk/base_edk/platform_message_loop_impl.cc
+++ b/mojo/edk/base_edk/platform_message_loop_impl.cc
@@ -39,6 +39,10 @@
base_message_loop_.QuitWhenIdle();
}
+void PlatformMessageLoopImpl::QuitNow() {
+ base_message_loop_.QuitNow();
+}
+
const RefPtr<TaskRunner>& PlatformMessageLoopImpl::GetTaskRunner() const {
return task_runner_;
}
diff --git a/mojo/edk/base_edk/platform_message_loop_impl.h b/mojo/edk/base_edk/platform_message_loop_impl.h
index a25b013..ae6b0a0 100644
--- a/mojo/edk/base_edk/platform_message_loop_impl.h
+++ b/mojo/edk/base_edk/platform_message_loop_impl.h
@@ -32,6 +32,7 @@
void Run() override;
void RunUntilIdle() override;
void QuitWhenIdle() override;
+ void QuitNow() override;
const mojo::util::RefPtr<mojo::platform::TaskRunner>& GetTaskRunner()
const override;
bool IsRunningOnCurrentThread() const override;
diff --git a/mojo/edk/base_edk/platform_message_loop_impl_unittest.cc b/mojo/edk/base_edk/platform_message_loop_impl_unittest.cc
index e5ea2e9..e74dcc4 100644
--- a/mojo/edk/base_edk/platform_message_loop_impl_unittest.cc
+++ b/mojo/edk/base_edk/platform_message_loop_impl_unittest.cc
@@ -69,6 +69,20 @@
EXPECT_EQ(std::vector<int>({4, 5, 6}), stuff);
stuff.clear();
+ task_runner->PostTask(ToClosure([&stuff, &message_loop, &task_runner]() {
+ EXPECT_TRUE(message_loop.IsRunningOnCurrentThread());
+ stuff.push_back(7);
+ message_loop.QuitNow();
+ task_runner->PostTask(ToClosure([&stuff]() { stuff.push_back(9); }));
+ }));
+ task_runner->PostTask(ToClosure([&stuff]() { stuff.push_back(8); }));
+ message_loop.Run();
+ EXPECT_EQ(std::vector<int>({7}), stuff);
+ stuff.clear();
+ message_loop.RunUntilIdle();
+ EXPECT_EQ(std::vector<int>({8, 9}), stuff);
+
+ stuff.clear();
message_loop.RunUntilIdle();
EXPECT_TRUE(stuff.empty());
@@ -86,19 +100,19 @@
std::thread other_thread([&stuff, &message_loop, task_runner]() {
EXPECT_FALSE(message_loop.IsRunningOnCurrentThread());
EXPECT_EQ(task_runner, message_loop.GetTaskRunner());
- stuff.push_back(7);
+ stuff.push_back(10);
task_runner->PostTask(ToClosure([&stuff, &message_loop]() {
EXPECT_TRUE(message_loop.IsRunningOnCurrentThread());
- stuff.push_back(8);
+ stuff.push_back(11);
message_loop.QuitWhenIdle();
}));
});
other_thread.join();
- EXPECT_EQ(std::vector<int>({7}), stuff);
+ EXPECT_EQ(std::vector<int>({10}), stuff);
stuff.clear();
}));
message_loop.Run();
- EXPECT_EQ(std::vector<int>({8}), stuff);
+ EXPECT_EQ(std::vector<int>({11}), stuff);
}
TEST(PlatformMessageLoopImpl, TypeIO) {
diff --git a/mojo/edk/platform/message_loop.h b/mojo/edk/platform/message_loop.h
index ad50177..4d6ae15 100644
--- a/mojo/edk/platform/message_loop.h
+++ b/mojo/edk/platform/message_loop.h
@@ -28,20 +28,24 @@
public:
virtual ~MessageLoop() {}
- // Runs the message loop until it is told to quit (via |QuitWhenIdle()|).
+ // Runs the message loop until it is told to quit (via |QuitNow() or
+ // |QuitWhenIdle()|).
virtual void Run() = 0;
// Runs the message loop until there are no more tasks available to execute
// immediately (i.e., not including delayed tasks).
virtual void RunUntilIdle() = 0;
- // Quits the message loop when there are no more tasks available to execute
- // immediately. (Note that this includes "future" tasks, i.e., those that are
- // posted as a result of executing other tasks, so this may never quit.
- // However, it does not include delayed tasks.)
- // TODO(vtl): Do we also want a |QuitNow()|?
+ // If running, quits the message loop when there are no more tasks available
+ // to execute immediately. (Note that this includes "future" tasks, i.e.,
+ // those that are posted as a result of executing other tasks, so this may
+ // never quit. However, it does not include delayed tasks.)
virtual void QuitWhenIdle() = 0;
+ // If running, quits the message loop now (i.e., do not process any further
+ // tasks until |Run()| or |RunUntilIdle()|) is called again.
+ virtual void QuitNow() = 0;
+
// Gets the |TaskRunner| for this message loop, which can be used to post
// tasks to it. For a given |MessageLoop| instance, this will always return a
// reference to the same |TaskRunner| (and different |MessageLoop| instances
diff --git a/mojo/edk/system/BUILD.gn b/mojo/edk/system/BUILD.gn
index d76668c..0a27354 100644
--- a/mojo/edk/system/BUILD.gn
+++ b/mojo/edk/system/BUILD.gn
@@ -175,6 +175,7 @@
mojo_edk_deps = [
"mojo/edk/base_edk",
+ "mojo/edk/base_edk:test_base_edk",
"mojo/edk/system/test",
"mojo/edk/test:test_support",
"mojo/edk/util",
diff --git a/mojo/edk/system/connection_manager_unittest.cc b/mojo/edk/system/connection_manager_unittest.cc
index c28e67c..8e2e219 100644
--- a/mojo/edk/system/connection_manager_unittest.cc
+++ b/mojo/edk/system/connection_manager_unittest.cc
@@ -9,16 +9,17 @@
#include <stdint.h>
+#include <memory>
#include <string>
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
#include "base/threading/thread_checker.h"
#include "mojo/edk/base_edk/platform_task_runner_impl.h"
#include "mojo/edk/embedder/master_process_delegate.h"
#include "mojo/edk/embedder/platform_channel_pair.h"
#include "mojo/edk/embedder/simple_platform_support.h"
#include "mojo/edk/embedder/slave_process_delegate.h"
+#include "mojo/edk/platform/message_loop.h"
+#include "mojo/edk/platform/test_message_loop.h"
#include "mojo/edk/system/master_connection_manager.h"
#include "mojo/edk/system/slave_connection_manager.h"
#include "mojo/edk/test/test_utils.h"
@@ -26,7 +27,9 @@
#include "mojo/public/cpp/system/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
+using mojo::platform::MessageLoop;
using mojo::platform::TaskRunner;
+using mojo::platform::test::CreateTestMessageLoop;
using mojo::util::MakeRefCounted;
using mojo::util::RefPtr;
@@ -87,15 +90,14 @@
class MockMasterProcessDelegate : public embedder::MasterProcessDelegate {
public:
MockMasterProcessDelegate()
- : current_run_loop_(), on_slave_disconnect_calls_(0) {}
+ : current_message_loop_(), on_slave_disconnect_calls_(0) {}
~MockMasterProcessDelegate() override {}
- void RunUntilNotified() {
- CHECK(!current_run_loop_);
- base::RunLoop run_loop;
- current_run_loop_ = &run_loop;
- run_loop.Run();
- current_run_loop_ = nullptr;
+ void RunUntilNotified(MessageLoop* message_loop) {
+ CHECK(!current_message_loop_);
+ current_message_loop_ = message_loop;
+ message_loop->Run();
+ current_message_loop_ = nullptr;
}
unsigned on_slave_disconnect_calls() const {
@@ -117,13 +119,13 @@
<< last_slave_disconnect_name_;
delete static_cast<TestSlaveInfo*>(slave_info);
- if (current_run_loop_)
- current_run_loop_->Quit();
+ if (current_message_loop_)
+ current_message_loop_->QuitNow();
}
private:
base::ThreadChecker thread_checker_;
- base::RunLoop* current_run_loop_;
+ MessageLoop* current_message_loop_;
unsigned on_slave_disconnect_calls_;
std::string last_slave_disconnect_name_;
@@ -134,15 +136,14 @@
class MockSlaveProcessDelegate : public embedder::SlaveProcessDelegate {
public:
MockSlaveProcessDelegate()
- : current_run_loop_(), on_master_disconnect_calls_(0) {}
+ : current_message_loop_(), on_master_disconnect_calls_(0) {}
~MockSlaveProcessDelegate() override {}
- void RunUntilNotified() {
- CHECK(!current_run_loop_);
- base::RunLoop run_loop;
- current_run_loop_ = &run_loop;
- run_loop.Run();
- current_run_loop_ = nullptr;
+ void RunUntilNotified(MessageLoop* message_loop) {
+ CHECK(!current_message_loop_);
+ current_message_loop_ = message_loop;
+ message_loop->Run();
+ current_message_loop_ = nullptr;
}
unsigned on_master_disconnect_calls() const {
@@ -157,13 +158,13 @@
on_master_disconnect_calls_++;
DVLOG(1) << "Disconnected from master process";
- if (current_run_loop_)
- current_run_loop_->Quit();
+ if (current_message_loop_)
+ current_message_loop_->QuitNow();
}
private:
base::ThreadChecker thread_checker_;
- base::RunLoop* current_run_loop_;
+ MessageLoop* current_message_loop_;
unsigned on_master_disconnect_calls_;
@@ -172,13 +173,14 @@
class ConnectionManagerTest : public testing::Test {
protected:
- ConnectionManagerTest()
- : task_runner_(MakeRefCounted<base_edk::PlatformTaskRunnerImpl>(
- message_loop_.task_runner())) {}
+ ConnectionManagerTest() : message_loop_(CreateTestMessageLoop()) {}
~ConnectionManagerTest() override {}
embedder::PlatformSupport* platform_support() { return &platform_support_; }
- const RefPtr<TaskRunner>& task_runner() { return task_runner_; }
+ MessageLoop* message_loop() { return message_loop_.get(); }
+ const RefPtr<TaskRunner>& task_runner() {
+ return message_loop_->GetTaskRunner();
+ }
MockMasterProcessDelegate& master_process_delegate() {
return master_process_delegate_;
}
@@ -195,15 +197,14 @@
ProcessIdentifier slave_process_identifier =
master->AddSlave(new TestSlaveInfo(slave_name),
platform_channel_pair.PassServerHandle());
- slave->Init(task_runner_.Clone(), slave_process_delegate,
+ slave->Init(task_runner().Clone(), slave_process_delegate,
platform_channel_pair.PassClientHandle());
return slave_process_identifier;
}
private:
embedder::SimplePlatformSupport platform_support_;
- base::MessageLoop message_loop_;
- RefPtr<TaskRunner> task_runner_;
+ std::unique_ptr<MessageLoop> message_loop_;
MockMasterProcessDelegate master_process_delegate_;
MOJO_DISALLOW_COPY_AND_ASSIGN(ConnectionManagerTest);
@@ -252,27 +253,27 @@
// The process manager shouldn't have gotten any notifications yet. (Spin the
// message loop to make sure none were enqueued.)
- base::RunLoop().RunUntilIdle();
+ message_loop()->RunUntilIdle();
EXPECT_EQ(0u, master_process_delegate().on_slave_disconnect_calls());
slave1.Shutdown();
// |OnSlaveDisconnect()| should be called once.
- master_process_delegate().RunUntilNotified();
+ master_process_delegate().RunUntilNotified(message_loop());
EXPECT_EQ(1u, master_process_delegate().on_slave_disconnect_calls());
EXPECT_EQ("slave1", master_process_delegate().last_slave_disconnect_name());
slave2.Shutdown();
// |OnSlaveDisconnect()| should be called again.
- master_process_delegate().RunUntilNotified();
+ master_process_delegate().RunUntilNotified(message_loop());
EXPECT_EQ(2u, master_process_delegate().on_slave_disconnect_calls());
EXPECT_EQ("slave2", master_process_delegate().last_slave_disconnect_name());
master.Shutdown();
// None of the above should result in |OnMasterDisconnect()| being called.
- base::RunLoop().RunUntilIdle();
+ message_loop()->RunUntilIdle();
EXPECT_EQ(0u, slave1_process_delegate.on_master_disconnect_calls());
EXPECT_EQ(0u, slave2_process_delegate.on_master_disconnect_calls());
}
@@ -289,18 +290,18 @@
// The process manager shouldn't have gotten any notifications yet. (Spin the
// message loop to make sure none were enqueued.)
- base::RunLoop().RunUntilIdle();
+ message_loop()->RunUntilIdle();
EXPECT_EQ(0u, master_process_delegate().on_slave_disconnect_calls());
master.Shutdown();
// |OnSlaveDisconnect()| should be called.
- master_process_delegate().RunUntilNotified();
+ master_process_delegate().RunUntilNotified(message_loop());
EXPECT_EQ(1u, master_process_delegate().on_slave_disconnect_calls());
EXPECT_EQ("slave", master_process_delegate().last_slave_disconnect_name());
// |OnMasterDisconnect()| should also be (or have been) called.
- slave_process_delegate.RunUntilNotified();
+ slave_process_delegate.RunUntilNotified(message_loop());
EXPECT_EQ(1u, slave_process_delegate.on_master_disconnect_calls());
slave.Shutdown();
@@ -369,7 +370,7 @@
// |OnSlaveDisconnect()| should be called. After it's called, this means that
// the disconnect has been detected and handled, including the removal of the
// pending connection.
- master_process_delegate().RunUntilNotified();
+ master_process_delegate().RunUntilNotified(message_loop());
EXPECT_EQ(1u, master_process_delegate().on_slave_disconnect_calls());
ProcessIdentifier peer2 = kInvalidProcessIdentifier;