diff --git a/dom/indexedDB/IndexedDatabaseManager.cpp b/dom/indexedDB/IndexedDatabaseManager.cpp index 7b6dbfe411d..e4fd84d93ed 100644 --- a/dom/indexedDB/IndexedDatabaseManager.cpp +++ b/dom/indexedDB/IndexedDatabaseManager.cpp @@ -608,7 +608,9 @@ IndexedDatabaseManager::AsyncDeleteFile(FileManager* aFileManager, // See if we're currently clearing the storages for this origin. If so then // we pretend that we've already deleted everything. - if (quotaManager->IsClearOriginPending(aFileManager->Origin())) { + if (quotaManager->IsClearOriginPending( + aFileManager->Origin(), + Nullable(aFileManager->Type()))) { return NS_OK; } diff --git a/dom/indexedDB/OpenDatabaseHelper.cpp b/dom/indexedDB/OpenDatabaseHelper.cpp index dc2c585c342..bef10fa967f 100644 --- a/dom/indexedDB/OpenDatabaseHelper.cpp +++ b/dom/indexedDB/OpenDatabaseHelper.cpp @@ -2146,7 +2146,8 @@ OpenDatabaseHelper::StartSetVersion() NS_ASSERTION(quotaManager, "This should never be null!"); rv = quotaManager->AcquireExclusiveAccess( - mDatabase, mDatabase->Origin(), helper, + mDatabase, mDatabase->Origin(), + Nullable(mDatabase->Type()), helper, &VersionChangeEventsRunnable::QueueVersionChange, helper); IDB_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); @@ -2176,7 +2177,8 @@ OpenDatabaseHelper::StartDelete() NS_ASSERTION(quotaManager, "This should never be null!"); rv = quotaManager->AcquireExclusiveAccess( - mDatabase, mDatabase->Origin(), helper, + mDatabase, mDatabase->Origin(), + Nullable(mDatabase->Type()), helper, &VersionChangeEventsRunnable::QueueVersionChange, helper); IDB_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); diff --git a/dom/quota/PersistenceType.h b/dom/quota/PersistenceType.h index 87a5d6032f1..171f061c4c3 100644 --- a/dom/quota/PersistenceType.h +++ b/dom/quota/PersistenceType.h @@ -55,6 +55,28 @@ PersistenceTypeFromText(const nsACString& aText) MOZ_ASSUME_UNREACHABLE("Should never get here!"); } +inline nsresult +NullablePersistenceTypeFromText(const nsACString& aText, + Nullable *aPersistenceType) +{ + if (aText.IsVoid()) { + *aPersistenceType = Nullable(); + return NS_OK; + } + + if (aText.EqualsLiteral("persistent")) { + *aPersistenceType = Nullable(PERSISTENCE_TYPE_PERSISTENT); + return NS_OK; + } + + if (aText.EqualsLiteral("temporary")) { + *aPersistenceType = Nullable(PERSISTENCE_TYPE_TEMPORARY); + return NS_OK; + } + + return NS_ERROR_UNEXPECTED; +} + inline mozilla::dom::StorageType PersistenceTypeToStorage(PersistenceType aPersistenceType) { diff --git a/dom/quota/QuotaManager.cpp b/dom/quota/QuotaManager.cpp index c30e329202b..569d12191d8 100644 --- a/dom/quota/QuotaManager.cpp +++ b/dom/quota/QuotaManager.cpp @@ -188,8 +188,10 @@ class OriginClearRunnable MOZ_FINAL : public nsRunnable, public: NS_DECL_ISUPPORTS_INHERITED - OriginClearRunnable(const OriginOrPatternString& aOriginOrPattern) + OriginClearRunnable(const OriginOrPatternString& aOriginOrPattern, + Nullable aPersistenceType) : mOriginOrPattern(aOriginOrPattern), + mPersistenceType(aPersistenceType), mCallbackState(Pending) { } @@ -228,6 +230,7 @@ public: private: OriginOrPatternString mOriginOrPattern; + Nullable mPersistenceType; CallbackState mCallbackState; }; @@ -2280,6 +2283,7 @@ NS_IMETHODIMP QuotaManager::ClearStoragesForURI(nsIURI* aURI, uint32_t aAppId, bool aInMozBrowserOnly, + const nsACString& aPersistenceType, uint8_t aOptionalArgCount) { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); @@ -2302,19 +2306,23 @@ QuotaManager::ClearStoragesForURI(nsIURI* aURI, nsAutoCString pattern; GetOriginPatternString(aAppId, aInMozBrowserOnly, origin, pattern); + Nullable persistenceType; + rv = NullablePersistenceTypeFromText(aPersistenceType, &persistenceType); + NS_ENSURE_SUCCESS(rv, rv); + // If there is a pending or running clear operation for this origin, return // immediately. - if (IsClearOriginPending(pattern)) { + if (IsClearOriginPending(pattern, persistenceType)) { return NS_OK; } OriginOrPatternString oops = OriginOrPatternString::FromPattern(pattern); // Queue up the origin clear runnable. - nsRefPtr runnable = new OriginClearRunnable(oops); + nsRefPtr runnable = + new OriginClearRunnable(oops, persistenceType); - rv = WaitForOpenAllowed(oops, Nullable(), EmptyCString(), - runnable); + rv = WaitForOpenAllowed(oops, persistenceType, EmptyCString(), runnable); NS_ENSURE_SUCCESS(rv, rv); runnable->AdvanceState(); @@ -2324,10 +2332,13 @@ QuotaManager::ClearStoragesForURI(nsIURI* aURI, matches.Find(mLiveStorages, pattern); for (uint32_t index = 0; index < matches.Length(); index++) { - // We need to grab references to any live storages here to prevent them - // from dying while we invalidate them. - nsCOMPtr storage = matches[index]; - storage->Invalidate(); + if (persistenceType.IsNull() || + matches[index]->Type() == persistenceType.Value()) { + // We need to grab references to any live storages here to prevent them + // from dying while we invalidate them. + nsCOMPtr storage = matches[index]; + storage->Invalidate(); + } } // After everything has been invalidated the helper should be dispatched to @@ -2640,6 +2651,7 @@ QuotaManager::LockedRemoveQuotaForOrigin(PersistenceType aPersistenceType, nsresult QuotaManager::AcquireExclusiveAccess(const nsACString& aPattern, + Nullable aPersistenceType, nsIOfflineStorage* aStorage, AcquireListener* aListener, WaitingOnStoragesCallback aCallback, @@ -2649,16 +2661,9 @@ QuotaManager::AcquireExclusiveAccess(const nsACString& aPattern, NS_ASSERTION(aListener, "Need a listener!"); // Find the right SynchronizedOp. - SynchronizedOp* op; - if (aStorage) { - op = FindSynchronizedOp(aPattern, - Nullable(aStorage->Type()), - aStorage->Id()); - } - else { - op = FindSynchronizedOp(aPattern, Nullable(), - EmptyCString()); - } + SynchronizedOp* op = + FindSynchronizedOp(aPattern, aPersistenceType, + aStorage ? aStorage->Id() : EmptyCString()); NS_ASSERTION(op, "We didn't find a SynchronizedOp?"); NS_ASSERTION(!op->mListener, "SynchronizedOp already has a listener?!?"); @@ -2840,20 +2845,23 @@ QuotaManager::ClearStoragesForApp(uint32_t aAppId, bool aBrowserOnly) nsAutoCString pattern; GetOriginPatternStringMaybeIgnoreBrowser(aAppId, aBrowserOnly, pattern); + // Clear both temporary and persistent storages. + Nullable persistenceType; + // If there is a pending or running clear operation for this app, return // immediately. - if (IsClearOriginPending(pattern)) { + if (IsClearOriginPending(pattern, persistenceType)) { return NS_OK; } OriginOrPatternString oops = OriginOrPatternString::FromPattern(pattern); // Queue up the origin clear runnable. - nsRefPtr runnable = new OriginClearRunnable(oops); + nsRefPtr runnable = + new OriginClearRunnable(oops, persistenceType); nsresult rv = - WaitForOpenAllowed(oops, Nullable(), EmptyCString(), - runnable); + WaitForOpenAllowed(oops, persistenceType, EmptyCString(), runnable); NS_ENSURE_SUCCESS(rv, rv); runnable->AdvanceState(); @@ -3507,8 +3515,9 @@ OriginClearRunnable::Run() // Now we have to wait until the thread pool is done with all of the // storages we care about. nsresult rv = - quotaManager->AcquireExclusiveAccess(mOriginOrPattern, this, - InvalidateOpenedStorages, nullptr); + quotaManager->AcquireExclusiveAccess(mOriginOrPattern, mPersistenceType, + this, InvalidateOpenedStorages, + nullptr); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; @@ -3519,9 +3528,12 @@ OriginClearRunnable::Run() AdvanceState(); - DeleteFiles(quotaManager, PERSISTENCE_TYPE_PERSISTENT); - - DeleteFiles(quotaManager, PERSISTENCE_TYPE_TEMPORARY); + if (mPersistenceType.IsNull()) { + DeleteFiles(quotaManager, PERSISTENCE_TYPE_PERSISTENT); + DeleteFiles(quotaManager, PERSISTENCE_TYPE_TEMPORARY); + } else { + DeleteFiles(quotaManager, mPersistenceType.Value()); + } // Now dispatch back to the main thread. if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) { @@ -3536,8 +3548,7 @@ OriginClearRunnable::Run() NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); // Tell the QuotaManager that we're done. - quotaManager->AllowNextSynchronizedOp(mOriginOrPattern, - Nullable(), + quotaManager->AllowNextSynchronizedOp(mOriginOrPattern, mPersistenceType, EmptyCString()); return NS_OK; @@ -3863,7 +3874,8 @@ ResetOrClearRunnable::Run() // Now we have to wait until the thread pool is done with all of the // storages we care about. nsresult rv = - quotaManager->AcquireExclusiveAccess(NullCString(), this, + quotaManager->AcquireExclusiveAccess(NullCString(), + Nullable(), this, InvalidateOpenedStorages, nullptr); NS_ENSURE_SUCCESS(rv, rv); diff --git a/dom/quota/QuotaManager.h b/dom/quota/QuotaManager.h index 29a163e17d3..90c506b2fd8 100644 --- a/dom/quota/QuotaManager.h +++ b/dom/quota/QuotaManager.h @@ -198,23 +198,25 @@ public: nsresult AcquireExclusiveAccess(nsIOfflineStorage* aStorage, const nsACString& aOrigin, + Nullable aPersistenceType, AcquireListener* aListener, WaitingOnStoragesCallback aCallback, void* aClosure) { NS_ASSERTION(aStorage, "Need a storage here!"); - return AcquireExclusiveAccess(aOrigin, aStorage, aListener, aCallback, - aClosure); + return AcquireExclusiveAccess(aOrigin, aPersistenceType, aStorage, + aListener, aCallback, aClosure); } nsresult AcquireExclusiveAccess(const nsACString& aOrigin, + Nullable aPersistenceType, AcquireListener* aListener, WaitingOnStoragesCallback aCallback, void* aClosure) { - return AcquireExclusiveAccess(aOrigin, nullptr, aListener, aCallback, - aClosure); + return AcquireExclusiveAccess(aOrigin, aPersistenceType, nullptr, + aListener, aCallback, aClosure); } void @@ -223,10 +225,10 @@ public: const nsACString& aId); bool - IsClearOriginPending(const nsACString& aPattern) + IsClearOriginPending(const nsACString& aPattern, + Nullable aPersistenceType) { - return !!FindSynchronizedOp(aPattern, Nullable(), - EmptyCString()); + return !!FindSynchronizedOp(aPattern, aPersistenceType, EmptyCString()); } nsresult @@ -369,6 +371,7 @@ private: nsresult AcquireExclusiveAccess(const nsACString& aOrigin, + Nullable aPersistenceType, nsIOfflineStorage* aStorage, AcquireListener* aListener, WaitingOnStoragesCallback aCallback, diff --git a/dom/quota/nsIQuotaManager.idl b/dom/quota/nsIQuotaManager.idl index cb864e81b35..5c534000585 100644 --- a/dom/quota/nsIQuotaManager.idl +++ b/dom/quota/nsIQuotaManager.idl @@ -10,7 +10,7 @@ interface nsIQuotaRequest; interface nsIURI; interface nsIUsageCallback; -[scriptable, builtinclass, uuid(f19a03ae-e97d-41e9-95dd-681b910c4093)] +[scriptable, builtinclass, uuid(2968fcd5-1872-4ddc-8c16-62b27e357f31)] interface nsIQuotaManager : nsISupports { /** @@ -51,7 +51,8 @@ interface nsIQuotaManager : nsISupports void clearStoragesForURI(in nsIURI aURI, [optional] in unsigned long aAppId, - [optional] in boolean aInMozBrowserOnly); + [optional] in boolean aInMozBrowserOnly, + [optional] in ACString aPersistenceType); /** * Resets quota and storage management. This can be used to force diff --git a/js/xpconnect/src/XPCQuickStubs.h b/js/xpconnect/src/XPCQuickStubs.h index e6341e4f327..de889166063 100644 --- a/js/xpconnect/src/XPCQuickStubs.h +++ b/js/xpconnect/src/XPCQuickStubs.h @@ -312,8 +312,8 @@ class xpc_qsACString : public xpc_qsBasicString public: xpc_qsACString(JSContext *cx, JS::HandleValue v, JS::MutableHandleValue pval, bool notpassed, - StringificationBehavior nullBehavior, - StringificationBehavior undefinedBehavior); + StringificationBehavior nullBehavior = eNull, + StringificationBehavior undefinedBehavior = eNull); }; /**