Bug 1103036 - Ensure __delete__ message from TabChild doesn't get sent after ActorDestroy (r=bent)
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -772,17 +772,20 @@ private:
}
NS_IMETHOD
Run()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mTabChild);
- unused << PBrowserChild::Send__delete__(mTabChild);
+ // Check in case ActorDestroy was called after RecvDestroy message.
+ if (mTabChild->IPCOpen()) {
+ unused << PBrowserChild::Send__delete__(mTabChild);
+ }
mTabChild = nullptr;
return NS_OK;
}
};
StaticRefPtr<TabChild> sPreallocatedTab;
@@ -900,16 +903,17 @@ TabChild::TabChild(nsIContentChild* aMan
, mEndTouchIsClick(false)
, mIgnoreKeyPressEvent(false)
, mActiveElementManager(new ActiveElementManager())
, mHasValidInnerSize(false)
, mDestroyed(false)
, mUniqueId(aTabId)
, mDPI(0)
, mDefaultScale(0)
+ , mIPCOpen(true)
{
if (!sActiveDurationMsSet) {
Preferences::AddIntVarCache(&sActiveDurationMs,
"ui.touch_activation.duration_ms",
sActiveDurationMs);
sActiveDurationMsSet = true;
}
@@ -1649,16 +1653,18 @@ TabChild::DestroyWindow()
}
mCachedFileDescriptorInfos.Clear();
}
void
TabChild::ActorDestroy(ActorDestroyReason why)
{
+ mIPCOpen = false;
+
DestroyWindow();
if (mTabChildGlobal) {
// The messageManager relays messages via the TabChild which
// no longer exists.
static_cast<nsFrameMessageManager*>
(mTabChildGlobal->mMessageManager.get())->Disconnect();
mTabChildGlobal->mMessageManager = nullptr;
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -494,16 +494,18 @@ public:
* Native widget remoting protocol for use with windowed plugins with e10s.
*/
PPluginWidgetChild* AllocPPluginWidgetChild() MOZ_OVERRIDE;
bool DeallocPPluginWidgetChild(PPluginWidgetChild* aActor) MOZ_OVERRIDE;
already_AddRefed<nsIWidget> CreatePluginWidget(nsIWidget* aParent);
nsIntPoint GetChromeDisplacement() { return mChromeDisp; };
+ bool IPCOpen() { return mIPCOpen; }
+
protected:
virtual ~TabChild();
virtual PRenderFrameChild* AllocPRenderFrameChild() MOZ_OVERRIDE;
virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) MOZ_OVERRIDE;
virtual bool RecvDestroy() MOZ_OVERRIDE;
virtual bool RecvSetUpdateHitRegion(const bool& aEnabled) MOZ_OVERRIDE;
virtual bool RecvSetIsDocShellActive(const bool& aIsActive) MOZ_OVERRIDE;
@@ -657,16 +659,17 @@ private:
nsRefPtr<ActiveElementManager> mActiveElementManager;
bool mHasValidInnerSize;
bool mDestroyed;
// Position of tab, relative to parent widget (typically the window)
nsIntPoint mChromeDisp;
TabId mUniqueId;
float mDPI;
double mDefaultScale;
+ bool mIPCOpen;
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};
}
}
#endif // mozilla_dom_TabChild_h