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

Side by Side Diff: chrome/browser/chromeos/boot_times_loader.cc

Issue 9453026: Make BootTimesLoader marker usage thread safe (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add minor comment Created 8 years, 10 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
« no previous file with comments | « chrome/browser/chromeos/boot_times_loader.h ('k') | no next file » | 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) 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/chromeos/boot_times_loader.h" 5 #include "chrome/browser/chromeos/boot_times_loader.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 // Append numbers to the files. 286 // Append numbers to the files.
287 AppendFile(uptime_output, uptime.data(), uptime.size()); 287 AppendFile(uptime_output, uptime.data(), uptime.size());
288 AppendFile(disk_output, disk.data(), disk.size()); 288 AppendFile(disk_output, disk.data(), disk.size());
289 } 289 }
290 290
291 // static 291 // static
292 void BootTimesLoader::WriteTimes( 292 void BootTimesLoader::WriteTimes(
293 const std::string base_name, 293 const std::string base_name,
294 const std::string uma_name, 294 const std::string uma_name,
295 const std::string uma_prefix, 295 const std::string uma_prefix,
296 const std::vector<TimeMarker> login_times) { 296 std::vector<TimeMarker> login_times) {
297 const int kMinTimeMillis = 1; 297 const int kMinTimeMillis = 1;
298 const int kMaxTimeMillis = 30000; 298 const int kMaxTimeMillis = 30000;
299 const int kNumBuckets = 100; 299 const int kNumBuckets = 100;
300 const FilePath log_path(kLoginLogPath); 300 const FilePath log_path(kLoginLogPath);
301 301
302 // Need to sort by time since the entries may have been pushed onto the
303 // vector (on the UI thread) in a different order from which they were
304 // created (potentially on other threads).
305 std::sort(login_times.begin(), login_times.end());
306
302 base::Time first = login_times.front().time(); 307 base::Time first = login_times.front().time();
303 base::Time last = login_times.back().time(); 308 base::Time last = login_times.back().time();
304 base::TimeDelta total = last - first; 309 base::TimeDelta total = last - first;
305 base::Histogram* total_hist = base::Histogram::FactoryTimeGet( 310 base::Histogram* total_hist = base::Histogram::FactoryTimeGet(
306 uma_name, 311 uma_name,
307 base::TimeDelta::FromMilliseconds(kMinTimeMillis), 312 base::TimeDelta::FromMilliseconds(kMinTimeMillis),
308 base::TimeDelta::FromMilliseconds(kMaxTimeMillis), 313 base::TimeDelta::FromMilliseconds(kMaxTimeMillis),
309 kNumBuckets, 314 kNumBuckets,
310 base::Histogram::kUmaTargetedHistogramFlag); 315 base::Histogram::kUmaTargetedHistogramFlag);
311 total_hist->AddTime(total); 316 total_hist->AddTime(total);
(...skipping 26 matching lines...) Expand all
338 name.data()); 343 name.data());
339 prev = tm.time(); 344 prev = tm.time();
340 } 345 }
341 output += '\n'; 346 output += '\n';
342 347
343 file_util::WriteFile( 348 file_util::WriteFile(
344 log_path.Append(base_name), output.data(), output.size()); 349 log_path.Append(base_name), output.data(), output.size());
345 } 350 }
346 351
347 void BootTimesLoader::LoginDone() { 352 void BootTimesLoader::LoginDone() {
353 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
348 AddLoginTimeMarker("LoginDone", true); 354 AddLoginTimeMarker("LoginDone", true);
349 RecordCurrentStats(kChromeFirstRender); 355 RecordCurrentStats(kChromeFirstRender);
350 registrar_.Remove(this, content::NOTIFICATION_LOAD_START, 356 registrar_.Remove(this, content::NOTIFICATION_LOAD_START,
351 content::NotificationService::AllSources()); 357 content::NotificationService::AllSources());
352 registrar_.Remove(this, content::NOTIFICATION_LOAD_STOP, 358 registrar_.Remove(this, content::NOTIFICATION_LOAD_STOP,
353 content::NotificationService::AllSources()); 359 content::NotificationService::AllSources());
354 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 360 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
355 content::NotificationService::AllSources()); 361 content::NotificationService::AllSources());
356 registrar_.Remove(this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_PAINT, 362 registrar_.Remove(this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_PAINT,
357 content::NotificationService::AllSources()); 363 content::NotificationService::AllSources());
358 // Don't swamp the FILE thread right away. 364 // Don't swamp the FILE thread right away.
359 BrowserThread::PostDelayedTask( 365 BrowserThread::PostDelayedTask(
360 BrowserThread::FILE, FROM_HERE, 366 BrowserThread::FILE, FROM_HERE,
361 base::Bind(&WriteTimes, kLoginTimes, kUmaLogin, kUmaLoginPrefix, 367 base::Bind(&WriteTimes, kLoginTimes, kUmaLogin, kUmaLoginPrefix,
362 login_time_markers_), 368 login_time_markers_),
363 kLoginTimeWriteDelayMs); 369 kLoginTimeWriteDelayMs);
364 } 370 }
365 371
366 void BootTimesLoader::WriteLogoutTimes() { 372 void BootTimesLoader::WriteLogoutTimes() {
373 // Either we're on the browser thread, or (more likely) Chrome is in the
374 // process of shutting down and we're on the main thread but the message loop
375 // has already been terminated.
376 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) ||
377 !BrowserThread::IsMessageLoopValid(BrowserThread::UI));
378
367 WriteTimes(kLogoutTimes, 379 WriteTimes(kLogoutTimes,
368 kUmaLogout, 380 kUmaLogout,
369 kUmaLogoutPrefix, 381 kUmaLogoutPrefix,
370 logout_time_markers_); 382 logout_time_markers_);
371 } 383 }
372 384
373 void BootTimesLoader::RecordStats(const std::string& name, const Stats& stats) { 385 void BootTimesLoader::RecordStats(const std::string& name, const Stats& stats) {
374 BrowserThread::PostTask( 386 BrowserThread::PostTask(
375 BrowserThread::FILE, FROM_HERE, 387 BrowserThread::FILE, FROM_HERE,
376 base::Bind(&RecordStatsDelayed, name, stats.uptime, stats.disk)); 388 base::Bind(&RecordStatsDelayed, name, stats.uptime, stats.disk));
(...skipping 15 matching lines...) Expand all
392 404
393 void BootTimesLoader::SaveChromeMainStats() { 405 void BootTimesLoader::SaveChromeMainStats() {
394 chrome_main_stats_ = GetCurrentStats(); 406 chrome_main_stats_ = GetCurrentStats();
395 } 407 }
396 408
397 void BootTimesLoader::RecordChromeMainStats() { 409 void BootTimesLoader::RecordChromeMainStats() {
398 RecordStats(kChromeMain, chrome_main_stats_); 410 RecordStats(kChromeMain, chrome_main_stats_);
399 } 411 }
400 412
401 void BootTimesLoader::RecordLoginAttempted() { 413 void BootTimesLoader::RecordLoginAttempted() {
414 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
402 login_time_markers_.clear(); 415 login_time_markers_.clear();
403 AddLoginTimeMarker("LoginStarted", false); 416 AddLoginTimeMarker("LoginStarted", false);
404 if (!have_registered_) { 417 if (!have_registered_) {
405 have_registered_ = true; 418 have_registered_ = true;
406 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_AUTHENTICATION, 419 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_AUTHENTICATION,
407 content::NotificationService::AllSources()); 420 content::NotificationService::AllSources());
408 registrar_.Add(this, content::NOTIFICATION_LOAD_START, 421 registrar_.Add(this, content::NOTIFICATION_LOAD_START,
409 content::NotificationService::AllSources()); 422 content::NotificationService::AllSources());
410 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, 423 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
411 content::NotificationService::AllSources()); 424 content::NotificationService::AllSources());
412 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 425 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
413 content::NotificationService::AllSources()); 426 content::NotificationService::AllSources());
414 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_PAINT, 427 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_PAINT,
415 content::NotificationService::AllSources()); 428 content::NotificationService::AllSources());
416 } 429 }
417 } 430 }
418 431
419 void BootTimesLoader::AddLoginTimeMarker( 432 void BootTimesLoader::AddLoginTimeMarker(
420 const std::string& marker_name, bool send_to_uma) { 433 const std::string& marker_name, bool send_to_uma) {
421 login_time_markers_.push_back(TimeMarker(marker_name, send_to_uma)); 434 AddMarker(&login_time_markers_, TimeMarker(marker_name, send_to_uma));
422 } 435 }
423 436
424 void BootTimesLoader::AddLogoutTimeMarker( 437 void BootTimesLoader::AddLogoutTimeMarker(
425 const std::string& marker_name, bool send_to_uma) { 438 const std::string& marker_name, bool send_to_uma) {
426 logout_time_markers_.push_back(TimeMarker(marker_name, send_to_uma)); 439 AddMarker(&logout_time_markers_, TimeMarker(marker_name, send_to_uma));
440 }
441
442 // static
443 void BootTimesLoader::AddMarker(std::vector<TimeMarker>* vector,
444 const TimeMarker& marker)
445 {
DaveMoore 2012/02/27 21:52:19 Why can't this all be done in AddMarker (with no A
Rick Byers 2012/02/27 21:58:23 No, AddMarkerImpl is the function that runs on the
446 // The marker vectors can only be safely manipulated on the main thread.
447 // If we're late in the process of shutting down (eg. as can be the case at
448 // logout), then we have to assume we're on the main thread already.
449 if (BrowserThread::CurrentlyOn(BrowserThread::UI) ||
450 !BrowserThread::IsMessageLoopValid(BrowserThread::UI)) {
451 AddMarkerImpl(vector, marker);
452 } else {
453 // Add the marker on the UI thread.
454 // Note that it's safe to use an unretained pointer to the vector because
455 // BootTimesLoader's lifetime exceeds that of the UI thread message loop.
456 BrowserThread::PostTask(
457 BrowserThread::UI, FROM_HERE,
458 base::Bind(&BootTimesLoader::AddMarkerImpl,
459 base::Unretained(vector),
460 marker));
461 }
462 }
463
464 // static
465 void BootTimesLoader::AddMarkerImpl(std::vector<TimeMarker>* vector,
466 TimeMarker marker)
467 {
468 vector->push_back(marker);
427 } 469 }
428 470
429 void BootTimesLoader::Observe( 471 void BootTimesLoader::Observe(
430 int type, 472 int type,
431 const content::NotificationSource& source, 473 const content::NotificationSource& source,
432 const content::NotificationDetails& details) { 474 const content::NotificationDetails& details) {
433 switch (type) { 475 switch (type) {
434 case chrome::NOTIFICATION_LOGIN_AUTHENTICATION: { 476 case chrome::NOTIFICATION_LOGIN_AUTHENTICATION: {
435 content::Details<AuthenticationNotificationDetails> auth_details(details); 477 content::Details<AuthenticationNotificationDetails> auth_details(details);
436 if (auth_details->success()) { 478 if (auth_details->success()) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 GetRenderWidgetHost(&web_contents->GetController()); 517 GetRenderWidgetHost(&web_contents->GetController());
476 render_widget_hosts_loading_.erase(render_widget_host); 518 render_widget_hosts_loading_.erase(render_widget_host);
477 break; 519 break;
478 } 520 }
479 default: 521 default:
480 break; 522 break;
481 } 523 }
482 } 524 }
483 525
484 } // namespace chromeos 526 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/boot_times_loader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698