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

Side by Side Diff: content/browser/child_process_launcher_helper.cc

Issue 2594203004: Unifying ChildProcessLauncher across platforms. (Closed)
Patch Set: Clean-up. Created 3 years, 11 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
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/child_process_launcher_helper.h"
6
7 #include "base/metrics/histogram_macros.h"
8 #include "content/browser/child_process_launcher.h"
9 #include "content/public/common/content_switches.h"
10 #include "content/public/common/sandboxed_process_launcher_delegate.h"
11 #include "mojo/edk/embedder/platform_channel_pair.h"
12
13 namespace content {
14 namespace internal {
15
16 namespace {
17
18 void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) {
19 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
20 // Log the launch time, separating out the first one (which will likely be
21 // slower due to the rest of the browser initializing at the same time).
22 static bool done_first_launch = false;
23 if (done_first_launch) {
24 UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchSubsequent", launch_time);
25 } else {
26 UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchFirst", launch_time);
27 done_first_launch = true;
28 }
29 }
30
31 } // namespace
32
33 ChildProcessLauncherHelper::Process::Process(Process&& other)
34 : process(std::move(other.process))
35 #if defined(OS_LINUX)
36 , zygote(other.zygote)
37 #endif
38 {
39 }
40
41 ChildProcessLauncherHelper::Process&
42 ChildProcessLauncherHelper::Process::Process::operator=(
43 ChildProcessLauncherHelper::Process&& other) {
44 DCHECK_NE(this, &other);
45 process = std::move(other.process);
46 #if defined(OS_LINUX)
47 zygote = other.zygote;
48 #endif
49 return *this;
50 }
51
52 ChildProcessLauncherHelper::ChildProcessLauncherHelper(
53 int child_process_id,
54 BrowserThread::ID client_thread_id,
55 std::unique_ptr<base::CommandLine> command_line,
56 std::unique_ptr<SandboxedProcessLauncherDelegate> delegate,
57 const base::WeakPtr<ChildProcessLauncher>& child_process_launcher,
58 bool terminate_on_shutdown)
59 : child_process_id_(child_process_id),
60 client_thread_id_(client_thread_id),
61 command_line_(std::move(command_line)),
62 delegate_(std::move(delegate)),
63 child_process_launcher_(child_process_launcher),
64 terminate_on_shutdown_(terminate_on_shutdown) {
65 }
66
67 ChildProcessLauncherHelper::~ChildProcessLauncherHelper() {
68 }
69
70 void ChildProcessLauncherHelper::StartLaunchOnClientThread() {
71 DCHECK_CURRENTLY_ON(client_thread_id_);
72
73 BeforeLaunchOnClientThread();
74
75 mojo_server_handle_ = PrepareMojoPipeHandlesOnClientThread();
76 if (!mojo_server_handle_.is_valid()) {
77 mojo::edk::PlatformChannelPair channel_pair;
78 mojo_server_handle_ = channel_pair.PassServerHandle();
79 mojo_client_handle_ = channel_pair.PassClientHandle();
80 }
81
82 BrowserThread::PostTask(
83 BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
84 base::Bind(&ChildProcessLauncherHelper::LaunchOnLauncherThread, this));
85 }
86
87 void ChildProcessLauncherHelper::LaunchOnLauncherThread() {
88 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
89
90 begin_launch_time_ = base::TimeTicks::Now();
91
92 std::unique_ptr<FileMappedForLaunch> files_to_register = GetFilesToMap();
93
94 bool is_synchronous_launch = true;
95 int launch_result = LAUNCH_RESULT_FAILURE;
96 base::LaunchOptions options;
97 BeforeLaunchOnLauncherThread(*files_to_register, &options);
98
99 Process process = LaunchProcessOnLauncherThread(options,
100 std::move(files_to_register),
101 &is_synchronous_launch,
102 &launch_result);
103
104 AfterLaunchOnLauncherThread(process, options);
105
106 if (is_synchronous_launch) {
107 PostLaunchOnLauncherThread(std::move(process), launch_result, false);
108 }
109 }
110
111 void ChildProcessLauncherHelper::PostLaunchOnLauncherThread(
112 ChildProcessLauncherHelper::Process process,
113 int launch_result,
114 bool post_launch_on_client_thread_called) {
115 // Release the client handle now that the process has been started (the pipe
116 // may not signal when the process dies otherwise and we would not detect the
117 // child process died).
118 mojo_client_handle_.reset();
119
120 if (process.process.IsValid()) {
121 RecordHistogramsOnLauncherThread(
122 base::TimeTicks::Now() - begin_launch_time_);
123 }
124
125 if (!post_launch_on_client_thread_called) {
126 BrowserThread::PostTask(
127 client_thread_id_, FROM_HERE,
128 base::Bind(&ChildProcessLauncherHelper::PostLaunchOnClientThread,
129 this, base::Passed(&process), launch_result));
130 }
131 }
132
133 void ChildProcessLauncherHelper::PostLaunchOnClientThread(
134 ChildProcessLauncherHelper::Process process,
135 int error_code) {
136 if (child_process_launcher_) {
137 child_process_launcher_->Notify(
138 std::move(process), std::move(mojo_server_handle_), error_code);
139 } else if (process.process.IsValid() && terminate_on_shutdown_) {
140 // Client is gone, terminate the process.
141 ForceNormalProcessTerminationAsync(std::move(process));
142 }
143 }
144
145 std::string ChildProcessLauncherHelper::GetProcessType() {
146 return command_line()->GetSwitchValueASCII(switches::kProcessType);
147 }
148
149 // static
150 void ChildProcessLauncherHelper::ForceNormalProcessTerminationAsync(
151 ChildProcessLauncherHelper::Process process) {
152 if (BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER)) {
153 ForceNormalProcessTerminationSync(std::move(process));
154 return;
155 }
156 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep!
157 // So don't do this on the UI/IO threads.
158 BrowserThread::PostTask(
159 BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
160 base::Bind(&ChildProcessLauncherHelper::ForceNormalProcessTerminationSync,
161 base::Passed(&process)));
162 }
163
164 } // namespace internal
165 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/child_process_launcher_helper.h ('k') | content/browser/child_process_launcher_helper_android.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698