| Index: chrome/chrome_watcher/chrome_watcher_main.cc
|
| diff --git a/chrome/chrome_watcher/chrome_watcher_main.cc b/chrome/chrome_watcher/chrome_watcher_main.cc
|
| index 4e294dc523ccb6a80655f45d6434814916d1d6f3..c88988fe7248f04920ea750f514f3ad049c5812d 100644
|
| --- a/chrome/chrome_watcher/chrome_watcher_main.cc
|
| +++ b/chrome/chrome_watcher/chrome_watcher_main.cc
|
| @@ -33,6 +33,9 @@ const GUID kChromeWatcherTraceProviderName = {
|
| 0x7fe69228, 0x633e, 0x4f06,
|
| { 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7 } };
|
|
|
| +// The amount of time we wait around for a WM_ENDSESSION or a process exit.
|
| +const int kDelayTimeSeconds = 30;
|
| +
|
| // Takes care of monitoring a browser. This class watches for a browser's exit
|
| // code, as well as listening for WM_ENDSESSION messages. Events are recorded in
|
| // an exit funnel, for reporting the next time Chrome runs.
|
| @@ -59,9 +62,6 @@ class BrowserMonitor {
|
| // Posted to main thread from Watch when browser exits.
|
| void BrowserExited();
|
|
|
| - // True if BrowserExited has run.
|
| - bool browser_exited_;
|
| -
|
| // The funnel used to record events for this browser.
|
| browser_watcher::ExitFunnel exit_funnel_;
|
|
|
| @@ -71,6 +71,10 @@ class BrowserMonitor {
|
| // The thread that runs Watch().
|
| base::Thread background_thread_;
|
|
|
| + // Set when the browser has exited, used to stretch the watcher's lifetime
|
| + // when WM_ENDSESSION occurs before browser exit.
|
| + base::WaitableEvent browser_exited_;
|
| +
|
| // The run loop for the main thread and its task runner.
|
| base::RunLoop* run_loop_;
|
| scoped_refptr<base::SequencedTaskRunner> main_thread_;
|
| @@ -80,7 +84,7 @@ class BrowserMonitor {
|
|
|
| BrowserMonitor::BrowserMonitor(base::RunLoop* run_loop,
|
| const base::char16* registry_path) :
|
| - browser_exited_(false),
|
| + browser_exited_(true, false), // manual reset, initially non-signalled.
|
| exit_code_watcher_(registry_path),
|
| end_session_watcher_window_(
|
| base::Bind(&BrowserMonitor::OnEndSessionMessage,
|
| @@ -139,9 +143,11 @@ void BrowserMonitor::OnEndSessionMessage(UINT message, LPARAM lparam) {
|
| if (lparam & ~kKnownBits)
|
| exit_funnel_.RecordEvent(L"ES_Other");
|
|
|
| - // Belt-and-suspenders; make sure our message loop exits ASAP.
|
| - if (browser_exited_)
|
| - run_loop_->Quit();
|
| + // If the browser hasn't exited yet, dally for a bit to try and stretch this
|
| + // process' lifetime to give it some more time to capture the browser exit.
|
| + browser_exited_.TimedWait(base::TimeDelta::FromSeconds(kDelayTimeSeconds));
|
| +
|
| + run_loop_->Quit();
|
| }
|
|
|
| void BrowserMonitor::Watch(base::win::ScopedHandle on_initialized_event) {
|
| @@ -156,6 +162,9 @@ void BrowserMonitor::Watch(base::win::ScopedHandle on_initialized_event) {
|
| exit_code_watcher_.WaitForExit();
|
| exit_funnel_.RecordEvent(L"BrowserExit");
|
|
|
| + // Note that the browser has exited.
|
| + browser_exited_.Signal();
|
| +
|
| main_thread_->PostTask(FROM_HERE,
|
| base::Bind(&BrowserMonitor::BrowserExited, base::Unretained(this)));
|
| }
|
| @@ -164,9 +173,6 @@ void BrowserMonitor::BrowserExited() {
|
| // This runs in the main thread.
|
| DCHECK_EQ(main_thread_, base::MessageLoopProxy::current());
|
|
|
| - // Note that the browser has exited.
|
| - browser_exited_ = true;
|
| -
|
| // Our background thread has served it's purpose.
|
| background_thread_.Stop();
|
|
|
| @@ -178,9 +184,10 @@ void BrowserMonitor::BrowserExited() {
|
| } else {
|
| // The browser exited abnormally, wait around for a little bit to see
|
| // whether this instance will get a logoff message.
|
| - main_thread_->PostDelayedTask(FROM_HERE,
|
| - run_loop_->QuitClosure(),
|
| - base::TimeDelta::FromSeconds(30));
|
| + main_thread_->PostDelayedTask(
|
| + FROM_HERE,
|
| + run_loop_->QuitClosure(),
|
| + base::TimeDelta::FromSeconds(kDelayTimeSeconds));
|
| }
|
| }
|
|
|
|
|