summaryrefslogtreecommitdiffstats
path: root/chrome/browser/worker_host
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-01 21:20:47 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-01 21:20:47 +0000
commitec775ef9b36dbcb5ebbd4fa550443bfa94c53a9f (patch)
tree5400ae2c5876e13aeeec2ab6ebcfc54f3f479840 /chrome/browser/worker_host
parent4b5d64ff3d7d95247ed4f078d8bf585a1726794d (diff)
downloadchromium_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.cc65
-rw-r--r--chrome/browser/worker_host/worker_process_host.h23
-rw-r--r--chrome/browser/worker_host/worker_service.cc37
-rw-r--r--chrome/browser/worker_host/worker_service.h29
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);
};