Bug 1350568 - don't dispatch IPC call to StunAddrsRequestChild after content process IPC channel goes away. r=jesup draft
authorMichael Froman <mfroman@mozilla.com>
Sun, 26 Mar 2017 13:30:28 -0500
changeset 555019 fc3a5d8d066dadb476ea965014553c99515b1547
parent 553751 3364cc17988c013c36f2a8123315db2855393011
child 622507 611ec9d9a2d0f17ed4f1baf053be2ed758c3e123
push id52126
push userbmo:mfroman@nostrum.com
push dateMon, 03 Apr 2017 14:22:07 +0000
reviewersjesup
bugs1350568
milestone55.0a1
Bug 1350568 - don't dispatch IPC call to StunAddrsRequestChild after content process IPC channel goes away. r=jesup MozReview-Commit-ID: IoAWO9Frf1u
media/mtransport/ipc/StunAddrsRequestParent.cpp
media/mtransport/ipc/StunAddrsRequestParent.h
--- a/media/mtransport/ipc/StunAddrsRequestParent.cpp
+++ b/media/mtransport/ipc/StunAddrsRequestParent.cpp
@@ -12,63 +12,91 @@
 #include "mtransport/nricestunaddr.h"
 
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 StunAddrsRequestParent::StunAddrsRequestParent()
+  : mIPCClosed(false)
 {
   NS_GetMainThread(getter_AddRefs(mMainThread));
 
   nsresult res;
   mSTSThread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &res);
   MOZ_ASSERT(mSTSThread);
 }
 
 mozilla::ipc::IPCResult
 StunAddrsRequestParent::RecvGetStunAddrs()
 {
   ASSERT_ON_THREAD(mMainThread);
 
+  if (mIPCClosed) {
+    return IPC_OK();
+  }
+
   RUN_ON_THREAD(mSTSThread,
-                WrapRunnable(this, &StunAddrsRequestParent::GetStunAddrs_s),
+                WrapRunnable(RefPtr<StunAddrsRequestParent>(this),
+                             &StunAddrsRequestParent::GetStunAddrs_s),
                 NS_DISPATCH_NORMAL);
 
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult
+StunAddrsRequestParent::Recv__delete__()
+{
+  // see note below in ActorDestroy
+  mIPCClosed = true;
+  return IPC_OK();
+}
+
 void
 StunAddrsRequestParent::ActorDestroy(ActorDestroyReason why)
 {
-  // nothing to do here
+  // We may still have refcount>0 if we haven't made it through
+  // GetStunAddrs_s and SendStunAddrs_m yet, but child process
+  // has crashed.  We must not send any more msgs to child, or
+  // IPDL will kill chrome process, too.
+  mIPCClosed = true;
 }
 
 void
 StunAddrsRequestParent::GetStunAddrs_s()
 {
   ASSERT_ON_THREAD(mSTSThread);
 
   // get the stun addresses while on STS thread
   NrIceStunAddrArray addrs = NrIceCtx::GetStunAddrs();
 
+  if (mIPCClosed) {
+    return;
+  }
+
   // in order to return the result over IPC, we need to be on main thread
   RUN_ON_THREAD(mMainThread,
-                WrapRunnable(this,
+                WrapRunnable(RefPtr<StunAddrsRequestParent>(this),
                              &StunAddrsRequestParent::SendStunAddrs_m,
                              std::move(addrs)),
                 NS_DISPATCH_NORMAL);
 }
 
 void
 StunAddrsRequestParent::SendStunAddrs_m(const NrIceStunAddrArray& addrs)
 {
   ASSERT_ON_THREAD(mMainThread);
 
+  if (mIPCClosed) {
+    // nothing to do: child probably crashed
+    return;
+  }
+
+  mIPCClosed = true;
   // send the new addresses back to the child
   Unused << SendOnStunAddrsAvailable(addrs);
 }
 
 NS_IMPL_ADDREF(StunAddrsRequestParent)
 NS_IMPL_RELEASE(StunAddrsRequestParent)
 
 } // namespace net
--- a/media/mtransport/ipc/StunAddrsRequestParent.h
+++ b/media/mtransport/ipc/StunAddrsRequestParent.h
@@ -13,28 +13,33 @@ namespace net {
 class StunAddrsRequestParent : public PStunAddrsRequestParent
 {
 public:
   StunAddrsRequestParent();
 
   NS_IMETHOD_(MozExternalRefCountType) AddRef();
   NS_IMETHOD_(MozExternalRefCountType) Release();
 
+  mozilla::ipc::IPCResult Recv__delete__() override;
+
 protected:
   virtual ~StunAddrsRequestParent() {}
 
   virtual mozilla::ipc::IPCResult RecvGetStunAddrs() override;
   virtual void ActorDestroy(ActorDestroyReason why) override;
 
   nsCOMPtr<nsIThread> mMainThread;
   nsCOMPtr<nsIEventTarget> mSTSThread;
 
   void GetStunAddrs_s();
   void SendStunAddrs_m(const NrIceStunAddrArray& addrs);
 
   ThreadSafeAutoRefCnt mRefCnt;
   NS_DECL_OWNINGTHREAD
+
+private:
+  bool mIPCClosed;  // true if IPDL channel has been closed (child crash)
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // mozilla_net_StunAddrsRequestParent_h