| Index: ipc/ipc_test_base.cc
|
| diff --git a/ipc/ipc_test_base.cc b/ipc/ipc_test_base.cc
|
| index d09b3b69ad96dad409e96f41139d8c442a500a99..fd17b944bcc6bedeedb9448212f5e8f96d488197 100644
|
| --- a/ipc/ipc_test_base.cc
|
| +++ b/ipc/ipc_test_base.cc
|
| @@ -13,7 +13,23 @@
|
| #include "build/build_config.h"
|
| #include "ipc/ipc_channel_mojo.h"
|
|
|
| -IPCChannelMojoTestBase::IPCChannelMojoTestBase() = default;
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| +#include "base/mac/mach_port_broker.h"
|
| +
|
| +namespace {
|
| +base::MachPortBroker* g_mach_broker = nullptr;
|
| +}
|
| +#endif
|
| +
|
| +IPCChannelMojoTestBase::IPCChannelMojoTestBase() {
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| + if (!g_mach_broker) {
|
| + g_mach_broker = new base::MachPortBroker("mojo_test");
|
| + CHECK(g_mach_broker->Init());
|
| + mojo::edk::SetMachPortProvider(g_mach_broker);
|
| + }
|
| +#endif
|
| +}
|
| IPCChannelMojoTestBase::~IPCChannelMojoTestBase() = default;
|
|
|
| void IPCChannelMojoTestBase::Init(const std::string& test_client_name) {
|
| @@ -24,12 +40,29 @@ void IPCChannelMojoTestBase::Init(const std::string& test_client_name) {
|
| void IPCChannelMojoTestBase::InitWithCustomMessageLoop(
|
| const std::string& test_client_name,
|
| std::unique_ptr<base::MessageLoop> message_loop) {
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| + // This lock needs to be held while launching the child because the Mach port
|
| + // broker only allows task ports to be received from known child processes.
|
| + // However, it can only know the child process's pid after the child has
|
| + // launched. To prevent a race where the child process sends its task port
|
| + // before the pid has been registered, the lock needs to be held over both
|
| + // launch and child pid registration.
|
| + base::AutoLock lock(g_mach_broker->GetLock());
|
| +#endif
|
| handle_ = helper_.StartChild(test_client_name);
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| + g_mach_broker->AddPlaceholderForPid(helper_.test_child().Handle());
|
| +#endif
|
| message_loop_ = std::move(message_loop);
|
| }
|
|
|
| bool IPCChannelMojoTestBase::WaitForClientShutdown() {
|
| - return helper_.WaitForChildTestShutdown();
|
| + int retval = helper_.WaitForChildTestShutdown();
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| + base::AutoLock lock(g_mach_broker->GetLock());
|
| + g_mach_broker->InvalidatePid(helper_.test_child().Handle());
|
| +#endif
|
| + return retval;
|
| }
|
|
|
| void IPCChannelMojoTestBase::TearDown() {
|
|
|