Bug 1469691 - Fix intermittent launch failure caused by registering a Mach port too late. r?erahm draft
authorJed Davis <jld@mozilla.com>
Thu, 21 Jun 2018 11:05:00 -0600
changeset 813241 580688c4456bb68773a06cb61efbda3ec6909877
parent 813062 9c02d2ecf22050bfee5d70c04a359d8aaff6eb91
push id114836
push userbmo:jld@mozilla.com
push dateMon, 02 Jul 2018 20:03:43 +0000
reviewerserahm
bugs1469691
milestone63.0a1
Bug 1469691 - Fix intermittent launch failure caused by registering a Mach port too late. r?erahm
ipc/glue/GeckoChildProcessHost.cpp
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -812,16 +812,22 @@ GeckoChildProcessHost::PerformAsyncLaunc
   // can't pretend being the child that's forked off.
   std::string mach_connection_name = StringPrintf("org.mozilla.machname.%d",
                                                   base::RandInt(0, std::numeric_limits<int>::max()));
   childArgv.push_back(mach_connection_name.c_str());
 # endif // MOZ_WIDGET_COCOA
 
   childArgv.push_back(childProcessType);
 
+# ifdef MOZ_WIDGET_COCOA
+  // Register the listening port before launching the child, to ensure
+  // that it's there when the child tries to look it up.
+  ReceivePort parent_recv_port(mach_connection_name.c_str());
+# endif // MOZ_WIDGET_COCOA
+
 # if defined(MOZ_WIDGET_ANDROID)
   LaunchAndroidService(childProcessType, childArgv,
                        mLaunchOptions->fds_to_remap, &process);
 # else // goes with defined(MOZ_WIDGET_ANDROID)
   base::LaunchApp(childArgv, *mLaunchOptions, &process);
 # endif // defined(MOZ_WIDGET_ANDROID)
 
   // We're in the parent and the child was launched. Close the child FD in the
@@ -829,17 +835,16 @@ GeckoChildProcessHost::PerformAsyncLaunc
   // child closes its FD (either due to normal exit or due to crash).
   GetChannel()->CloseClientFileDescriptor();
 
 # ifdef MOZ_WIDGET_COCOA
   // Wait for the child process to send us its 'task_t' data.
   const int kTimeoutMs = 10000;
 
   MachReceiveMessage child_message;
-  ReceivePort parent_recv_port(mach_connection_name.c_str());
   kern_return_t err = parent_recv_port.WaitForMessage(&child_message, kTimeoutMs);
   if (err != KERN_SUCCESS) {
     std::string errString = StringPrintf("0x%x %s", err, mach_error_string(err));
     CHROMIUM_LOG(ERROR) << "parent WaitForMessage() failed: " << errString;
 #ifdef ASYNC_CONTENTPROC_LAUNCH
     MOZ_RELEASE_ASSERT(3 == 4);
 #endif
     return false;