| 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/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/mach_ipc_mac.h" | 9 #include "base/mach_ipc_mac.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 if (child_task == MACH_PORT_NULL) { | 84 if (child_task == MACH_PORT_NULL) { |
| 85 LOG(ERROR) << "parent GetTranslatedPort(0) failed."; | 85 LOG(ERROR) << "parent GetTranslatedPort(0) failed."; |
| 86 continue; | 86 continue; |
| 87 } | 87 } |
| 88 | 88 |
| 89 // It is possible for the child process to die after the call to | 89 // It is possible for the child process to die after the call to |
| 90 // |pid_for_task()| but before the call to |FinalizePid()|. To prevent | 90 // |pid_for_task()| but before the call to |FinalizePid()|. To prevent |
| 91 // leaking MachBroker map entries in this case, lock around both these | 91 // leaking MachBroker map entries in this case, lock around both these |
| 92 // calls. If the child dies, the death notification will be processed | 92 // calls. If the child dies, the death notification will be processed |
| 93 // after the call to FinalizePid(), ensuring proper cleanup. | 93 // after the call to FinalizePid(), ensuring proper cleanup. |
| 94 AutoLock lock(broker_->GetLock()); | 94 base::AutoLock lock(broker_->GetLock()); |
| 95 | 95 |
| 96 int pid; | 96 int pid; |
| 97 err = pid_for_task(child_task, &pid); | 97 err = pid_for_task(child_task, &pid); |
| 98 if (err == KERN_SUCCESS) { | 98 if (err == KERN_SUCCESS) { |
| 99 broker_->FinalizePid(pid, | 99 broker_->FinalizePid(pid, |
| 100 MachBroker::MachInfo().SetTask(child_task)); | 100 MachBroker::MachInfo().SetTask(child_task)); |
| 101 } else { | 101 } else { |
| 102 LOG(ERROR) << "Error getting pid for task " << child_task | 102 LOG(ERROR) << "Error getting pid for task " << child_task |
| 103 << ": " << MachErrorCode(err); | 103 << ": " << MachErrorCode(err); |
| 104 } | 104 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 } | 163 } |
| 164 | 164 |
| 165 DCHECK_EQ(1, count); | 165 DCHECK_EQ(1, count); |
| 166 DCHECK(mach_map_[pid].mach_task_ == MACH_PORT_NULL); | 166 DCHECK(mach_map_[pid].mach_task_ == MACH_PORT_NULL); |
| 167 if (mach_map_[pid].mach_task_ == MACH_PORT_NULL) | 167 if (mach_map_[pid].mach_task_ == MACH_PORT_NULL) |
| 168 mach_map_[pid] = mach_info; | 168 mach_map_[pid] = mach_info; |
| 169 } | 169 } |
| 170 | 170 |
| 171 // Removes all mappings belonging to |pid| from the broker. | 171 // Removes all mappings belonging to |pid| from the broker. |
| 172 void MachBroker::InvalidatePid(base::ProcessHandle pid) { | 172 void MachBroker::InvalidatePid(base::ProcessHandle pid) { |
| 173 AutoLock lock(lock_); | 173 base::AutoLock lock(lock_); |
| 174 MachBroker::MachMap::iterator it = mach_map_.find(pid); | 174 MachBroker::MachMap::iterator it = mach_map_.find(pid); |
| 175 if (it == mach_map_.end()) | 175 if (it == mach_map_.end()) |
| 176 return; | 176 return; |
| 177 | 177 |
| 178 kern_return_t kr = mach_port_deallocate(mach_task_self(), | 178 kern_return_t kr = mach_port_deallocate(mach_task_self(), |
| 179 it->second.mach_task_); | 179 it->second.mach_task_); |
| 180 LOG_IF(WARNING, kr != KERN_SUCCESS) | 180 LOG_IF(WARNING, kr != KERN_SUCCESS) |
| 181 << "Failed to mach_port_deallocate mach task " << it->second.mach_task_ | 181 << "Failed to mach_port_deallocate mach task " << it->second.mach_task_ |
| 182 << ", error " << MachErrorCode(kr); | 182 << ", error " << MachErrorCode(kr); |
| 183 mach_map_.erase(it); | 183 mach_map_.erase(it); |
| 184 } | 184 } |
| 185 | 185 |
| 186 Lock& MachBroker::GetLock() { | 186 base::Lock& MachBroker::GetLock() { |
| 187 return lock_; | 187 return lock_; |
| 188 } | 188 } |
| 189 | 189 |
| 190 // Returns the mach task belonging to |pid|. | 190 // Returns the mach task belonging to |pid|. |
| 191 mach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const { | 191 mach_port_t MachBroker::TaskForPid(base::ProcessHandle pid) const { |
| 192 AutoLock lock(lock_); | 192 base::AutoLock lock(lock_); |
| 193 MachBroker::MachMap::const_iterator it = mach_map_.find(pid); | 193 MachBroker::MachMap::const_iterator it = mach_map_.find(pid); |
| 194 if (it == mach_map_.end()) | 194 if (it == mach_map_.end()) |
| 195 return MACH_PORT_NULL; | 195 return MACH_PORT_NULL; |
| 196 return it->second.mach_task_; | 196 return it->second.mach_task_; |
| 197 } | 197 } |
| 198 | 198 |
| 199 void MachBroker::Observe(NotificationType type, | 199 void MachBroker::Observe(NotificationType type, |
| 200 const NotificationSource& source, | 200 const NotificationSource& source, |
| 201 const NotificationDetails& details) { | 201 const NotificationDetails& details) { |
| 202 // TODO(rohitrao): These notifications do not always carry the proper PIDs, | 202 // TODO(rohitrao): These notifications do not always carry the proper PIDs, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 233 #endif | 233 #endif |
| 234 ".rohitfork.%d"; | 234 ".rohitfork.%d"; |
| 235 | 235 |
| 236 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | 236 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); |
| 237 const bool is_child = command_line.HasSwitch(switches::kProcessType); | 237 const bool is_child = command_line.HasSwitch(switches::kProcessType); |
| 238 | 238 |
| 239 // In non-browser (child) processes, use the parent's pid. | 239 // In non-browser (child) processes, use the parent's pid. |
| 240 const pid_t pid = is_child ? getppid() : getpid(); | 240 const pid_t pid = is_child ? getppid() : getpid(); |
| 241 return StringPrintf(kFormatString, pid); | 241 return StringPrintf(kFormatString, pid); |
| 242 } | 242 } |
| OLD | NEW |