Index: chrome/browser/mach_broker_mac.cc |
diff --git a/chrome/browser/mach_broker_mac.cc b/chrome/browser/mach_broker_mac.cc |
index 59f77282234969846948cac52df23c0b7a8b449b..f9e52540c5065adbc0c4a78e360dfada7f239399 100644 |
--- a/chrome/browser/mach_broker_mac.cc |
+++ b/chrome/browser/mach_broker_mac.cc |
@@ -5,6 +5,30 @@ |
#include "chrome/browser/mach_broker_mac.h" |
#include "base/logging.h" |
+#include "chrome/browser/extensions/extension_host.h" |
+#include "chrome/browser/renderer_host/render_process_host.h" |
+#include "chrome/common/child_process_info.h" |
+#include "chrome/common/notification_service.h" |
+ |
+MachBroker::MachBroker() { |
+ CHECK(NotificationService::current() != NULL) |
Mark Mentovai
2010/01/11 20:22:46
CHECK_NE?
|
+ << "Called too early / on wrong thread"; |
+ registrar_.Add(this, |
+ NotificationType::RENDERER_PROCESS_CLOSED, |
+ NotificationService::AllSources()); |
+ registrar_.Add(this, |
+ NotificationType::RENDERER_PROCESS_TERMINATED, |
+ NotificationService::AllSources()); |
+ registrar_.Add(this, |
+ NotificationType::CHILD_PROCESS_CRASHED, |
+ NotificationService::AllSources()); |
+ registrar_.Add(this, |
+ NotificationType::CHILD_PROCESS_HOST_DISCONNECTED, |
+ NotificationService::AllSources()); |
+ registrar_.Add(this, |
+ NotificationType::EXTENSION_PROCESS_TERMINATED, |
+ NotificationService::AllSources()); |
+} |
// Returns the global MachBroker. |
MachBroker* MachBroker::instance() { |
@@ -21,8 +45,20 @@ void MachBroker::RegisterPid( |
// Removes all mappings belonging to |pid| from the broker. |
void MachBroker::Invalidate(base::ProcessHandle pid) { |
+fprintf(stderr, "invalidating pid %d\n", (int)pid); |
Mark Mentovai
2010/01/11 20:22:46
Turdlet!
|
+ |
AutoLock lock(lock_); |
- mach_map_.erase(pid); |
+ MachBroker::MachMap::iterator it = mach_map_.find(pid); |
+ if (it == mach_map_.end()) |
+ return; |
+ |
+ kern_return_t kr = mach_port_deallocate(mach_task_self(), |
+ it->second.mach_task_); |
+ if (kr != KERN_SUCCESS) { |
+ 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.
|
+ << ", error " << kr; |
+ } |
+ mach_map_.erase(it); |
} |
// Returns the mach task belonging to |pid|. |
@@ -33,3 +69,28 @@ mach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const { |
return MACH_PORT_NULL; |
return it->second.mach_task_; |
} |
+ |
+// TODO(thakis): unittest |
+void MachBroker::Observe(NotificationType type, |
+ const NotificationSource& source, |
+ const NotificationDetails& details) { |
+ base::ProcessHandle handle = 0; |
+ switch (type.value) { |
+ case NotificationType::RENDERER_PROCESS_CLOSED: |
+ case NotificationType::RENDERER_PROCESS_TERMINATED: |
+ handle = Source<RenderProcessHost>(source)->GetHandle(); |
+ break; |
+ case NotificationType::EXTENSION_PROCESS_TERMINATED: |
+ handle = |
+ Details<ExtensionHost>(details)->render_process_host()->GetHandle(); |
+ break; |
+ case NotificationType::CHILD_PROCESS_CRASHED: |
+ case NotificationType::CHILD_PROCESS_HOST_DISCONNECTED: |
+ handle = Details<ChildProcessInfo>(details)->handle(); |
+ break; |
+ default: |
+ NOTREACHED() << "Unexpected notification"; |
+ break; |
+ } |
+ Invalidate(handle); |
Mark Mentovai
2010/01/11 20:22:46
If handle is 0, you know you don't need to waste t
|
+} |