diff options
Diffstat (limited to 'content/browser/browser_child_process_host.cc')
-rw-r--r-- | content/browser/browser_child_process_host.cc | 141 |
1 files changed, 72 insertions, 69 deletions
diff --git a/content/browser/browser_child_process_host.cc b/content/browser/browser_child_process_host.cc index 9bd3b21..fee30a2 100644 --- a/content/browser/browser_child_process_host.cc +++ b/content/browser/browser_child_process_host.cc @@ -20,6 +20,7 @@ #include "content/common/child_process_host_impl.h" #include "content/common/plugin_messages.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/browser_child_process_host_delegate.h" #include "content/public/browser/child_process_data.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/notification_service.h" @@ -33,31 +34,48 @@ #include "base/bind.h" #endif +using content::BrowserChildProcessHostDelegate; using content::BrowserThread; +using content::ChildProcessData; using content::ChildProcessHost; using content::ChildProcessHostImpl; namespace { -typedef std::list<BrowserChildProcessHost*> BrowserChildProcessList; -static base::LazyInstance<BrowserChildProcessList> g_child_process_list = - LAZY_INSTANCE_INITIALIZER; +static base::LazyInstance<BrowserChildProcessHost::BrowserChildProcessList> + g_child_process_list = LAZY_INSTANCE_INITIALIZER; // Helper functions since the child process related notifications happen on the // UI thread. void ChildNotificationHelper(int notification_type, - const content::ChildProcessData& data) { + const ChildProcessData& data) { content::NotificationService::current()-> Notify(notification_type, content::NotificationService::AllSources(), - content::Details<const content::ChildProcessData>(&data)); + content::Details<const ChildProcessData>(&data)); } } // namespace +namespace content { + +BrowserChildProcessHost* BrowserChildProcessHost::Create( + ProcessType type, + BrowserChildProcessHostDelegate* delegate) { + return new ::BrowserChildProcessHost(type, delegate); +} + +} // namespace content + +BrowserChildProcessHost::BrowserChildProcessList* + BrowserChildProcessHost::GetIterator() { + return g_child_process_list.Pointer(); +} + BrowserChildProcessHost::BrowserChildProcessHost( - content::ProcessType type) + content::ProcessType type, + BrowserChildProcessHostDelegate* delegate) : data_(type), - ALLOW_THIS_IN_INITIALIZER_LIST(client_(this)), + delegate_(delegate), #if !defined(OS_WIN) ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), #endif @@ -77,6 +95,7 @@ BrowserChildProcessHost::~BrowserChildProcessHost() { // static void BrowserChildProcessHost::TerminateAll() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // Make a copy since the BrowserChildProcessHost dtor mutates the original // list. BrowserChildProcessList copy = g_child_process_list.Get(); @@ -91,9 +110,10 @@ void BrowserChildProcessHost::Launch( const base::environment_vector& environ, #endif CommandLine* cmd_line) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); content::GetContentClient()->browser()->AppendExtraCommandLineSwitches( - cmd_line, data().id); + cmd_line, data_.id); child_process_.reset(new ChildProcessLauncher( #if defined(OS_WIN) @@ -101,13 +121,24 @@ void BrowserChildProcessHost::Launch( #elif defined(OS_POSIX) use_zygote, environ, - child_process_host()->TakeClientFileDescriptor(), + child_process_host_->TakeClientFileDescriptor(), #endif cmd_line, - &client_)); + this)); } -base::ProcessHandle BrowserChildProcessHost::GetChildProcessHandle() const { +const ChildProcessData& BrowserChildProcessHost::GetData() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + return data_; +} + +ChildProcessHost* BrowserChildProcessHost::GetHost() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + return child_process_host_.get(); +} + +base::ProcessHandle BrowserChildProcessHost::GetHandle() const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(child_process_.get()) << "Requesting a child process handle before launching."; DCHECK(child_process_->GetHandle()) @@ -116,20 +147,24 @@ base::ProcessHandle BrowserChildProcessHost::GetChildProcessHandle() const { } void BrowserChildProcessHost::SetName(const string16& name) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); data_.name = name; } void BrowserChildProcessHost::SetHandle(base::ProcessHandle handle) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); data_.handle = handle; } void BrowserChildProcessHost::ForceShutdown() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); g_child_process_list.Get().remove(this); child_process_host_->ForceShutdown(); } void BrowserChildProcessHost::SetTerminateChildOnShutdown( - bool terminate_on_shutdown) { + bool terminate_on_shutdown) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown); } @@ -140,23 +175,29 @@ void BrowserChildProcessHost::Notify(int type) { base::Bind(&ChildNotificationHelper, type, data_)); } -base::TerminationStatus BrowserChildProcessHost::GetChildTerminationStatus( +base::TerminationStatus BrowserChildProcessHost::GetTerminationStatus( int* exit_code) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (!child_process_.get()) // If the delegate doesn't use Launch() helper. - return base::GetTerminationStatus(data().handle, exit_code); + return base::GetTerminationStatus(data_.handle, exit_code); return child_process_->GetChildTerminationStatus(exit_code); } bool BrowserChildProcessHost::OnMessageReceived(const IPC::Message& message) { - return false; + return delegate_->OnMessageReceived(message); } void BrowserChildProcessHost::OnChannelConnected(int32 peer_pid) { Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_CONNECTED); + delegate_->OnChannelConnected(peer_pid); +} + +void BrowserChildProcessHost::OnChannelError() { + delegate_->OnChannelError(); } bool BrowserChildProcessHost::CanShutdown() { - return true; + return delegate_->CanShutdown(); } // Normally a ChildProcessHostDelegate deletes itself from this callback, but at @@ -167,21 +208,21 @@ bool BrowserChildProcessHost::CanShutdown() { // may be called twice: once from the actual channel error and once from // OnWaitableEventSignaled() or the delayed task. void BrowserChildProcessHost::OnChildDisconnected() { - DCHECK(data().handle != base::kNullProcessHandle); + DCHECK(data_.handle != base::kNullProcessHandle); int exit_code; - base::TerminationStatus status = GetChildTerminationStatus(&exit_code); + base::TerminationStatus status = GetTerminationStatus(&exit_code); switch (status) { case base::TERMINATION_STATUS_PROCESS_CRASHED: case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: { - OnProcessCrashed(exit_code); + delegate_->OnProcessCrashed(exit_code); // Report that this child process crashed. Notify(content::NOTIFICATION_CHILD_PROCESS_CRASHED); UMA_HISTOGRAM_ENUMERATION("ChildProcess.Crashed", - data().type, + data_.type, content::PROCESS_TYPE_MAX); if (disconnect_was_alive_) { UMA_HISTOGRAM_ENUMERATION("ChildProcess.CrashedWasAlive", - data().type, + data_.type, content::PROCESS_TYPE_MAX); } break; @@ -189,11 +230,11 @@ void BrowserChildProcessHost::OnChildDisconnected() { case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: { // Report that this child process was killed. UMA_HISTOGRAM_ENUMERATION("ChildProcess.Killed", - data().type, + data_.type, content::PROCESS_TYPE_MAX); if (disconnect_was_alive_) { UMA_HISTOGRAM_ENUMERATION("ChildProcess.KilledWasAlive", - data().type, + data_.type, content::PROCESS_TYPE_MAX); } break; @@ -203,14 +244,14 @@ void BrowserChildProcessHost::OnChildDisconnected() { // code. if (disconnect_was_alive_) { UMA_HISTOGRAM_ENUMERATION("ChildProcess.DisconnectedAlive", - data().type, + data_.type, content::PROCESS_TYPE_MAX); break; } disconnect_was_alive_ = true; #if defined(OS_WIN) child_watcher_.StartWatching( - new base::WaitableEvent(data().handle), this); + new base::WaitableEvent(data_.handle), this); #else // On non-Windows platforms, give the child process some time to die after // disconnecting the channel so that the exit code and termination status @@ -230,7 +271,7 @@ void BrowserChildProcessHost::OnChildDisconnected() { break; } UMA_HISTOGRAM_ENUMERATION("ChildProcess.Disconnected", - data().type, + data_.type, content::PROCESS_TYPE_MAX); // Notify in the main loop of the disconnection. Notify(content::NOTIFICATION_CHILD_PROCESS_HOST_DISCONNECTED); @@ -265,50 +306,12 @@ void BrowserChildProcessHost::ShutdownStarted() { g_child_process_list.Get().remove(this); } -BrowserChildProcessHost::ClientHook::ClientHook(BrowserChildProcessHost* host) - : host_(host) { -} -void BrowserChildProcessHost::ClientHook::OnProcessLaunched() { - if (!host_->child_process_->GetHandle()) { - delete host_; +void BrowserChildProcessHost::OnProcessLaunched() { + if (!child_process_->GetHandle()) { + delete this; return; } - host_->data_.handle = host_->child_process_->GetHandle(); - host_->OnProcessLaunched(); -} - -BrowserChildProcessHost::Iterator::Iterator() - : all_(true), type_(content::PROCESS_TYPE_UNKNOWN) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << - "BrowserChildProcessHost::Iterator must be used on the IO thread."; - iterator_ = g_child_process_list.Get().begin(); -} - -BrowserChildProcessHost::Iterator::Iterator(content::ProcessType type) - : all_(false), type_(type) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)) << - "BrowserChildProcessHost::Iterator must be used on the IO thread."; - iterator_ = g_child_process_list.Get().begin(); - if (!Done() && (*iterator_)->data().type != type_) - ++(*this); -} - -BrowserChildProcessHost* BrowserChildProcessHost::Iterator::operator++() { - do { - ++iterator_; - if (Done()) - break; - - if (!all_ && (*iterator_)->data().type != type_) - continue; - - return *iterator_; - } while (true); - - return NULL; -} - -bool BrowserChildProcessHost::Iterator::Done() { - return iterator_ == g_child_process_list.Get().end(); + data_.handle = child_process_->GetHandle(); + delegate_->OnProcessLaunched(); } |