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

Side by Side Diff: chrome/app/chrome_watcher_command_line_win.cc

Issue 886613002: Introduce the ability to wait for the watcher process to initialize. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review feedback. Created 5 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
« no previous file with comments | « chrome/app/chrome_watcher_command_line_win.h ('k') | chrome/app/client_util.cc » ('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) 2014 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2014 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/app/chrome_watcher_command_line_win.h" 5 #include "chrome/app/chrome_watcher_command_line_win.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "chrome/common/chrome_switches.h" 14 #include "chrome/common/chrome_switches.h"
15 15
16 namespace { 16 namespace {
17
18 const char kOnIninitializedEventHandleSwitch[] = "on-initialized-event-handle";
17 const char kParentHandleSwitch[] = "parent-handle"; 19 const char kParentHandleSwitch[] = "parent-handle";
20
21 void AppendHandleSwitch(const std::string& switch_name,
22 HANDLE handle,
23 base::CommandLine* command_line) {
24 command_line->AppendSwitchASCII(
25 switch_name, base::UintToString(reinterpret_cast<unsigned int>(handle)));
26 }
27
28 HANDLE ReadHandleFromSwitch(const base::CommandLine& command_line,
29 const std::string& switch_name) {
30 std::string switch_string = command_line.GetSwitchValueASCII(switch_name);
31 unsigned int switch_uint = 0;
32 if (switch_string.empty() ||
33 !base::StringToUint(switch_string, &switch_uint)) {
34 DLOG(ERROR) << "Missing or invalid " << switch_name << " argument.";
35 return nullptr;
36 }
37 return reinterpret_cast<HANDLE>(switch_uint);
38 }
39
18 } // namespace 40 } // namespace
19 41
20 base::CommandLine GenerateChromeWatcherCommandLine( 42 base::CommandLine GenerateChromeWatcherCommandLine(
21 const base::FilePath& chrome_exe, 43 const base::FilePath& chrome_exe,
22 HANDLE parent_process) { 44 HANDLE parent_process,
45 HANDLE on_initialized_event) {
23 base::CommandLine command_line(chrome_exe); 46 base::CommandLine command_line(chrome_exe);
24 command_line.AppendSwitchASCII(switches::kProcessType, "watcher"); 47 command_line.AppendSwitchASCII(switches::kProcessType, "watcher");
25 command_line.AppendSwitchASCII( 48 AppendHandleSwitch(kOnIninitializedEventHandleSwitch, on_initialized_event,
26 kParentHandleSwitch, 49 &command_line);
27 base::UintToString(reinterpret_cast<unsigned int>(parent_process))); 50 AppendHandleSwitch(kParentHandleSwitch, parent_process, &command_line);
28 return command_line; 51 return command_line;
29 } 52 }
30 53
31 base::win::ScopedHandle InterpretChromeWatcherCommandLine( 54 bool InterpretChromeWatcherCommandLine(
32 const base::CommandLine& command_line) { 55 const base::CommandLine& command_line,
33 std::string parent_handle_str = 56 base::win::ScopedHandle* parent_process,
34 command_line.GetSwitchValueASCII(kParentHandleSwitch); 57 base::win::ScopedHandle* on_initialized_event) {
35 unsigned parent_handle_uint = 0; 58 DCHECK(on_initialized_event);
36 if (parent_handle_str.empty() || 59 DCHECK(parent_process);
37 !base::StringToUint(parent_handle_str, &parent_handle_uint)) { 60
38 LOG(ERROR) << "Missing or invalid " << kParentHandleSwitch << " argument."; 61 // For consistency, always close any existing HANDLEs here.
39 return base::win::ScopedHandle(); 62 on_initialized_event->Close();
63 parent_process->Close();
64
65 HANDLE parent_handle =
66 ReadHandleFromSwitch(command_line, kParentHandleSwitch);
67 HANDLE on_initialized_event_handle =
68 ReadHandleFromSwitch(command_line, kOnIninitializedEventHandleSwitch);
69
70 if (parent_handle) {
71 // Initial test of the handle, a zero PID indicates invalid handle, or not
72 // a process handle. In this case, parsing fails and we avoid closing the
73 // handle.
74 DWORD process_pid = ::GetProcessId(parent_handle);
75 if (process_pid == 0) {
76 DLOG(ERROR) << "Invalid " << kParentHandleSwitch
77 << " argument. Can't get parent PID.";
78 } else {
79 parent_process->Set(parent_handle);
80 }
40 } 81 }
41 82
42 HANDLE parent_process = reinterpret_cast<HANDLE>(parent_handle_uint); 83 if (on_initialized_event_handle) {
43 // Initial test of the handle, a zero PID indicates invalid handle, or not 84 DWORD result = ::WaitForSingleObject(on_initialized_event_handle, 0);
44 // a process handle. In this case, parsing fails and we avoid closing the 85 if (result == WAIT_FAILED) {
45 // handle. 86 DPLOG(ERROR)
46 DWORD process_pid = ::GetProcessId(parent_process); 87 << "Unexpected error while testing the initialization event.";
47 if (process_pid == 0) { 88 } else if (result != WAIT_TIMEOUT) {
48 LOG(ERROR) << "Invalid " << kParentHandleSwitch 89 DLOG(ERROR) << "Unexpected result while testing the initialization event "
49 << " argument. Can't get parent PID."; 90 "with WaitForSingleObject: " << result;
50 return base::win::ScopedHandle(); 91 } else {
92 on_initialized_event->Set(on_initialized_event_handle);
93 }
51 } 94 }
52 95
53 return base::win::ScopedHandle(parent_process); 96 if (!on_initialized_event->IsValid() || !parent_process->IsValid()) {
97 // If one was valid and not the other, free the valid one.
98 on_initialized_event->Close();
99 parent_process->Close();
100 return false;
101 }
102
103 return true;
54 } 104 }
OLDNEW
« no previous file with comments | « chrome/app/chrome_watcher_command_line_win.h ('k') | chrome/app/client_util.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698