From ef2cb4ed8431e780c209663f210c4a357017573e Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Wed, 16 Jul 2014 16:16:30 +0200 Subject: [PATCH] Bug 976608 - applicationCache corrupted due to concurrent updates running (should coalesce), r=jduell --- uriloader/prefetch/OfflineCacheUpdateGlue.cpp | 17 +++++++++++++++++ uriloader/prefetch/OfflineCacheUpdateGlue.h | 1 + uriloader/prefetch/OfflineCacheUpdateParent.cpp | 2 +- uriloader/prefetch/nsOfflineCacheUpdate.cpp | 14 ++++++++++++++ uriloader/prefetch/nsOfflineCacheUpdate.h | 2 ++ .../prefetch/nsOfflineCacheUpdateService.cpp | 3 ++- 6 files changed, 37 insertions(+), 2 deletions(-) diff --git a/uriloader/prefetch/OfflineCacheUpdateGlue.cpp b/uriloader/prefetch/OfflineCacheUpdateGlue.cpp index 1e33d3a0866f..bfcb253931a4 100644 --- a/uriloader/prefetch/OfflineCacheUpdateGlue.cpp +++ b/uriloader/prefetch/OfflineCacheUpdateGlue.cpp @@ -50,6 +50,7 @@ NS_IMPL_ISUPPORTS(OfflineCacheUpdateGlue, //----------------------------------------------------------------------------- OfflineCacheUpdateGlue::OfflineCacheUpdateGlue() +: mCoalesced(false) { LOG(("OfflineCacheUpdateGlue::OfflineCacheUpdateGlue [%p]", this)); } @@ -89,6 +90,9 @@ OfflineCacheUpdateGlue::Schedule() // Do not use weak reference, we must survive! mUpdate->AddObserver(this, false); + if (mCoalesced) // already scheduled + return NS_OK; + return mUpdate->Schedule(); } @@ -100,6 +104,14 @@ OfflineCacheUpdateGlue::Init(nsIURI *aManifestURI, uint32_t aAppID, bool aInBrowser) { + nsOfflineCacheUpdateService* service = + nsOfflineCacheUpdateService::EnsureService(); + if (service) { + service->FindUpdate(aManifestURI, aAppID, aInBrowser, aCustomProfileDir, + getter_AddRefs(mUpdate)); + mCoalesced = !!mUpdate; + } + if (!EnsureUpdate()) return NS_ERROR_NULL_POINTER; @@ -108,6 +120,11 @@ OfflineCacheUpdateGlue::Init(nsIURI *aManifestURI, if (aDocument) SetDocument(aDocument); + if (mCoalesced) { // already initialized + LOG(("OfflineCacheUpdateGlue %p coalesced with update %p", this, mUpdate.get())); + return NS_OK; + } + return mUpdate->Init(aManifestURI, aDocumentURI, nullptr, aCustomProfileDir, aAppID, aInBrowser); } diff --git a/uriloader/prefetch/OfflineCacheUpdateGlue.h b/uriloader/prefetch/OfflineCacheUpdateGlue.h index 13d29d3f05cd..c275a647d647 100644 --- a/uriloader/prefetch/OfflineCacheUpdateGlue.h +++ b/uriloader/prefetch/OfflineCacheUpdateGlue.h @@ -67,6 +67,7 @@ private: ~OfflineCacheUpdateGlue(); nsRefPtr mUpdate; + bool mCoalesced; /* Document that requested this update */ nsCOMPtr mDocument; diff --git a/uriloader/prefetch/OfflineCacheUpdateParent.cpp b/uriloader/prefetch/OfflineCacheUpdateParent.cpp index 04ced4468a21..ea4e58cc9770 100644 --- a/uriloader/prefetch/OfflineCacheUpdateParent.cpp +++ b/uriloader/prefetch/OfflineCacheUpdateParent.cpp @@ -112,7 +112,7 @@ OfflineCacheUpdateParent::Schedule(const URIParams& aManifestURI, if (!NS_SecurityCompareURIs(manifestURI, documentURI, false)) return NS_ERROR_DOM_SECURITY_ERR; - service->FindUpdate(manifestURI, mAppId, mIsInBrowserElement, + service->FindUpdate(manifestURI, mAppId, mIsInBrowserElement, nullptr, getter_AddRefs(update)); if (!update) { update = new nsOfflineCacheUpdate(); diff --git a/uriloader/prefetch/nsOfflineCacheUpdate.cpp b/uriloader/prefetch/nsOfflineCacheUpdate.cpp index bdd39af57456..7aafdcf4d09d 100644 --- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp +++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp @@ -1994,6 +1994,20 @@ nsOfflineCacheUpdate::IsForGroupID(const nsCSubstring &groupID) return mGroupID == groupID; } +bool +nsOfflineCacheUpdate::IsForProfile(nsIFile* aCustomProfileDir) +{ + if (!mCustomProfileDir && !aCustomProfileDir) + return true; + if (!mCustomProfileDir || !aCustomProfileDir) + return false; + + bool equals; + nsresult rv = mCustomProfileDir->Equals(aCustomProfileDir, &equals); + + return NS_SUCCEEDED(rv) && equals; +} + nsresult nsOfflineCacheUpdate::UpdateFinished(nsOfflineCacheUpdate *aUpdate) { diff --git a/uriloader/prefetch/nsOfflineCacheUpdate.h b/uriloader/prefetch/nsOfflineCacheUpdate.h index 3a29d2d40b5f..083ae1726934 100644 --- a/uriloader/prefetch/nsOfflineCacheUpdate.h +++ b/uriloader/prefetch/nsOfflineCacheUpdate.h @@ -222,6 +222,7 @@ public: void SetOwner(nsOfflineCacheUpdateOwner *aOwner); bool IsForGroupID(const nsCSubstring &groupID); + bool IsForProfile(nsIFile* aCustomProfileDir); virtual nsresult UpdateFinished(nsOfflineCacheUpdate *aUpdate); @@ -337,6 +338,7 @@ public: nsresult FindUpdate(nsIURI *aManifestURI, uint32_t aAppID, bool aInBrowser, + nsIFile *aCustomProfileDir, nsOfflineCacheUpdate **aUpdate); nsresult Schedule(nsIURI *aManifestURI, diff --git a/uriloader/prefetch/nsOfflineCacheUpdateService.cpp b/uriloader/prefetch/nsOfflineCacheUpdateService.cpp index 9b4fe2e986f3..3ff6b02f27a5 100644 --- a/uriloader/prefetch/nsOfflineCacheUpdateService.cpp +++ b/uriloader/prefetch/nsOfflineCacheUpdateService.cpp @@ -491,6 +491,7 @@ nsresult nsOfflineCacheUpdateService::FindUpdate(nsIURI *aManifestURI, uint32_t aAppID, bool aInBrowser, + nsIFile *aCustomProfileDir, nsOfflineCacheUpdate **aUpdate) { nsresult rv; @@ -518,7 +519,7 @@ nsOfflineCacheUpdateService::FindUpdate(nsIURI *aManifestURI, continue; } - if (update->IsForGroupID(groupID)) { + if (update->IsForGroupID(groupID) && update->IsForProfile(aCustomProfileDir)) { update.swap(*aUpdate); return NS_OK; }