Bug 1354968 - Avoid concurrent access of mTableRefreshness. r=francois
mTableRefreshness, a non-thread-safe object, might be accessed on worker thread and update thread cocurrently. To solve this issue, on update thread we only insert data to mNewTableRefreshness and merge to mTableRefreshness on the worker thread later. MozReview-Commit-ID: 9WgoeYfWVfK
This commit is contained in:
@@ -621,6 +621,8 @@ Classifier::RemoveUpdateIntermediaries()
|
|||||||
}
|
}
|
||||||
mNewLookupCaches.Clear();
|
mNewLookupCaches.Clear();
|
||||||
|
|
||||||
|
mNewTableFreshness.Clear();
|
||||||
|
|
||||||
// Remove the "old" directory. (despite its looking-new name)
|
// Remove the "old" directory. (despite its looking-new name)
|
||||||
if (NS_FAILED(mUpdatingDirectory->Remove(true))) {
|
if (NS_FAILED(mUpdatingDirectory->Remove(true))) {
|
||||||
// If the directory is locked from removal for some reason,
|
// If the directory is locked from removal for some reason,
|
||||||
@@ -685,16 +687,21 @@ Classifier::SwapInNewTablesAndCleanup()
|
|||||||
// up later.
|
// up later.
|
||||||
MergeNewLookupCaches();
|
MergeNewLookupCaches();
|
||||||
|
|
||||||
// Step 3. Re-generate active tables based on on-disk tables.
|
// Step 3. Merge mTableFreshnessForUpdate.
|
||||||
|
for (auto itr = mNewTableFreshness.ConstIter(); !itr.Done(); itr.Next()) {
|
||||||
|
mTableFreshness.Put(itr.Key(), itr.Data());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4. Re-generate active tables based on on-disk tables.
|
||||||
rv = RegenActiveTables();
|
rv = RegenActiveTables();
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
LOG(("Failed to re-generate active tables!"));
|
LOG(("Failed to re-generate active tables!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4. Clean up intermediaries for update.
|
// Step 5. Clean up intermediaries for update.
|
||||||
RemoveUpdateIntermediaries();
|
RemoveUpdateIntermediaries();
|
||||||
|
|
||||||
// Step 5. Invalidate cached tableRequest request.
|
// Step 6. Invalidate cached tableRequest request.
|
||||||
mIsTableRequestResultOutdated = true;
|
mIsTableRequestResultOutdated = true;
|
||||||
|
|
||||||
LOG(("Done swap in updated tables."));
|
LOG(("Done swap in updated tables."));
|
||||||
@@ -1299,7 +1306,7 @@ Classifier::UpdateHashStore(nsTArray<TableUpdate*>* aUpdates,
|
|||||||
|
|
||||||
int64_t now = (PR_Now() / PR_USEC_PER_SEC);
|
int64_t now = (PR_Now() / PR_USEC_PER_SEC);
|
||||||
LOG(("Successfully updated %s", store.TableName().get()));
|
LOG(("Successfully updated %s", store.TableName().get()));
|
||||||
mTableFreshness.Put(store.TableName(), now);
|
mNewTableFreshness.Put(store.TableName(), now);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@@ -1401,7 +1408,7 @@ Classifier::UpdateTableV4(nsTArray<TableUpdate*>* aUpdates,
|
|||||||
|
|
||||||
int64_t now = (PR_Now() / PR_USEC_PER_SEC);
|
int64_t now = (PR_Now() / PR_USEC_PER_SEC);
|
||||||
LOG(("Successfully updated %s\n", PromiseFlatCString(aTable).get()));
|
LOG(("Successfully updated %s\n", PromiseFlatCString(aTable).get()));
|
||||||
mTableFreshness.Put(aTable, now);
|
mNewTableFreshness.Put(aTable, now);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,6 +214,7 @@ private:
|
|||||||
uint32_t mHashKey;
|
uint32_t mHashKey;
|
||||||
// Stores the last time a given table was updated (seconds).
|
// Stores the last time a given table was updated (seconds).
|
||||||
TableFreshnessMap mTableFreshness;
|
TableFreshnessMap mTableFreshness;
|
||||||
|
TableFreshnessMap mNewTableFreshness;
|
||||||
|
|
||||||
// In-memory cache for the result of TableRequest. See
|
// In-memory cache for the result of TableRequest. See
|
||||||
// nsIUrlClassifierDBService.getTables for the format.
|
// nsIUrlClassifierDBService.getTables for the format.
|
||||||
|
|||||||
Reference in New Issue
Block a user