| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/browser/browser_child_process_host.h" | 5 #include "content/browser/browser_child_process_host.h" |
| 6 | 6 |
| 7 #include "base/bind.h" |
| 7 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 8 #include "base/file_path.h" | 9 #include "base/file_path.h" |
| 9 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 12 #include "base/path_service.h" | 13 #include "base/path_service.h" |
| 13 #include "base/process_util.h" | 14 #include "base/process_util.h" |
| 14 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
| 15 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 16 #include "content/browser/renderer_host/resource_message_filter.h" | 17 #include "content/browser/renderer_host/resource_message_filter.h" |
| 17 #include "content/browser/trace_message_filter.h" | 18 #include "content/browser/trace_message_filter.h" |
| 18 #include "content/common/plugin_messages.h" | 19 #include "content/common/plugin_messages.h" |
| 19 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
| 21 #include "content/public/browser/child_process_data.h" |
| 20 #include "content/public/browser/content_browser_client.h" | 22 #include "content/public/browser/content_browser_client.h" |
| 21 #include "content/public/browser/notification_service.h" | 23 #include "content/public/browser/notification_service.h" |
| 22 #include "content/public/browser/notification_types.h" | 24 #include "content/public/browser/notification_types.h" |
| 23 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/content_switches.h" |
| 24 #include "content/public/common/result_codes.h" | 26 #include "content/public/common/result_codes.h" |
| 25 | 27 |
| 26 #if defined(OS_WIN) | 28 #if defined(OS_WIN) |
| 27 #include "base/synchronization/waitable_event.h" | 29 #include "base/synchronization/waitable_event.h" |
| 28 #else | 30 #else |
| 29 #include "base/bind.h" | 31 #include "base/bind.h" |
| 30 #endif | 32 #endif |
| 31 | 33 |
| 32 using content::BrowserThread; | 34 using content::BrowserThread; |
| 33 | 35 |
| 34 namespace { | 36 namespace { |
| 35 | 37 |
| 36 typedef std::list<BrowserChildProcessHost*> ChildProcessList; | 38 typedef std::list<BrowserChildProcessHost*> ChildProcessList; |
| 37 static base::LazyInstance<ChildProcessList> g_child_process_list = | 39 static base::LazyInstance<ChildProcessList> g_child_process_list = |
| 38 LAZY_INSTANCE_INITIALIZER; | 40 LAZY_INSTANCE_INITIALIZER; |
| 39 | 41 |
| 40 // The NotificationTask is used to notify about plugin process connection/ | 42 // Helper functions since the child process related notifications happen on the |
| 41 // disconnection. It is needed because the notifications in the | 43 // UI thread. |
| 42 // NotificationService must happen in the main thread. | 44 void ChildNotificationHelper(int notification_type, |
| 43 class ChildNotificationTask : public Task { | 45 content::ChildProcessData data) { |
| 44 public: | 46 content::NotificationService::current()-> |
| 45 ChildNotificationTask( | 47 Notify(notification_type, content::NotificationService::AllSources(), |
| 46 int notification_type, ChildProcessInfo* info) | 48 content::Details<content::ChildProcessData>(&data)); |
| 47 : notification_type_(notification_type), info_(*info) { } | 49 } |
| 48 | |
| 49 virtual void Run() { | |
| 50 content::NotificationService::current()-> | |
| 51 Notify(notification_type_, content::NotificationService::AllSources(), | |
| 52 content::Details<ChildProcessInfo>(&info_)); | |
| 53 } | |
| 54 | |
| 55 private: | |
| 56 int notification_type_; | |
| 57 ChildProcessInfo info_; | |
| 58 }; | |
| 59 | 50 |
| 60 } // namespace | 51 } // namespace |
| 61 | 52 |
| 62 BrowserChildProcessHost::BrowserChildProcessHost( | 53 BrowserChildProcessHost::BrowserChildProcessHost( |
| 63 content::ProcessType type) | 54 content::ProcessType type) |
| 64 : ChildProcessInfo(type, -1), | 55 : ALLOW_THIS_IN_INITIALIZER_LIST(client_(this)), |
| 65 ALLOW_THIS_IN_INITIALIZER_LIST(client_(this)), | |
| 66 #if !defined(OS_WIN) | 56 #if !defined(OS_WIN) |
| 67 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), | 57 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), |
| 68 #endif | 58 #endif |
| 69 disconnect_was_alive_(false) { | 59 disconnect_was_alive_(false) { |
| 60 data_.type = type; |
| 61 data_.id = GenerateChildProcessUniqueId(); |
| 62 |
| 70 AddFilter(new TraceMessageFilter); | 63 AddFilter(new TraceMessageFilter); |
| 71 | 64 |
| 72 g_child_process_list.Get().push_back(this); | 65 g_child_process_list.Get().push_back(this); |
| 73 } | 66 } |
| 74 | 67 |
| 75 BrowserChildProcessHost::~BrowserChildProcessHost() { | 68 BrowserChildProcessHost::~BrowserChildProcessHost() { |
| 76 g_child_process_list.Get().remove(this); | 69 g_child_process_list.Get().remove(this); |
| 77 } | 70 } |
| 78 | 71 |
| 79 // static | 72 // static |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 ChildProcessHost::ForceShutdown(); | 113 ChildProcessHost::ForceShutdown(); |
| 121 } | 114 } |
| 122 | 115 |
| 123 void BrowserChildProcessHost::SetTerminateChildOnShutdown( | 116 void BrowserChildProcessHost::SetTerminateChildOnShutdown( |
| 124 bool terminate_on_shutdown) { | 117 bool terminate_on_shutdown) { |
| 125 child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown); | 118 child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown); |
| 126 } | 119 } |
| 127 | 120 |
| 128 void BrowserChildProcessHost::Notify(int type) { | 121 void BrowserChildProcessHost::Notify(int type) { |
| 129 BrowserThread::PostTask( | 122 BrowserThread::PostTask( |
| 130 BrowserThread::UI, FROM_HERE, new ChildNotificationTask(type, this)); | 123 BrowserThread::UI, |
| 124 FROM_HERE, |
| 125 base::Bind(&ChildNotificationHelper, type, data_)); |
| 131 } | 126 } |
| 132 | 127 |
| 133 base::TerminationStatus BrowserChildProcessHost::GetChildTerminationStatus( | 128 base::TerminationStatus BrowserChildProcessHost::GetChildTerminationStatus( |
| 134 int* exit_code) { | 129 int* exit_code) { |
| 135 return child_process_->GetChildTerminationStatus(exit_code); | 130 return child_process_->GetChildTerminationStatus(exit_code); |
| 136 } | 131 } |
| 137 | 132 |
| 138 void BrowserChildProcessHost::OnChannelConnected(int32 peer_pid) { | 133 void BrowserChildProcessHost::OnChannelConnected(int32 peer_pid) { |
| 139 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); | 134 Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); |
| 140 } | 135 } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 | 237 |
| 243 BrowserChildProcessHost::ClientHook::ClientHook(BrowserChildProcessHost* host) | 238 BrowserChildProcessHost::ClientHook::ClientHook(BrowserChildProcessHost* host) |
| 244 : host_(host) { | 239 : host_(host) { |
| 245 } | 240 } |
| 246 | 241 |
| 247 void BrowserChildProcessHost::ClientHook::OnProcessLaunched() { | 242 void BrowserChildProcessHost::ClientHook::OnProcessLaunched() { |
| 248 if (!host_->child_process_->GetHandle()) { | 243 if (!host_->child_process_->GetHandle()) { |
| 249 host_->OnChildDied(); | 244 host_->OnChildDied(); |
| 250 return; | 245 return; |
| 251 } | 246 } |
| 252 host_->set_handle(host_->child_process_->GetHandle()); | 247 host_->data_.handle = host_->child_process_->GetHandle(); |
| 253 host_->OnProcessLaunched(); | 248 host_->OnProcessLaunched(); |
| 254 } | 249 } |
| 255 | 250 |
| 256 BrowserChildProcessHost::Iterator::Iterator() | 251 BrowserChildProcessHost::Iterator::Iterator() |
| 257 : all_(true), type_(content::PROCESS_TYPE_UNKNOWN) { | 252 : all_(true), type_(content::PROCESS_TYPE_UNKNOWN) { |
| 258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << | 253 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << |
| 259 "ChildProcessInfo::Iterator must be used on the IO thread."; | 254 "BrowserChildProcessHost::Iterator must be used on the IO thread."; |
| 260 iterator_ = g_child_process_list.Get().begin(); | 255 iterator_ = g_child_process_list.Get().begin(); |
| 261 } | 256 } |
| 262 | 257 |
| 263 BrowserChildProcessHost::Iterator::Iterator(content::ProcessType type) | 258 BrowserChildProcessHost::Iterator::Iterator(content::ProcessType type) |
| 264 : all_(false), type_(type) { | 259 : all_(false), type_(type) { |
| 265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << | 260 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << |
| 266 "ChildProcessInfo::Iterator must be used on the IO thread."; | 261 "BrowserChildProcessHost::Iterator must be used on the IO thread."; |
| 267 iterator_ = g_child_process_list.Get().begin(); | 262 iterator_ = g_child_process_list.Get().begin(); |
| 268 if (!Done() && (*iterator_)->type() != type_) | 263 if (!Done() && (*iterator_)->type() != type_) |
| 269 ++(*this); | 264 ++(*this); |
| 270 } | 265 } |
| 271 | 266 |
| 272 BrowserChildProcessHost* BrowserChildProcessHost::Iterator::operator++() { | 267 BrowserChildProcessHost* BrowserChildProcessHost::Iterator::operator++() { |
| 273 do { | 268 do { |
| 274 ++iterator_; | 269 ++iterator_; |
| 275 if (Done()) | 270 if (Done()) |
| 276 break; | 271 break; |
| 277 | 272 |
| 278 if (!all_ && (*iterator_)->type() != type_) | 273 if (!all_ && (*iterator_)->type() != type_) |
| 279 continue; | 274 continue; |
| 280 | 275 |
| 281 return *iterator_; | 276 return *iterator_; |
| 282 } while (true); | 277 } while (true); |
| 283 | 278 |
| 284 return NULL; | 279 return NULL; |
| 285 } | 280 } |
| 286 | 281 |
| 287 bool BrowserChildProcessHost::Iterator::Done() { | 282 bool BrowserChildProcessHost::Iterator::Done() { |
| 288 return iterator_ == g_child_process_list.Get().end(); | 283 return iterator_ == g_child_process_list.Get().end(); |
| 289 } | 284 } |
| OLD | NEW |