mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-13 07:24:47 +00:00
Bug 916781 - DOM storage instances across managers must not share single eTLD+1 limit check, r=smaug
This commit is contained in:
parent
7c5b6ad83d
commit
3cc47ba520
@ -75,12 +75,12 @@ NS_IMETHODIMP_(void) DOMStorageCacheBridge::Release(void)
|
||||
// DOMStorageCache
|
||||
|
||||
DOMStorageCache::DOMStorageCache(const nsACString* aScope)
|
||||
: mManager(nullptr)
|
||||
, mScope(*aScope)
|
||||
: mScope(*aScope)
|
||||
, mMonitor("DOMStorageCache")
|
||||
, mLoaded(false)
|
||||
, mLoadResult(NS_OK)
|
||||
, mInitialized(false)
|
||||
, mPersistent(false)
|
||||
, mSessionOnlyDataSetActive(false)
|
||||
, mPreloadTelemetryRecorded(false)
|
||||
{
|
||||
@ -128,15 +128,17 @@ DOMStorageCache::Init(DOMStorageManager* aManager,
|
||||
return;
|
||||
}
|
||||
|
||||
mManager = aManager;
|
||||
mInitialized = true;
|
||||
mPrincipal = aPrincipal;
|
||||
mPersistent = aPersistent;
|
||||
mQuotaScope = aQuotaScope.IsEmpty() ? mScope : aQuotaScope;
|
||||
|
||||
if (mPersistent) {
|
||||
mManager = aManager;
|
||||
Preload();
|
||||
}
|
||||
|
||||
mUsage = aManager->GetScopeUsage(mQuotaScope);
|
||||
}
|
||||
|
||||
inline bool
|
||||
@ -208,12 +210,8 @@ DOMStorageCache::ProcessUsageDelta(uint32_t aGetDataSetIndex, const int64_t aDel
|
||||
}
|
||||
|
||||
// Now check eTLD+1 limit
|
||||
GetDatabase();
|
||||
if (sDatabase) {
|
||||
DOMStorageUsage* usage = sDatabase->GetScopeUsage(mQuotaScope);
|
||||
if (!usage->CheckAndSetETLD1UsageDelta(aGetDataSetIndex, aDelta)) {
|
||||
return false;
|
||||
}
|
||||
if (mUsage && !mUsage->CheckAndSetETLD1UsageDelta(aGetDataSetIndex, aDelta)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update size in our data set
|
||||
@ -235,7 +233,6 @@ DOMStorageCache::Preload()
|
||||
}
|
||||
|
||||
sDatabase->AsyncPreload(this);
|
||||
sDatabase->GetScopeUsage(mQuotaScope);
|
||||
}
|
||||
|
||||
namespace { // anon
|
||||
@ -686,6 +683,11 @@ DOMStorageCache::LoadWait()
|
||||
}
|
||||
}
|
||||
|
||||
// DOMStorageUsageBridge
|
||||
|
||||
NS_IMPL_ADDREF(DOMStorageUsageBridge)
|
||||
NS_IMPL_RELEASE(DOMStorageUsageBridge)
|
||||
|
||||
// DOMStorageUsage
|
||||
|
||||
DOMStorageUsage::DOMStorageUsage(const nsACString& aScope)
|
||||
|
@ -20,6 +20,7 @@ namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class DOMStorage;
|
||||
class DOMStorageUsage;
|
||||
class DOMStorageManager;
|
||||
class DOMStorageDBBridge;
|
||||
|
||||
@ -170,6 +171,10 @@ private:
|
||||
// Cache could potentially overlive the manager, hence the hard ref.
|
||||
nsRefPtr<DOMStorageManager> mManager;
|
||||
|
||||
// Reference to the usage counter object we check on for eTLD+1 quota limit.
|
||||
// Obtained from the manager during initialization (Init method).
|
||||
nsRefPtr<DOMStorageUsage> mUsage;
|
||||
|
||||
// Timer that holds this cache alive for a while after it has been preloaded.
|
||||
nsCOMPtr<nsITimer> mKeepAliveTimer;
|
||||
|
||||
@ -227,10 +232,17 @@ private:
|
||||
class DOMStorageUsageBridge
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD_(nsrefcnt) AddRef(void);
|
||||
NS_IMETHOD_(nsrefcnt) Release(void);
|
||||
|
||||
virtual ~DOMStorageUsageBridge() {}
|
||||
|
||||
virtual const nsCString& Scope() = 0;
|
||||
virtual void LoadUsage(const int64_t aUsage) = 0;
|
||||
|
||||
protected:
|
||||
ThreadSafeAutoRefCnt mRefCnt;
|
||||
NS_DECL_OWNINGTHREAD
|
||||
};
|
||||
|
||||
class DOMStorageUsage : public DOMStorageUsageBridge
|
||||
|
@ -37,21 +37,6 @@ DOMStorageDBBridge::DOMStorageDBBridge()
|
||||
{
|
||||
}
|
||||
|
||||
DOMStorageUsage*
|
||||
DOMStorageDBBridge::GetScopeUsage(const nsACString& aScope)
|
||||
{
|
||||
DOMStorageUsage* usage;
|
||||
if (mUsages.Get(aScope, &usage)) {
|
||||
return usage;
|
||||
}
|
||||
|
||||
usage = new DOMStorageUsage(aScope);
|
||||
AsyncGetUsage(usage);
|
||||
mUsages.Put(aScope, usage);
|
||||
|
||||
return usage;
|
||||
}
|
||||
|
||||
|
||||
DOMStorageDBThread::DOMStorageDBThread()
|
||||
: mThread(nullptr)
|
||||
|
@ -81,13 +81,6 @@ public:
|
||||
|
||||
// Get the complete list of scopes having data
|
||||
virtual void GetScopesHavingData(InfallibleTArray<nsCString>* aScopes) = 0;
|
||||
|
||||
// Returns object keeping usage cache for the scope.
|
||||
DOMStorageUsage* GetScopeUsage(const nsACString& aScope);
|
||||
|
||||
protected:
|
||||
// Keeps usage cache objects for eTLD+1 scopes we have touched.
|
||||
nsClassHashtable<nsCStringHashKey, DOMStorageUsage> mUsages;
|
||||
};
|
||||
|
||||
// The implementation of the the database engine, this directly works
|
||||
@ -157,7 +150,7 @@ public:
|
||||
friend class PendingOperations;
|
||||
OperationType mType;
|
||||
nsRefPtr<DOMStorageCacheBridge> mCache;
|
||||
DOMStorageUsageBridge* mUsage;
|
||||
nsRefPtr<DOMStorageUsageBridge> mUsage;
|
||||
nsString mKey;
|
||||
nsString mValue;
|
||||
nsCString mScope;
|
||||
|
@ -253,12 +253,7 @@ DOMStorageDBChild::RecvLoadDone(const nsCString& aScope, const nsresult& aRv)
|
||||
bool
|
||||
DOMStorageDBChild::RecvLoadUsage(const nsCString& aScope, const int64_t& aUsage)
|
||||
{
|
||||
DOMStorageDBBridge* db = DOMStorageCache::GetDatabase();
|
||||
if (!db) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DOMStorageUsageBridge* scopeUsage = db->GetScopeUsage(aScope);
|
||||
nsRefPtr<DOMStorageUsageBridge> scopeUsage = mManager->GetScopeUsage(aScope);
|
||||
scopeUsage->LoadUsage(aUsage);
|
||||
return true;
|
||||
}
|
||||
@ -404,7 +399,7 @@ DOMStorageDBParent::RecvAsyncGetUsage(const nsCString& aScope)
|
||||
}
|
||||
|
||||
// The object releases it self in LoadUsage method
|
||||
UsageParentBridge* usage = new UsageParentBridge(this, aScope);
|
||||
nsRefPtr<UsageParentBridge> usage = new UsageParentBridge(this, aScope);
|
||||
db->AsyncGetUsage(usage);
|
||||
return true;
|
||||
}
|
||||
@ -733,7 +728,6 @@ DOMStorageDBParent::UsageParentBridge::LoadUsage(const int64_t aUsage)
|
||||
{
|
||||
nsRefPtr<UsageRunnable> r = new UsageRunnable(mParent, mScope, aUsage);
|
||||
NS_DispatchToMainThread(r);
|
||||
delete this;
|
||||
}
|
||||
|
||||
} // ::dom
|
||||
|
@ -269,6 +269,28 @@ DOMStorageManager::GetCache(const nsACString& aScope) const
|
||||
return entry->cache();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMStorageUsage>
|
||||
DOMStorageManager::GetScopeUsage(const nsACString& aScope)
|
||||
{
|
||||
nsRefPtr<DOMStorageUsage> usage;
|
||||
if (mUsages.Get(aScope, &usage)) {
|
||||
return usage.forget();
|
||||
}
|
||||
|
||||
usage = new DOMStorageUsage(aScope);
|
||||
|
||||
if (mType == LocalStorage) {
|
||||
DOMStorageDBBridge* db = DOMStorageCache::StartDatabase();
|
||||
if (db) {
|
||||
db->AsyncGetUsage(usage);
|
||||
}
|
||||
}
|
||||
|
||||
mUsages.Put(aScope, usage);
|
||||
|
||||
return usage.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMStorageCache>
|
||||
DOMStorageManager::PutCache(const nsACString& aScope,
|
||||
nsIPrincipal* aPrincipal)
|
||||
@ -283,7 +305,7 @@ DOMStorageManager::PutCache(const nsACString& aScope,
|
||||
case SessionStorage:
|
||||
// Lifetime handled by the manager, don't persist
|
||||
entry->HardRef();
|
||||
cache->Init(nullptr, false, aPrincipal, quotaScope);
|
||||
cache->Init(this, false, aPrincipal, quotaScope);
|
||||
break;
|
||||
|
||||
case LocalStorage:
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "DOMStorageCache.h"
|
||||
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -35,6 +37,8 @@ public:
|
||||
static uint32_t GetQuota();
|
||||
// Gets (but not ensures) cache for the given scope
|
||||
DOMStorageCache* GetCache(const nsACString& aScope) const;
|
||||
// Returns object keeping usage cache for the scope.
|
||||
already_AddRefed<DOMStorageUsage> GetScopeUsage(const nsACString& aScope);
|
||||
|
||||
protected:
|
||||
DOMStorageManager(nsPIDOMStorage::StorageType aType);
|
||||
@ -97,6 +101,9 @@ private:
|
||||
void* aClosure);
|
||||
|
||||
protected:
|
||||
// Keeps usage cache objects for eTLD+1 scopes we have touched.
|
||||
nsDataHashtable<nsCStringHashKey, nsRefPtr<DOMStorageUsage> > mUsages;
|
||||
|
||||
friend class DOMStorageCache;
|
||||
// Releases cache since it is no longer referrered by any DOMStorage object.
|
||||
virtual void DropCache(DOMStorageCache* aCache);
|
||||
|
Loading…
x
Reference in New Issue
Block a user