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

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

Issue 11742037: Make ServerBoundCertStore interface async, move SQLiteServerBoundCertStore load onto DB thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix login_utils_browsertest Created 7 years, 11 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_server_bound_cert_store.h" 5 #include "chrome/browser/net/sqlite_server_bound_cert_store.h"
6 6
7 #include <list> 7 #include <list>
8 #include <set> 8 #include <set>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 23 matching lines...) Expand all
34 : public base::RefCountedThreadSafe<SQLiteServerBoundCertStore::Backend> { 34 : public base::RefCountedThreadSafe<SQLiteServerBoundCertStore::Backend> {
35 public: 35 public:
36 Backend(const FilePath& path, ClearOnExitPolicy* clear_on_exit_policy) 36 Backend(const FilePath& path, ClearOnExitPolicy* clear_on_exit_policy)
37 : path_(path), 37 : path_(path),
38 db_(NULL), 38 db_(NULL),
39 num_pending_(0), 39 num_pending_(0),
40 force_keep_session_state_(false), 40 force_keep_session_state_(false),
41 clear_on_exit_policy_(clear_on_exit_policy) { 41 clear_on_exit_policy_(clear_on_exit_policy) {
42 } 42 }
43 43
44 // Creates or load the SQLite database. 44 // Creates or loads the SQLite database.
45 bool Load( 45 void Load(const LoadedCallback& loaded_callback);
46 std::vector<net::DefaultServerBoundCertStore::ServerBoundCert*>* certs);
47 46
48 // Batch a server bound cert addition. 47 // Batch a server bound cert addition.
49 void AddServerBoundCert( 48 void AddServerBoundCert(
50 const net::DefaultServerBoundCertStore::ServerBoundCert& cert); 49 const net::DefaultServerBoundCertStore::ServerBoundCert& cert);
51 50
52 // Batch a server bound cert deletion. 51 // Batch a server bound cert deletion.
53 void DeleteServerBoundCert( 52 void DeleteServerBoundCert(
54 const net::DefaultServerBoundCertStore::ServerBoundCert& cert); 53 const net::DefaultServerBoundCertStore::ServerBoundCert& cert);
55 54
56 // Commit pending operations as soon as possible. 55 // Commit pending operations as soon as possible.
57 void Flush(const base::Closure& completion_task); 56 void Flush(const base::Closure& completion_task);
58 57
59 // Commit any pending operations and close the database. This must be called 58 // Commit any pending operations and close the database. This must be called
60 // before the object is destructed. 59 // before the object is destructed.
61 void Close(); 60 void Close();
62 61
63 void SetForceKeepSessionState(); 62 void SetForceKeepSessionState();
64 63
65 private: 64 private:
65 void LoadOnDBThreadAndNotify(const LoadedCallback& loaded_callback);
66 void LoadOnDBThread(
67 std::vector<net::DefaultServerBoundCertStore::ServerBoundCert*>* certs);
68
66 friend class base::RefCountedThreadSafe<SQLiteServerBoundCertStore::Backend>; 69 friend class base::RefCountedThreadSafe<SQLiteServerBoundCertStore::Backend>;
67 70
68 // You should call Close() before destructing this object. 71 // You should call Close() before destructing this object.
69 ~Backend() { 72 ~Backend() {
70 DCHECK(!db_.get()) << "Close should have already been called."; 73 DCHECK(!db_.get()) << "Close should have already been called.";
71 DCHECK(num_pending_ == 0 && pending_.empty()); 74 DCHECK(num_pending_ == 0 && pending_.empty());
72 } 75 }
73 76
74 // Database upgrade statements. 77 // Database upgrade statements.
75 bool EnsureDatabaseVersion(); 78 bool EnsureDatabaseVersion();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 "expiration_time INTEGER," 151 "expiration_time INTEGER,"
149 "creation_time INTEGER)")) 152 "creation_time INTEGER)"))
150 return false; 153 return false;
151 } 154 }
152 155
153 return true; 156 return true;
154 } 157 }
155 158
156 } // namespace 159 } // namespace
157 160
158 bool SQLiteServerBoundCertStore::Backend::Load( 161 void SQLiteServerBoundCertStore::Backend::Load(
159 std::vector<net::DefaultServerBoundCertStore::ServerBoundCert*>* certs) { 162 const LoadedCallback& loaded_callback) {
160 // This function should be called only once per instance. 163 // This function should be called only once per instance.
161 DCHECK(!db_.get()); 164 DCHECK(!db_.get());
162 165
163 // TODO(paivanof@gmail.com): We do a lot of disk access in this function, 166 BrowserThread::PostTask(
164 // thus we do an exception to allow IO on the UI thread. This code will be 167 BrowserThread::DB, FROM_HERE,
165 // moved to the DB thread as part of http://crbug.com/89665. 168 base::Bind(&Backend::LoadOnDBThreadAndNotify, this, loaded_callback));
166 base::ThreadRestrictions::ScopedAllowIO allow_io; 169 }
170
171 void SQLiteServerBoundCertStore::Backend::LoadOnDBThreadAndNotify(
172 const LoadedCallback& loaded_callback) {
173 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
174 scoped_ptr<ScopedVector<net::DefaultServerBoundCertStore::ServerBoundCert> >
175 certs(new ScopedVector<net::DefaultServerBoundCertStore::ServerBoundCert>(
176 ));
177
178 LoadOnDBThread(&certs->get());
179
180 BrowserThread::PostTask(
181 BrowserThread::IO, FROM_HERE,
182 base::Bind(loaded_callback, base::Passed(&certs)));
183 }
184
185 void SQLiteServerBoundCertStore::Backend::LoadOnDBThread(
186 std::vector<net::DefaultServerBoundCertStore::ServerBoundCert*>* certs) {
187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
188
189 // This method should be called only once per instance.
190 DCHECK(!db_.get());
167 191
168 base::TimeTicks start = base::TimeTicks::Now(); 192 base::TimeTicks start = base::TimeTicks::Now();
169 193
170 // Ensure the parent directory for storing certs is created before reading 194 // Ensure the parent directory for storing certs is created before reading
171 // from it. 195 // from it.
172 const FilePath dir = path_.DirName(); 196 const FilePath dir = path_.DirName();
173 if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir)) 197 if (!file_util::PathExists(dir) && !file_util::CreateDirectory(dir))
174 return false; 198 return;
175 199
176 int64 db_size = 0; 200 int64 db_size = 0;
177 if (file_util::GetFileSize(path_, &db_size)) 201 if (file_util::GetFileSize(path_, &db_size))
178 UMA_HISTOGRAM_COUNTS("DomainBoundCerts.DBSizeInKB", db_size / 1024 ); 202 UMA_HISTOGRAM_COUNTS("DomainBoundCerts.DBSizeInKB", db_size / 1024 );
179 203
180 db_.reset(new sql::Connection); 204 db_.reset(new sql::Connection);
181 if (!db_->Open(path_)) { 205 if (!db_->Open(path_)) {
182 NOTREACHED() << "Unable to open cert DB."; 206 NOTREACHED() << "Unable to open cert DB.";
183 db_.reset(); 207 db_.reset();
184 return false; 208 return;
185 } 209 }
186 210
187 if (!EnsureDatabaseVersion() || !InitTable(db_.get())) { 211 if (!EnsureDatabaseVersion() || !InitTable(db_.get())) {
188 NOTREACHED() << "Unable to open cert DB."; 212 NOTREACHED() << "Unable to open cert DB.";
189 db_.reset(); 213 db_.reset();
190 return false; 214 return;
191 } 215 }
192 216
193 db_->Preload(); 217 db_->Preload();
194 218
195 // Slurp all the certs into the out-vector. 219 // Slurp all the certs into the out-vector.
196 sql::Statement smt(db_->GetUniqueStatement( 220 sql::Statement smt(db_->GetUniqueStatement(
197 "SELECT origin, private_key, cert, cert_type, expiration_time, " 221 "SELECT origin, private_key, cert, cert_type, expiration_time, "
198 "creation_time FROM origin_bound_certs")); 222 "creation_time FROM origin_bound_certs"));
199 if (!smt.is_valid()) { 223 if (!smt.is_valid()) {
200 db_.reset(); 224 db_.reset();
201 return false; 225 return;
202 } 226 }
203 227
204 while (smt.Step()) { 228 while (smt.Step()) {
205 std::string private_key_from_db, cert_from_db; 229 std::string private_key_from_db, cert_from_db;
206 smt.ColumnBlobAsString(1, &private_key_from_db); 230 smt.ColumnBlobAsString(1, &private_key_from_db);
207 smt.ColumnBlobAsString(2, &cert_from_db); 231 smt.ColumnBlobAsString(2, &cert_from_db);
208 scoped_ptr<net::DefaultServerBoundCertStore::ServerBoundCert> cert( 232 scoped_ptr<net::DefaultServerBoundCertStore::ServerBoundCert> cert(
209 new net::DefaultServerBoundCertStore::ServerBoundCert( 233 new net::DefaultServerBoundCertStore::ServerBoundCert(
210 smt.ColumnString(0), // origin 234 smt.ColumnString(0), // origin
211 static_cast<net::SSLClientCertType>(smt.ColumnInt(3)), 235 static_cast<net::SSLClientCertType>(smt.ColumnInt(3)),
212 base::Time::FromInternalValue(smt.ColumnInt64(5)), 236 base::Time::FromInternalValue(smt.ColumnInt64(5)),
213 base::Time::FromInternalValue(smt.ColumnInt64(4)), 237 base::Time::FromInternalValue(smt.ColumnInt64(4)),
214 private_key_from_db, 238 private_key_from_db,
215 cert_from_db)); 239 cert_from_db));
216 cert_origins_.insert(cert->server_identifier()); 240 cert_origins_.insert(cert->server_identifier());
217 certs->push_back(cert.release()); 241 certs->push_back(cert.release());
218 } 242 }
219 243
220 UMA_HISTOGRAM_COUNTS_10000("DomainBoundCerts.DBLoadedCount", certs->size()); 244 UMA_HISTOGRAM_COUNTS_10000("DomainBoundCerts.DBLoadedCount", certs->size());
245 base::TimeDelta load_time = base::TimeTicks::Now() - start;
221 UMA_HISTOGRAM_CUSTOM_TIMES("DomainBoundCerts.DBLoadTime", 246 UMA_HISTOGRAM_CUSTOM_TIMES("DomainBoundCerts.DBLoadTime",
222 base::TimeTicks::Now() - start, 247 load_time,
223 base::TimeDelta::FromMilliseconds(1), 248 base::TimeDelta::FromMilliseconds(1),
224 base::TimeDelta::FromMinutes(1), 249 base::TimeDelta::FromMinutes(1),
225 50); 250 50);
226 return true; 251 DVLOG(1) << "loaded " << certs->size() << " in " << load_time.InMilliseconds()
252 << " ms";
227 } 253 }
228 254
229 bool SQLiteServerBoundCertStore::Backend::EnsureDatabaseVersion() { 255 bool SQLiteServerBoundCertStore::Backend::EnsureDatabaseVersion() {
230 // Version check. 256 // Version check.
231 if (!meta_table_.Init( 257 if (!meta_table_.Init(
232 db_.get(), kCurrentVersionNumber, kCompatibleVersionNumber)) { 258 db_.get(), kCurrentVersionNumber, kCompatibleVersionNumber)) {
233 return false; 259 return false;
234 } 260 }
235 261
236 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { 262 if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) {
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 base::AutoLock locked(lock_); 563 base::AutoLock locked(lock_);
538 force_keep_session_state_ = true; 564 force_keep_session_state_ = true;
539 } 565 }
540 566
541 SQLiteServerBoundCertStore::SQLiteServerBoundCertStore( 567 SQLiteServerBoundCertStore::SQLiteServerBoundCertStore(
542 const FilePath& path, 568 const FilePath& path,
543 ClearOnExitPolicy* clear_on_exit_policy) 569 ClearOnExitPolicy* clear_on_exit_policy)
544 : backend_(new Backend(path, clear_on_exit_policy)) { 570 : backend_(new Backend(path, clear_on_exit_policy)) {
545 } 571 }
546 572
547 bool SQLiteServerBoundCertStore::Load( 573 void SQLiteServerBoundCertStore::Load(
548 std::vector<net::DefaultServerBoundCertStore::ServerBoundCert*>* certs) { 574 const LoadedCallback& loaded_callback) {
549 return backend_->Load(certs); 575 backend_->Load(loaded_callback);
550 } 576 }
551 577
552 void SQLiteServerBoundCertStore::AddServerBoundCert( 578 void SQLiteServerBoundCertStore::AddServerBoundCert(
553 const net::DefaultServerBoundCertStore::ServerBoundCert& cert) { 579 const net::DefaultServerBoundCertStore::ServerBoundCert& cert) {
554 backend_->AddServerBoundCert(cert); 580 backend_->AddServerBoundCert(cert);
555 } 581 }
556 582
557 void SQLiteServerBoundCertStore::DeleteServerBoundCert( 583 void SQLiteServerBoundCertStore::DeleteServerBoundCert(
558 const net::DefaultServerBoundCertStore::ServerBoundCert& cert) { 584 const net::DefaultServerBoundCertStore::ServerBoundCert& cert) {
559 backend_->DeleteServerBoundCert(cert); 585 backend_->DeleteServerBoundCert(cert);
560 } 586 }
561 587
562 void SQLiteServerBoundCertStore::SetForceKeepSessionState() { 588 void SQLiteServerBoundCertStore::SetForceKeepSessionState() {
563 backend_->SetForceKeepSessionState(); 589 backend_->SetForceKeepSessionState();
564 } 590 }
565 591
566 void SQLiteServerBoundCertStore::Flush(const base::Closure& completion_task) { 592 void SQLiteServerBoundCertStore::Flush(const base::Closure& completion_task) {
567 backend_->Flush(completion_task); 593 backend_->Flush(completion_task);
568 } 594 }
569 595
570 SQLiteServerBoundCertStore::~SQLiteServerBoundCertStore() { 596 SQLiteServerBoundCertStore::~SQLiteServerBoundCertStore() {
571 backend_->Close(); 597 backend_->Close();
572 // We release our reference to the Backend, though it will probably still have 598 // We release our reference to the Backend, though it will probably still have
573 // a reference if the background thread has not run Close() yet. 599 // a reference if the background thread has not run Close() yet.
574 } 600 }
OLDNEW
« no previous file with comments | « chrome/browser/net/sqlite_server_bound_cert_store.h ('k') | chrome/browser/net/sqlite_server_bound_cert_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698