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

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

Issue 2684433003: Files required by a service now listed in manifest. (Closed)
Patch Set: Fixed analysis. Created 3 years, 10 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 2017 The Chromium Authors. All rights reserved. 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 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 "content/browser/child_process_launcher_helper.h" 5 #include "content/browser/child_process_launcher_helper.h"
6 6
7 #include "base/base_paths.h"
8 #include "base/files/file.h"
9 #include "base/lazy_instance.h"
7 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
11 #include "base/path_service.h"
12 #include "base/posix/global_descriptors.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h"
8 #include "content/browser/child_process_launcher.h" 15 #include "content/browser/child_process_launcher.h"
16 #include "content/public/common/content_descriptors.h"
9 #include "content/public/common/content_switches.h" 17 #include "content/public/common/content_switches.h"
10 #include "content/public/common/sandboxed_process_launcher_delegate.h" 18 #include "content/public/common/sandboxed_process_launcher_delegate.h"
11 #include "mojo/edk/embedder/platform_channel_pair.h" 19 #include "mojo/edk/embedder/platform_channel_pair.h"
12 20
13 namespace content { 21 namespace content {
14 namespace internal { 22 namespace internal {
15 23
16 namespace { 24 namespace {
17 25
26 base::LazyInstance<
27 std::map<std::string, std::unique_ptr<catalog::RequiredFileMap>>>
28 g_required_files_by_service = LAZY_INSTANCE_INITIALIZER;
29
30 base::LazyInstance<std::map<std::string, std::string>>
31 g_process_name_to_service_name = LAZY_INSTANCE_INITIALIZER;
32
33 typedef std::map<base::FilePath,
34 std::pair<base::PlatformFile, base::MemoryMappedFile::Region>>
35 OpenedFileMap;
36 base::LazyInstance<OpenedFileMap> g_opened_files = LAZY_INSTANCE_INITIALIZER;
37
18 void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) { 38 void RecordHistogramsOnLauncherThread(base::TimeDelta launch_time) {
19 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 39 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
20 // Log the launch time, separating out the first one (which will likely be 40 // 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). 41 // slower due to the rest of the browser initializing at the same time).
22 static bool done_first_launch = false; 42 static bool done_first_launch = false;
23 if (done_first_launch) { 43 if (done_first_launch) {
24 UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchSubsequent", launch_time); 44 UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchSubsequent", launch_time);
25 } else { 45 } else {
26 UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchFirst", launch_time); 46 UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchFirst", launch_time);
27 done_first_launch = true; 47 done_first_launch = true;
28 } 48 }
29 } 49 }
30 50
51 base::PlatformFile OpenFileIfNecessary(const base::FilePath& path,
52 base::MemoryMappedFile::Region* region) {
53 const auto& iter = g_opened_files.Get().find(path);
54 if (iter != g_opened_files.Get().end()) {
55 *region = iter->second.second;
56 return iter->second.first;
57 }
58 base::File file = ChildProcessLauncherHelper::OpenFile(path, region);
59 if (!file.IsValid()) {
60 return base::kInvalidPlatformFile;
61 }
62 // g_opened_files becomes the owner of the file descriptor.
63 base::PlatformFile fd = file.TakePlatformFile();
64 g_opened_files.Get()[path] = std::make_pair(fd, *region);
65 return fd;
66 }
67
31 } // namespace 68 } // namespace
32 69
33 ChildProcessLauncherHelper::Process::Process(Process&& other) 70 ChildProcessLauncherHelper::Process::Process(Process&& other)
34 : process(std::move(other.process)) 71 : process(std::move(other.process))
35 #if defined(OS_LINUX) 72 #if defined(OS_LINUX)
36 , zygote(other.zygote) 73 , zygote(other.zygote)
37 #endif 74 #endif
38 { 75 {
39 } 76 }
40 77
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 base::Bind(&ChildProcessLauncherHelper::LaunchOnLauncherThread, this)); 121 base::Bind(&ChildProcessLauncherHelper::LaunchOnLauncherThread, this));
85 } 122 }
86 123
87 void ChildProcessLauncherHelper::LaunchOnLauncherThread() { 124 void ChildProcessLauncherHelper::LaunchOnLauncherThread() {
88 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER); 125 DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
89 126
90 begin_launch_time_ = base::TimeTicks::Now(); 127 begin_launch_time_ = base::TimeTicks::Now();
91 128
92 std::unique_ptr<FileMappedForLaunch> files_to_register = GetFilesToMap(); 129 std::unique_ptr<FileMappedForLaunch> files_to_register = GetFilesToMap();
93 130
131 // Also include the files specified in the services' manifests.
132 const auto& service_name_iter =
133 g_process_name_to_service_name.Get().find(GetProcessType());
134 CHECK(service_name_iter != g_process_name_to_service_name.Get().end());
135 std::string service_name = service_name_iter->second;
136 const auto& files_iter = g_required_files_by_service.Get().find(service_name);
137 if (files_iter != g_required_files_by_service.Get().end()) {
138 catalog::RequiredFileMap* required_files_map = files_iter->second.get();
139 base::GlobalDescriptors::Key key = kContentDynamicDescriptorStart;
140 std::string switch_value;
141 for (const auto& key_path_iter : *required_files_map) {
142 base::MemoryMappedFile::Region region;
143 base::PlatformFile file =
144 OpenFileIfNecessary(base::FilePath(key_path_iter.second), &region);
145 if (file == base::kInvalidPlatformFile) {
146 LOG(ERROR) << "Ignoring invalid file " << key_path_iter.second;
147 continue;
148 }
149 if (!switch_value.empty()) {
150 switch_value += ",";
151 }
152 switch_value += key_path_iter.first;
153 switch_value += ":";
154 switch_value += base::IntToString(key);
155 files_to_register->ShareWithRegion(key, file, region);
156 key++;
157 DCHECK(key < kContentDynamicDescriptorMax);
158 }
159 command_line()->AppendSwitchASCII(switches::kSharedFiles, switch_value);
160 }
161
94 bool is_synchronous_launch = true; 162 bool is_synchronous_launch = true;
95 int launch_result = LAUNCH_RESULT_FAILURE; 163 int launch_result = LAUNCH_RESULT_FAILURE;
96 base::LaunchOptions options; 164 base::LaunchOptions options;
97 BeforeLaunchOnLauncherThread(*files_to_register, &options); 165 BeforeLaunchOnLauncherThread(*files_to_register, &options);
98 166
99 Process process = LaunchProcessOnLauncherThread(options, 167 Process process = LaunchProcessOnLauncherThread(options,
100 std::move(files_to_register), 168 std::move(files_to_register),
101 &is_synchronous_launch, 169 &is_synchronous_launch,
102 &launch_result); 170 &launch_result);
103 171
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 return; 222 return;
155 } 223 }
156 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep! 224 // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep!
157 // So don't do this on the UI/IO threads. 225 // So don't do this on the UI/IO threads.
158 BrowserThread::PostTask( 226 BrowserThread::PostTask(
159 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, 227 BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
160 base::Bind(&ChildProcessLauncherHelper::ForceNormalProcessTerminationSync, 228 base::Bind(&ChildProcessLauncherHelper::ForceNormalProcessTerminationSync,
161 base::Passed(&process))); 229 base::Passed(&process)));
162 } 230 }
163 231
232 // static
233 void ChildProcessLauncherHelper::SetRegisteredFilesForService(
234 const std::string& service_name,
235 std::unique_ptr<catalog::RequiredFileMap> required_files) {
236 if (required_files->empty())
237 return;
238
239 std::map<std::string, std::string>& service_name_resolver =
Ken Rockot(use gerrit already) 2017/02/09 17:17:28 I don't see this being used? Is the |service_name|
Jay Civelli 2017/02/09 22:08:27 It's a bit confusing, I am setting a local var tha
240 g_process_name_to_service_name.Get();
241 if (service_name_resolver.empty()) {
242 // Populate the process name to service name.
Ken Rockot(use gerrit already) 2017/02/09 17:17:28 nit: s/Populate/Translate/? Also maybe add a TODO
Jay Civelli 2017/02/09 22:08:27 Changed to populate map.
243 // The service names are defined in the JSON manifests, so we don't have a
244 // constant accessible for them.
245 service_name_resolver[switches::kRendererProcess] = "content_renderer";
246 service_name_resolver[switches::kGpuProcess] = "content_gpu";
247 service_name_resolver[switches::kPpapiPluginProcess] = "content_plugin";
248 service_name_resolver[switches::kUtilityProcess] = "content_utility";
249 }
250
251 if (!base::StartsWith(service_name, "content",
252 base::CompareCase::INSENSITIVE_ASCII)) {
253 // Not a content child service, ignore.
254 return;
255 }
256
257 DCHECK(g_required_files_by_service.Get().count(service_name) == 0);
258 g_required_files_by_service.Get()[service_name] = std::move(required_files);
259 }
260
164 } // namespace internal 261 } // namespace internal
165 } // namespace content 262 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698