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

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

Issue 7833042: Finalize a CL originally by departed intern ycxiao@ that detaches the loading of cookies from the... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 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) 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 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/bind.h"
10 #include "base/file_path.h" 11 #include "base/file_path.h"
11 #include "base/file_util.h" 12 #include "base/file_util.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/memory/ref_counted.h" 14 #include "base/memory/ref_counted.h"
14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_ptr.h"
15 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
16 #include "base/string_util.h" 17 #include "base/string_util.h"
17 #include "base/threading/thread.h" 18 #include "base/threading/thread.h"
18 #include "base/threading/thread_restrictions.h" 19 #include "base/threading/thread_restrictions.h"
19 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" 20 #include "chrome/browser/diagnostics/sqlite_diagnostics.h"
20 #include "content/browser/browser_thread.h" 21 #include "content/browser/browser_thread.h"
21 #include "googleurl/src/gurl.h" 22 #include "googleurl/src/gurl.h"
22 #include "sql/meta_table.h" 23 #include "sql/meta_table.h"
23 #include "sql/statement.h" 24 #include "sql/statement.h"
24 #include "sql/transaction.h" 25 #include "sql/transaction.h"
25 26
26 using base::Time; 27 using base::Time;
27 28
28 // This class is designed to be shared between any calling threads and the 29 // This class is designed to be shared between any calling threads and the
29 // database thread. It batches operations and commits them on a timer. 30 // database thread. It batches operations and commits them on a timer.
Randy Smith (Not in Mondays) 2011/09/07 19:04:07 nit: Could you add a comment here about thread acc
erikwright (departed) 2011/09/08 02:48:58 I hope my new comment seems an improvement to you.
30 class SQLitePersistentCookieStore::Backend 31 class SQLitePersistentCookieStore::Backend
31 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { 32 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> {
32 public: 33 public:
33 explicit Backend(const FilePath& path) 34 explicit Backend(const FilePath& path)
34 : path_(path), 35 : path_(path),
35 db_(NULL), 36 db_(NULL),
36 num_pending_(0), 37 num_pending_(0),
37 clear_local_state_on_exit_(false) { 38 clear_local_state_on_exit_(false) {
38 } 39 }
39 40
40 // Creates or load the SQLite database. 41 // Creates or load the SQLite database.
41 bool Load(std::vector<net::CookieMonster::CanonicalCookie*>* cookies); 42 bool Load(const LoadedCallback& loaded_callback);
42 43
43 // Batch a cookie addition. 44 // Batch a cookie addition.
44 void AddCookie(const net::CookieMonster::CanonicalCookie& cc); 45 void AddCookie(const net::CookieMonster::CanonicalCookie& cc);
45 46
46 // Batch a cookie access time update. 47 // Batch a cookie access time update.
47 void UpdateCookieAccessTime(const net::CookieMonster::CanonicalCookie& cc); 48 void UpdateCookieAccessTime(const net::CookieMonster::CanonicalCookie& cc);
48 49
49 // Batch a cookie deletion. 50 // Batch a cookie deletion.
50 void DeleteCookie(const net::CookieMonster::CanonicalCookie& cc); 51 void DeleteCookie(const net::CookieMonster::CanonicalCookie& cc);
51 52
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 85
85 OperationType op() const { return op_; } 86 OperationType op() const { return op_; }
86 const net::CookieMonster::CanonicalCookie& cc() const { return cc_; } 87 const net::CookieMonster::CanonicalCookie& cc() const { return cc_; }
87 88
88 private: 89 private:
89 OperationType op_; 90 OperationType op_;
90 net::CookieMonster::CanonicalCookie cc_; 91 net::CookieMonster::CanonicalCookie cc_;
91 }; 92 };
92 93
93 private: 94 private:
95 // Creates or load the SQLite database on DB thread.
96 void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback);
97 // Notify the CookieMonster when loading complete.
98 void NotifyOnIOThread(
99 const LoadedCallback& loaded_callback,
100 bool load_success,
101 const std::vector<net::CookieMonster::CanonicalCookie*>& cookies);
102 // Initialize the data base.
103 bool InitializeDatabase();
104 // Load cookies to the data base, and read cookies.
105 bool LoadInternal(std::vector<net::CookieMonster::CanonicalCookie*>* cookies);
106
94 // Batch a cookie operation (add or delete) 107 // Batch a cookie operation (add or delete)
95 void BatchOperation(PendingOperation::OperationType op, 108 void BatchOperation(PendingOperation::OperationType op,
96 const net::CookieMonster::CanonicalCookie& cc); 109 const net::CookieMonster::CanonicalCookie& cc);
97 // Commit our pending operations to the database. 110 // Commit our pending operations to the database.
98 void Commit(); 111 void Commit();
99 // Close() executed on the background thread. 112 // Close() executed on the background thread.
100 void InternalBackgroundClose(); 113 void InternalBackgroundClose();
101 114
102 FilePath path_; 115 FilePath path_;
103 scoped_ptr<sql::Connection> db_; 116 scoped_ptr<sql::Connection> db_;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 // Try to create the index every time. Older versions did not have this index, 160 // Try to create the index every time. Older versions did not have this index,
148 // so we want those people to get it. Ignore errors, since it may exist. 161 // so we want those people to get it. Ignore errors, since it may exist.
149 db->Execute("CREATE INDEX IF NOT EXISTS cookie_times ON cookies" 162 db->Execute("CREATE INDEX IF NOT EXISTS cookie_times ON cookies"
150 " (creation_utc)"); 163 " (creation_utc)");
151 return true; 164 return true;
152 } 165 }
153 166
154 } // namespace 167 } // namespace
155 168
156 bool SQLitePersistentCookieStore::Backend::Load( 169 bool SQLitePersistentCookieStore::Backend::Load(
157 std::vector<net::CookieMonster::CanonicalCookie*>* cookies) { 170 const LoadedCallback& loaded_callback) {
158 // This function should be called only once per instance. 171 // This function should be called only once per instance.
159 DCHECK(!db_.get()); 172 DCHECK(!db_.get());
173 BrowserThread::PostTask(
174 BrowserThread::DB, FROM_HERE,
175 base::Bind(&Backend::LoadAndNotifyOnDBThread, base::Unretained(this),
176 loaded_callback));
177 return true;
178 }
160 179
161 // Ensure the parent directory for storing cookies is created before reading 180 void SQLitePersistentCookieStore::Backend::LoadAndNotifyOnDBThread(
162 // from it. We make an exception to allow IO on the UI thread here because 181 const LoadedCallback& loaded_callback) {
163 // we are going to disk anyway in db_->Open. (This code will be moved to the 182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
164 // DB thread as part of http://crbug.com/52909.) 183 std::vector<net::CookieMonster::CanonicalCookie*> cookies;
165 { 184
166 base::ThreadRestrictions::ScopedAllowIO allow_io; 185 bool load_success = LoadInternal(&cookies);
167 const FilePath dir = path_.DirName(); 186
168 if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) 187 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
169 return false; 188 &SQLitePersistentCookieStore::Backend::NotifyOnIOThread,
189 base::Unretained(this), loaded_callback, load_success, cookies));
190 }
191
192 void SQLitePersistentCookieStore::Backend::NotifyOnIOThread(
193 const LoadedCallback& loaded_callback,
194 bool load_success,
195 const std::vector<net::CookieMonster::CanonicalCookie*>& cookies) {
196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
197 loaded_callback.Run(cookies);
198 }
199
200 bool SQLitePersistentCookieStore::Backend::InitializeDatabase() {
201 const FilePath dir = path_.DirName();
202 if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) {
203 return false;
170 } 204 }
171 205
172 db_.reset(new sql::Connection); 206 db_.reset(new sql::Connection);
173 if (!db_->Open(path_)) { 207 if (!db_->Open(path_)) {
174 NOTREACHED() << "Unable to open cookie DB."; 208 NOTREACHED() << "Unable to open cookie DB.";
175 db_.reset(); 209 db_.reset();
176 return false; 210 return false;
177 } 211 }
178 212
179 db_->set_error_delegate(GetErrorHandlerForCookieDb()); 213 db_->set_error_delegate(GetErrorHandlerForCookieDb());
180 214
181 if (!EnsureDatabaseVersion() || !InitTable(db_.get())) { 215 if (!EnsureDatabaseVersion() || !InitTable(db_.get())) {
182 NOTREACHED() << "Unable to open cookie DB."; 216 NOTREACHED() << "Unable to open cookie DB.";
183 db_.reset(); 217 db_.reset();
184 return false; 218 return false;
185 } 219 }
186 220
187 db_->Preload(); 221 db_->Preload();
222 return true;
223 }
224
225 bool SQLitePersistentCookieStore::Backend::LoadInternal(
226 std::vector<net::CookieMonster::CanonicalCookie*>* cookies) {
227 if (!InitializeDatabase()) {
228 return false;
229 }
188 230
189 // Slurp all the cookies into the out-vector. 231 // Slurp all the cookies into the out-vector.
190 sql::Statement smt(db_->GetUniqueStatement( 232 sql::Statement smt(db_->GetUniqueStatement(
191 "SELECT creation_utc, host_key, name, value, path, expires_utc, secure, " 233 "SELECT creation_utc, host_key, name, value, path, expires_utc, secure, "
192 "httponly, last_access_utc FROM cookies")); 234 "httponly, last_access_utc FROM cookies"));
193 if (!smt) { 235 if (!smt) {
194 NOTREACHED() << "select statement prep failed"; 236 NOTREACHED() << "select statement prep failed";
195 db_.reset(); 237 db_.reset();
196 return false; 238 return false;
197 } 239 }
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 file_util::Delete(path_, false); 507 file_util::Delete(path_, false);
466 } 508 }
467 509
468 void SQLitePersistentCookieStore::Backend::SetClearLocalStateOnExit( 510 void SQLitePersistentCookieStore::Backend::SetClearLocalStateOnExit(
469 bool clear_local_state) { 511 bool clear_local_state) {
470 base::AutoLock locked(lock_); 512 base::AutoLock locked(lock_);
471 clear_local_state_on_exit_ = clear_local_state; 513 clear_local_state_on_exit_ = clear_local_state;
472 } 514 }
473 SQLitePersistentCookieStore::SQLitePersistentCookieStore(const FilePath& path) 515 SQLitePersistentCookieStore::SQLitePersistentCookieStore(const FilePath& path)
474 : backend_(new Backend(path)) { 516 : backend_(new Backend(path)) {
517 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB));
475 } 518 }
476 519
477 SQLitePersistentCookieStore::~SQLitePersistentCookieStore() { 520 SQLitePersistentCookieStore::~SQLitePersistentCookieStore() {
478 if (backend_.get()) { 521 if (backend_.get()) {
479 backend_->Close(); 522 backend_->Close();
480 // Release our reference, it will probably still have a reference if the 523 // Release our reference, it will probably still have a reference if the
481 // background thread has not run Close() yet. 524 // background thread has not run Close() yet.
482 backend_ = NULL; 525 backend_ = NULL;
483 } 526 }
484 } 527 }
485 528
486 bool SQLitePersistentCookieStore::Load( 529 bool SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback) {
487 std::vector<net::CookieMonster::CanonicalCookie*>* cookies) { 530 return backend_->Load(loaded_callback);
488 return backend_->Load(cookies);
489 } 531 }
490 532
491 void SQLitePersistentCookieStore::AddCookie( 533 void SQLitePersistentCookieStore::AddCookie(
492 const net::CookieMonster::CanonicalCookie& cc) { 534 const net::CookieMonster::CanonicalCookie& cc) {
493 if (backend_.get()) 535 if (backend_.get())
494 backend_->AddCookie(cc); 536 backend_->AddCookie(cc);
495 } 537 }
496 538
497 void SQLitePersistentCookieStore::UpdateCookieAccessTime( 539 void SQLitePersistentCookieStore::UpdateCookieAccessTime(
498 const net::CookieMonster::CanonicalCookie& cc) { 540 const net::CookieMonster::CanonicalCookie& cc) {
(...skipping 12 matching lines...) Expand all
511 if (backend_.get()) 553 if (backend_.get())
512 backend_->SetClearLocalStateOnExit(clear_local_state); 554 backend_->SetClearLocalStateOnExit(clear_local_state);
513 } 555 }
514 556
515 void SQLitePersistentCookieStore::Flush(Task* completion_task) { 557 void SQLitePersistentCookieStore::Flush(Task* completion_task) {
516 if (backend_.get()) 558 if (backend_.get())
517 backend_->Flush(completion_task); 559 backend_->Flush(completion_task);
518 else if (completion_task) 560 else if (completion_task)
519 MessageLoop::current()->PostTask(FROM_HERE, completion_task); 561 MessageLoop::current()->PostTask(FROM_HERE, completion_task);
520 } 562 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698