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

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

Issue 2594203004: Unifying ChildProcessLauncher across platforms. (Closed)
Patch Set: Addressed boliu@'s comments. 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 2016 The Chromium Authors. All rights reserved.
boliu 2017/01/13 19:00:56 all new files 2017?
Jay Civelli 2017/01/17 17:50:02 Done.
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 "base/posix/global_descriptors.h"
6 #include "content/browser/child_process_launcher.h"
7 #include "content/browser/child_process_launcher_posix.h"
8 #include "content/browser/renderer_host/render_sandbox_host_linux.h"
9 #include "content/browser/zygote_host/zygote_communication_linux.h"
10 #include "content/browser/zygote_host/zygote_host_impl_linux.h"
11 #include "content/common/child_process_sandbox_support_impl_linux.h"
12 #include "content/public/browser/content_browser_client.h"
13 #include "content/public/browser/zygote_handle_linux.h"
14 #include "content/public/common/content_client.h"
15 #include "content/public/common/content_switches.h"
16 #include "content/public/common/result_codes.h"
17 #include "content/public/common/sandboxed_process_launcher_delegate.h"
18 #include "gin/v8_initializer.h"
19
20 namespace content {
21
22 mojo::edk::ScopedPlatformHandle
23 ChildProcessLauncher::Helper::PrepareMojoPipeHandlesOnClientThread() {
24 DCHECK_CURRENTLY_ON(client_thread_id_);
25 return mojo::edk::ScopedPlatformHandle();
26 }
27
28 void ChildProcessLauncher::Helper::BeforeLaunchOnClientThread() {
29 DCHECK_CURRENTLY_ON(client_thread_id_);
30 }
31
32 bool ChildProcessLauncher::Helper::ShouldForkAsZygote() {
33 return !base::CommandLine::ForCurrentProcess()->HasSwitch(
34 switches::kNoZygote) && delegate_->GetZygote() != nullptr;
35 }
36
37 ZygoteHandle ChildProcessLauncher::Helper::ForkAsZygote(
38 std::unique_ptr<FileDescriptorInfo> files_to_register,
39 base::Process* process) {
40 ZygoteHandle* zygote_handle = delegate_->GetZygote();
41 DCHECK(zygote_handle); // This should only be called when ZygoteSuppported()
42 // returned true.
43
44 // This code runs on the PROCESS_LAUNCHER thread so race conditions are not
45 // an issue with the lazy initialization.
46 if (*zygote_handle == nullptr) {
47 *zygote_handle = CreateZygote();
48 }
49 base::ProcessHandle handle = (*zygote_handle)->ForkRequest(
50 command_line()->argv(),
51 std::move(files_to_register),
52 GetProcessType());
53 *process = base::Process(handle);
54
55 return *zygote_handle;
56 }
57
58 std::unique_ptr<FileDescriptorInfo>
59 ChildProcessLauncher::Helper::GetFilesToMap() {
60 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
61
62 std::unique_ptr<FileDescriptorInfo> files_to_register =
63 CreateDefaultPosixFilesToMap(*command_line(), child_process_id(),
64 mojo_client_handle());
65
66 #if defined(V8_USE_EXTERNAL_STARTUP_DATA)
67 bool snapshot_loaded = false;
68 base::MemoryMappedFile::Region unused_region;
69 base::PlatformFile natives_pf =
70 gin::V8Initializer::GetOpenNativesFileForChildProcesses(&unused_region);
71 DCHECK_GE(natives_pf, 0);
72 files_to_register->Share(kV8NativesDataDescriptor, natives_pf);
73
74 base::MemoryMappedFile::Region snapshot_region;
75 base::PlatformFile snapshot_pf =
76 gin::V8Initializer::GetOpenSnapshotFileForChildProcesses(
77 &snapshot_region);
78 // Failure to load the V8 snapshot is not necessarily an error. V8 can start
79 // up (slower) without the snapshot.
80 if (snapshot_pf != -1) {
81 snapshot_loaded = true;
82 files_to_register->Share(kV8SnapshotDataDescriptor, snapshot_pf);
83 }
84 if (GetProcessType() != switches::kZygoteProcess) {
85 command_line()->AppendSwitch(::switches::kV8NativesPassedByFD);
86 if (snapshot_loaded) {
87 command_line()->AppendSwitch(::switches::kV8SnapshotPassedByFD);
88 }
89 }
90 #endif // defined(V8_USE_EXTERNAL_STARTUP_DATA)
91
92 return files_to_register;
93 }
94
95 void ChildProcessLauncher::Helper::BeforeLaunchOnLauncherThread(
96 const FileDescriptorInfo& files_to_register,
97 base::LaunchOptions* options) {
98 // Convert FD mapping to FileHandleMappingVector
99 std::unique_ptr<base::FileHandleMappingVector> fds_to_map =
100 files_to_register.GetMappingWithIDAdjustment(
101 base::GlobalDescriptors::kBaseDescriptor);
102
103 if (GetProcessType() == switches::kRendererProcess) {
104 const int sandbox_fd =
105 RenderSandboxHostLinux::GetInstance()->GetRendererSocket();
106 fds_to_map->push_back(std::make_pair(sandbox_fd, GetSandboxFD()));
107 }
108
109 options->environ = delegate_->GetEnvironment();
110 // fds_to_remap will de deleted in AfterLaunchOnLauncherThread() below.
111 options->fds_to_remap = fds_to_map.release();
112 }
113
114 base::Process ChildProcessLauncher::Helper::LaunchProcessOnLauncherThread(
115 const base::LaunchOptions& options,
116 FileDescriptorInfo* files_to_register,
117 bool* is_synchronous_launch,
118 int* launch_result) {
119 *is_synchronous_launch = true;
120 base::Process process = base::LaunchProcess(*command_line(), options);
121 *launch_result = process.IsValid() ? LAUNCH_RESULT_SUCCESS
122 : LAUNCH_RESULT_FAILURE;
123 return process;
124 }
125
126 void ChildProcessLauncher::Helper::AfterLaunchOnLauncherThread(
127 const base::Process& process,
128 const base::LaunchOptions& options) {
129 delete options.fds_to_remap;
130 }
131
132 void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) {
133 DCHECK(CalledOnValidThread());
134 if (zygote_) {
135 termination_status_ = zygote_->GetTerminationStatus(
136 process_.Handle(), known_dead, &exit_code_);
137 } else if (known_dead) {
138 termination_status_ =
139 base::GetKnownDeadTerminationStatus(process_.Handle(), &exit_code_);
140 } else {
141 termination_status_ =
142 base::GetTerminationStatus(process_.Handle(), &exit_code_);
143 }
144 }
145
146 // static
147 bool ChildProcessLauncher::TerminateProcess(
148 const base::Process& process, int exit_code, bool wait) {
149 return process.Terminate(exit_code, wait);
150 }
151
152 // static
153 void ChildProcessLauncher::TerminateOnLauncherThread(
154 ZygoteHandle zygote, base::Process process) {
155 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
156 // Client has gone away, so just kill the process. Using exit code 0
157 // means that UMA won't treat this as a crash.
158 process.Terminate(RESULT_CODE_NORMAL_EXIT, false);
159 // On POSIX, we must additionally reap the child.
160 if (zygote) {
161 // If the renderer was created via a zygote, we have to proxy the reaping
162 // through the zygote process.
163 zygote->EnsureProcessTerminated(process.Handle());
164 } else {
165 base::EnsureProcessTerminated(std::move(process));
166 }
167 }
168
169 // static
170 void ChildProcessLauncher::SetProcessBackgroundedOnLauncherThread(
171 base::Process process, bool background) {
172 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
173 if (process.CanBackgroundProcesses())
174 process.SetProcessBackgrounded(background);
175 }
176
177 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698