Index: chrome/app/chrome_watcher_command_line_win.cc |
diff --git a/chrome/app/chrome_watcher_command_line_win.cc b/chrome/app/chrome_watcher_command_line_win.cc |
index 00938631eba5d67f676676e68ca842fcc19c4b46..1eaf1a668f0d47a1625b29486b92b2768ff0c846 100644 |
--- a/chrome/app/chrome_watcher_command_line_win.cc |
+++ b/chrome/app/chrome_watcher_command_line_win.cc |
@@ -14,41 +14,91 @@ |
#include "chrome/common/chrome_switches.h" |
namespace { |
+ |
+const char kOnIninitializedEventHandleSwitch[] = "on-initialized-event-handle"; |
const char kParentHandleSwitch[] = "parent-handle"; |
+ |
+void AppendHandleSwitch(const std::string& switch_name, |
+ HANDLE handle, |
+ base::CommandLine* command_line) { |
+ command_line->AppendSwitchASCII( |
+ switch_name, base::UintToString(reinterpret_cast<unsigned int>(handle))); |
+} |
+ |
+HANDLE ReadHandleFromSwitch(const base::CommandLine& command_line, |
+ const std::string& switch_name) { |
+ std::string switch_string = command_line.GetSwitchValueASCII(switch_name); |
+ unsigned int switch_uint = 0; |
+ if (switch_string.empty() || |
+ !base::StringToUint(switch_string, &switch_uint)) { |
+ DLOG(ERROR) << "Missing or invalid " << switch_name << " argument."; |
+ return nullptr; |
+ } |
+ return reinterpret_cast<HANDLE>(switch_uint); |
+} |
+ |
} // namespace |
base::CommandLine GenerateChromeWatcherCommandLine( |
const base::FilePath& chrome_exe, |
- HANDLE parent_process) { |
+ HANDLE parent_process, |
+ HANDLE on_initialized_event) { |
base::CommandLine command_line(chrome_exe); |
command_line.AppendSwitchASCII(switches::kProcessType, "watcher"); |
- command_line.AppendSwitchASCII( |
- kParentHandleSwitch, |
- base::UintToString(reinterpret_cast<unsigned int>(parent_process))); |
+ AppendHandleSwitch(kOnIninitializedEventHandleSwitch, on_initialized_event, |
+ &command_line); |
+ AppendHandleSwitch(kParentHandleSwitch, parent_process, &command_line); |
return command_line; |
} |
-base::win::ScopedHandle InterpretChromeWatcherCommandLine( |
- const base::CommandLine& command_line) { |
- std::string parent_handle_str = |
- command_line.GetSwitchValueASCII(kParentHandleSwitch); |
- unsigned parent_handle_uint = 0; |
- if (parent_handle_str.empty() || |
- !base::StringToUint(parent_handle_str, &parent_handle_uint)) { |
- LOG(ERROR) << "Missing or invalid " << kParentHandleSwitch << " argument."; |
- return base::win::ScopedHandle(); |
+bool InterpretChromeWatcherCommandLine( |
+ const base::CommandLine& command_line, |
+ base::win::ScopedHandle* parent_process, |
+ base::win::ScopedHandle* on_initialized_event) { |
+ DCHECK(on_initialized_event); |
+ DCHECK(parent_process); |
+ |
+ // For consistency, always close any existing HANDLEs here. |
+ on_initialized_event->Close(); |
+ parent_process->Close(); |
+ |
+ HANDLE parent_handle = |
+ ReadHandleFromSwitch(command_line, kParentHandleSwitch); |
+ HANDLE on_initialized_event_handle = |
+ ReadHandleFromSwitch(command_line, kOnIninitializedEventHandleSwitch); |
+ |
+ if (parent_handle) { |
+ // Initial test of the handle, a zero PID indicates invalid handle, or not |
+ // a process handle. In this case, parsing fails and we avoid closing the |
+ // handle. |
+ DWORD process_pid = ::GetProcessId(parent_handle); |
+ if (process_pid == 0) { |
+ DLOG(ERROR) << "Invalid " << kParentHandleSwitch |
+ << " argument. Can't get parent PID."; |
+ } else { |
+ parent_process->Set(parent_handle); |
+ } |
+ } |
+ |
+ if (on_initialized_event_handle) { |
+ DWORD result = ::WaitForSingleObject(on_initialized_event_handle, 0); |
+ if (result == WAIT_FAILED) { |
+ DPLOG(ERROR) |
+ << "Unexpected error while testing the initialization event."; |
+ } else if (result != WAIT_TIMEOUT) { |
+ DLOG(ERROR) << "Unexpected result while testing the initialization event " |
+ "with WaitForSingleObject: " << result; |
+ } else { |
+ on_initialized_event->Set(on_initialized_event_handle); |
+ } |
} |
- HANDLE parent_process = reinterpret_cast<HANDLE>(parent_handle_uint); |
- // Initial test of the handle, a zero PID indicates invalid handle, or not |
- // a process handle. In this case, parsing fails and we avoid closing the |
- // handle. |
- DWORD process_pid = ::GetProcessId(parent_process); |
- if (process_pid == 0) { |
- LOG(ERROR) << "Invalid " << kParentHandleSwitch |
- << " argument. Can't get parent PID."; |
- return base::win::ScopedHandle(); |
+ if (!on_initialized_event->IsValid() || !parent_process->IsValid()) { |
+ // If one was valid and not the other, free the valid one. |
+ on_initialized_event->Close(); |
+ parent_process->Close(); |
+ return false; |
} |
- return base::win::ScopedHandle(parent_process); |
+ return true; |
} |