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

Side by Side Diff: mojo/runner/child_process.cc

Issue 1350023003: Add a Mojo EDK for Chrome that uses one OS pipe per message pipe. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: move to mojo::edk namespace in preparation for runtim flag Created 5 years, 3 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
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/runner/child_process.h" 5 #include "mojo/runner/child_process.h"
6 6
7 #include "base/base_switches.h" 7 #include "base/base_switches.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
16 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
17 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
18 #include "base/single_thread_task_runner.h" 18 #include "base/single_thread_task_runner.h"
19 #include "base/synchronization/waitable_event.h" 19 #include "base/synchronization/waitable_event.h"
20 #include "base/thread_task_runner_handle.h" 20 #include "base/thread_task_runner_handle.h"
21 #include "base/threading/thread.h" 21 #include "base/threading/thread.h"
22 #include "base/threading/thread_checker.h" 22 #include "base/threading/thread_checker.h"
23 #include "mojo/edk/embedder/embedder.h"
24 #include "mojo/edk/embedder/platform_channel_pair.h"
25 #include "mojo/edk/embedder/process_delegate.h"
26 #include "mojo/edk/embedder/scoped_platform_handle.h"
27 #include "mojo/edk/embedder/simple_platform_support.h"
28 #include "mojo/message_pump/message_pump_mojo.h" 23 #include "mojo/message_pump/message_pump_mojo.h"
29 #include "mojo/public/cpp/bindings/binding.h" 24 #include "mojo/public/cpp/bindings/binding.h"
30 #include "mojo/public/cpp/system/core.h" 25 #include "mojo/public/cpp/system/core.h"
31 #include "mojo/runner/child_process.mojom.h" 26 #include "mojo/runner/child_process.mojom.h"
32 #include "mojo/runner/native_application_support.h" 27 #include "mojo/runner/native_application_support.h"
33 #include "mojo/runner/switches.h" 28 #include "mojo/runner/switches.h"
34 29
30 #if defined(USE_CHROME_EDK)
31 #include "mojo/edk/embedder/embedder.h"
32 #include "mojo/edk/embedder/platform_channel_pair.h"
33 #include "mojo/edk/embedder/process_delegate.h"
34 #include "mojo/edk/embedder/scoped_platform_handle.h"
35 #include "mojo/edk/embedder/simple_platform_support.h"
36 #else
37 #include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
38 #include "third_party/mojo/src/mojo/edk/embedder/platform_channel_pair.h"
39 #include "third_party/mojo/src/mojo/edk/embedder/process_delegate.h"
40 #include "third_party/mojo/src/mojo/edk/embedder/scoped_platform_handle.h"
41 #include "third_party/mojo/src/mojo/edk/embedder/simple_platform_support.h"
42 #endif
43
35 #if defined(OS_LINUX) && !defined(OS_ANDROID) 44 #if defined(OS_LINUX) && !defined(OS_ANDROID)
36 #include "base/rand_util.h" 45 #include "base/rand_util.h"
37 #include "base/sys_info.h" 46 #include "base/sys_info.h"
38 #include "mojo/runner/linux_sandbox.h" 47 #include "mojo/runner/linux_sandbox.h"
39 #endif 48 #endif
40 49
41 namespace mojo { 50 namespace mojo {
42 namespace runner { 51 namespace runner {
43 52
44 namespace { 53 namespace {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 base::Closure run_after_; 94 base::Closure run_after_;
86 95
87 DISALLOW_COPY_AND_ASSIGN(Blocker); 96 DISALLOW_COPY_AND_ASSIGN(Blocker);
88 }; 97 };
89 98
90 // AppContext ------------------------------------------------------------------ 99 // AppContext ------------------------------------------------------------------
91 100
92 class ChildControllerImpl; 101 class ChildControllerImpl;
93 102
94 // Should be created and initialized on the main thread. 103 // Should be created and initialized on the main thread.
104 #if defined(USE_CHROME_EDK)
105 class AppContext : public edk::ProcessDelegate {
106 #else
95 class AppContext : public embedder::ProcessDelegate { 107 class AppContext : public embedder::ProcessDelegate {
108 #endif
96 public: 109 public:
97 AppContext() 110 AppContext()
98 : io_thread_("io_thread"), controller_thread_("controller_thread") {} 111 : io_thread_("io_thread"), controller_thread_("controller_thread") {}
99 ~AppContext() override {} 112 ~AppContext() override {}
100 113
101 void Init() { 114 void Init() {
102 // Initialize Mojo before starting any threads. 115 // Initialize Mojo before starting any threads.
116 #if defined(USE_CHROME_EDK)
117 edk::Init(make_scoped_ptr(new edk::SimplePlatformSupport()));
118 #else
103 embedder::Init(make_scoped_ptr(new embedder::SimplePlatformSupport())); 119 embedder::Init(make_scoped_ptr(new embedder::SimplePlatformSupport()));
120 #endif
104 121
105 // Create and start our I/O thread. 122 // Create and start our I/O thread.
106 base::Thread::Options io_thread_options(base::MessageLoop::TYPE_IO, 0); 123 base::Thread::Options io_thread_options(base::MessageLoop::TYPE_IO, 0);
107 CHECK(io_thread_.StartWithOptions(io_thread_options)); 124 CHECK(io_thread_.StartWithOptions(io_thread_options));
108 io_runner_ = io_thread_.task_runner().get(); 125 io_runner_ = io_thread_.task_runner().get();
109 CHECK(io_runner_.get()); 126 CHECK(io_runner_.get());
110 127
111 // Create and start our controller thread. 128 // Create and start our controller thread.
112 base::Thread::Options controller_thread_options; 129 base::Thread::Options controller_thread_options;
113 controller_thread_options.message_loop_type = 130 controller_thread_options.message_loop_type =
114 base::MessageLoop::TYPE_CUSTOM; 131 base::MessageLoop::TYPE_CUSTOM;
115 controller_thread_options.message_pump_factory = 132 controller_thread_options.message_pump_factory =
116 base::Bind(&common::MessagePumpMojo::Create); 133 base::Bind(&common::MessagePumpMojo::Create);
117 CHECK(controller_thread_.StartWithOptions(controller_thread_options)); 134 CHECK(controller_thread_.StartWithOptions(controller_thread_options));
118 controller_runner_ = controller_thread_.task_runner().get(); 135 controller_runner_ = controller_thread_.task_runner().get();
119 CHECK(controller_runner_.get()); 136 CHECK(controller_runner_.get());
120 137
138 #if defined(USE_CHROME_EDK)
139 edk::InitIPCSupport(controller_runner_, this, io_runner_,
140 edk::ScopedPlatformHandle());
141 #else
121 // TODO(vtl): This should be SLAVE, not NONE. 142 // TODO(vtl): This should be SLAVE, not NONE.
122 embedder::InitIPCSupport(embedder::ProcessType::NONE, controller_runner_, 143 embedder::InitIPCSupport(embedder::ProcessType::NONE, controller_runner_,
123 this, io_runner_, 144 this, io_runner_,
124 embedder::ScopedPlatformHandle()); 145 embedder::ScopedPlatformHandle());
146 #endif
125 } 147 }
126 148
127 void Shutdown() { 149 void Shutdown() {
128 Blocker blocker; 150 Blocker blocker;
129 shutdown_unblocker_ = blocker.GetUnblocker(); 151 shutdown_unblocker_ = blocker.GetUnblocker();
130 controller_runner_->PostTask( 152 controller_runner_->PostTask(
131 FROM_HERE, base::Bind(&AppContext::ShutdownOnControllerThread, 153 FROM_HERE, base::Bind(&AppContext::ShutdownOnControllerThread,
132 base::Unretained(this))); 154 base::Unretained(this)));
133 blocker.Block(); 155 blocker.Block();
134 } 156 }
135 157
136 base::SingleThreadTaskRunner* io_runner() const { return io_runner_.get(); } 158 base::SingleThreadTaskRunner* io_runner() const { return io_runner_.get(); }
137 159
138 base::SingleThreadTaskRunner* controller_runner() const { 160 base::SingleThreadTaskRunner* controller_runner() const {
139 return controller_runner_.get(); 161 return controller_runner_.get();
140 } 162 }
141 163
142 ChildControllerImpl* controller() const { return controller_.get(); } 164 ChildControllerImpl* controller() const { return controller_.get(); }
143 165
144 void set_controller(scoped_ptr<ChildControllerImpl> controller) { 166 void set_controller(scoped_ptr<ChildControllerImpl> controller) {
145 controller_ = controller.Pass(); 167 controller_ = controller.Pass();
146 } 168 }
147 169
148 private: 170 private:
149 void ShutdownOnControllerThread() { 171 void ShutdownOnControllerThread() {
150 // First, destroy the controller. 172 // First, destroy the controller.
151 controller_.reset(); 173 controller_.reset();
152 174
153 // Next shutdown IPC. We'll unblock the main thread in OnShutdownComplete(). 175 // Next shutdown IPC. We'll unblock the main thread in OnShutdownComplete().
176 #if defined(USE_CHROME_EDK)
177 edk::ShutdownIPCSupport();
178 #else
154 embedder::ShutdownIPCSupport(); 179 embedder::ShutdownIPCSupport();
180 #endif
155 } 181 }
156 182
157 // ProcessDelegate implementation. 183 // ProcessDelegate implementation.
158 void OnShutdownComplete() override { 184 void OnShutdownComplete() override {
159 shutdown_unblocker_.Unblock(base::Closure()); 185 shutdown_unblocker_.Unblock(base::Closure());
160 } 186 }
161 187
162 base::Thread io_thread_; 188 base::Thread io_thread_;
163 scoped_refptr<base::SingleThreadTaskRunner> io_runner_; 189 scoped_refptr<base::SingleThreadTaskRunner> io_runner_;
164 190
(...skipping 17 matching lines...) Expand all
182 DCHECK(thread_checker_.CalledOnValidThread()); 208 DCHECK(thread_checker_.CalledOnValidThread());
183 209
184 // TODO(vtl): Pass in the result from |MainMain()|. 210 // TODO(vtl): Pass in the result from |MainMain()|.
185 on_app_complete_.Run(MOJO_RESULT_UNIMPLEMENTED); 211 on_app_complete_.Run(MOJO_RESULT_UNIMPLEMENTED);
186 } 212 }
187 213
188 // To be executed on the controller thread. Creates the |ChildController|, 214 // To be executed on the controller thread. Creates the |ChildController|,
189 // etc. 215 // etc.
190 static void Init(AppContext* app_context, 216 static void Init(AppContext* app_context,
191 base::NativeLibrary app_library, 217 base::NativeLibrary app_library,
218 #if defined(USE_CHROME_EDK)
219 edk::ScopedPlatformHandle platform_channel,
220 #else
192 embedder::ScopedPlatformHandle platform_channel, 221 embedder::ScopedPlatformHandle platform_channel,
222 #endif
193 const Blocker::Unblocker& unblocker) { 223 const Blocker::Unblocker& unblocker) {
194 DCHECK(app_context); 224 DCHECK(app_context);
195 DCHECK(platform_channel.is_valid()); 225 DCHECK(platform_channel.is_valid());
196 226
197 DCHECK(!app_context->controller()); 227 DCHECK(!app_context->controller());
198 228
199 scoped_ptr<ChildControllerImpl> impl( 229 scoped_ptr<ChildControllerImpl> impl(
200 new ChildControllerImpl(app_context, app_library, unblocker)); 230 new ChildControllerImpl(app_context, app_library, unblocker));
201 231
232 #if defined(USE_CHROME_EDK)
233 ScopedMessagePipeHandle host_message_pipe(
234 edk::CreateMessagePipe(platform_channel.Pass()));
235 #else
202 ScopedMessagePipeHandle host_message_pipe(embedder::CreateChannel( 236 ScopedMessagePipeHandle host_message_pipe(embedder::CreateChannel(
203 platform_channel.Pass(), 237 platform_channel.Pass(),
204 base::Bind(&ChildControllerImpl::DidCreateChannel, 238 base::Bind(&ChildControllerImpl::DidCreateChannel,
205 base::Unretained(impl.get())), 239 base::Unretained(impl.get())),
206 base::ThreadTaskRunnerHandle::Get())); 240 base::ThreadTaskRunnerHandle::Get()));
241 #endif
207 242
208 impl->Bind(host_message_pipe.Pass()); 243 impl->Bind(host_message_pipe.Pass());
209 244
210 app_context->set_controller(impl.Pass()); 245 app_context->set_controller(impl.Pass());
211 } 246 }
212 247
213 void Bind(ScopedMessagePipeHandle handle) { binding_.Bind(handle.Pass()); } 248 void Bind(ScopedMessagePipeHandle handle) { binding_.Bind(handle.Pass()); }
214 249
215 void OnConnectionError() { 250 void OnConnectionError() {
216 // A connection error means the connection to the shell is lost. This is not 251 // A connection error means the connection to the shell is lost. This is not
(...skipping 18 matching lines...) Expand all
235 _exit(exit_code); 270 _exit(exit_code);
236 } 271 }
237 272
238 private: 273 private:
239 ChildControllerImpl(AppContext* app_context, 274 ChildControllerImpl(AppContext* app_context,
240 base::NativeLibrary app_library, 275 base::NativeLibrary app_library,
241 const Blocker::Unblocker& unblocker) 276 const Blocker::Unblocker& unblocker)
242 : app_context_(app_context), 277 : app_context_(app_context),
243 app_library_(app_library), 278 app_library_(app_library),
244 unblocker_(unblocker), 279 unblocker_(unblocker),
280 #if !defined(USE_CHROME_EDK)
245 channel_info_(nullptr), 281 channel_info_(nullptr),
282 #endif
246 binding_(this) { 283 binding_(this) {
247 binding_.set_connection_error_handler([this]() { OnConnectionError(); }); 284 binding_.set_connection_error_handler([this]() { OnConnectionError(); });
248 } 285 }
249 286
287 #if !defined(USE_CHROME_EDK)
250 // Callback for |embedder::CreateChannel()|. 288 // Callback for |embedder::CreateChannel()|.
251 void DidCreateChannel(embedder::ChannelInfo* channel_info) { 289 void DidCreateChannel(embedder::ChannelInfo* channel_info) {
252 DVLOG(2) << "ChildControllerImpl::DidCreateChannel()"; 290 DVLOG(2) << "ChildControllerImpl::DidCreateChannel()";
253 DCHECK(thread_checker_.CalledOnValidThread()); 291 DCHECK(thread_checker_.CalledOnValidThread());
254 channel_info_ = channel_info; 292 channel_info_ = channel_info;
255 } 293 }
294 #endif
256 295
257 static void StartAppOnMainThread( 296 static void StartAppOnMainThread(
258 base::NativeLibrary app_library, 297 base::NativeLibrary app_library,
259 InterfaceRequest<Application> application_request) { 298 InterfaceRequest<Application> application_request) {
260 if (!RunNativeApplication(app_library, application_request.Pass())) { 299 if (!RunNativeApplication(app_library, application_request.Pass())) {
261 LOG(ERROR) << "Failure to RunNativeApplication()"; 300 LOG(ERROR) << "Failure to RunNativeApplication()";
262 } 301 }
263 } 302 }
264 303
265 base::ThreadChecker thread_checker_; 304 base::ThreadChecker thread_checker_;
266 AppContext* const app_context_; 305 AppContext* const app_context_;
267 base::NativeLibrary app_library_; 306 base::NativeLibrary app_library_;
268 Blocker::Unblocker unblocker_; 307 Blocker::Unblocker unblocker_;
269 StartAppCallback on_app_complete_; 308 StartAppCallback on_app_complete_;
270 309
310 #if !defined(USE_CHROME_EDK)
271 embedder::ChannelInfo* channel_info_; 311 embedder::ChannelInfo* channel_info_;
312 #endif
272 Binding<ChildController> binding_; 313 Binding<ChildController> binding_;
273 314
274 DISALLOW_COPY_AND_ASSIGN(ChildControllerImpl); 315 DISALLOW_COPY_AND_ASSIGN(ChildControllerImpl);
275 }; 316 };
276 317
277 } // namespace 318 } // namespace
278 319
279 int ChildProcessMain() { 320 int ChildProcessMain() {
280 DVLOG(2) << "ChildProcessMain()"; 321 DVLOG(2) << "ChildProcessMain()";
281 const base::CommandLine& command_line = 322 const base::CommandLine& command_line =
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 BrokerFilePermission::ReadWriteCreateUnlinkRecursive("/dev/shm/")); 357 BrokerFilePermission::ReadWriteCreateUnlinkRecursive("/dev/shm/"));
317 sandbox.reset(new mandoline::LinuxSandbox(permissions)); 358 sandbox.reset(new mandoline::LinuxSandbox(permissions));
318 sandbox->Warmup(); 359 sandbox->Warmup();
319 sandbox->EngageNamespaceSandbox(); 360 sandbox->EngageNamespaceSandbox();
320 sandbox->EngageSeccompSandbox(); 361 sandbox->EngageSeccompSandbox();
321 sandbox->Seal(); 362 sandbox->Seal();
322 } 363 }
323 #endif 364 #endif
324 } 365 }
325 366
367 #if defined(USE_CHROME_EDK)
368 edk::ScopedPlatformHandle platform_channel =
369 edk::PlatformChannelPair::PassClientHandleFromParentProcess(
370 command_line);
371 #else
326 embedder::ScopedPlatformHandle platform_channel = 372 embedder::ScopedPlatformHandle platform_channel =
327 embedder::PlatformChannelPair::PassClientHandleFromParentProcess( 373 embedder::PlatformChannelPair::PassClientHandleFromParentProcess(
328 command_line); 374 command_line);
375 #endif
329 CHECK(platform_channel.is_valid()); 376 CHECK(platform_channel.is_valid());
330 377
331 DCHECK(!base::MessageLoop::current()); 378 DCHECK(!base::MessageLoop::current());
332 379
333 AppContext app_context; 380 AppContext app_context;
334 app_context.Init(); 381 app_context.Init();
335 382
336 Blocker blocker; 383 Blocker blocker;
337 app_context.controller_runner()->PostTask( 384 app_context.controller_runner()->PostTask(
338 FROM_HERE, 385 FROM_HERE,
339 base::Bind(&ChildControllerImpl::Init, base::Unretained(&app_context), 386 base::Bind(&ChildControllerImpl::Init, base::Unretained(&app_context),
340 base::Unretained(app_library), base::Passed(&platform_channel), 387 base::Unretained(app_library), base::Passed(&platform_channel),
341 blocker.GetUnblocker())); 388 blocker.GetUnblocker()));
342 // This will block, then run whatever the controller wants. 389 // This will block, then run whatever the controller wants.
343 blocker.Block(); 390 blocker.Block();
344 391
345 app_context.Shutdown(); 392 app_context.Shutdown();
346 393
347 return 0; 394 return 0;
348 } 395 }
349 396
350 } // namespace runner 397 } // namespace runner
351 } // namespace mojo 398 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698