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

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

Issue 5430004: Refactored cookies persistent store clean-up on shutdown. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Lock protected the clear on exit flag. Created 10 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "app/sql/meta_table.h" 9 #include "app/sql/meta_table.h"
10 #include "app/sql/statement.h" 10 #include "app/sql/statement.h"
(...skipping 13 matching lines...) Expand all
24 using base::Time; 24 using base::Time;
25 25
26 // This class is designed to be shared between any calling threads and the 26 // This class is designed to be shared between any calling threads and the
27 // database thread. It batches operations and commits them on a timer. 27 // database thread. It batches operations and commits them on a timer.
28 class SQLitePersistentCookieStore::Backend 28 class SQLitePersistentCookieStore::Backend
29 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { 29 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> {
30 public: 30 public:
31 explicit Backend(const FilePath& path) 31 explicit Backend(const FilePath& path)
32 : path_(path), 32 : path_(path),
33 db_(NULL), 33 db_(NULL),
34 num_pending_(0) { 34 num_pending_(0),
35 clear_local_state_on_exit_(false) {
35 } 36 }
36 37
37 // Creates or load the SQLite database. 38 // Creates or load the SQLite database.
38 bool Load(std::vector<net::CookieMonster::CanonicalCookie*>* cookies); 39 bool Load(std::vector<net::CookieMonster::CanonicalCookie*>* cookies);
39 40
40 // Batch a cookie addition. 41 // Batch a cookie addition.
41 void AddCookie(const net::CookieMonster::CanonicalCookie& cc); 42 void AddCookie(const net::CookieMonster::CanonicalCookie& cc);
42 43
43 // Batch a cookie access time update. 44 // Batch a cookie access time update.
44 void UpdateCookieAccessTime(const net::CookieMonster::CanonicalCookie& cc); 45 void UpdateCookieAccessTime(const net::CookieMonster::CanonicalCookie& cc);
45 46
46 // Batch a cookie deletion. 47 // Batch a cookie deletion.
47 void DeleteCookie(const net::CookieMonster::CanonicalCookie& cc); 48 void DeleteCookie(const net::CookieMonster::CanonicalCookie& cc);
48 49
49 // Commit any pending operations and close the database. This must be called 50 // Commit any pending operations and close the database. This must be called
50 // before the object is destructed. 51 // before the object is destructed.
51 void Close(); 52 void Close();
52 53
54 void SetClearLocalStateOnExit(bool clear_local_state);
55
53 private: 56 private:
54 friend class base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend>; 57 friend class base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend>;
55 58
56 // You should call Close() before destructing this object. 59 // You should call Close() before destructing this object.
57 ~Backend() { 60 ~Backend() {
58 DCHECK(!db_.get()) << "Close should have already been called."; 61 DCHECK(!db_.get()) << "Close should have already been called.";
59 DCHECK(num_pending_ == 0 && pending_.empty()); 62 DCHECK(num_pending_ == 0 && pending_.empty());
60 } 63 }
61 64
62 // Database upgrade statements. 65 // Database upgrade statements.
(...skipping 28 matching lines...) Expand all
91 // Close() executed on the background thread. 94 // Close() executed on the background thread.
92 void InternalBackgroundClose(); 95 void InternalBackgroundClose();
93 96
94 FilePath path_; 97 FilePath path_;
95 scoped_ptr<sql::Connection> db_; 98 scoped_ptr<sql::Connection> db_;
96 sql::MetaTable meta_table_; 99 sql::MetaTable meta_table_;
97 100
98 typedef std::list<PendingOperation*> PendingOperationsList; 101 typedef std::list<PendingOperation*> PendingOperationsList;
99 PendingOperationsList pending_; 102 PendingOperationsList pending_;
100 PendingOperationsList::size_type num_pending_; 103 PendingOperationsList::size_type num_pending_;
101 Lock pending_lock_; // Guard pending_ and num_pending_ 104 // True if the persistent store should be deleted upon destruction.
105 bool clear_local_state_on_exit_;
106 // Guard |pending_|, |num_pending_| and |clear_local_state_on_exit_|.
107 Lock lock_;
102 108
103 DISALLOW_COPY_AND_ASSIGN(Backend); 109 DISALLOW_COPY_AND_ASSIGN(Backend);
104 }; 110 };
105 111
106 // Version number of the database. In version 4, we migrated the time epoch. 112 // Version number of the database. In version 4, we migrated the time epoch.
107 // If you open the DB with an older version on Mac or Linux, the times will 113 // If you open the DB with an older version on Mac or Linux, the times will
108 // look wonky, but the file will likely be usable. On Windows version 3 and 4 114 // look wonky, but the file will likely be usable. On Windows version 3 and 4
109 // are the same. 115 // are the same.
110 // 116 //
111 // Version 3 updated the database to include the last access time, so we can 117 // Version 3 updated the database to include the last access time, so we can
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 static const int kCommitIntervalMs = 30 * 1000; 296 static const int kCommitIntervalMs = 30 * 1000;
291 // Commit right away if we have more than 512 outstanding operations. 297 // Commit right away if we have more than 512 outstanding operations.
292 static const size_t kCommitAfterBatchSize = 512; 298 static const size_t kCommitAfterBatchSize = 512;
293 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); 299 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB));
294 300
295 // We do a full copy of the cookie here, and hopefully just here. 301 // We do a full copy of the cookie here, and hopefully just here.
296 scoped_ptr<PendingOperation> po(new PendingOperation(op, cc)); 302 scoped_ptr<PendingOperation> po(new PendingOperation(op, cc));
297 303
298 PendingOperationsList::size_type num_pending; 304 PendingOperationsList::size_type num_pending;
299 { 305 {
300 AutoLock locked(pending_lock_); 306 AutoLock locked(lock_);
301 pending_.push_back(po.release()); 307 pending_.push_back(po.release());
302 num_pending = ++num_pending_; 308 num_pending = ++num_pending_;
303 } 309 }
304 310
305 if (num_pending == 1) { 311 if (num_pending == 1) {
306 // We've gotten our first entry for this batch, fire off the timer. 312 // We've gotten our first entry for this batch, fire off the timer.
307 BrowserThread::PostDelayedTask( 313 BrowserThread::PostDelayedTask(
308 BrowserThread::DB, FROM_HERE, 314 BrowserThread::DB, FROM_HERE,
309 NewRunnableMethod(this, &Backend::Commit), kCommitIntervalMs); 315 NewRunnableMethod(this, &Backend::Commit), kCommitIntervalMs);
310 } else if (num_pending == kCommitAfterBatchSize) { 316 } else if (num_pending == kCommitAfterBatchSize) {
311 // We've reached a big enough batch, fire off a commit now. 317 // We've reached a big enough batch, fire off a commit now.
312 BrowserThread::PostTask( 318 BrowserThread::PostTask(
313 BrowserThread::DB, FROM_HERE, 319 BrowserThread::DB, FROM_HERE,
314 NewRunnableMethod(this, &Backend::Commit)); 320 NewRunnableMethod(this, &Backend::Commit));
315 } 321 }
316 } 322 }
317 323
318 void SQLitePersistentCookieStore::Backend::Commit() { 324 void SQLitePersistentCookieStore::Backend::Commit() {
319 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 325 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
320 PendingOperationsList ops; 326 PendingOperationsList ops;
321 { 327 {
322 AutoLock locked(pending_lock_); 328 AutoLock locked(lock_);
323 pending_.swap(ops); 329 pending_.swap(ops);
324 num_pending_ = 0; 330 num_pending_ = 0;
325 } 331 }
326 332
327 // Maybe an old timer fired or we are already Close()'ed. 333 // Maybe an old timer fired or we are already Close()'ed.
328 if (!db_.get() || ops.empty()) 334 if (!db_.get() || ops.empty())
329 return; 335 return;
330 336
331 sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE, 337 sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE,
332 "INSERT INTO cookies (creation_utc, host_key, name, value, path, " 338 "INSERT INTO cookies (creation_utc, host_key, name, value, path, "
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 BrowserThread::DB, FROM_HERE, 419 BrowserThread::DB, FROM_HERE,
414 NewRunnableMethod(this, &Backend::InternalBackgroundClose)); 420 NewRunnableMethod(this, &Backend::InternalBackgroundClose));
415 } 421 }
416 422
417 void SQLitePersistentCookieStore::Backend::InternalBackgroundClose() { 423 void SQLitePersistentCookieStore::Backend::InternalBackgroundClose() {
418 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 424 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
419 // Commit any pending operations 425 // Commit any pending operations
420 Commit(); 426 Commit();
421 427
422 db_.reset(); 428 db_.reset();
429
430 if (clear_local_state_on_exit_)
431 file_util::Delete(path_, false);
423 } 432 }
424 433
434 void SQLitePersistentCookieStore::Backend::SetClearLocalStateOnExit(
435 bool clear_local_state) {
436 AutoLock locked(lock_);
437 clear_local_state_on_exit_ = clear_local_state;
438 }
425 SQLitePersistentCookieStore::SQLitePersistentCookieStore(const FilePath& path) 439 SQLitePersistentCookieStore::SQLitePersistentCookieStore(const FilePath& path)
426 : backend_(new Backend(path)) { 440 : backend_(new Backend(path)) {
427 } 441 }
428 442
429 SQLitePersistentCookieStore::~SQLitePersistentCookieStore() { 443 SQLitePersistentCookieStore::~SQLitePersistentCookieStore() {
430 if (backend_.get()) { 444 if (backend_.get()) {
431 backend_->Close(); 445 backend_->Close();
432 // Release our reference, it will probably still have a reference if the 446 // Release our reference, it will probably still have a reference if the
433 // background thread has not run Close() yet. 447 // background thread has not run Close() yet.
434 backend_ = NULL; 448 backend_ = NULL;
(...skipping 16 matching lines...) Expand all
451 if (backend_.get()) 465 if (backend_.get())
452 backend_->UpdateCookieAccessTime(cc); 466 backend_->UpdateCookieAccessTime(cc);
453 } 467 }
454 468
455 void SQLitePersistentCookieStore::DeleteCookie( 469 void SQLitePersistentCookieStore::DeleteCookie(
456 const net::CookieMonster::CanonicalCookie& cc) { 470 const net::CookieMonster::CanonicalCookie& cc) {
457 if (backend_.get()) 471 if (backend_.get())
458 backend_->DeleteCookie(cc); 472 backend_->DeleteCookie(cc);
459 } 473 }
460 474
461 // static 475 void SQLitePersistentCookieStore::SetClearLocalStateOnExit(
462 void SQLitePersistentCookieStore::ClearLocalState( 476 bool clear_local_state) {
463 const FilePath& path) { 477 if (backend_.get())
464 file_util::Delete(path, false); 478 backend_->SetClearLocalStateOnExit(clear_local_state);
465 } 479 }
OLDNEW
« no previous file with comments | « chrome/browser/net/sqlite_persistent_cookie_store.h ('k') | chrome/browser/net/sqlite_persistent_cookie_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698