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

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

Issue 306032: Simplify threading in browser thread by making only ChromeThread deal with di... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: a few more simplifications Created 11 years, 1 month 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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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/statement.h" 9 #include "app/sql/statement.h"
10 #include "app/sql/transaction.h" 10 #include "app/sql/transaction.h"
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/ref_counted.h" 13 #include "base/ref_counted.h"
14 #include "base/scoped_ptr.h" 14 #include "base/scoped_ptr.h"
15 #include "base/string_util.h" 15 #include "base/string_util.h"
16 #include "base/thread.h" 16 #include "base/thread.h"
17 #include "chrome/browser/chrome_thread.h"
17 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" 18 #include "chrome/browser/diagnostics/sqlite_diagnostics.h"
18 19
19 using base::Time; 20 using base::Time;
20 21
21 // This class is designed to be shared between any calling threads and the 22 // This class is designed to be shared between any calling threads and the
22 // database thread. It batches operations and commits them on a timer. 23 // database thread. It batches operations and commits them on a timer.
23 class SQLitePersistentCookieStore::Backend 24 class SQLitePersistentCookieStore::Backend
24 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { 25 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> {
25 public: 26 public:
26 // The passed database pointer must be already-initialized. This object will 27 // The passed database pointer must be already-initialized. This object will
27 // take ownership. 28 // take ownership.
28 explicit Backend(sql::Connection* db, MessageLoop* loop) 29 explicit Backend(sql::Connection* db)
29 : db_(db), 30 : db_(db),
30 background_loop_(loop),
31 num_pending_(0) { 31 num_pending_(0) {
32 DCHECK(db_) << "Database must exist."; 32 DCHECK(db_) << "Database must exist.";
33 } 33 }
34 34
35 // You should call Close() before destructing this object. 35 // You should call Close() before destructing this object.
36 ~Backend() { 36 ~Backend() {
37 DCHECK(!db_) << "Close should have already been called."; 37 DCHECK(!db_) << "Close should have already been called.";
38 DCHECK(num_pending_ == 0 && pending_.empty()); 38 DCHECK(num_pending_ == 0 && pending_.empty());
39 } 39 }
40 40
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 // Batch a cookie operation (add or delete) 80 // Batch a cookie operation (add or delete)
81 void BatchOperation(PendingOperation::OperationType op, 81 void BatchOperation(PendingOperation::OperationType op,
82 const std::string& key, 82 const std::string& key,
83 const net::CookieMonster::CanonicalCookie& cc); 83 const net::CookieMonster::CanonicalCookie& cc);
84 // Commit our pending operations to the database. 84 // Commit our pending operations to the database.
85 void Commit(); 85 void Commit();
86 // Close() executed on the background thread. 86 // Close() executed on the background thread.
87 void InternalBackgroundClose(); 87 void InternalBackgroundClose();
88 88
89 sql::Connection* db_; 89 sql::Connection* db_;
90 MessageLoop* background_loop_;
91 90
92 typedef std::list<PendingOperation*> PendingOperationsList; 91 typedef std::list<PendingOperation*> PendingOperationsList;
93 PendingOperationsList pending_; 92 PendingOperationsList pending_;
94 PendingOperationsList::size_type num_pending_; 93 PendingOperationsList::size_type num_pending_;
95 Lock pending_lock_; // Guard pending_ and num_pending_ 94 Lock pending_lock_; // Guard pending_ and num_pending_
96 95
97 DISALLOW_COPY_AND_ASSIGN(Backend); 96 DISALLOW_COPY_AND_ASSIGN(Backend);
98 }; 97 };
99 98
100 void SQLitePersistentCookieStore::Backend::AddCookie( 99 void SQLitePersistentCookieStore::Backend::AddCookie(
(...skipping 13 matching lines...) Expand all
114 } 113 }
115 114
116 void SQLitePersistentCookieStore::Backend::BatchOperation( 115 void SQLitePersistentCookieStore::Backend::BatchOperation(
117 PendingOperation::OperationType op, 116 PendingOperation::OperationType op,
118 const std::string& key, 117 const std::string& key,
119 const net::CookieMonster::CanonicalCookie& cc) { 118 const net::CookieMonster::CanonicalCookie& cc) {
120 // Commit every 30 seconds. 119 // Commit every 30 seconds.
121 static const int kCommitIntervalMs = 30 * 1000; 120 static const int kCommitIntervalMs = 30 * 1000;
122 // Commit right away if we have more than 512 outstanding operations. 121 // Commit right away if we have more than 512 outstanding operations.
123 static const size_t kCommitAfterBatchSize = 512; 122 static const size_t kCommitAfterBatchSize = 512;
124 DCHECK(MessageLoop::current() != background_loop_); 123 DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::DB));
125 124
126 // We do a full copy of the cookie here, and hopefully just here. 125 // We do a full copy of the cookie here, and hopefully just here.
127 scoped_ptr<PendingOperation> po(new PendingOperation(op, key, cc)); 126 scoped_ptr<PendingOperation> po(new PendingOperation(op, key, cc));
128 CHECK(po.get()); 127 CHECK(po.get());
129 128
130 PendingOperationsList::size_type num_pending; 129 PendingOperationsList::size_type num_pending;
131 { 130 {
132 AutoLock locked(pending_lock_); 131 AutoLock locked(pending_lock_);
133 pending_.push_back(po.release()); 132 pending_.push_back(po.release());
134 num_pending = ++num_pending_; 133 num_pending = ++num_pending_;
135 } 134 }
136 135
137 // TODO(abarth): What if the DB thread is being destroyed on the UI thread?
138 if (num_pending == 1) { 136 if (num_pending == 1) {
139 // We've gotten our first entry for this batch, fire off the timer. 137 // We've gotten our first entry for this batch, fire off the timer.
140 background_loop_->PostDelayedTask(FROM_HERE, 138 ChromeThread::PostDelayedTask(
139 ChromeThread::DB, FROM_HERE,
141 NewRunnableMethod(this, &Backend::Commit), kCommitIntervalMs); 140 NewRunnableMethod(this, &Backend::Commit), kCommitIntervalMs);
142 } else if (num_pending == kCommitAfterBatchSize) { 141 } else if (num_pending == kCommitAfterBatchSize) {
143 // We've reached a big enough batch, fire off a commit now. 142 // We've reached a big enough batch, fire off a commit now.
144 background_loop_->PostTask(FROM_HERE, 143 ChromeThread::PostTask(
145 NewRunnableMethod(this, &Backend::Commit)); 144 ChromeThread::DB, FROM_HERE, NewRunnableMethod(this, &Backend::Commit));
146 } 145 }
147 } 146 }
148 147
149 void SQLitePersistentCookieStore::Backend::Commit() { 148 void SQLitePersistentCookieStore::Backend::Commit() {
150 DCHECK(MessageLoop::current() == background_loop_); 149 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
151 PendingOperationsList ops; 150 PendingOperationsList ops;
152 { 151 {
153 AutoLock locked(pending_lock_); 152 AutoLock locked(pending_lock_);
154 pending_.swap(ops); 153 pending_.swap(ops);
155 num_pending_ = 0; 154 num_pending_ = 0;
156 } 155 }
157 156
158 // Maybe an old timer fired or we are already Close()'ed. 157 // Maybe an old timer fired or we are already Close()'ed.
159 if (!db_ || ops.empty()) 158 if (!db_ || ops.empty())
160 return; 159 return;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 break; 228 break;
230 } 229 }
231 } 230 }
232 transaction.Commit(); 231 transaction.Commit();
233 } 232 }
234 233
235 // Fire off a close message to the background thread. We could still have a 234 // Fire off a close message to the background thread. We could still have a
236 // pending commit timer that will be holding a reference on us, but if/when 235 // pending commit timer that will be holding a reference on us, but if/when
237 // this fires we will already have been cleaned up and it will be ignored. 236 // this fires we will already have been cleaned up and it will be ignored.
238 void SQLitePersistentCookieStore::Backend::Close() { 237 void SQLitePersistentCookieStore::Backend::Close() {
239 DCHECK(MessageLoop::current() != background_loop_); 238 DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::DB));
240 // Must close the backend on the background thread. 239 // Must close the backend on the background thread.
241 // TODO(abarth): What if the DB thread is being destroyed on the UI thread? 240 ChromeThread::PostTask(
242 background_loop_->PostTask(FROM_HERE, 241 ChromeThread::DB, FROM_HERE,
243 NewRunnableMethod(this, &Backend::InternalBackgroundClose)); 242 NewRunnableMethod(this, &Backend::InternalBackgroundClose));
244 } 243 }
245 244
246 void SQLitePersistentCookieStore::Backend::InternalBackgroundClose() { 245 void SQLitePersistentCookieStore::Backend::InternalBackgroundClose() {
247 DCHECK(MessageLoop::current() == background_loop_); 246 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB));
248 // Commit any pending operations 247 // Commit any pending operations
249 Commit(); 248 Commit();
250 249
251 delete db_; 250 delete db_;
252 db_ = NULL; 251 db_ = NULL;
253 } 252 }
254 253
255 SQLitePersistentCookieStore::SQLitePersistentCookieStore( 254 SQLitePersistentCookieStore::SQLitePersistentCookieStore(const FilePath& path)
256 const FilePath& path, 255 : path_(path) {
257 MessageLoop* background_loop)
258 : path_(path),
259 background_loop_(background_loop) {
260 DCHECK(background_loop) << "SQLitePersistentCookieStore needs a MessageLoop";
261 } 256 }
262 257
263 SQLitePersistentCookieStore::~SQLitePersistentCookieStore() { 258 SQLitePersistentCookieStore::~SQLitePersistentCookieStore() {
264 if (backend_.get()) { 259 if (backend_.get()) {
265 backend_->Close(); 260 backend_->Close();
266 // Release our reference, it will probably still have a reference if the 261 // Release our reference, it will probably still have a reference if the
267 // background thread has not run Close() yet. 262 // background thread has not run Close() yet.
268 backend_ = NULL; 263 backend_ = NULL;
269 } 264 }
270 } 265 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 true, // has_expires 341 true, // has_expires
347 Time::FromInternalValue(smt.ColumnInt64(5)))); // expires_utc 342 Time::FromInternalValue(smt.ColumnInt64(5)))); // expires_utc
348 DLOG_IF(WARNING, 343 DLOG_IF(WARNING,
349 cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; 344 cc->CreationDate() > Time::Now()) << L"CreationDate too recent";
350 cookies->push_back( 345 cookies->push_back(
351 net::CookieMonster::KeyedCanonicalCookie(smt.ColumnString(1), 346 net::CookieMonster::KeyedCanonicalCookie(smt.ColumnString(1),
352 cc.release())); 347 cc.release()));
353 } 348 }
354 349
355 // Create the backend, this will take ownership of the db pointer. 350 // Create the backend, this will take ownership of the db pointer.
356 backend_ = new Backend(db.release(), background_loop_); 351 backend_ = new Backend(db.release());
357 return true; 352 return true;
358 } 353 }
359 354
360 bool SQLitePersistentCookieStore::EnsureDatabaseVersion(sql::Connection* db) { 355 bool SQLitePersistentCookieStore::EnsureDatabaseVersion(sql::Connection* db) {
361 // Version check. 356 // Version check.
362 if (!meta_table_.Init(db, kCurrentVersionNumber, kCompatibleVersionNumber)) 357 if (!meta_table_.Init(db, kCurrentVersionNumber, kCompatibleVersionNumber))
363 return false; 358 return false;
364 359
365 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { 360 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
366 LOG(WARNING) << "Cookie database is too new."; 361 LOG(WARNING) << "Cookie database is too new.";
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 const net::CookieMonster::CanonicalCookie& cc) { 435 const net::CookieMonster::CanonicalCookie& cc) {
441 if (backend_.get()) 436 if (backend_.get())
442 backend_->UpdateCookieAccessTime(cc); 437 backend_->UpdateCookieAccessTime(cc);
443 } 438 }
444 439
445 void SQLitePersistentCookieStore::DeleteCookie( 440 void SQLitePersistentCookieStore::DeleteCookie(
446 const net::CookieMonster::CanonicalCookie& cc) { 441 const net::CookieMonster::CanonicalCookie& cc) {
447 if (backend_.get()) 442 if (backend_.get())
448 backend_->DeleteCookie(cc); 443 backend_->DeleteCookie(cc);
449 } 444 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698