Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(577)

Side by Side Diff: chrome/browser/safe_browsing/safe_browsing_database.h

Issue 794273002: Introduce SafeBrowsingDatabase::ThreadSafeStateManager. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@a6_dedup_sideeffectfreeWLcode
Patch Set: fix memory management Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/safe_browsing/safe_browsing_database.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_ 5 #ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_
6 #define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_ 6 #define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_
7 7
8 #include <map> 8 #include <map>
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 // matching hash prefixes which had no cached results and |cache_hits| 110 // matching hash prefixes which had no cached results and |cache_hits|
111 // contains any matching cached gethash results. This function is safe to 111 // contains any matching cached gethash results. This function is safe to
112 // call from any thread. 112 // call from any thread.
113 virtual bool ContainsUnwantedSoftwareUrl( 113 virtual bool ContainsUnwantedSoftwareUrl(
114 const GURL& url, 114 const GURL& url,
115 std::vector<SBPrefix>* prefix_hits, 115 std::vector<SBPrefix>* prefix_hits,
116 std::vector<SBFullHashResult>* cache_hits) = 0; 116 std::vector<SBFullHashResult>* cache_hits) = 0;
117 117
118 // Returns false if none of |urls| are in Download database. If it returns 118 // Returns false if none of |urls| are in Download database. If it returns
119 // true, |prefix_hits| should contain the prefixes for the URLs that were in 119 // true, |prefix_hits| should contain the prefixes for the URLs that were in
120 // the database. This function can ONLY be called from the creation thread. 120 // the database. This function can ONLY be accessed from creation thread.
121 virtual bool ContainsDownloadUrl(const std::vector<GURL>& urls, 121 virtual bool ContainsDownloadUrl(const std::vector<GURL>& urls,
122 std::vector<SBPrefix>* prefix_hits) = 0; 122 std::vector<SBPrefix>* prefix_hits) = 0;
123 123
124 // Returns false if |url| is not on the client-side phishing detection 124 // Returns false if |url| is not on the client-side phishing detection
125 // whitelist. Otherwise, this function returns true. Note: the whitelist 125 // whitelist. Otherwise, this function returns true. Note: the whitelist
126 // only contains full-length hashes so we don't return any prefix hit. This 126 // only contains full-length hashes so we don't return any prefix hit. This
127 // function is safe to call from any thread. 127 // function is safe to call from any thread.
128 virtual bool ContainsCsdWhitelistedUrl(const GURL& url) = 0; 128 virtual bool ContainsCsdWhitelistedUrl(const GURL& url) = 0;
129 129
130 // The download whitelist is used for two purposes: a white-domain list of 130 // The download whitelist is used for two purposes: a white-domain list of
131 // sites that are considered to host only harmless binaries as well as a 131 // sites that are considered to host only harmless binaries as well as a
132 // whitelist of arbitrary strings such as hashed certificate authorities that 132 // whitelist of arbitrary strings such as hashed certificate authorities that
133 // are considered to be trusted. The two methods below let you lookup the 133 // are considered to be trusted. The two methods below let you lookup the
134 // whitelist either for a URL or an arbitrary string. These methods will 134 // whitelist either for a URL or an arbitrary string. These methods will
135 // return false if no match is found and true otherwise. This function is safe 135 // return false if no match is found and true otherwise. This function is safe
136 // to call from any thread. 136 // to call from any thread.
137 virtual bool ContainsDownloadWhitelistedUrl(const GURL& url) = 0; 137 virtual bool ContainsDownloadWhitelistedUrl(const GURL& url) = 0;
138 virtual bool ContainsDownloadWhitelistedString(const std::string& str) = 0; 138 virtual bool ContainsDownloadWhitelistedString(const std::string& str) = 0;
139 139
140 // Populates |prefix_hits| with any prefixes in |prefixes| that have matches 140 // Populates |prefix_hits| with any prefixes in |prefixes| that have matches
141 // in the database. 141 // in the database.
142 // 142 //
143 // This function can ONLY be called from the creation thread. 143 // This function can ONLY be accessed from the creation thread.
144 virtual bool ContainsExtensionPrefixes( 144 virtual bool ContainsExtensionPrefixes(
145 const std::vector<SBPrefix>& prefixes, 145 const std::vector<SBPrefix>& prefixes,
146 std::vector<SBPrefix>* prefix_hits) = 0; 146 std::vector<SBPrefix>* prefix_hits) = 0;
147 147
148 // Returns false unless the hash of |url| is on the side-effect free 148 // Returns false unless the hash of |url| is on the side-effect free
149 // whitelist. This function is safe to call from any thread. 149 // whitelist. This function is safe to call from any thread.
150 virtual bool ContainsSideEffectFreeWhitelistUrl(const GURL& url) = 0; 150 virtual bool ContainsSideEffectFreeWhitelistUrl(const GURL& url) = 0;
151 151
152 // Returns true iff the given IP is currently on the csd malware IP blacklist. 152 // Returns true iff the given IP is currently on the csd malware IP blacklist.
153 // This function is safe to call from any thread. 153 // This function is safe to call from any thread.
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 // A SafeBrowsing whitelist contains a list of whitelisted full-hashes (stored 360 // A SafeBrowsing whitelist contains a list of whitelisted full-hashes (stored
361 // in a sorted vector) as well as a boolean flag indicating whether all 361 // in a sorted vector) as well as a boolean flag indicating whether all
362 // lookups in the whitelist should be considered matches for safety. 362 // lookups in the whitelist should be considered matches for safety.
363 typedef std::pair<std::vector<SBFullHash>, bool> SBWhitelist; 363 typedef std::pair<std::vector<SBFullHash>, bool> SBWhitelist;
364 364
365 // This map holds a csd malware IP blacklist which maps a prefix mask 365 // This map holds a csd malware IP blacklist which maps a prefix mask
366 // to a set of hashed blacklisted IP prefixes. Each IP prefix is a hashed 366 // to a set of hashed blacklisted IP prefixes. Each IP prefix is a hashed
367 // IPv6 IP prefix using SHA-1. 367 // IPv6 IP prefix using SHA-1.
368 typedef std::map<std::string, base::hash_set<std::string> > IPBlacklist; 368 typedef std::map<std::string, base::hash_set<std::string> > IPBlacklist;
369 369
370 bool PrefixSetContainsUrl( 370 typedef std::map<SBPrefix, SBCachedFullHashResult> PrefixGetHashCache;
371 const GURL& url, 371
372 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter, 372 // The ThreadSafeStateManager holds the SafeBrowsingDatabase's state which
373 std::vector<SBPrefix>* prefix_hits, 373 // must be accessed in a thread-safe fashion. It must be constructed on the
374 std::vector<SBFullHashResult>* cache_hits); 374 // SafeBrowsingDatabaseManager's main thread. The main thread will then be the
375 // only thread on which this state can be modified; allowing for unlocked
376 // reads on the main thread and thus avoiding contention while performing
377 // intensive operations such as writing that state to disk. The state can only
378 // be accessed via (Read|Write)Transactions obtained through this class which
379 // will automatically handle thread-safety.
380 class ThreadSafeStateManager {
381 public:
382 // Identifiers for stores held by the ThreadSafeStateManager. Allows helper
383 // methods to start a transaction themselves and keep it as short as
384 // possible rather than force callers to start the transaction early to pass
385 // a store pointer to the said helper methods.
386 enum class SBWhitelistId {
387 CSD,
388 DOWNLOAD,
389 };
390 enum class PrefixSetId {
391 BROWSE,
392 SIDE_EFFECT_FREE_WHITELIST,
393 UNWANTED_SOFTWARE,
394 };
395
396 // Obtained through BeginReadTransaction(NoLockOnMainThread)?(): a
397 // ReadTransaction allows read-only observations of the
398 // ThreadSafeStateManager's state. The |prefix_gethash_cache_| has a special
399 // allowance to be writable from a ReadTransaction but can't benefit from
400 // unlocked ReadTransactions. ReadTransaction should be held for the
401 // shortest amount of time possible (e.g., release it before computing final
402 // results if possible).
403 class ReadTransaction;
404
405 // Obtained through BeginWriteTransaction(): a WriteTransaction allows
406 // modification of the ThreadSafeStateManager's state. It should be used for
407 // the shortest amount of time possible (e.g., pre-compute the new state
408 // before grabbing a WriteTransaction to swap it in atomically).
409 class WriteTransaction;
410
411 explicit ThreadSafeStateManager(const base::ThreadChecker& thread_checker);
412 ~ThreadSafeStateManager();
413
414 scoped_ptr<ReadTransaction> BeginReadTransaction();
415 scoped_ptr<ReadTransaction> BeginReadTransactionNoLockOnMainThread();
416 scoped_ptr<WriteTransaction> BeginWriteTransaction();
417
418 private:
419 // The SafeBrowsingDatabase's ThreadChecker, used to verify that writes are
420 // only made on its main thread. This is important as it allows reading from
421 // the main thread without holding the lock.
422 const base::ThreadChecker& thread_checker_;
423
424 // Lock for protecting access to this class' state.
425 mutable base::Lock lock_;
426
427 SBWhitelist csd_whitelist_;
428 SBWhitelist download_whitelist_;
429
430 // The IP blacklist should be small. At most a couple hundred IPs.
431 IPBlacklist ip_blacklist_;
432
433 // PrefixSets to speed up lookups for particularly large lists. The
434 // PrefixSet themselves are never modified, instead a new one is swapped in
435 // on update.
436 scoped_ptr<const safe_browsing::PrefixSet> browse_prefix_set_;
437 scoped_ptr<const safe_browsing::PrefixSet>
438 side_effect_free_whitelist_prefix_set_;
439 scoped_ptr<const safe_browsing::PrefixSet> unwanted_software_prefix_set_;
440
441 // Cache of gethash results for prefix stores. Entries should not be used if
442 // they are older than their expire_after field. Cached misses will have
443 // empty full_hashes field. Cleared on each update. The cache is "mutable"
444 // as it can be written to from any transaction holding the lock, including
445 // ReadTransactions.
446 mutable PrefixGetHashCache prefix_gethash_cache_;
447
448 DISALLOW_COPY_AND_ASSIGN(ThreadSafeStateManager);
449 };
450
451 // Forward the above inner-definitions to alleviate some verbosity in the
452 // impl.
453 using SBWhitelistId = ThreadSafeStateManager::SBWhitelistId;
454 using PrefixSetId = ThreadSafeStateManager::PrefixSetId;
455 using ReadTransaction = ThreadSafeStateManager::ReadTransaction;
456 using WriteTransaction = ThreadSafeStateManager::WriteTransaction;
457
458 bool PrefixSetContainsUrl(const GURL& url,
459 PrefixSetId prefix_set_id,
460 std::vector<SBPrefix>* prefix_hits,
461 std::vector<SBFullHashResult>* cache_hits);
375 462
376 // Exposed for testing of PrefixSetContainsUrlHashes() on the 463 // Exposed for testing of PrefixSetContainsUrlHashes() on the
377 // PrefixSet backing kMalwareList. 464 // PrefixSet backing kMalwareList.
378 bool ContainsBrowseUrlHashesForTesting( 465 bool ContainsBrowseUrlHashesForTesting(
379 const std::vector<SBFullHash>& full_hashes, 466 const std::vector<SBFullHash>& full_hashes,
380 std::vector<SBPrefix>* prefix_hits, 467 std::vector<SBPrefix>* prefix_hits,
381 std::vector<SBFullHashResult>* cache_hits); 468 std::vector<SBFullHashResult>* cache_hits);
382 469
383 bool PrefixSetContainsUrlHashes( 470 bool PrefixSetContainsUrlHashes(const std::vector<SBFullHash>& full_hashes,
384 const std::vector<SBFullHash>& full_hashes, 471 PrefixSetId prefix_set_id,
385 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set_getter, 472 std::vector<SBPrefix>* prefix_hits,
386 std::vector<SBPrefix>* prefix_hits, 473 std::vector<SBFullHashResult>* cache_hits);
387 std::vector<SBFullHashResult>* cache_hits);
388 474
389 // Returns true if the whitelist is disabled or if any of the given hashes 475 // Returns true if the whitelist is disabled or if any of the given hashes
390 // matches the whitelist. 476 // matches the whitelist.
391 bool ContainsWhitelistedHashes(const SBWhitelist& whitelist, 477 bool ContainsWhitelistedHashes(SBWhitelistId whitelist_id,
392 const std::vector<SBFullHash>& hashes); 478 const std::vector<SBFullHash>& hashes);
393 479
394 // Return the browse_store_, download_store_, download_whitelist_store or 480 // Return the browse_store_, download_store_, download_whitelist_store or
395 // csd_whitelist_store_ based on list_id. 481 // csd_whitelist_store_ based on list_id.
396 SafeBrowsingStore* GetStore(int list_id); 482 SafeBrowsingStore* GetStore(int list_id);
397 483
398 // Deletes the files on disk. 484 // Deletes the files on disk.
399 bool Delete(); 485 bool Delete();
400 486
401 // Load the prefix set in "|db_filename| Prefix Set" off disk, if available, 487 // Load the prefix set in "|db_filename| Prefix Set" off disk, if available,
402 // and stores it in |prefix_set|. |read_failure_type| provides a 488 // and stores it in the PrefixSet identified by |prefix_set_id|.
403 // caller-specific error code to be used on failure. 489 // |read_failure_type| provides a caller-specific error code to be used on
490 // failure. This method should only ever be called during initialization as
491 // it performs some disk IO while holding a transaction (for the sake of
492 // avoiding uncessary back-and-forth interactions with the lock during
493 // Init()).
404 void LoadPrefixSet(const base::FilePath& db_filename, 494 void LoadPrefixSet(const base::FilePath& db_filename,
405 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, 495 ThreadSafeStateManager::WriteTransaction* txn,
496 PrefixSetId prefix_set_id,
406 FailureType read_failure_type); 497 FailureType read_failure_type);
407 498
408 // Writes the current prefix set "|db_filename| Prefix Set" on disk. 499 // Writes the current prefix set "|db_filename| Prefix Set" on disk.
409 // |write_failure_type| provides a caller-specific error code to be used on 500 // |write_failure_type| provides a caller-specific error code to be used on
410 // failure. 501 // failure.
411 void WritePrefixSet(const base::FilePath& db_filename, 502 void WritePrefixSet(const base::FilePath& db_filename,
412 const safe_browsing::PrefixSet* prefix_set, 503 const safe_browsing::PrefixSet* prefix_set,
413 FailureType write_failure_type); 504 FailureType write_failure_type);
414 505
415 // Loads the given full-length hashes to the given whitelist. If the number 506 // Loads the given full-length hashes to the given whitelist. If the number
416 // of hashes is too large or if the kill switch URL is on the whitelist 507 // of hashes is too large or if the kill switch URL is on the whitelist
417 // we will whitelist everything. 508 // we will whitelist everything.
418 void LoadWhitelist(const std::vector<SBAddFullHash>& full_hashes, 509 void LoadWhitelist(const std::vector<SBAddFullHash>& full_hashes,
419 SBWhitelist* whitelist); 510 SBWhitelistId whitelist_id);
420
421 // Call this method if an error occured with the given whitelist. This will
422 // result in all lookups to the whitelist to return true.
423 void WhitelistEverything(SBWhitelist* whitelist);
424 511
425 // Parses the IP blacklist from the given full-length hashes. 512 // Parses the IP blacklist from the given full-length hashes.
426 void LoadIpBlacklist(const std::vector<SBAddFullHash>& full_hashes); 513 void LoadIpBlacklist(const std::vector<SBAddFullHash>& full_hashes);
427 514
428 // Helpers for handling database corruption. 515 // Helpers for handling database corruption.
429 // |OnHandleCorruptDatabase()| runs |ResetDatabase()| and sets 516 // |OnHandleCorruptDatabase()| runs |ResetDatabase()| and sets
430 // |corruption_detected_|, |HandleCorruptDatabase()| posts 517 // |corruption_detected_|, |HandleCorruptDatabase()| posts
431 // |OnHandleCorruptDatabase()| to the current thread, to be run 518 // |OnHandleCorruptDatabase()| to the current thread, to be run
432 // after the current task completes. 519 // after the current task completes.
433 // TODO(shess): Wire things up to entirely abort the update 520 // TODO(shess): Wire things up to entirely abort the update
(...skipping 12 matching lines...) Expand all
446 // Returns the size in bytes of the store after the update. 533 // Returns the size in bytes of the store after the update.
447 int64 UpdateHashPrefixStore(const base::FilePath& store_filename, 534 int64 UpdateHashPrefixStore(const base::FilePath& store_filename,
448 SafeBrowsingStore* store, 535 SafeBrowsingStore* store,
449 FailureType failure_type); 536 FailureType failure_type);
450 537
451 // Updates a PrefixStore store for URLs (|url_store|) which is backed on disk 538 // Updates a PrefixStore store for URLs (|url_store|) which is backed on disk
452 // by a "|db_filename| Prefix Set" file. Specific failure types are provided 539 // by a "|db_filename| Prefix Set" file. Specific failure types are provided
453 // to highlight the specific store who made the initial request on failure. 540 // to highlight the specific store who made the initial request on failure.
454 // |store_full_hashes_in_prefix_set| dictates whether full_hashes from the 541 // |store_full_hashes_in_prefix_set| dictates whether full_hashes from the
455 // |url_store| should be cached in the |prefix_set| as well. 542 // |url_store| should be cached in the |prefix_set| as well.
456 void UpdatePrefixSetUrlStore( 543 void UpdatePrefixSetUrlStore(const base::FilePath& db_filename,
457 const base::FilePath& db_filename, 544 SafeBrowsingStore* url_store,
458 SafeBrowsingStore* url_store, 545 PrefixSetId prefix_set_id,
459 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, 546 FailureType finish_failure_type,
460 FailureType finish_failure_type, 547 FailureType write_failure_type,
461 FailureType write_failure_type, 548 bool store_full_hashes_in_prefix_set);
462 bool store_full_hashes_in_prefix_set);
463 549
464 void UpdateUrlStore(SafeBrowsingStore* url_store, 550 void UpdateUrlStore(SafeBrowsingStore* url_store,
465 scoped_ptr<const safe_browsing::PrefixSet>* prefix_set, 551 PrefixSetId prefix_set_id,
466 FailureType failure_type); 552 FailureType failure_type);
467 553
468 void UpdateWhitelistStore(const base::FilePath& store_filename, 554 void UpdateWhitelistStore(const base::FilePath& store_filename,
469 SafeBrowsingStore* store, 555 SafeBrowsingStore* store,
470 SBWhitelist* whitelist); 556 SBWhitelistId whitelist_id);
471 void UpdateIpBlacklistStore(); 557 void UpdateIpBlacklistStore();
472 558
473 // Used to verify that various calls are made from the thread the 559 // Returns a raw pointer to ThreadSafeStateManager's PrefixGetHashCache for
474 // object was created on (i.e., the safe_browsing_thread). 560 // testing. This should only be used in unit tests (where multi-threading and
561 // synchronization are not problematic).
562 PrefixGetHashCache* GetUnsynchronizedPrefixGetHashCacheForTesting();
563
475 base::ThreadChecker thread_checker_; 564 base::ThreadChecker thread_checker_;
476 565
566 ThreadSafeStateManager state_manager_;
567
477 // The base filename passed to Init(), used to generate the store and prefix 568 // The base filename passed to Init(), used to generate the store and prefix
478 // set filenames used to store data on disk. 569 // set filenames used to store data on disk.
479 base::FilePath filename_base_; 570 base::FilePath filename_base_;
480 571
481 // Underlying persistent store for chunk data. 572 // Underlying persistent store for chunk data.
482 // For browsing related (phishing and malware URLs) chunks and prefixes. 573 // For browsing related (phishing and malware URLs) chunks and prefixes.
483 scoped_ptr<SafeBrowsingStore> browse_store_; 574 scoped_ptr<SafeBrowsingStore> browse_store_;
484 575
485 // For download related (download URL and binary hash) chunks and prefixes. 576 // For download related (download URL and binary hash) chunks and prefixes.
486 scoped_ptr<SafeBrowsingStore> download_store_; 577 scoped_ptr<SafeBrowsingStore> download_store_;
(...skipping 11 matching lines...) Expand all
498 589
499 // For side-effect free whitelist. 590 // For side-effect free whitelist.
500 scoped_ptr<SafeBrowsingStore> side_effect_free_whitelist_store_; 591 scoped_ptr<SafeBrowsingStore> side_effect_free_whitelist_store_;
501 592
502 // For IP blacklist. 593 // For IP blacklist.
503 scoped_ptr<SafeBrowsingStore> ip_blacklist_store_; 594 scoped_ptr<SafeBrowsingStore> ip_blacklist_store_;
504 595
505 // For unwanted software list. 596 // For unwanted software list.
506 scoped_ptr<SafeBrowsingStore> unwanted_software_store_; 597 scoped_ptr<SafeBrowsingStore> unwanted_software_store_;
507 598
508 // Lock for protecting access to variables that may be used on any threads.
509 // This includes all SBWhitelist's, PrefixSet's, and caches.
510 base::Lock lookup_lock_;
511
512 SBWhitelist csd_whitelist_;
513 SBWhitelist download_whitelist_;
514
515 // The IP blacklist should be small. At most a couple hundred IPs.
516 IPBlacklist ip_blacklist_;
517
518 // Cache of gethash results for prefix stores. Entries should not be used if
519 // they are older than their expire_after field. Cached misses will have
520 // empty full_hashes field. Cleared on each update.
521 std::map<SBPrefix, SBCachedFullHashResult> prefix_gethash_cache_;
522
523 // Set if corruption is detected during the course of an update. 599 // Set if corruption is detected during the course of an update.
524 // Causes the update functions to fail with no side effects, until 600 // Causes the update functions to fail with no side effects, until
525 // the next call to |UpdateStarted()|. 601 // the next call to |UpdateStarted()|.
526 bool corruption_detected_; 602 bool corruption_detected_;
527 603
528 // Set to true if any chunks are added or deleted during an update. 604 // Set to true if any chunks are added or deleted during an update.
529 // Used to optimize away database update. 605 // Used to optimize away database update.
530 bool change_detected_; 606 bool change_detected_;
531 607
532 // PrefixSets to speed up lookups for particularly large lists. The PrefixSet
533 // themselves are never modified, instead a new one is swapped in on update
534 // while holding |lookup_lock_|. Any thread other than this class' main thread
535 // (which handles updates) must hold |lookup_lock_| before reading from these
536 // sets.
537 // TODO(gab): Enforce this by design.
538 scoped_ptr<const safe_browsing::PrefixSet> browse_prefix_set_;
539 scoped_ptr<const safe_browsing::PrefixSet>
540 side_effect_free_whitelist_prefix_set_;
541 scoped_ptr<const safe_browsing::PrefixSet> unwanted_software_prefix_set_;
542
543 // Used to schedule resetting the database because of corruption. 608 // Used to schedule resetting the database because of corruption.
544 base::WeakPtrFactory<SafeBrowsingDatabaseNew> reset_factory_; 609 base::WeakPtrFactory<SafeBrowsingDatabaseNew> reset_factory_;
545 }; 610 };
546 611
547 #endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_ 612 #endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_DATABASE_H_
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/safe_browsing/safe_browsing_database.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698