summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-04 00:39:56 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-04 00:39:56 +0000
commiteb47a137b7ce84a6df0ccc9550c75b6bec60eb68 (patch)
tree7f6c4e1d169bf60465a0b642a4434a239aaf0f6d /chrome/renderer
parent0ff03ae3f1bf6f877a4aa32263f6418f2c5797d2 (diff)
downloadchromium_src-eb47a137b7ce84a6df0ccc9550c75b6bec60eb68.zip
chromium_src-eb47a137b7ce84a6df0ccc9550c75b6bec60eb68.tar.gz
chromium_src-eb47a137b7ce84a6df0ccc9550c75b6bec60eb68.tar.bz2
Initial checkin of the out of process worker implementation.
WebWorkerClient/WebWorker are parallel interfaces of WebCore::{WorkerObjectProxy, WorkerContextProxy} that use Chrome data types. When WebKit requests a WorkerObjectProxy, we create an instance of WebWorkerClientImpl. This class creates an object that implements a Chromium version of WorkerObjectProxy (i.e. with Chrome data types) through WebViewDelegate. That object is a WebWorkerProxy and talks over IPC to a WebWorker object in the worker process. The WebWorker object creates the actual WebCore::Worker object using another class in glue: WebWorkerImpl. When the WebCore::Worker object running in the worker process wants to talk back to the code running in the renderer, it talks to WebWorkerImpl which implements WebCore::WorkerObjectProxy. WebWorkerImpl converts the data types to Chrome compatible ones, and then calls the WebWorkerClient version which does IPC to get to the renderer process. This ends up at WebWorkerProxy, which calls WebWorkerClientImpl (the original class). In future changes, sandboxing, multiple worker processes etc will be added. Note that I also had to make two small changes to WebKit, since WorkerMessagingProxy couldn't be created as is for the nested worker case. I'll either check it in myself or work with Jian to do so. Review URL: http://codereview.chromium.org/27157 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10847 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/render_thread.cc6
-rw-r--r--chrome/renderer/render_view.cc11
-rw-r--r--chrome/renderer/render_view.h1
-rw-r--r--chrome/renderer/renderer.scons2
-rw-r--r--chrome/renderer/renderer.vcproj8
-rw-r--r--chrome/renderer/webworker_proxy.cc92
-rw-r--r--chrome/renderer/webworker_proxy.h56
7 files changed, 172 insertions, 4 deletions
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 1870c00..f244092 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -40,8 +40,6 @@
static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */;
-// V8 needs a 1MB stack size.
-static const size_t kStackSize = 1024 * 1024;
//-----------------------------------------------------------------------------
// Methods below are only called on the owner's thread:
@@ -51,13 +49,13 @@ static const size_t kStackSize = 1024 * 1024;
RenderThread::RenderThread()
: ChildThread(
base::Thread::Options(RenderProcess::InProcessPlugins() ?
- MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kStackSize)) {
+ MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kV8StackSize)) {
}
RenderThread::RenderThread(const std::wstring& channel_name)
: ChildThread(
base::Thread::Options(RenderProcess::InProcessPlugins() ?
- MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kStackSize)) {
+ MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kV8StackSize)) {
SetChannelName(channel_name);
}
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 59ba2c9..461f99c 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -36,6 +36,7 @@
#include "chrome/renderer/visitedlink_slave.h"
#include "chrome/renderer/webmediaplayer_delegate_impl.h"
#include "chrome/renderer/webplugin_delegate_proxy.h"
+#include "chrome/renderer/webworker_proxy.h"
#include "grit/generated_resources.h"
#include "grit/renderer_resources.h"
#include "net/base/escape.h"
@@ -1973,6 +1974,16 @@ void RenderView::OnMissingPluginStatus(WebPluginDelegate* delegate,
#endif
}
+WebWorker* RenderView::CreateWebWorker(WebWorkerClient* client) {
+#if defined(OS_WIN)
+ return new WebWorkerProxy(this, client);
+#else
+ // TODO(port): out of process workers
+ NOTIMPLEMENTED();
+ return NULL;
+#endif
+}
+
void RenderView::OpenURL(WebView* webview, const GURL& url,
const GURL& referrer,
WindowOpenDisposition disposition) {
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 3ce6c3c..1c0078c 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -239,6 +239,7 @@ class RenderView : public RenderWidget,
const std::string& mime_type,
const std::string& clsid,
std::string* actual_mime_type);
+ virtual WebWorker* CreateWebWorker(WebWorkerClient* client);
virtual webkit_glue::WebMediaPlayerDelegate* CreateMediaPlayerDelegate();
virtual void OnMissingPluginStatus(WebPluginDelegate* delegate, int status);
virtual void OpenURL(WebView* webview, const GURL& url,
diff --git a/chrome/renderer/renderer.scons b/chrome/renderer/renderer.scons
index e8dfddd..62b6d57 100644
--- a/chrome/renderer/renderer.scons
+++ b/chrome/renderer/renderer.scons
@@ -108,6 +108,8 @@ input_files = ChromeFileList([
'webmediaplayer_delegate_impl.h',
'webplugin_delegate_proxy.cc',
'webplugin_delegate_proxy.h',
+ 'webworker_proxy.cc',
+ 'webworker_proxy.h',
])
if not env.Bit('windows'):
diff --git a/chrome/renderer/renderer.vcproj b/chrome/renderer/renderer.vcproj
index 908f55d..a566716f 100644
--- a/chrome/renderer/renderer.vcproj
+++ b/chrome/renderer/renderer.vcproj
@@ -393,6 +393,14 @@
RelativePath=".\webplugin_delegate_proxy.h"
>
</File>
+ <File
+ RelativePath=".\webworker_proxy.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\webworker_proxy.h"
+ >
+ </File>
</Files>
<Globals>
</Globals>
diff --git a/chrome/renderer/webworker_proxy.cc b/chrome/renderer/webworker_proxy.cc
new file mode 100644
index 0000000..c271e40
--- /dev/null
+++ b/chrome/renderer/webworker_proxy.cc
@@ -0,0 +1,92 @@
+// 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.
+
+#include "chrome/renderer/webworker_proxy.h"
+
+#include "chrome/common/render_messages.h"
+#include "chrome/common/worker_messages.h"
+#include "chrome/renderer/render_thread.h"
+#include "webkit/glue/webworkerclient.h"
+
+WebWorkerProxy::WebWorkerProxy(
+ IPC::Message::Sender* sender, WebWorkerClient* client)
+ : sender_(sender),
+ route_id_(MSG_ROUTING_NONE),
+ client_(client) {
+}
+
+WebWorkerProxy::~WebWorkerProxy() {
+}
+
+void WebWorkerProxy::StartWorkerContext(
+ const GURL& script_url,
+ const string16& user_agent,
+ const string16& source_code) {
+ sender_->Send(
+ new ViewHostMsg_CreateDedicatedWorker(script_url, &route_id_));
+ if (route_id_ == MSG_ROUTING_NONE)
+ return;
+
+ RenderThread::current()->AddRoute(route_id_, this);
+ Send(new WorkerMsg_StartWorkerContext(
+ route_id_, script_url, user_agent, source_code));
+}
+
+void WebWorkerProxy::TerminateWorkerContext() {
+ if (route_id_ != MSG_ROUTING_NONE) {
+ Send(new WorkerMsg_TerminateWorkerContext(route_id_));
+ RenderThread::current()->RemoveRoute(route_id_);
+ route_id_ = MSG_ROUTING_NONE;
+ }
+}
+
+void WebWorkerProxy::PostMessageToWorkerContext(
+ const string16& message) {
+ Send(new WorkerMsg_PostMessageToWorkerContext(route_id_, message));
+}
+
+void WebWorkerProxy::WorkerObjectDestroyed() {
+ client_ = NULL;
+ Send(new WorkerMsg_WorkerObjectDestroyed(route_id_));
+}
+
+bool WebWorkerProxy::Send(IPC::Message* message) {
+ if (route_id_ == MSG_ROUTING_NONE) {
+ delete message;
+ return false;
+ }
+
+ // For now we proxy all messages to the worker process through the browser.
+ // Revisit if we find this slow.
+ // TODO(jabdelmalek): handle sync messages if we need them.
+ IPC::Message* wrapped_msg = new ViewHostMsg_ForwardToWorker(*message);
+ delete message;
+ return sender_->Send(wrapped_msg);
+}
+
+void WebWorkerProxy::OnMessageReceived(const IPC::Message& message) {
+ if (!client_)
+ return;
+
+ IPC_BEGIN_MESSAGE_MAP(WebWorkerProxy, message)
+ IPC_MESSAGE_FORWARD(WorkerHostMsg_PostMessageToWorkerObject,
+ client_,
+ WebWorkerClient::PostMessageToWorkerObject)
+ IPC_MESSAGE_FORWARD(WorkerHostMsg_PostExceptionToWorkerObject,
+ client_,
+ WebWorkerClient::PostExceptionToWorkerObject)
+ IPC_MESSAGE_FORWARD(WorkerHostMsg_PostConsoleMessageToWorkerObject,
+ client_,
+ WebWorkerClient::PostConsoleMessageToWorkerObject)
+ IPC_MESSAGE_FORWARD(WorkerHostMsg_ConfirmMessageFromWorkerObject,
+ client_,
+ WebWorkerClient::ConfirmMessageFromWorkerObject)
+ IPC_MESSAGE_FORWARD(WorkerHostMsg_ReportPendingActivity,
+ client_,
+ WebWorkerClient::ReportPendingActivity)
+ IPC_MESSAGE_FORWARD(WorkerHostMsg_WorkerContextDestroyed,
+ client_,
+ WebWorkerClient::WorkerContextDestroyed)
+ IPC_END_MESSAGE_MAP()
+}
diff --git a/chrome/renderer/webworker_proxy.h b/chrome/renderer/webworker_proxy.h
new file mode 100644
index 0000000..019ff0d
--- /dev/null
+++ b/chrome/renderer/webworker_proxy.h
@@ -0,0 +1,56 @@
+// 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_RENDERER_WEBWORKER_PROXY_H_
+#define CHROME_RENDERER_WEBWORKER_PROXY_H_
+
+#include "base/basictypes.h"
+#include "chrome/common/ipc_channel.h"
+#include "webkit/glue/webworker.h"
+
+class GURL;
+class RenderView;
+
+namespace IPC {
+class Message;
+}
+
+// This class provides an implementation of WebWorker that the renderer provides
+// to the glue. This class converts function calls to IPC messages that are
+// dispatched in the worker process by WebWorkerClientProxy. It also receives
+// IPC messages from WebWorkerClientProxy which it converts to function calls to
+// WebWorkerClient.
+class WebWorkerProxy : public WebWorker,
+ public IPC::Channel::Listener {
+ public:
+ WebWorkerProxy(IPC::Message::Sender* sender, WebWorkerClient* client);
+ virtual ~WebWorkerProxy();
+
+ // WebWorker implementation.
+ // These functions are called by WebKit (after the data types have been
+ // converted by glue code).
+ virtual void StartWorkerContext(const GURL& script_url,
+ const string16& user_agent,
+ const string16& source_code);
+ virtual void TerminateWorkerContext();
+ virtual void PostMessageToWorkerContext(const string16& message);
+ virtual void WorkerObjectDestroyed();
+
+ // IPC::Channel::Listener implementation.
+ void OnMessageReceived(const IPC::Message& message);
+
+ private:
+ bool Send(IPC::Message* message);
+
+ IPC::Message::Sender* sender_;
+ int route_id_;
+
+ // Used to communicate to the WebCore::Worker object in response to IPC
+ // messages.
+ WebWorkerClient* client_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebWorkerProxy);
+};
+
+#endif // CHROME_RENDERER_WEBWORKER_PROXY_H_