diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-20 07:51:54 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-20 07:51:54 +0000 |
commit | f177ffd84b0f1b94de05fa0166520783cb5cddb9 (patch) | |
tree | 54f755e0de2d845cd2d8b481f08c528911ce62d2 /content/browser/browser_child_process_host.cc | |
parent | 57c1b56f4ae39e8cb1cd805fb46653423d4e5456 (diff) | |
download | chromium_src-f177ffd84b0f1b94de05fa0166520783cb5cddb9.zip chromium_src-f177ffd84b0f1b94de05fa0166520783cb5cddb9.tar.gz chromium_src-f177ffd84b0f1b94de05fa0166520783cb5cddb9.tar.bz2 |
Revert 118415 - Add a Content API around BrowserChildProcessHost, similar to what was done with ChildProcessHost. Now classes like PluginProcessHost don't derive from it, but instead use composition.
I've also moved the iterator class into its own file in the public directory. Since classes don't derive from BrowserChildProcessHost and so can't static_cast from it, I added a template helper that does this.
BUG=98716
Review URL: https://chromiumcodereview.appspot.com/9150017
TBR=jam@chromium.org
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118420 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/browser_child_process_host.cc')
-rw-r--r-- | content/browser/browser_child_process_host.cc | 141 |
1 files changed, 69 insertions, 72 deletions
diff --git a/content/browser/browser_child_process_host.cc b/content/browser/browser_child_process_host.cc index fee30a2..9bd3b21 100644 --- a/content/browser/browser_child_process_host.cc +++ b/content/browser/browser_child_process_host.cc @@ -20,7 +20,6 @@ #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" @@ -34,48 +33,31 @@ #include "base/bind.h" #endif -using content::BrowserChildProcessHostDelegate; using content::BrowserThread; -using content::ChildProcessData; using content::ChildProcessHost; using content::ChildProcessHostImpl; namespace { -static base::LazyInstance<BrowserChildProcessHost::BrowserChildProcessList> - g_child_process_list = LAZY_INSTANCE_INITIALIZER; +typedef std::list<BrowserChildProcessHost*> BrowserChildProcessList; +static base::LazyInstance<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 ChildProcessData& data) { + const content::ChildProcessData& data) { content::NotificationService::current()-> Notify(notification_type, content::NotificationService::AllSources(), - content::Details<const ChildProcessData>(&data)); + content::Details<const content::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, - BrowserChildProcessHostDelegate* delegate) + content::ProcessType type) : data_(type), - delegate_(delegate), + ALLOW_THIS_IN_INITIALIZER_LIST(client_(this)), #if !defined(OS_WIN) ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), #endif @@ -95,7 +77,6 @@ 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(); @@ -110,10 +91,9 @@ 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) @@ -121,24 +101,13 @@ void BrowserChildProcessHost::Launch( #elif defined(OS_POSIX) use_zygote, environ, - child_process_host_->TakeClientFileDescriptor(), + child_process_host()->TakeClientFileDescriptor(), #endif cmd_line, - this)); + &client_)); } -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)); +base::ProcessHandle BrowserChildProcessHost::GetChildProcessHandle() const { DCHECK(child_process_.get()) << "Requesting a child process handle before launching."; DCHECK(child_process_->GetHandle()) @@ -147,24 +116,20 @@ base::ProcessHandle BrowserChildProcessHost::GetHandle() 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) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + bool terminate_on_shutdown) { child_process_->SetTerminateChildOnShutdown(terminate_on_shutdown); } @@ -175,29 +140,23 @@ void BrowserChildProcessHost::Notify(int type) { base::Bind(&ChildNotificationHelper, type, data_)); } -base::TerminationStatus BrowserChildProcessHost::GetTerminationStatus( +base::TerminationStatus BrowserChildProcessHost::GetChildTerminationStatus( 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 delegate_->OnMessageReceived(message); + return false; } 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 delegate_->CanShutdown(); + return true; } // Normally a ChildProcessHostDelegate deletes itself from this callback, but at @@ -208,21 +167,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 = GetTerminationStatus(&exit_code); + base::TerminationStatus status = GetChildTerminationStatus(&exit_code); switch (status) { case base::TERMINATION_STATUS_PROCESS_CRASHED: case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: { - delegate_->OnProcessCrashed(exit_code); + 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; @@ -230,11 +189,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; @@ -244,14 +203,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 @@ -271,7 +230,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); @@ -306,12 +265,50 @@ void BrowserChildProcessHost::ShutdownStarted() { g_child_process_list.Get().remove(this); } +BrowserChildProcessHost::ClientHook::ClientHook(BrowserChildProcessHost* host) + : host_(host) { +} -void BrowserChildProcessHost::OnProcessLaunched() { - if (!child_process_->GetHandle()) { - delete this; +void BrowserChildProcessHost::ClientHook::OnProcessLaunched() { + if (!host_->child_process_->GetHandle()) { + delete host_; return; } - data_.handle = child_process_->GetHandle(); - delegate_->OnProcessLaunched(); + 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(); } |