Index: chrome/browser/safe_browsing/safe_browsing_database.cc |
diff --git a/chrome/browser/safe_browsing/safe_browsing_database.cc b/chrome/browser/safe_browsing/safe_browsing_database.cc |
index 28cb1b9051e6615cc79d41105e1ebe93deb1e496..a5de866781858abc3bc049c2e7a463f3dd214ea3 100644 |
--- a/chrome/browser/safe_browsing/safe_browsing_database.cc |
+++ b/chrome/browser/safe_browsing/safe_browsing_database.cc |
@@ -432,6 +432,9 @@ base::FilePath SafeBrowsingDatabase::UnwantedSoftwareDBFilename( |
} |
SafeBrowsingStore* SafeBrowsingDatabaseNew::GetStore(const int list_id) { |
+ // Stores are not thread safe. |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
if (list_id == safe_browsing_util::PHISH || |
list_id == safe_browsing_util::MALWARE) { |
return browse_store_.get(); |
@@ -487,8 +490,7 @@ SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew( |
SafeBrowsingStore* side_effect_free_whitelist_store, |
SafeBrowsingStore* ip_blacklist_store, |
SafeBrowsingStore* unwanted_software_store) |
- : creation_loop_(base::MessageLoop::current()), |
- browse_store_(browse_store), |
+ : browse_store_(browse_store), |
download_store_(download_store), |
csd_whitelist_store_(csd_whitelist_store), |
download_whitelist_store_(download_whitelist_store), |
@@ -504,11 +506,11 @@ SafeBrowsingDatabaseNew::SafeBrowsingDatabaseNew( |
SafeBrowsingDatabaseNew::~SafeBrowsingDatabaseNew() { |
// The DCHECK is disabled due to crbug.com/338486 . |
- // DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ // DCHECK(thread_checker_.CalledOnValidThread()); |
} |
void SafeBrowsingDatabaseNew::Init(const base::FilePath& filename_base) { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
// This should not be run multiple times. |
DCHECK(filename_base_.empty()); |
@@ -645,7 +647,7 @@ void SafeBrowsingDatabaseNew::Init(const base::FilePath& filename_base) { |
} |
bool SafeBrowsingDatabaseNew::ResetDatabase() { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
// Delete files on disk. |
// TODO(shess): Hard to see where one might want to delete without a |
@@ -672,6 +674,10 @@ bool SafeBrowsingDatabaseNew::ContainsBrowseUrl( |
const GURL& url, |
std::vector<SBPrefix>* prefix_hits, |
std::vector<SBFullHashResult>* cache_hits) { |
+ // This method is theoretically thread-safe but document that it is currently |
+ // only expected to be called on the IO thread. |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
mattm
2014/12/03 22:57:08
The comments in the header say it's safe to call t
gab
2014/12/04 19:57:27
Ah, right, in fact I just updated all of those com
|
+ |
return PrefixSetContainsUrl( |
url, &browse_prefix_set_, prefix_hits, cache_hits); |
} |
@@ -680,6 +686,10 @@ bool SafeBrowsingDatabaseNew::ContainsUnwantedSoftwareUrl( |
const GURL& url, |
std::vector<SBPrefix>* prefix_hits, |
std::vector<SBFullHashResult>* cache_hits) { |
+ // This method is theoretically thread-safe but document that it is currently |
+ // only expected to be called on the IO thread. |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
return PrefixSetContainsUrl( |
url, &unwanted_software_prefix_set_, prefix_hits, cache_hits); |
} |
@@ -689,6 +699,10 @@ bool SafeBrowsingDatabaseNew::PrefixSetContainsUrl( |
scoped_ptr<safe_browsing::PrefixSet>* prefix_set_getter, |
std::vector<SBPrefix>* prefix_hits, |
std::vector<SBFullHashResult>* cache_hits) { |
+ // This method is theoretically thread-safe but document that it is currently |
+ // only expected to be called on the IO thread. |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
// Clear the results first. |
prefix_hits->clear(); |
cache_hits->clear(); |
@@ -715,11 +729,13 @@ bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes( |
scoped_ptr<safe_browsing::PrefixSet>* prefix_set_getter, |
std::vector<SBPrefix>* prefix_hits, |
std::vector<SBFullHashResult>* cache_hits) { |
+ // This method is theoretically thread-safe but document that it is currently |
+ // only expected to be called on the IO thread. |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
// Used to determine cache expiration. |
const base::Time now = base::Time::Now(); |
- // This function is called on the I/O thread, prevent changes to |
- // filter and caches. |
base::AutoLock locked(lookup_lock_); |
// |prefix_set| is empty until it is either read from disk, or the first |
@@ -751,7 +767,7 @@ bool SafeBrowsingDatabaseNew::PrefixSetContainsUrlHashes( |
bool SafeBrowsingDatabaseNew::ContainsDownloadUrl( |
const std::vector<GURL>& urls, |
std::vector<SBPrefix>* prefix_hits) { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
// Ignore this check when download checking is not enabled. |
if (!download_store_.get()) |
@@ -766,9 +782,10 @@ bool SafeBrowsingDatabaseNew::ContainsDownloadUrl( |
} |
bool SafeBrowsingDatabaseNew::ContainsCsdWhitelistedUrl(const GURL& url) { |
- // This method is theoretically thread-safe but we expect all calls to |
- // originate from the IO thread. |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ // This method is theoretically thread-safe but document that it is currently |
+ // only expected to be called on the IO thread. |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
std::vector<SBFullHash> full_hashes; |
UrlToFullHashes(url, true, &full_hashes); |
return ContainsWhitelistedHashes(csd_whitelist_, full_hashes); |
@@ -783,7 +800,7 @@ bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedUrl(const GURL& url) { |
bool SafeBrowsingDatabaseNew::ContainsExtensionPrefixes( |
const std::vector<SBPrefix>& prefixes, |
std::vector<SBPrefix>* prefix_hits) { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (!extension_blacklist_store_) |
return false; |
@@ -795,6 +812,10 @@ bool SafeBrowsingDatabaseNew::ContainsExtensionPrefixes( |
bool SafeBrowsingDatabaseNew::ContainsSideEffectFreeWhitelistUrl( |
const GURL& url) { |
+ // This method is theoretically thread-safe but document that it is currently |
+ // only expected to be called on the UI thread. |
+ DCHECK_CURRENTLY_ON(BrowserThread::UI); |
+ |
std::string host; |
std::string path; |
std::string query; |
@@ -804,7 +825,6 @@ bool SafeBrowsingDatabaseNew::ContainsSideEffectFreeWhitelistUrl( |
url_to_check += "?" + query; |
SBFullHash full_hash = SBFullHashForString(url_to_check); |
- // This function can be called on any thread, so lock against any changes |
base::AutoLock locked(lookup_lock_); |
// |side_effect_free_whitelist_prefix_set_| is empty until it is either read |
@@ -817,6 +837,10 @@ bool SafeBrowsingDatabaseNew::ContainsSideEffectFreeWhitelistUrl( |
} |
bool SafeBrowsingDatabaseNew::ContainsMalwareIP(const std::string& ip_address) { |
+ // This method is theoretically thread-safe but document that it is currently |
+ // only expected to be called on the IO thread. |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
net::IPAddressNumber ip_number; |
if (!net::ParseIPLiteralToNumber(ip_address, &ip_number)) |
return false; |
@@ -825,7 +849,6 @@ bool SafeBrowsingDatabaseNew::ContainsMalwareIP(const std::string& ip_address) { |
if (ip_number.size() != net::kIPv6AddressSize) |
return false; // better safe than sorry. |
- // This function can be called from any thread. |
base::AutoLock locked(lookup_lock_); |
for (IPBlacklist::const_iterator it = ip_blacklist_.begin(); |
it != ip_blacklist_.end(); |
@@ -851,6 +874,10 @@ bool SafeBrowsingDatabaseNew::ContainsMalwareIP(const std::string& ip_address) { |
bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString( |
const std::string& str) { |
+ // This method is theoretically thread-safe but document that it is currently |
+ // only expected to be called on the IO thread. |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
std::vector<SBFullHash> hashes; |
hashes.push_back(SBFullHashForString(str)); |
return ContainsWhitelistedHashes(download_whitelist_, hashes); |
@@ -859,6 +886,10 @@ bool SafeBrowsingDatabaseNew::ContainsDownloadWhitelistedString( |
bool SafeBrowsingDatabaseNew::ContainsWhitelistedHashes( |
const SBWhitelist& whitelist, |
const std::vector<SBFullHash>& hashes) { |
+ // This method is theoretically thread-safe but document that it is currently |
+ // only expected to be called on the IO thread. |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
base::AutoLock l(lookup_lock_); |
if (whitelist.second) |
return true; |
@@ -877,7 +908,7 @@ void SafeBrowsingDatabaseNew::InsertAddChunk( |
SafeBrowsingStore* store, |
const safe_browsing_util::ListType list_id, |
const SBChunkData& chunk_data) { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(store); |
// The server can give us a chunk that we already have because |
@@ -908,7 +939,7 @@ void SafeBrowsingDatabaseNew::InsertSubChunk( |
SafeBrowsingStore* store, |
const safe_browsing_util::ListType list_id, |
const SBChunkData& chunk_data) { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(store); |
// The server can give us a chunk that we already have because |
@@ -943,7 +974,7 @@ void SafeBrowsingDatabaseNew::InsertSubChunk( |
void SafeBrowsingDatabaseNew::InsertChunks( |
const std::string& list_name, |
const std::vector<SBChunkData*>& chunks) { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (corruption_detected_ || chunks.empty()) |
return; |
@@ -978,7 +1009,7 @@ void SafeBrowsingDatabaseNew::InsertChunks( |
void SafeBrowsingDatabaseNew::DeleteChunks( |
const std::vector<SBChunkDelete>& chunk_deletes) { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (corruption_detected_ || chunk_deletes.empty()) |
return; |
@@ -1009,9 +1040,12 @@ void SafeBrowsingDatabaseNew::CacheHashResults( |
const std::vector<SBPrefix>& prefixes, |
const std::vector<SBFullHashResult>& full_hits, |
const base::TimeDelta& cache_lifetime) { |
+ // This method is theoretically thread-safe but document that it is currently |
+ // only expected to be called on the IO thread. |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
const base::Time expire_after = base::Time::Now() + cache_lifetime; |
- // This is called on the I/O thread, lock against updates. |
base::AutoLock locked(lookup_lock_); |
// Create or reset all cached results for these prefixes. |
@@ -1029,7 +1063,7 @@ void SafeBrowsingDatabaseNew::CacheHashResults( |
bool SafeBrowsingDatabaseNew::UpdateStarted( |
std::vector<SBListChunkRanges>* lists) { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(lists); |
// If |BeginUpdate()| fails, reset the database. |
@@ -1128,7 +1162,7 @@ bool SafeBrowsingDatabaseNew::UpdateStarted( |
} |
void SafeBrowsingDatabaseNew::UpdateFinished(bool update_succeeded) { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
// The update may have failed due to corrupt storage (for instance, |
// an excessive number of invalid add_chunks and sub_chunks). |
@@ -1250,6 +1284,8 @@ void SafeBrowsingDatabaseNew::UpdateWhitelistStore( |
const base::FilePath& store_filename, |
SafeBrowsingStore* store, |
SBWhitelist* whitelist) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
if (!store) |
return; |
@@ -1274,6 +1310,8 @@ int64 SafeBrowsingDatabaseNew::UpdateHashPrefixStore( |
const base::FilePath& store_filename, |
SafeBrowsingStore* store, |
FailureType failure_type) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
// These results are not used after this call. Simply ignore the |
// returned value after FinishUpdate(...). |
safe_browsing::PrefixSetBuilder builder; |
@@ -1295,6 +1333,8 @@ void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore( |
scoped_ptr<safe_browsing::PrefixSet>* prefix_set, |
FailureType finish_failure_type, |
FailureType write_failure_type) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
// Measure the amount of IO during the filter build. |
base::IoCounters io_before, io_after; |
base::ProcessHandle handle = base::GetCurrentProcessHandle(); |
@@ -1372,6 +1412,8 @@ void SafeBrowsingDatabaseNew::UpdatePrefixSetUrlStore( |
} |
void SafeBrowsingDatabaseNew::UpdateSideEffectFreeWhitelistStore() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
safe_browsing::PrefixSetBuilder builder; |
std::vector<SBAddFullHash> add_full_hashes_result; |
@@ -1419,6 +1461,8 @@ void SafeBrowsingDatabaseNew::UpdateSideEffectFreeWhitelistStore() { |
} |
void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
// Note: prefixes will not be empty. The current data store implementation |
// stores all full-length hashes as both full and prefix hashes. |
safe_browsing::PrefixSetBuilder builder; |
@@ -1437,6 +1481,8 @@ void SafeBrowsingDatabaseNew::UpdateIpBlacklistStore() { |
} |
void SafeBrowsingDatabaseNew::HandleCorruptDatabase() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
// Reset the database after the current task has unwound (but only |
// reset once within the scope of a given task). |
if (!reset_factory_.HasWeakPtrs()) { |
@@ -1448,6 +1494,8 @@ void SafeBrowsingDatabaseNew::HandleCorruptDatabase() { |
} |
void SafeBrowsingDatabaseNew::OnHandleCorruptDatabase() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
RecordFailure(FAILURE_DATABASE_CORRUPT_HANDLER); |
corruption_detected_ = true; // Stop updating the database. |
ResetDatabase(); |
@@ -1465,10 +1513,11 @@ void SafeBrowsingDatabaseNew::LoadPrefixSet( |
const base::FilePath& db_filename, |
scoped_ptr<safe_browsing::PrefixSet>* prefix_set, |
FailureType read_failure_type) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
if (!prefix_set) |
return; |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
DCHECK(!filename_base_.empty()); |
const base::FilePath prefix_set_filename = PrefixSetForFilename(db_filename); |
@@ -1492,7 +1541,7 @@ void SafeBrowsingDatabaseNew::LoadPrefixSet( |
} |
bool SafeBrowsingDatabaseNew::Delete() { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(!filename_base_.empty()); |
// TODO(shess): This is a mess. SafeBrowsingFileStore::Delete() closes the |
@@ -1575,7 +1624,7 @@ void SafeBrowsingDatabaseNew::WritePrefixSet( |
const base::FilePath& db_filename, |
safe_browsing::PrefixSet* prefix_set, |
FailureType write_failure_type) { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
if (!prefix_set) |
return; |
@@ -1599,6 +1648,7 @@ void SafeBrowsingDatabaseNew::WritePrefixSet( |
} |
void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
base::AutoLock locked(lookup_lock_); |
whitelist->second = true; |
whitelist->first.clear(); |
@@ -1607,7 +1657,8 @@ void SafeBrowsingDatabaseNew::WhitelistEverything(SBWhitelist* whitelist) { |
void SafeBrowsingDatabaseNew::LoadWhitelist( |
const std::vector<SBAddFullHash>& full_hashes, |
SBWhitelist* whitelist) { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
if (full_hashes.size() > kMaxWhitelistSize) { |
WhitelistEverything(whitelist); |
return; |
@@ -1635,7 +1686,8 @@ void SafeBrowsingDatabaseNew::LoadWhitelist( |
void SafeBrowsingDatabaseNew::LoadIpBlacklist( |
const std::vector<SBAddFullHash>& full_hashes) { |
- DCHECK_EQ(creation_loop_, base::MessageLoop::current()); |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
IPBlacklist new_blacklist; |
for (std::vector<SBAddFullHash>::const_iterator it = full_hashes.begin(); |
it != full_hashes.end(); |
@@ -1674,6 +1726,10 @@ void SafeBrowsingDatabaseNew::LoadIpBlacklist( |
} |
bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { |
+ // This method is theoretically thread-safe but document that it is currently |
+ // only expected to be called on the IO thread. |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
+ |
SBFullHash malware_kill_switch = SBFullHashForString(kMalwareIPKillSwitchUrl); |
std::vector<SBFullHash> full_hashes; |
full_hashes.push_back(malware_kill_switch); |
@@ -1681,5 +1737,9 @@ bool SafeBrowsingDatabaseNew::IsMalwareIPMatchKillSwitchOn() { |
} |
bool SafeBrowsingDatabaseNew::IsCsdWhitelistKillSwitchOn() { |
+ // This method is theoretically thread-safe but document that it is currently |
+ // only expected to be called on the IO thread. |
+ DCHECK_CURRENTLY_ON(BrowserThread::IO); |
mattm
2014/12/03 22:57:08
Actually this function does not look safe. It shou
gab
2014/12/04 19:57:27
Ah ah, indeed, this is exactly why I want to alter
|
+ |
return csd_whitelist_.second; |
} |