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; |