Index: base/mac/mach_port_broker.mm |
diff --git a/content/browser/mach_broker_mac.mm b/base/mac/mach_port_broker.mm |
similarity index 50% |
copy from content/browser/mach_broker_mac.mm |
copy to base/mac/mach_port_broker.mm |
index 4cf3bb6c77c3d2de33c545754cc35eda9f1c98c6..3d563bab0ec73e7c80df732649141a38d851db9e 100644 |
--- a/content/browser/mach_broker_mac.mm |
+++ b/base/mac/mach_port_broker.mm |
@@ -1,34 +1,24 @@ |
-// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "content/browser/mach_broker_mac.h" |
+#include "base/mac/mach_port_broker.h" |
#include <bsm/libbsm.h> |
#include <servers/bootstrap.h> |
-#include "base/bind.h" |
-#include "base/bind_helpers.h" |
-#include "base/command_line.h" |
#include "base/logging.h" |
#include "base/mac/foundation_util.h" |
#include "base/mac/mach_logging.h" |
#include "base/strings/string_util.h" |
#include "base/strings/stringprintf.h" |
-#include "base/strings/sys_string_conversions.h" |
-#include "content/browser/renderer_host/render_process_host_impl.h" |
-#include "content/public/browser/browser_thread.h" |
-#include "content/public/browser/child_process_data.h" |
-#include "content/public/browser/notification_service.h" |
-#include "content/public/browser/notification_types.h" |
-#include "content/public/common/content_switches.h" |
-namespace content { |
+namespace base { |
namespace { |
// Mach message structure used in the child as a sending message. |
-struct MachBroker_ChildSendMsg { |
+struct MachPortBroker_ChildSendMsg { |
mach_msg_header_t header; |
mach_msg_body_t body; |
mach_msg_port_descriptor_t child_task_port; |
@@ -36,18 +26,19 @@ struct MachBroker_ChildSendMsg { |
// Complement to the ChildSendMsg, this is used in the parent for receiving |
// a message. Contains a message trailer with audit information. |
-struct MachBroker_ParentRecvMsg : public MachBroker_ChildSendMsg { |
+struct MachPortBroker_ParentRecvMsg : public MachPortBroker_ChildSendMsg { |
mach_msg_audit_trailer_t trailer; |
}; |
} // namespace |
-bool MachBroker::ChildSendTaskPortToParent() { |
- // Look up the named MachBroker port that's been registered with the |
+// static |
+bool MachPortBroker::ChildSendTaskPortToParent(const std::string& name) { |
+ // Look up the named MachPortBroker port that's been registered with the |
// bootstrap server. |
mach_port_t parent_port; |
kern_return_t kr = bootstrap_look_up(bootstrap_port, |
- const_cast<char*>(GetMachPortName().c_str()), &parent_port); |
+ const_cast<char*>(GetMachPortName(name, true).c_str()), &parent_port); |
if (kr != KERN_SUCCESS) { |
BOOTSTRAP_LOG(ERROR, kr) << "bootstrap_look_up"; |
return false; |
@@ -56,7 +47,7 @@ bool MachBroker::ChildSendTaskPortToParent() { |
// Create the check in message. This will copy a send right on this process' |
// (the child's) task port and send it to the parent. |
- MachBroker_ChildSendMsg msg; |
+ MachPortBroker_ChildSendMsg msg; |
bzero(&msg, sizeof(msg)); |
msg.header.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND) | |
MACH_MSGH_BITS_COMPLEX; |
@@ -77,99 +68,34 @@ bool MachBroker::ChildSendTaskPortToParent() { |
return true; |
} |
-MachBroker* MachBroker::GetInstance() { |
- return base::Singleton<MachBroker, |
- base::LeakySingletonTraits<MachBroker>>::get(); |
-} |
- |
-base::Lock& MachBroker::GetLock() { |
- return lock_; |
-} |
- |
-void MachBroker::EnsureRunning() { |
- lock_.AssertAcquired(); |
- |
- if (initialized_) |
- return; |
- |
- // Do not attempt to reinitialize in the event of failure. |
- initialized_ = true; |
- |
- BrowserThread::PostTask( |
- BrowserThread::UI, FROM_HERE, |
- base::Bind(&MachBroker::RegisterNotifications, base::Unretained(this))); |
- |
- if (!Init()) { |
- LOG(ERROR) << "Failed to initialize the MachListenerThreadDelegate"; |
- } |
-} |
- |
-void MachBroker::AddPlaceholderForPid(base::ProcessHandle pid, |
- int child_process_id) { |
- lock_.AssertAcquired(); |
- |
- DCHECK_EQ(0u, mach_map_.count(pid)); |
- mach_map_[pid] = MACH_PORT_NULL; |
- child_process_id_map_[child_process_id] = pid; |
+// static |
+std::string MachPortBroker::GetMachPortName(const std::string& name, |
+ bool is_child) { |
+ // In child processes, use the parent's pid. |
+ const pid_t pid = is_child ? getppid() : getpid(); |
+ return base::StringPrintf( |
+ "%s.%s.%d", base::mac::BaseBundleID(), name.c_str(), pid); |
} |
-mach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const { |
+mach_port_t MachPortBroker::TaskForPid(base::ProcessHandle pid) const { |
base::AutoLock lock(lock_); |
- MachBroker::MachMap::const_iterator it = mach_map_.find(pid); |
+ MachPortBroker::MachMap::const_iterator it = mach_map_.find(pid); |
if (it == mach_map_.end()) |
return MACH_PORT_NULL; |
return it->second; |
} |
-void MachBroker::BrowserChildProcessHostDisconnected( |
- const ChildProcessData& data) { |
- InvalidateChildProcessId(data.id); |
-} |
- |
-void MachBroker::BrowserChildProcessCrashed(const ChildProcessData& data, |
- int exit_code) { |
- InvalidateChildProcessId(data.id); |
-} |
+MachPortBroker::MachPortBroker(const std::string& name) : name_(name) {} |
-void MachBroker::Observe(int type, |
- const NotificationSource& source, |
- const NotificationDetails& details) { |
- switch (type) { |
- case NOTIFICATION_RENDERER_PROCESS_TERMINATED: |
- case NOTIFICATION_RENDERER_PROCESS_CLOSED: { |
- RenderProcessHost* host = Source<RenderProcessHost>(source).ptr(); |
- InvalidateChildProcessId(host->GetID()); |
- break; |
- } |
- default: |
- NOTREACHED() << "Unexpected notification"; |
- break; |
- } |
-} |
- |
-// static |
-std::string MachBroker::GetMachPortName() { |
- const base::CommandLine* command_line = |
- base::CommandLine::ForCurrentProcess(); |
- const bool is_child = command_line->HasSwitch(switches::kProcessType); |
- |
- // In non-browser (child) processes, use the parent's pid. |
- const pid_t pid = is_child ? getppid() : getpid(); |
- return base::StringPrintf("%s.rohitfork.%d", base::mac::BaseBundleID(), pid); |
-} |
+MachPortBroker::~MachPortBroker() {} |
-MachBroker::MachBroker() : initialized_(false) { |
-} |
- |
-MachBroker::~MachBroker() {} |
- |
-bool MachBroker::Init() { |
+bool MachPortBroker::Init() { |
DCHECK(server_port_.get() == MACH_PORT_NULL); |
// Check in with launchd and publish the service name. |
mach_port_t port; |
- kern_return_t kr = |
- bootstrap_check_in(bootstrap_port, GetMachPortName().c_str(), &port); |
+ kern_return_t kr = bootstrap_check_in( |
+ bootstrap_port, GetMachPortName(name_, false).c_str(), &port); |
if (kr != KERN_SUCCESS) { |
BOOTSTRAP_LOG(ERROR, kr) << "bootstrap_check_in"; |
return false; |
@@ -178,7 +104,7 @@ bool MachBroker::Init() { |
// Start the dispatch source. |
std::string queue_name = |
- base::StringPrintf("%s.MachBroker", base::mac::BaseBundleID()); |
+ base::StringPrintf("%s.MachPortBroker", base::mac::BaseBundleID()); |
dispatch_source_.reset(new base::DispatchSourceMach( |
queue_name.c_str(), server_port_.get(), ^{ HandleRequest(); })); |
dispatch_source_->Resume(); |
@@ -186,8 +112,25 @@ bool MachBroker::Init() { |
return true; |
} |
-void MachBroker::HandleRequest() { |
- MachBroker_ParentRecvMsg msg; |
+void MachPortBroker::AddPlaceholderForPid(base::ProcessHandle pid) { |
+ lock_.AssertAcquired(); |
+ DCHECK_EQ(0u, mach_map_.count(pid)); |
+ mach_map_[pid] = MACH_PORT_NULL; |
+} |
+ |
+void MachPortBroker::InvalidatePid(base::ProcessHandle pid) { |
+ lock_.AssertAcquired(); |
+ |
+ MachMap::iterator mach_it = mach_map_.find(pid); |
+ if (mach_it != mach_map_.end()) { |
+ kern_return_t kr = mach_port_deallocate(mach_task_self(), mach_it->second); |
+ MACH_LOG_IF(WARNING, kr != KERN_SUCCESS, kr) << "mach_port_deallocate"; |
+ mach_map_.erase(mach_it); |
+ } |
+} |
+ |
+void MachPortBroker::HandleRequest() { |
+ MachPortBroker_ParentRecvMsg msg; |
bzero(&msg, sizeof(msg)); |
msg.header.msgh_size = sizeof(msg); |
msg.header.msgh_local_port = server_port_.get(); |
@@ -220,12 +163,12 @@ void MachBroker::HandleRequest() { |
mach_port_t child_task_port = msg.child_task_port.name; |
// Take the lock and update the broker information. |
- base::AutoLock lock(GetLock()); |
+ base::AutoLock lock(lock_); |
FinalizePid(child_pid, child_task_port); |
} |
-void MachBroker::FinalizePid(base::ProcessHandle pid, |
- mach_port_t task_port) { |
+void MachPortBroker::FinalizePid(base::ProcessHandle pid, |
+ mach_port_t task_port) { |
lock_.AssertAcquired(); |
MachMap::iterator it = mach_map_.find(pid); |
@@ -240,32 +183,4 @@ void MachBroker::FinalizePid(base::ProcessHandle pid, |
it->second = task_port; |
} |
-void MachBroker::InvalidateChildProcessId(int child_process_id) { |
- base::AutoLock lock(lock_); |
- MachBroker::ChildProcessIdMap::iterator it = |
- child_process_id_map_.find(child_process_id); |
- if (it == child_process_id_map_.end()) |
- return; |
- |
- MachMap::iterator mach_it = mach_map_.find(it->second); |
- if (mach_it != mach_map_.end()) { |
- kern_return_t kr = mach_port_deallocate(mach_task_self(), |
- mach_it->second); |
- MACH_LOG_IF(WARNING, kr != KERN_SUCCESS, kr) << "mach_port_deallocate"; |
- mach_map_.erase(mach_it); |
- } |
- child_process_id_map_.erase(it); |
-} |
- |
-void MachBroker::RegisterNotifications() { |
- registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSED, |
- NotificationService::AllBrowserContextsAndSources()); |
- registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
- NotificationService::AllBrowserContextsAndSources()); |
- |
- // No corresponding StopObservingBrowserChildProcesses, |
- // we leak this singleton. |
- BrowserChildProcessObserver::Add(this); |
-} |
- |
-} // namespace content |
+} // namespace base |