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 // Required because notifications happen on the UI thread. |
| 14 class RegisterNotificationTask : public Task { |
| 15 public: |
| 16 RegisterNotificationTask( |
| 17 MachBroker* broker) |
| 18 : broker_(broker) { } |
| 19 |
| 20 virtual void Run() { |
| 21 broker_->registrar_.Add(broker_, |
| 22 NotificationType::RENDERER_PROCESS_CLOSED, |
| 23 NotificationService::AllSources()); |
| 24 broker_->registrar_.Add(broker_, |
| 25 NotificationType::RENDERER_PROCESS_TERMINATED, |
| 26 NotificationService::AllSources()); |
| 27 broker_->registrar_.Add(broker_, |
| 28 NotificationType::CHILD_PROCESS_CRASHED, |
| 29 NotificationService::AllSources()); |
| 30 broker_->registrar_.Add(broker_, |
| 31 NotificationType::CHILD_PROCESS_HOST_DISCONNECTED, |
| 32 NotificationService::AllSources()); |
| 33 broker_->registrar_.Add(broker_, |
| 34 NotificationType::EXTENSION_PROCESS_TERMINATED, |
| 35 NotificationService::AllSources()); |
| 36 } |
| 37 |
| 38 private: |
| 39 MachBroker* broker_; |
| 40 }; |
| 41 |
| 42 MachBroker::MachBroker() { |
| 43 ChromeThread::PostTask( |
| 44 ChromeThread::UI, FROM_HERE, new RegisterNotificationTask(this)); |
| 45 } |
8 | 46 |
9 // Returns the global MachBroker. | 47 // Returns the global MachBroker. |
10 MachBroker* MachBroker::instance() { | 48 MachBroker* MachBroker::instance() { |
11 return Singleton<MachBroker>::get(); | 49 return Singleton<MachBroker>::get(); |
12 } | 50 } |
13 | 51 |
14 // Adds mach info for a given pid. | 52 // Adds mach info for a given pid. |
15 void MachBroker::RegisterPid( | 53 void MachBroker::RegisterPid( |
16 base::ProcessHandle pid, const MachInfo& mach_info) { | 54 base::ProcessHandle pid, const MachInfo& mach_info) { |
17 AutoLock lock(lock_); | 55 AutoLock lock(lock_); |
18 DCHECK_EQ(0u, mach_map_.count(pid)); | 56 DCHECK_EQ(0u, mach_map_.count(pid)); |
19 mach_map_[pid] = mach_info; | 57 mach_map_[pid] = mach_info; |
20 } | 58 } |
21 | 59 |
22 // Removes all mappings belonging to |pid| from the broker. | 60 // Removes all mappings belonging to |pid| from the broker. |
23 void MachBroker::Invalidate(base::ProcessHandle pid) { | 61 void MachBroker::Invalidate(base::ProcessHandle pid) { |
24 AutoLock lock(lock_); | 62 AutoLock lock(lock_); |
25 mach_map_.erase(pid); | 63 MachBroker::MachMap::iterator it = mach_map_.find(pid); |
| 64 if (it == mach_map_.end()) |
| 65 return; |
| 66 |
| 67 kern_return_t kr = mach_port_deallocate(mach_task_self(), |
| 68 it->second.mach_task_); |
| 69 LOG_IF(WARNING, kr != KERN_SUCCESS) |
| 70 << "Failed to deallocate mach task " << it->second.mach_task_ |
| 71 << ", error " << kr; |
| 72 mach_map_.erase(it); |
26 } | 73 } |
27 | 74 |
28 // Returns the mach task belonging to |pid|. | 75 // Returns the mach task belonging to |pid|. |
29 mach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const { | 76 mach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const { |
30 AutoLock lock(lock_); | 77 AutoLock lock(lock_); |
31 MachBroker::MachMap::const_iterator it = mach_map_.find(pid); | 78 MachBroker::MachMap::const_iterator it = mach_map_.find(pid); |
32 if (it == mach_map_.end()) | 79 if (it == mach_map_.end()) |
33 return MACH_PORT_NULL; | 80 return MACH_PORT_NULL; |
34 return it->second.mach_task_; | 81 return it->second.mach_task_; |
35 } | 82 } |
| 83 |
| 84 void MachBroker::Observe(NotificationType type, |
| 85 const NotificationSource& source, |
| 86 const NotificationDetails& details) { |
| 87 base::ProcessHandle handle = 0; |
| 88 switch (type.value) { |
| 89 case NotificationType::RENDERER_PROCESS_CLOSED: |
| 90 case NotificationType::RENDERER_PROCESS_TERMINATED: |
| 91 handle = Source<RenderProcessHost>(source)->GetHandle(); |
| 92 break; |
| 93 case NotificationType::EXTENSION_PROCESS_TERMINATED: |
| 94 handle = |
| 95 Details<ExtensionHost>(details)->render_process_host()->GetHandle(); |
| 96 break; |
| 97 case NotificationType::CHILD_PROCESS_CRASHED: |
| 98 case NotificationType::CHILD_PROCESS_HOST_DISCONNECTED: |
| 99 handle = Details<ChildProcessInfo>(details)->handle(); |
| 100 break; |
| 101 default: |
| 102 NOTREACHED() << "Unexpected notification"; |
| 103 break; |
| 104 } |
| 105 Invalidate(handle); |
| 106 } |
OLD | NEW |