summaryrefslogtreecommitdiffstats
path: root/webkit
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 /webkit
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 'webkit')
-rw-r--r--webkit/glue/glue.vcproj24
-rw-r--r--webkit/glue/webview_delegate.h7
-rw-r--r--webkit/glue/webworker.h31
-rw-r--r--webkit/glue/webworker_impl.cc91
-rw-r--r--webkit/glue/webworker_impl.h57
-rw-r--r--webkit/glue/webworkerclient.h36
-rw-r--r--webkit/glue/webworkerclient_impl.cc128
-rw-r--r--webkit/glue/webworkerclient_impl.h61
8 files changed, 435 insertions, 0 deletions
diff --git a/webkit/glue/glue.vcproj b/webkit/glue/glue.vcproj
index 4ce48b8..34a6b0b 100644
--- a/webkit/glue/glue.vcproj
+++ b/webkit/glue/glue.vcproj
@@ -249,6 +249,14 @@
>
</File>
<File
+ RelativePath=".\webworker.h"
+ >
+ </File>
+ <File
+ RelativePath=".\webworkerclient.h"
+ >
+ </File>
+ <File
RelativePath=".\window_open_disposition.h"
>
</File>
@@ -700,6 +708,22 @@
RelativePath=".\webwidget_impl.h"
>
</File>
+ <File
+ RelativePath=".\webworker_impl.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\webworker_impl.h"
+ >
+ </File>
+ <File
+ RelativePath=".\webworkerclient_impl.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\webworkerclient_impl.h"
+ >
+ </File>
</Filter>
<Filter
Name="Plugins"
diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h
index 7ef577a..59d4d95 100644
--- a/webkit/glue/webview_delegate.h
+++ b/webkit/glue/webview_delegate.h
@@ -54,6 +54,8 @@ class WebRequest;
class WebResponse;
class WebView;
class WebWidget;
+class WebWorker;
+class WebWorkerClient;
enum WebNavigationType {
WebNavigationTypeLinkClicked,
@@ -127,6 +129,11 @@ class WebViewDelegate : virtual public WebWidgetDelegate {
return NULL;
}
+ // This method is called when the renderer creates a worker object.
+ virtual WebWorker* CreateWebWorker(WebWorkerClient* client) {
+ return NULL;
+ }
+
// Called when a WebMediaPlayerDelegate is needed.
virtual webkit_glue::WebMediaPlayerDelegate* CreateMediaPlayerDelegate() {
return NULL;
diff --git a/webkit/glue/webworker.h b/webkit/glue/webworker.h
new file mode 100644
index 0000000..302fa24
--- /dev/null
+++ b/webkit/glue/webworker.h
@@ -0,0 +1,31 @@
+// 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 WEBKIT_GLUE_WEBWORKER_H_
+#define WEBKIT_GLUE_WEBWORKER_H_
+
+#include "base/string16.h"
+
+class GURL;
+class WebWorkerClient;
+
+// This is a version of the WebCore::WorkerContextProxy interface that uses
+// Chrome data types.
+class WebWorker {
+ public:
+ virtual ~WebWorker() { }
+
+ // Creates a WebWorker object that wraps around the WebKit code that implements
+ // web workers.
+ static WebWorker* Create(WebWorkerClient* client);
+
+ virtual void StartWorkerContext(const GURL& script_url,
+ const string16& user_agent,
+ const string16& source_code) = 0;
+ virtual void TerminateWorkerContext() = 0;
+ virtual void PostMessageToWorkerContext(const string16& message) = 0;
+ virtual void WorkerObjectDestroyed() = 0;
+};
+
+#endif // #ifndef WEBKIT_GLUE_WEBWORKER_H_
diff --git a/webkit/glue/webworker_impl.cc b/webkit/glue/webworker_impl.cc
new file mode 100644
index 0000000..3bb5d20
--- /dev/null
+++ b/webkit/glue/webworker_impl.cc
@@ -0,0 +1,91 @@
+// 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 "config.h"
+
+#include "base/compiler_specific.h"
+#include "webkit/glue/glue_util.h"
+#include "webkit/glue/webworkerclient.h"
+#include "webkit/glue/webworker_impl.h"
+
+#if ENABLE(WORKERS)
+
+
+WebWorker* WebWorker::Create(WebWorkerClient* client) {
+ return new WebWorkerImpl(client);
+}
+
+
+WebWorkerImpl::WebWorkerImpl(WebWorkerClient* client) : client_(client) {
+}
+
+WebWorkerImpl::~WebWorkerImpl() {
+}
+
+void WebWorkerImpl::StartWorkerContext(const GURL& script_url,
+ const string16& user_agent,
+ const string16& source_code) {
+ // TODO(jianli): implement WorkerContextProxy here (i.e. create WorkerThread
+ // etc). The WebKit code uses worker_object_proxy_ when it wants to talk to
+ // code running in the renderer process.
+}
+
+void WebWorkerImpl::TerminateWorkerContext() {
+}
+
+void WebWorkerImpl::PostMessageToWorkerContext(const string16& message) {
+}
+
+void WebWorkerImpl::WorkerObjectDestroyed() {
+}
+
+void WebWorkerImpl::postMessageToWorkerObject(const WebCore::String& message) {
+ client_->PostMessageToWorkerObject(webkit_glue::StringToString16(message));
+}
+
+void WebWorkerImpl::postExceptionToWorkerObject(
+ const WebCore::String& errorMessage,
+ int lineNumber,
+ const WebCore::String& sourceURL) {
+ client_->PostExceptionToWorkerObject(
+ webkit_glue::StringToString16(errorMessage),
+ lineNumber,
+ webkit_glue::StringToString16(sourceURL));
+}
+
+void WebWorkerImpl::postConsoleMessageToWorkerObject(
+ WebCore::MessageDestination destination,
+ WebCore::MessageSource source,
+ WebCore::MessageLevel level,
+ const WebCore::String& message,
+ int lineNumber,
+ const WebCore::String& sourceURL) {
+ client_->PostConsoleMessageToWorkerObject(
+ destination,
+ source,
+ level,
+ webkit_glue::StringToString16(message),
+ lineNumber,
+ webkit_glue::StringToString16(sourceURL));
+}
+
+void WebWorkerImpl::confirmMessageFromWorkerObject(bool hasPendingActivity) {
+ client_->ConfirmMessageFromWorkerObject(hasPendingActivity);
+}
+
+void WebWorkerImpl::reportPendingActivity(bool hasPendingActivity) {
+ client_->ReportPendingActivity(hasPendingActivity);
+}
+
+void WebWorkerImpl::workerContextDestroyed() {
+ client_->WorkerContextDestroyed();
+}
+
+#else
+
+WebWorker* WebWorker::Create(WebWorkerClient* client) {
+ return NULL;
+}
+
+#endif
diff --git a/webkit/glue/webworker_impl.h b/webkit/glue/webworker_impl.h
new file mode 100644
index 0000000..9903cea
--- /dev/null
+++ b/webkit/glue/webworker_impl.h
@@ -0,0 +1,57 @@
+// 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 WEBKIT_GLUE_WEBWORKER_IMPL_H_
+#define WEBKIT_GLUE_WEBWORKER_IMPL_H_
+
+#include "webkit/glue/webworker.h"
+
+#if ENABLE(WORKERS)
+
+#include "ScriptExecutionContext.h"
+#include "WorkerObjectProxy.h"
+
+// This class is used by the worker process code to talk to the WebCore::Worker
+// implementation. It can't use it directly since it uses WebKit types, so this
+// class converts the data types. When the WebCore::Worker object wants to call
+// WebCore::WorkerObjectProxy, this class will conver to Chrome data types first
+// and then call the supplied WebWorkerClient.
+class WebWorkerImpl: public WebCore::WorkerObjectProxy,
+ public WebWorker {
+ public:
+ WebWorkerImpl(WebWorkerClient* client);
+ virtual ~WebWorkerImpl();
+
+ // WebCore::WorkerObjectProxy implementation.
+ void postMessageToWorkerObject(const WebCore::String& message);
+ void postExceptionToWorkerObject(const WebCore::String& errorMessage,
+ int lineNumber,
+ const WebCore::String& sourceURL);
+ void postConsoleMessageToWorkerObject(WebCore::MessageDestination destination,
+ WebCore::MessageSource source,
+ WebCore::MessageLevel level,
+ const WebCore::String& message,
+ int lineNumber,
+ const WebCore::String& sourceURL);
+ void confirmMessageFromWorkerObject(bool hasPendingActivity);
+ void reportPendingActivity(bool hasPendingActivity);
+ void workerContextDestroyed();
+
+ // WebWorker implementation.
+ void StartWorkerContext(const GURL& script_url,
+ const string16& user_agent,
+ const string16& source_code);
+ void TerminateWorkerContext();
+ void PostMessageToWorkerContext(const string16& message);
+ void WorkerObjectDestroyed();
+
+ private:
+ WebWorkerClient* client_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebWorkerImpl);
+};
+
+#endif
+
+#endif // WEBKIT_GLUE_WEBWORKER_IMPL_H_
diff --git a/webkit/glue/webworkerclient.h b/webkit/glue/webworkerclient.h
new file mode 100644
index 0000000..aaa56b8
--- /dev/null
+++ b/webkit/glue/webworkerclient.h
@@ -0,0 +1,36 @@
+// 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 WEBKIT_GLUE_WEBWORKERCLIENT_H_
+#define WEBKIT_GLUE_WEBWORKERCLIENT_H_
+
+#include "base/string16.h"
+
+// This is a version of the WebCore::WorkerObjectProxy interface that uses
+// Chrome data types.
+class WebWorkerClient {
+ public:
+ virtual ~WebWorkerClient() { }
+
+ virtual void PostMessageToWorkerObject(const string16& message) = 0;
+ virtual void PostExceptionToWorkerObject(
+ const string16& error_message,
+ int line_number,
+ const string16& source_url) = 0;
+ // destination, source, and level are the int values of the corresponding
+ // WebKit enums. This avoids duplicating the enums and having to stay up to
+ // date.
+ virtual void PostConsoleMessageToWorkerObject(
+ int destination,
+ int source,
+ int level,
+ const string16& message,
+ int line_number,
+ const string16& source_url) = 0;
+ virtual void ConfirmMessageFromWorkerObject(bool has_pending_activity) = 0;
+ virtual void ReportPendingActivity(bool has_pending_activity) = 0;
+ virtual void WorkerContextDestroyed() = 0;
+};
+
+#endif // #ifndef WEBKIT_GLUE_WEBWORKERCLIENT_H_
diff --git a/webkit/glue/webworkerclient_impl.cc b/webkit/glue/webworkerclient_impl.cc
new file mode 100644
index 0000000..d140681
--- /dev/null
+++ b/webkit/glue/webworkerclient_impl.cc
@@ -0,0 +1,128 @@
+// 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 "config.h"
+
+#if ENABLE(WORKERS)
+
+#include "base/compiler_specific.h"
+
+#include "Frame.h"
+#include "FrameLoaderClient.h"
+#include "WorkerMessagingProxy.h"
+#include "Worker.h"
+
+#undef LOG
+
+#include "webkit/glue/webworkerclient_impl.h"
+
+#include "webkit/glue/glue_util.h"
+#include "webkit/glue/webframeloaderclient_impl.h"
+#include "webkit/glue/webframe_impl.h"
+#include "webkit/glue/webview_delegate.h"
+#include "webkit/glue/webview_impl.h"
+#include "webkit/glue/webworker.h"
+
+
+// When WebKit creates a WorkerContextProxy object, we check if we're in the
+// renderer or worker process. If the latter, then we just use
+// WebCore::WorkerMessagingProxy.
+//
+// If we're in the renderer process, then we need use the glue provided
+// WebWorker object to talk to the worker process over IPC. The worker process
+// talks to WebCore::Worker* using WorkerObjectProxy, which we implement on
+// WebWorkerClientImpl.
+WebCore::WorkerContextProxy* WebCore::WorkerContextProxy::create(
+ WebCore::Worker* worker) {
+ if (!worker->scriptExecutionContext()->isDocument())
+ return new WebCore::WorkerMessagingProxy(worker);
+
+ WebWorkerClientImpl* proxy = new WebWorkerClientImpl(worker);
+
+ // Get to the RenderView, so that we can tell the browser to create a
+ // worker process if necessary.
+ WebCore::Document* document = static_cast<WebCore::Document*>(
+ worker->scriptExecutionContext());
+ WebFrameLoaderClient* frame_loader_client =
+ static_cast<WebFrameLoaderClient*>(document->frame()->loader()->client());
+ WebViewDelegate* webview_delegate =
+ frame_loader_client->webframe()->webview_impl()->delegate();
+ WebWorker* webworker = webview_delegate->CreateWebWorker(proxy);
+ proxy->set_webworker(webworker);
+ return proxy;
+}
+
+
+WebWorkerClientImpl::WebWorkerClientImpl(WebCore::Worker* worker)
+ : worker_(worker) {
+}
+
+WebWorkerClientImpl::~WebWorkerClientImpl() {
+}
+
+void WebWorkerClientImpl::set_webworker(WebWorker* webworker) {
+ webworker_.reset(webworker);
+}
+
+void WebWorkerClientImpl::startWorkerContext(
+ const WebCore::KURL& scriptURL,
+ const WebCore::String& userAgent,
+ const WebCore::String& sourceCode) {
+ webworker_->StartWorkerContext(webkit_glue::KURLToGURL(scriptURL),
+ webkit_glue::StringToString16(userAgent),
+ webkit_glue::StringToString16(sourceCode));
+}
+
+void WebWorkerClientImpl::terminateWorkerContext() {
+ webworker_->TerminateWorkerContext();
+}
+
+void WebWorkerClientImpl::postMessageToWorkerContext(
+ const WebCore::String& message) {
+ webworker_->PostMessageToWorkerContext(
+ webkit_glue::StringToString16(message));
+}
+
+bool WebWorkerClientImpl::hasPendingActivity() const {
+ // TODO(jianli): we should use the same logic from WorkerMessagingProxy
+ // here, so that we don't do a synchronous IPC.
+ // Until then, always return true.
+ return true;
+}
+
+void WebWorkerClientImpl::workerObjectDestroyed() {
+ webworker_->WorkerObjectDestroyed();
+}
+
+void WebWorkerClientImpl::PostMessageToWorkerObject(const string16& message) {
+ // TODO(jianli): this method, and the ones below, need to implement
+ // WorkerObjectProxy.
+}
+
+void WebWorkerClientImpl::PostExceptionToWorkerObject(
+ const string16& error_message,
+ int line_number,
+ const string16& source_url) {
+}
+
+void WebWorkerClientImpl::PostConsoleMessageToWorkerObject(
+ int destination,
+ int source,
+ int level,
+ const string16& message,
+ int line_number,
+ const string16& source_url) {
+}
+
+void WebWorkerClientImpl::ConfirmMessageFromWorkerObject(bool has_pending_activity) {
+}
+
+void WebWorkerClientImpl::ReportPendingActivity(bool has_pending_activity) {
+}
+
+void WebWorkerClientImpl::WorkerContextDestroyed() {
+ delete this;
+}
+
+#endif
diff --git a/webkit/glue/webworkerclient_impl.h b/webkit/glue/webworkerclient_impl.h
new file mode 100644
index 0000000..fc93a3c
--- /dev/null
+++ b/webkit/glue/webworkerclient_impl.h
@@ -0,0 +1,61 @@
+// 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 WEBKIT_GLUE_WEBWORKERCLIENT_IMPL_H_
+#define WEBKIT_GLUE_WEBWORKERCLIENT_IMPL_H_
+
+#if ENABLE(WORKERS)
+
+#include "base/scoped_ptr.h"
+#include "webkit/glue/webworkerclient.h"
+
+#include "WorkerContextProxy.h"
+
+class WebWorker;
+
+// The purpose of this class is to provide a WorkerContextProxy
+// implementation that we can give to WebKit. Internally, it converts the
+// data types to Chrome compatible ones so that renderer code can use it over
+// IPC.
+class WebWorkerClientImpl : public WebCore::WorkerContextProxy,
+ public WebWorkerClient {
+ public:
+ WebWorkerClientImpl(WebCore::Worker* worker);
+
+ void set_webworker(WebWorker* webworker);
+
+ // WebCore::WorkerContextProxy implementation
+ void startWorkerContext(const WebCore::KURL& scriptURL,
+ const WebCore::String& userAgent,
+ const WebCore::String& sourceCode);
+ void terminateWorkerContext();
+ void postMessageToWorkerContext(const WebCore::String& message);
+ bool hasPendingActivity() const;
+ void workerObjectDestroyed();
+
+ // WebWorkerClient implementation.
+ void PostMessageToWorkerObject(const string16& message);
+ void PostExceptionToWorkerObject(const string16& error_message,
+ int line_number,
+ const string16& source_url);
+ void PostConsoleMessageToWorkerObject(int destination,
+ int source,
+ int level,
+ const string16& message,
+ int line_number,
+ const string16& source_url);
+ void ConfirmMessageFromWorkerObject(bool has_pending_activity);
+ void ReportPendingActivity(bool has_pending_activity);
+ void WorkerContextDestroyed();
+
+ private:
+ virtual ~WebWorkerClientImpl();
+
+ WebCore::Worker* worker_;
+ scoped_ptr<WebWorker> webworker_;
+};
+
+#endif
+
+#endif // WEBKIT_GLUE_WEBWORKERCLIENT_IMPL_H_