Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/mach_broker_mac.h" | 5 #include "chrome/browser/mach_broker_mac.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "chrome/browser/extensions/extension_host.h" | |
| 9 #include "chrome/browser/renderer_host/render_process_host.h" | |
| 10 #include "chrome/common/child_process_info.h" | |
| 11 #include "chrome/common/notification_service.h" | |
| 12 | |
| 13 MachBroker::MachBroker() { | |
| 14 CHECK(NotificationService::current() != NULL) | |
|
Mark Mentovai
2010/01/11 20:22:46
CHECK_NE?
| |
| 15 << "Called too early / on wrong thread"; | |
| 16 registrar_.Add(this, | |
| 17 NotificationType::RENDERER_PROCESS_CLOSED, | |
| 18 NotificationService::AllSources()); | |
| 19 registrar_.Add(this, | |
| 20 NotificationType::RENDERER_PROCESS_TERMINATED, | |
| 21 NotificationService::AllSources()); | |
| 22 registrar_.Add(this, | |
| 23 NotificationType::CHILD_PROCESS_CRASHED, | |
| 24 NotificationService::AllSources()); | |
| 25 registrar_.Add(this, | |
| 26 NotificationType::CHILD_PROCESS_HOST_DISCONNECTED, | |
| 27 NotificationService::AllSources()); | |
| 28 registrar_.Add(this, | |
| 29 NotificationType::EXTENSION_PROCESS_TERMINATED, | |
| 30 NotificationService::AllSources()); | |
| 31 } | |
| 8 | 32 |
| 9 // Returns the global MachBroker. | 33 // Returns the global MachBroker. |
| 10 MachBroker* MachBroker::instance() { | 34 MachBroker* MachBroker::instance() { |
| 11 return Singleton<MachBroker>::get(); | 35 return Singleton<MachBroker>::get(); |
| 12 } | 36 } |
| 13 | 37 |
| 14 // Adds mach info for a given pid. | 38 // Adds mach info for a given pid. |
| 15 void MachBroker::RegisterPid( | 39 void MachBroker::RegisterPid( |
| 16 base::ProcessHandle pid, const MachInfo& mach_info) { | 40 base::ProcessHandle pid, const MachInfo& mach_info) { |
| 17 AutoLock lock(lock_); | 41 AutoLock lock(lock_); |
| 18 DCHECK_EQ(0u, mach_map_.count(pid)); | 42 DCHECK_EQ(0u, mach_map_.count(pid)); |
| 19 mach_map_[pid] = mach_info; | 43 mach_map_[pid] = mach_info; |
| 20 } | 44 } |
| 21 | 45 |
| 22 // Removes all mappings belonging to |pid| from the broker. | 46 // Removes all mappings belonging to |pid| from the broker. |
| 23 void MachBroker::Invalidate(base::ProcessHandle pid) { | 47 void MachBroker::Invalidate(base::ProcessHandle pid) { |
| 48 fprintf(stderr, "invalidating pid %d\n", (int)pid); | |
|
Mark Mentovai
2010/01/11 20:22:46
Turdlet!
| |
| 49 | |
| 24 AutoLock lock(lock_); | 50 AutoLock lock(lock_); |
| 25 mach_map_.erase(pid); | 51 MachBroker::MachMap::iterator it = mach_map_.find(pid); |
| 52 if (it == mach_map_.end()) | |
| 53 return; | |
| 54 | |
| 55 kern_return_t kr = mach_port_deallocate(mach_task_self(), | |
| 56 it->second.mach_task_); | |
| 57 if (kr != KERN_SUCCESS) { | |
| 58 LOG(WARNING) << "Failed to deallocate mach task " << it->second.mach_task_ | |
|
Mark Mentovai
2010/01/11 20:22:46
This can be a LOG_IF.
| |
| 59 << ", error " << kr; | |
| 60 } | |
| 61 mach_map_.erase(it); | |
| 26 } | 62 } |
| 27 | 63 |
| 28 // Returns the mach task belonging to |pid|. | 64 // Returns the mach task belonging to |pid|. |
| 29 mach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const { | 65 mach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const { |
| 30 AutoLock lock(lock_); | 66 AutoLock lock(lock_); |
| 31 MachBroker::MachMap::const_iterator it = mach_map_.find(pid); | 67 MachBroker::MachMap::const_iterator it = mach_map_.find(pid); |
| 32 if (it == mach_map_.end()) | 68 if (it == mach_map_.end()) |
| 33 return MACH_PORT_NULL; | 69 return MACH_PORT_NULL; |
| 34 return it->second.mach_task_; | 70 return it->second.mach_task_; |
| 35 } | 71 } |
| 72 | |
| 73 // TODO(thakis): unittest | |
| 74 void MachBroker::Observe(NotificationType type, | |
| 75 const NotificationSource& source, | |
| 76 const NotificationDetails& details) { | |
| 77 base::ProcessHandle handle = 0; | |
| 78 switch (type.value) { | |
| 79 case NotificationType::RENDERER_PROCESS_CLOSED: | |
| 80 case NotificationType::RENDERER_PROCESS_TERMINATED: | |
| 81 handle = Source<RenderProcessHost>(source)->GetHandle(); | |
| 82 break; | |
| 83 case NotificationType::EXTENSION_PROCESS_TERMINATED: | |
| 84 handle = | |
| 85 Details<ExtensionHost>(details)->render_process_host()->GetHandle(); | |
| 86 break; | |
| 87 case NotificationType::CHILD_PROCESS_CRASHED: | |
| 88 case NotificationType::CHILD_PROCESS_HOST_DISCONNECTED: | |
| 89 handle = Details<ChildProcessInfo>(details)->handle(); | |
| 90 break; | |
| 91 default: | |
| 92 NOTREACHED() << "Unexpected notification"; | |
| 93 break; | |
| 94 } | |
| 95 Invalidate(handle); | |
|
Mark Mentovai
2010/01/11 20:22:46
If handle is 0, you know you don't need to waste t
| |
| 96 } | |
| OLD | NEW |