Bug 1298329 - Part 0: Add persisted attribute to OriginInfo; r=janv

This commit is contained in:
Tom Tung 2017-01-17 09:41:00 +08:00
Родитель 60d0774ea7
Коммит aa5d3ca4c9
2 изменённых файлов: 135 добавлений и 57 удалений

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

@ -487,21 +487,26 @@ class OriginInfo final
public: public:
OriginInfo(GroupInfo* aGroupInfo, const nsACString& aOrigin, OriginInfo(GroupInfo* aGroupInfo, const nsACString& aOrigin,
uint64_t aUsage, int64_t aAccessTime) uint64_t aUsage, int64_t aAccessTime, bool aPersisted);
: mGroupInfo(aGroupInfo), mOrigin(aOrigin), mUsage(aUsage),
mAccessTime(aAccessTime)
{
MOZ_COUNT_CTOR(OriginInfo);
}
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OriginInfo) NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OriginInfo)
int64_t int64_t
AccessTime() const LockedAccessTime() const
{ {
AssertCurrentThreadOwnsQuotaMutex();
return mAccessTime; return mAccessTime;
} }
bool
LockedPersisted() const
{
AssertCurrentThreadOwnsQuotaMutex();
return mPersisted;
}
private: private:
// Private destructor, to discourage deletion outside of Release(): // Private destructor, to discourage deletion outside of Release():
~OriginInfo() ~OriginInfo()
@ -522,12 +527,16 @@ private:
mAccessTime = aAccessTime; mAccessTime = aAccessTime;
} }
void
LockedPersist();
nsDataHashtable<nsStringHashKey, QuotaObject*> mQuotaObjects; nsDataHashtable<nsStringHashKey, QuotaObject*> mQuotaObjects;
GroupInfo* mGroupInfo; GroupInfo* mGroupInfo;
const nsCString mOrigin; const nsCString mOrigin;
uint64_t mUsage; uint64_t mUsage;
int64_t mAccessTime; int64_t mAccessTime;
bool mPersisted;
}; };
class OriginInfoLRUComparator class OriginInfoLRUComparator
@ -536,14 +545,16 @@ public:
bool bool
Equals(const OriginInfo* a, const OriginInfo* b) const Equals(const OriginInfo* a, const OriginInfo* b) const
{ {
return return a && b ?
a && b ? a->AccessTime() == b->AccessTime() : !a && !b ? true : false; a->LockedAccessTime() == b->LockedAccessTime() :
!a && !b ? true : false;
} }
bool bool
LessThan(const OriginInfo* a, const OriginInfo* b) const LessThan(const OriginInfo* a, const OriginInfo* b) const
{ {
return a && b ? a->AccessTime() < b->AccessTime() : b ? true : false; return
a && b ? a->LockedAccessTime() < b->LockedAccessTime() : b ? true : false;
} }
}; };
@ -2717,8 +2728,10 @@ QuotaObject::MaybeUpdateSize(int64_t aSize, bool aTruncate)
AssertNoUnderflow(quotaManager->mTemporaryStorageUsage, delta); AssertNoUnderflow(quotaManager->mTemporaryStorageUsage, delta);
quotaManager->mTemporaryStorageUsage -= delta; quotaManager->mTemporaryStorageUsage -= delta;
AssertNoUnderflow(groupInfo->mUsage, delta); if (!mOriginInfo->LockedPersisted()) {
groupInfo->mUsage -= delta; AssertNoUnderflow(groupInfo->mUsage, delta);
groupInfo->mUsage -= delta;
}
AssertNoUnderflow(mOriginInfo->mUsage, delta); AssertNoUnderflow(mOriginInfo->mUsage, delta);
mOriginInfo->mUsage -= delta; mOriginInfo->mUsage -= delta;
@ -2742,20 +2755,23 @@ QuotaObject::MaybeUpdateSize(int64_t aSize, bool aTruncate)
// Temporary storage has no limit for origin usage (there's a group and the // Temporary storage has no limit for origin usage (there's a group and the
// global limit though). // global limit though).
AssertNoOverflow(groupInfo->mUsage, delta); uint64_t newGroupUsage = groupInfo->mUsage;
uint64_t newGroupUsage = groupInfo->mUsage + delta; if (!mOriginInfo->LockedPersisted()) {
AssertNoOverflow(groupInfo->mUsage, delta);
newGroupUsage += delta;
uint64_t groupUsage = groupInfo->mUsage; uint64_t groupUsage = groupInfo->mUsage;
if (complementaryGroupInfo) { if (complementaryGroupInfo) {
AssertNoOverflow(groupUsage, complementaryGroupInfo->mUsage); AssertNoOverflow(groupUsage, complementaryGroupInfo->mUsage);
groupUsage += complementaryGroupInfo->mUsage; groupUsage += complementaryGroupInfo->mUsage;
} }
// Temporary storage has a hard limit for group usage (20 % of the global // Temporary storage has a hard limit for group usage (20 % of the global
// limit). // limit).
AssertNoOverflow(groupUsage, delta); AssertNoOverflow(groupUsage, delta);
if (groupUsage + delta > quotaManager->GetGroupLimit()) { if (groupUsage + delta > quotaManager->GetGroupLimit()) {
return false; return false;
}
} }
AssertNoOverflow(quotaManager->mTemporaryStorageUsage, delta); AssertNoOverflow(quotaManager->mTemporaryStorageUsage, delta);
@ -2771,6 +2787,8 @@ QuotaObject::MaybeUpdateSize(int64_t aSize, bool aTruncate)
quotaManager->LockedCollectOriginsForEviction(delta, locks); quotaManager->LockedCollectOriginsForEviction(delta, locks);
if (!sizeToBeFreed) { if (!sizeToBeFreed) {
// XXX prompt for asking to delete persistent origins if there is any
// persistent origin.
return false; return false;
} }
@ -2816,26 +2834,29 @@ QuotaObject::MaybeUpdateSize(int64_t aSize, bool aTruncate)
AssertNoOverflow(mOriginInfo->mUsage, delta); AssertNoOverflow(mOriginInfo->mUsage, delta);
newUsage = mOriginInfo->mUsage + delta; newUsage = mOriginInfo->mUsage + delta;
AssertNoOverflow(groupInfo->mUsage, delta); newGroupUsage = groupInfo->mUsage;
newGroupUsage = groupInfo->mUsage + delta; if (!mOriginInfo->LockedPersisted()) {
AssertNoOverflow(groupInfo->mUsage, delta);
newGroupUsage += delta;
groupUsage = groupInfo->mUsage; uint64_t groupUsage = groupInfo->mUsage;
if (complementaryGroupInfo) { if (complementaryGroupInfo) {
AssertNoOverflow(groupUsage, complementaryGroupInfo->mUsage); AssertNoOverflow(groupUsage, complementaryGroupInfo->mUsage);
groupUsage += complementaryGroupInfo->mUsage; groupUsage += complementaryGroupInfo->mUsage;
} }
AssertNoOverflow(groupUsage, delta); AssertNoOverflow(groupUsage, delta);
if (groupUsage + delta > quotaManager->GetGroupLimit()) { if (groupUsage + delta > quotaManager->GetGroupLimit()) {
// Unfortunately some other thread increased the group usage in the // Unfortunately some other thread increased the group usage in the
// meantime and we are not below the group limit anymore. // meantime and we are not below the group limit anymore.
// However, the origin eviction must be finalized in this case too. // However, the origin eviction must be finalized in this case too.
MutexAutoUnlock autoUnlock(quotaManager->mQuotaMutex); MutexAutoUnlock autoUnlock(quotaManager->mQuotaMutex);
quotaManager->FinalizeOriginEviction(locks); quotaManager->FinalizeOriginEviction(locks);
return false; return false;
}
} }
AssertNoOverflow(quotaManager->mTemporaryStorageUsage, delta); AssertNoOverflow(quotaManager->mTemporaryStorageUsage, delta);
@ -2847,7 +2868,9 @@ QuotaObject::MaybeUpdateSize(int64_t aSize, bool aTruncate)
// Ok, we successfully freed enough space and the operation can continue // Ok, we successfully freed enough space and the operation can continue
// without throwing the quota error. // without throwing the quota error.
mOriginInfo->mUsage = newUsage; mOriginInfo->mUsage = newUsage;
groupInfo->mUsage = newGroupUsage; if (!mOriginInfo->LockedPersisted()) {
groupInfo->mUsage = newGroupUsage;
}
quotaManager->mTemporaryStorageUsage = newTemporaryStorageUsage;; quotaManager->mTemporaryStorageUsage = newTemporaryStorageUsage;;
// Some other thread could increase the size in the meantime, but no more // Some other thread could increase the size in the meantime, but no more
@ -2865,7 +2888,9 @@ QuotaObject::MaybeUpdateSize(int64_t aSize, bool aTruncate)
} }
mOriginInfo->mUsage = newUsage; mOriginInfo->mUsage = newUsage;
groupInfo->mUsage = newGroupUsage; if (!mOriginInfo->LockedPersisted()) {
groupInfo->mUsage = newGroupUsage;
}
quotaManager->mTemporaryStorageUsage = newTemporaryStorageUsage; quotaManager->mTemporaryStorageUsage = newTemporaryStorageUsage;
mSize = aSize; mSize = aSize;
@ -3141,6 +3166,10 @@ QuotaManager::CollectOriginsForEviction(
MOZ_ASSERT(originInfo->mGroupInfo->mPersistenceType != MOZ_ASSERT(originInfo->mGroupInfo->mPersistenceType !=
PERSISTENCE_TYPE_PERSISTENT); PERSISTENCE_TYPE_PERSISTENT);
if (originInfo->LockedPersisted()) {
continue;
}
OriginScope originScope = OriginScope::FromOrigin(originInfo->mOrigin); OriginScope originScope = OriginScope::FromOrigin(originInfo->mOrigin);
bool match = false; bool match = false;
@ -3393,7 +3422,8 @@ QuotaManager::InitQuotaForOrigin(PersistenceType aPersistenceType,
const nsACString& aGroup, const nsACString& aGroup,
const nsACString& aOrigin, const nsACString& aOrigin,
uint64_t aUsageBytes, uint64_t aUsageBytes,
int64_t aAccessTime) int64_t aAccessTime,
bool aPersisted)
{ {
AssertIsOnIOThread(); AssertIsOnIOThread();
MOZ_ASSERT(aPersistenceType != PERSISTENCE_TYPE_PERSISTENT); MOZ_ASSERT(aPersistenceType != PERSISTENCE_TYPE_PERSISTENT);
@ -3414,7 +3444,7 @@ QuotaManager::InitQuotaForOrigin(PersistenceType aPersistenceType,
} }
RefPtr<OriginInfo> originInfo = RefPtr<OriginInfo> originInfo =
new OriginInfo(groupInfo, aOrigin, aUsageBytes, aAccessTime); new OriginInfo(groupInfo, aOrigin, aUsageBytes, aAccessTime, aPersisted);
groupInfo->LockedAddOriginInfo(originInfo); groupInfo->LockedAddOriginInfo(originInfo);
} }
@ -3883,7 +3913,7 @@ QuotaManager::InitializeRepository(PersistenceType aPersistenceType)
} }
rv = InitializeOrigin(aPersistenceType, group, origin, timestamp, rv = InitializeOrigin(aPersistenceType, group, origin, timestamp,
childDirectory); /* aPersisted */ false, childDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
@ -3900,6 +3930,7 @@ QuotaManager::InitializeOrigin(PersistenceType aPersistenceType,
const nsACString& aGroup, const nsACString& aGroup,
const nsACString& aOrigin, const nsACString& aOrigin,
int64_t aAccessTime, int64_t aAccessTime,
bool aPersisted,
nsIFile* aDirectory) nsIFile* aDirectory)
{ {
AssertIsOnIOThread(); AssertIsOnIOThread();
@ -3972,7 +4003,7 @@ QuotaManager::InitializeOrigin(PersistenceType aPersistenceType,
if (trackQuota) { if (trackQuota) {
InitQuotaForOrigin(aPersistenceType, aGroup, aOrigin, InitQuotaForOrigin(aPersistenceType, aGroup, aOrigin,
usageInfo->TotalUsage(), aAccessTime); usageInfo->TotalUsage(), aAccessTime, aPersisted);
} }
return NS_OK; return NS_OK;
@ -4857,7 +4888,7 @@ QuotaManager::EnsureOriginIsInitializedInternal(
} }
rv = InitializeOrigin(aPersistenceType, aGroup, aOrigin, timestamp, rv = InitializeOrigin(aPersistenceType, aGroup, aOrigin, timestamp,
directory); /* aPersisted */ true, directory);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
mInitializedOrigins.AppendElement(aOrigin); mInitializedOrigins.AppendElement(aOrigin);
@ -4881,7 +4912,7 @@ QuotaManager::EnsureOriginIsInitializedInternal(
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = InitializeOrigin(aPersistenceType, aGroup, aOrigin, timestamp, rv = InitializeOrigin(aPersistenceType, aGroup, aOrigin, timestamp,
directory); /* aPersisted */ false, directory);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
@ -5242,6 +5273,9 @@ QuotaManager::CheckTemporaryStorageLimits()
for (uint32_t i = 0; i < originInfos.Length(); i++) { for (uint32_t i = 0; i < originInfos.Length(); i++) {
OriginInfo* originInfo = originInfos[i]; OriginInfo* originInfo = originInfos[i];
if (originInfo->LockedPersisted()) {
continue;
}
doomedOriginInfos.AppendElement(originInfo); doomedOriginInfos.AppendElement(originInfo);
groupUsage -= originInfo->mUsage; groupUsage -= originInfo->mUsage;
@ -5281,7 +5315,8 @@ QuotaManager::CheckTemporaryStorageLimits()
} }
for (uint32_t index = originInfos.Length(); index > 0; index--) { for (uint32_t index = originInfos.Length(); index > 0; index--) {
if (doomedOriginInfos.Contains(originInfos[index - 1])) { if (doomedOriginInfos.Contains(originInfos[index - 1]) ||
originInfos[index - 1]->LockedPersisted()) {
originInfos.RemoveElementAt(index - 1); originInfos.RemoveElementAt(index - 1);
} }
} }
@ -5304,6 +5339,13 @@ QuotaManager::CheckTemporaryStorageLimits()
for (uint32_t index = 0; index < doomedOriginInfos.Length(); index++) { for (uint32_t index = 0; index < doomedOriginInfos.Length(); index++) {
OriginInfo* doomedOriginInfo = doomedOriginInfos[index]; OriginInfo* doomedOriginInfo = doomedOriginInfos[index];
#ifdef DEBUG
{
MutexAutoLock lock(mQuotaMutex);
MOZ_ASSERT(!doomedOriginInfo->LockedPersisted());
}
#endif
DeleteFilesForOrigin(doomedOriginInfo->mGroupInfo->mPersistenceType, DeleteFilesForOrigin(doomedOriginInfo->mGroupInfo->mPersistenceType,
doomedOriginInfo->mOrigin); doomedOriginInfo->mOrigin);
} }
@ -5407,6 +5449,18 @@ QuotaManager::GetDirectoryLockTable(PersistenceType aPersistenceType)
* Local class implementations * Local class implementations
******************************************************************************/ ******************************************************************************/
OriginInfo::OriginInfo(GroupInfo* aGroupInfo, const nsACString& aOrigin,
uint64_t aUsage, int64_t aAccessTime, bool aPersisted)
: mGroupInfo(aGroupInfo), mOrigin(aOrigin), mUsage(aUsage),
mAccessTime(aAccessTime), mPersisted(aPersisted)
{
MOZ_ASSERT(aGroupInfo);
MOZ_ASSERT_IF(aPersisted,
aGroupInfo->mPersistenceType == PERSISTENCE_TYPE_DEFAULT);
MOZ_COUNT_CTOR(OriginInfo);
}
void void
OriginInfo::LockedDecreaseUsage(int64_t aSize) OriginInfo::LockedDecreaseUsage(int64_t aSize)
{ {
@ -5415,8 +5469,10 @@ OriginInfo::LockedDecreaseUsage(int64_t aSize)
AssertNoUnderflow(mUsage, aSize); AssertNoUnderflow(mUsage, aSize);
mUsage -= aSize; mUsage -= aSize;
AssertNoUnderflow(mGroupInfo->mUsage, aSize); if (!LockedPersisted()) {
mGroupInfo->mUsage -= aSize; AssertNoUnderflow(mGroupInfo->mUsage, aSize);
mGroupInfo->mUsage -= aSize;
}
QuotaManager* quotaManager = QuotaManager::Get(); QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager); MOZ_ASSERT(quotaManager);
@ -5425,6 +5481,20 @@ OriginInfo::LockedDecreaseUsage(int64_t aSize)
quotaManager->mTemporaryStorageUsage -= aSize; quotaManager->mTemporaryStorageUsage -= aSize;
} }
void
OriginInfo::LockedPersist()
{
AssertCurrentThreadOwnsQuotaMutex();
MOZ_ASSERT(mGroupInfo->mPersistenceType == PERSISTENCE_TYPE_DEFAULT);
MOZ_ASSERT(!mPersisted);
mPersisted = true;
// Remove Usage from GroupInfo
AssertNoUnderflow(mGroupInfo->mUsage, mUsage);
mGroupInfo->mUsage -= mUsage;
}
already_AddRefed<OriginInfo> already_AddRefed<OriginInfo>
GroupInfo::LockedGetOriginInfo(const nsACString& aOrigin) GroupInfo::LockedGetOriginInfo(const nsACString& aOrigin)
{ {
@ -5449,8 +5519,10 @@ GroupInfo::LockedAddOriginInfo(OriginInfo* aOriginInfo)
"Replacing an existing entry!"); "Replacing an existing entry!");
mOriginInfos.AppendElement(aOriginInfo); mOriginInfos.AppendElement(aOriginInfo);
AssertNoOverflow(mUsage, aOriginInfo->mUsage); if (!aOriginInfo->LockedPersisted()) {
mUsage += aOriginInfo->mUsage; AssertNoOverflow(mUsage, aOriginInfo->mUsage);
mUsage += aOriginInfo->mUsage;
}
QuotaManager* quotaManager = QuotaManager::Get(); QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager); MOZ_ASSERT(quotaManager);
@ -5466,8 +5538,10 @@ GroupInfo::LockedRemoveOriginInfo(const nsACString& aOrigin)
for (uint32_t index = 0; index < mOriginInfos.Length(); index++) { for (uint32_t index = 0; index < mOriginInfos.Length(); index++) {
if (mOriginInfos[index]->mOrigin == aOrigin) { if (mOriginInfos[index]->mOrigin == aOrigin) {
AssertNoUnderflow(mUsage, mOriginInfos[index]->mUsage); if (!mOriginInfos[index]->LockedPersisted()) {
mUsage -= mOriginInfos[index]->mUsage; AssertNoUnderflow(mUsage, mOriginInfos[index]->mUsage);
mUsage -= mOriginInfos[index]->mUsage;
}
QuotaManager* quotaManager = QuotaManager::Get(); QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager); MOZ_ASSERT(quotaManager);
@ -5494,8 +5568,10 @@ GroupInfo::LockedRemoveOriginInfos()
for (uint32_t index = mOriginInfos.Length(); index > 0; index--) { for (uint32_t index = mOriginInfos.Length(); index > 0; index--) {
OriginInfo* originInfo = mOriginInfos[index - 1]; OriginInfo* originInfo = mOriginInfos[index - 1];
AssertNoUnderflow(mUsage, originInfo->mUsage); if (!originInfo->LockedPersisted()) {
mUsage -= originInfo->mUsage; AssertNoUnderflow(mUsage, originInfo->mUsage);
mUsage -= originInfo->mUsage;
}
AssertNoUnderflow(quotaManager->mTemporaryStorageUsage, originInfo->mUsage); AssertNoUnderflow(quotaManager->mTemporaryStorageUsage, originInfo->mUsage);
quotaManager->mTemporaryStorageUsage -= originInfo->mUsage; quotaManager->mTemporaryStorageUsage -= originInfo->mUsage;

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

@ -147,7 +147,8 @@ public:
const nsACString& aGroup, const nsACString& aGroup,
const nsACString& aOrigin, const nsACString& aOrigin,
uint64_t aUsageBytes, uint64_t aUsageBytes,
int64_t aAccessTime); int64_t aAccessTime,
bool aPersisted);
void void
DecreaseUsageForOrigin(PersistenceType aPersistenceType, DecreaseUsageForOrigin(PersistenceType aPersistenceType,
@ -460,6 +461,7 @@ private:
const nsACString& aGroup, const nsACString& aGroup,
const nsACString& aOrigin, const nsACString& aOrigin,
int64_t aAccessTime, int64_t aAccessTime,
bool aPersisted,
nsIFile* aDirectory); nsIFile* aDirectory);
void void