OLD | NEW |
---|---|
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 #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> |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
58 class SQLitePersistentCookieStore::Backend | 58 class SQLitePersistentCookieStore::Backend |
59 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { | 59 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { |
60 public: | 60 public: |
61 Backend(const FilePath& path, bool restore_old_session_cookies) | 61 Backend(const FilePath& path, bool restore_old_session_cookies) |
62 : path_(path), | 62 : path_(path), |
63 db_(NULL), | 63 db_(NULL), |
64 num_pending_(0), | 64 num_pending_(0), |
65 clear_local_state_on_exit_(false), | 65 clear_local_state_on_exit_(false), |
66 initialized_(false), | 66 initialized_(false), |
67 restore_old_session_cookies_(restore_old_session_cookies), | 67 restore_old_session_cookies_(restore_old_session_cookies), |
68 num_cookies_read_(0), | |
68 num_priority_waiting_(0), | 69 num_priority_waiting_(0), |
69 total_priority_requests_(0) { | 70 total_priority_requests_(0) { |
70 } | 71 } |
71 | 72 |
72 // Creates or loads the SQLite database. | 73 // Creates or loads the SQLite database. |
73 void Load(const LoadedCallback& loaded_callback); | 74 void Load(const LoadedCallback& loaded_callback); |
74 | 75 |
75 // Loads cookies for the domain key (eTLD+1). | 76 // Loads cookies for the domain key (eTLD+1). |
76 void LoadCookiesForKey(const std::string& domain, | 77 void LoadCookiesForKey(const std::string& domain, |
77 const LoadedCallback& loaded_callback); | 78 const LoadedCallback& loaded_callback); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 OperationType op() const { return op_; } | 122 OperationType op() const { return op_; } |
122 const net::CookieMonster::CanonicalCookie& cc() const { return cc_; } | 123 const net::CookieMonster::CanonicalCookie& cc() const { return cc_; } |
123 | 124 |
124 private: | 125 private: |
125 OperationType op_; | 126 OperationType op_; |
126 net::CookieMonster::CanonicalCookie cc_; | 127 net::CookieMonster::CanonicalCookie cc_; |
127 }; | 128 }; |
128 | 129 |
129 private: | 130 private: |
130 // Creates or loads the SQLite database on DB thread. | 131 // Creates or loads the SQLite database on DB thread. |
131 void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback); | 132 void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback, |
133 const base::Time& posted_at); | |
132 | 134 |
133 // Loads cookies for the domain key (eTLD+1) on DB thread. | 135 // Loads cookies for the domain key (eTLD+1) on DB thread. |
134 void LoadKeyAndNotifyOnDBThread(const std::string& domains, | 136 void LoadKeyAndNotifyOnDBThread(const std::string& domains, |
135 const LoadedCallback& loaded_callback); | 137 const LoadedCallback& loaded_callback, |
138 const base::Time& posted_at); | |
136 | 139 |
137 // Notifies the CookieMonster when loading completes for a specific domain key | 140 // Notifies the CookieMonster when loading completes for a specific domain key |
138 // or for all domain keys. Triggers the callback and passes it all cookies | 141 // or for all domain keys. Triggers the callback and passes it all cookies |
139 // that have been loaded from DB since last IO notification. | 142 // that have been loaded from DB since last IO notification. |
140 void Notify(const LoadedCallback& loaded_callback, bool load_success); | 143 void Notify(const LoadedCallback& loaded_callback, bool load_success); |
141 | 144 |
142 // Sends notification when the entire store is loaded, and reports metrics | 145 // Sends notification when the entire store is loaded, and reports metrics |
143 // for the total time to load and aggregated results from any priority loads | 146 // for the total time to load and aggregated results from any priority loads |
144 // that occurred. | 147 // that occurred. |
145 void CompleteLoadOnIOThread(const LoadedCallback& loaded_callback, | 148 void CompleteLoadOnIOThread(const LoadedCallback& loaded_callback, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
202 // Indicates if DB has been initialized. | 205 // Indicates if DB has been initialized. |
203 bool initialized_; | 206 bool initialized_; |
204 | 207 |
205 // If false, we should filter out session cookies when reading the DB. | 208 // If false, we should filter out session cookies when reading the DB. |
206 bool restore_old_session_cookies_; | 209 bool restore_old_session_cookies_; |
207 | 210 |
208 // The cumulative time spent loading the cookies on the DB thread. Incremented | 211 // The cumulative time spent loading the cookies on the DB thread. Incremented |
209 // and reported from the DB thread. | 212 // and reported from the DB thread. |
210 base::TimeDelta cookie_load_duration_; | 213 base::TimeDelta cookie_load_duration_; |
211 | 214 |
215 // The total number of cookies read. Incremented and reported on the DB | |
216 // thread. | |
217 int num_cookies_read_; | |
218 | |
212 // Guards the following metrics-related properties (only accessed when | 219 // Guards the following metrics-related properties (only accessed when |
213 // starting/completing priority loads or completing the total load). | 220 // starting/completing priority loads or completing the total load). |
214 base::Lock metrics_lock_; | 221 base::Lock metrics_lock_; |
215 int num_priority_waiting_; | 222 int num_priority_waiting_; |
216 // The total number of priority requests. | 223 // The total number of priority requests. |
217 int total_priority_requests_; | 224 int total_priority_requests_; |
218 // The time when |num_priority_waiting_| incremented to 1. | 225 // The time when |num_priority_waiting_| incremented to 1. |
219 base::Time current_priority_wait_start_; | 226 base::Time current_priority_wait_start_; |
220 // The cumulative duration of time when |num_priority_waiting_| was greater | 227 // The cumulative duration of time when |num_priority_waiting_| was greater |
221 // than 1. | 228 // than 1. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
296 } | 303 } |
297 | 304 |
298 } // namespace | 305 } // namespace |
299 | 306 |
300 void SQLitePersistentCookieStore::Backend::Load( | 307 void SQLitePersistentCookieStore::Backend::Load( |
301 const LoadedCallback& loaded_callback) { | 308 const LoadedCallback& loaded_callback) { |
302 // This function should be called only once per instance. | 309 // This function should be called only once per instance. |
303 DCHECK(!db_.get()); | 310 DCHECK(!db_.get()); |
304 BrowserThread::PostTask( | 311 BrowserThread::PostTask( |
305 BrowserThread::DB, FROM_HERE, | 312 BrowserThread::DB, FROM_HERE, |
306 base::Bind(&Backend::LoadAndNotifyOnDBThread, this, loaded_callback)); | 313 base::Bind(&Backend::LoadAndNotifyOnDBThread, this, loaded_callback, |
314 base::Time::Now())); | |
307 } | 315 } |
308 | 316 |
309 void SQLitePersistentCookieStore::Backend::LoadCookiesForKey( | 317 void SQLitePersistentCookieStore::Backend::LoadCookiesForKey( |
310 const std::string& key, | 318 const std::string& key, |
311 const LoadedCallback& loaded_callback) { | 319 const LoadedCallback& loaded_callback) { |
312 { | 320 { |
313 base::AutoLock locked(metrics_lock_); | 321 base::AutoLock locked(metrics_lock_); |
314 if (num_priority_waiting_ == 0) | 322 if (num_priority_waiting_ == 0) |
315 current_priority_wait_start_ = base::Time::Now(); | 323 current_priority_wait_start_ = base::Time::Now(); |
316 num_priority_waiting_++; | 324 num_priority_waiting_++; |
317 total_priority_requests_++; | 325 total_priority_requests_++; |
318 } | 326 } |
319 | 327 |
320 BrowserThread::PostTask( | 328 BrowserThread::PostTask( |
321 BrowserThread::DB, FROM_HERE, | 329 BrowserThread::DB, FROM_HERE, |
322 base::Bind(&Backend::LoadKeyAndNotifyOnDBThread, this, | 330 base::Bind(&Backend::LoadKeyAndNotifyOnDBThread, this, |
323 key, | 331 key, |
324 loaded_callback)); | 332 loaded_callback, |
333 base::Time::Now())); | |
325 } | 334 } |
326 | 335 |
327 void SQLitePersistentCookieStore::Backend::LoadAndNotifyOnDBThread( | 336 void SQLitePersistentCookieStore::Backend::LoadAndNotifyOnDBThread( |
328 const LoadedCallback& loaded_callback) { | 337 const LoadedCallback& loaded_callback, const base::Time& posted_at) { |
329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
330 IncrementTimeDelta increment(&cookie_load_duration_); | 339 IncrementTimeDelta increment(&cookie_load_duration_); |
331 | 340 |
341 UMA_HISTOGRAM_CUSTOM_TIMES( | |
342 "Cookie.TimeLoadDBQueueWait", | |
343 base::Time::Now() - posted_at, | |
344 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), | |
345 50); | |
Randy Smith (Not in Mondays)
2011/12/05 22:18:08
Do the queue load histograms give us a lot more in
erikwright (departed)
2011/12/06 00:07:09
AFAIK, task profiler data is not yet available fro
| |
346 | |
332 if (!InitializeDatabase()) { | 347 if (!InitializeDatabase()) { |
333 BrowserThread::PostTask( | 348 BrowserThread::PostTask( |
334 BrowserThread::IO, FROM_HERE, | 349 BrowserThread::IO, FROM_HERE, |
335 base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread, | 350 base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread, |
336 this, loaded_callback, false)); | 351 this, loaded_callback, false)); |
337 } else { | 352 } else { |
338 ChainLoadCookies(loaded_callback); | 353 ChainLoadCookies(loaded_callback); |
339 } | 354 } |
340 } | 355 } |
341 | 356 |
342 void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread( | 357 void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread( |
343 const std::string& key, | 358 const std::string& key, |
344 const LoadedCallback& loaded_callback) { | 359 const LoadedCallback& loaded_callback, |
360 const base::Time& posted_at) { | |
345 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 361 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
346 IncrementTimeDelta increment(&cookie_load_duration_); | 362 IncrementTimeDelta increment(&cookie_load_duration_); |
347 | 363 |
364 UMA_HISTOGRAM_CUSTOM_TIMES( | |
365 "Cookie.TimeKeyLoadDBQueueWait", | |
366 base::Time::Now() - posted_at, | |
367 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), | |
368 50); | |
369 | |
348 bool success = false; | 370 bool success = false; |
349 if (InitializeDatabase()) { | 371 if (InitializeDatabase()) { |
350 std::map<std::string, std::set<std::string> >::iterator | 372 std::map<std::string, std::set<std::string> >::iterator |
351 it = keys_to_load_.find(key); | 373 it = keys_to_load_.find(key); |
352 if (it != keys_to_load_.end()) { | 374 if (it != keys_to_load_.end()) { |
353 success = LoadCookiesForDomains(it->second); | 375 success = LoadCookiesForDomains(it->second); |
354 keys_to_load_.erase(it); | 376 keys_to_load_.erase(it); |
355 } else { | 377 } else { |
356 success = true; | 378 success = true; |
357 } | 379 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
396 base::AutoLock locked(metrics_lock_); | 418 base::AutoLock locked(metrics_lock_); |
397 UMA_HISTOGRAM_CUSTOM_TIMES( | 419 UMA_HISTOGRAM_CUSTOM_TIMES( |
398 "Cookie.PriorityBlockingTime", | 420 "Cookie.PriorityBlockingTime", |
399 priority_wait_duration_, | 421 priority_wait_duration_, |
400 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), | 422 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), |
401 50); | 423 50); |
402 | 424 |
403 UMA_HISTOGRAM_COUNTS_100( | 425 UMA_HISTOGRAM_COUNTS_100( |
404 "Cookie.PriorityLoadCount", | 426 "Cookie.PriorityLoadCount", |
405 total_priority_requests_); | 427 total_priority_requests_); |
428 | |
429 UMA_HISTOGRAM_COUNTS_10000( | |
430 "Cookie.NumberOfLoadedCookies", | |
431 num_cookies_read_); | |
406 } | 432 } |
407 } | 433 } |
408 | 434 |
409 void SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread( | 435 void SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread( |
410 const LoadedCallback& loaded_callback, bool load_success) { | 436 const LoadedCallback& loaded_callback, bool load_success) { |
411 Notify(loaded_callback, load_success); | 437 Notify(loaded_callback, load_success); |
412 | 438 |
413 if (load_success) | 439 if (load_success) |
414 ReportMetrics(); | 440 ReportMetrics(); |
415 } | 441 } |
(...skipping 12 matching lines...) Expand all Loading... | |
428 loaded_callback.Run(cookies); | 454 loaded_callback.Run(cookies); |
429 } | 455 } |
430 | 456 |
431 bool SQLitePersistentCookieStore::Backend::InitializeDatabase() { | 457 bool SQLitePersistentCookieStore::Backend::InitializeDatabase() { |
432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 458 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
433 | 459 |
434 if (initialized_) { | 460 if (initialized_) { |
435 return true; | 461 return true; |
436 } | 462 } |
437 | 463 |
464 base::Time start = base::Time::Now(); | |
465 | |
438 const FilePath dir = path_.DirName(); | 466 const FilePath dir = path_.DirName(); |
439 if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) { | 467 if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) { |
440 return false; | 468 return false; |
441 } | 469 } |
442 | 470 |
471 int64 db_size = 0; | |
472 if (file_util::GetFileSize(path_, &db_size)) { | |
473 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
474 UMA_HISTOGRAM_COUNTS("Cookie.DBSizeInKB", db_size / 1024 ); | |
475 } | |
476 | |
443 db_.reset(new sql::Connection); | 477 db_.reset(new sql::Connection); |
444 if (!db_->Open(path_)) { | 478 if (!db_->Open(path_)) { |
445 NOTREACHED() << "Unable to open cookie DB."; | 479 NOTREACHED() << "Unable to open cookie DB."; |
446 db_.reset(); | 480 db_.reset(); |
447 return false; | 481 return false; |
448 } | 482 } |
449 | 483 |
450 db_->set_error_delegate(GetErrorHandlerForCookieDb()); | 484 db_->set_error_delegate(GetErrorHandlerForCookieDb()); |
451 | 485 |
452 if (!EnsureDatabaseVersion() || !InitTable(db_.get())) { | 486 if (!EnsureDatabaseVersion() || !InitTable(db_.get())) { |
453 NOTREACHED() << "Unable to open cookie DB."; | 487 NOTREACHED() << "Unable to open cookie DB."; |
454 db_.reset(); | 488 db_.reset(); |
455 return false; | 489 return false; |
456 } | 490 } |
457 | 491 |
458 db_->Preload(); | 492 db_->Preload(); |
Randy Smith (Not in Mondays)
2011/12/05 22:18:08
Didn't we nuke this? Is there context I'm missing
erikwright (departed)
2011/12/06 00:07:09
After uploading that CL I decided I would prefer t
| |
459 | 493 |
494 UMA_HISTOGRAM_CUSTOM_TIMES( | |
495 "Cookie.TimeInitializeDB", | |
496 base::Time::Now() - start, | |
497 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), | |
498 50); | |
499 | |
500 start = base::Time::Now(); | |
501 | |
460 // Retrieve all the domains | 502 // Retrieve all the domains |
461 sql::Statement smt(db_->GetUniqueStatement( | 503 sql::Statement smt(db_->GetUniqueStatement( |
462 "SELECT DISTINCT host_key FROM cookies")); | 504 "SELECT DISTINCT host_key FROM cookies")); |
463 | 505 |
464 if (!smt) { | 506 if (!smt) { |
465 NOTREACHED() << "select statement prep failed"; | 507 NOTREACHED() << "select statement prep failed"; |
466 db_.reset(); | 508 db_.reset(); |
467 return false; | 509 return false; |
468 } | 510 } |
469 | 511 |
470 // Build a map of domain keys (always eTLD+1) to domains. | 512 // Build a map of domain keys (always eTLD+1) to domains. |
471 while (smt.Step()) { | 513 while (smt.Step()) { |
472 std::string domain = smt.ColumnString(0); | 514 std::string domain = smt.ColumnString(0); |
473 std::string key = | 515 std::string key = |
474 net::RegistryControlledDomainService::GetDomainAndRegistry(domain); | 516 net::RegistryControlledDomainService::GetDomainAndRegistry(domain); |
475 | 517 |
476 std::map<std::string, std::set<std::string> >::iterator it = | 518 std::map<std::string, std::set<std::string> >::iterator it = |
477 keys_to_load_.find(key); | 519 keys_to_load_.find(key); |
478 if (it == keys_to_load_.end()) | 520 if (it == keys_to_load_.end()) |
479 it = keys_to_load_.insert(std::make_pair | 521 it = keys_to_load_.insert(std::make_pair |
480 (key, std::set<std::string>())).first; | 522 (key, std::set<std::string>())).first; |
481 it->second.insert(domain); | 523 it->second.insert(domain); |
482 } | 524 } |
483 | 525 |
526 UMA_HISTOGRAM_CUSTOM_TIMES( | |
527 "Cookie.TimeInitializeDomainMap", | |
528 base::Time::Now() - start, | |
529 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), | |
530 50); | |
531 | |
484 initialized_ = true; | 532 initialized_ = true; |
485 return true; | 533 return true; |
486 } | 534 } |
487 | 535 |
488 void SQLitePersistentCookieStore::Backend::ChainLoadCookies( | 536 void SQLitePersistentCookieStore::Backend::ChainLoadCookies( |
489 const LoadedCallback& loaded_callback) { | 537 const LoadedCallback& loaded_callback) { |
490 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
491 IncrementTimeDelta increment(&cookie_load_duration_); | 539 IncrementTimeDelta increment(&cookie_load_duration_); |
492 | 540 |
493 bool load_success = true; | 541 bool load_success = true; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
558 Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc | 606 Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc |
559 Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc | 607 Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc |
560 Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc | 608 Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc |
561 smt.ColumnInt(6) != 0, // secure | 609 smt.ColumnInt(6) != 0, // secure |
562 smt.ColumnInt(7) != 0, // httponly | 610 smt.ColumnInt(7) != 0, // httponly |
563 smt.ColumnInt(9) != 0, // has_expires | 611 smt.ColumnInt(9) != 0, // has_expires |
564 smt.ColumnInt(10) != 0)); // is_persistent | 612 smt.ColumnInt(10) != 0)); // is_persistent |
565 DLOG_IF(WARNING, | 613 DLOG_IF(WARNING, |
566 cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; | 614 cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; |
567 cookies.push_back(cc.release()); | 615 cookies.push_back(cc.release()); |
616 ++num_cookies_read_; | |
568 } | 617 } |
569 smt.Reset(); | 618 smt.Reset(); |
570 } | 619 } |
571 { | 620 { |
572 base::AutoLock locked(lock_); | 621 base::AutoLock locked(lock_); |
573 cookies_.insert(cookies_.end(), cookies.begin(), cookies.end()); | 622 cookies_.insert(cookies_.end(), cookies.begin(), cookies.end()); |
574 } | 623 } |
575 return true; | 624 return true; |
576 } | 625 } |
577 | 626 |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
906 if (backend_.get()) | 955 if (backend_.get()) |
907 backend_->SetClearLocalStateOnExit(clear_local_state); | 956 backend_->SetClearLocalStateOnExit(clear_local_state); |
908 } | 957 } |
909 | 958 |
910 void SQLitePersistentCookieStore::Flush(Task* completion_task) { | 959 void SQLitePersistentCookieStore::Flush(Task* completion_task) { |
911 if (backend_.get()) | 960 if (backend_.get()) |
912 backend_->Flush(completion_task); | 961 backend_->Flush(completion_task); |
913 else if (completion_task) | 962 else if (completion_task) |
914 MessageLoop::current()->PostTask(FROM_HERE, completion_task); | 963 MessageLoop::current()->PostTask(FROM_HERE, completion_task); |
915 } | 964 } |
OLD | NEW |