Bug 1350568 - don't dispatch IPC call to StunAddrsRequestChild after content process IPC channel goes away. r=jesup
MozReview-Commit-ID: IoAWO9Frf1u
--- 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