From e5b08c22865254cc333c9c2827cf09c8ce8c7bb0 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Wed, 28 Oct 2015 16:01:07 -0400 Subject: [PATCH] Bug 1202085 - Part 6: Clear the entries in the image cache belonging to a controlled document when it gets destroyed; r=seth --- dom/base/nsDocument.cpp | 10 ++++++++-- image/ImageCacheKey.h | 4 ++++ image/imgICache.idl | 10 +++++++++- image/imgLoader.cpp | 19 +++++++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index bd4939a9cbf6..331395f5ffd3 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -70,7 +70,8 @@ #include "mozilla/dom/TreeWalker.h" #include "nsIServiceManager.h" -#include "nsIServiceWorkerManager.h" +#include "mozilla/dom/workers/ServiceWorkerManager.h" +#include "imgLoader.h" #include "nsCanvasFrame.h" #include "nsContentCID.h" @@ -8893,8 +8894,13 @@ nsDocument::Destroy() mRegistry = nullptr; - nsCOMPtr swm = mozilla::services::GetServiceWorkerManager(); + using mozilla::dom::workers::ServiceWorkerManager; + RefPtr swm = ServiceWorkerManager::GetInstance(); if (swm) { + ErrorResult error; + if (swm->IsControlled(this, error)) { + nsContentUtils::GetImgLoaderForDocument(this)->ClearCacheForControlledDocument(this); + } swm->MaybeStopControlling(this); } diff --git a/image/ImageCacheKey.h b/image/ImageCacheKey.h index beca733064c1..919bff6d9147 100644 --- a/image/ImageCacheKey.h +++ b/image/ImageCacheKey.h @@ -46,6 +46,10 @@ public: /// Is this cache entry for a chrome image? bool IsChrome() const { return mIsChrome; } + /// A token indicating which service worker controlled document this entry + /// belongs to, if any. + void* ControlledDocument() const { return mControlledDocument; } + private: static uint32_t ComputeHash(ImageURL* aURI, const Maybe& aBlobSerial, diff --git a/image/imgICache.idl b/image/imgICache.idl index ede42991eb5d..abfe0d09099a 100644 --- a/image/imgICache.idl +++ b/image/imgICache.idl @@ -7,6 +7,7 @@ #include "nsISupports.idl" interface imgIRequest; +interface nsIDocument; interface nsIDOMDocument; interface nsIProperties; interface nsIURI; @@ -18,7 +19,7 @@ interface nsIURI; * @version 0.1 * @see imagelib2 */ -[scriptable, builtinclass, uuid(6c1e3f96-4701-4c75-9883-217a790a53e2)] +[scriptable, builtinclass, uuid(bfdf23ff-378e-402e-8a6c-840f0c82b6c3)] interface imgICache : nsISupports { /** @@ -52,4 +53,11 @@ interface imgICache : nsISupports * last-pb-context-exited notification is observed. */ void respectPrivacyNotifications(); + + /** + * Clear the image cache for a document. Controlled documents are responsible + * for doing this manually when they get destroyed. + */ + [noscript, notxpcom] + void clearCacheForControlledDocument(in nsIDocument doc); }; diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp index 880afcc09a1a..e991c9310064 100644 --- a/image/imgLoader.cpp +++ b/image/imgLoader.cpp @@ -1361,6 +1361,25 @@ imgLoader::FindEntryProperties(nsIURI* uri, return NS_OK; } +NS_IMETHODIMP_(void) +imgLoader::ClearCacheForControlledDocument(nsIDocument* aDoc) +{ + MOZ_ASSERT(aDoc); + nsAutoTArray, 128> entriesToBeRemoved; + imgCacheTable& cache = GetCache(false); + for (auto iter = cache.Iter(); !iter.Done(); iter.Next()) { + auto& key = iter.Key(); + if (key.ControlledDocument() == aDoc) { + entriesToBeRemoved.AppendElement(iter.Data()); + } + } + for (auto& entry : entriesToBeRemoved) { + if (!RemoveFromCache(entry)) { + NS_WARNING("Couldn't remove an entry from the cache in ClearCacheForControlledDocument()\n"); + } + } +} + void imgLoader::Shutdown() {