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 |