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

Side by Side Diff: mojo/shell/runner/host/child_process_host.cc

Issue 1754003002: Properly handle unmanaged processes in mojo::shell:ChildProcessHost (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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 | « mojo/shell/runner/host/child_process_host.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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 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 "mojo/shell/runner/host/child_process_host.h" 5 #include "mojo/shell/runner/host/child_process_host.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 start_child_process_event_(false, false), 48 start_child_process_event_(false, false),
49 weak_factory_(this) { 49 weak_factory_(this) {
50 node_channel_.reset(new edk::PlatformChannelPair); 50 node_channel_.reset(new edk::PlatformChannelPair);
51 primordial_pipe_token_ = edk::GenerateRandomToken(); 51 primordial_pipe_token_ = edk::GenerateRandomToken();
52 controller_.Bind( 52 controller_.Bind(
53 InterfacePtrInfo<mojom::ChildController>( 53 InterfacePtrInfo<mojom::ChildController>(
54 edk::CreateParentMessagePipe(primordial_pipe_token_), 0u)); 54 edk::CreateParentMessagePipe(primordial_pipe_token_), 0u));
55 } 55 }
56 56
57 ChildProcessHost::ChildProcessHost(ScopedHandle channel) 57 ChildProcessHost::ChildProcessHost(ScopedHandle channel)
58 : launch_process_runner_(nullptr), 58 : external_process_(true),
59 launch_process_runner_(nullptr),
59 delegate_(nullptr), 60 delegate_(nullptr),
60 start_sandboxed_(false), 61 start_sandboxed_(false),
61 start_child_process_event_(false, false), 62 start_child_process_event_(false, false),
62 weak_factory_(this) { 63 weak_factory_(this) {
63 CHECK(channel.is_valid()); 64 CHECK(channel.is_valid());
64 ScopedMessagePipeHandle handle(MessagePipeHandle(channel.release().value())); 65 ScopedMessagePipeHandle handle(MessagePipeHandle(channel.release().value()));
65 controller_.Bind( 66 controller_.Bind(
66 InterfacePtrInfo<mojom::ChildController>(std::move(handle), 0u)); 67 InterfacePtrInfo<mojom::ChildController>(std::move(handle), 0u));
67 } 68 }
68 69
69 ChildProcessHost::~ChildProcessHost() { 70 ChildProcessHost::~ChildProcessHost() {
70 if (!app_path_.empty()) 71 if (!app_path_.empty())
71 CHECK(!controller_) << "Destroying ChildProcessHost before calling Join"; 72 CHECK(!controller_) << "Destroying ChildProcessHost before calling Join";
72 } 73 }
73 74
74 void ChildProcessHost::Start(const ProcessReadyCallback& callback) { 75 void ChildProcessHost::Start(const ProcessReadyCallback& callback) {
76 DCHECK(!external_process_);
75 DCHECK(!child_process_.IsValid()); 77 DCHECK(!child_process_.IsValid());
76 launch_process_runner_->PostTaskAndReply( 78 launch_process_runner_->PostTaskAndReply(
77 FROM_HERE, 79 FROM_HERE,
78 base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this)), 80 base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this)),
79 base::Bind(&ChildProcessHost::DidStart, 81 base::Bind(&ChildProcessHost::DidStart,
80 weak_factory_.GetWeakPtr(), callback)); 82 weak_factory_.GetWeakPtr(), callback));
81 } 83 }
82 84
83 int ChildProcessHost::Join() { 85 int ChildProcessHost::Join() {
84 if (controller_) // We use this as a signal that Start was called. 86 if (controller_ && !external_process_)
85 start_child_process_event_.Wait(); 87 start_child_process_event_.Wait();
86 88
87 controller_ = mojom::ChildControllerPtr(); 89 controller_ = mojom::ChildControllerPtr();
90
88 // This host may be hosting a child process whose lifetime is controlled 91 // This host may be hosting a child process whose lifetime is controlled
89 // elsewhere. In this case we have no known process handle to wait on. 92 // elsewhere. In this case we have no known process handle to wait on.
90 if (child_process_.IsValid()) { 93 if (child_process_.IsValid()) {
91 int rv = -1; 94 int rv = -1;
92 LOG_IF(ERROR, !child_process_.WaitForExit(&rv)) 95 LOG_IF(ERROR, !child_process_.WaitForExit(&rv))
93 << "Failed to wait for child process"; 96 << "Failed to wait for child process";
94 97
95 child_process_.Close(); 98 child_process_.Close();
96 return rv; 99 return rv;
97 } 100 }
98 101
99 return 0; 102 return 0;
100 } 103 }
101 104
102 void ChildProcessHost::StartApp( 105 void ChildProcessHost::StartApp(
103 InterfaceRequest<mojom::ShellClient> request, 106 InterfaceRequest<mojom::ShellClient> request,
104 const mojom::ChildController::StartAppCallback& on_app_complete) { 107 const mojom::ChildController::StartAppCallback& on_app_complete) {
105 DCHECK(controller_); 108 DCHECK(controller_);
106
107 // In this case the process must have already been launched.
108 start_child_process_event_.Signal();
109
110 on_app_complete_ = on_app_complete; 109 on_app_complete_ = on_app_complete;
111 controller_->StartApp( 110 controller_->StartApp(
112 std::move(request), 111 std::move(request),
113 base::Bind(&ChildProcessHost::AppCompleted, weak_factory_.GetWeakPtr())); 112 base::Bind(&ChildProcessHost::AppCompleted, weak_factory_.GetWeakPtr()));
114 } 113 }
115 114
116 void ChildProcessHost::ExitNow(int32_t exit_code) { 115 void ChildProcessHost::ExitNow(int32_t exit_code) {
117 DCHECK(controller_); 116 DCHECK(controller_);
118 117
119 controller_->ExitNow(exit_code); 118 controller_->ExitNow(exit_code);
120 } 119 }
121 120
122 void ChildProcessHost::DidStart(const ProcessReadyCallback& callback) { 121 void ChildProcessHost::DidStart(const ProcessReadyCallback& callback) {
123 DVLOG(2) << "ChildProcessHost::DidStart()"; 122 DVLOG(2) << "ChildProcessHost::DidStart()";
124 123
125 if (child_process_.IsValid()) { 124 if (child_process_.IsValid()) {
126 callback.Run(child_process_.Pid()); 125 callback.Run(child_process_.Pid());
127 } else { 126 } else {
128 LOG(ERROR) << "Failed to start child process"; 127 LOG(ERROR) << "Failed to start child process";
129 AppCompleted(MOJO_RESULT_UNKNOWN); 128 AppCompleted(MOJO_RESULT_UNKNOWN);
130 } 129 }
131 } 130 }
132 131
133 void ChildProcessHost::DoLaunch() { 132 void ChildProcessHost::DoLaunch() {
133 DCHECK(!external_process_);
134
134 const base::CommandLine* parent_command_line = 135 const base::CommandLine* parent_command_line =
135 base::CommandLine::ForCurrentProcess(); 136 base::CommandLine::ForCurrentProcess();
136 base::FilePath target_path = parent_command_line->GetProgram(); 137 base::FilePath target_path = parent_command_line->GetProgram();
137 // |app_path_| can be empty in tests. 138 // |app_path_| can be empty in tests.
138 if (!app_path_.MatchesExtension(FILE_PATH_LITERAL(".mojo")) && 139 if (!app_path_.MatchesExtension(FILE_PATH_LITERAL(".mojo")) &&
139 !app_path_.empty()) { 140 !app_path_.empty()) {
140 target_path = app_path_; 141 target_path = app_path_;
141 } 142 }
142 143
143 base::CommandLine child_command_line(target_path); 144 base::CommandLine child_command_line(target_path);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 void ChildProcessHost::AppCompleted(int32_t result) { 232 void ChildProcessHost::AppCompleted(int32_t result) {
232 if (!on_app_complete_.is_null()) { 233 if (!on_app_complete_.is_null()) {
233 auto on_app_complete = on_app_complete_; 234 auto on_app_complete = on_app_complete_;
234 on_app_complete_.reset(); 235 on_app_complete_.reset();
235 on_app_complete.Run(result); 236 on_app_complete.Run(result);
236 } 237 }
237 } 238 }
238 239
239 } // namespace shell 240 } // namespace shell
240 } // namespace mojo 241 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/shell/runner/host/child_process_host.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698