Bug 1364364 - Part 3: Clear dynamic subframe entries in RemoveFromBFCacheSync/Async. r=smaug

MozReview-Commit-ID: F8OTxbWIp5O

--HG--
extra : rebase_source : 000ac21b857f53268b6dae54ab76a44f1c7b0e3e
This commit is contained in:
Samael Wang 2017-08-24 15:17:39 +08:00
Родитель 1cee800a66
Коммит 6ecf7b4ce8
1 изменённых файлов: 34 добавлений и 34 удалений

Просмотреть файл

@ -168,56 +168,59 @@ nsSHEntryShared::RemoveFromBFCacheSync()
{
MOZ_ASSERT(mContentViewer && mDocument, "we're not in the bfcache!");
// The call to DropPresentationState could drop the last reference, so hold
// |this| until RemoveDynEntriesForBFCacheEntry finishes.
RefPtr<nsSHEntryShared> kungFuDeathGrip = this;
// DropPresentationState would clear mContentViewer.
nsCOMPtr<nsIContentViewer> viewer = mContentViewer;
DropPresentationState();
// Warning! The call to DropPresentationState could have dropped the last
// reference to this object, so don't access members beyond here.
if (viewer) {
viewer->Destroy();
}
// Now that we've dropped the viewer, we have to clear associated dynamic
// subframe entries.
nsCOMPtr<nsISHistoryInternal> shistory = do_QueryReferent(mSHistory);
if (shistory) {
shistory->RemoveDynEntriesForBFCacheEntry(this);
}
return NS_OK;
}
class DestroyViewerEvent : public mozilla::Runnable
{
public:
DestroyViewerEvent(nsIContentViewer* aViewer, nsIDocument* aDocument)
: mozilla::Runnable("DestroyViewerEvent")
, mViewer(aViewer)
, mDocument(aDocument)
{
}
NS_IMETHOD Run() override
{
if (mViewer) {
mViewer->Destroy();
}
return NS_OK;
}
nsCOMPtr<nsIContentViewer> mViewer;
nsCOMPtr<nsIDocument> mDocument;
};
nsresult
nsSHEntryShared::RemoveFromBFCacheAsync()
{
MOZ_ASSERT(mContentViewer && mDocument, "we're not in the bfcache!");
// Release the reference to the contentviewer asynchronously so that the
// document doesn't get nuked mid-mutation.
// Check it again to play safe in release builds.
if (!mDocument) {
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIRunnable> evt = new DestroyViewerEvent(mContentViewer, mDocument);
nsresult rv = mDocument->Dispatch(mozilla::TaskCategory::Other, evt.forget());
// DropPresentationState would clear mContentViewer & mDocument. Capture and
// release the references asynchronously so that the document doesn't get
// nuked mid-mutation.
nsCOMPtr<nsIContentViewer> viewer = mContentViewer;
nsCOMPtr<nsIDocument> document = mDocument;
RefPtr<nsSHEntryShared> self = this;
nsresult rv = mDocument->Dispatch(mozilla::TaskCategory::Other,
NS_NewRunnableFunction("nsSHEntryShared::RemoveFromBFCacheAsync",
[self, viewer, document]() {
if (viewer) {
viewer->Destroy();
}
nsCOMPtr<nsISHistoryInternal> shistory = do_QueryReferent(self->mSHistory);
if (shistory) {
shistory->RemoveDynEntriesForBFCacheEntry(self);
}
}));
if (NS_FAILED(rv)) {
NS_WARNING("failed to dispatch DestroyViewerEvent");
NS_WARNING("Failed to dispatch RemoveFromBFCacheAsync runnable.");
} else {
// Drop presentation. Only do this if we succeeded in posting the event
// since otherwise the document could be torn down mid-mutation, causing
@ -225,9 +228,6 @@ nsSHEntryShared::RemoveFromBFCacheAsync()
DropPresentationState();
}
// Careful! The call to DropPresentationState could have dropped the last
// reference to this nsSHEntryShared, so don't access members beyond here.
return NS_OK;
}