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

Side by Side Diff: shell/child_process_host.cc

Issue 1146273002: Make ChildProcessHost::DoLaunch() not touch a random set of things on a different thread. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 7 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 | « shell/child_process_host.h ('k') | shell/child_process_host_unittest.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 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 "shell/child_process_host.h" 5 #include "shell/child_process_host.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/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/location.h" 11 #include "base/location.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
15 #include "base/process/kill.h" 15 #include "base/process/kill.h"
16 #include "base/process/launch.h" 16 #include "base/process/launch.h"
17 #include "base/task_runner.h" 17 #include "base/task_runner.h"
18 #include "base/task_runner_util.h" 18 #include "base/task_runner_util.h"
19 #include "mojo/edk/embedder/embedder.h" 19 #include "mojo/edk/embedder/embedder.h"
20 #include "mojo/edk/embedder/platform_channel_pair.h"
20 #include "mojo/public/cpp/system/message_pipe.h" 21 #include "mojo/public/cpp/system/message_pipe.h"
21 #include "shell/child_switches.h" 22 #include "shell/child_switches.h"
22 #include "shell/context.h" 23 #include "shell/context.h"
23 #include "shell/task_runners.h" 24 #include "shell/task_runners.h"
24 25
25 namespace shell { 26 namespace shell {
26 27
28 struct ChildProcessHost::LaunchData {
29 LaunchData() {}
30 ~LaunchData() {}
31
32 base::FilePath child_path;
33 mojo::embedder::PlatformChannelPair platform_channel_pair;
34 std::string child_connection_id;
35 };
36
27 ChildProcessHost::ChildProcessHost(Context* context) 37 ChildProcessHost::ChildProcessHost(Context* context)
28 : context_(context), channel_info_(nullptr) { 38 : context_(context), channel_info_(nullptr) {
29 } 39 }
30 40
31 ChildProcessHost::~ChildProcessHost() { 41 ChildProcessHost::~ChildProcessHost() {
32 DCHECK(!child_process_.IsValid()); 42 DCHECK(!child_process_.IsValid());
33 } 43 }
34 44
35 void ChildProcessHost::Start() { 45 void ChildProcessHost::Start() {
36 DCHECK(!child_process_.IsValid()); 46 DCHECK(!child_process_.IsValid());
37 47
48 scoped_ptr<LaunchData> launch_data(new LaunchData());
49 launch_data->child_path = context_->mojo_shell_child_path();
50
38 // TODO(vtl): Add something for |slave_info|. 51 // TODO(vtl): Add something for |slave_info|.
39 mojo::embedder::ScopedPlatformHandle platform_handle_for_channel; 52 mojo::embedder::ScopedPlatformHandle platform_handle_for_channel;
40 std::string child_connection_id;
41 mojo::embedder::ConnectToSlave( 53 mojo::embedder::ConnectToSlave(
42 nullptr, platform_channel_pair_.PassServerHandle(), 54 nullptr, launch_data->platform_channel_pair.PassServerHandle(),
43 &platform_handle_for_channel, &child_connection_id); 55 &platform_handle_for_channel, &launch_data->child_connection_id);
44 56
45 mojo::ScopedMessagePipeHandle handle(mojo::embedder::CreateChannel( 57 mojo::ScopedMessagePipeHandle handle(mojo::embedder::CreateChannel(
46 platform_handle_for_channel.Pass(), context_->task_runners()->io_runner(), 58 platform_handle_for_channel.Pass(), context_->task_runners()->io_runner(),
47 base::Bind(&ChildProcessHost::DidCreateChannel, base::Unretained(this)), 59 base::Bind(&ChildProcessHost::DidCreateChannel, base::Unretained(this)),
48 base::MessageLoop::current()->message_loop_proxy())); 60 base::MessageLoop::current()->message_loop_proxy()));
49 61
50 controller_.Bind(mojo::InterfacePtrInfo<ChildController>(handle.Pass(), 0u)); 62 controller_.Bind(mojo::InterfacePtrInfo<ChildController>(handle.Pass(), 0u));
51 controller_.set_error_handler(this); 63 controller_.set_error_handler(this);
52 64
53 CHECK(base::PostTaskAndReplyWithResult( 65 CHECK(base::PostTaskAndReplyWithResult(
54 context_->task_runners()->blocking_pool(), FROM_HERE, 66 context_->task_runners()->blocking_pool(), FROM_HERE,
55 base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this), 67 base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this),
56 child_connection_id), 68 base::Passed(&launch_data)),
57 base::Bind(&ChildProcessHost::DidStart, base::Unretained(this)))); 69 base::Bind(&ChildProcessHost::DidStart, base::Unretained(this))));
58 } 70 }
59 71
60 int ChildProcessHost::Join() { 72 int ChildProcessHost::Join() {
61 DCHECK(child_process_.IsValid()); 73 DCHECK(child_process_.IsValid());
62 int rv = -1; 74 int rv = -1;
63 LOG_IF(ERROR, !child_process_.WaitForExit(&rv)) 75 LOG_IF(ERROR, !child_process_.WaitForExit(&rv))
64 << "Failed to wait for child process"; 76 << "Failed to wait for child process";
65 child_process_.Close(); 77 child_process_.Close();
66 return rv; 78 return rv;
(...skipping 10 matching lines...) Expand all
77 app_path, application_request.Pass(), 89 app_path, application_request.Pass(),
78 base::Bind(&ChildProcessHost::AppCompleted, base::Unretained(this))); 90 base::Bind(&ChildProcessHost::AppCompleted, base::Unretained(this)));
79 } 91 }
80 92
81 void ChildProcessHost::ExitNow(int32_t exit_code) { 93 void ChildProcessHost::ExitNow(int32_t exit_code) {
82 DCHECK(controller_); 94 DCHECK(controller_);
83 95
84 controller_->ExitNow(exit_code); 96 controller_->ExitNow(exit_code);
85 } 97 }
86 98
87 void ChildProcessHost::DidStart(bool success) { 99 void ChildProcessHost::DidStart(base::Process child_process) {
88 DVLOG(2) << "ChildProcessHost::DidStart()"; 100 DVLOG(2) << "ChildProcessHost::DidStart()";
101 DCHECK(!child_process_.IsValid());
89 102
90 if (!success) { 103 if (!child_process.IsValid()) {
91 LOG(ERROR) << "Failed to start app child process"; 104 LOG(ERROR) << "Failed to start app child process";
92 AppCompleted(MOJO_RESULT_UNKNOWN); 105 AppCompleted(MOJO_RESULT_UNKNOWN);
93 return; 106 return;
94 } 107 }
108
109 child_process_ = child_process.Pass();
95 } 110 }
96 111
97 // Callback for |mojo::embedder::CreateChannel()|. 112 // Callback for |mojo::embedder::CreateChannel()|.
98 void ChildProcessHost::DidCreateChannel( 113 void ChildProcessHost::DidCreateChannel(
99 mojo::embedder::ChannelInfo* channel_info) { 114 mojo::embedder::ChannelInfo* channel_info) {
100 DVLOG(2) << "ChildProcessHost::DidCreateChannel()"; 115 DVLOG(2) << "ChildProcessHost::DidCreateChannel()";
101 116
102 CHECK(channel_info); 117 CHECK(channel_info);
103 channel_info_ = channel_info; 118 channel_info_ = channel_info;
104 } 119 }
105 120
106 bool ChildProcessHost::DoLaunch(const std::string& child_connection_id) { 121 base::Process ChildProcessHost::DoLaunch(scoped_ptr<LaunchData> launch_data) {
107 static const char* kForwardSwitches[] = { 122 static const char* kForwardSwitches[] = {
108 switches::kTraceToConsole, switches::kV, switches::kVModule, 123 switches::kTraceToConsole, switches::kV, switches::kVModule,
109 }; 124 };
110 125
111 base::CommandLine child_command_line(context_->mojo_shell_child_path()); 126 base::CommandLine child_command_line(launch_data->child_path);
112 child_command_line.CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(), 127 child_command_line.CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
113 kForwardSwitches, 128 kForwardSwitches,
114 arraysize(kForwardSwitches)); 129 arraysize(kForwardSwitches));
115 child_command_line.AppendSwitchASCII(switches::kChildConnectionId, 130 child_command_line.AppendSwitchASCII(switches::kChildConnectionId,
116 child_connection_id); 131 launch_data->child_connection_id);
117 132
118 mojo::embedder::HandlePassingInformation handle_passing_info; 133 mojo::embedder::HandlePassingInformation handle_passing_info;
119 platform_channel_pair_.PrepareToPassClientHandleToChildProcess( 134 launch_data->platform_channel_pair.PrepareToPassClientHandleToChildProcess(
120 &child_command_line, &handle_passing_info); 135 &child_command_line, &handle_passing_info);
121 136
122 base::LaunchOptions options; 137 base::LaunchOptions options;
123 options.fds_to_remap = &handle_passing_info; 138 options.fds_to_remap = &handle_passing_info;
124 DVLOG(2) << "Launching child with command line: " 139 DVLOG(2) << "Launching child with command line: "
125 << child_command_line.GetCommandLineString(); 140 << child_command_line.GetCommandLineString();
126 child_process_ = base::LaunchProcess(child_command_line, options); 141 base::Process child_process =
127 if (!child_process_.IsValid()) 142 base::LaunchProcess(child_command_line, options);
128 return false; 143 if (child_process.IsValid())
129 144 launch_data->platform_channel_pair.ChildProcessLaunched();
130 platform_channel_pair_.ChildProcessLaunched(); 145 return child_process.Pass();
131 return true;
132 } 146 }
133 147
134 void ChildProcessHost::AppCompleted(int32_t result) { 148 void ChildProcessHost::AppCompleted(int32_t result) {
135 if (!on_app_complete_.is_null()) { 149 if (!on_app_complete_.is_null()) {
136 auto on_app_complete = on_app_complete_; 150 auto on_app_complete = on_app_complete_;
137 on_app_complete_.reset(); 151 on_app_complete_.reset();
138 on_app_complete.Run(result); 152 on_app_complete.Run(result);
139 } 153 }
140 } 154 }
141 155
142 void ChildProcessHost::OnConnectionError() { 156 void ChildProcessHost::OnConnectionError() {
143 AppCompleted(MOJO_RESULT_UNKNOWN); 157 AppCompleted(MOJO_RESULT_UNKNOWN);
144 } 158 }
145 159
146 } // namespace shell 160 } // namespace shell
OLDNEW
« no previous file with comments | « shell/child_process_host.h ('k') | shell/child_process_host_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698