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

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

Issue 8537016: Add/change metrics for cookie store loading: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use a separate lock for metrics. Created 9 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
« no previous file with comments | « no previous file | net/base/cookie_monster.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include <map> 8 #include <map>
9 #include <set> 9 #include <set>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/file_path.h" 14 #include "base/file_path.h"
15 #include "base/file_util.h" 15 #include "base/file_util.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/memory/ref_counted.h" 17 #include "base/memory/ref_counted.h"
18 #include "base/memory/scoped_ptr.h" 18 #include "base/memory/scoped_ptr.h"
19 #include "base/metrics/histogram.h" 19 #include "base/metrics/histogram.h"
20 #include "base/string_util.h" 20 #include "base/string_util.h"
21 #include "base/synchronization/lock.h" 21 #include "base/synchronization/lock.h"
22 #include "base/threading/thread.h" 22 #include "base/threading/thread.h"
23 #include "base/threading/thread_restrictions.h" 23 #include "base/threading/thread_restrictions.h"
24 #include "base/time.h"
24 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" 25 #include "chrome/browser/diagnostics/sqlite_diagnostics.h"
25 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
26 #include "googleurl/src/gurl.h" 27 #include "googleurl/src/gurl.h"
27 #include "net/base/registry_controlled_domain.h" 28 #include "net/base/registry_controlled_domain.h"
28 #include "sql/meta_table.h" 29 #include "sql/meta_table.h"
29 #include "sql/statement.h" 30 #include "sql/statement.h"
30 #include "sql/transaction.h" 31 #include "sql/transaction.h"
31 32
32 using base::Time; 33 using base::Time;
33 using content::BrowserThread; 34 using content::BrowserThread;
34 35
35 // This class is designed to be shared between any calling threads and the 36 // This class is designed to be shared between any calling threads and the
36 // database thread. It batches operations and commits them on a timer. 37 // database thread. It batches operations and commits them on a timer.
37 // 38 //
38 // SQLitePersistentCookieStore::Load is called to load all cookies. It 39 // SQLitePersistentCookieStore::Load is called to load all cookies. It
39 // delegates to Backend::Load, which posts a Backend::LoadAndNotifyOnDBThread 40 // delegates to Backend::Load, which posts a Backend::LoadAndNotifyOnDBThread
40 // task to the DB thread. This task calls Backend::ChainLoadCookies(), which 41 // task to the DB thread. This task calls Backend::ChainLoadCookies(), which
41 // repeatedly posts itself to the DB thread to load each eTLD+1's cookies in 42 // repeatedly posts itself to the DB thread to load each eTLD+1's cookies in
42 // separate tasks. When this is complete, Backend::NotifyOnIOThread is posted 43 // separate tasks. When this is complete, Backend::CompleteLoadOnIOThread is
43 // to the IO thread, which notifies the caller of SQLitePersistentCookieStore:: 44 // posted to the IO thread, which notifies the caller of
44 // Load that the load is complete. 45 // SQLitePersistentCookieStore::Load that the load is complete.
45 // 46 //
46 // If a priority load request is invoked via SQLitePersistentCookieStore:: 47 // If a priority load request is invoked via SQLitePersistentCookieStore::
47 // LoadCookiesForKey, it is delegated to Backend::LoadCookiesForKey, which posts 48 // LoadCookiesForKey, it is delegated to Backend::LoadCookiesForKey, which posts
48 // Backend::LoadKeyAndNotifyOnDBThread to the DB thread. That routine loads just 49 // Backend::LoadKeyAndNotifyOnDBThread to the DB thread. That routine loads just
49 // that single domain key (eTLD+1)'s cookies, and posts a Backend:: 50 // that single domain key (eTLD+1)'s cookies, and posts a Backend::
50 // NotifyOnIOThread to the IO thread to notify the caller of 51 // CompleteLoadForKeyOnIOThread to the IO thread to notify the caller of
51 // SQLitePersistentCookieStore::LoadCookiesForKey that that load is complete. 52 // SQLitePersistentCookieStore::LoadCookiesForKey that that load is complete.
52 // 53 //
53 // Subsequent to loading, mutations may be queued by any thread using 54 // Subsequent to loading, mutations may be queued by any thread using
54 // AddCookie, UpdateCookieAccessTime, and DeleteCookie. These are flushed to 55 // AddCookie, UpdateCookieAccessTime, and DeleteCookie. These are flushed to
55 // disk on the DB thread every 30 seconds, 512 operations, or call to Flush(), 56 // disk on the DB thread every 30 seconds, 512 operations, or call to Flush(),
56 // whichever occurs first. 57 // whichever occurs first.
57 class SQLitePersistentCookieStore::Backend 58 class SQLitePersistentCookieStore::Backend
58 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { 59 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> {
59 public: 60 public:
60 explicit Backend(const FilePath& path) 61 explicit Backend(const FilePath& path)
61 : path_(path), 62 : path_(path),
62 db_(NULL), 63 db_(NULL),
63 num_pending_(0), 64 num_pending_(0),
64 clear_local_state_on_exit_(false), 65 clear_local_state_on_exit_(false),
65 initialized_(false) { 66 initialized_(false),
67 num_priority_waiting_(0),
68 total_priority_requests_(0),
69 metrics_reporting_deferred_(false) {
66 } 70 }
67 71
68 // Creates or loads the SQLite database. 72 // Creates or loads the SQLite database.
69 void Load(const LoadedCallback& loaded_callback); 73 void Load(const LoadedCallback& loaded_callback);
70 74
71 // Loads cookies for the domain key (eTLD+1). 75 // Loads cookies for the domain key (eTLD+1).
72 void LoadCookiesForKey(const std::string& domain, 76 void LoadCookiesForKey(const std::string& domain,
73 const LoadedCallback& loaded_callback); 77 const LoadedCallback& loaded_callback);
74 78
75 // Batch a cookie addition. 79 // Batch a cookie addition.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 // Creates or loads the SQLite database on DB thread. 130 // Creates or loads the SQLite database on DB thread.
127 void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback); 131 void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback);
128 132
129 // Loads cookies for the domain key (eTLD+1) on DB thread. 133 // Loads cookies for the domain key (eTLD+1) on DB thread.
130 void LoadKeyAndNotifyOnDBThread(const std::string& domains, 134 void LoadKeyAndNotifyOnDBThread(const std::string& domains,
131 const LoadedCallback& loaded_callback); 135 const LoadedCallback& loaded_callback);
132 136
133 // Notifies the CookieMonster when loading completes for a specific domain key 137 // Notifies the CookieMonster when loading completes for a specific domain key
134 // or for all domain keys. Triggers the callback and passes it all cookies 138 // or for all domain keys. Triggers the callback and passes it all cookies
135 // that have been loaded from DB since last IO notification. 139 // that have been loaded from DB since last IO notification.
136 void NotifyOnIOThread( 140 void Notify(const LoadedCallback& loaded_callback, bool load_success);
137 const LoadedCallback& loaded_callback, 141
138 bool load_success); 142 // 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
144 // that occurred.
145 void CompleteLoadOnIOThread(const LoadedCallback& loaded_callback,
146 bool load_success);
147
148 // Sends notification when a single priority load completes. Updates priority
149 // load metric data. The data is sent only after the final load completes.
150 void CompleteLoadForKeyOnIOThread(const LoadedCallback& loaded_callback,
151 bool load_success);
152
153 // Sends all metrics, including posting a ReportMetricsOnDBThread task.
154 // Called after all priority and regular loading is complete.
155 void ReportMetrics();
156
157 // Sends DB-thread owned metrics (i.e., the combined duration of all DB-thread
158 // tasks).
159 void ReportMetricsOnDBThread();
139 160
140 // Initialize the data base. 161 // Initialize the data base.
141 bool InitializeDatabase(); 162 bool InitializeDatabase();
142 163
143 // Loads cookies for the next domain key from the DB, then either reschedules 164 // Loads cookies for the next domain key from the DB, then either reschedules
144 // itself or schedules the provided callback to run on the IO thread (if all 165 // itself or schedules the provided callback to run on the IO thread (if all
145 // domains are loaded). 166 // domains are loaded).
146 void ChainLoadCookies(const LoadedCallback& loaded_callback); 167 void ChainLoadCookies(const LoadedCallback& loaded_callback);
147 168
148 // Load all cookies for a set of domains/hosts 169 // Load all cookies for a set of domains/hosts
149 bool LoadCookiesForDomains(const std::set<std::string>& key); 170 bool LoadCookiesForDomains(const std::set<std::string>& key);
150 171
151 // Batch a cookie operation (add or delete) 172 // Batch a cookie operation (add or delete)
152 void BatchOperation(PendingOperation::OperationType op, 173 void BatchOperation(PendingOperation::OperationType op,
153 const net::CookieMonster::CanonicalCookie& cc); 174 const net::CookieMonster::CanonicalCookie& cc);
154 // Commit our pending operations to the database. 175 // Commit our pending operations to the database.
155 void Commit(); 176 void Commit();
156 // Close() executed on the background thread. 177 // Close() executed on the background thread.
157 void InternalBackgroundClose(); 178 void InternalBackgroundClose();
158 179
159 FilePath path_; 180 FilePath path_;
160 scoped_ptr<sql::Connection> db_; 181 scoped_ptr<sql::Connection> db_;
161 sql::MetaTable meta_table_; 182 sql::MetaTable meta_table_;
162 183
163 typedef std::list<PendingOperation*> PendingOperationsList; 184 typedef std::list<PendingOperation*> PendingOperationsList;
164 PendingOperationsList pending_; 185 PendingOperationsList pending_;
165 PendingOperationsList::size_type num_pending_; 186 PendingOperationsList::size_type num_pending_;
166 // True if the persistent store should be deleted upon destruction. 187 // True if the persistent store should be deleted upon destruction.
167 bool clear_local_state_on_exit_; 188 bool clear_local_state_on_exit_;
168 // Guard |cookies_|, |pending_|, |num_pending_| and 189 // Guard |cookies_|, |pending_|, |num_pending_|, |clear_local_state_on_exit_|
169 // |clear_local_state_on_exit_|.
170 base::Lock lock_; 190 base::Lock lock_;
171 191
172 // Temporary buffer for cookies loaded from DB. Accumulates cookies to reduce 192 // Temporary buffer for cookies loaded from DB. Accumulates cookies to reduce
173 // the number of messages sent to the IO thread. Sent back in response to 193 // the number of messages sent to the IO thread. Sent back in response to
174 // individual load requests for domain keys or when all loading completes. 194 // individual load requests for domain keys or when all loading completes.
175 std::vector<net::CookieMonster::CanonicalCookie*> cookies_; 195 std::vector<net::CookieMonster::CanonicalCookie*> cookies_;
176 196
177 // Map of domain keys(eTLD+1) to domains/hosts that are to be loaded from DB. 197 // Map of domain keys(eTLD+1) to domains/hosts that are to be loaded from DB.
178 std::map<std::string, std::set<std::string> > keys_to_load_; 198 std::map<std::string, std::set<std::string> > keys_to_load_;
179 199
180 // Indicates if DB has been initialized. 200 // Indicates if DB has been initialized.
181 bool initialized_; 201 bool initialized_;
182 202
203 // The cumulative time spent loading the cookies on the DB thread. Incremented
204 // and reported from the DB thread.
205 base::TimeDelta cookie_load_duration_;
206
207 // Guards the following metrics-related properties (only accessed when
208 // starting/completing priority loads or completing the total load).
209 base::Lock metrics_lock_;
Randy Smith (Not in Mondays) 2011/11/13 03:38:23 Why do we need this lock? All of the variables pr
erikwright (departed) 2011/11/13 22:23:31 Unfortunately, technically Load and LoadCookiesFor
Randy Smith (Not in Mondays) 2011/11/14 19:55:33 D'oh! Good point. If it's still in your plan to
210 int num_priority_waiting_;
211 // The total number of priority requests.
212 int total_priority_requests_;
213 // The time when |num_priority_waiting_| incremented to 1.
214 base::Time current_priority_wait_start_;
215 // The cumulative duration of time when |num_priority_waiting_| was greater
216 // than 1.
217 base::TimeDelta priority_wait_duration_;
218 // In the case of a race condition where a priority load is ongoing when
219 // regular loading completes, we defer metric reporting until the priority
220 // load completes with this flag.
221 bool metrics_reporting_deferred_;
Randy Smith (Not in Mondays) 2011/11/13 03:38:23 I think if you wanted to you could get rid of this
erikwright (departed) 2011/11/13 22:23:31 The race condition does not represent a bug, so as
Randy Smith (Not in Mondays) 2011/11/14 19:55:33 Why do you say it's not a bug? I'm not saying it'
222
183 DISALLOW_COPY_AND_ASSIGN(Backend); 223 DISALLOW_COPY_AND_ASSIGN(Backend);
184 }; 224 };
185 225
186 // Version number of the database. In version 4, we migrated the time epoch. 226 // Version number of the database. In version 4, we migrated the time epoch.
187 // If you open the DB with an older version on Mac or Linux, the times will 227 // If you open the DB with an older version on Mac or Linux, the times will
188 // look wonky, but the file will likely be usable. On Windows version 3 and 4 228 // look wonky, but the file will likely be usable. On Windows version 3 and 4
189 // are the same. 229 // are the same.
190 // 230 //
191 // Version 3 updated the database to include the last access time, so we can 231 // Version 3 updated the database to include the last access time, so we can
192 // expire them in decreasing order of use when we've reached the maximum 232 // expire them in decreasing order of use when we've reached the maximum
193 // number of cookies. 233 // number of cookies.
194 static const int kCurrentVersionNumber = 4; 234 static const int kCurrentVersionNumber = 4;
195 static const int kCompatibleVersionNumber = 3; 235 static const int kCompatibleVersionNumber = 3;
196 236
197 namespace { 237 namespace {
198 238
239 // Increments a specified TimeDelta by the duration between this object's
240 // constructor and destructor. Not thread safe. Multiple instances may be
241 // created with the same delta instance as long as their lifetimes are nested.
242 // The shortest lived instances have no impact.
Randy Smith (Not in Mondays) 2011/11/13 03:38:23 Nice idea! I have to admit, the thing I'd really
erikwright (departed) 2011/11/13 22:23:31 If there were other places looking for the same th
243 class IncrementTimeDelta {
Randy Smith (Not in Mondays) 2011/11/13 03:38:23 Looking over this code, I think it would be simple
erikwright (departed) 2011/11/13 22:23:31 Initialize DB is a significant cost, based on Hui'
Randy Smith (Not in Mondays) 2011/11/14 19:55:33 Completely fair; I'd just solve that by incrementi
244 public:
245 explicit IncrementTimeDelta(base::TimeDelta* delta) :
246 delta_(delta),
247 original_value_(*delta),
248 start_(base::Time::Now()) {}
249
250 ~IncrementTimeDelta() {
251 *delta_ = original_value_ + base::Time::Now() - start_;
252 }
253
254 private:
255 base::TimeDelta* delta_;
256 base::TimeDelta original_value_;
257 base::Time start_;
258
259 DISALLOW_COPY_AND_ASSIGN(IncrementTimeDelta);
260 };
261
199 // Initializes the cookies table, returning true on success. 262 // Initializes the cookies table, returning true on success.
200 bool InitTable(sql::Connection* db) { 263 bool InitTable(sql::Connection* db) {
201 if (!db->DoesTableExist("cookies")) { 264 if (!db->DoesTableExist("cookies")) {
202 if (!db->Execute("CREATE TABLE cookies (" 265 if (!db->Execute("CREATE TABLE cookies ("
203 "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," 266 "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY,"
204 "host_key TEXT NOT NULL," 267 "host_key TEXT NOT NULL,"
205 "name TEXT NOT NULL," 268 "name TEXT NOT NULL,"
206 "value TEXT NOT NULL," 269 "value TEXT NOT NULL,"
207 "path TEXT NOT NULL," 270 "path TEXT NOT NULL,"
208 // We only store persistent, so we know it expires 271 // We only store persistent, so we know it expires
(...skipping 21 matching lines...) Expand all
230 // This function should be called only once per instance. 293 // This function should be called only once per instance.
231 DCHECK(!db_.get()); 294 DCHECK(!db_.get());
232 BrowserThread::PostTask( 295 BrowserThread::PostTask(
233 BrowserThread::DB, FROM_HERE, 296 BrowserThread::DB, FROM_HERE,
234 base::Bind(&Backend::LoadAndNotifyOnDBThread, this, loaded_callback)); 297 base::Bind(&Backend::LoadAndNotifyOnDBThread, this, loaded_callback));
235 } 298 }
236 299
237 void SQLitePersistentCookieStore::Backend::LoadCookiesForKey( 300 void SQLitePersistentCookieStore::Backend::LoadCookiesForKey(
238 const std::string& key, 301 const std::string& key,
239 const LoadedCallback& loaded_callback) { 302 const LoadedCallback& loaded_callback) {
303 {
304 base::AutoLock locked(metrics_lock_);
305 if (num_priority_waiting_ == 0)
306 current_priority_wait_start_ = base::Time::Now();
307 num_priority_waiting_++;
308 total_priority_requests_++;
309 }
310
240 BrowserThread::PostTask( 311 BrowserThread::PostTask(
241 BrowserThread::DB, FROM_HERE, 312 BrowserThread::DB, FROM_HERE,
242 base::Bind(&Backend::LoadKeyAndNotifyOnDBThread, this, 313 base::Bind(&Backend::LoadKeyAndNotifyOnDBThread, this,
243 key, 314 key,
244 loaded_callback)); 315 loaded_callback));
245 } 316 }
246 317
247 void SQLitePersistentCookieStore::Backend::LoadAndNotifyOnDBThread( 318 void SQLitePersistentCookieStore::Backend::LoadAndNotifyOnDBThread(
248 const LoadedCallback& loaded_callback) { 319 const LoadedCallback& loaded_callback) {
249 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
321 IncrementTimeDelta increment(&cookie_load_duration_);
250 322
251 if (!InitializeDatabase()) { 323 if (!InitializeDatabase()) {
252 BrowserThread::PostTask( 324 BrowserThread::PostTask(
253 BrowserThread::IO, FROM_HERE, 325 BrowserThread::IO, FROM_HERE,
254 base::Bind(&SQLitePersistentCookieStore::Backend::NotifyOnIOThread, 326 base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread,
255 this, loaded_callback, false)); 327 this, loaded_callback, false));
256 } else { 328 } else {
257 ChainLoadCookies(loaded_callback); 329 ChainLoadCookies(loaded_callback);
258 } 330 }
259 } 331 }
260 332
261 void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread( 333 void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyOnDBThread(
262 const std::string& key, 334 const std::string& key,
263 const LoadedCallback& loaded_callback) { 335 const LoadedCallback& loaded_callback) {
264 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 336 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
337 IncrementTimeDelta increment(&cookie_load_duration_);
265 338
266 bool success = false; 339 bool success = false;
267 if (InitializeDatabase()) { 340 if (InitializeDatabase()) {
268 std::map<std::string, std::set<std::string> >::iterator 341 std::map<std::string, std::set<std::string> >::iterator
269 it = keys_to_load_.find(key); 342 it = keys_to_load_.find(key);
270 if (it != keys_to_load_.end()) { 343 if (it != keys_to_load_.end()) {
271 success = LoadCookiesForDomains(it->second); 344 success = LoadCookiesForDomains(it->second);
272 keys_to_load_.erase(it); 345 keys_to_load_.erase(it);
273 } else { 346 } else {
274 success = true; 347 success = true;
275 } 348 }
276 } 349 }
277 350
278 BrowserThread::PostTask( 351 BrowserThread::PostTask(
279 BrowserThread::IO, FROM_HERE, 352 BrowserThread::IO, FROM_HERE,
280 base::Bind(&SQLitePersistentCookieStore::Backend::NotifyOnIOThread, 353 base::Bind(
281 this, loaded_callback, success)); 354 &SQLitePersistentCookieStore::Backend::CompleteLoadForKeyOnIOThread,
355 this, loaded_callback, success));
282 } 356 }
283 357
284 void SQLitePersistentCookieStore::Backend::NotifyOnIOThread( 358 void SQLitePersistentCookieStore::Backend::CompleteLoadForKeyOnIOThread(
359 const LoadedCallback& loaded_callback,
360 bool load_success) {
361 Notify(loaded_callback, load_success);
362
363 {
364 base::AutoLock locked(metrics_lock_);
365 num_priority_waiting_--;
366 if (num_priority_waiting_ == 0) {
367 priority_wait_duration_ +=
368 base::Time::Now() - current_priority_wait_start_;
369 if (metrics_reporting_deferred_) {
370 metrics_reporting_deferred_ = false;
371 ReportMetrics();
372 }
373 }
374 }
375
376 }
377
378 void SQLitePersistentCookieStore::Backend::ReportMetricsOnDBThread() {
379 UMA_HISTOGRAM_CUSTOM_TIMES(
380 "Cookie.TimeLoad",
381 cookie_load_duration_,
382 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
383 50);
384 }
385
386 void SQLitePersistentCookieStore::Backend::ReportMetrics() {
387 metrics_lock_.AssertAcquired();
388
389 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, base::Bind(
390 &SQLitePersistentCookieStore::Backend::ReportMetricsOnDBThread, this));
391
392 UMA_HISTOGRAM_CUSTOM_TIMES(
393 "Cookie.PriorityBlockingTime",
394 priority_wait_duration_,
395 base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1),
396 50);
397
398 UMA_HISTOGRAM_COUNTS_100(
399 "Cookie.PriorityLoadCount",
400 total_priority_requests_);
401 }
402
403 void SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread(
404 const LoadedCallback& loaded_callback, bool load_success) {
405 Notify(loaded_callback, load_success);
406
407 if (load_success) {
408 base::AutoLock locked(metrics_lock_);
409
410 // There is a race condition where a priority load could complete after
411 // regular loading completes. In that case, defer metric reporting. See
412 // CompleteLoadForKeyOnIOThread for the continuation.
413 if (num_priority_waiting_ == 0)
414 ReportMetrics();
415 else
416 metrics_reporting_deferred_ = true;
417 }
418 }
419
420 void SQLitePersistentCookieStore::Backend::Notify(
285 const LoadedCallback& loaded_callback, 421 const LoadedCallback& loaded_callback,
286 bool load_success) { 422 bool load_success) {
287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 423 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
288 424
289 std::vector<net::CookieMonster::CanonicalCookie*> cookies; 425 std::vector<net::CookieMonster::CanonicalCookie*> cookies;
290 { 426 {
291 base::AutoLock locked(lock_); 427 base::AutoLock locked(lock_);
292 cookies.swap(cookies_); 428 cookies.swap(cookies_);
293 } 429 }
294 430
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 it->second.insert(domain); 484 it->second.insert(domain);
349 } 485 }
350 486
351 initialized_ = true; 487 initialized_ = true;
352 return true; 488 return true;
353 } 489 }
354 490
355 void SQLitePersistentCookieStore::Backend::ChainLoadCookies( 491 void SQLitePersistentCookieStore::Backend::ChainLoadCookies(
356 const LoadedCallback& loaded_callback) { 492 const LoadedCallback& loaded_callback) {
357 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 493 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
494 IncrementTimeDelta increment(&cookie_load_duration_);
358 495
359 bool load_success = true; 496 bool load_success = true;
360 497
361 if (keys_to_load_.size() > 0) { 498 if (keys_to_load_.size() > 0) {
362 // Load cookies for the first domain key. 499 // Load cookies for the first domain key.
363 std::map<std::string, std::set<std::string> >::iterator 500 std::map<std::string, std::set<std::string> >::iterator
364 it = keys_to_load_.begin(); 501 it = keys_to_load_.begin();
365 load_success = LoadCookiesForDomains(it->second); 502 load_success = LoadCookiesForDomains(it->second);
366 keys_to_load_.erase(it); 503 keys_to_load_.erase(it);
367 } 504 }
368 505
369 // If load is successful and there are more domain keys to be loaded, 506 // If load is successful and there are more domain keys to be loaded,
370 // then post a DB task to continue chain-load; 507 // then post a DB task to continue chain-load;
371 // Otherwise notify on IO thread. 508 // Otherwise notify on IO thread.
372 if (load_success && keys_to_load_.size() > 0) { 509 if (load_success && keys_to_load_.size() > 0) {
373 BrowserThread::PostTask( 510 BrowserThread::PostTask(
374 BrowserThread::DB, FROM_HERE, 511 BrowserThread::DB, FROM_HERE,
375 base::Bind(&Backend::ChainLoadCookies, this, loaded_callback)); 512 base::Bind(&Backend::ChainLoadCookies, this, loaded_callback));
376 } else { 513 } else {
377 BrowserThread::PostTask( 514 BrowserThread::PostTask(
378 BrowserThread::IO, FROM_HERE, 515 BrowserThread::IO, FROM_HERE,
379 base::Bind(&SQLitePersistentCookieStore::Backend::NotifyOnIOThread, 516 base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread,
380 this, loaded_callback, load_success)); 517 this, loaded_callback, load_success));
381 } 518 }
382 } 519 }
383 520
384 bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains( 521 bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains(
385 const std::set<std::string>& domains) { 522 const std::set<std::string>& domains) {
386 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 523 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
387 524
388 sql::Statement smt(db_->GetCachedStatement(SQL_FROM_HERE, 525 sql::Statement smt(db_->GetCachedStatement(SQL_FROM_HERE,
389 "SELECT creation_utc, host_key, name, value, path, expires_utc, secure, " 526 "SELECT creation_utc, host_key, name, value, path, expires_utc, secure, "
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 if (backend_.get()) 864 if (backend_.get())
728 backend_->SetClearLocalStateOnExit(clear_local_state); 865 backend_->SetClearLocalStateOnExit(clear_local_state);
729 } 866 }
730 867
731 void SQLitePersistentCookieStore::Flush(Task* completion_task) { 868 void SQLitePersistentCookieStore::Flush(Task* completion_task) {
732 if (backend_.get()) 869 if (backend_.get())
733 backend_->Flush(completion_task); 870 backend_->Flush(completion_task);
734 else if (completion_task) 871 else if (completion_task)
735 MessageLoop::current()->PostTask(FROM_HERE, completion_task); 872 MessageLoop::current()->PostTask(FROM_HERE, completion_task);
736 } 873 }
OLDNEW
« no previous file with comments | « no previous file | net/base/cookie_monster.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698