Bug 1549321 - Pass AudioIPC init failure back to child rather than IPC_FAIL() killing parent. r=achronop
authorMatthew Gregan <kinetik@flim.org>
Fri, 07 Jun 2019 11:52:54 +0000
changeset 477836 ecdebbbb2253bf877ba3b68a0e872b5ed9dbac34
parent 477835 56dd373240fc1bac328bb3453b8489e4c1b12037
child 477837 000091da2b92ddcb030cfc39f6c7271be6d50af7
push id36125
push userapavel@mozilla.com
push dateFri, 07 Jun 2019 22:00:07 +0000
treeherdermozilla-central@d820bbb356aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersachronop
bugs1549321
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1549321 - Pass AudioIPC init failure back to child rather than IPC_FAIL() killing parent. r=achronop Differential Revision: https://phabricator.services.mozilla.com/D34105
dom/ipc/ContentParent.cpp
dom/ipc/PContent.ipdl
dom/media/CubebUtils.cpp
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -4418,20 +4418,23 @@ mozilla::ipc::IPCResult ContentParent::R
 
   rv = NS_OK;
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvCreateAudioIPCConnection(
     CreateAudioIPCConnectionResolver&& aResolver) {
   FileDescriptor fd = CubebUtils::CreateAudioIPCConnection();
-  if (!fd.IsValid()) {
-    return IPC_FAIL(this, "CubebUtils::CreateAudioIPCConnection failed");
-  }
-  aResolver(std::move(fd));
+  FileDescOrError result;
+  if (fd.IsValid()) {
+    result = fd;
+  } else {
+    result = NS_ERROR_FAILURE;
+  }
+  aResolver(std::move(result));
   return IPC_OK();
 }
 
 static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID);
 
 mozilla::ipc::IPCResult ContentParent::RecvKeygenProcessValue(
     const nsString& oldValue, const nsString& challenge,
     const nsString& keytype, const nsString& keyparams, nsString* newValue) {
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -868,17 +868,17 @@ parent:
     async PSpeechSynthesis();
 
     async PMedia();
 
     async PWebrtcGlobal();
 
     async PPresentation();
 
-    async CreateAudioIPCConnection() returns (FileDescriptor fd);
+    async CreateAudioIPCConnection() returns (FileDescOrError fd);
 
     sync PURLClassifier(Principal principal)
         returns (bool success);
 
     async PURLClassifierLocal(URIParams uri, IPCURLClassifierFeature[] features);
 
     async PLoginReputation(URIParams formURI);
 
--- a/dom/media/CubebUtils.cpp
+++ b/dom/media/CubebUtils.cpp
@@ -396,24 +396,29 @@ void InitBrandName() {
 
 #ifdef MOZ_CUBEB_REMOTING
 void InitAudioIPCConnection() {
   MOZ_ASSERT(NS_IsMainThread());
   auto contentChild = dom::ContentChild::GetSingleton();
   auto promise = contentChild->SendCreateAudioIPCConnection();
   promise->Then(
       AbstractThread::MainThread(), __func__,
-      [](ipc::FileDescriptor&& aFD) {
+      [](dom::FileDescOrError&& aFD) {
         StaticMutexAutoLock lock(sMutex);
         MOZ_ASSERT(!sIPCConnection);
-        sIPCConnection = new ipc::FileDescriptor(std::move(aFD));
+        if (aFD.type() == dom::FileDescOrError::Type::TFileDescriptor) {
+          sIPCConnection = new ipc::FileDescriptor(std::move(aFD));
+        } else {
+          MOZ_LOG(gCubebLog, LogLevel::Error,
+                  ("SendCreateAudioIPCConnection failed: invalid FD"));
+        }
       },
       [](mozilla::ipc::ResponseRejectReason&& aReason) {
         MOZ_LOG(gCubebLog, LogLevel::Error,
-                ("SendCreateAudioIPCConnection failed: %d", int(aReason)));
+                ("SendCreateAudioIPCConnection rejected: %d", int(aReason)));
       });
 }
 #endif
 
 ipc::FileDescriptor CreateAudioIPCConnection() {
 #ifdef MOZ_CUBEB_REMOTING
   MOZ_ASSERT(sServerHandle);
   ipc::FileDescriptor::PlatformHandleType rawFD =
@@ -464,22 +469,27 @@ cubeb* GetCubebContextUnlocked() {
   }
 
   int rv = CUBEB_ERROR;
 #ifdef MOZ_CUBEB_REMOTING
   MOZ_LOG(gCubebLog, LogLevel::Info,
           ("%s: %s", PREF_CUBEB_SANDBOX, sCubebSandbox ? "true" : "false"));
 
   if (sCubebSandbox) {
-    if (XRE_IsParentProcess()) {
+    if (XRE_IsParentProcess() && !sIPCConnection) {
       // TODO: Don't use audio IPC when within the same process.
-      MOZ_ASSERT(!sIPCConnection);
-      sIPCConnection = new ipc::FileDescriptor(CreateAudioIPCConnection());
-    } else {
-      MOZ_DIAGNOSTIC_ASSERT(sIPCConnection);
+      auto fd = CreateAudioIPCConnection();
+      if (fd.IsValid()) {
+        sIPCConnection = new ipc::FileDescriptor(fd);
+      }
+    }
+    if (NS_WARN_IF(!sIPCConnection)) {
+      // Either the IPC connection failed to init or we're still waiting for
+      // InitAudioIPCConnection to complete (bug 1454782).
+      return nullptr;
     }
 
     AudioIpcInitParams initParams;
     initParams.mPoolSize = sAudioIPCPoolSize;
     initParams.mStackSize = sAudioIPCStackSize;
     initParams.mServerConnection =
         sIPCConnection->ClonePlatformHandle().release();
     initParams.mThreadCreateCallback = [](const char* aName) {