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 4bd8410b4bb18eb551f06a9d19bc857761aa31b9..5b5504b50f7e60b90f1e33fad3f72ce3b6f06b94 100644 |
--- a/chrome/chrome_watcher/chrome_watcher_main.cc |
+++ b/chrome/chrome_watcher/chrome_watcher_main.cc |
@@ -34,23 +34,27 @@ const GUID kChromeWatcherTraceProviderName = { |
{ 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7 } }; |
// 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. |
+// code, as well as listening for WM_ENDSESSION messages. Events are recorded in |
+// an exit funnel, for reporting the next time Chrome runs. |
class BrowserMonitor { |
public: |
BrowserMonitor(base::RunLoop* run_loop, const base::char16* registry_path); |
~BrowserMonitor(); |
- // Starts the monitor, returns true on success. |
+ // Initiates the asynchronous monitoring process, returns true on success. |
+ // |on_initialized_event| will be signaled immediately before blocking on the |
+ // exit of |process|. |
bool StartWatching(const base::char16* registry_path, |
- base::Process process); |
+ base::Process process, |
+ base::win::ScopedHandle on_initialized_event); |
private: |
// Called from EndSessionWatcherWindow on a WM_ENDSESSION message. |
void OnEndSession(LPARAM lparam); |
- // Blocking function that runs on |background_thread_|. |
- void Watch(); |
+ // Blocking function that runs on |background_thread_|. Signals |
+ // |on_initialized_event| before waiting for the browser process to exit. |
+ void Watch(base::win::ScopedHandle on_initialized_event); |
// Posted to main thread from Watch when browser exits. |
void BrowserExited(); |
@@ -88,8 +92,10 @@ BrowserMonitor::BrowserMonitor(base::RunLoop* run_loop, |
BrowserMonitor::~BrowserMonitor() { |
} |
-bool BrowserMonitor::StartWatching(const base::char16* registry_path, |
- base::Process process) { |
+bool BrowserMonitor::StartWatching( |
+ const base::char16* registry_path, |
+ base::Process process, |
+ base::win::ScopedHandle on_initialized_event) { |
if (!exit_code_watcher_.Initialize(process.Pass())) |
return false; |
@@ -103,8 +109,9 @@ bool BrowserMonitor::StartWatching(const base::char16* registry_path, |
return false; |
} |
- if (!background_thread_.task_runner()->PostTask(FROM_HERE, |
- base::Bind(&BrowserMonitor::Watch, base::Unretained(this)))) { |
+ if (!background_thread_.task_runner()->PostTask( |
+ FROM_HERE, base::Bind(&BrowserMonitor::Watch, base::Unretained(this), |
+ base::Passed(on_initialized_event.Pass())))) { |
background_thread_.Stop(); |
return false; |
} |
@@ -132,10 +139,15 @@ void BrowserMonitor::OnEndSession(LPARAM lparam) { |
run_loop_->Quit(); |
} |
-void BrowserMonitor::Watch() { |
+void BrowserMonitor::Watch(base::win::ScopedHandle on_initialized_event) { |
// This needs to run on an IO thread. |
DCHECK_NE(main_thread_, base::MessageLoopProxy::current()); |
+ // Signal our client now that the Kasko reporter is initialized and we have |
+ // cleared all of the obstacles that might lead to an early exit. |
+ ::SetEvent(on_initialized_event.Get()); |
+ on_initialized_event.Close(); |
+ |
exit_code_watcher_.WaitForExit(); |
exit_funnel_.RecordEvent(L"BrowserExit"); |
@@ -172,8 +184,10 @@ void BrowserMonitor::BrowserExited() { |
// The main entry point to the watcher, declared as extern "C" to avoid name |
// mangling. |
extern "C" int WatcherMain(const base::char16* registry_path, |
- HANDLE process_handle) { |
+ HANDLE process_handle, |
+ HANDLE on_initialized_event_handle) { |
base::Process process(process_handle); |
+ base::win::ScopedHandle on_initialized_event(on_initialized_event_handle); |
// The exit manager is in charge of calling the dtors of singletons. |
base::AtExitManager exit_manager; |
@@ -192,8 +206,10 @@ extern "C" int WatcherMain(const base::char16* registry_path, |
base::RunLoop run_loop; |
BrowserMonitor monitor(&run_loop, registry_path); |
- if (!monitor.StartWatching(registry_path, process.Pass())) |
+ if (!monitor.StartWatching(registry_path, process.Pass(), |
+ on_initialized_event.Pass())) { |
return 1; |
+ } |
run_loop.Run(); |