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

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

Issue 2224063002: Use persistent memory for receiving metrics from sub-processes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 4 years, 4 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/browser_child_process_host_impl.h" 5 #include "content/browser/browser_child_process_host_impl.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/debug/dump_without_crashing.h" 10 #include "base/debug/dump_without_crashing.h"
11 #include "base/feature_list.h" 11 #include "base/feature_list.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/metrics/field_trial.h" 16 #include "base/metrics/field_trial.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/metrics/persistent_histogram_allocator.h"
19 #include "base/metrics/persistent_memory_allocator.h"
18 #include "base/stl_util.h" 20 #include "base/stl_util.h"
19 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
20 #include "base/synchronization/waitable_event.h" 22 #include "base/synchronization/waitable_event.h"
21 #include "base/threading/thread_task_runner_handle.h" 23 #include "base/threading/thread_task_runner_handle.h"
22 #include "build/build_config.h" 24 #include "build/build_config.h"
23 #include "components/tracing/common/tracing_switches.h" 25 #include "components/tracing/common/tracing_switches.h"
24 #include "content/browser/histogram_message_filter.h" 26 #include "content/browser/histogram_message_filter.h"
25 #include "content/browser/loader/resource_message_filter.h" 27 #include "content/browser/loader/resource_message_filter.h"
26 #include "content/browser/memory/memory_message_filter.h" 28 #include "content/browser/memory/memory_message_filter.h"
27 #include "content/browser/profiler_message_filter.h" 29 #include "content/browser/profiler_message_filter.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(), 79 FOR_EACH_OBSERVER(BrowserChildProcessObserver, g_observers.Get(),
78 BrowserChildProcessKilled(data, exit_code)); 80 BrowserChildProcessKilled(data, exit_code));
79 } 81 }
80 82
81 } // namespace 83 } // namespace
82 84
83 BrowserChildProcessHost* BrowserChildProcessHost::Create( 85 BrowserChildProcessHost* BrowserChildProcessHost::Create(
84 content::ProcessType process_type, 86 content::ProcessType process_type,
85 BrowserChildProcessHostDelegate* delegate) { 87 BrowserChildProcessHostDelegate* delegate) {
86 return new BrowserChildProcessHostImpl( 88 return new BrowserChildProcessHostImpl(
87 process_type, delegate, mojo::edk::GenerateRandomToken()); 89 process_type, delegate, mojo::edk::GenerateRandomToken(), 0, nullptr);
88 } 90 }
89 91
90 BrowserChildProcessHost* BrowserChildProcessHost::Create( 92 BrowserChildProcessHost* BrowserChildProcessHost::Create(
91 content::ProcessType process_type, 93 content::ProcessType process_type,
92 BrowserChildProcessHostDelegate* delegate, 94 BrowserChildProcessHostDelegate* delegate,
93 const std::string& mojo_child_token) { 95 const std::string& mojo_child_token) {
94 return new BrowserChildProcessHostImpl( 96 return new BrowserChildProcessHostImpl(process_type, delegate,
95 process_type, delegate, mojo_child_token); 97 mojo_child_token, 0, nullptr);
96 } 98 }
97 99
98 BrowserChildProcessHost* BrowserChildProcessHost::FromID(int child_process_id) { 100 BrowserChildProcessHost* BrowserChildProcessHost::FromID(int child_process_id) {
99 DCHECK_CURRENTLY_ON(BrowserThread::IO); 101 DCHECK_CURRENTLY_ON(BrowserThread::IO);
100 BrowserChildProcessHostImpl::BrowserChildProcessList* process_list = 102 BrowserChildProcessHostImpl::BrowserChildProcessList* process_list =
101 g_child_process_list.Pointer(); 103 g_child_process_list.Pointer();
102 for (BrowserChildProcessHostImpl* host : *process_list) { 104 for (BrowserChildProcessHostImpl* host : *process_list) {
103 if (host->GetData().id == child_process_id) 105 if (host->GetData().id == child_process_id)
104 return host; 106 return host;
105 } 107 }
(...skipping 22 matching lines...) Expand all
128 // static 130 // static
129 void BrowserChildProcessHostImpl::RemoveObserver( 131 void BrowserChildProcessHostImpl::RemoveObserver(
130 BrowserChildProcessObserver* observer) { 132 BrowserChildProcessObserver* observer) {
131 // TODO(phajdan.jr): Check thread after fixing http://crbug.com/167126. 133 // TODO(phajdan.jr): Check thread after fixing http://crbug.com/167126.
132 g_observers.Get().RemoveObserver(observer); 134 g_observers.Get().RemoveObserver(observer);
133 } 135 }
134 136
135 BrowserChildProcessHostImpl::BrowserChildProcessHostImpl( 137 BrowserChildProcessHostImpl::BrowserChildProcessHostImpl(
136 content::ProcessType process_type, 138 content::ProcessType process_type,
137 BrowserChildProcessHostDelegate* delegate, 139 BrowserChildProcessHostDelegate* delegate,
138 const std::string& mojo_child_token) 140 const std::string& mojo_child_token,
141 size_t shared_metrics_memory_size,
142 base::StringPiece shared_metrics_name)
139 : data_(process_type), 143 : data_(process_type),
140 delegate_(delegate), 144 delegate_(delegate),
141 mojo_child_token_(mojo_child_token), 145 mojo_child_token_(mojo_child_token),
142 power_monitor_message_broadcaster_(this), 146 power_monitor_message_broadcaster_(this),
143 is_channel_connected_(false), 147 is_channel_connected_(false),
144 notify_child_disconnected_(false), 148 notify_child_disconnected_(false),
145 weak_factory_(this) { 149 weak_factory_(this) {
146 data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId(); 150 data_.id = ChildProcessHostImpl::GenerateChildProcessUniqueId();
147 151
148 #if USE_ATTACHMENT_BROKER 152 #if USE_ATTACHMENT_BROKER
(...skipping 12 matching lines...) Expand all
161 child_process_host_.reset(ChildProcessHost::Create(this)); 165 child_process_host_.reset(ChildProcessHost::Create(this));
162 AddFilter(new TraceMessageFilter(data_.id)); 166 AddFilter(new TraceMessageFilter(data_.id));
163 AddFilter(new ProfilerMessageFilter(process_type)); 167 AddFilter(new ProfilerMessageFilter(process_type));
164 AddFilter(new HistogramMessageFilter); 168 AddFilter(new HistogramMessageFilter);
165 AddFilter(new MemoryMessageFilter(this, process_type)); 169 AddFilter(new MemoryMessageFilter(this, process_type));
166 170
167 g_child_process_list.Get().push_back(this); 171 g_child_process_list.Get().push_back(this);
168 GetContentClient()->browser()->BrowserChildProcessHostCreated(this); 172 GetContentClient()->browser()->BrowserChildProcessHostCreated(this);
169 173
170 power_monitor_message_broadcaster_.Init(); 174 power_monitor_message_broadcaster_.Init();
175
176 // Create a persistent memory segment for subprocess histograms only if
177 // they're active in the browser.
178 if (shared_metrics_memory_size > 0 && base::GlobalHistogramAllocator::Get()) {
179 std::unique_ptr<base::SharedMemory> shm(new base::SharedMemory());
180 shm->CreateAndMapAnonymous(shared_metrics_memory_size);
181 metrics_allocator_.reset(new base::SharedPersistentMemoryAllocator(
182 std::move(shm), static_cast<uint64_t>(data_.id), shared_metrics_name,
183 /*readonly=*/false));
Alexei Svitkine (slow) 2016/08/12 23:14:36 I think it would be better to just have the the Br
bcwhite 2016/08/15 19:43:10 I don't think that would be good. That would forc
Alexei Svitkine (slow) 2016/08/18 07:21:19 The callers wouldn't need to know the persistent c
bcwhite 2016/08/18 15:21:55 This class knows about creating shared memory beca
Alexei Svitkine (slow) 2016/08/18 15:57:28 Let me step back a bit. The concrete things I'm no
bcwhite 2016/08/18 17:42:17 It cares about the shared memory details but that'
Alexei Svitkine (slow) 2016/08/19 15:10:51 I see your point. I still don't like that this cla
bcwhite 2016/08/19 15:55:21 Eventually that will be removed, but it's used her
bcwhite 2016/08/19 15:55:21 New separate method for creating the allocator tha
184 }
171 } 185 }
172 186
173 BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() { 187 BrowserChildProcessHostImpl::~BrowserChildProcessHostImpl() {
174 g_child_process_list.Get().remove(this); 188 g_child_process_list.Get().remove(this);
175 189
176 if (notify_child_disconnected_) { 190 if (notify_child_disconnected_) {
177 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 191 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
178 base::Bind(&NotifyProcessHostDisconnected, data_)); 192 base::Bind(&NotifyProcessHostDisconnected, data_));
179 } 193 }
180 } 194 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 275
262 const base::Process& BrowserChildProcessHostImpl::GetProcess() const { 276 const base::Process& BrowserChildProcessHostImpl::GetProcess() const {
263 DCHECK_CURRENTLY_ON(BrowserThread::IO); 277 DCHECK_CURRENTLY_ON(BrowserThread::IO);
264 DCHECK(child_process_.get()) 278 DCHECK(child_process_.get())
265 << "Requesting a child process handle before launching."; 279 << "Requesting a child process handle before launching.";
266 DCHECK(child_process_->GetProcess().IsValid()) 280 DCHECK(child_process_->GetProcess().IsValid())
267 << "Requesting a child process handle before launch has completed OK."; 281 << "Requesting a child process handle before launch has completed OK.";
268 return child_process_->GetProcess(); 282 return child_process_->GetProcess();
269 } 283 }
270 284
285 std::unique_ptr<base::SharedPersistentMemoryAllocator>
286 BrowserChildProcessHostImpl::TakeMetricsAllocator() {
287 return std::move(metrics_allocator_);
288 }
289
271 void BrowserChildProcessHostImpl::SetName(const base::string16& name) { 290 void BrowserChildProcessHostImpl::SetName(const base::string16& name) {
272 DCHECK_CURRENTLY_ON(BrowserThread::IO); 291 DCHECK_CURRENTLY_ON(BrowserThread::IO);
273 data_.name = name; 292 data_.name = name;
274 } 293 }
275 294
276 void BrowserChildProcessHostImpl::SetHandle(base::ProcessHandle handle) { 295 void BrowserChildProcessHostImpl::SetHandle(base::ProcessHandle handle) {
277 DCHECK_CURRENTLY_ON(BrowserThread::IO); 296 DCHECK_CURRENTLY_ON(BrowserThread::IO);
278 data_.handle = handle; 297 data_.handle = handle;
279 } 298 }
280 299
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 // error on the IPC channel. 347 // error on the IPC channel.
329 early_exit_watcher_.StopWatching(); 348 early_exit_watcher_.StopWatching();
330 #endif 349 #endif
331 350
332 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 351 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
333 base::Bind(&NotifyProcessHostConnected, data_)); 352 base::Bind(&NotifyProcessHostConnected, data_));
334 353
335 delegate_->OnChannelConnected(peer_pid); 354 delegate_->OnChannelConnected(peer_pid);
336 355
337 if (IsProcessLaunched()) { 356 if (IsProcessLaunched()) {
357 ShareMetricsAllocatorToProcess();
338 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 358 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
339 base::Bind(&NotifyProcessLaunchedAndConnected, 359 base::Bind(&NotifyProcessLaunchedAndConnected,
340 data_)); 360 data_));
341 } 361 }
342 } 362 }
343 363
344 void BrowserChildProcessHostImpl::OnChannelError() { 364 void BrowserChildProcessHostImpl::OnChannelError() {
345 delegate_->OnChannelError(); 365 delegate_->OnChannelError();
346 } 366 }
347 367
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 } 449 }
430 #endif 450 #endif
431 } 451 }
432 delete delegate_; // Will delete us 452 delete delegate_; // Will delete us
433 } 453 }
434 454
435 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) { 455 bool BrowserChildProcessHostImpl::Send(IPC::Message* message) {
436 return child_process_host_->Send(message); 456 return child_process_host_->Send(message);
437 } 457 }
438 458
459 void BrowserChildProcessHostImpl::ShareMetricsAllocatorToProcess() {
460 if (metrics_allocator_) {
461 base::SharedMemoryHandle shm_handle;
462 metrics_allocator_->shared_memory()->ShareToProcess(data_.handle,
463 &shm_handle);
464 Send(new ChildProcessMsg_SetHistogramMemory(
465 shm_handle, metrics_allocator_->shared_memory()->mapped_size()));
466 }
467 }
468
439 void BrowserChildProcessHostImpl::OnProcessLaunchFailed(int error_code) { 469 void BrowserChildProcessHostImpl::OnProcessLaunchFailed(int error_code) {
440 delegate_->OnProcessLaunchFailed(error_code); 470 delegate_->OnProcessLaunchFailed(error_code);
441 notify_child_disconnected_ = false; 471 notify_child_disconnected_ = false;
442 delete delegate_; // Will delete us 472 delete delegate_; // Will delete us
443 } 473 }
444 474
445 void BrowserChildProcessHostImpl::OnProcessLaunched() { 475 void BrowserChildProcessHostImpl::OnProcessLaunched() {
446 DCHECK_CURRENTLY_ON(BrowserThread::IO); 476 DCHECK_CURRENTLY_ON(BrowserThread::IO);
447 477
448 const base::Process& process = child_process_->GetProcess(); 478 const base::Process& process = child_process_->GetProcess();
449 DCHECK(process.IsValid()); 479 DCHECK(process.IsValid());
450 480
451 #if defined(OS_WIN) 481 #if defined(OS_WIN)
452 // Start a WaitableEventWatcher that will invoke OnProcessExitedEarly if the 482 // Start a WaitableEventWatcher that will invoke OnProcessExitedEarly if the
453 // child process exits. This watcher is stopped once the IPC channel is 483 // child process exits. This watcher is stopped once the IPC channel is
454 // connected and the exit of the child process is detecter by an error on the 484 // connected and the exit of the child process is detecter by an error on the
455 // IPC channel thereafter. 485 // IPC channel thereafter.
456 DCHECK(!early_exit_watcher_.GetWatchedObject()); 486 DCHECK(!early_exit_watcher_.GetWatchedObject());
457 early_exit_watcher_.StartWatchingOnce(process.Handle(), this); 487 early_exit_watcher_.StartWatchingOnce(process.Handle(), this);
458 #endif 488 #endif
459 489
460 // TODO(rvargas) crbug.com/417532: Don't store a handle. 490 // TODO(rvargas) crbug.com/417532: Don't store a handle.
461 data_.handle = process.Handle(); 491 data_.handle = process.Handle();
462 delegate_->OnProcessLaunched(); 492 delegate_->OnProcessLaunched();
463 493
464 if (is_channel_connected_) { 494 if (is_channel_connected_) {
495 ShareMetricsAllocatorToProcess();
465 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 496 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
466 base::Bind(&NotifyProcessLaunchedAndConnected, 497 base::Bind(&NotifyProcessLaunchedAndConnected,
467 data_)); 498 data_));
468 } 499 }
469 } 500 }
470 501
471 bool BrowserChildProcessHostImpl::IsProcessLaunched() const { 502 bool BrowserChildProcessHostImpl::IsProcessLaunched() const {
472 DCHECK_CURRENTLY_ON(BrowserThread::IO); 503 DCHECK_CURRENTLY_ON(BrowserThread::IO);
473 504
474 return child_process_.get() && child_process_->GetProcess().IsValid(); 505 return child_process_.get() && child_process_->GetProcess().IsValid();
(...skipping 28 matching lines...) Expand all
503 534
504 #if defined(OS_WIN) 535 #if defined(OS_WIN)
505 536
506 void BrowserChildProcessHostImpl::OnObjectSignaled(HANDLE object) { 537 void BrowserChildProcessHostImpl::OnObjectSignaled(HANDLE object) {
507 OnChildDisconnected(); 538 OnChildDisconnected();
508 } 539 }
509 540
510 #endif 541 #endif
511 542
512 } // namespace content 543 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698