blob: dfbf71f600b64f0d3d883d1bfba690c2d426f285 [file] [log] [blame]
[email protected]3c2119d2013-04-11 14:27:281// Copyright (c) 2011 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/mach_broker_mac.h"
6
[email protected]3c2119d2013-04-11 14:27:287#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/command_line.h"
10#include "base/logging.h"
[email protected]3c2119d2013-04-11 14:27:2811#include "content/browser/renderer_host/render_process_host_impl.h"
[email protected]3c2119d2013-04-11 14:27:2812#include "content/public/browser/browser_thread.h"
[email protected]348fbaac2013-06-11 06:31:5113#include "content/public/browser/child_process_data.h"
[email protected]3c2119d2013-04-11 14:27:2814#include "content/public/browser/notification_service.h"
15#include "content/public/browser/notification_types.h"
16#include "content/public/common/content_switches.h"
17
18namespace content {
19
20namespace {
amistry11ca9a52016-03-04 02:04:4921const char kBootstrapName[] = "rohitfork";
22}
[email protected]3c2119d2013-04-11 14:27:2823
amistry11ca9a52016-03-04 02:04:4924// static
[email protected]3c2119d2013-04-11 14:27:2825bool MachBroker::ChildSendTaskPortToParent() {
amistry11ca9a52016-03-04 02:04:4926 return base::MachPortBroker::ChildSendTaskPortToParent(kBootstrapName);
[email protected]3c2119d2013-04-11 14:27:2827}
28
29MachBroker* MachBroker::GetInstance() {
olli.raula36aa8be2015-09-10 11:14:2230 return base::Singleton<MachBroker,
31 base::LeakySingletonTraits<MachBroker>>::get();
[email protected]3c2119d2013-04-11 14:27:2832}
33
34base::Lock& MachBroker::GetLock() {
amistry11ca9a52016-03-04 02:04:4935 return broker_.GetLock();
[email protected]3c2119d2013-04-11 14:27:2836}
37
38void MachBroker::EnsureRunning() {
amistry11ca9a52016-03-04 02:04:4939 GetLock().AssertAcquired();
[email protected]3c2119d2013-04-11 14:27:2840
rsesekca5b918a2015-05-14 00:01:1541 if (initialized_)
42 return;
[email protected]3c2119d2013-04-11 14:27:2843
rsesekca5b918a2015-05-14 00:01:1544 // Do not attempt to reinitialize in the event of failure.
45 initialized_ = true;
[email protected]3c2119d2013-04-11 14:27:2846
rsesekca5b918a2015-05-14 00:01:1547 BrowserThread::PostTask(
48 BrowserThread::UI, FROM_HERE,
49 base::Bind(&MachBroker::RegisterNotifications, base::Unretained(this)));
50
amistry11ca9a52016-03-04 02:04:4951 if (!broker_.Init()) {
rsesekca5b918a2015-05-14 00:01:1552 LOG(ERROR) << "Failed to initialize the MachListenerThreadDelegate";
[email protected]3c2119d2013-04-11 14:27:2853 }
54}
55
sramajay52ac072b2014-12-02 17:18:3556void MachBroker::AddPlaceholderForPid(base::ProcessHandle pid,
57 int child_process_id) {
amistry11ca9a52016-03-04 02:04:4958 GetLock().AssertAcquired();
[email protected]3c2119d2013-04-11 14:27:2859
amistry11ca9a52016-03-04 02:04:4960 broker_.AddPlaceholderForPid(pid);
sramajay52ac072b2014-12-02 17:18:3561 child_process_id_map_[child_process_id] = pid;
[email protected]3c2119d2013-04-11 14:27:2862}
63
64mach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const {
amistry11ca9a52016-03-04 02:04:4965 return broker_.TaskForPid(pid);
[email protected]3c2119d2013-04-11 14:27:2866}
67
68void MachBroker::BrowserChildProcessHostDisconnected(
69 const ChildProcessData& data) {
sramajay52ac072b2014-12-02 17:18:3570 InvalidateChildProcessId(data.id);
[email protected]3c2119d2013-04-11 14:27:2871}
72
wfh22e2f4a22015-04-28 22:39:2173void MachBroker::BrowserChildProcessCrashed(const ChildProcessData& data,
74 int exit_code) {
sramajay52ac072b2014-12-02 17:18:3575 InvalidateChildProcessId(data.id);
[email protected]3c2119d2013-04-11 14:27:2876}
77
78void MachBroker::Observe(int type,
79 const NotificationSource& source,
80 const NotificationDetails& details) {
[email protected]3c2119d2013-04-11 14:27:2881 switch (type) {
[email protected]3c2119d2013-04-11 14:27:2882 case NOTIFICATION_RENDERER_PROCESS_TERMINATED:
sramajay52ac072b2014-12-02 17:18:3583 case NOTIFICATION_RENDERER_PROCESS_CLOSED: {
84 RenderProcessHost* host = Source<RenderProcessHost>(source).ptr();
85 InvalidateChildProcessId(host->GetID());
[email protected]3c2119d2013-04-11 14:27:2886 break;
sramajay52ac072b2014-12-02 17:18:3587 }
[email protected]3c2119d2013-04-11 14:27:2888 default:
89 NOTREACHED() << "Unexpected notification";
90 break;
91 }
[email protected]3c2119d2013-04-11 14:27:2892}
93
rsesekdba84112015-09-18 19:22:0794// static
95std::string MachBroker::GetMachPortName() {
96 const base::CommandLine* command_line =
97 base::CommandLine::ForCurrentProcess();
98 const bool is_child = command_line->HasSwitch(switches::kProcessType);
amistry11ca9a52016-03-04 02:04:4999 return base::MachPortBroker::GetMachPortName(kBootstrapName, is_child);
rsesekdba84112015-09-18 19:22:07100}
101
amistrydb2273152016-03-10 23:45:40102MachBroker::MachBroker() : initialized_(false), broker_(kBootstrapName) {
103 broker_.AddObserver(this);
104}
[email protected]3c2119d2013-04-11 14:27:28105
amistrydb2273152016-03-10 23:45:40106MachBroker::~MachBroker() {
107 broker_.RemoveObserver(this);
108}
109
110void MachBroker::OnReceivedTaskPort(base::ProcessHandle process) {
111 NotifyObservers(process);
112}
[email protected]3c2119d2013-04-11 14:27:28113
sramajay52ac072b2014-12-02 17:18:35114void MachBroker::InvalidateChildProcessId(int child_process_id) {
amistry11ca9a52016-03-04 02:04:49115 base::AutoLock lock(GetLock());
sramajay52ac072b2014-12-02 17:18:35116 MachBroker::ChildProcessIdMap::iterator it =
117 child_process_id_map_.find(child_process_id);
118 if (it == child_process_id_map_.end())
[email protected]3c2119d2013-04-11 14:27:28119 return;
120
amistry11ca9a52016-03-04 02:04:49121 broker_.InvalidatePid(it->second);
sramajay52ac072b2014-12-02 17:18:35122 child_process_id_map_.erase(it);
[email protected]3c2119d2013-04-11 14:27:28123}
124
[email protected]3c2119d2013-04-11 14:27:28125void MachBroker::RegisterNotifications() {
126 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSED,
127 NotificationService::AllBrowserContextsAndSources());
128 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED,
129 NotificationService::AllBrowserContextsAndSources());
130
131 // No corresponding StopObservingBrowserChildProcesses,
132 // we leak this singleton.
133 BrowserChildProcessObserver::Add(this);
134}
135
136} // namespace content