Bug 1342397 - Properly reset stuff when failing to create LookupCache for update. r=gcp

MozReview-Commit-ID: 1ecI2lFIj2U
This commit is contained in:
Henry Chang
2017-02-25 00:22:39 +08:00
parent 31d462f19b
commit 73fc8b0a2d
2 changed files with 42 additions and 26 deletions

View File

@@ -732,7 +732,11 @@ Classifier::ApplyUpdates(nsTArray<TableUpdate*>* aUpdates)
LOG(("Failed to copy in-use directory for update."));
return rv;
}
CopyInUseLookupCacheForUpdate(); // i.e. mNewLookupCaches will be setup.
rv = CopyInUseLookupCacheForUpdate(); // i.e. mNewLookupCaches will be setup.
if (NS_FAILED(rv)) {
LOG(("Failed to create lookup caches from copied files."));
return rv;
}
}
LOG(("Applying %" PRIuSIZE " table updates.", aUpdates->Length()));
@@ -1017,7 +1021,7 @@ Classifier::CopyInUseDirForUpdate()
return NS_OK;
}
void
nsresult
Classifier::CopyInUseLookupCacheForUpdate()
{
MOZ_ASSERT(mNewLookupCaches.IsEmpty(), "Update intermediaries is forgotten to "
@@ -1028,8 +1032,12 @@ Classifier::CopyInUseLookupCacheForUpdate()
// Another option is to NOT pre-open these LookupCaches and
// do a "merge" instead of "swap" after update.
for (auto c: mLookupCaches) {
Unused << GetLookupCacheForUpdate(c->TableName());
if (!GetLookupCacheForUpdate(c->TableName())) {
return NS_ERROR_FAILURE;
}
}
return NS_OK;
}
nsresult
@@ -1333,20 +1341,14 @@ Classifier::UpdateCache(TableUpdate* aUpdate)
LookupCache *
Classifier::GetLookupCache(const nsACString& aTable, bool aForUpdate)
{
if (aForUpdate) {
return GetLookupCacheFrom(aTable, mNewLookupCaches, mUpdatingDirectory);
}
return GetLookupCacheFrom(aTable, mLookupCaches, mRootStoreDirectory);
}
nsTArray<LookupCache*>& lookupCaches = aForUpdate ? mNewLookupCaches
: mLookupCaches;
auto& rootStoreDirectory = aForUpdate ? mUpdatingDirectory
: mRootStoreDirectory;
LookupCache *
Classifier::GetLookupCacheFrom(const nsACString& aTable,
nsTArray<LookupCache*>& aLookupCaches,
nsIFile* aRootStoreDirectory)
{
for (uint32_t i = 0; i < aLookupCaches.Length(); i++) {
if (aLookupCaches[i]->TableName().Equals(aTable)) {
return aLookupCaches[i];
for (auto c: lookupCaches) {
if (c->TableName().Equals(aTable)) {
return c;
}
}
@@ -1356,9 +1358,9 @@ Classifier::GetLookupCacheFrom(const nsACString& aTable,
UniquePtr<LookupCache> cache;
nsCString provider = GetProvider(aTable);
if (StringEndsWith(aTable, NS_LITERAL_CSTRING("-proto"))) {
cache = MakeUnique<LookupCacheV4>(aTable, provider, aRootStoreDirectory);
cache = MakeUnique<LookupCacheV4>(aTable, provider, rootStoreDirectory);
} else {
cache = MakeUnique<LookupCacheV2>(aTable, provider, aRootStoreDirectory);
cache = MakeUnique<LookupCacheV2>(aTable, provider, rootStoreDirectory);
}
nsresult rv = cache->Init();
@@ -1366,14 +1368,28 @@ Classifier::GetLookupCacheFrom(const nsACString& aTable,
return nullptr;
}
rv = cache->Open();
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_FILE_CORRUPTED) {
Reset();
}
if (NS_SUCCEEDED(rv)) {
lookupCaches.AppendElement(cache.get());
return cache.release();
}
// At this point we failed to open LookupCache.
//
// GetLookupCache for update and for other usage will run on update thread
// and worker thread respectively (Bug 1339760). Removing stuff only in
// their own realms potentially increases the concurrency.
if (aForUpdate) {
// Remove intermediaries no matter if it's due to file corruption or not.
RemoveUpdateIntermediaries();
return nullptr;
}
aLookupCaches.AppendElement(cache.get());
return cache.release();
// Non-update case.
if (rv == NS_ERROR_FILE_CORRUPTED) {
Reset(); // Not including the update intermediaries.
}
return nullptr;
}
nsresult