1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/mach_broker_mac.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/command_line.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/mach_ipc_mac.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_util.h" 113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/sys_string_conversions.h" 123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/platform_thread.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_host.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/chrome_switches.h" 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_process_host.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/child_process_info.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricknamespace { 213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Prints a string representation of a Mach error code. 223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstd::string MachErrorCode(kern_return_t err) { 233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return StringPrintf("0x%x %s", err, mach_error_string(err)); 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} // namespace 263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Required because notifications happen on the UI thread. 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass RegisterNotificationTask : public Task { 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RegisterNotificationTask( 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MachBroker* broker) 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : broker_(broker) { } 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch virtual void Run() { 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch broker_->registrar_.Add(broker_, 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::RENDERER_PROCESS_CLOSED, 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::AllSources()); 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch broker_->registrar_.Add(broker_, 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::RENDERER_PROCESS_TERMINATED, 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::AllSources()); 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch broker_->registrar_.Add(broker_, 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::CHILD_PROCESS_CRASHED, 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::AllSources()); 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch broker_->registrar_.Add(broker_, 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::CHILD_PROCESS_HOST_DISCONNECTED, 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::AllSources()); 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch broker_->registrar_.Add(broker_, 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::EXTENSION_PROCESS_TERMINATED, 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::AllSources()); 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MachBroker* broker_; 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DISALLOW_COPY_AND_ASSIGN(RegisterNotificationTask); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 573f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenclass MachListenerThreadDelegate : public base::PlatformThread::Delegate { 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public: 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MachListenerThreadDelegate(MachBroker* broker) : broker_(broker) { 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(broker_); 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string port_name = MachBroker::GetMachPortName(); 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Create the receive port in the constructor, not in ThreadMain(). It is 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // important to create and register the receive port before starting the 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // thread so that child processes will always have someone who's listening. 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick receive_port_.reset(new base::ReceivePort(port_name.c_str())); 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Implement |PlatformThread::Delegate|. 703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void ThreadMain() { 713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::MachReceiveMessage message; 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kern_return_t err; 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick while ((err = receive_port_->WaitForMessage(&message, 743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MACH_MSG_TIMEOUT_NONE)) == 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick KERN_SUCCESS) { 763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // 0 was the secret message id. Reject any messages that don't have it. 773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (message.GetMessageID() != 0) { 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(ERROR) << "Received message with incorrect id: " 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << message.GetMessageID(); 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick continue; 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const task_t child_task = message.GetTranslatedPort(0); 843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (child_task == MACH_PORT_NULL) { 853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(ERROR) << "parent GetTranslatedPort(0) failed."; 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick continue; 873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // It is possible for the child process to die after the call to 903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // |pid_for_task()| but before the call to |FinalizePid()|. To prevent 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // leaking MachBroker map entries in this case, lock around both these 923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // calls. If the child dies, the death notification will be processed 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // after the call to FinalizePid(), ensuring proper cleanup. 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(broker_->GetLock()); 953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int pid; 973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick err = pid_for_task(child_task, &pid); 983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (err == KERN_SUCCESS) { 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick broker_->FinalizePid(pid, 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MachBroker::MachInfo().SetTask(child_task)); 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(ERROR) << "Error getting pid for task " << child_task 1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << ": " << MachErrorCode(err); 1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(ERROR) << "Mach listener thread exiting; " 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << "parent WaitForMessage() likely failed: " 1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << MachErrorCode(err); 1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The Mach port to listen on. Created on thread startup. 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<base::ReceivePort> receive_port_; 1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The MachBroker to use when new child task rights are received. Can be 1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // NULL. 1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MachBroker* broker_; // weak 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DISALLOW_COPY_AND_ASSIGN(MachListenerThreadDelegate); 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the global MachBroker. 12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenMachBroker* MachBroker::GetInstance() { 1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return Singleton<MachBroker, LeakySingletonTraits<MachBroker> >::get(); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickMachBroker::MachBroker() : listener_thread_started_(false) { 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 131dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenMachBroker::~MachBroker() {} 132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MachBroker::PrepareForFork() { 1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!listener_thread_started_) { 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick listener_thread_started_ = true; 1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::UI, FROM_HERE, new RegisterNotificationTask(this)); 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Intentional leak. This thread is never joined or reaped. 1413f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::PlatformThread::CreateNonJoinable( 1423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen 0, new MachListenerThreadDelegate(this)); 1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Adds a placeholder to the map for the given pid with MACH_PORT_NULL. 1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MachBroker::AddPlaceholderForPid(base::ProcessHandle pid) { 1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick lock_.AssertAcquired(); 1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick MachInfo mach_info; 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(0u, mach_map_.count(pid)); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mach_map_[pid] = mach_info; 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Updates the mapping for |pid| to include the given |mach_info|. 1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MachBroker::FinalizePid(base::ProcessHandle pid, 1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const MachInfo& mach_info) { 1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick lock_.AssertAcquired(); 1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const int count = mach_map_.count(pid); 1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (count == 0) { 1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Do nothing for unknown pids. 1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(ERROR) << "Unknown process " << pid << " is sending Mach IPC messages!"; 1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_EQ(1, count); 1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(mach_map_[pid].mach_task_ == MACH_PORT_NULL); 1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (mach_map_[pid].mach_task_ == MACH_PORT_NULL) 1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick mach_map_[pid] = mach_info; 1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Removes all mappings belonging to |pid| from the broker. 1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid MachBroker::InvalidatePid(base::ProcessHandle pid) { 17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MachBroker::MachMap::iterator it = mach_map_.find(pid); 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (it == mach_map_.end()) 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kern_return_t kr = mach_port_deallocate(mach_task_self(), 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch it->second.mach_task_); 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG_IF(WARNING, kr != KERN_SUCCESS) 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch << "Failed to mach_port_deallocate mach task " << it->second.mach_task_ 1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick << ", error " << MachErrorCode(kr); 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch mach_map_.erase(it); 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbase::Lock& MachBroker::GetLock() { 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return lock_; 1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the mach task belonging to |pid|. 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochmach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const { 19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MachBroker::MachMap::const_iterator it = mach_map_.find(pid); 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (it == mach_map_.end()) 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return MACH_PORT_NULL; 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return it->second.mach_task_; 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MachBroker::Observe(NotificationType type, 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationSource& source, 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const NotificationDetails& details) { 2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // TODO(rohitrao): These notifications do not always carry the proper PIDs, 2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // especially when the renderer is already gone or has crashed. Find a better 2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // way to listen for child process deaths. http://crbug.com/55734 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::ProcessHandle handle = 0; 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (type.value) { 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::RENDERER_PROCESS_CLOSED: 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::RENDERER_PROCESS_TERMINATED: 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch handle = Source<RenderProcessHost>(source)->GetHandle(); 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::EXTENSION_PROCESS_TERMINATED: 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch handle = 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<ExtensionHost>(details)->render_process_host()->GetHandle(); 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::CHILD_PROCESS_CRASHED: 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case NotificationType::CHILD_PROCESS_HOST_DISCONNECTED: 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch handle = Details<ChildProcessInfo>(details)->handle(); 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Unexpected notification"; 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 2253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick InvalidatePid(handle); 2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static 2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstd::string MachBroker::GetMachPortName() { 2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static const char kFormatString[] = 2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(GOOGLE_CHROME_BUILD) 2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "com.google.Chrome" 2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#else 2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "org.chromium.Chromium" 2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif 2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ".rohitfork.%d"; 2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const bool is_child = command_line.HasSwitch(switches::kProcessType); 2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // In non-browser (child) processes, use the parent's pid. 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const pid_t pid = is_child ? getppid() : getpid(); 2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return StringPrintf(kFormatString, pid); 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 245