| Index: mojo/edk/test/mojo_test_base.cc
|
| diff --git a/mojo/edk/test/mojo_test_base.cc b/mojo/edk/test/mojo_test_base.cc
|
| index 7ec067aeae6742fe27c8f3ee33341536270d99bf..4b044f6334c9f0c1709738516e07c1b1c39f1e82 100644
|
| --- a/mojo/edk/test/mojo_test_base.cc
|
| +++ b/mojo/edk/test/mojo_test_base.cc
|
| @@ -13,11 +13,29 @@
|
| #include "mojo/public/c/system/functions.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| +#include "base/mac/mach_port_broker.h"
|
| +#endif
|
| +
|
| namespace mojo {
|
| namespace edk {
|
| namespace test {
|
|
|
| +
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| +namespace {
|
| +base::MachPortBroker* g_mach_broker = nullptr;
|
| +}
|
| +#endif
|
| +
|
| MojoTestBase::MojoTestBase() {
|
| +#if defined(OS_MACOSX) && !defined(OS_IOS)
|
| + if (!g_mach_broker) {
|
| + g_mach_broker = new base::MachPortBroker("mojo_test");
|
| + CHECK(g_mach_broker->Init());
|
| + SetMachPortProvider(g_mach_broker);
|
| + }
|
| +#endif
|
| }
|
|
|
| MojoTestBase::~MojoTestBase() {}
|
| @@ -31,12 +49,22 @@ MojoTestBase::ClientController& MojoTestBase::StartClient(
|
|
|
| MojoTestBase::ClientController::ClientController(const std::string& client_name,
|
| MojoTestBase* test)
|
| - : test_(test)
|
| + : test_(test) {
|
| #if !defined(OS_IOS)
|
| - ,
|
| - pipe_(helper_.StartChild(client_name))
|
| +#if defined(OS_MACOSX)
|
| + // 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
|
| + pipe_ = helper_.StartChild(client_name);
|
| +#if defined(OS_MACOSX)
|
| + g_mach_broker->AddPlaceholderForPid(helper_.test_child().Handle());
|
| +#endif
|
| #endif
|
| -{
|
| }
|
|
|
| MojoTestBase::ClientController::~ClientController() {
|
| @@ -47,7 +75,12 @@ MojoTestBase::ClientController::~ClientController() {
|
| int MojoTestBase::ClientController::WaitForShutdown() {
|
| was_shutdown_ = true;
|
| #if !defined(OS_IOS)
|
| - return helper_.WaitForChildShutdown();
|
| + int retval = helper_.WaitForChildShutdown();
|
| +#if defined(OS_MACOSX)
|
| + base::AutoLock lock(g_mach_broker->GetLock());
|
| + g_mach_broker->InvalidatePid(helper_.test_child().Handle());
|
| +#endif
|
| + return retval;
|
| #else
|
| NOTREACHED();
|
| return 1;
|
|
|