diff options
-rw-r--r-- | chrome/browser/browser.cc | 22 | ||||
-rw-r--r-- | chrome/browser/memory_details.cc | 22 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host.cc | 86 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host.h | 13 | ||||
-rw-r--r-- | chrome/browser/plugin_service.cc | 64 | ||||
-rw-r--r-- | chrome/browser/plugin_service.h | 73 | ||||
-rw-r--r-- | chrome/browser/renderer_host/browser_render_process_host.cc | 2 | ||||
-rw-r--r-- | chrome/browser/task_manager_resource_providers.cc | 12 | ||||
-rw-r--r-- | chrome/common/child_process_info.cc | 80 | ||||
-rw-r--r-- | chrome/common/child_process_info.h | 182 | ||||
-rw-r--r-- | chrome/common/debug_flags.cc | 14 | ||||
-rw-r--r-- | chrome/common/debug_flags.h | 4 | ||||
-rw-r--r-- | chrome/test/ui/ui_test.cc | 3 |
13 files changed, 278 insertions, 299 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 440c959..222fab2 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -23,6 +23,7 @@ #include "chrome/browser/tab_contents/site_instance.h" #include "chrome/browser/tab_contents/tab_contents_type.h" #include "chrome/browser/tab_contents/web_contents.h" +#include "chrome/common/child_process_info.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/l10n_util.h" @@ -59,8 +60,6 @@ #include "chrome/browser/history_tab_ui.h" #include "chrome/browser/options_window.h" #include "chrome/browser/net/url_fixer_upper.h" -#include "chrome/browser/plugin_process_host.h" -#include "chrome/browser/plugin_service.h" #include "chrome/browser/ssl/ssl_error_info.h" #include "chrome/browser/status_bubble.h" #include "chrome/browser/tab_contents/interstitial_page.h" @@ -92,15 +91,15 @@ static const int kWindowTilePixels = 20; /////////////////////////////////////////////////////////////////////////////// -// A task to reduce the working set of the plugins. -class ReducePluginsWorkingSetTask : public Task { +// A task to reduce the working set of the child processes that live on the IO +// thread (i.e. plugins, workers). +class ReduceChildProcessesWorkingSetTask : public Task { public: virtual void Run() { #if defined(OS_WIN) - for (PluginProcessHostIterator iter; !iter.Done(); ++iter) { - ChildProcessInfo* child = const_cast<PluginProcessHost*>(*iter); - DCHECK(child->process().handle()); - child->process().ReduceWorkingSet(); + for (ChildProcessInfo::Iterator iter; !iter.Done(); ++iter) { + DCHECK(iter->process().handle()); + iter->process().ReduceWorkingSet(); } #endif } @@ -132,11 +131,10 @@ class BrowserIdleTimer : public base::IdleTimer { process.ReduceWorkingSet(); } - // Handle the Plugin(s). We need to iterate through the plugin processes - // on the IO thread because that thread manages the plugin process - // collection. + // Handle the child processe. We need to iterate through them on the IO + // thread because that thread manages the child process collection. g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, - new ReducePluginsWorkingSetTask()); + new ReduceChildProcessesWorkingSetTask()); #endif } }; diff --git a/chrome/browser/memory_details.cc b/chrome/browser/memory_details.cc index 927b2eb..2eb0135 100644 --- a/chrome/browser/memory_details.cc +++ b/chrome/browser/memory_details.cc @@ -14,12 +14,11 @@ #include "base/thread.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_thread.h" -#include "chrome/browser/plugin_process_host.h" -#include "chrome/browser/plugin_service.h" #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/web_contents.h" +#include "chrome/common/child_process_info.h" class RenderViewHostDelegate; @@ -38,7 +37,7 @@ static ProcessData g_process_template[] = { // // This operation will hit no fewer than 3 threads. // -// The PluginHostIterator can only be accessed from the IO thread. +// The ChildProcessInfo::Iterator can only be accessed from the IO thread. // // The RenderProcessHostIterator can only be accessed from the UI thread. // @@ -73,21 +72,18 @@ void MemoryDetails::CollectChildInfoOnIOThread() { std::vector<ProcessMemoryInformation> child_info; - // Collect the list of plugins. - for (PluginProcessHostIterator plugin_iter; - !plugin_iter.Done(); ++plugin_iter) { - ChildProcessInfo* child = const_cast<PluginProcessHost*>(*plugin_iter); - DCHECK(child); - if (!child || !child->process().handle()) + // Collect the list of child processes. + for (ChildProcessInfo::Iterator iter; !iter.Done(); ++iter) { + if (!iter->process().handle()) continue; ProcessMemoryInformation info; - info.pid = child->process().pid(); + info.pid = iter->process().pid(); if (!info.pid) continue; - info.type = child->type(); - info.titles.push_back(child->name()); + info.type = iter->type(); + info.titles.push_back(iter->name()); child_info.push_back(info); } @@ -244,7 +240,7 @@ void MemoryDetails::CollectChildInfoOnUIThread() { ChildProcessInfo::UNKNOWN_PROCESS) { process_data_[CHROME_BROWSER].processes.erase( process_data_[CHROME_BROWSER].processes.begin() + index); - index --; + index--; } } diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index 6ba74de..f14524d 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -357,13 +357,10 @@ class DestroyWindowTask : public Task { }; -PluginProcessHost::PluginProcessHost(PluginService* plugin_service) - : opening_channel_(false), - resource_dispatcher_host_(plugin_service->resource_dispatcher_host()), - ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)), - plugin_service_(plugin_service) { - DCHECK(resource_dispatcher_host_); - set_type(PLUGIN_PROCESS); +PluginProcessHost::PluginProcessHost() + : ChildProcessInfo(PLUGIN_PROCESS), + opening_channel_(false), + ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)) { } PluginProcessHost::~PluginProcessHost() { @@ -446,7 +443,7 @@ bool PluginProcessHost::Init(const WebPluginInfo& info, // Gears requires the data dir to be available on startup. std::wstring data_dir = - plugin_service_->GetChromePluginDataDir().ToWStringHack(); + PluginService::GetInstance()->GetChromePluginDataDir().ToWStringHack(); DCHECK(!data_dir.empty()); cmd_line.AppendSwitchWithValue(switches::kPluginDataDir, data_dir); @@ -463,7 +460,7 @@ bool PluginProcessHost::Init(const WebPluginInfo& info, browser_command_line.HasSwitch(switches::kSafePlugins); bool child_needs_help = - DebugFlags::ProcessDebugFlags(&cmd_line, DebugFlags::PLUGIN, in_sandbox); + DebugFlags::ProcessDebugFlags(&cmd_line, type(), in_sandbox); if (in_sandbox) { // spawn the child process in the sandbox @@ -547,23 +544,22 @@ void PluginProcessHost::OnObjectSignaled(HANDLE object) { if (did_crash) { // Report that this plugin crashed. - plugin_service_->main_message_loop()->PostTask(FROM_HERE, - new PluginNotificationTask( + PluginService::GetInstance()->main_message_loop()->PostTask( + FROM_HERE, new PluginNotificationTask( NotificationType::CHILD_PROCESS_CRASHED, this)); } // Notify in the main loop of the disconnection. - plugin_service_->main_message_loop()->PostTask(FROM_HERE, - new PluginNotificationTask( + PluginService::GetInstance()->main_message_loop()->PostTask( + FROM_HERE, new PluginNotificationTask( NotificationType::CHILD_PROCESS_HOST_DISCONNECTED, this)); // Cancel all requests for plugin processes. // TODO(mpcomplete): use a real process ID when http://b/issue?id=1210062 is // fixed. - resource_dispatcher_host_->CancelRequestsForProcess(-1); + PluginService::GetInstance()->resource_dispatcher_host()-> + CancelRequestsForProcess(-1); - // This next line will delete this. It should be kept at the end of the - // method. - plugin_service_->OnPluginProcessExited(this); + delete this; } @@ -621,8 +617,8 @@ void PluginProcessHost::OnChannelConnected(int32 peer_pid) { pending_requests_.clear(); // Notify in the main loop of the connection. - plugin_service_->main_message_loop()->PostTask(FROM_HERE, - new PluginNotificationTask( + PluginService::GetInstance()->main_message_loop()->PostTask( + FROM_HERE, new PluginNotificationTask( NotificationType::CHILD_PROCESS_HOST_CONNECTED, this)); } @@ -643,8 +639,8 @@ void PluginProcessHost::OpenChannelToPlugin( const std::string& mime_type, IPC::Message* reply_msg) { // Notify in the main loop of the instantiation. - plugin_service_->main_message_loop()->PostTask(FROM_HERE, - new PluginNotificationTask( + PluginService::GetInstance()->main_message_loop()->PostTask( + FROM_HERE, new PluginNotificationTask( NotificationType::CHILD_INSTANCE_CREATED, this)); if (opening_channel_) { @@ -678,32 +674,27 @@ void PluginProcessHost::OnRequestResource( if (!context) context = Profile::GetDefaultRequestContext(); - resource_dispatcher_host_->BeginRequest(this, - process().handle(), - render_process_host_id, - MSG_ROUTING_CONTROL, - request_id, - request, - context, - NULL); + PluginService::GetInstance()->resource_dispatcher_host()-> + BeginRequest(this, process().handle(), render_process_host_id, + MSG_ROUTING_CONTROL, request_id, request, context, NULL); } void PluginProcessHost::OnCancelRequest(int request_id) { int render_process_host_id = -1; - resource_dispatcher_host_->CancelRequest(render_process_host_id, - request_id, true); + PluginService::GetInstance()->resource_dispatcher_host()-> + CancelRequest(render_process_host_id, request_id, true); } void PluginProcessHost::OnDataReceivedACK(int request_id) { int render_process_host_id = -1; - resource_dispatcher_host_->OnDataReceivedACK(render_process_host_id, - request_id); + PluginService::GetInstance()->resource_dispatcher_host()-> + OnDataReceivedACK(render_process_host_id, request_id); } void PluginProcessHost::OnUploadProgressACK(int request_id) { int render_process_host_id = -1; - resource_dispatcher_host_->OnUploadProgressACK(render_process_host_id, - request_id); + PluginService::GetInstance()->resource_dispatcher_host()-> + OnUploadProgressACK(render_process_host_id, request_id); } void PluginProcessHost::OnSyncLoad( @@ -717,14 +708,10 @@ void PluginProcessHost::OnSyncLoad( if (!context) context = Profile::GetDefaultRequestContext(); - resource_dispatcher_host_->BeginRequest(this, - process().handle(), - render_process_host_id, - MSG_ROUTING_CONTROL, - request_id, - request, - context, - sync_result); + PluginService::GetInstance()->resource_dispatcher_host()-> + BeginRequest(this, process().handle(), render_process_host_id, + MSG_ROUTING_CONTROL, request_id, request, context, + sync_result); } void PluginProcessHost::OnGetCookies(uint32 request_context, @@ -837,10 +824,6 @@ void PluginProcessHost::OnPluginShutdownRequest() { // If we have pending channel open requests from the renderers, then // refuse the shutdown request from the plugin process. bool ok_to_shutdown = sent_requests_.empty(); - - if (ok_to_shutdown) - plugin_service_->OnPluginProcessIsShuttingDown(this); - Send(new PluginProcessMsg_ShutdownResponse(ok_to_shutdown)); } @@ -859,16 +842,15 @@ void PluginProcessHost::OnPluginMessage( void PluginProcessHost::OnCreateWindow(HWND parent, IPC::Message* reply_msg) { // Need to create this window on the UI thread. - plugin_service_->main_message_loop()->PostTask(FROM_HERE, - new CreateWindowTask(info_.path, parent, reply_msg)); + PluginService::GetInstance()->main_message_loop()->PostTask( + FROM_HERE, new CreateWindowTask(info_.path, parent, reply_msg)); } void PluginProcessHost::OnDestroyWindow(HWND window) { - plugin_service_->main_message_loop()->PostTask(FROM_HERE, - new DestroyWindowTask(window)); + PluginService::GetInstance()->main_message_loop()->PostTask( + FROM_HERE, new DestroyWindowTask(window)); } void PluginProcessHost::Shutdown() { - Send(new PluginProcessMsg_BrowserShutdown); } diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h index 74e86fc..f9b79f4 100644 --- a/chrome/browser/plugin_process_host.h +++ b/chrome/browser/plugin_process_host.h @@ -8,18 +8,15 @@ #include <vector> #include "base/basictypes.h" -#include "base/id_map.h" #include "base/object_watcher.h" #include "base/scoped_ptr.h" #include "base/task.h" #include "chrome/browser/net/resolve_proxy_msg_helper.h" #include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/common/child_process_info.h" -#include "chrome/common/ipc_channel_proxy.h" +#include "chrome/common/ipc_channel.h" #include "webkit/glue/webplugin.h" -class PluginService; -class PluginProcessHost; class ResourceDispatcherHost; class URLRequestContext; struct ViewHostMsg_Resource_Request; @@ -39,7 +36,7 @@ class PluginProcessHost : public ChildProcessInfo, public base::ObjectWatcher::Delegate, public ResolveProxyMsgHelper::Delegate { public: - PluginProcessHost(PluginService* plugin_service); + PluginProcessHost(); ~PluginProcessHost(); // Initialize the new plugin process, returning true on success. This must @@ -89,6 +86,8 @@ class PluginProcessHost : public ChildProcessInfo, // Shuts down the current plugin process instance. void Shutdown(); + const WebPluginInfo& info() const { return info_; } + private: friend class PluginResolveProxyHelper; @@ -153,10 +152,6 @@ class PluginProcessHost : public ChildProcessInfo, // Information about the plugin. WebPluginInfo info_; - PluginService* plugin_service_; - - ResourceDispatcherHost* resource_dispatcher_host_; - // Helper class for handling PluginProcessHost_ResolveProxy messages (manages // the requests to the proxy service). ResolveProxyMsgHelper resolve_proxy_msg_helper_; diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc index d36cc69..87d2aeb 100644 --- a/chrome/browser/plugin_service.cc +++ b/chrome/browser/plugin_service.cc @@ -5,7 +5,6 @@ #include "chrome/browser/plugin_service.h" #include "base/command_line.h" -#include "base/singleton.h" #include "base/thread.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_plugin_host.h" @@ -30,7 +29,6 @@ PluginService::PluginService() plugin_shutdown_handler_(new ShutdownHandler) { // Have the NPAPI plugin list search for Chrome plugins as well. ChromePluginLib::RegisterPluginsWithNPAPI(); - // Load the one specified on the command line as well. const CommandLine* command_line = CommandLine::ForCurrentProcess(); std::wstring path = command_line->GetSwitchValue(switches::kLoadPlugin); @@ -77,9 +75,13 @@ PluginProcessHost* PluginService::FindPluginProcess( return NULL; } - PluginMap::iterator found = plugin_hosts_.find(plugin_path); - if (found != plugin_hosts_.end()) - return found->second; + for (ChildProcessInfo::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS); + !iter.Done(); ++iter) { + PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter); + if (plugin->info().path == plugin_path) + return plugin; + } + return NULL; } @@ -100,13 +102,13 @@ PluginProcessHost* PluginService::FindOrStartPluginProcess( } // This plugin isn't loaded by any plugin process, so create a new process. - plugin_host = new PluginProcessHost(this); + plugin_host = new PluginProcessHost(); if (!plugin_host->Init(info, clsid, ui_locale_)) { DCHECK(false); // Init is not expected to fail delete plugin_host; return NULL; } - plugin_hosts_[plugin_path] = plugin_host; + return plugin_host; // TODO(jabdelmalek): adding a new channel means we can have one less @@ -133,31 +135,6 @@ void PluginService::OpenChannelToPlugin( } } -void PluginService::OnPluginProcessIsShuttingDown(PluginProcessHost* host) { - RemoveHost(host); -} - -void PluginService::OnPluginProcessExited(PluginProcessHost* host) { - RemoveHost(host); // in case shutdown was not graceful - delete host; -} - -void PluginService::RemoveHost(PluginProcessHost* host) { - DCHECK(MessageLoop::current() == - ChromeThread::GetMessageLoop(ChromeThread::IO)); - // Search for the instance rather than lookup by plugin path, - // there is a small window where two instances for the same - // plugin path can co-exists. - PluginMap::iterator i = plugin_hosts_.begin(); - while (i != plugin_hosts_.end()) { - if (i->second == host) { - plugin_hosts_.erase(i); - return; - } - i++; - } -} - FilePath PluginService::GetPluginPath(const GURL& url, const std::string& mime_type, const std::string& clsid, @@ -193,29 +170,12 @@ void PluginService::Shutdown() { } void PluginService::OnShutdown() { - PluginMap::iterator host_index; - for (host_index = plugin_hosts_.begin(); host_index != plugin_hosts_.end(); - ++host_index) { - host_index->second->Shutdown(); + for (ChildProcessInfo::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS); + !iter.Done(); ++iter) { + static_cast<PluginProcessHost*>(*iter)->Shutdown(); } } -PluginProcessHostIterator::PluginProcessHostIterator() - : iterator_(PluginService::GetInstance()->plugin_hosts_.begin()), - end_(PluginService::GetInstance()->plugin_hosts_.end()) { - DCHECK(MessageLoop::current() == - ChromeThread::GetMessageLoop(ChromeThread::IO)) << - "PluginProcessHostIterator must be used on the IO thread."; -} - -PluginProcessHostIterator::PluginProcessHostIterator( - const PluginProcessHostIterator& instance) - : iterator_(instance.iterator_) { - DCHECK(MessageLoop::current() == - ChromeThread::GetMessageLoop(ChromeThread::IO)) << - "PluginProcessHostIterator must be used on the IO thread."; -} - void PluginService::ShutdownHandler::InitiateShutdown() { g_browser_process->io_thread()->message_loop()->PostTask( FROM_HERE, diff --git a/chrome/browser/plugin_service.h b/chrome/browser/plugin_service.h index c569bdb..66bd408 100644 --- a/chrome/browser/plugin_service.h +++ b/chrome/browser/plugin_service.h @@ -14,6 +14,7 @@ #include "base/hash_tables.h" #include "base/lock.h" #include "base/ref_counted.h" +#include "base/singleton.h" #include "chrome/browser/browser_process.h" #include "webkit/glue/webplugin.h" @@ -34,13 +35,6 @@ class PluginService { // Returns the PluginService singleton. static PluginService* GetInstance(); - // Creates the PluginService object, but doesn't actually build the plugin - // list yet. It's generated lazily. - // Note: don't call these directly - use GetInstance() above. They are public - // so Singleton can access them. - PluginService(); - ~PluginService(); - // Gets the list of available plugins. void GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins); @@ -78,13 +72,6 @@ class PluginService { const std::wstring& locale, IPC::Message* reply_msg); - // A PluginProcessHost object calls this before its process is shut down. - void OnPluginProcessIsShuttingDown(PluginProcessHost* host); - - // A PluginProcessHost object calls this after its process has exited. This - // call deletes the host instance. - void OnPluginProcessExited(PluginProcessHost* host); - bool HavePluginFor(const std::string& mime_type, bool allow_wildcard); FilePath GetPluginPath(const GURL& url, @@ -114,10 +101,12 @@ class PluginService { void Shutdown(); private: - friend class PluginProcessHostIterator; + friend DefaultSingletonTraits<PluginService>; - // Removes a host from the plugin_hosts collection - void RemoveHost(PluginProcessHost* host); + // Creates the PluginService object, but doesn't actually build the plugin + // list yet. It's generated lazily. + PluginService(); + ~PluginService(); // Shutdown handler which executes in the context of the IO thread. void OnShutdown(); @@ -165,54 +154,4 @@ class PluginService { DISALLOW_COPY_AND_ASSIGN(PluginService); }; -// The PluginProcessHostIterator allows to iterate through all the -// PluginProcessHosts. Note that this should be done from the IO thread and that -// the iterator should not be kept around as it may be invalidated on -// subsequent event processing in the event loop. -class PluginProcessHostIterator { - public: - PluginProcessHostIterator(); - PluginProcessHostIterator(const PluginProcessHostIterator& instance); - - PluginProcessHostIterator& operator=( - const PluginProcessHostIterator& instance) { - iterator_ = instance.iterator_; - return *this; - } - - const PluginProcessHost* operator->() const { - return iterator_->second; - } - - const PluginProcessHost* operator*() const { - return iterator_->second; - } - - const PluginProcessHost* operator++() { // ++preincrement - ++iterator_; - if (iterator_ == end_) - return NULL; - else - return iterator_->second; - } - - const PluginProcessHost* operator++(int) { // postincrement++ - const PluginProcessHost* r; - if (iterator_ == end_) - r = NULL; - else - r = iterator_->second; - iterator_++; - return r; - } - - bool Done() { - return (iterator_ == end_); - } - - private: - PluginService::PluginMap::const_iterator iterator_; - PluginService::PluginMap::const_iterator end_; -}; - #endif // CHROME_BROWSER_PLUGIN_SERVICE_H_ diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 1e3bcc5..f587f05 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -291,7 +291,7 @@ bool BrowserRenderProcessHost::Init() { #if defined(OS_WIN) bool child_needs_help = DebugFlags::ProcessDebugFlags(&cmd_line, - DebugFlags::RENDERER, + ChildProcessInfo::RENDER_PROCESS, in_sandbox); #elif defined(OS_POSIX) if (browser_command_line.HasSwitch(switches::kRendererCmdPrefix)) { diff --git a/chrome/browser/task_manager_resource_providers.cc b/chrome/browser/task_manager_resource_providers.cc index f5983ca..ec95cbe 100644 --- a/chrome/browser/task_manager_resource_providers.cc +++ b/chrome/browser/task_manager_resource_providers.cc @@ -12,8 +12,6 @@ #include "grit/theme_resources.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_list.h" -#include "chrome/browser/plugin_process_host.h" -#include "chrome/browser/plugin_service.h" #include "chrome/browser/renderer_host/render_process_host.h" #include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/browser/tab_contents/tab_util.h" @@ -427,13 +425,13 @@ void TaskManagerChildProcessResourceProvider::AddToTaskManager( task_manager_->AddResource(resource); } -// The PluginProcessIterator has to be used from the IO thread. +// The ChildProcessInfo::Iterator has to be used from the IO thread. void TaskManagerChildProcessResourceProvider::RetrieveChildProcessInfo() { - for (PluginProcessHostIterator iter; !iter.Done(); ++iter) { - const ChildProcessInfo* child = *iter; - existing_child_process_info_.push_back(*child); + for (ChildProcessInfo::Iterator iter; !iter.Done(); ++iter) { + existing_child_process_info_.push_back(**iter); } - // Now notify the UI thread that we have retrieved the PluginProcessHosts. + // Now notify the UI thread that we have retrieved information about child + // processes. ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, &TaskManagerChildProcessResourceProvider::ChildProcessInfoRetreived)); } diff --git a/chrome/common/child_process_info.cc b/chrome/common/child_process_info.cc index ca777bd..af69e10 100644 --- a/chrome/common/child_process_info.cc +++ b/chrome/common/child_process_info.cc @@ -5,26 +5,31 @@ #include "chrome/common/child_process_info.h" #include "base/logging.h" +#include "base/singleton.h" +#include "chrome/browser/chrome_thread.h" #include "chrome/common/l10n_util.h" #include "generated_resources.h" +typedef std::list<ChildProcessInfo*> ChildProcessList; + + std::wstring ChildProcessInfo::GetTypeNameInEnglish( ChildProcessInfo::ProcessType type) { switch (type) { - case BROWSER_PROCESS: - return L"Browser"; - case RENDER_PROCESS: - return L"Tab"; - case PLUGIN_PROCESS: - return L"Plug-in"; - case WORKER_PROCESS: - return L"Web Worker"; - case UNKNOWN_PROCESS: - default: - DCHECK(false) << "Unknown child process type!"; - return L"Unknown"; - } + case BROWSER_PROCESS: + return L"Browser"; + case RENDER_PROCESS: + return L"Tab"; + case PLUGIN_PROCESS: + return L"Plug-in"; + case WORKER_PROCESS: + return L"Web Worker"; + case UNKNOWN_PROCESS: + default: + DCHECK(false) << "Unknown child process type!"; + return L"Unknown"; + } } std::wstring ChildProcessInfo::GetLocalizedTitle() const { @@ -49,3 +54,52 @@ std::wstring ChildProcessInfo::GetLocalizedTitle() const { l10n_util::AdjustStringForLocaleDirection(title, &title); return l10n_util::GetStringF(message_id, title); } + +ChildProcessInfo::ChildProcessInfo(ProcessType type) { + // This constructor is only used by objects which derive from this class, + // which means *this* is a real object that refers to a child process, and not + // just a simple object that contains information about it. So add it to our + // list of running processes. + type_ = type; + Singleton<ChildProcessList>::get()->push_back(this); +} + + +ChildProcessInfo::~ChildProcessInfo() { + Singleton<ChildProcessList>::get()->remove(this); +} + + +ChildProcessInfo::Iterator::Iterator() : all_(true) { + iterator_ = Singleton<ChildProcessList>::get()->begin(); + DCHECK(MessageLoop::current() == + ChromeThread::GetMessageLoop(ChromeThread::IO)) << + "ChildProcessInfo::Iterator must be used on the IO thread."; +} + +ChildProcessInfo::Iterator::Iterator(ProcessType type) + : all_(false), type_(type) { + iterator_ = Singleton<ChildProcessList>::get()->begin(); + DCHECK(MessageLoop::current() == + ChromeThread::GetMessageLoop(ChromeThread::IO)) << + "ChildProcessInfo::Iterator must be used on the IO thread."; +} + +ChildProcessInfo* ChildProcessInfo::Iterator::operator++() { + do { + ++iterator_; + if (Done()) + break; + + if (!all_ && (*iterator_)->type() != type_) + continue; + + return *iterator_; + } while (true); + + return NULL; +} + +bool ChildProcessInfo::Iterator::Done() { + return iterator_ == Singleton<ChildProcessList>::get()->end(); +} diff --git a/chrome/common/child_process_info.h b/chrome/common/child_process_info.h index 2007bcb..d95eac4 100644 --- a/chrome/common/child_process_info.h +++ b/chrome/common/child_process_info.h @@ -1,66 +1,116 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_COMMON_CHILD_PROCESS_INFO_H_ -#define CHROME_COMMON_CHILD_PROCESS_INFO_H_ - -#include <string> -#include "base/basictypes.h" -#include "base/process.h" - -// Holds information about a child process. -class ChildProcessInfo { - public: - enum ProcessType { - BROWSER_PROCESS, - RENDER_PROCESS, - PLUGIN_PROCESS, - WORKER_PROCESS, - UNKNOWN_PROCESS, - }; - - // Returns the type of the process. - ProcessType type() const { return type_; } - - // Returns the name of the process. i.e. for plugins it might be Flash, while - // for workers it might be the domain that it's from. - std::wstring name() const { return name_; } - - // Getter to the process. - base::Process& process() { return process_; } - - // Returns an English name of the process type, should only be used for non - // user-visible strings, or debugging pages like about:memory. - static std::wstring GetTypeNameInEnglish(ProcessType type); - - // Returns a localized title for the child process. For example, a plugin - // process would be "Plug-in: Flash" when name is "Flash". - std::wstring GetLocalizedTitle() const; - - // We define the < operator so that the ChildProcessInfo can be used as a key - // in a std::map. - bool operator <(const ChildProcessInfo& rhs) const { - if (process_.handle() != rhs.process_.handle()) - return process_ .handle() < rhs.process_.handle(); - return name_ < rhs.name_; - } - - bool operator ==(const ChildProcessInfo& rhs) const { - return (process_.handle() == rhs.process_.handle()) && (name_ == rhs.name_); - } - - protected: - void set_type(ProcessType type) { type_ = type; } - void set_name(const std::wstring& name) { name_ = name; } - - private: - ProcessType type_; - std::wstring name_; - - // The handle to the process. - base::Process process_; -}; - -#endif // CHROME_COMMON_CHILD_PROCESS_INFO_H_ - +// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_COMMON_CHILD_PROCESS_INFO_H_
+#define CHROME_COMMON_CHILD_PROCESS_INFO_H_
+
+#include <list>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/process.h"
+
+class ChildProcessInfo;
+
+// Holds information about a child process. Plugins/workers and other child
+// processes that live on the IO thread derive from this.
+class ChildProcessInfo {
+ public:
+ enum ProcessType {
+ BROWSER_PROCESS,
+ RENDER_PROCESS,
+ PLUGIN_PROCESS,
+ WORKER_PROCESS,
+ UNKNOWN_PROCESS,
+ };
+
+ // Returns the type of the process.
+ ProcessType type() const { return type_; }
+
+ // Returns the name of the process. i.e. for plugins it might be Flash, while
+ // for workers it might be the domain that it's from.
+ std::wstring name() const { return name_; }
+
+ // Getter to the process.
+ base::Process& process() { return process_; }
+
+ // Returns an English name of the process type, should only be used for non
+ // user-visible strings, or debugging pages like about:memory.
+ static std::wstring GetTypeNameInEnglish(ProcessType type);
+
+ // Returns a localized title for the child process. For example, a plugin
+ // process would be "Plug-in: Flash" when name is "Flash".
+ std::wstring GetLocalizedTitle() const;
+
+ ChildProcessInfo(const ChildProcessInfo& original) {
+ type_ = original.type_;
+ name_ = original.name_;
+ process_ = original.process_;
+ }
+
+ ChildProcessInfo& operator=(const ChildProcessInfo& original) {
+ if (&original != this) {
+ type_ = original.type_;
+ name_ = original.name_;
+ process_ = original.process_;
+ }
+ return *this;
+ }
+
+ ~ChildProcessInfo();
+
+ // We define the < operator so that the ChildProcessInfo can be used as a key
+ // in a std::map.
+ bool operator <(const ChildProcessInfo& rhs) const {
+ if (process_.handle() != rhs.process_.handle())
+ return process_ .handle() < rhs.process_.handle();
+ return name_ < rhs.name_;
+ }
+
+ bool operator ==(const ChildProcessInfo& rhs) const {
+ return (process_.handle() == rhs.process_.handle()) && (name_ == rhs.name_);
+ }
+
+ // The Iterator class allows iteration through either all child processes, or
+ // ones of a specific type, depending on which constructor is used. Note that
+ // this should be done from the IO thread and that the iterator should not be
+ // kept around as it may be invalidated on subsequent event processing in the
+ // event loop.
+ class Iterator {
+ public:
+ Iterator();
+ Iterator(ProcessType type);
+ ChildProcessInfo* operator->() { return *iterator_; }
+ ChildProcessInfo* operator*() { return *iterator_; }
+ ChildProcessInfo* operator++();
+ bool Done();
+
+ private:
+ bool all_;
+ ProcessType type_;
+ std::list<ChildProcessInfo*>::iterator iterator_;
+ };
+
+ protected:
+ void set_type(ProcessType type) { type_ = type; }
+ void set_name(const std::wstring& name) { name_ = name; }
+
+ // Derived objects need to use this constructor so we know what type we are.
+ ChildProcessInfo(ProcessType type);
+
+ private:
+ // By making the constructor private, we can ensure that ChildProcessInfo
+ // objects can only be created by creating objects derived from them (i.e.
+ // PluginProcessHost) or by using the copy constructor or assignment operator
+ // to create an object from the former.
+ ChildProcessInfo() { }
+
+ ProcessType type_;
+ std::wstring name_;
+
+ // The handle to the process.
+ base::Process process_;
+};
+
+#endif // CHROME_COMMON_CHILD_PROCESS_INFO_H_
diff --git a/chrome/common/debug_flags.cc b/chrome/common/debug_flags.cc index 9f62cbe..97c2725 100644 --- a/chrome/common/debug_flags.cc +++ b/chrome/common/debug_flags.cc @@ -9,7 +9,7 @@ #include "chrome/common/chrome_switches.h" bool DebugFlags::ProcessDebugFlags(CommandLine* command_line, - ChildProcessType type, + ChildProcessInfo::ProcessType type, bool is_in_sandbox) { bool should_help_child = false; const CommandLine& current_cmd_line = *CommandLine::ForCurrentProcess(); @@ -18,8 +18,10 @@ bool DebugFlags::ProcessDebugFlags(CommandLine* command_line, std::wstring value; value = current_cmd_line.GetSwitchValue(switches::kDebugChildren); if (value.empty() || - (type == RENDERER && value == switches::kRendererProcess) || - (type == PLUGIN && value == switches::kPluginProcess)) { + (type == ChildProcessInfo::RENDER_PROCESS && + value == switches::kRendererProcess) || + (type == ChildProcessInfo::PLUGIN_PROCESS && + value == switches::kPluginProcess)) { command_line->AppendSwitch(switches::kDebugOnStart); should_help_child = true; } @@ -29,8 +31,10 @@ bool DebugFlags::ProcessDebugFlags(CommandLine* command_line, std::wstring value; value = current_cmd_line.GetSwitchValue(switches::kWaitForDebuggerChildren); if (value.empty() || - (type == RENDERER && value == switches::kRendererProcess) || - (type == PLUGIN && value == switches::kPluginProcess)) { + (type == ChildProcessInfo::RENDER_PROCESS && + value == switches::kRendererProcess) || + (type == ChildProcessInfo::PLUGIN_PROCESS && + value == switches::kPluginProcess)) { command_line->AppendSwitch(switches::kWaitForDebugger); } command_line->AppendSwitchWithValue(switches::kWaitForDebuggerChildren, diff --git a/chrome/common/debug_flags.h b/chrome/common/debug_flags.h index c2115a9..1a6d813 100644 --- a/chrome/common/debug_flags.h +++ b/chrome/common/debug_flags.h @@ -5,6 +5,8 @@ #ifndef CHROME_COMMON_DEBUG_FLAGS_H__ #define CHROME_COMMON_DEBUG_FLAGS_H__ +#include "chrome/common/child_process_info.h" + class CommandLine; class DebugFlags { @@ -24,7 +26,7 @@ class DebugFlags { // calling the JIT debugger on it. It may only happen if // is_in_sandbox is true. static bool ProcessDebugFlags(CommandLine* command_line, - ChildProcessType type, + ChildProcessInfo::ProcessType type, bool is_in_sandbox); }; diff --git a/chrome/test/ui/ui_test.cc b/chrome/test/ui/ui_test.cc index 486ee0d..fc3b9a0 100644 --- a/chrome/test/ui/ui_test.cc +++ b/chrome/test/ui/ui_test.cc @@ -332,7 +332,8 @@ void UITest::LaunchBrowser(const CommandLine& arguments, bool clear_profile) { command_line.AppendSwitchWithValue(switches::kTestName, ui_test_name_); - DebugFlags::ProcessDebugFlags(&command_line, DebugFlags::UNKNOWN, false); + DebugFlags::ProcessDebugFlags( + &command_line, ChildProcessInfo::UNKNOWN_PROCESS, false); command_line.AppendArguments(arguments, false); // Clear user data directory to make sure test environment is consistent |