diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-01 21:20:47 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-01 21:20:47 +0000 |
commit | ec775ef9b36dbcb5ebbd4fa550443bfa94c53a9f (patch) | |
tree | 5400ae2c5876e13aeeec2ab6ebcfc54f3f479840 /chrome/browser/worker_host | |
parent | 4b5d64ff3d7d95247ed4f078d8bf585a1726794d (diff) | |
download | chromium_src-ec775ef9b36dbcb5ebbd4fa550443bfa94c53a9f.zip chromium_src-ec775ef9b36dbcb5ebbd4fa550443bfa94c53a9f.tar.gz chromium_src-ec775ef9b36dbcb5ebbd4fa550443bfa94c53a9f.tar.bz2 |
Run workers in separate processes.
Review URL: http://codereview.chromium.org/99016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15098 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/worker_host')
-rw-r--r-- | chrome/browser/worker_host/worker_process_host.cc | 65 | ||||
-rw-r--r-- | chrome/browser/worker_host/worker_process_host.h | 23 | ||||
-rw-r--r-- | chrome/browser/worker_host/worker_service.cc | 37 | ||||
-rw-r--r-- | chrome/browser/worker_host/worker_service.h | 29 |
4 files changed, 114 insertions, 40 deletions
diff --git a/chrome/browser/worker_host/worker_process_host.cc b/chrome/browser/worker_host/worker_process_host.cc index 4bb11ae..abf71d1 100644 --- a/chrome/browser/worker_host/worker_process_host.cc +++ b/chrome/browser/worker_host/worker_process_host.cc @@ -13,7 +13,6 @@ #include "base/string_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/browser/worker_host/worker_service.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/debug_flags.h" @@ -52,10 +51,13 @@ WorkerProcessHost::WorkerProcessHost( } WorkerProcessHost::~WorkerProcessHost() { + WorkerService::GetInstance()->NotifySenderShutdown(this); + // If we crashed, tell the RenderViewHost. + MessageLoop* ui_loop = WorkerService::GetInstance()->ui_loop(); for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { - i->filter->ui_loop()->PostTask(FROM_HERE, new WorkerCrashTask( - i->filter->GetProcessId(), i->render_view_route_id)); + ui_loop->PostTask(FROM_HERE, new WorkerCrashTask( + i->renderer_process_id, i->render_view_route_id)); } } @@ -71,6 +73,12 @@ bool WorkerProcessHost::Init() { cmd_line.AppendSwitchWithValue(switches::kProcessType, switches::kWorkerProcess); cmd_line.AppendSwitchWithValue(switches::kProcessChannelID, channel_id()); + + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kWebWorkerShareProcesses)) { + cmd_line.AppendSwitch(switches::kWebWorkerShareProcesses); + } + base::ProcessHandle process; #if defined(OS_WIN) process = sandbox::StartProcess(&cmd_line); @@ -85,25 +93,31 @@ bool WorkerProcessHost::Init() { } void WorkerProcessHost::CreateWorker(const GURL& url, + int renderer_process_id, int render_view_route_id, int worker_route_id, - int renderer_route_id, - ResourceMessageFilter* filter) { + IPC::Message::Sender* sender, + int sender_pid, + int sender_route_id) { WorkerInstance instance; instance.url = url; + instance.renderer_process_id = renderer_process_id; instance.render_view_route_id = render_view_route_id; instance.worker_route_id = worker_route_id; - instance.renderer_route_id = renderer_route_id; - instance.filter = filter; + instance.sender = sender; + instance.sender_pid = sender_pid; + instance.sender_route_id = sender_route_id; instances_.push_back(instance); Send(new WorkerProcessMsg_CreateWorker(url, worker_route_id)); UpdateTitle(); } -bool WorkerProcessHost::FilterMessage(const IPC::Message& message) { +bool WorkerProcessHost::FilterMessage(const IPC::Message& message, + int sender_pid) { for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { - if (i->renderer_route_id == message.routing_id()) { + if (i->sender_pid == sender_pid && + i->sender_route_id == message.routing_id()) { IPC::Message* new_message = new IPC::Message(message); new_message->set_routing_id(i->worker_route_id); Send(new_message); @@ -121,11 +135,22 @@ URLRequestContext* WorkerProcessHost::GetRequestContext( } void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(WorkerProcessHost, message) + IPC_MESSAGE_HANDLER(ViewHostMsg_CreateDedicatedWorker, + OnCreateDedicatedWorker) + IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToWorker, + OnForwardToWorker) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP_EX() + if (handled) + return; + for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { if (i->worker_route_id == message.routing_id()) { IPC::Message* new_message = new IPC::Message(message); - new_message->set_routing_id(i->renderer_route_id); - i->filter->Send(new_message); + new_message->set_routing_id(i->sender_route_id); + i->sender->Send(new_message); if (message.type() == WorkerHostMsg_WorkerContextDestroyed::ID) { instances_.erase(i); @@ -136,9 +161,9 @@ void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) { } } -void WorkerProcessHost::RendererShutdown(ResourceMessageFilter* filter) { +void WorkerProcessHost::SenderShutdown(IPC::Message::Sender* sender) { for (Instances::iterator i = instances_.begin(); i != instances_.end();) { - if (i->filter == filter) { + if (i->sender == sender) { i = instances_.erase(i); } else { ++i; @@ -170,3 +195,17 @@ void WorkerProcessHost::UpdateTitle() { set_name(ASCIIToWide(display_title)); } + +void WorkerProcessHost::OnCreateDedicatedWorker(const GURL& url, + int render_view_route_id, + int* route_id) { + DCHECK(instances_.size() == 1); // Only called when one process per worker. + *route_id = WorkerService::GetInstance()->next_worker_route_id(); + WorkerService::GetInstance()->CreateDedicatedWorker( + url, instances_.front().renderer_process_id, + instances_.front().render_view_route_id, this, GetProcessId(), *route_id); +} + +void WorkerProcessHost::OnForwardToWorker(const IPC::Message& message) { + WorkerService::GetInstance()->ForwardMessage(message, GetProcessId()); +} diff --git a/chrome/browser/worker_host/worker_process_host.h b/chrome/browser/worker_host/worker_process_host.h index 5432396..5474724 100644 --- a/chrome/browser/worker_host/worker_process_host.h +++ b/chrome/browser/worker_host/worker_process_host.h @@ -12,8 +12,6 @@ #include "chrome/common/ipc_channel.h" #include "googleurl/src/gurl.h" -class ResourceMessageFilter; - class WorkerProcessHost : public ChildProcessHost { public: WorkerProcessHost(ResourceDispatcherHost* resource_dispatcher_host_); @@ -24,16 +22,18 @@ class WorkerProcessHost : public ChildProcessHost { // Creates a worker object in the process. void CreateWorker(const GURL& url, + int renderer_process_id, int render_view_route_id, int worker_route_id, - int renderer_route_id, - ResourceMessageFilter* filter); + IPC::Message::Sender* sender, + int sender_pid, + int sender_route_id); // Returns true iff the given message from a renderer process was forwarded to // the worker. - bool FilterMessage(const IPC::Message& message); + bool FilterMessage(const IPC::Message& message, int sender_pid); - void RendererShutdown(ResourceMessageFilter* filter); + void SenderShutdown(IPC::Message::Sender* sender); protected: friend class WorkerService; @@ -42,10 +42,12 @@ class WorkerProcessHost : public ChildProcessHost { // between the renderer and worker processes. struct WorkerInstance { GURL url; + int renderer_process_id; int render_view_route_id; int worker_route_id; - int renderer_route_id; - ResourceMessageFilter* filter; + IPC::Message::Sender* sender; + int sender_pid; + int sender_route_id; }; typedef std::list<WorkerInstance> Instances; @@ -65,6 +67,11 @@ class WorkerProcessHost : public ChildProcessHost { // Updates the title shown in the task manager. void UpdateTitle(); + void OnCreateDedicatedWorker(const GURL& url, + int render_view_route_id, + int* route_id); + void OnForwardToWorker(const IPC::Message& message); + Instances instances_; DISALLOW_COPY_AND_ASSIGN(WorkerProcessHost); diff --git a/chrome/browser/worker_host/worker_service.cc b/chrome/browser/worker_host/worker_service.cc index 49e25bc..a90c30e 100644 --- a/chrome/browser/worker_host/worker_service.cc +++ b/chrome/browser/worker_host/worker_service.cc @@ -25,7 +25,10 @@ WorkerService* WorkerService::GetInstance() { return Singleton<WorkerService>::get(); } -WorkerService::WorkerService() : next_worker_route_id_(0) { +WorkerService::WorkerService() + : next_worker_route_id_(0), + resource_dispatcher_host_(NULL), + ui_loop_(NULL) { // Receive a notification if the message filter is deleted. NotificationService::current()->AddObserver( this, @@ -33,24 +36,33 @@ WorkerService::WorkerService() : next_worker_route_id_(0) { NotificationService::AllSources()); } +void WorkerService::Initialize(ResourceDispatcherHost* rdh, + MessageLoop* ui_loop) { + resource_dispatcher_host_ = rdh; + ui_loop_ = ui_loop; +} + WorkerService::~WorkerService() { } bool WorkerService::CreateDedicatedWorker(const GURL &url, + int renderer_process_id, int render_view_route_id, - ResourceMessageFilter* filter, - int renderer_route_id) { + IPC::Message::Sender* sender, + int sender_pid, + int sender_route_id) { WorkerProcessHost* worker = NULL; if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kWebWorkerProcessPerCore)) { worker = GetProcessToFillUpCores(); - } else { + } else if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kWebWorkerShareProcesses)) { worker = GetProcessForDomain(url); } if (!worker) { - worker = new WorkerProcessHost(filter->resource_dispatcher_host()); + worker = new WorkerProcessHost(resource_dispatcher_host_); if (!worker->Init()) { delete worker; return false; @@ -61,17 +73,19 @@ bool WorkerService::CreateDedicatedWorker(const GURL &url, // unique among all worker processes. That way when the worker process sends // a wrapped IPC message through us, we know which WorkerProcessHost to give // it to. - worker->CreateWorker(url, render_view_route_id, ++next_worker_route_id_, - renderer_route_id, filter); + worker->CreateWorker(url, renderer_process_id, render_view_route_id, + next_worker_route_id(), sender, sender_pid, + sender_route_id); return true; } -void WorkerService::ForwardMessage(const IPC::Message& message) { +void WorkerService::ForwardMessage(const IPC::Message& message, + int sender_pid) { for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); !iter.Done(); ++iter) { WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); - if (worker->FilterMessage(message)) + if (worker->FilterMessage(message, sender_pid)) return; } @@ -131,10 +145,13 @@ void WorkerService::Observe(NotificationType type, const NotificationDetails& details) { DCHECK(type.value == NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN); ResourceMessageFilter* filter = Source<ResourceMessageFilter>(source).ptr(); + NotifySenderShutdown(filter); +} +void WorkerService::NotifySenderShutdown(IPC::Message::Sender* sender) { for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS); !iter.Done(); ++iter) { WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter); - worker->RendererShutdown(filter); + worker->SenderShutdown(sender); } } diff --git a/chrome/browser/worker_host/worker_service.h b/chrome/browser/worker_host/worker_service.h index cf18d58..0a88071 100644 --- a/chrome/browser/worker_host/worker_service.h +++ b/chrome/browser/worker_host/worker_service.h @@ -9,37 +9,46 @@ #include "base/basictypes.h" #include "base/singleton.h" +#include "chrome/common/ipc_message.h" #include "chrome/common/notification_observer.h" #include "googleurl/src/gurl.h" -namespace IPC { -class Message; -} class MessageLoop; class WorkerProcessHost; -class ResourceMessageFilter; +class ResourceDispatcherHost; class WorkerService : public NotificationObserver { public: // Returns the WorkerService singleton. static WorkerService* GetInstance(); + // Initialize the WorkerService. OK to be called multiple times. + void Initialize(ResourceDispatcherHost* rdh, MessageLoop* ui_loop); + // Creates a dedicated worker. Returns true on success. bool CreateDedicatedWorker(const GURL &url, + int renderer_process_id, int render_view_route_id, - ResourceMessageFilter* filter, - int renderer_route_id); + IPC::Message::Sender* sender, + int sender_pid, + int sender_route_id); - // Called by ResourceMessageFilter when a message from the renderer comes that - // should be forwarded to the worker process. - void ForwardMessage(const IPC::Message& message); + // Called by the worker creator when a message arrives that should be + // forwarded to the worker process. + void ForwardMessage(const IPC::Message& message, int sender_pid); // NotificationObserver interface. void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); + void NotifySenderShutdown(IPC::Message::Sender* sender); + + MessageLoop* ui_loop() { return ui_loop_; } + + int next_worker_route_id() { return ++next_worker_route_id_; } + private: friend struct DefaultSingletonTraits<WorkerService>; @@ -59,6 +68,8 @@ class WorkerService : public NotificationObserver { WorkerProcessHost* GetLeastLoadedWorker(); int next_worker_route_id_; + ResourceDispatcherHost* resource_dispatcher_host_; + MessageLoop* ui_loop_; DISALLOW_COPY_AND_ASSIGN(WorkerService); }; |