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

Side by Side Diff: chrome/browser/net/sqlite_persistent_cookie_store.cc

Issue 12314015: Make SQLitePersistentCookieStore run on injected SequencedTaskRunners vs named BrowserThreads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix perf tests. Created 7 years, 10 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "chrome/browser/net/sqlite_persistent_cookie_store.h" 5 #include "chrome/browser/net/sqlite_persistent_cookie_store.h"
6 6
7 #include <list> 7 #include <list>
8 #include <map> 8 #include <map>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/callback.h" 14 #include "base/callback.h"
15 #include "base/file_path.h" 15 #include "base/file_path.h"
16 #include "base/file_util.h" 16 #include "base/file_util.h"
17 #include "base/location.h"
17 #include "base/logging.h" 18 #include "base/logging.h"
18 #include "base/memory/ref_counted.h" 19 #include "base/memory/ref_counted.h"
19 #include "base/memory/scoped_ptr.h" 20 #include "base/memory/scoped_ptr.h"
20 #include "base/metrics/histogram.h" 21 #include "base/metrics/histogram.h"
22 #include "base/sequenced_task_runner.h"
21 #include "base/string_util.h" 23 #include "base/string_util.h"
22 #include "base/synchronization/lock.h" 24 #include "base/synchronization/lock.h"
23 #include "base/threading/thread.h" 25 #include "base/threading/thread.h"
mmenke 2013/02/20 20:58:30 Don't think this is needed.
erikwright (departed) 2013/02/21 20:11:43 Done.
24 #include "base/time.h" 26 #include "base/time.h"
25 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" 27 #include "chrome/browser/diagnostics/sqlite_diagnostics.h"
26 #include "chrome/browser/net/clear_on_exit_policy.h" 28 #include "chrome/browser/net/clear_on_exit_policy.h"
27 #include "content/public/browser/browser_thread.h"
28 #include "googleurl/src/gurl.h" 29 #include "googleurl/src/gurl.h"
29 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 30 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
30 #include "net/cookies/canonical_cookie.h" 31 #include "net/cookies/canonical_cookie.h"
31 #include "sql/error_delegate_util.h" 32 #include "sql/error_delegate_util.h"
32 #include "sql/meta_table.h" 33 #include "sql/meta_table.h"
33 #include "sql/statement.h" 34 #include "sql/statement.h"
34 #include "sql/transaction.h" 35 #include "sql/transaction.h"
35 #include "third_party/sqlite/sqlite3.h" 36 #include "third_party/sqlite/sqlite3.h"
36 37
37 using base::Time; 38 using base::Time;
38 using content::BrowserThread;
39 39
40 // This class is designed to be shared between any calling threads and the 40 // This class is designed to be shared between any calling threads and the
41 // database thread. It batches operations and commits them on a timer. 41 // database thread. It batches operations and commits them on a timer.
42 // 42 //
43 // SQLitePersistentCookieStore::Load is called to load all cookies. It 43 // SQLitePersistentCookieStore::Load is called to load all cookies. It
44 // delegates to Backend::Load, which posts a Backend::LoadAndNotifyOnDBThread 44 // delegates to Backend::Load, which posts a Backend::LoadAndNotifyOnDBThread
45 // task to the DB thread. This task calls Backend::ChainLoadCookies(), which 45 // task to the background thread. This task calls Backend::ChainLoadCookies(),
mmenke 2013/02/20 20:58:30 SequencedTaskRunners aren't guaranteed to be threa
erikwright (departed) 2013/02/21 20:11:43 Done.
46 // repeatedly posts itself to the DB thread to load each eTLD+1's cookies in 46 // which repeatedly posts itself to the BG thread to load each eTLD+1's cookies
47 // separate tasks. When this is complete, Backend::CompleteLoadOnIOThread is 47 // in separate tasks. When this is complete, Backend::CompleteLoadOnIOThread is
48 // posted to the IO thread, which notifies the caller of 48 // posted to the client thread, which notifies the caller of
49 // SQLitePersistentCookieStore::Load that the load is complete. 49 // SQLitePersistentCookieStore::Load that the load is complete.
50 // 50 //
51 // If a priority load request is invoked via SQLitePersistentCookieStore:: 51 // If a priority load request is invoked via SQLitePersistentCookieStore::
52 // LoadCookiesForKey, it is delegated to Backend::LoadCookiesForKey, which posts 52 // LoadCookiesForKey, it is delegated to Backend::LoadCookiesForKey, which posts
53 // Backend::LoadKeyAndNotifyOnDBThread to the DB thread. That routine loads just 53 // Backend::LoadKeyAndNotifyOnDBThread to the BG thread. That routine loads just
54 // that single domain key (eTLD+1)'s cookies, and posts a Backend:: 54 // that single domain key (eTLD+1)'s cookies, and posts a Backend::
55 // CompleteLoadForKeyOnIOThread to the IO thread to notify the caller of 55 // CompleteLoadForKeyOnIOThread to the client thread to notify the caller of
56 // SQLitePersistentCookieStore::LoadCookiesForKey that that load is complete. 56 // SQLitePersistentCookieStore::LoadCookiesForKey that that load is complete.
57 // 57 //
58 // Subsequent to loading, mutations may be queued by any thread using 58 // Subsequent to loading, mutations may be queued by any thread using
59 // AddCookie, UpdateCookieAccessTime, and DeleteCookie. These are flushed to 59 // AddCookie, UpdateCookieAccessTime, and DeleteCookie. These are flushed to
60 // disk on the DB thread every 30 seconds, 512 operations, or call to Flush(), 60 // disk on the BG thread every 30 seconds, 512 operations, or call to Flush(),
61 // whichever occurs first. 61 // whichever occurs first.
62 class SQLitePersistentCookieStore::Backend 62 class SQLitePersistentCookieStore::Backend
63 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { 63 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> {
64 public: 64 public:
65 Backend(const base::FilePath& path, 65 Backend(
66 bool restore_old_session_cookies, 66 const base::FilePath& path,
67 ClearOnExitPolicy* clear_on_exit_policy) 67 const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
68 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
69 bool restore_old_session_cookies,
70 ClearOnExitPolicy* clear_on_exit_policy)
68 : path_(path), 71 : path_(path),
69 db_(NULL), 72 db_(NULL),
70 num_pending_(0), 73 num_pending_(0),
71 force_keep_session_state_(false), 74 force_keep_session_state_(false),
72 initialized_(false), 75 initialized_(false),
73 corruption_detected_(false), 76 corruption_detected_(false),
74 restore_old_session_cookies_(restore_old_session_cookies), 77 restore_old_session_cookies_(restore_old_session_cookies),
75 clear_on_exit_policy_(clear_on_exit_policy), 78 clear_on_exit_policy_(clear_on_exit_policy),
76 num_cookies_read_(0), 79 num_cookies_read_(0),
80 client_task_runner_(client_task_runner),
81 background_task_runner_(background_task_runner),
77 num_priority_waiting_(0), 82 num_priority_waiting_(0),
78 total_priority_requests_(0) { 83 total_priority_requests_(0) {
79 } 84 }
80 85
81 // Creates or loads the SQLite database. 86 // Creates or loads the SQLite database.
82 void Load(const LoadedCallback& loaded_callback); 87 void Load(const LoadedCallback& loaded_callback);
83 88
84 // Loads cookies for the domain key (eTLD+1). 89 // Loads cookies for the domain key (eTLD+1).
85 void LoadCookiesForKey(const std::string& domain, 90 void LoadCookiesForKey(const std::string& domain,
86 const LoadedCallback& loaded_callback); 91 const LoadedCallback& loaded_callback);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 }; 162 };
158 163
159 private: 164 private:
160 // Creates or loads the SQLite database on DB thread. 165 // Creates or loads the SQLite database on DB thread.
161 void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback, 166 void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback,
162 const base::Time& posted_at); 167 const base::Time& posted_at);
163 168
164 // Loads cookies for the domain key (eTLD+1) on DB thread. 169 // Loads cookies for the domain key (eTLD+1) on DB thread.
165 void LoadKeyAndNotifyOnDBThread(const std::string& domains, 170 void LoadKeyAndNotifyOnDBThread(const std::string& domains,
166 const LoadedCallback& loaded_callback, 171 const LoadedCallback& loaded_callback,
167 const base::Time& posted_at); 172 const base::Time& posted_at);
mmenke 2013/02/20 20:58:30 These should be renamed to *OnBGThread. Actually,
erikwright (departed) 2013/02/21 20:11:43 Done.
168 173
169 // Notifies the CookieMonster when loading completes for a specific domain key 174 // Notifies the CookieMonster when loading completes for a specific domain key
170 // or for all domain keys. Triggers the callback and passes it all cookies 175 // or for all domain keys. Triggers the callback and passes it all cookies
171 // that have been loaded from DB since last IO notification. 176 // that have been loaded from DB since last IO notification.
172 void Notify(const LoadedCallback& loaded_callback, bool load_success); 177 void Notify(const LoadedCallback& loaded_callback, bool load_success);
173 178
174 // Sends notification when the entire store is loaded, and reports metrics 179 // Sends notification when the entire store is loaded, and reports metrics
175 // for the total time to load and aggregated results from any priority loads 180 // for the total time to load and aggregated results from any priority loads
176 // that occurred. 181 // that occurred.
177 void CompleteLoadOnIOThread(const LoadedCallback& loaded_callback, 182 void CompleteLoadOnIOThread(const LoadedCallback& loaded_callback,
178 bool load_success); 183 bool load_success);
179 184
180 // Sends notification when a single priority load completes. Updates priority 185 // Sends notification when a single priority load completes. Updates priority
181 // load metric data. The data is sent only after the final load completes. 186 // load metric data. The data is sent only after the final load completes.
182 void CompleteLoadForKeyOnIOThread(const LoadedCallback& loaded_callback, 187 void CompleteLoadForKeyOnIOThread(const LoadedCallback& loaded_callback,
183 bool load_success); 188 bool load_success);
mmenke 2013/02/20 20:58:30 These should also be renamed to *OnClientThread.
erikwright (departed) 2013/02/21 20:11:43 Done.
184 189
185 // Sends all metrics, including posting a ReportMetricsOnDBThread task. 190 // Sends all metrics, including posting a ReportMetricsOnDBThread task.
186 // Called after all priority and regular loading is complete. 191 // Called after all priority and regular loading is complete.
187 void ReportMetrics(); 192 void ReportMetrics();
188 193
189 // Sends DB-thread owned metrics (i.e., the combined duration of all DB-thread 194 // Sends DB-thread owned metrics (i.e., the combined duration of all DB-thread
190 // tasks). 195 // tasks).
191 void ReportMetricsOnDBThread(); 196 void ReportMetricsOnDBThread();
192 197
193 // Initialize the data base. 198 // Initialize the data base.
(...skipping 15 matching lines...) Expand all
209 // Close() executed on the background thread. 214 // Close() executed on the background thread.
210 void InternalBackgroundClose(); 215 void InternalBackgroundClose();
211 216
212 void DeleteSessionCookiesOnStartup(); 217 void DeleteSessionCookiesOnStartup();
213 218
214 void DeleteSessionCookiesOnShutdown(); 219 void DeleteSessionCookiesOnShutdown();
215 220
216 void KillDatabase(); 221 void KillDatabase();
217 void ScheduleKillDatabase(); 222 void ScheduleKillDatabase();
218 223
224 void PostBackgroundTask(const tracked_objects::Location& origin,
225 const base::Closure& task);
226 void PostClientTask(const tracked_objects::Location& origin,
227 const base::Closure& task);
228
219 base::FilePath path_; 229 base::FilePath path_;
220 scoped_ptr<sql::Connection> db_; 230 scoped_ptr<sql::Connection> db_;
221 sql::MetaTable meta_table_; 231 sql::MetaTable meta_table_;
222 232
223 typedef std::list<PendingOperation*> PendingOperationsList; 233 typedef std::list<PendingOperation*> PendingOperationsList;
224 PendingOperationsList pending_; 234 PendingOperationsList pending_;
225 PendingOperationsList::size_type num_pending_; 235 PendingOperationsList::size_type num_pending_;
226 // True if the persistent store should skip delete on exit rules. 236 // True if the persistent store should skip delete on exit rules.
227 bool force_keep_session_state_; 237 bool force_keep_session_state_;
228 // Guard |cookies_|, |pending_|, |num_pending_|, |force_keep_session_state_| 238 // Guard |cookies_|, |pending_|, |num_pending_|, |force_keep_session_state_|
(...skipping 26 matching lines...) Expand all
255 scoped_refptr<ClearOnExitPolicy> clear_on_exit_policy_; 265 scoped_refptr<ClearOnExitPolicy> clear_on_exit_policy_;
256 266
257 // The cumulative time spent loading the cookies on the DB thread. Incremented 267 // The cumulative time spent loading the cookies on the DB thread. Incremented
258 // and reported from the DB thread. 268 // and reported from the DB thread.
259 base::TimeDelta cookie_load_duration_; 269 base::TimeDelta cookie_load_duration_;
260 270
261 // The total number of cookies read. Incremented and reported on the DB 271 // The total number of cookies read. Incremented and reported on the DB
262 // thread. 272 // thread.
263 int num_cookies_read_; 273 int num_cookies_read_;
264 274
275 scoped_refptr<base::SequencedTaskRunner> client_task_runner_;
276 scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
277
265 // Guards the following metrics-related properties (only accessed when 278 // Guards the following metrics-related properties (only accessed when
266 // starting/completing priority loads or completing the total load). 279 // starting/completing priority loads or completing the total load).
267 base::Lock metrics_lock_; 280 base::Lock metrics_lock_;
268 int num_priority_waiting_; 281 int num_priority_waiting_;
269 // The total number of priority requests. 282 // The total number of priority requests.
270 int total_priority_requests_; 283 int total_priority_requests_;
271 // The time when |num_priority_waiting_| incremented to 1. 284 // The time when |num_priority_waiting_| incremented to 1.
272 base::Time current_priority_wait_start_; 285 base::Time current_priority_wait_start_;
273 // The cumulative duration of time when |num_priority_waiting_| was greater 286 // The cumulative duration of time when |num_priority_waiting_| was greater
274 // than 1. 287 // than 1.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 380
368 return true; 381 return true;
369 } 382 }
370 383
371 } // namespace 384 } // namespace
372 385
373 void SQLitePersistentCookieStore::Backend::Load( 386 void SQLitePersistentCookieStore::Backend::Load(
374 const LoadedCallback& loaded_callback) { 387 const LoadedCallback& loaded_callback) {
375 // This function should be called only once per instance. 388 // This function should be called only once per instance.
376 DCHECK(!db_.get()); 389 DCHECK(!db_.get());
377 BrowserThread::PostTask( 390 PostBackgroundTask(FROM_HERE, base::Bind(
378 BrowserThread::DB, FROM_HERE, 391 &Backend::LoadAndNotifyOnDBThread, this,
379 base::Bind(&Backend::LoadAndNotifyOnDBThread, this, loaded_callback, 392 loaded_callback, base::Time::Now()));
380 base::Time::Now()));
381 } 393 }
382 394
383 void SQLitePersistentCookieStore::Backend::LoadCookiesForKey( 395 void SQLitePersistentCookieStore::Backend::LoadCookiesForKey(
384 const std::string& key, 396 const std::string& key,
385 const LoadedCallback& loaded_callback) { 397 const LoadedCallback& loaded_callback) {
386 { 398 {
387 base::AutoLock locked(metrics_lock_); 399 base::AutoLock locked(metrics_lock_);
388 if (num_priority_waiting_ == 0) 400 if (num_priority_waiting_ == 0)
389 current_priority_wait_start_ = base::Time::Now(); 401 current_priority_wait_start_ = base::Time::Now();
390 num_priority_waiting_++; 402 num_priority_waiting_++;
391 total_priority_requests_++; 403 total_priority_requests_++;
392 } 404 }
393 405
394 BrowserThread::PostTask( 406 PostBackgroundTask(FROM_HERE, base::Bind(
395 BrowserThread::DB, FROM_HERE, 407 &Backend::LoadKeyAndNotifyOnDBThread,
396 base::Bind(&Backend::LoadKeyAndNotifyOnDBThread, this, 408 this, key, loaded_callback, base::Time::Now()));
397 key,
398 loaded_callback,
399 base::Time::Now()));
400 } 409 }
401 410
402 void SQLitePersistentCookieStore::Backend::LoadAndNotifyOnDBThread( 411 void SQLitePersistentCookieStore::Backend::LoadAndNotifyOnDBThread(
403 const LoadedCallback& loaded_callback, const base::Time& posted_at) { 412 const LoadedCallback& loaded_callback, const base::Time& posted_at) {
404 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 413 DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
405 IncrementTimeDelta increment(&cookie_load_duration_); 414 IncrementTimeDelta increment(&cookie_load_duration_);
406 415
407 UMA_HISTOGRAM_CUSTOM_TIMES( 416 UMA_HISTOGRAM_CUSTOM_TIMES(
408 "Cookie.TimeLoadDBQueueWait", 417 "Cookie.TimeLoadDBQueueWait",
409 base::Time::Now() - posted_at, 418 base::Time::Now() - posted_at,
410 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 419 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
411 50); 420 50);
412 421
413 if (!InitializeDatabase()) { 422 if (!InitializeDatabase()) {
414 BrowserThread::PostTask( 423 PostClientTask(FROM_HERE, base::Bind(
415 BrowserThread::IO, FROM_HERE, 424 &Backend::CompleteLoadOnIOThread, this, loaded_callback, false));
416 base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread,
417 this, loaded_callback, false));
418 } else { 425 } else {
419 ChainLoadCookies(loaded_callback); 426 ChainLoadCookies(loaded_callback);
420 } 427 }
421 } 428 }
422 429
423 void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread( 430 void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread(
424 const std::string& key, 431 const std::string& key,
425 const LoadedCallback& loaded_callback, 432 const LoadedCallback& loaded_callback,
426 const base::Time& posted_at) { 433 const base::Time& posted_at) {
427 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 434 DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
428 IncrementTimeDelta increment(&cookie_load_duration_); 435 IncrementTimeDelta increment(&cookie_load_duration_);
429 436
430 UMA_HISTOGRAM_CUSTOM_TIMES( 437 UMA_HISTOGRAM_CUSTOM_TIMES(
431 "Cookie.TimeKeyLoadDBQueueWait", 438 "Cookie.TimeKeyLoadDBQueueWait",
432 base::Time::Now() - posted_at, 439 base::Time::Now() - posted_at,
433 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 440 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
434 50); 441 50);
435 442
436 bool success = false; 443 bool success = false;
437 if (InitializeDatabase()) { 444 if (InitializeDatabase()) {
438 std::map<std::string, std::set<std::string> >::iterator 445 std::map<std::string, std::set<std::string> >::iterator
439 it = keys_to_load_.find(key); 446 it = keys_to_load_.find(key);
440 if (it != keys_to_load_.end()) { 447 if (it != keys_to_load_.end()) {
441 success = LoadCookiesForDomains(it->second); 448 success = LoadCookiesForDomains(it->second);
442 keys_to_load_.erase(it); 449 keys_to_load_.erase(it);
443 } else { 450 } else {
444 success = true; 451 success = true;
445 } 452 }
446 } 453 }
447 454
448 BrowserThread::PostTask( 455 PostClientTask(FROM_HERE, base::Bind(
449 BrowserThread::IO, FROM_HERE, 456 &SQLitePersistentCookieStore::Backend::CompleteLoadForKeyOnIOThread,
450 base::Bind( 457 this, loaded_callback, success));
451 &SQLitePersistentCookieStore::Backend::CompleteLoadForKeyOnIOThread,
452 this, loaded_callback, success));
453 } 458 }
454 459
455 void SQLitePersistentCookieStore::Backend::CompleteLoadForKeyOnIOThread( 460 void SQLitePersistentCookieStore::Backend::CompleteLoadForKeyOnIOThread(
456 const LoadedCallback& loaded_callback, 461 const LoadedCallback& loaded_callback,
457 bool load_success) { 462 bool load_success) {
mmenke 2013/02/20 20:58:30 Know it wasn't here before, but maybe a "DCHECK(ba
erikwright (departed) 2013/02/21 20:11:43 Done.
458 Notify(loaded_callback, load_success); 463 Notify(loaded_callback, load_success);
459 464
460 { 465 {
461 base::AutoLock locked(metrics_lock_); 466 base::AutoLock locked(metrics_lock_);
462 num_priority_waiting_--; 467 num_priority_waiting_--;
463 if (num_priority_waiting_ == 0) { 468 if (num_priority_waiting_ == 0) {
464 priority_wait_duration_ += 469 priority_wait_duration_ +=
465 base::Time::Now() - current_priority_wait_start_; 470 base::Time::Now() - current_priority_wait_start_;
466 } 471 }
467 } 472 }
468 473
469 } 474 }
470 475
471 void SQLitePersistentCookieStore::Backend::ReportMetricsOnDBThread() { 476 void SQLitePersistentCookieStore::Backend::ReportMetricsOnDBThread() {
472 UMA_HISTOGRAM_CUSTOM_TIMES( 477 UMA_HISTOGRAM_CUSTOM_TIMES(
473 "Cookie.TimeLoad", 478 "Cookie.TimeLoad",
474 cookie_load_duration_, 479 cookie_load_duration_,
475 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 480 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
476 50); 481 50);
477 } 482 }
478 483
479 void SQLitePersistentCookieStore::Backend::ReportMetrics() { 484 void SQLitePersistentCookieStore::Backend::ReportMetrics() {
480 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, base::Bind( 485 PostBackgroundTask(FROM_HERE, base::Bind(
481 &SQLitePersistentCookieStore::Backend::ReportMetricsOnDBThread, this)); 486 &SQLitePersistentCookieStore::Backend::ReportMetricsOnDBThread, this));
482 487
483 { 488 {
484 base::AutoLock locked(metrics_lock_); 489 base::AutoLock locked(metrics_lock_);
485 UMA_HISTOGRAM_CUSTOM_TIMES( 490 UMA_HISTOGRAM_CUSTOM_TIMES(
486 "Cookie.PriorityBlockingTime", 491 "Cookie.PriorityBlockingTime",
487 priority_wait_duration_, 492 priority_wait_duration_,
488 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 493 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
489 50); 494 50);
490 495
(...skipping 11 matching lines...) Expand all
502 const LoadedCallback& loaded_callback, bool load_success) { 507 const LoadedCallback& loaded_callback, bool load_success) {
503 Notify(loaded_callback, load_success); 508 Notify(loaded_callback, load_success);
504 509
505 if (load_success) 510 if (load_success)
506 ReportMetrics(); 511 ReportMetrics();
507 } 512 }
508 513
509 void SQLitePersistentCookieStore::Backend::Notify( 514 void SQLitePersistentCookieStore::Backend::Notify(
510 const LoadedCallback& loaded_callback, 515 const LoadedCallback& loaded_callback,
511 bool load_success) { 516 bool load_success) {
512 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 517 DCHECK(client_task_runner_->RunsTasksOnCurrentThread());
513 518
514 std::vector<net::CanonicalCookie*> cookies; 519 std::vector<net::CanonicalCookie*> cookies;
515 { 520 {
516 base::AutoLock locked(lock_); 521 base::AutoLock locked(lock_);
517 cookies.swap(cookies_); 522 cookies.swap(cookies_);
518 } 523 }
519 524
520 loaded_callback.Run(cookies); 525 loaded_callback.Run(cookies);
521 } 526 }
522 527
523 bool SQLitePersistentCookieStore::Backend::InitializeDatabase() { 528 bool SQLitePersistentCookieStore::Backend::InitializeDatabase() {
524 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 529 DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
525 530
526 if (initialized_ || corruption_detected_) { 531 if (initialized_ || corruption_detected_) {
527 // Return false if we were previously initialized but the DB has since been 532 // Return false if we were previously initialized but the DB has since been
528 // closed, or if corruption caused a database reset during initialization. 533 // closed, or if corruption caused a database reset during initialization.
529 return db_ != NULL; 534 return db_ != NULL;
530 } 535 }
531 536
532 base::Time start = base::Time::Now(); 537 base::Time start = base::Time::Now();
533 538
534 const base::FilePath dir = path_.DirName(); 539 const base::FilePath dir = path_.DirName();
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 base::Time::Now() - start, 606 base::Time::Now() - start,
602 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 607 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
603 50); 608 50);
604 609
605 initialized_ = true; 610 initialized_ = true;
606 return true; 611 return true;
607 } 612 }
608 613
609 void SQLitePersistentCookieStore::Backend::ChainLoadCookies( 614 void SQLitePersistentCookieStore::Backend::ChainLoadCookies(
610 const LoadedCallback& loaded_callback) { 615 const LoadedCallback& loaded_callback) {
611 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 616 DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
612 IncrementTimeDelta increment(&cookie_load_duration_); 617 IncrementTimeDelta increment(&cookie_load_duration_);
613 618
614 bool load_success = true; 619 bool load_success = true;
615 620
616 if (!db_.get()) { 621 if (!db_.get()) {
617 // Close() has been called on this store. 622 // Close() has been called on this store.
618 load_success = false; 623 load_success = false;
619 } else if (keys_to_load_.size() > 0) { 624 } else if (keys_to_load_.size() > 0) {
620 // Load cookies for the first domain key. 625 // Load cookies for the first domain key.
621 std::map<std::string, std::set<std::string> >::iterator 626 std::map<std::string, std::set<std::string> >::iterator
622 it = keys_to_load_.begin(); 627 it = keys_to_load_.begin();
623 load_success = LoadCookiesForDomains(it->second); 628 load_success = LoadCookiesForDomains(it->second);
624 keys_to_load_.erase(it); 629 keys_to_load_.erase(it);
625 } 630 }
626 631
627 // If load is successful and there are more domain keys to be loaded, 632 // If load is successful and there are more domain keys to be loaded,
628 // then post a DB task to continue chain-load; 633 // then post a DB task to continue chain-load;
629 // Otherwise notify on IO thread. 634 // Otherwise notify on IO thread.
630 if (load_success && keys_to_load_.size() > 0) { 635 if (load_success && keys_to_load_.size() > 0) {
631 BrowserThread::PostTask( 636 PostBackgroundTask(FROM_HERE, base::Bind(
632 BrowserThread::DB, FROM_HERE, 637 &Backend::ChainLoadCookies, this, loaded_callback));
633 base::Bind(&Backend::ChainLoadCookies, this, loaded_callback));
634 } else { 638 } else {
635 BrowserThread::PostTask( 639 PostClientTask(FROM_HERE, base::Bind(
636 BrowserThread::IO, FROM_HERE, 640 &Backend::CompleteLoadOnIOThread, this, loaded_callback, load_success));
637 base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread,
638 this, loaded_callback, load_success));
639 if (load_success && !restore_old_session_cookies_) 641 if (load_success && !restore_old_session_cookies_)
640 DeleteSessionCookiesOnStartup(); 642 DeleteSessionCookiesOnStartup();
641 } 643 }
642 } 644 }
643 645
644 bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains( 646 bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains(
645 const std::set<std::string>& domains) { 647 const std::set<std::string>& domains) {
646 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 648 DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
647 649
648 sql::Statement smt; 650 sql::Statement smt;
649 if (restore_old_session_cookies_) { 651 if (restore_old_session_cookies_) {
650 smt.Assign(db_->GetCachedStatement( 652 smt.Assign(db_->GetCachedStatement(
651 SQL_FROM_HERE, 653 SQL_FROM_HERE,
652 "SELECT creation_utc, host_key, name, value, path, expires_utc, " 654 "SELECT creation_utc, host_key, name, value, path, expires_utc, "
653 "secure, httponly, last_access_utc, has_expires, persistent " 655 "secure, httponly, last_access_utc, has_expires, persistent "
654 "FROM cookies WHERE host_key = ?")); 656 "FROM cookies WHERE host_key = ?"));
655 } else { 657 } else {
656 smt.Assign(db_->GetCachedStatement( 658 smt.Assign(db_->GetCachedStatement(
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 BatchOperation(PendingOperation::COOKIE_DELETE, cc); 825 BatchOperation(PendingOperation::COOKIE_DELETE, cc);
824 } 826 }
825 827
826 void SQLitePersistentCookieStore::Backend::BatchOperation( 828 void SQLitePersistentCookieStore::Backend::BatchOperation(
827 PendingOperation::OperationType op, 829 PendingOperation::OperationType op,
828 const net::CanonicalCookie& cc) { 830 const net::CanonicalCookie& cc) {
829 // Commit every 30 seconds. 831 // Commit every 30 seconds.
830 static const int kCommitIntervalMs = 30 * 1000; 832 static const int kCommitIntervalMs = 30 * 1000;
831 // Commit right away if we have more than 512 outstanding operations. 833 // Commit right away if we have more than 512 outstanding operations.
832 static const size_t kCommitAfterBatchSize = 512; 834 static const size_t kCommitAfterBatchSize = 512;
833 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); 835 DCHECK(!background_task_runner_->RunsTasksOnCurrentThread());
834 836
835 // We do a full copy of the cookie here, and hopefully just here. 837 // We do a full copy of the cookie here, and hopefully just here.
836 scoped_ptr<PendingOperation> po(new PendingOperation(op, cc)); 838 scoped_ptr<PendingOperation> po(new PendingOperation(op, cc));
837 839
838 PendingOperationsList::size_type num_pending; 840 PendingOperationsList::size_type num_pending;
839 { 841 {
840 base::AutoLock locked(lock_); 842 base::AutoLock locked(lock_);
841 pending_.push_back(po.release()); 843 pending_.push_back(po.release());
842 num_pending = ++num_pending_; 844 num_pending = ++num_pending_;
843 } 845 }
844 846
845 if (num_pending == 1) { 847 if (num_pending == 1) {
846 // We've gotten our first entry for this batch, fire off the timer. 848 // We've gotten our first entry for this batch, fire off the timer.
847 BrowserThread::PostDelayedTask( 849 if (!background_task_runner_->PostDelayedTask(
848 BrowserThread::DB, FROM_HERE, 850 FROM_HERE, base::Bind(&Backend::Commit, this),
849 base::Bind(&Backend::Commit, this), 851 base::TimeDelta::FromMilliseconds(kCommitIntervalMs))) {
850 base::TimeDelta::FromMilliseconds(kCommitIntervalMs)); 852 NOTREACHED() << "background_task_runner_ is not running.";
853 }
851 } else if (num_pending == kCommitAfterBatchSize) { 854 } else if (num_pending == kCommitAfterBatchSize) {
852 // We've reached a big enough batch, fire off a commit now. 855 // We've reached a big enough batch, fire off a commit now.
853 BrowserThread::PostTask( 856 PostBackgroundTask(FROM_HERE, base::Bind(&Backend::Commit, this));
854 BrowserThread::DB, FROM_HERE,
855 base::Bind(&Backend::Commit, this));
856 } 857 }
857 } 858 }
858 859
859 void SQLitePersistentCookieStore::Backend::Commit() { 860 void SQLitePersistentCookieStore::Backend::Commit() {
860 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 861 DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
861 862
862 PendingOperationsList ops; 863 PendingOperationsList ops;
863 { 864 {
864 base::AutoLock locked(lock_); 865 base::AutoLock locked(lock_);
865 pending_.swap(ops); 866 pending_.swap(ops);
866 num_pending_ = 0; 867 num_pending_ = 0;
867 } 868 }
868 869
869 // Maybe an old timer fired or we are already Close()'ed. 870 // Maybe an old timer fired or we are already Close()'ed.
870 if (!db_.get() || ops.empty()) 871 if (!db_.get() || ops.empty())
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 break; 941 break;
941 } 942 }
942 } 943 }
943 bool succeeded = transaction.Commit(); 944 bool succeeded = transaction.Commit();
944 UMA_HISTOGRAM_ENUMERATION("Cookie.BackingStoreUpdateResults", 945 UMA_HISTOGRAM_ENUMERATION("Cookie.BackingStoreUpdateResults",
945 succeeded ? 0 : 1, 2); 946 succeeded ? 0 : 1, 2);
946 } 947 }
947 948
948 void SQLitePersistentCookieStore::Backend::Flush( 949 void SQLitePersistentCookieStore::Backend::Flush(
949 const base::Closure& callback) { 950 const base::Closure& callback) {
950 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); 951 DCHECK(!background_task_runner_->RunsTasksOnCurrentThread());
951 BrowserThread::PostTask( 952 PostBackgroundTask(FROM_HERE, base::Bind(&Backend::Commit, this));
952 BrowserThread::DB, FROM_HERE, base::Bind(&Backend::Commit, this)); 953
953 if (!callback.is_null()) { 954 if (!callback.is_null()) {
954 // We want the completion task to run immediately after Commit() returns. 955 // We want the completion task to run immediately after Commit() returns.
955 // Posting it from here means there is less chance of another task getting 956 // Posting it from here means there is less chance of another task getting
956 // onto the message queue first, than if we posted it from Commit() itself. 957 // onto the message queue first, than if we posted it from Commit() itself.
957 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, callback); 958 PostBackgroundTask(FROM_HERE, callback);
958 } 959 }
959 } 960 }
960 961
961 // Fire off a close message to the background thread. We could still have a 962 // Fire off a close message to the background thread. We could still have a
962 // pending commit timer or Load operations holding references on us, but if/when 963 // pending commit timer or Load operations holding references on us, but if/when
963 // this fires we will already have been cleaned up and it will be ignored. 964 // this fires we will already have been cleaned up and it will be ignored.
964 void SQLitePersistentCookieStore::Backend::Close() { 965 void SQLitePersistentCookieStore::Backend::Close() {
965 if (BrowserThread::CurrentlyOn(BrowserThread::DB)) { 966 if (background_task_runner_->RunsTasksOnCurrentThread()) {
966 InternalBackgroundClose(); 967 InternalBackgroundClose();
967 } else { 968 } else {
968 // Must close the backend on the background thread. 969 // Must close the backend on the background thread.
969 BrowserThread::PostTask( 970 PostBackgroundTask(FROM_HERE,
970 BrowserThread::DB, FROM_HERE, 971 base::Bind(&Backend::InternalBackgroundClose, this));
971 base::Bind(&Backend::InternalBackgroundClose, this));
972 } 972 }
973 } 973 }
974 974
975 void SQLitePersistentCookieStore::Backend::InternalBackgroundClose() { 975 void SQLitePersistentCookieStore::Backend::InternalBackgroundClose() {
976 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 976 DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
977 // Commit any pending operations 977 // Commit any pending operations
978 Commit(); 978 Commit();
979 979
980 if (!force_keep_session_state_ && clear_on_exit_policy_.get() && 980 if (!force_keep_session_state_ && clear_on_exit_policy_.get() &&
981 clear_on_exit_policy_->HasClearOnExitOrigins()) { 981 clear_on_exit_policy_->HasClearOnExitOrigins()) {
982 DeleteSessionCookiesOnShutdown(); 982 DeleteSessionCookiesOnShutdown();
983 } 983 }
984 984
985 meta_table_.Reset(); 985 meta_table_.Reset();
986 db_.reset(); 986 db_.reset();
987 } 987 }
988 988
989 void SQLitePersistentCookieStore::Backend::DeleteSessionCookiesOnShutdown() { 989 void SQLitePersistentCookieStore::Backend::DeleteSessionCookiesOnShutdown() {
990 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 990 DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
991 991
992 if (!db_.get()) 992 if (!db_.get())
993 return; 993 return;
994 994
995 sql::Statement del_smt(db_->GetCachedStatement( 995 sql::Statement del_smt(db_->GetCachedStatement(
996 SQL_FROM_HERE, "DELETE FROM cookies WHERE host_key=? AND secure=?")); 996 SQL_FROM_HERE, "DELETE FROM cookies WHERE host_key=? AND secure=?"));
997 if (!del_smt.is_valid()) { 997 if (!del_smt.is_valid()) {
998 LOG(WARNING) << "Unable to delete cookies on shutdown."; 998 LOG(WARNING) << "Unable to delete cookies on shutdown.";
999 return; 999 return;
1000 } 1000 }
(...skipping 20 matching lines...) Expand all
1021 del_smt.BindInt(1, it->first.second); 1021 del_smt.BindInt(1, it->first.second);
1022 if (!del_smt.Run()) 1022 if (!del_smt.Run())
1023 NOTREACHED() << "Could not delete a cookie from the DB."; 1023 NOTREACHED() << "Could not delete a cookie from the DB.";
1024 } 1024 }
1025 1025
1026 if (!transaction.Commit()) 1026 if (!transaction.Commit())
1027 LOG(WARNING) << "Unable to delete cookies on shutdown."; 1027 LOG(WARNING) << "Unable to delete cookies on shutdown.";
1028 } 1028 }
1029 1029
1030 void SQLitePersistentCookieStore::Backend::ScheduleKillDatabase() { 1030 void SQLitePersistentCookieStore::Backend::ScheduleKillDatabase() {
1031 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 1031 DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
1032 1032
1033 corruption_detected_ = true; 1033 corruption_detected_ = true;
1034 1034
1035 // Don't just do the close/delete here, as we are being called by |db| and 1035 // Don't just do the close/delete here, as we are being called by |db| and
1036 // that seems dangerous. 1036 // that seems dangerous.
1037 MessageLoop::current()->PostTask( 1037 PostBackgroundTask(FROM_HERE, base::Bind(&Backend::KillDatabase, this));
1038 FROM_HERE, base::Bind(&Backend::KillDatabase, this));
1039 } 1038 }
1040 1039
1041 void SQLitePersistentCookieStore::Backend::KillDatabase() { 1040 void SQLitePersistentCookieStore::Backend::KillDatabase() {
1042 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 1041 DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
1043 1042
1044 if (db_.get()) { 1043 if (db_.get()) {
1045 // This Backend will now be in-memory only. In a future run we will recreate 1044 // This Backend will now be in-memory only. In a future run we will recreate
1046 // the database. Hopefully things go better then! 1045 // the database. Hopefully things go better then!
1047 bool success = db_->RazeAndClose(); 1046 bool success = db_->RazeAndClose();
1048 UMA_HISTOGRAM_BOOLEAN("Cookie.KillDatabaseResult", success); 1047 UMA_HISTOGRAM_BOOLEAN("Cookie.KillDatabaseResult", success);
1049 meta_table_.Reset(); 1048 meta_table_.Reset();
1050 db_.reset(); 1049 db_.reset();
1051 } 1050 }
1052 } 1051 }
1053 1052
1054 void SQLitePersistentCookieStore::Backend::SetForceKeepSessionState() { 1053 void SQLitePersistentCookieStore::Backend::SetForceKeepSessionState() {
1055 base::AutoLock locked(lock_); 1054 base::AutoLock locked(lock_);
1056 force_keep_session_state_ = true; 1055 force_keep_session_state_ = true;
1057 } 1056 }
1058 1057
1059 void SQLitePersistentCookieStore::Backend::DeleteSessionCookiesOnStartup() { 1058 void SQLitePersistentCookieStore::Backend::DeleteSessionCookiesOnStartup() {
1060 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 1059 DCHECK(background_task_runner_->RunsTasksOnCurrentThread());
1061 if (!db_->Execute("DELETE FROM cookies WHERE persistent == 0")) 1060 if (!db_->Execute("DELETE FROM cookies WHERE persistent == 0"))
1062 LOG(WARNING) << "Unable to delete session cookies."; 1061 LOG(WARNING) << "Unable to delete session cookies.";
1063 } 1062 }
1064 1063
1064 void SQLitePersistentCookieStore::Backend::PostBackgroundTask(
1065 const tracked_objects::Location& origin, const base::Closure& task) {
1066 if (!background_task_runner_->PostTask(origin, task)) {
1067 NOTREACHED() << "Failed to post task from " << origin.ToString()
1068 << " to background_task_runner_.";
1069 }
1070 }
1071
1072 void SQLitePersistentCookieStore::Backend::PostClientTask(
1073 const tracked_objects::Location& origin, const base::Closure& task) {
1074 if (!client_task_runner_->PostTask(origin, task)) {
1075 NOTREACHED() << "Failed to post task from " << origin.ToString()
1076 << " to client_task_runner_.";
1077 }
1078 }
1079
1065 SQLitePersistentCookieStore::SQLitePersistentCookieStore( 1080 SQLitePersistentCookieStore::SQLitePersistentCookieStore(
1066 const base::FilePath& path, 1081 const base::FilePath& path,
1082 const scoped_refptr<base::SequencedTaskRunner>& client_task_runner,
1083 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
1067 bool restore_old_session_cookies, 1084 bool restore_old_session_cookies,
1068 ClearOnExitPolicy* clear_on_exit_policy) 1085 ClearOnExitPolicy* clear_on_exit_policy)
1069 : backend_( 1086 : backend_(new Backend(path,
1070 new Backend(path, restore_old_session_cookies, clear_on_exit_policy)) { 1087 client_task_runner,
1088 background_task_runner,
1089 restore_old_session_cookies,
1090 clear_on_exit_policy)) {
1071 } 1091 }
1072 1092
1073 void SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback) { 1093 void SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback) {
1074 backend_->Load(loaded_callback); 1094 backend_->Load(loaded_callback);
1075 } 1095 }
1076 1096
1077 void SQLitePersistentCookieStore::LoadCookiesForKey( 1097 void SQLitePersistentCookieStore::LoadCookiesForKey(
1078 const std::string& key, 1098 const std::string& key,
1079 const LoadedCallback& loaded_callback) { 1099 const LoadedCallback& loaded_callback) {
1080 backend_->LoadCookiesForKey(key, loaded_callback); 1100 backend_->LoadCookiesForKey(key, loaded_callback);
(...skipping 18 matching lines...) Expand all
1099 1119
1100 void SQLitePersistentCookieStore::Flush(const base::Closure& callback) { 1120 void SQLitePersistentCookieStore::Flush(const base::Closure& callback) {
1101 backend_->Flush(callback); 1121 backend_->Flush(callback);
1102 } 1122 }
1103 1123
1104 SQLitePersistentCookieStore::~SQLitePersistentCookieStore() { 1124 SQLitePersistentCookieStore::~SQLitePersistentCookieStore() {
1105 backend_->Close(); 1125 backend_->Close();
1106 // We release our reference to the Backend, though it will probably still have 1126 // We release our reference to the Backend, though it will probably still have
1107 // a reference if the background thread has not run Close() yet. 1127 // a reference if the background thread has not run Close() yet.
1108 } 1128 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698