Bug 1509591 - Part 2: Remove now-unnecessary mIPCOpen variable, r=mccr8
☠☠ backed out by 9bfe29337ffe ☠ ☠
authorNika Layzell <nika@thelayzells.com>
Fri, 23 Nov 2018 18:01:03 -0500
changeset 504882 6494840edc17b976778f057b1edd0b7c03e19d0b
parent 504881 123b5d5a36377f409cb5c0a5e691e5eadb31626a
child 504883 c3fe435e473a463fbc22d4afa531bdedb757079c
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1509591
milestone65.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 1509591 - Part 2: Remove now-unnecessary mIPCOpen variable, r=mccr8 This should eliminate most variables which can be replaced with IPCOpen(). Differential Revision: https://phabricator.services.mozilla.com/D12957
dom/base/nsContentPermissionHelper.cpp
dom/base/nsContentPermissionHelper.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/ProcessHangMonitor.cpp
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/URLClassifierParent.cpp
dom/ipc/URLClassifierParent.h
dom/network/TCPServerSocketChild.cpp
dom/network/TCPServerSocketChild.h
dom/network/TCPServerSocketParent.cpp
dom/network/TCPServerSocketParent.h
dom/network/TCPSocketChild.cpp
dom/network/TCPSocketChild.h
dom/network/TCPSocketParent.cpp
dom/network/TCPSocketParent.h
dom/network/UDPSocketChild.cpp
dom/network/UDPSocketChild.h
dom/network/UDPSocketParent.cpp
dom/network/UDPSocketParent.h
dom/storage/StorageIPC.cpp
dom/storage/StorageIPC.h
gfx/layers/client/TextureClient.cpp
gfx/layers/ipc/LayerTransactionChild.h
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayerTransactionParent.h
gfx/layers/wr/WebRenderBridgeChild.cpp
gfx/layers/wr/WebRenderBridgeChild.h
gfx/vr/ipc/VRLayerChild.cpp
gfx/vr/ipc/VRLayerChild.h
gfx/vr/ipc/VRLayerParent.cpp
gfx/vr/ipc/VRLayerParent.h
netwerk/cookie/CookieServiceChild.cpp
netwerk/cookie/CookieServiceChild.h
netwerk/dns/DNSRequestChild.cpp
netwerk/dns/DNSRequestChild.h
netwerk/protocol/data/DataChannelChild.cpp
netwerk/protocol/data/DataChannelChild.h
netwerk/protocol/file/FileChannelChild.cpp
netwerk/protocol/file/FileChannelChild.h
netwerk/protocol/ftp/FTPChannelChild.cpp
netwerk/protocol/ftp/FTPChannelChild.h
netwerk/protocol/http/AltDataOutputStreamChild.cpp
netwerk/protocol/http/AltDataOutputStreamChild.h
netwerk/protocol/http/AltDataOutputStreamParent.cpp
netwerk/protocol/http/AltDataOutputStreamParent.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/websocket/WebSocketChannelParent.cpp
netwerk/protocol/websocket/WebSocketChannelParent.h
netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
netwerk/protocol/wyciwyg/WyciwygChannelChild.h
security/manager/ssl/PSMContentListener.cpp
security/manager/ssl/PSMContentListener.h
toolkit/components/reputationservice/LoginReputationIPC.cpp
toolkit/components/reputationservice/LoginReputationIPC.h
--- a/dom/base/nsContentPermissionHelper.cpp
+++ b/dom/base/nsContentPermissionHelper.cpp
@@ -987,26 +987,26 @@ nsContentPermissionRequestProxy::GetRequ
 
 NS_IMPL_ISUPPORTS(RemotePermissionRequest, nsIContentPermissionRequestCallback);
 
 RemotePermissionRequest::RemotePermissionRequest(
   nsIContentPermissionRequest* aRequest,
   nsPIDOMWindowInner* aWindow)
   : mRequest(aRequest)
   , mWindow(aWindow)
-  , mIPCOpen(false)
   , mDestroyed(false)
 {
   mListener = new VisibilityChangeListener(mWindow);
   mListener->SetCallback(this);
 }
 
 RemotePermissionRequest::~RemotePermissionRequest()
 {
-  MOZ_ASSERT(!mIPCOpen, "Protocol must not be open when RemotePermissionRequest is destroyed.");
+  MOZ_ASSERT(!mozilla::ipc::IProtocol::IPCOpen(),
+             "Protocol must not be open when RemotePermissionRequest is destroyed.");
 }
 
 void
 RemotePermissionRequest::DoCancel()
 {
   NS_ASSERTION(mRequest, "We need a request");
   mRequest->Cancel();
 }
--- a/dom/base/nsContentPermissionHelper.h
+++ b/dom/base/nsContentPermissionHelper.h
@@ -229,37 +229,36 @@ public:
   // It will be called when prompt dismissed.
   virtual mozilla::ipc::IPCResult RecvNotifyResult(const bool &aAllow,
                                                    InfallibleTArray<PermissionChoice>&& aChoices) override;
 
   virtual mozilla::ipc::IPCResult RecvGetVisibility() override;
 
   void IPDLAddRef()
   {
-    mIPCOpen = true;
     AddRef();
   }
 
   void IPDLRelease()
   {
-    mIPCOpen = false;
     Release();
   }
 
   void Destroy();
 
-  bool IPCOpen() const { return mIPCOpen && !mDestroyed; }
+  bool IPCOpen() const {
+    return mozilla::ipc::IProtocol::IPCOpen() && !mDestroyed;
+  }
 
 private:
   virtual ~RemotePermissionRequest();
 
   void DoAllow(JS::HandleValue aChoices);
   void DoCancel();
 
   nsCOMPtr<nsIContentPermissionRequest> mRequest;
   nsCOMPtr<nsPIDOMWindowInner>          mWindow;
-  bool                                  mIPCOpen;
   bool                                  mDestroyed;
   RefPtr<VisibilityChangeListener>    mListener;
 };
 
 #endif // nsContentPermissionHelper_h
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1479,17 +1479,17 @@ ContentParent::ShutDownProcess(ShutDownM
           !NS_FAILED(file->AppendNative(nsPrintfCString("Recording.%d.%d",
                                                         base::GetCurrentProcId(),
                                                         ++sNumSavedRecordings)))) {
         bool unused;
         SaveRecording(file, &unused);
       }
     }
 
-    if (mIPCOpen && !mShutdownPending) {
+    if (IPCOpen() && !mShutdownPending) {
       // Stop sending input events with input priority when shutting down.
       SetInputPriorityEventEnabled(false);
       if (SendShutdown()) {
         mShutdownPending = true;
         // Start the force-kill timer if we haven't already.
         StartForceKillTimer();
       }
     }
@@ -1682,20 +1682,16 @@ ContentParent::ActorDestroy(ActorDestroy
   RefPtr<ContentParent> kungFuDeathGrip(mSelfRef.forget());
   MOZ_RELEASE_ASSERT(kungFuDeathGrip);
 
   if (mForceKillTimer) {
     mForceKillTimer->Cancel();
     mForceKillTimer = nullptr;
   }
 
-  // Signal shutdown completion regardless of error state, so we can
-  // finish waiting in the xpcom-shutdown/profile-before-change observer.
-  mIPCOpen = false;
-
   if (mHangMonitorActor) {
     ProcessHangMonitor::RemoveProcess(mHangMonitorActor);
     mHangMonitorActor = nullptr;
   }
 
   RefPtr<FileSystemSecurity> fss = FileSystemSecurity::Get();
   if (fss) {
     fss->Forget(ChildID());
@@ -1939,17 +1935,17 @@ ContentParent::NotifyTabDestroying(const
   } else {
     ContentChild::GetSingleton()->SendNotifyTabDestroying(aTabId, aCpId);
   }
 }
 
 void
 ContentParent::StartForceKillTimer()
 {
-  if (mForceKillTimer || !mIPCOpen) {
+  if (mForceKillTimer || !IPCOpen()) {
     return;
   }
 
   int32_t timeoutSecs = StaticPrefs::dom_ipc_tabs_shutdownTimeoutSecs();
   if (timeoutSecs > 0) {
     NS_NewTimerWithFuncCallback(getter_AddRefs(mForceKillTimer),
                                 ContentParent::ForceKillTimerCallback,
                                 this,
@@ -2396,17 +2392,16 @@ ContentParent::ContentParent(ContentPare
   , mIsAlive(true)
   , mIsForBrowser(!mRemoteType.IsEmpty())
   , mRecordReplayState(aRecordReplayState)
   , mRecordingFile(aRecordingFile)
   , mCalledClose(false)
   , mCalledKillHard(false)
   , mCreatedPairedMinidumps(false)
   , mShutdownPending(false)
-  , mIPCOpen(true)
   , mIsRemoteInputEventQueueEnabled(false)
   , mIsInputPriorityEventEnabled(false)
   , mHangMonitorActor(nullptr)
 {
   // Insert ourselves into the global linked list of ContentParent objects.
   if (!sContentParents) {
     sContentParents = new LinkedList<ContentParent>();
   }
@@ -2901,17 +2896,17 @@ ContentParent::IsInputEventQueueSupporte
     sInitialized = true;
   }
   return sSupported;
 }
 
 void
 ContentParent::OnVarChanged(const GfxVarUpdate& aVar)
 {
-  if (!mIPCOpen) {
+  if (!IPCOpen()) {
     return;
   }
   Unused << SendVarUpdate(aVar);
 }
 
 mozilla::ipc::IPCResult
 ContentParent::RecvReadFontList(InfallibleTArray<FontListEntry>* retValue)
 {
@@ -3135,17 +3130,17 @@ ContentParent::Observe(nsISupports* aSub
 
     // Okay to call ShutDownProcess multiple times.
     ShutDownProcess(SEND_SHUTDOWN_MESSAGE);
     MarkAsDead();
 
     // Wait for shutdown to complete, so that we receive any shutdown
     // data (e.g. telemetry) from the child before we quit.
     // This loop terminate prematurely based on mForceKillTimer.
-    SpinEventLoopUntil([&]() { return !mIPCOpen || mCalledKillHard; });
+    SpinEventLoopUntil([&]() { return !IPCOpen() || mCalledKillHard; });
     NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
   }
 
   if (!mIsAlive || !mSubprocess)
     return NS_OK;
 
   // listening for memory pressure event
   if (!strcmp(aTopic, "memory-pressure")) {
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -283,17 +283,17 @@ public:
    *
    * aWidget - the eWindowType_plugin_ipc_chrome widget associated with
    *           this plugin window.
    */
   static void SendAsyncUpdate(nsIWidget* aWidget);
 #endif
 
   // Let managees query if it is safe to send messages.
-  bool IsDestroyed() const { return !mIPCOpen; }
+  bool IsDestroyed() const { return !IPCOpen(); }
 
   virtual mozilla::ipc::IPCResult RecvCreateChildProcess(const IPCTabContext& aContext,
                                                          const hal::ProcessPriority& aPriority,
                                                          const TabId& aOpenerTabId,
                                                          const TabId& aTabId,
                                                          ContentParentId* aCpId,
                                                          bool* aIsForBrowser) override;
 
@@ -1346,17 +1346,16 @@ private:
   Vector<mozilla::ipc::GeckoChildProcessHost*> mReplayingChildren;
 
   // These variables track whether we've called Close() and KillHard() on our
   // channel.
   bool mCalledClose;
   bool mCalledKillHard;
   bool mCreatedPairedMinidumps;
   bool mShutdownPending;
-  bool mIPCOpen;
 
   // True if the input event queue on the main thread of the content process is
   // enabled.
   bool mIsRemoteInputEventQueueEnabled;
 
   // True if we send input events with input priority. Otherwise, we send input
   // events with normal priority.
   bool mIsInputPriorityEventEnabled;
--- a/dom/ipc/ProcessHangMonitor.cpp
+++ b/dom/ipc/ProcessHangMonitor.cpp
@@ -149,19 +149,16 @@ class HangMonitorChild
   bool mFinishedStartingDebugger;
   bool mPaintWhileInterruptingJS;
   bool mPaintWhileInterruptingJSForce;
   TabId mPaintWhileInterruptingJSTab;
   MOZ_INIT_OUTSIDE_CTOR LayersObserverEpoch mPaintWhileInterruptingJSEpoch;
   JSContext* mContext;
   bool mShutdownDone;
 
-  // This field is only accessed on the hang thread.
-  bool mIPCOpen;
-
   // Allows us to ensure we NotifyActivity only once, allowing
   // either thread to do so.
   Atomic<bool> mPaintWhileInterruptingJSActive;
 };
 
 Atomic<HangMonitorChild*, SequentiallyConsistent,
        recordreplay::Behavior::DontPreserve> HangMonitorChild::sInstance;
 
@@ -271,19 +268,16 @@ private:
 
   void ShutdownOnThread();
 
   const RefPtr<ProcessHangMonitor> mHangMonitor;
 
   // This field is read-only after construction.
   bool mReportHangs;
 
-  // This field is only accessed on the hang thread.
-  bool mIPCOpen;
-
   Monitor mMonitor;
 
   // Must be accessed with mMonitor held.
   RefPtr<HangMonitoredProcess> mProcess;
   bool mShutdownDone;
   // Map from plugin ID to crash dump ID. Protected by mBrowserCrashDumpHashLock.
   nsDataHashtable<nsUint32HashKey, nsString> mBrowserCrashDumpIds;
   Mutex mBrowserCrashDumpHashLock;
@@ -306,17 +300,16 @@ HangMonitorChild::HangMonitorChild(Proce
    mSentReport(false),
    mTerminateScript(false),
    mTerminateGlobal(false),
    mStartDebugger(false),
    mFinishedStartingDebugger(false),
    mPaintWhileInterruptingJS(false),
    mPaintWhileInterruptingJSForce(false),
    mShutdownDone(false),
-   mIPCOpen(true),
    mPaintWhileInterruptingJSActive(false)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   mContext = danger::GetJSContext();
 
   BackgroundHangMonitor::RegisterAnnotator(*this);
 }
 
@@ -388,18 +381,16 @@ HangMonitorChild::ShutdownOnThread()
   mMonitor.Notify();
 }
 
 void
 HangMonitorChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   MOZ_RELEASE_ASSERT(IsOnThread());
 
-  mIPCOpen = false;
-
   // We use a task here to ensure that IPDL is finished with this
   // HangMonitorChild before it gets deleted on the main thread.
   Dispatch(NewNonOwningRunnableMethod("HangMonitorChild::ShutdownOnThread",
                                       this,
                                       &HangMonitorChild::ShutdownOnThread));
 }
 
 mozilla::ipc::IPCResult
@@ -483,17 +474,17 @@ HangMonitorChild::Bind(Endpoint<PProcess
   MOZ_ASSERT(ok);
 }
 
 void
 HangMonitorChild::NotifySlowScriptAsync(TabId aTabId,
                                         const nsCString& aFileName,
                                         const nsString& aAddonId)
 {
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     Unused << SendHangEvidence(SlowScriptData(aTabId, aFileName, aAddonId));
   }
 }
 
 HangMonitorChild::SlowScriptAction
 HangMonitorChild::NotifySlowScript(nsITabChild* aTabChild,
                                    const char* aFileName,
                                    const nsString& aAddonId)
@@ -569,17 +560,17 @@ HangMonitorChild::NotifyPluginHang(uint3
 }
 
 void
 HangMonitorChild::NotifyPluginHangAsync(uint32_t aPluginId)
 {
   MOZ_RELEASE_ASSERT(IsOnThread());
 
   // bounce back to parent on background thread
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     Unused << SendHangEvidence(PluginHangData(aPluginId,
                                               base::GetCurrentProcId()));
   }
 }
 
 void
 HangMonitorChild::ClearHang()
 {
@@ -601,26 +592,25 @@ HangMonitorChild::ClearHang()
 }
 
 void
 HangMonitorChild::ClearHangAsync()
 {
   MOZ_RELEASE_ASSERT(IsOnThread());
 
   // bounce back to parent on background thread
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     Unused << SendClearHang();
   }
 }
 
 /* HangMonitorParent implementation */
 
 HangMonitorParent::HangMonitorParent(ProcessHangMonitor* aMonitor)
  : mHangMonitor(aMonitor),
-   mIPCOpen(true),
    mMonitor("HangMonitorParent lock"),
    mShutdownDone(false),
    mBrowserCrashDumpHashLock("mBrowserCrashDumpIds lock"),
    mMainThreadTaskFactory(this)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   mReportHangs = mozilla::Preferences::GetBool("dom.ipc.reportProcessHangs", false);
 
@@ -665,20 +655,19 @@ HangMonitorParent::Shutdown()
   }
 }
 
 void
 HangMonitorParent::ShutdownOnThread()
 {
   MOZ_RELEASE_ASSERT(IsOnThread());
 
-  // mIPCOpen is only written from this thread, so need need to take the lock
-  // here. We'd be shooting ourselves in the foot, because ActorDestroy takes
-  // it.
-  if (mIPCOpen) {
+  // Don't take the lock until after IPCOpen() is checked, as the actor lives on
+  // this thread and ActorDestroy will also take a lock.
+  if (IPCOpen()) {
     Close();
   }
 
   MonitorAutoLock lock(mMonitor);
   mShutdownDone = true;
   mMonitor.Notify();
 }
 
@@ -702,26 +691,25 @@ HangMonitorParent::PaintWhileInterruptin
 
 void
 HangMonitorParent::PaintWhileInterruptingJSOnThread(TabId aTabId,
                                                     bool aForceRepaint,
                                                     const LayersObserverEpoch& aEpoch)
 {
   MOZ_RELEASE_ASSERT(IsOnThread());
 
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     Unused << SendPaintWhileInterruptingJS(aTabId, aForceRepaint, aEpoch);
   }
 }
 
 void
 HangMonitorParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   MOZ_RELEASE_ASSERT(IsOnThread());
-  mIPCOpen = false;
 }
 
 void
 HangMonitorParent::Bind(Endpoint<PProcessHangMonitorParent>&& aEndpoint)
 {
   MOZ_RELEASE_ASSERT(IsOnThread());
 
   DebugOnly<bool> ok = aEndpoint.Bind(this);
@@ -854,37 +842,37 @@ HangMonitorParent::RecvClearHang()
   return IPC_OK();
 }
 
 void
 HangMonitorParent::TerminateScript(bool aTerminateGlobal)
 {
   MOZ_RELEASE_ASSERT(IsOnThread());
 
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     Unused << SendTerminateScript(aTerminateGlobal);
   }
 }
 
 void
 HangMonitorParent::BeginStartingDebugger()
 {
   MOZ_RELEASE_ASSERT(IsOnThread());
 
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     Unused << SendBeginStartingDebugger();
   }
 }
 
 void
 HangMonitorParent::EndStartingDebugger()
 {
   MOZ_RELEASE_ASSERT(IsOnThread());
 
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     Unused << SendEndStartingDebugger();
   }
 }
 
 void
 HangMonitorParent::CleanupPluginHang(uint32_t aPluginId, bool aRemoveFiles)
 {
   MutexAutoLock lock(mBrowserCrashDumpHashLock);
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -406,17 +406,16 @@ TabChild::TabChild(nsIContentChild* aMan
   , mTriedBrowserInit(false)
   , mOrientation(hal::eScreenOrientation_PortraitPrimary)
   , mIgnoreKeyPressEvent(false)
   , mHasValidInnerSize(false)
   , mDestroyed(false)
   , mUniqueId(aTabId)
   , mHasSiblings(false)
   , mIsTransparent(false)
-  , mIPCOpen(false)
   , mParentIsActive(false)
   , mDidSetRealShowInfo(false)
   , mDidLoadURLInit(false)
   , mAwaitingLA(false)
   , mSkipKeyPress(false)
   , mLayersObserverEpoch{1}
 #if defined(XP_WIN) && defined(ACCESSIBILITY)
   , mNativeWindowHandle(0)
@@ -622,18 +621,16 @@ TabChild::Init(mozIDOMWindowProxy* aPare
                     bool aPreventDefault)
       {
         if (nsCOMPtr<nsITabChild> tabChild = do_QueryReferent(weakPtrThis)) {
           static_cast<TabChild*>(tabChild.get())->ContentReceivedInputBlock(aGuid, aInputBlockId, aPreventDefault);
         }
       });
   mAPZEventState = new APZEventState(mPuppetWidget, std::move(callback));
 
-  mIPCOpen = true;
-
   // Recording/replaying processes use their own compositor.
   if (recordreplay::IsRecordingOrReplaying()) {
     mPuppetWidget->CreateCompositor();
   }
 
   return NS_OK;
 }
 
@@ -1034,18 +1031,16 @@ TabChild::DestroyWindow()
       }
       mLayersId = layers::LayersId{0};
     }
 }
 
 void
 TabChild::ActorDestroy(ActorDestroyReason why)
 {
-  mIPCOpen = false;
-
   DestroyWindow();
 
   if (mTabChildMessageManager) {
     // We should have a message manager if the global is alive, but it
     // seems sometimes we don't.  Assert in aurora/nightly, but don't
     // crash in release builds.
     MOZ_DIAGNOSTIC_ASSERT(mTabChildMessageManager->GetMessageManager());
     if (mTabChildMessageManager->GetMessageManager()) {
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -583,18 +583,16 @@ public:
   AllocPPaymentRequestChild() override;
 
   virtual bool
   DeallocPPaymentRequestChild(PPaymentRequestChild* aActor) override;
 
   LayoutDeviceIntPoint GetClientOffset() const { return mClientOffset; }
   LayoutDeviceIntPoint GetChromeOffset() const { return mChromeOffset; };
 
-  bool IPCOpen() const { return mIPCOpen; }
-
   bool ParentIsActive() const
   {
     return mParentIsActive;
   }
 
   const mozilla::layers::CompositorOptions& GetCompositorOptions() const;
   bool AsyncPanZoomEnabled() const;
 
@@ -847,17 +845,16 @@ private:
   // Holds the compositor options for the compositor rendering this tab,
   // once we find out which compositor that is.
   Maybe<mozilla::layers::CompositorOptions> mCompositorOptions;
 
   friend class ContentChild;
 
   bool mIsTransparent;
 
-  bool mIPCOpen;
   bool mParentIsActive;
   CSSSize mUnscaledInnerSize;
   bool mDidSetRealShowInfo;
   bool mDidLoadURLInit;
   bool mAwaitingLA;
 
   bool mSkipKeyPress;
 
--- a/dom/ipc/URLClassifierParent.cpp
+++ b/dom/ipc/URLClassifierParent.cpp
@@ -39,22 +39,16 @@ URLClassifierParent::StartClassify(nsIPr
     // This means that code using this in the child process will only get a hit
     // on its callback if some classification actually happens.
     *aSuccess = false;
     ClassificationFailed();
   }
   return IPC_OK();
 }
 
-void
-URLClassifierParent::ActorDestroy(ActorDestroyReason aWhy)
-{
-  mIPCOpen = false;
-}
-
 /////////////////////////////////////////////////////////////////////
 //URLClassifierLocalParent.
 
 NS_IMPL_ISUPPORTS(URLClassifierLocalParent, nsIURIClassifierCallback)
 
 mozilla::ipc::IPCResult
 URLClassifierLocalParent::StartClassify(nsIURI* aURI, const nsACString& aTables)
 {
@@ -74,14 +68,8 @@ URLClassifierLocalParent::StartClassify(
     // Cannot do ClassificationFailed() because the child side
     // is expecting a callback. Only the second parameter will
     // be used, which is the "matched list". We treat "unable
     // to classify" as "not on any list".
     OnClassifyComplete(NS_OK, EmptyCString(), EmptyCString(), EmptyCString());
   }
   return IPC_OK();
 }
-
-void
-URLClassifierLocalParent::ActorDestroy(ActorDestroyReason aWhy)
-{
-  mIPCOpen = false;
-}
--- a/dom/ipc/URLClassifierParent.h
+++ b/dom/ipc/URLClassifierParent.h
@@ -20,70 +20,62 @@ class URLClassifierParentBase : public n
 {
 public:
   // nsIURIClassifierCallback.
   NS_IMETHOD OnClassifyComplete(nsresult aErrorCode,
                                 const nsACString& aList,
                                 const nsACString& aProvider,
                                 const nsACString& aFullHash) override
   {
-    if (mIPCOpen) {
+    if (BaseProtocol::IPCOpen()) {
       ClassifierInfo info = ClassifierInfo(nsCString(aList),
                                            nsCString(aProvider),
                                            nsCString(aFullHash));
       Unused << BaseProtocol::Send__delete__(this, info, aErrorCode);
     }
     return NS_OK;
   }
 
   // Custom.
   void ClassificationFailed()
   {
-    if (mIPCOpen) {
+    if (BaseProtocol::IPCOpen()) {
       Unused << BaseProtocol::Send__delete__(this, void_t(), NS_ERROR_FAILURE);
     }
   }
 
 protected:
   ~URLClassifierParentBase() = default;
-  bool mIPCOpen = true;
 };
 
 //////////////////////////////////////////////////////////////
 // URLClassifierParent
 
 class URLClassifierParent : public URLClassifierParentBase<PURLClassifierParent>
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
   mozilla::ipc::IPCResult StartClassify(nsIPrincipal* aPrincipal,
                                         bool aUseTrackingProtection,
                                         bool* aSuccess);
 private:
   ~URLClassifierParent() = default;
-
-  // Override PURLClassifierParent::ActorDestroy. We seem to unable to
-  // override from the base template class.
-  void ActorDestroy(ActorDestroyReason aWhy) override;
 };
 
 //////////////////////////////////////////////////////////////
 // URLClassifierLocalParent
 
 class URLClassifierLocalParent : public URLClassifierParentBase<PURLClassifierLocalParent>
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
   mozilla::ipc::IPCResult StartClassify(nsIURI* aURI, const nsACString& aTables);
 
 private:
   ~URLClassifierLocalParent() = default;
-
-  // Override PURLClassifierParent::ActorDestroy.
-  void ActorDestroy(ActorDestroyReason aWhy) override;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_URLClassifierParent_h
--- a/dom/network/TCPServerSocketChild.cpp
+++ b/dom/network/TCPServerSocketChild.cpp
@@ -22,28 +22,27 @@ NS_IMPL_CYCLE_COLLECTION(TCPServerSocket
 NS_IMPL_CYCLE_COLLECTING_ADDREF(TCPServerSocketChildBase)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(TCPServerSocketChildBase)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TCPServerSocketChildBase)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 TCPServerSocketChildBase::TCPServerSocketChildBase()
-: mIPCOpen(false)
 {
 }
 
 TCPServerSocketChildBase::~TCPServerSocketChildBase()
 {
 }
 
 NS_IMETHODIMP_(MozExternalRefCountType) TCPServerSocketChild::Release(void)
 {
   nsrefcnt refcnt = TCPServerSocketChildBase::Release();
-  if (refcnt == 1 && mIPCOpen) {
+  if (refcnt == 1 && IPCOpen()) {
     PTCPServerSocketChild::SendRequestDelete();
     return 1;
   }
   return refcnt;
 }
 
 TCPServerSocketChild::TCPServerSocketChild(TCPServerSocket* aServerSocket, uint16_t aLocalPort,
                                            uint16_t aBacklog, bool aUseArrayBuffers,
@@ -55,26 +54,22 @@ TCPServerSocketChild::TCPServerSocketChi
   }
   AddIPDLReference();
   gNeckoChild->SendPTCPServerSocketConstructor(this, aLocalPort, aBacklog, aUseArrayBuffers);
 }
 
 void
 TCPServerSocketChildBase::ReleaseIPDLReference()
 {
-  MOZ_ASSERT(mIPCOpen);
-  mIPCOpen = false;
   this->Release();
 }
 
 void
 TCPServerSocketChildBase::AddIPDLReference()
 {
-  MOZ_ASSERT(!mIPCOpen);
-  mIPCOpen = true;
   this->AddRef();
 }
 
 TCPServerSocketChild::~TCPServerSocketChild()
 {
 }
 
 mozilla::ipc::IPCResult
--- a/dom/network/TCPServerSocketChild.h
+++ b/dom/network/TCPServerSocketChild.h
@@ -29,17 +29,16 @@ public:
   void AddIPDLReference();
   void ReleaseIPDLReference();
 
 protected:
   TCPServerSocketChildBase();
   virtual ~TCPServerSocketChildBase();
 
   RefPtr<TCPServerSocket> mServerSocket;
-  bool mIPCOpen;
 };
 
 class TCPServerSocketChild : public mozilla::net::PTCPServerSocketChild
                            , public TCPServerSocketChildBase
 {
 public:
   NS_IMETHOD_(MozExternalRefCountType) Release() override;
 
--- a/dom/network/TCPServerSocketParent.cpp
+++ b/dom/network/TCPServerSocketParent.cpp
@@ -21,35 +21,30 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(TCPServ
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TCPServerSocketParent)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 void
 TCPServerSocketParent::ReleaseIPDLReference()
 {
-  MOZ_ASSERT(mIPCOpen);
-  mIPCOpen = false;
   this->Release();
 }
 
 void
 TCPServerSocketParent::AddIPDLReference()
 {
-  MOZ_ASSERT(!mIPCOpen);
-  mIPCOpen = true;
   this->AddRef();
 }
 
 TCPServerSocketParent::TCPServerSocketParent(PNeckoParent* neckoParent,
                                              uint16_t aLocalPort,
                                              uint16_t aBacklog,
                                              bool aUseArrayBuffers)
 : mNeckoParent(neckoParent)
-, mIPCOpen(false)
 {
   mServerSocket = new TCPServerSocket(nullptr, aLocalPort, aUseArrayBuffers, aBacklog);
   mServerSocket->SetServerBridgeParent(this);
 }
 
 TCPServerSocketParent::~TCPServerSocketParent()
 {
 }
--- a/dom/network/TCPServerSocketParent.h
+++ b/dom/network/TCPServerSocketParent.h
@@ -43,15 +43,14 @@ private:
   ~TCPServerSocketParent();
 
   nsresult SendCallbackAccept(TCPSocketParent *socket);
 
   virtual void ActorDestroy(ActorDestroyReason why) override;
 
   PNeckoParent* mNeckoParent;
   RefPtr<TCPServerSocket> mServerSocket;
-  bool mIPCOpen;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_TCPServerSocketParent_h
--- a/dom/network/TCPSocketChild.cpp
+++ b/dom/network/TCPSocketChild.cpp
@@ -64,30 +64,29 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
 NS_IMPL_CYCLE_COLLECTING_ADDREF(TCPSocketChildBase)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(TCPSocketChildBase)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TCPSocketChildBase)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 TCPSocketChildBase::TCPSocketChildBase()
-: mIPCOpen(false)
 {
   mozilla::HoldJSObjects(this);
 }
 
 TCPSocketChildBase::~TCPSocketChildBase()
 {
   mozilla::DropJSObjects(this);
 }
 
 NS_IMETHODIMP_(MozExternalRefCountType) TCPSocketChild::Release(void)
 {
   nsrefcnt refcnt = TCPSocketChildBase::Release();
-  if (refcnt == 1 && mIPCOpen) {
+  if (refcnt == 1 && IPCOpen()) {
     PTCPSocketChild::SendRequestDelete();
     return 1;
   }
   return refcnt;
 }
 
 TCPSocketChild::TCPSocketChild(const nsAString& aHost,
                                const uint16_t& aPort,
@@ -133,27 +132,23 @@ TCPSocketChild::SendWindowlessOpenBind(n
                                 nsCString(aLocalHost), aLocalPort,
                                 aUseSSL, aReuseAddrPort,
                                 true, mFilterName);
 }
 
 void
 TCPSocketChildBase::ReleaseIPDLReference()
 {
-  MOZ_ASSERT(mIPCOpen);
-  mIPCOpen = false;
   mSocket = nullptr;
   this->Release();
 }
 
 void
 TCPSocketChildBase::AddIPDLReference()
 {
-  MOZ_ASSERT(!mIPCOpen);
-  mIPCOpen = true;
   this->AddRef();
 }
 
 TCPSocketChild::~TCPSocketChild()
 {
 }
 
 mozilla::ipc::IPCResult
--- a/dom/network/TCPSocketChild.h
+++ b/dom/network/TCPSocketChild.h
@@ -35,17 +35,16 @@ public:
   void AddIPDLReference();
   void ReleaseIPDLReference();
 
 protected:
   TCPSocketChildBase();
   virtual ~TCPSocketChildBase();
 
   nsCOMPtr<nsITCPSocketCallback> mSocket;
-  bool mIPCOpen;
 };
 
 class TCPSocketChild : public mozilla::net::PTCPSocketChild
                      , public TCPSocketChildBase
 {
 public:
   NS_IMETHOD_(MozExternalRefCountType) Release() override;
 
--- a/dom/network/TCPSocketParent.cpp
+++ b/dom/network/TCPSocketParent.cpp
@@ -57,44 +57,39 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION(TCPSocketParentBase, mSocket)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(TCPSocketParentBase)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(TCPSocketParentBase)
 
 TCPSocketParentBase::TCPSocketParentBase()
-: mIPCOpen(false)
 {
 }
 
 TCPSocketParentBase::~TCPSocketParentBase()
 {
 }
 
 void
 TCPSocketParentBase::ReleaseIPDLReference()
 {
-  MOZ_ASSERT(mIPCOpen);
-  mIPCOpen = false;
   this->Release();
 }
 
 void
 TCPSocketParentBase::AddIPDLReference()
 {
-  MOZ_ASSERT(!mIPCOpen);
-  mIPCOpen = true;
   this->AddRef();
 }
 
 NS_IMETHODIMP_(MozExternalRefCountType) TCPSocketParent::Release(void)
 {
   nsrefcnt refcnt = TCPSocketParentBase::Release();
-  if (refcnt == 1 && mIPCOpen) {
+  if (refcnt == 1 && IPCOpen()) {
     mozilla::Unused << PTCPSocketParent::SendRequestDelete();
     return 1;
   }
   return refcnt;
 }
 
 mozilla::ipc::IPCResult
 TCPSocketParent::RecvOpen(const nsString& aHost, const uint16_t& aPort, const bool& aUseSSL,
@@ -325,17 +320,17 @@ TCPSocketParent::FireStringDataEvent(con
   MOZ_ASSERT(!mFilter, "Socket filtering doesn't support nsCString");
 
   SendEvent(NS_LITERAL_STRING("data"), data, aReadyState);
 }
 
 void
 TCPSocketParent::SendEvent(const nsAString& aType, CallbackData aData, TCPReadyState aReadyState)
 {
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     mozilla::Unused << PTCPSocketParent::SendCallback(nsString(aType),
                                                       aData,
                                                       static_cast<uint32_t>(aReadyState));
   }
 }
 
 void
 TCPSocketParent::SetSocket(TCPSocket *socket)
--- a/dom/network/TCPSocketParent.h
+++ b/dom/network/TCPSocketParent.h
@@ -31,17 +31,16 @@ public:
   void AddIPDLReference();
   void ReleaseIPDLReference();
 
 protected:
   TCPSocketParentBase();
   virtual ~TCPSocketParentBase();
 
   RefPtr<TCPSocket> mSocket;
-  bool mIPCOpen;
 };
 
 class TCPSocketParent : public mozilla::net::PTCPSocketParent
                       , public TCPSocketParentBase
 {
 public:
   NS_IMETHOD_(MozExternalRefCountType) Release() override;
 
--- a/dom/network/UDPSocketChild.cpp
+++ b/dom/network/UDPSocketChild.cpp
@@ -18,45 +18,40 @@
 using mozilla::net::gNeckoChild;
 
 namespace mozilla {
 namespace dom {
 
 NS_IMPL_ISUPPORTS(UDPSocketChildBase, nsIUDPSocketChild)
 
 UDPSocketChildBase::UDPSocketChildBase()
-: mIPCOpen(false)
 {
 }
 
 UDPSocketChildBase::~UDPSocketChildBase()
 {
 }
 
 void
 UDPSocketChildBase::ReleaseIPDLReference()
 {
-  MOZ_ASSERT(mIPCOpen);
-  mIPCOpen = false;
   mSocket = nullptr;
   this->Release();
 }
 
 void
 UDPSocketChildBase::AddIPDLReference()
 {
-  MOZ_ASSERT(!mIPCOpen);
-  mIPCOpen = true;
   this->AddRef();
 }
 
 NS_IMETHODIMP_(MozExternalRefCountType) UDPSocketChild::Release(void)
 {
   nsrefcnt refcnt = UDPSocketChildBase::Release();
-  if (refcnt == 1 && mIPCOpen) {
+  if (refcnt == 1 && IPCOpen()) {
     PUDPSocketChild::SendRequestDelete();
     return 1;
   }
   return refcnt;
 }
 
 UDPSocketChild::UDPSocketChild()
 :mBackgroundManager(nullptr)
--- a/dom/network/UDPSocketChild.h
+++ b/dom/network/UDPSocketChild.h
@@ -24,17 +24,16 @@ public:
 
   void AddIPDLReference();
   void ReleaseIPDLReference();
 
 protected:
   UDPSocketChildBase();
   virtual ~UDPSocketChildBase();
   nsCOMPtr<nsIUDPSocketInternal> mSocket;
-  bool mIPCOpen;
 };
 
 class UDPSocketChild : public mozilla::net::PUDPSocketChild
                      , public UDPSocketChildBase
 {
 public:
   NS_DECL_NSIUDPSOCKETCHILD
   NS_IMETHOD_(MozExternalRefCountType) Release() override;
--- a/dom/network/UDPSocketParent.cpp
+++ b/dom/network/UDPSocketParent.cpp
@@ -25,23 +25,21 @@ namespace mozilla {
 using namespace net;
 
 namespace dom {
 
 NS_IMPL_ISUPPORTS(UDPSocketParent, nsIUDPSocketListener)
 
 UDPSocketParent::UDPSocketParent(PBackgroundParent* aManager)
   : mBackgroundManager(aManager)
-  , mIPCOpen(true)
 {
 }
 
 UDPSocketParent::UDPSocketParent(PNeckoParent* aManager)
   : mBackgroundManager(nullptr)
-  , mIPCOpen(true)
 {
 }
 
 UDPSocketParent::~UDPSocketParent()
 {
 }
 
 bool
@@ -505,31 +503,29 @@ UDPSocketParent::RecvRequestDelete()
 {
   mozilla::Unused << Send__delete__(this);
   return IPC_OK();
 }
 
 void
 UDPSocketParent::ActorDestroy(ActorDestroyReason why)
 {
-  MOZ_ASSERT(mIPCOpen);
-  mIPCOpen = false;
   if (mSocket) {
     mSocket->Close();
   }
   mSocket = nullptr;
 }
 
 // nsIUDPSocketListener
 
 NS_IMETHODIMP
 UDPSocketParent::OnPacketReceived(nsIUDPSocket* aSocket, nsIUDPMessage* aMessage)
 {
   // receiving packet from remote host, forward the message content to child process
-  if (!mIPCOpen) {
+  if (!IPCOpen()) {
     return NS_OK;
   }
 
   uint16_t port;
   nsCString ip;
   nsCOMPtr<nsINetAddr> fromAddr;
   aMessage->GetFromAddr(getter_AddRefs(fromAddr));
   fromAddr->GetPort(&port);
@@ -572,26 +568,26 @@ UDPSocketParent::OnPacketReceived(nsIUDP
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 UDPSocketParent::OnStopListening(nsIUDPSocket* aSocket, nsresult aStatus)
 {
   // underlying socket is dead, send state update to child process
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     mozilla::Unused << SendCallbackClosed();
   }
   return NS_OK;
 }
 
 void
 UDPSocketParent::FireInternalError(uint32_t aLineNo)
 {
-  if (!mIPCOpen) {
+  if (!IPCOpen()) {
     return;
   }
 
   mozilla::Unused << SendCallbackError(NS_LITERAL_CSTRING("Internal error"),
                                        NS_LITERAL_CSTRING(__FILE__), aLineNo);
 }
 
 void
--- a/dom/network/UDPSocketParent.h
+++ b/dom/network/UDPSocketParent.h
@@ -65,17 +65,16 @@ private:
                         const uint32_t& sendBufferSize);
   nsresult ConnectInternal(const nsCString& aHost, const uint16_t& aPort);
   void FireInternalError(uint32_t aLineNo);
   void SendInternalError(nsIEventTarget *aThread,
                          uint32_t aLineNo);
 
   PBackgroundParent* mBackgroundManager;
 
-  bool mIPCOpen;
   nsCOMPtr<nsIUDPSocket> mSocket;
   nsCOMPtr<nsISocketFilter> mFilter;
   nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/storage/StorageIPC.cpp
+++ b/dom/storage/StorageIPC.cpp
@@ -124,33 +124,28 @@ private:
   {
     MOZ_ASSERT(NS_IsMainThread());
   }
 };
 
 void
 StorageDBChild::AddIPDLReference()
 {
-  MOZ_ASSERT(!mIPCOpen, "Attempting to retain multiple IPDL references");
-  mIPCOpen = true;
   AddRef();
 }
 
 void
 StorageDBChild::ReleaseIPDLReference()
 {
-  MOZ_ASSERT(mIPCOpen, "Attempting to release non-existent IPDL reference");
-  mIPCOpen = false;
   Release();
 }
 
 StorageDBChild::StorageDBChild(LocalStorageManager* aManager)
   : mManager(aManager)
   , mStatus(NS_OK)
-  , mIPCOpen(false)
 {
 }
 
 StorageDBChild::~StorageDBChild()
 {
 }
 
 // static
@@ -243,45 +238,45 @@ StorageDBChild::Shutdown()
   // the actual thread running on the parent process will also stop
   // automatically in profile-before-change topic observer.
   return NS_OK;
 }
 
 void
 StorageDBChild::AsyncPreload(LocalStorageCacheBridge* aCache, bool aPriority)
 {
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     // Adding ref to cache for the time of preload.  This ensures a reference to
     // to the cache and that all keys will load into this cache object.
     mLoadingCaches.PutEntry(aCache);
     SendAsyncPreload(aCache->OriginSuffix(), aCache->OriginNoSuffix(),
                      aPriority);
   } else {
     // No IPC, no love.  But the LoadDone call is expected.
     aCache->LoadDone(NS_ERROR_UNEXPECTED);
   }
 }
 
 void
 StorageDBChild::AsyncGetUsage(StorageUsageBridge* aUsage)
 {
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     SendAsyncGetUsage(aUsage->OriginScope());
   }
 }
 
 void
 StorageDBChild::SyncPreload(LocalStorageCacheBridge* aCache, bool aForceSync)
 {
   if (NS_FAILED(mStatus)) {
     aCache->LoadDone(mStatus);
     return;
   }
 
-  if (!mIPCOpen) {
+  if (!IPCOpen()) {
     aCache->LoadDone(NS_ERROR_UNEXPECTED);
     return;
   }
 
   // There is no way to put the child process to a wait state to receive all
   // incoming async responses from the parent, hence we have to do a sync
   // preload instead.  We are smart though, we only demand keys that are left to
   // load in case the async preload has already loaded some keys.
@@ -297,58 +292,58 @@ StorageDBChild::SyncPreload(LocalStorage
   aCache->LoadDone(rv);
 }
 
 nsresult
 StorageDBChild::AsyncAddItem(LocalStorageCacheBridge* aCache,
                              const nsAString& aKey,
                              const nsAString& aValue)
 {
-  if (NS_FAILED(mStatus) || !mIPCOpen) {
+  if (NS_FAILED(mStatus) || !IPCOpen()) {
     return mStatus;
   }
 
   SendAsyncAddItem(aCache->OriginSuffix(), aCache->OriginNoSuffix(),
                    nsString(aKey), nsString(aValue));
   OriginsHavingData().PutEntry(aCache->Origin());
   return NS_OK;
 }
 
 nsresult
 StorageDBChild::AsyncUpdateItem(LocalStorageCacheBridge* aCache,
                                 const nsAString& aKey,
                                 const nsAString& aValue)
 {
-  if (NS_FAILED(mStatus) || !mIPCOpen) {
+  if (NS_FAILED(mStatus) || !IPCOpen()) {
     return mStatus;
   }
 
   SendAsyncUpdateItem(aCache->OriginSuffix(), aCache->OriginNoSuffix(),
                       nsString(aKey), nsString(aValue));
   OriginsHavingData().PutEntry(aCache->Origin());
   return NS_OK;
 }
 
 nsresult
 StorageDBChild::AsyncRemoveItem(LocalStorageCacheBridge* aCache,
                                 const nsAString& aKey)
 {
-  if (NS_FAILED(mStatus) || !mIPCOpen) {
+  if (NS_FAILED(mStatus) || !IPCOpen()) {
     return mStatus;
   }
 
   SendAsyncRemoveItem(aCache->OriginSuffix(), aCache->OriginNoSuffix(),
                       nsString(aKey));
   return NS_OK;
 }
 
 nsresult
 StorageDBChild::AsyncClear(LocalStorageCacheBridge* aCache)
 {
-  if (NS_FAILED(mStatus) || !mIPCOpen) {
+  if (NS_FAILED(mStatus) || !IPCOpen()) {
     return mStatus;
   }
 
   SendAsyncClear(aCache->OriginSuffix(), aCache->OriginNoSuffix());
   OriginsHavingData().RemoveEntry(aCache->Origin());
   return NS_OK;
 }
 
@@ -602,36 +597,31 @@ private:
 };
 
 NS_IMPL_ADDREF(StorageDBParent)
 NS_IMPL_RELEASE(StorageDBParent)
 
 void
 StorageDBParent::AddIPDLReference()
 {
-  MOZ_ASSERT(!mIPCOpen, "Attempting to retain multiple IPDL references");
-  mIPCOpen = true;
   AddRef();
 }
 
 void
 StorageDBParent::ReleaseIPDLReference()
 {
-  MOZ_ASSERT(mIPCOpen, "Attempting to release non-existent IPDL reference");
-  mIPCOpen = false;
   Release();
 }
 
 namespace {
 
 } // namespace
 
 StorageDBParent::StorageDBParent(const nsString& aProfilePath)
   : mProfilePath(aProfilePath)
-  , mIPCOpen(false)
 {
   AssertIsOnBackgroundThread();
 
   // We are always open by IPC only
   AddIPDLReference();
 }
 
 StorageDBParent::~StorageDBParent()
@@ -839,17 +829,17 @@ StorageDBParent::RecvAsyncAddItem(const 
   if (!storageThread) {
     return IPC_FAIL_NO_REASON(this);
   }
 
   nsresult rv =
     storageThread->AsyncAddItem(NewCache(aOriginSuffix, aOriginNoSuffix),
                                 aKey,
                                 aValue);
-  if (NS_FAILED(rv) && mIPCOpen) {
+  if (NS_FAILED(rv) && IPCOpen()) {
     mozilla::Unused << SendError(rv);
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 StorageDBParent::RecvAsyncUpdateItem(const nsCString& aOriginSuffix,
@@ -861,17 +851,17 @@ StorageDBParent::RecvAsyncUpdateItem(con
   if (!storageThread) {
     return IPC_FAIL_NO_REASON(this);
   }
 
   nsresult rv =
     storageThread->AsyncUpdateItem(NewCache(aOriginSuffix, aOriginNoSuffix),
                                    aKey,
                                    aValue);
-  if (NS_FAILED(rv) && mIPCOpen) {
+  if (NS_FAILED(rv) && IPCOpen()) {
     mozilla::Unused << SendError(rv);
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 StorageDBParent::RecvAsyncRemoveItem(const nsCString& aOriginSuffix,
@@ -881,17 +871,17 @@ StorageDBParent::RecvAsyncRemoveItem(con
   StorageDBThread* storageThread = StorageDBThread::GetOrCreate(mProfilePath);
   if (!storageThread) {
     return IPC_FAIL_NO_REASON(this);
   }
 
   nsresult rv =
     storageThread->AsyncRemoveItem(NewCache(aOriginSuffix, aOriginNoSuffix),
                                    aKey);
-  if (NS_FAILED(rv) && mIPCOpen) {
+  if (NS_FAILED(rv) && IPCOpen()) {
     mozilla::Unused << SendError(rv);
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 StorageDBParent::RecvAsyncClear(const nsCString& aOriginSuffix,
@@ -899,17 +889,17 @@ StorageDBParent::RecvAsyncClear(const ns
 {
   StorageDBThread* storageThread = StorageDBThread::GetOrCreate(mProfilePath);
   if (!storageThread) {
     return IPC_FAIL_NO_REASON(this);
   }
 
   nsresult rv =
     storageThread->AsyncClear(NewCache(aOriginSuffix, aOriginNoSuffix));
-  if (NS_FAILED(rv) && mIPCOpen) {
+  if (NS_FAILED(rv) && IPCOpen()) {
     mozilla::Unused << SendError(rv);
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 StorageDBParent::RecvAsyncFlush()
@@ -975,17 +965,17 @@ StorageDBParent::RecvClearMatchingOrigin
   return IPC_OK();
 }
 
 void
 StorageDBParent::Observe(const nsCString& aTopic,
                          const nsString& aOriginAttributesPattern,
                          const nsCString& aOriginScope)
 {
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     mozilla::Unused <<
       SendObserve(aTopic, aOriginAttributesPattern, aOriginScope);
   }
 }
 
 namespace {
 
 // Results must be sent back on the main thread
--- a/dom/storage/StorageIPC.h
+++ b/dom/storage/StorageIPC.h
@@ -173,18 +173,16 @@ private:
   nsAutoPtr<nsTHashtable<nsCStringHashKey>> mOriginsHavingData;
 
   // List of caches waiting for preload.  This ensures the contract that
   // AsyncPreload call references the cache for time of the preload.
   nsTHashtable<nsRefPtrHashKey<LocalStorageCacheBridge>> mLoadingCaches;
 
   // Status of the remote database
   nsresult mStatus;
-
-  bool mIPCOpen;
 };
 
 class LocalStorageCacheParent final
   : public PBackgroundLocalStorageCacheParent
 {
   const PrincipalInfo mPrincipalInfo;
   const nsCString mOriginKey;
   uint32_t mPrivateBrowsingId;
@@ -234,18 +232,16 @@ public:
   Init();
 
   NS_IMETHOD_(MozExternalRefCountType) AddRef(void);
   NS_IMETHOD_(MozExternalRefCountType) Release(void);
 
   void AddIPDLReference();
   void ReleaseIPDLReference();
 
-  bool IPCOpen() { return mIPCOpen; }
-
 public:
   // Fake cache class receiving async callbacks from DB thread, sending
   // them back to appropriate cache object on the child process.
   class CacheParentBridge : public LocalStorageCacheBridge {
   public:
     CacheParentBridge(StorageDBParent* aParentDB,
                       const nsACString& aOriginSuffix,
                       const nsACString& aOriginNoSuffix)
@@ -362,19 +358,16 @@ private:
   // background thread when invoking StorageDBThread::GetOrCreate because it
   // cannot safely perform a synchronous dispatch back to the main thread
   // (because we are already synchronously doing things on the stack).
   // Populated for the same process actors, empty for other process actors.
   nsString mProfilePath;
 
   ThreadSafeAutoRefCnt mRefCnt;
   NS_DECL_OWNINGTHREAD
-
-  // True when IPC channel is open and Send*() methods are OK to use.
-  bool mIPCOpen;
 };
 
 PBackgroundLocalStorageCacheParent*
 AllocPBackgroundLocalStorageCacheParent(
                               const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
                               const nsCString& aOriginKey,
                               const uint32_t& aPrivateBrowsingId);
 
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -101,49 +101,32 @@ public:
 
   TextureChild()
   : mCompositableForwarder(nullptr)
   , mTextureForwarder(nullptr)
   , mTextureClient(nullptr)
   , mTextureData(nullptr)
   , mDestroyed(false)
   , mMainThreadOnly(false)
-  , mIPCOpen(false)
   , mOwnsTextureData(false)
   , mOwnerCalledDestroy(false)
   {}
 
   mozilla::ipc::IPCResult Recv__delete__() override { return IPC_OK(); }
 
   LayersIPCChannel* GetAllocator() { return mTextureForwarder; }
 
   void ActorDestroy(ActorDestroyReason why) override;
 
-  bool IPCOpen() const { return mIPCOpen; }
-
   void Lock() const { if (mCompositableForwarder && mCompositableForwarder->GetTextureForwarder()->UsesImageBridge()) { mLock.Enter(); } }
 
   void Unlock() const { if (mCompositableForwarder && mCompositableForwarder->GetTextureForwarder()->UsesImageBridge()) { mLock.Leave(); } }
 
 private:
 
-  // AddIPDLReference and ReleaseIPDLReference are only to be called by CreateIPDLActor
-  // and DestroyIPDLActor, respectively. We intentionally make them private to prevent misuse.
-  // The purpose of these methods is to be aware of when the IPC system around this
-  // actor goes down: mIPCOpen is then set to false.
-  void AddIPDLReference() {
-    MOZ_ASSERT(mIPCOpen == false);
-    mIPCOpen = true;
-    AddRef();
-  }
-  void ReleaseIPDLReference() {
-    MOZ_ASSERT(mIPCOpen == false);
-    Release();
-  }
-
   /// The normal way to destroy the actor.
   ///
   /// This will asynchronously send a Destroy message to the parent actor, whom
   /// will send the delete message.
   void Destroy(const TextureDeallocParams& aParams);
 
   // This lock is used order to prevent several threads to access the
   // TextureClient's data concurrently. In particular, it prevents shutdown
@@ -212,17 +195,16 @@ private:
 
   RefPtr<CompositableForwarder> mCompositableForwarder;
   RefPtr<TextureForwarder> mTextureForwarder;
 
   TextureClient* mTextureClient;
   TextureData* mTextureData;
   Atomic<bool> mDestroyed;
   bool mMainThreadOnly;
-  bool mIPCOpen;
   bool mOwnsTextureData;
   bool mOwnerCalledDestroy;
 
   friend class TextureClient;
   friend void DeallocateTextureClient(TextureDeallocParams params);
 };
 
 
@@ -250,18 +232,16 @@ static void DestroyTextureData(TextureDa
   }
   delete aTextureData;
 }
 
 void
 TextureChild::ActorDestroy(ActorDestroyReason why)
 {
   AUTO_PROFILER_LABEL("TextureChild::ActorDestroy", GRAPHICS);
-  MOZ_ASSERT(mIPCOpen);
-  mIPCOpen = false;
 
   if (mTextureData) {
     DestroyTextureData(mTextureData, GetAllocator(), mOwnsTextureData, mMainThreadOnly);
     mTextureData = nullptr;
   }
 }
 
 void
@@ -739,26 +719,25 @@ TextureClient::ToSurfaceDescriptor(Surfa
 
   return mData ? mData->Serialize(aOutDescriptor) : false;
 }
 
 // static
 PTextureChild*
 TextureClient::CreateIPDLActor()
 {
-  TextureChild* c = new TextureChild();
-  c->AddIPDLReference();
-  return c;
+  RefPtr<TextureChild> c = new TextureChild();
+  return c.forget().take();
 }
 
 // static
 bool
 TextureClient::DestroyIPDLActor(PTextureChild* actor)
 {
-  static_cast<TextureChild*>(actor)->ReleaseIPDLReference();
+  RefPtr<TextureChild> tc = dont_AddRef(static_cast<TextureChild*>(actor));
   return true;
 }
 
 // static
 already_AddRefed<TextureClient>
 TextureClient::AsTextureClient(PTextureChild* actor)
 {
   if (!actor) {
--- a/gfx/layers/ipc/LayerTransactionChild.h
+++ b/gfx/layers/ipc/LayerTransactionChild.h
@@ -28,55 +28,51 @@ public:
    * to be sent from the parent side.
    *
    * It is expected (checked with an assert) that all shadow layers
    * created by this have already been destroyed and
    * Send__delete__()d by the time this method is called.
    */
   void Destroy();
 
-  bool IPCOpen() const { return mIPCOpen && !mDestroyed; }
+  bool IPCOpen() const {
+    return mozilla::ipc::IProtocol::IPCOpen() && !mDestroyed;
+  }
   bool IsDestroyed() const { return mDestroyed; }
 
   void SetForwarder(ShadowLayerForwarder* aForwarder)
   {
     mForwarder = aForwarder;
   }
 
   LayersId GetId() const { return mId; }
 
   void MarkDestroyed() {
     mDestroyed = true;
   }
 
 protected:
   explicit LayerTransactionChild(const LayersId& aId)
     : mForwarder(nullptr)
-    , mIPCOpen(false)
     , mDestroyed(false)
     , mId(aId)
   {}
   ~LayerTransactionChild() { }
 
   void ActorDestroy(ActorDestroyReason why) override;
 
   void AddIPDLReference() {
-    MOZ_ASSERT(mIPCOpen == false);
-    mIPCOpen = true;
     AddRef();
   }
   void ReleaseIPDLReference() {
-    MOZ_ASSERT(mIPCOpen == true);
-    mIPCOpen = false;
     Release();
   }
   friend class CompositorBridgeChild;
 
   ShadowLayerForwarder* mForwarder;
-  bool mIPCOpen;
   bool mDestroyed;
   LayersId mId;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // MOZILLA_LAYERS_LAYERTRANSACTIONCHILD_H
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -53,17 +53,16 @@ LayerTransactionParent::LayerTransaction
   , mCompositorBridge(aBridge)
   , mAnimStorage(aAnimStorage)
   , mId(aId)
   , mChildEpoch{0}
   , mParentEpoch{0}
   , mVsyncRate(aVsyncRate)
   , mPendingTransaction{0}
   , mDestroyed(false)
-  , mIPCOpen(false)
   , mUpdateHitTestingTree(false)
 {
   MOZ_ASSERT(mId.IsValid());
 }
 
 LayerTransactionParent::~LayerTransactionParent()
 {
 }
@@ -879,38 +878,38 @@ LayerTransactionParent::ActorDestroy(Act
   Destroy();
 }
 
 bool
 LayerTransactionParent::AllocShmem(size_t aSize,
                                    ipc::SharedMemory::SharedMemoryType aType,
                                    ipc::Shmem* aShmem)
 {
-  if (!mIPCOpen || mDestroyed) {
+  if (!IPCOpen() || mDestroyed) {
     return false;
   }
   return PLayerTransactionParent::AllocShmem(aSize, aType, aShmem);
 }
 
 bool
 LayerTransactionParent::AllocUnsafeShmem(size_t aSize,
                                          ipc::SharedMemory::SharedMemoryType aType,
                                          ipc::Shmem* aShmem)
 {
-  if (!mIPCOpen || mDestroyed) {
+  if (!IPCOpen() || mDestroyed) {
     return false;
   }
 
   return PLayerTransactionParent::AllocUnsafeShmem(aSize, aType, aShmem);
 }
 
 void
 LayerTransactionParent::DeallocShmem(ipc::Shmem& aShmem)
 {
-  if (!mIPCOpen || mDestroyed) {
+  if (!IPCOpen() || mDestroyed) {
     return;
   }
   PLayerTransactionParent::DeallocShmem(aShmem);
 }
 
 bool LayerTransactionParent::IsSameProcess() const
 {
   return OtherPid() == base::GetCurrentProcId();
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -52,16 +52,18 @@ protected:
 public:
   void Destroy();
 
   void SetLayerManager(HostLayerManager* aLayerManager, CompositorAnimationStorage* aAnimStorage);
 
   LayersId GetId() const { return mId; }
   Layer* GetRoot() const { return mRoot; }
 
+  bool IPCOpen() const override { return mozilla::ipc::IProtocol::IPCOpen(); }
+
   LayersObserverEpoch GetChildEpoch() const { return mChildEpoch; }
   bool ShouldParentObserveEpoch();
 
   ShmemAllocator* AsShmemAllocator() override { return this; }
 
   bool AllocShmem(size_t aSize,
                   ipc::SharedMemory::SharedMemoryType aType,
                   ipc::Shmem* aShmem) override;
@@ -149,23 +151,19 @@ protected:
 
   bool BindLayerToHandle(RefPtr<Layer> aLayer, const LayerHandle& aHandle);
 
   Layer* AsLayer(const LayerHandle& aLayer);
 
   bool Attach(Layer* aLayer, CompositableHost* aCompositable, bool aIsAsyncVideo);
 
   void AddIPDLReference() {
-    MOZ_ASSERT(mIPCOpen == false);
-    mIPCOpen = true;
     AddRef();
   }
   void ReleaseIPDLReference() {
-    MOZ_ASSERT(mIPCOpen == true);
-    mIPCOpen = false;
     Release();
   }
   friend class CompositorBridgeParent;
   friend class CrossProcessCompositorBridgeParent;
 
 private:
   // This is a function so we can log or breakpoint on why hit
   // testing tree changes are made.
@@ -212,17 +210,16 @@ private:
   // because they refer to "zombie layers" on this side.  So, we track
   // that state with |mDestroyed|.  This is similar to, but separate
   // from, |mLayerManager->IsDestroyed()|; we might have had Destroy()
   // called on us but the mLayerManager might not be destroyed, or
   // vice versa.  In both cases though, we want to ignore shadow-layer
   // transactions posted by the child.
 
   bool mDestroyed;
-  bool mIPCOpen;
 
   // This is set during RecvUpdate to track whether we'll need to update
   // APZ's hit test regions.
   bool mUpdateHitTestingTree;
 };
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -24,17 +24,16 @@ using namespace mozilla::gfx;
 
 WebRenderBridgeChild::WebRenderBridgeChild(const wr::PipelineId& aPipelineId)
   : mIsInTransaction(false)
   , mIsInClearCachedResources(false)
   , mIdNamespace{0}
   , mResourceId(0)
   , mPipelineId(aPipelineId)
   , mManager(nullptr)
-  , mIPCOpen(false)
   , mDestroyed(false)
   , mFontKeysDeleted(0)
   , mFontInstanceKeysDeleted(0)
 {
 }
 
 WebRenderBridgeChild::~WebRenderBridgeChild()
 {
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -108,17 +108,19 @@ public:
   /// It is used for recycling TextureClient.
   void ReleaseTextureOfImage(const wr::ImageKey& aKey);
 
   /**
    * Clean this up, finishing with SendShutDown() which will cause __delete__
    * to be sent from the parent side.
    */
   void Destroy(bool aIsSync);
-  bool IPCOpen() const { return mIPCOpen && !mDestroyed; }
+  bool IPCOpen() const {
+    return mozilla::ipc::IProtocol::IPCOpen() && !mDestroyed;
+  }
   bool IsDestroyed() const { return mDestroyed; }
 
   uint32_t GetNextResourceId() { return ++mResourceId; }
   wr::IdNamespace GetNamespace() { return mIdNamespace; }
   void SetNamespace(wr::IdNamespace aIdNamespace)
   {
     mIdNamespace = aIdNamespace;
   }
@@ -208,39 +210,34 @@ private:
 
   void DoDestroy();
 
   mozilla::ipc::IPCResult RecvWrUpdated(const wr::IdNamespace& aNewIdNamespace,
                                         const TextureFactoryIdentifier& textureFactoryIdentifier) override;
   mozilla::ipc::IPCResult RecvWrReleasedImages(nsTArray<wr::ExternalImageKeyPair>&& aPairs) override;
 
   void AddIPDLReference() {
-    MOZ_ASSERT(mIPCOpen == false);
-    mIPCOpen = true;
     AddRef();
   }
   void ReleaseIPDLReference() {
-    MOZ_ASSERT(mIPCOpen == true);
-    mIPCOpen = false;
     Release();
   }
 
   bool AddOpDestroy(const OpDestroy& aOp);
 
   nsTArray<WebRenderParentCommand> mParentCommands;
   nsTArray<OpDestroy> mDestroyedActors;
   nsDataHashtable<nsUint64HashKey, CompositableClient*> mCompositables;
   bool mIsInTransaction;
   bool mIsInClearCachedResources;
   wr::IdNamespace mIdNamespace;
   uint32_t mResourceId;
   wr::PipelineId mPipelineId;
   WebRenderLayerManager* mManager;
 
-  bool mIPCOpen;
   bool mDestroyed;
 
   uint32_t mFontKeysDeleted;
   nsDataHashtable<UnscaledFontHashKey, wr::FontKey> mFontKeys;
 
   uint32_t mFontInstanceKeysDeleted;
   nsDataHashtable<ScaledFontHashKey, wr::FontInstanceKey> mFontInstanceKeys;
 
--- a/gfx/vr/ipc/VRLayerChild.cpp
+++ b/gfx/vr/ipc/VRLayerChild.cpp
@@ -15,17 +15,16 @@
 #include "mozilla/dom/HTMLCanvasElement.h"
 #include "mozilla/layers/SyncObject.h" // for SyncObjectClient
 
 namespace mozilla {
 namespace gfx {
 
 VRLayerChild::VRLayerChild()
   : mCanvasElement(nullptr)
-  , mIPCOpen(false)
   , mLastSubmittedFrameId(0)
 {
   MOZ_COUNT_CTOR(VRLayerChild);
 }
 
 VRLayerChild::~VRLayerChild()
 {
   ClearSurfaces();
@@ -107,32 +106,26 @@ VRLayerChild::SubmitFrame(const VRDispla
   }
 
   SendSubmitFrame(desc, frameId, mLeftEyeRect, mRightEyeRect);
 }
 
 bool
 VRLayerChild::IsIPCOpen()
 {
-  return mIPCOpen;
+  return IPCOpen();
 }
 
 void
 VRLayerChild::ClearSurfaces()
 {
   mThisFrameTexture = nullptr;
   mLastFrameTexture = nullptr;
 }
 
-void
-VRLayerChild::ActorDestroy(ActorDestroyReason aWhy)
-{
-  mIPCOpen = false;
-}
-
 // static
 PVRLayerChild*
 VRLayerChild::CreateIPDLActor()
 {
   VRLayerChild* c = new VRLayerChild();
   c->AddIPDLReference();
   return c;
 }
@@ -142,20 +135,17 @@ bool
 VRLayerChild::DestroyIPDLActor(PVRLayerChild* actor)
 {
   static_cast<VRLayerChild*>(actor)->ReleaseIPDLReference();
   return true;
 }
 
 void
 VRLayerChild::AddIPDLReference() {
-  MOZ_ASSERT(mIPCOpen == false);
-  mIPCOpen = true;
   AddRef();
 }
 void
 VRLayerChild::ReleaseIPDLReference() {
-  MOZ_ASSERT(mIPCOpen == false);
   Release();
 }
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/vr/ipc/VRLayerChild.h
+++ b/gfx/vr/ipc/VRLayerChild.h
@@ -39,20 +39,18 @@ public:
                   const gfx::Rect& aLeftEyeRect, const gfx::Rect& aRightEyeRect);
   void SubmitFrame(const VRDisplayInfo& aDisplayInfo);
   bool IsIPCOpen();
 
 private:
   VRLayerChild();
   virtual ~VRLayerChild();
   void ClearSurfaces();
-  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   RefPtr<dom::HTMLCanvasElement> mCanvasElement;
-  bool mIPCOpen;
 
   // AddIPDLReference and ReleaseIPDLReference are only to be called by CreateIPDLActor
   // and DestroyIPDLActor, respectively. We intentionally make them private to prevent misuse.
   // The purpose of these methods is to be aware of when the IPC system around this
   // actor goes down: mIPCOpen is then set to false.
   void AddIPDLReference();
   void ReleaseIPDLReference();
 
--- a/gfx/vr/ipc/VRLayerParent.cpp
+++ b/gfx/vr/ipc/VRLayerParent.cpp
@@ -10,18 +10,17 @@
 #include "VRDisplayHost.h"
 #include "mozilla/layers/CompositorThread.h"
 
 namespace mozilla {
 using namespace layers;
 namespace gfx {
 
 VRLayerParent::VRLayerParent(uint32_t aVRDisplayID, const uint32_t aGroup)
-  : mIPCOpen(true)
-  , mVRDisplayID(aVRDisplayID)
+  : mVRDisplayID(aVRDisplayID)
   , mGroup(aGroup)
 {
 }
 
 VRLayerParent::~VRLayerParent()
 {
   MOZ_COUNT_DTOR(VRLayerParent);
 }
@@ -29,36 +28,30 @@ VRLayerParent::~VRLayerParent()
 mozilla::ipc::IPCResult
 VRLayerParent::RecvDestroy()
 {
   Destroy();
   return IPC_OK();
 }
 
 void
-VRLayerParent::ActorDestroy(ActorDestroyReason aWhy)
-{
-  mIPCOpen = false;
-}
-
-void
 VRLayerParent::Destroy()
 {
   if (mVRDisplayID) {
     VRManager* vm = VRManager::Get();
     RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(mVRDisplayID);
     if (display) {
       display->RemoveLayer(this);
     }
     // 0 will never be a valid VRDisplayID; we can use it to indicate that
     // we are destroyed and no longer associated with a display.
     mVRDisplayID = 0;
   }
 
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     Unused << PVRLayerParent::Send__delete__(this);
   }
 }
 
 mozilla::ipc::IPCResult
 VRLayerParent::RecvSubmitFrame(const layers::SurfaceDescriptor &aTexture,
                                const uint64_t& aFrameId,
                                const gfx::Rect& aLeftEyeRect,
--- a/gfx/vr/ipc/VRLayerParent.h
+++ b/gfx/vr/ipc/VRLayerParent.h
@@ -24,23 +24,19 @@ public:
   virtual mozilla::ipc::IPCResult RecvSubmitFrame(const layers::SurfaceDescriptor &aTexture,
                                                   const uint64_t& aFrameId,
                                                   const gfx::Rect& aLeftEyeRect,
                                                   const gfx::Rect& aRightEyeRect) override;
   virtual mozilla::ipc::IPCResult RecvDestroy() override;
   uint32_t GetDisplayID() const { return mVRDisplayID; }
   uint32_t GetGroup() const { return mGroup; }
 protected:
-  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
-
   virtual ~VRLayerParent();
   void Destroy();
 
-  bool mIPCOpen;
-
   uint32_t mVRDisplayID;
   gfx::Rect mLeftEyeRect;
   gfx::Rect mRightEyeRect;
   uint32_t mGroup;
 };
 
 } // namespace gfx
 } // namespace mozilla
--- a/netwerk/cookie/CookieServiceChild.cpp
+++ b/netwerk/cookie/CookieServiceChild.cpp
@@ -63,17 +63,16 @@ NS_IMPL_ISUPPORTS(CookieServiceChild,
                   nsITimerCallback,
                   nsISupportsWeakReference)
 
 CookieServiceChild::CookieServiceChild()
   : mCookieBehavior(nsICookieService::BEHAVIOR_ACCEPT)
   , mThirdPartySession(false)
   , mThirdPartyNonsecureSession(false)
   , mLeaveSecureAlone(true)
-  , mIPCOpen(false)
 {
   NS_ASSERTION(IsNeckoChild(), "not a child process");
 
   mozilla::dom::ContentChild* cc =
     static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
   if (cc->IsShuttingDown()) {
     return;
   }
@@ -81,18 +80,16 @@ CookieServiceChild::CookieServiceChild()
   // This corresponds to Release() in DeallocPCookieService.
   NS_ADDREF_THIS();
 
   NeckoChild::InitNeckoChild();
 
   // Create a child PCookieService actor.
   gNeckoChild->SendPCookieServiceConstructor(this);
 
-  mIPCOpen = true;
-
   mTLDService = do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
   NS_ASSERTION(mTLDService, "couldn't get TLDService");
 
   // Init our prefs and observer.
   nsCOMPtr<nsIPrefBranch> prefBranch =
     do_GetService(NS_PREFSERVICE_CONTRACTID);
   NS_WARNING_ASSERTION(prefBranch, "no prefservice");
   if (prefBranch) {
@@ -152,25 +149,19 @@ CookieServiceChild::Notify(nsITimer *aTi
 }
 
 CookieServiceChild::~CookieServiceChild()
 {
   gCookieService = nullptr;
 }
 
 void
-CookieServiceChild::ActorDestroy(ActorDestroyReason why)
-{
-  mIPCOpen = false;
-}
-
-void
 CookieServiceChild::TrackCookieLoad(nsIChannel *aChannel)
 {
-  if (!mIPCOpen) {
+  if (!IPCOpen()) {
     return;
   }
 
   bool isForeign = false;
   bool isTrackingResource = false;
   bool firstPartyStorageAccessGranted = false;
   nsCOMPtr<nsIURI> uri;
   aChannel->GetURI(getter_AddRefs(uri));
@@ -647,17 +638,17 @@ CookieServiceChild::SetCookieStringInter
     if (loadInfo) {
       attrs = loadInfo->GetOriginAttributes();
     }
   } else {
     SerializeURI(nullptr, channelURIParams);
   }
 
   // Asynchronously call the parent.
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     SendSetCookieString(hostURIParams, channelURIParams,
                         isForeign, isTrackingResource,
                         firstPartyStorageAccessGranted, cookieString,
                         stringServerTime, attrs, aFromHttp);
   }
 
   bool requireHostMatch;
   nsCString baseDomain;
--- a/netwerk/cookie/CookieServiceChild.h
+++ b/netwerk/cookie/CookieServiceChild.h
@@ -111,26 +111,23 @@ protected:
   virtual
   mozilla::ipc::IPCResult RecvRemoveCookie(const CookieStruct &aCookie,
                                            const OriginAttributes &aAttrs) override;
 
   virtual
   mozilla::ipc::IPCResult RecvAddCookie(const CookieStruct &aCookie,
                                         const OriginAttributes &aAttrs) override;
 
-  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
-
   CookiesMap mCookiesMap;
   nsCOMPtr<nsITimer> mCookieTimer;
   nsCOMPtr<mozIThirdPartyUtil> mThirdPartyUtil;
   nsCOMPtr<nsIEffectiveTLDService> mTLDService;
   uint8_t mCookieBehavior;
   bool mThirdPartySession;
   bool mThirdPartyNonsecureSession;
   bool mLeaveSecureAlone;
-  bool mIPCOpen;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // mozilla_net_CookieServiceChild_h__
 
--- a/netwerk/dns/DNSRequestChild.cpp
+++ b/netwerk/dns/DNSRequestChild.cpp
@@ -210,17 +210,17 @@ public:
   CancelDNSRequestEvent(DNSRequestChild* aDnsReq, nsresult aReason)
     : Runnable("net::CancelDNSRequestEvent")
     , mDnsRequest(aDnsReq)
     , mReasonForCancel(aReason)
   {}
 
   NS_IMETHOD Run() override
   {
-    if (mDnsRequest->mIPCOpen) {
+    if (mDnsRequest->IPCOpen()) {
       // Send request to Parent process.
       mDnsRequest->SendCancelDNSRequest(mDnsRequest->mHost,
                                         mDnsRequest->mType,
                                         mDnsRequest->mOriginAttributes,
                                         mDnsRequest->mFlags,
                                         mReasonForCancel);
     }
     return NS_OK;
@@ -242,17 +242,16 @@ DNSRequestChild::DNSRequestChild(const n
                                  nsIEventTarget *target)
   : mListener(aListener)
   , mTarget(target)
   , mResultStatus(NS_OK)
   , mHost(aHost)
   , mType(aType)
   , mOriginAttributes(aOriginAttributes)
   , mFlags(aFlags)
-  , mIPCOpen(false)
 {
 }
 
 void
 DNSRequestChild::StartRequest()
 {
   // we can only do IPDL on the main thread
   if (!NS_IsMainThread()) {
@@ -273,17 +272,16 @@ DNSRequestChild::StartRequest()
     static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
   if (cc->IsShuttingDown()) {
     return;
   }
 
   // Send request to Parent process.
   gNeckoChild->SendPDNSRequestConstructor(this, mHost, mOriginAttributes,
                                           mFlags);
-  mIPCOpen = true;
 
   // IPDL holds a reference until IPDL channel gets destroyed
   AddIPDLReference();
 }
 
 void
 DNSRequestChild::CallOnLookupComplete()
 {
@@ -297,17 +295,16 @@ DNSRequestChild::CallOnLookupByTypeCompl
   MOZ_ASSERT(mListener);
   MOZ_ASSERT(mType != nsIDNSService::RESOLVE_TYPE_DEFAULT);
   mListener->OnLookupByTypeComplete(this, mResultByTypeRecords, mResultStatus);
 }
 
 mozilla::ipc::IPCResult
 DNSRequestChild::RecvLookupCompleted(const DNSRequestResponse& reply)
 {
-  mIPCOpen = false;
   MOZ_ASSERT(mListener);
 
   switch (reply.type()) {
   case DNSRequestResponse::TDNSRecord: {
     mResultRecord = new ChildDNSRecord(reply.get_DNSRecord(), mFlags);
     break;
   }
   case DNSRequestResponse::Tnsresult: {
@@ -366,37 +363,31 @@ DNSRequestChild::ReleaseIPDLReference()
   // Request is done or destroyed. Remove it from the hash table.
   RefPtr<ChildDNSService> dnsServiceChild =
     dont_AddRef(ChildDNSService::GetSingleton());
   dnsServiceChild->NotifyRequestDone(this);
 
   Release();
 }
 
-void
-DNSRequestChild::ActorDestroy(ActorDestroyReason why)
-{
-  mIPCOpen = false;
-}
-
 //-----------------------------------------------------------------------------
 // DNSRequestChild::nsISupports
 //-----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS(DNSRequestChild,
                   nsICancelable)
 
 //-----------------------------------------------------------------------------
 // DNSRequestChild::nsICancelable
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 DNSRequestChild::Cancel(nsresult reason)
 {
-  if(mIPCOpen) {
+  if(IPCOpen()) {
     // We can only do IPDL on the main thread
     nsCOMPtr<nsIRunnable> runnable = new CancelDNSRequestEvent(this, reason);
     SystemGroup::Dispatch(TaskCategory::Other, runnable.forget());
   }
   return NS_OK;
 }
 
 //------------------------------------------------------------------------------
--- a/netwerk/dns/DNSRequestChild.h
+++ b/netwerk/dns/DNSRequestChild.h
@@ -42,31 +42,29 @@ public:
   void CallOnLookupByTypeComplete();
 
 protected:
   friend class CancelDNSRequestEvent;
   friend class ChildDNSService;
   virtual ~DNSRequestChild() {}
 
   virtual mozilla::ipc::IPCResult RecvLookupCompleted(const DNSRequestResponse& reply) override;
-  virtual void ActorDestroy(ActorDestroyReason why) override;
 
   nsCOMPtr<nsIDNSListener>     mListener;
   nsCOMPtr<nsIEventTarget>     mTarget;
   nsCOMPtr<nsIDNSRecord>       mResultRecord;
   nsCOMPtr<nsIDNSByTypeRecord> mResultByTypeRecords; // the result of a by-type
                                                      // query (mType must not be
                                                      // equal to
                                                      // nsIDNSService::RESOLVE_TYPE_DEFAULT
                                                      // (this is reserved for
                                                      // the standard A/AAAA query)).
   nsresult                     mResultStatus;
   nsCString                    mHost;
   uint16_t                     mType;
   const OriginAttributes       mOriginAttributes;
   uint16_t                     mFlags;
-  bool                         mIPCOpen;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // mozilla_net_DNSRequestChild_h
--- a/netwerk/protocol/data/DataChannelChild.cpp
+++ b/netwerk/protocol/data/DataChannelChild.cpp
@@ -12,17 +12,16 @@
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ISUPPORTS_INHERITED(DataChannelChild, nsDataChannel, nsIChildChannel)
 
 DataChannelChild::DataChannelChild(nsIURI* aURI)
     : nsDataChannel(aURI)
-    , mIPCOpen(false)
 {
 }
 
 NS_IMETHODIMP
 DataChannelChild::ConnectParent(uint32_t aId)
 {
     mozilla::dom::ContentChild* cc =
         static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
@@ -50,31 +49,28 @@ DataChannelChild::CompleteRedirectSetup(
     }
     else {
         rv = AsyncOpen(aListener, aContext);
     }
     if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
     }
 
-    if (mIPCOpen) {
+    if (IPCOpen()) {
         Unused << Send__delete__(this);
     }
     return NS_OK;
 }
 
 void
 DataChannelChild::AddIPDLReference()
 {
     AddRef();
-    mIPCOpen = true;
 }
 
 void
 DataChannelChild::ActorDestroy(ActorDestroyReason why)
 {
-    MOZ_ASSERT(mIPCOpen);
-    mIPCOpen = false;
     Release();
 }
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/data/DataChannelChild.h
+++ b/netwerk/protocol/data/DataChannelChild.h
@@ -28,16 +28,14 @@ public:
 
 protected:
     virtual void ActorDestroy(ActorDestroyReason why) override;
 
 private:
     ~DataChannelChild() = default;
 
     void AddIPDLReference();
-
-    bool mIPCOpen;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif /* NS_DATACHANNELCHILD_H */
--- a/netwerk/protocol/file/FileChannelChild.cpp
+++ b/netwerk/protocol/file/FileChannelChild.cpp
@@ -12,17 +12,16 @@
 
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ISUPPORTS_INHERITED(FileChannelChild, nsFileChannel, nsIChildChannel)
 
 FileChannelChild::FileChannelChild(nsIURI *uri)
   : nsFileChannel(uri)
-  , mIPCOpen(false)
 {
 }
 
 NS_IMETHODIMP
 FileChannelChild::ConnectParent(uint32_t id)
 {
   mozilla::dom::ContentChild* cc =
     static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
@@ -50,32 +49,29 @@ FileChannelChild::CompleteRedirectSetup(
   } else {
     rv = AsyncOpen(listener, ctx);
   }
 
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     Unused << Send__delete__(this);
   }
 
   return NS_OK;
 }
 
 void
 FileChannelChild::AddIPDLReference()
 {
   AddRef();
-  mIPCOpen = true;
 }
 
 void
 FileChannelChild::ActorDestroy(ActorDestroyReason why)
 {
-  MOZ_ASSERT(mIPCOpen);
-  mIPCOpen = false;
   Release();
 }
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/file/FileChannelChild.h
+++ b/netwerk/protocol/file/FileChannelChild.h
@@ -28,16 +28,14 @@ public:
 
 protected:
   virtual void ActorDestroy(ActorDestroyReason why) override;
 
 private:
   ~FileChannelChild() = default;;
 
   void AddIPDLReference();
-
-  bool mIPCOpen;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif /* mozilla__net__FileChannelChild_h */
--- a/netwerk/protocol/ftp/FTPChannelChild.cpp
+++ b/netwerk/protocol/ftp/FTPChannelChild.cpp
@@ -29,18 +29,17 @@ using namespace mozilla::ipc;
 
 #undef LOG
 #define LOG(args) MOZ_LOG(gFTPLog, mozilla::LogLevel::Debug, args)
 
 namespace mozilla {
 namespace net {
 
 FTPChannelChild::FTPChannelChild(nsIURI* uri)
-: mIPCOpen(false)
-, mUnknownDecoderInvolved(false)
+: mUnknownDecoderInvolved(false)
 , mCanceled(false)
 , mSuspendCount(0)
 , mIsPending(false)
 , mLastModifiedTime(0)
 , mStartPos(0)
 , mDivertingToParent(false)
 , mFlushedForDiversion(false)
 , mSuspendSent(false)
@@ -60,26 +59,22 @@ FTPChannelChild::~FTPChannelChild()
 {
   LOG(("Destroying FTPChannelChild @%p\n", this));
   gFtpHandler->Release();
 }
 
 void
 FTPChannelChild::AddIPDLReference()
 {
-  MOZ_ASSERT(!mIPCOpen, "Attempt to retain more than one IPDL reference");
-  mIPCOpen = true;
   AddRef();
 }
 
 void
 FTPChannelChild::ReleaseIPDLReference()
 {
-  MOZ_ASSERT(mIPCOpen, "Attempt to release nonexistent IPDL reference");
-  mIPCOpen = false;
   Release();
 }
 
 //-----------------------------------------------------------------------------
 // FTPChannelChild::nsISupports
 //-----------------------------------------------------------------------------
 
 NS_IMPL_ISUPPORTS_INHERITED(FTPChannelChild,
@@ -682,18 +677,19 @@ FTPChannelChild::DoFailedAsyncOpen(const
     mListener->OnStopRequest(this, mListenerContext, statusCode);
   } else {
     mIsPending = false;
   }
 
   mListener = nullptr;
   mListenerContext = nullptr;
 
-  if (mIPCOpen)
+  if (IPCOpen()) {
     Send__delete__(this);
+  }
 }
 
 class FTPFlushedForDiversionEvent : public NeckoTargetChannelEvent<FTPChannelChild>
 {
  public:
   explicit FTPFlushedForDiversionEvent(FTPChannelChild* aChild)
   : NeckoTargetChannelEvent<FTPChannelChild>(aChild)
   {
@@ -758,38 +754,40 @@ FTPChannelChild::RecvDeleteSelf()
 {
   mEventQ->RunOrEnqueue(new FTPDeleteSelfEvent(this));
   return IPC_OK();
 }
 
 void
 FTPChannelChild::DoDeleteSelf()
 {
-  if (mIPCOpen)
+  if (IPCOpen()) {
     Send__delete__(this);
+  }
 }
 
 NS_IMETHODIMP
 FTPChannelChild::Cancel(nsresult status)
 {
   LOG(("FTPChannelChild::Cancel [this=%p]\n", this));
   if (mCanceled)
     return NS_OK;
 
   mCanceled = true;
   mStatus = status;
-  if (mIPCOpen)
+  if (IPCOpen()) {
     SendCancel(status);
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FTPChannelChild::Suspend()
 {
-  NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
+  NS_ENSURE_TRUE(IPCOpen(), NS_ERROR_NOT_AVAILABLE);
 
   LOG(("FTPChannelChild::Suspend [this=%p]\n", this));
 
   // SendSuspend only once, when suspend goes from 0 to 1.
   // Don't SendSuspend at all if we're diverting callbacks to the parent;
   // suspend will be called at the correct time in the parent itself.
   if (!mSuspendCount++ && !mDivertingToParent) {
     SendSuspend();
@@ -798,17 +796,17 @@ FTPChannelChild::Suspend()
   mEventQ->Suspend();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 FTPChannelChild::Resume()
 {
-  NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
+  NS_ENSURE_TRUE(IPCOpen(), NS_ERROR_NOT_AVAILABLE);
 
   LOG(("FTPChannelChild::Resume [this=%p]\n", this));
 
   // SendResume only once, when suspend count drops to 0.
   // Don't SendResume at all if we're diverting callbacks to the parent (unless
   // suspend was sent earlier); otherwise, resume will be called at the correct
   // time in the parent itself.
   if (!--mSuspendCount && (!mDivertingToParent || mSuspendSent)) {
@@ -900,17 +898,17 @@ FTPChannelChild::DivertToParent(ChannelD
 
   // This method should only be called during OnStartRequest.
   if (!mDuringOnStart) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   // We must fail DivertToParent() if there's no parent end of the channel (and
   // won't be!) due to early failure.
-  if (NS_FAILED(mStatus) && !mIPCOpen) {
+  if (NS_FAILED(mStatus) && !IPCOpen()) {
     return mStatus;
   }
 
   nsresult rv = Suspend();
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
--- a/netwerk/protocol/ftp/FTPChannelChild.h
+++ b/netwerk/protocol/ftp/FTPChannelChild.h
@@ -128,17 +128,16 @@ protected:
   friend class FTPFailedAsyncOpenEvent;
   friend class FTPFlushedForDiversionEvent;
   friend class FTPDeleteSelfEvent;
   friend class NeckoTargetChannelEvent<FTPChannelChild>;
 
 private:
   nsCOMPtr<nsIInputStream> mUploadStream;
 
-  bool mIPCOpen;
   RefPtr<ChannelEventQueue> mEventQ;
 
   // If nsUnknownDecoder is involved we queue onDataAvailable (and possibly
   // OnStopRequest) so that we can divert them if needed when the listener's
   // OnStartRequest is finally called
   nsTArray<UniquePtr<ChannelEvent>> mUnknownDecoderEventQ;
   bool mUnknownDecoderInvolved;
 
--- a/netwerk/protocol/http/AltDataOutputStreamChild.cpp
+++ b/netwerk/protocol/http/AltDataOutputStreamChild.cpp
@@ -9,17 +9,17 @@ NS_IMPL_ADDREF(AltDataOutputStreamChild)
 
 NS_IMETHODIMP_(MozExternalRefCountType) AltDataOutputStreamChild::Release()
 {
   MOZ_ASSERT(0 != mRefCnt, "dup release");
   MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
   --mRefCnt;
   NS_LOG_RELEASE(this, mRefCnt, "AltDataOutputStreamChild");
 
-  if (mRefCnt == 1 && mIPCOpen) {
+  if (mRefCnt == 1 && IPCOpen()) {
     // The only reference left is the IPDL one. After the parent replies back
     // with a DeleteSelf message, the child will call Send__delete__(this),
     // decrementing the ref count and triggering the destructor.
     SendDeleteSelf();
     return 1;
   }
 
   if (mRefCnt == 0) {
@@ -31,85 +31,79 @@ NS_IMETHODIMP_(MozExternalRefCountType) 
 }
 
 NS_INTERFACE_MAP_BEGIN(AltDataOutputStreamChild)
   NS_INTERFACE_MAP_ENTRY(nsIOutputStream)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 AltDataOutputStreamChild::AltDataOutputStreamChild()
-  : mIPCOpen(false)
-  , mError(NS_OK)
+  : mError(NS_OK)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
 }
 
 void
 AltDataOutputStreamChild::AddIPDLReference()
 {
-  MOZ_ASSERT(!mIPCOpen, "Attempt to retain more than one IPDL reference");
-  mIPCOpen = true;
   AddRef();
 }
 
 void
 AltDataOutputStreamChild::ReleaseIPDLReference()
 {
-  MOZ_ASSERT(mIPCOpen, "Attempt to release nonexistent IPDL reference");
-  mIPCOpen = false;
   Release();
 }
 
 bool
 AltDataOutputStreamChild::WriteDataInChunks(const nsDependentCSubstring& data)
 {
   const uint32_t kChunkSize = 128*1024;
   uint32_t next = std::min(data.Length(), kChunkSize);
   for (uint32_t i = 0; i < data.Length();
        i = next, next = std::min(data.Length(), next + kChunkSize)) {
     nsCString chunk(Substring(data, i, kChunkSize));
-    if (mIPCOpen && !SendWriteData(chunk)) {
-      mIPCOpen = false;
+    if (IPCOpen() && !SendWriteData(chunk)) {
       return false;
     }
   }
   return true;
 }
 
 NS_IMETHODIMP
 AltDataOutputStreamChild::Close()
 {
-  if (!mIPCOpen) {
+  if (!IPCOpen()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   if (NS_FAILED(mError)) {
     return mError;
   }
   Unused << SendClose();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 AltDataOutputStreamChild::Flush()
 {
-  if (!mIPCOpen) {
+  if (!IPCOpen()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   if (NS_FAILED(mError)) {
     return mError;
   }
 
   // This is a no-op
   return NS_OK;
 }
 
 NS_IMETHODIMP
 AltDataOutputStreamChild::Write(const char * aBuf, uint32_t aCount, uint32_t *_retval)
 {
-  if (!mIPCOpen) {
+  if (!IPCOpen()) {
     return NS_ERROR_NOT_AVAILABLE;
   }
   if (NS_FAILED(mError)) {
     return mError;
   }
   if (WriteDataInChunks(nsDependentCSubstring(aBuf, aCount))) {
     *_retval = aCount;
     return NS_OK;
--- a/netwerk/protocol/http/AltDataOutputStreamChild.h
+++ b/netwerk/protocol/http/AltDataOutputStreamChild.h
@@ -29,17 +29,16 @@ public:
   virtual mozilla::ipc::IPCResult RecvError(const nsresult& err) override;
   virtual mozilla::ipc::IPCResult RecvDeleteSelf() override;
 
 private:
   virtual ~AltDataOutputStreamChild() = default;
   // Sends data to the parent process in 256k chunks.
   bool WriteDataInChunks(const nsDependentCSubstring& data);
 
-  bool mIPCOpen;
   // If there was an error opening the output stream or writing to it on the
   // parent side, this will be set to the error code. We check it before we
   // write so we can report an error to the consumer.
   nsresult mError;
 };
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/http/AltDataOutputStreamParent.cpp
+++ b/netwerk/protocol/http/AltDataOutputStreamParent.cpp
@@ -11,75 +11,67 @@
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ISUPPORTS0(AltDataOutputStreamParent)
 
 AltDataOutputStreamParent::AltDataOutputStreamParent(nsIOutputStream* aStream)
   : mOutputStream(aStream)
   , mStatus(NS_OK)
-  , mIPCOpen(true)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
 }
 
 AltDataOutputStreamParent::~AltDataOutputStreamParent()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
 }
 
 mozilla::ipc::IPCResult
 AltDataOutputStreamParent::RecvWriteData(const nsCString& data)
 {
   if (NS_FAILED(mStatus)) {
-    if (mIPCOpen) {
+    if (IPCOpen()) {
       Unused << SendError(mStatus);
     }
     return IPC_OK();
   }
   nsresult rv;
   uint32_t n;
   if (mOutputStream) {
     rv = mOutputStream->Write(data.BeginReading(), data.Length(), &n);
     MOZ_ASSERT(n == data.Length() || NS_FAILED(rv));
-    if (NS_FAILED(rv) && mIPCOpen) {
+    if (NS_FAILED(rv) && IPCOpen()) {
       Unused << SendError(rv);
     }
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 AltDataOutputStreamParent::RecvClose()
 {
   if (NS_FAILED(mStatus)) {
-    if (mIPCOpen) {
+    if (IPCOpen()) {
       Unused << SendError(mStatus);
     }
     return IPC_OK();
   }
   nsresult rv;
   if (mOutputStream) {
     rv = mOutputStream->Close();
-    if (NS_FAILED(rv) && mIPCOpen) {
+    if (NS_FAILED(rv) && IPCOpen()) {
       Unused << SendError(rv);
     }
     mOutputStream = nullptr;
   }
   return IPC_OK();
 }
 
-void
-AltDataOutputStreamParent::ActorDestroy(ActorDestroyReason aWhy)
-{
-  mIPCOpen = false;
-}
-
 mozilla::ipc::IPCResult
 AltDataOutputStreamParent::RecvDeleteSelf()
 {
-  mIPCOpen = false;
   Unused << SendDeleteSelf();
   return IPC_OK();
 }
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/http/AltDataOutputStreamParent.h
+++ b/netwerk/protocol/http/AltDataOutputStreamParent.h
@@ -28,27 +28,25 @@ public:
   explicit AltDataOutputStreamParent(nsIOutputStream* aStream);
 
   // Called when data is received from the content process.
   // We proceed to write that data to the output stream.
   virtual mozilla::ipc::IPCResult RecvWriteData(const nsCString& data) override;
   // Called when AltDataOutputStreamChild::Close() is
   // Closes and nulls the output stream.
   virtual mozilla::ipc::IPCResult RecvClose() override;
-  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   // Sets an error that will be reported to the content process.
   void SetError(nsresult status) { mStatus = status; }
   virtual mozilla::ipc::IPCResult RecvDeleteSelf() override;
 
 private:
   virtual ~AltDataOutputStreamParent();
   nsCOMPtr<nsIOutputStream> mOutputStream;
   // In case any error occurs mStatus will be != NS_OK, and this status code will
   // be sent to the content process asynchronously.
   nsresult mStatus;
-  bool     mIPCOpen;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // mozilla_net_AltDataOutputStreamParent_h
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -2436,20 +2436,21 @@ HttpChannelChild::OnRedirectVerifyCallba
   nsCOMPtr<nsIChannel> newChannel = do_QueryInterface(mRedirectChannelChild);
   if (newChannel) {
     Unused << newChannel->GetLoadInfo(getter_AddRefs(newChannelLoadInfo));
   }
 
   ChildLoadInfoForwarderArgs loadInfoForwarder;
   LoadInfoToChildLoadInfoForwarder(newChannelLoadInfo, &loadInfoForwarder);
 
-  if (mIPCOpen)
+  if (mIPCOpen) {
     SendRedirect2Verify(result, *headerTuples, loadInfoForwarder, loadFlags,
                         referrerPolicy, referrerURI, redirectURI,
                         corsPreflightArgs, chooseAppcache);
+  }
 
   return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // HttpChannelChild::nsIRequest
 //-----------------------------------------------------------------------------
 
--- a/netwerk/protocol/websocket/WebSocketChannelParent.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelParent.cpp
@@ -24,34 +24,33 @@ NS_IMPL_ISUPPORTS(WebSocketChannelParent
                   nsIInterfaceRequestor)
 
 WebSocketChannelParent::WebSocketChannelParent(nsIAuthPromptProvider* aAuthProvider,
                                                nsILoadContext* aLoadContext,
                                                PBOverrideStatus aOverrideStatus,
                                                uint32_t aSerial)
   : mAuthProvider(aAuthProvider)
   , mLoadContext(aLoadContext)
-  , mIPCOpen(true)
   , mSerial(aSerial)
 {
   // Websocket channels can't have a private browsing override
   MOZ_ASSERT_IF(!aLoadContext, aOverrideStatus == kPBOverride_Unset);
 }
 //-----------------------------------------------------------------------------
 // WebSocketChannelParent::PWebSocketChannelParent
 //-----------------------------------------------------------------------------
 
 mozilla::ipc::IPCResult
 WebSocketChannelParent::RecvDeleteSelf()
 {
   LOG(("WebSocketChannelParent::RecvDeleteSelf() %p\n", this));
   mChannel = nullptr;
   mAuthProvider = nullptr;
   IProtocol* mgr = Manager();
-  if (mIPCOpen && !Send__delete__(this)) {
+  if (IPCOpen() && !Send__delete__(this)) {
     return IPC_FAIL_NO_REASON(mgr);
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 WebSocketChannelParent::RecvAsyncOpen(const OptionalURIParams& aURI,
                                       const nsCString& aOrigin,
@@ -217,86 +216,84 @@ WebSocketChannelParent::OnStart(nsISuppo
 
     RefPtr<WebSocketChannel> channel;
     channel = static_cast<WebSocketChannel*>(mChannel.get());
     MOZ_ASSERT(channel);
 
     channel->GetEffectiveURL(effectiveURL);
     encrypted = channel->IsEncrypted();
   }
-  if (!mIPCOpen || !SendOnStart(protocol, extensions, effectiveURL, encrypted)) {
+  if (!IPCOpen() || !SendOnStart(protocol, extensions, effectiveURL, encrypted)) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WebSocketChannelParent::OnStop(nsISupports *aContext, nsresult aStatusCode)
 {
   LOG(("WebSocketChannelParent::OnStop() %p\n", this));
-  if (!mIPCOpen || !SendOnStop(aStatusCode)) {
+  if (!IPCOpen() || !SendOnStop(aStatusCode)) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WebSocketChannelParent::OnMessageAvailable(nsISupports *aContext, const nsACString& aMsg)
 {
   LOG(("WebSocketChannelParent::OnMessageAvailable() %p\n", this));
-  if (!mIPCOpen || !SendOnMessageAvailable(nsCString(aMsg))) {
+  if (!IPCOpen() || !SendOnMessageAvailable(nsCString(aMsg))) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WebSocketChannelParent::OnBinaryMessageAvailable(nsISupports *aContext, const nsACString& aMsg)
 {
   LOG(("WebSocketChannelParent::OnBinaryMessageAvailable() %p\n", this));
-  if (!mIPCOpen || !SendOnBinaryMessageAvailable(nsCString(aMsg))) {
+  if (!IPCOpen() || !SendOnBinaryMessageAvailable(nsCString(aMsg))) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WebSocketChannelParent::OnAcknowledge(nsISupports *aContext, uint32_t aSize)
 {
   LOG(("WebSocketChannelParent::OnAcknowledge() %p\n", this));
-  if (!mIPCOpen || !SendOnAcknowledge(aSize)) {
+  if (!IPCOpen() || !SendOnAcknowledge(aSize)) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WebSocketChannelParent::OnServerClose(nsISupports *aContext,
                                       uint16_t code, const nsACString & reason)
 {
   LOG(("WebSocketChannelParent::OnServerClose() %p\n", this));
-  if (!mIPCOpen || !SendOnServerClose(code, nsCString(reason))) {
+  if (!IPCOpen() || !SendOnServerClose(code, nsCString(reason))) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 void
 WebSocketChannelParent::ActorDestroy(ActorDestroyReason why)
 {
   LOG(("WebSocketChannelParent::ActorDestroy() %p\n", this));
 
   // Make sure we close the channel if the content process dies without going
   // through a clean shutdown.
   if (mChannel) {
     Unused << mChannel->Close(nsIWebSocketChannel::CLOSE_GOING_AWAY,
                               NS_LITERAL_CSTRING("Child was killed"));
   }
-
-  mIPCOpen = false;
 }
 
 //-----------------------------------------------------------------------------
 // WebSocketChannelParent::nsIInterfaceRequestor
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 WebSocketChannelParent::GetInterface(const nsIID & iid, void **result)
--- a/netwerk/protocol/websocket/WebSocketChannelParent.h
+++ b/netwerk/protocol/websocket/WebSocketChannelParent.h
@@ -56,17 +56,16 @@ class WebSocketChannelParent : public PW
                                                const uint32_t& aLength) override;
   mozilla::ipc::IPCResult RecvDeleteSelf() override;
 
   void ActorDestroy(ActorDestroyReason why) override;
 
   nsCOMPtr<nsIAuthPromptProvider> mAuthProvider;
   nsCOMPtr<nsIWebSocketChannel> mChannel;
   nsCOMPtr<nsILoadContext> mLoadContext;
-  bool mIPCOpen;
 
   uint32_t mSerial;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif // mozilla_net_WebSocketChannelParent_h
--- a/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
@@ -42,17 +42,16 @@ WyciwygChannelChild::WyciwygChannelChild
   : NeckoTargetHolder(aNeckoTarget)
   , mStatus(NS_OK)
   , mIsPending(false)
   , mCanceled(false)
   , mLoadFlags(LOAD_NORMAL)
   , mContentLength(-1)
   , mCharsetSource(kCharsetUninitialized)
   , mState(WCC_NEW)
-  , mIPCOpen(false)
   , mSentAppData(false)
 {
   LOG(("Creating WyciwygChannelChild @%p\n", this));
   mEventQ = new ChannelEventQueue(NS_ISUPPORTS_CAST(nsIWyciwygChannel*, this));
 
   if (mNeckoTarget) {
     gNeckoChild->SetEventTargetForActor(this, mNeckoTarget);
   }
@@ -69,26 +68,22 @@ WyciwygChannelChild::~WyciwygChannelChil
     NS_ReleaseOnMainThreadSystemGroup(
       "WyciwygChannelChild::mLoadInfo", mLoadInfo.forget());
   }
 }
 
 void
 WyciwygChannelChild::AddIPDLReference()
 {
-  MOZ_ASSERT(!mIPCOpen, "Attempt to retain more than one IPDL reference");
-  mIPCOpen = true;
   AddRef();
 }
 
 void
 WyciwygChannelChild::ReleaseIPDLReference()
 {
-  MOZ_ASSERT(mIPCOpen, "Attempt to release nonexistent IPDL reference");
-  mIPCOpen = false;
   Release();
 }
 
 nsresult
 WyciwygChannelChild::Init(nsIURI* uri)
 {
   NS_ENSURE_ARG_POINTER(uri);
 
@@ -323,18 +318,19 @@ WyciwygChannelChild::OnStopRequest(const
 
     if (mLoadGroup)
       mLoadGroup->RemoveRequest(this, nullptr, mStatus);
 
     mCallbacks = nullptr;
     mProgressSink = nullptr;
   }
 
-  if (mIPCOpen)
+  if (IPCOpen()) {
     PWyciwygChannelChild::Send__delete__(this);
+  }
 }
 
 class WyciwygCancelEvent : public NeckoTargetChannelEvent<WyciwygChannelChild>
 {
  public:
   WyciwygCancelEvent(WyciwygChannelChild* child, const nsresult& status)
   : NeckoTargetChannelEvent<WyciwygChannelChild>(child)
   , mStatus(status) {}
@@ -368,18 +364,19 @@ void WyciwygChannelChild::CancelEarly(co
 
   if (mListener) {
     mListener->OnStartRequest(this, mListenerContext);
     mListener->OnStopRequest(this, mListenerContext, mStatus);
   }
   mListener = nullptr;
   mListenerContext = nullptr;
 
-  if (mIPCOpen)
+  if (IPCOpen()) {
     PWyciwygChannelChild::Send__delete__(this);
+  }
 }
 
 //-----------------------------------------------------------------------------
 // nsIRequest
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 WyciwygChannelChild::GetName(nsACString & aName)
@@ -404,18 +401,19 @@ WyciwygChannelChild::GetStatus(nsresult 
 NS_IMETHODIMP
 WyciwygChannelChild::Cancel(nsresult aStatus)
 {
   if (mCanceled)
     return NS_OK;
 
   mCanceled = true;
   mStatus = aStatus;
-  if (mIPCOpen)
+  if (IPCOpen()) {
     SendCancel(aStatus);
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WyciwygChannelChild::Suspend()
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
@@ -748,18 +746,19 @@ WyciwygChannelChild::WriteToCacheEntry(c
 NS_IMETHODIMP
 WyciwygChannelChild::CloseCacheEntry(nsresult reason)
 {
   NS_ENSURE_TRUE(mState == WCC_ONWRITE, NS_ERROR_UNEXPECTED);
 
   SendCloseCacheEntry(reason);
   mState = WCC_ONCLOSED;
 
-  if (mIPCOpen)
+  if (IPCOpen()) {
     PWyciwygChannelChild::Send__delete__(this);
+  }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WyciwygChannelChild::SetSecurityInfo(nsISupports *aSecurityInfo)
 {
   mSecurityInfo = aSecurityInfo;
--- a/netwerk/protocol/wyciwyg/WyciwygChannelChild.h
+++ b/netwerk/protocol/wyciwyg/WyciwygChannelChild.h
@@ -99,17 +99,16 @@ private:
   nsCOMPtr<nsILoadGroup>            mLoadGroup;
   nsCOMPtr<nsIStreamListener>       mListener;
   nsCOMPtr<nsISupports>             mListenerContext;
   nsCOMPtr<nsISupports>             mSecurityInfo;
 
   // FIXME: replace with IPDL states (bug 536319)
   enum WyciwygChannelChildState mState;
 
-  bool mIPCOpen;
   bool mSentAppData;
   RefPtr<ChannelEventQueue> mEventQ;
 
   friend class WyciwygStartRequestEvent;
   friend class WyciwygDataAvailableEvent;
   friend class WyciwygStopRequestEvent;
   friend class WyciwygCancelEvent;
   friend class NeckoTargetChannelEvent<WyciwygChannelChild>;
--- a/security/manager/ssl/PSMContentListener.cpp
+++ b/security/manager/ssl/PSMContentListener.cpp
@@ -208,17 +208,16 @@ PSMContentStreamListener::ImportCertific
 }
 
 /* ------------------------
  * PSMContentDownloaderParent
  * ------------------------ */
 
 PSMContentDownloaderParent::PSMContentDownloaderParent(uint32_t type)
   : PSMContentStreamListener(type)
-  , mIPCOpen(true)
 {
 }
 
 PSMContentDownloaderParent::~PSMContentDownloaderParent()
 {
 }
 
 mozilla::ipc::IPCResult
@@ -243,49 +242,43 @@ PSMContentDownloaderParent::RecvOnStopRe
   if (NS_SUCCEEDED(code)) {
     // See also PSMContentStreamListener::OnStopRequest. In this case, we don't
     // have to dispatch ImportCertificate off of an event because we don't have
     // to worry about Necko sending "clean up" events and destroying us if
     // ImportCertificate spins the event loop.
     ImportCertificate();
   }
 
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     mozilla::Unused << Send__delete__(this);
   }
   return IPC_OK();
 }
 
 NS_IMETHODIMP
 PSMContentDownloaderParent::OnStopRequest(nsIRequest* request, nsISupports* context, nsresult code)
 {
   nsresult rv = PSMContentStreamListener::OnStopRequest(request, context, code);
 
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     mozilla::Unused << Send__delete__(this);
   }
   return rv;
 }
 
 mozilla::ipc::IPCResult
 PSMContentDownloaderParent::RecvDivertToParentUsing(mozilla::net::PChannelDiverterParent* diverter)
 {
   MOZ_ASSERT(diverter);
   auto p = static_cast<mozilla::net::ChannelDiverterParent*>(diverter);
   p->DivertTo(this);
   mozilla::Unused << mozilla::net::ChannelDiverterParent::Send__delete__(p);
   return IPC_OK();
 }
 
-void
-PSMContentDownloaderParent::ActorDestroy(ActorDestroyReason why)
-{
-  mIPCOpen = false;
-}
-
 /* ------------------------
  * PSMContentDownloaderChild
  * ------------------------ */
 
 NS_IMPL_ISUPPORTS(PSMContentDownloaderChild, nsIStreamListener)
 
 PSMContentDownloaderChild::PSMContentDownloaderChild()
 {
--- a/security/manager/ssl/PSMContentListener.h
+++ b/security/manager/ssl/PSMContentListener.h
@@ -62,19 +62,16 @@ public:
   // we have to override OnStopRequest to know when we're done with our IPC
   // ref.
   NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports *aContext, nsresult code) override;
 
   virtual mozilla::ipc::IPCResult RecvDivertToParentUsing(mozilla::net::PChannelDiverterParent *diverter) override;
 
 protected:
   virtual ~PSMContentDownloaderParent();
-
-  virtual void ActorDestroy(ActorDestroyReason why) override;
-  bool mIPCOpen;
 };
 
 // Child actor for importing a cert.
 class PSMContentDownloaderChild : public nsIStreamListener
                                 , public PPSMContentDownloaderChild
 {
 public:
   PSMContentDownloaderChild();
--- a/toolkit/components/reputationservice/LoginReputationIPC.cpp
+++ b/toolkit/components/reputationservice/LoginReputationIPC.cpp
@@ -41,19 +41,13 @@ LoginReputationParent::QueryReputation(n
 
 NS_IMETHODIMP
 LoginReputationParent::OnComplete(nsresult aResult,
                                   VerdictType aVerdict)
 {
   LR_LOG(("OnComplete() [verdict=%s]",
     LoginReputationService::VerdictTypeToString(aVerdict).get()));
 
-  if (mIPCOpen) {
+  if (IPCOpen()) {
     Unused << Send__delete__(this);
   }
   return NS_OK;
 }
-
-void
-LoginReputationParent::ActorDestroy(ActorDestroyReason aWhy)
-{
-  mIPCOpen = false;
-}
--- a/toolkit/components/reputationservice/LoginReputationIPC.h
+++ b/toolkit/components/reputationservice/LoginReputationIPC.h
@@ -19,19 +19,16 @@ class LoginReputationParent : public nsI
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSILOGINREPUTATIONQUERYCALLBACK
 
   LoginReputationParent() = default;
 
   mozilla::ipc::IPCResult QueryReputation(nsIURI* aURI);
 
-  void ActorDestroy(ActorDestroyReason aWhy) override;
-
 private:
   ~LoginReputationParent() = default;
-  bool mIPCOpen = true;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_LoginReputationIPC_h