summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--chrome/SConscript2
-rw-r--r--chrome/app/chrome_dll_main.cc5
-rw-r--r--chrome/browser/browser.scons4
-rw-r--r--chrome/browser/browser.vcproj20
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc17
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h2
-rw-r--r--chrome/browser/worker_host/worker_process_host.cc99
-rw-r--r--chrome/browser/worker_host/worker_process_host.h56
-rw-r--r--chrome/browser/worker_host/worker_service.cc73
-rw-r--r--chrome/browser/worker_host/worker_service.h52
-rw-r--r--chrome/chrome.gyp4
-rw-r--r--chrome/chrome.sln16
-rw-r--r--chrome/common/child_process_host.cc6
-rw-r--r--chrome/common/child_thread.cc3
-rw-r--r--chrome/common/child_thread.h3
-rw-r--r--chrome/common/chrome_switches.cc5
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/common/common.scons2
-rw-r--r--chrome/common/common.vcproj8
-rw-r--r--chrome/common/ipc_message_utils.h151
-rw-r--r--chrome/common/render_messages_internal.h12
-rw-r--r--chrome/common/worker_messages.h21
-rw-r--r--chrome/common/worker_messages_internal.h73
-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
-rw-r--r--chrome/worker/webworkerclient_proxy.cc95
-rw-r--r--chrome/worker/webworkerclient_proxy.h68
-rw-r--r--chrome/worker/worker.scons102
-rw-r--r--chrome/worker/worker.vcproj171
-rw-r--r--chrome/worker/worker_main.cc39
-rw-r--r--chrome/worker/worker_process.cc14
-rw-r--r--chrome/worker/worker_process.h28
-rw-r--r--chrome/worker/worker_thread.cc26
-rw-r--r--chrome/worker/worker_thread.h31
-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
47 files changed, 1757 insertions, 63 deletions
diff --git a/chrome/SConscript b/chrome/SConscript
index 28d8de1..d6a3e78 100644
--- a/chrome/SConscript
+++ b/chrome/SConscript
@@ -142,6 +142,7 @@ if env.Bit('windows'):
env_dll.Append(
LIBS = [
'plugin',
+ 'worker',
]
)
@@ -293,6 +294,7 @@ p = env.ChromeMSVSProject('app/chrome_dll.vcproj',
'$BASE_DIR/build/base.vcproj',
'$WEBKIT_DIR/build/WebCore/WebCore.vcproj',
'$CHROME_DIR/plugin/plugin.vcproj',
+ '$CHROME_DIR/worker/worker.vcproj',
'$LIBJPEG_DIR/libjpeg.vcproj',
'$BZIP2_DIR/bzip2.vcproj',
'$NET_DIR/build/net.vcproj',
diff --git a/chrome/app/chrome_dll_main.cc b/chrome/app/chrome_dll_main.cc
index 6f77924..1e3e428 100644
--- a/chrome/app/chrome_dll_main.cc
+++ b/chrome/app/chrome_dll_main.cc
@@ -55,6 +55,7 @@
extern int BrowserMain(const MainFunctionParams&);
extern int RendererMain(const MainFunctionParams&);
extern int PluginMain(const MainFunctionParams&);
+extern int WorkerMain(const MainFunctionParams&);
#if defined(OS_WIN)
// TODO(erikkay): isn't this already defined somewhere?
@@ -370,6 +371,10 @@ int ChromeMain(int argc, const char** argv) {
#if defined(OS_WIN)
rv = PluginMain(main_params);
#endif
+ } else if (process_type == switches::kWorkerProcess) {
+#if defined(OS_WIN)
+ rv = WorkerMain(main_params);
+#endif
} else if (process_type.empty()) {
ScopedOleInitializer ole_initializer;
rv = BrowserMain(main_params);
diff --git a/chrome/browser/browser.scons b/chrome/browser/browser.scons
index 64d190f..bb765f6 100644
--- a/chrome/browser/browser.scons
+++ b/chrome/browser/browser.scons
@@ -648,6 +648,10 @@ input_files = ChromeFileList([
'plugin_installer.h',
'toolbar_model.cc',
'toolbar_model.h',
+ 'worker_host/worker_process_host.cc',
+ 'worker_host/worker_process_host.h',
+ 'worker_host/worker_service.cc',
+ 'worker_host/worker_service.h',
])
if not env.Bit('windows'):
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index 2b032b6..9c63f9c 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -2386,6 +2386,26 @@
>
</File>
</Filter>
+ <Filter
+ Name="Worker Host"
+ >
+ <File
+ RelativePath=".\worker_host\worker_process_host.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\worker_host\worker_process_host.h"
+ >
+ </File>
+ <File
+ RelativePath=".\worker_host\worker_service.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\worker_host\worker_service.h"
+ >
+ </File>
+ </Filter>
<File
RelativePath=".\browser_trial.cc"
>
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index bf6c8b9..edec4d7 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -22,6 +22,7 @@
#include "chrome/browser/renderer_host/browser_render_process_host.h"
#include "chrome/browser/renderer_host/render_widget_helper.h"
#include "chrome/browser/spellchecker.h"
+#include "chrome/browser/worker_host/worker_service.h"
#include "chrome/common/chrome_plugin_lib.h"
#include "chrome/common/chrome_plugin_util.h"
#include "chrome/common/notification_service.h"
@@ -123,6 +124,8 @@ ResourceMessageFilter::ResourceMessageFilter(
}
ResourceMessageFilter::~ResourceMessageFilter() {
+ WorkerService::GetInstance()->RendererShutdown(this);
+
if (render_handle_)
base::CloseProcessHandle(render_handle_);
@@ -201,6 +204,10 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message) {
OnReceiveContextMenuMsg(message))
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_OpenChannelToPlugin,
OnOpenChannelToPlugin)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_CreateDedicatedWorker,
+ OnCreateDedicatedWorker)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_ForwardToWorker,
+ OnForwardToWorker)
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_SpellCheck, OnSpellCheck)
IPC_MESSAGE_HANDLER(ViewHostMsg_DnsPrefetch, OnDnsPrefetch)
IPC_MESSAGE_HANDLER(ViewHostMsg_RendererHistograms,
@@ -492,6 +499,16 @@ void ResourceMessageFilter::OnOpenChannelToPlugin(const GURL& url,
locale, reply_msg);
}
+void ResourceMessageFilter::OnCreateDedicatedWorker(const GURL& url,
+ int* route_id) {
+ *route_id = render_widget_helper_->GetNextRoutingID();
+ WorkerService::GetInstance()->CreateDedicatedWorker(url, this, *route_id);
+}
+
+void ResourceMessageFilter::OnForwardToWorker(const IPC::Message& message) {
+ WorkerService::GetInstance()->ForwardMessage(message);
+}
+
void ResourceMessageFilter::OnDownloadUrl(const IPC::Message& message,
const GURL& url,
const GURL& referrer) {
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 537c937..b131488 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -143,6 +143,8 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
const std::string& clsid,
const std::wstring& locale,
IPC::Message* reply_msg);
+ void OnCreateDedicatedWorker(const GURL& url, int* route_id);
+ void OnForwardToWorker(const IPC::Message& msg);
void OnDownloadUrl(const IPC::Message& message,
const GURL& url,
const GURL& referrer);
diff --git a/chrome/browser/worker_host/worker_process_host.cc b/chrome/browser/worker_host/worker_process_host.cc
new file mode 100644
index 0000000..3b713fd
--- /dev/null
+++ b/chrome/browser/worker_host/worker_process_host.cc
@@ -0,0 +1,99 @@
+// 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/browser/worker_host/worker_process_host.h"
+
+#include "base/command_line.h"
+#include "base/debug_util.h"
+#include "base/logging.h"
+#include "base/path_service.h"
+#include "base/process_util.h"
+#include "chrome/browser/browser_process.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"
+#include "chrome/common/process_watcher.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/common/worker_messages.h"
+
+
+WorkerProcessHost::WorkerProcessHost(MessageLoop* main_message_loop)
+ : ChildProcessHost(WORKER_PROCESS, main_message_loop) {
+}
+
+WorkerProcessHost::~WorkerProcessHost() {
+}
+
+bool WorkerProcessHost::Init() {
+ // TODO(jabdelmalek): figure out what to set as the title.
+ set_name(L"TBD");
+
+ if (!CreateChannel())
+ return false;
+
+ std::wstring exe_path;
+ if (!PathService::Get(base::FILE_EXE, &exe_path))
+ return false;
+
+ CommandLine cmd_line(exe_path);
+
+ // TODO(jabdelmalek): factor out common code from renderer/plugin that does
+ // sandboxing and command line copying and reuse here.
+ cmd_line.AppendSwitchWithValue(switches::kProcessType,
+ switches::kWorkerProcess);
+ cmd_line.AppendSwitchWithValue(switches::kProcessChannelID, channel_id());
+ base::ProcessHandle handle;
+ if (!base::LaunchApp(cmd_line, false, false, &handle))
+ return false;
+ SetHandle(handle);
+
+ return true;
+}
+
+void WorkerProcessHost::CreateWorker(const GURL& url,
+ int worker_route_id,
+ int renderer_route_id,
+ ResourceMessageFilter* filter) {
+ WorkerInstance instance;
+ instance.worker_route_id = worker_route_id;
+ instance.renderer_route_id = renderer_route_id;
+ instance.filter = filter;
+ instances_.push_back(instance);
+ Send(new WorkerProcessMsg_CreateWorker(url, worker_route_id));
+}
+
+bool WorkerProcessHost::FilterMessage(const IPC::Message& message) {
+ for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) {
+ if (i->renderer_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);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) {
+ 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);
+ break;
+ }
+ }
+}
+
+void WorkerProcessHost::RendererShutdown(ResourceMessageFilter* filter) {
+ for (Instances::iterator i = instances_.begin(); i != instances_.end();) {
+ if (i->filter == filter) {
+ i = instances_.erase(i);
+ } else {
+ ++i;
+ }
+ }
+}
diff --git a/chrome/browser/worker_host/worker_process_host.h b/chrome/browser/worker_host/worker_process_host.h
new file mode 100644
index 0000000..40da66f
--- /dev/null
+++ b/chrome/browser/worker_host/worker_process_host.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_BROWSER_WORKER_HOST_WORKER_PROCESS_HOST_H_
+#define CHROME_BROWSER_WORKER_HOST_WORKER_PROCESS_HOST_H_
+
+#include <list>
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "chrome/common/child_process_host.h"
+#include "chrome/common/ipc_channel.h"
+#include "googleurl/src/gurl.h"
+
+class ResourceMessageFilter;
+
+class WorkerProcessHost : public ChildProcessHost {
+ public:
+ WorkerProcessHost(MessageLoop* main_message_loop);
+ ~WorkerProcessHost();
+
+ // Starts the process. Returns true iff it succeeded.
+ bool Init();
+
+ // Creates a worker object in the process.
+ void CreateWorker(const GURL& url,
+ int worker_route_id,
+ int renderer_route_id,
+ ResourceMessageFilter* filter);
+
+ // Returns true iff the given message from a renderer process was forwarded to
+ // the worker.
+ bool FilterMessage(const IPC::Message& message);
+
+ void RendererShutdown(ResourceMessageFilter* filter);
+
+ private:
+ // Called when a message arrives from the worker process.
+ void OnMessageReceived(const IPC::Message& message);
+
+ // Contains information about each worker instance, needed to forward messages
+ // between the renderer and worker processes.
+ struct WorkerInstance {
+ int worker_route_id;
+ int renderer_route_id;
+ ResourceMessageFilter* filter;
+ };
+
+ typedef std::list<WorkerInstance> Instances;
+ Instances instances_;
+
+ DISALLOW_COPY_AND_ASSIGN(WorkerProcessHost);
+};
+
+#endif // CHROME_BROWSER_WORKER_HOST_WORKER_PROCESS_HOST_H_
diff --git a/chrome/browser/worker_host/worker_service.cc b/chrome/browser/worker_host/worker_service.cc
new file mode 100644
index 0000000..cdbf69c
--- /dev/null
+++ b/chrome/browser/worker_host/worker_service.cc
@@ -0,0 +1,73 @@
+// 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/browser/worker_host/worker_service.h"
+
+#include "base/singleton.h"
+#include "base/thread.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/plugin_service.h"
+#include "chrome/browser/worker_host/worker_process_host.h"
+#include "chrome/browser/renderer_host/render_process_host.h"
+#include "chrome/browser/renderer_host/resource_message_filter.h"
+
+WorkerService* WorkerService::GetInstance() {
+ return Singleton<WorkerService>::get();
+}
+
+WorkerService::WorkerService() : next_worker_route_id_(0) {
+}
+
+WorkerService::~WorkerService() {
+}
+
+bool WorkerService::CreateDedicatedWorker(const GURL &url,
+ ResourceMessageFilter* filter,
+ int renderer_route_id) {
+ WorkerProcessHost* worker = NULL;
+ // One worker process for quick bringup!
+ for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
+ !iter.Done(); ++iter) {
+ worker = static_cast<WorkerProcessHost*>(*iter);
+ break;
+ }
+
+ if (!worker) {
+ // TODO(jabdelmalek): there has to be a better way to get the main message
+ // loop than to go through PluginService.
+ worker = new WorkerProcessHost(
+ PluginService::GetInstance()->main_message_loop());
+ if (!worker->Init()) {
+ delete worker;
+ return false;
+ }
+ }
+
+ // Generate a unique route id for the browser-worker communication that's
+ // 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, ++next_worker_route_id_, renderer_route_id, filter);
+
+ return true;
+}
+
+void WorkerService::ForwardMessage(const IPC::Message& message) {
+ for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
+ !iter.Done(); ++iter) {
+ WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
+ if (worker->FilterMessage(message))
+ return;
+ }
+
+ // TODO(jabdelmalek): tell sender that callee is gone
+}
+
+void WorkerService::RendererShutdown(ResourceMessageFilter* filter) {
+ for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
+ !iter.Done(); ++iter) {
+ WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
+ worker->RendererShutdown(filter);
+ }
+}
diff --git a/chrome/browser/worker_host/worker_service.h b/chrome/browser/worker_host/worker_service.h
new file mode 100644
index 0000000..7f7b282
--- /dev/null
+++ b/chrome/browser/worker_host/worker_service.h
@@ -0,0 +1,52 @@
+// 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_BROWSER_WORKER_HOST__WORKER_SERVICE_H_
+#define CHROME_BROWSER_WORKER_HOST__WORKER_SERVICE_H_
+
+#include <list>
+
+#include "base/basictypes.h"
+#include "base/hash_tables.h"
+#include "base/singleton.h"
+#include "googleurl/src/gurl.h"
+
+namespace IPC {
+class Message;
+}
+
+class MessageLoop;
+class WorkerProcessHost;
+class ResourceMessageFilter;
+
+class WorkerService {
+ public:
+ // Returns the WorkerService singleton.
+ static WorkerService* GetInstance();
+
+ // Creates a dedicated worker. Returns true on success.
+ bool CreateDedicatedWorker(const GURL &url,
+ ResourceMessageFilter* filter,
+ int renderer_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 ResourceMessageFilter when it's destructed so that all the
+ // WorkerProcessHost objects can remove their pointers to it.
+ void RendererShutdown(ResourceMessageFilter* filter);
+
+ private:
+ friend struct DefaultSingletonTraits<WorkerService>;
+
+ WorkerService();
+ ~WorkerService();
+
+ int next_worker_route_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(WorkerService);
+};
+
+#endif // CHROME_BROWSER_WORKER_HOST__WORKER_SERVICE_H_
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index fbf1155..c361074 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -955,6 +955,10 @@
'browser/views/toolbar_view.h',
'browser/views/user_data_dir_dialog.cc',
'browser/views/user_data_dir_dialog.h',
+ 'browser/worker_host/worker_process_host.cc',
+ 'browser/worker_host/worker_process_host.h',
+ 'browser/worker_host/worker_service.cc',
+ 'browser/worker_host/worker_service.h',
'browser/webdata/web_data_service.cc',
'browser/webdata/web_data_service.h',
'browser/webdata/web_data_service_win.cc',
diff --git a/chrome/chrome.sln b/chrome/chrome.sln
index d9678c6..099f905 100644
--- a/chrome/chrome.sln
+++ b/chrome/chrome.sln
@@ -165,6 +165,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "chrome_dll", "app\chrome_dl
{C0334F9A-1168-4101-9DD8-C30FB252D435} = {C0334F9A-1168-4101-9DD8-C30FB252D435}
{C564F145-9172-42C3-BFCB-6014CA97DBCD} = {C564F145-9172-42C3-BFCB-6014CA97DBCD}
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09} = {C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09}
+ {C78D02D0-A366-4EC6-A248-AA8E64C4BA18} = {C78D02D0-A366-4EC6-A248-AA8E64C4BA18}
{CD9CA56E-4E94-444C-87D4-58CA1E6F300D} = {CD9CA56E-4E94-444C-87D4-58CA1E6F300D}
{D5E8DCB2-9C61-446F-8BEE-B18CA0E0936E} = {D5E8DCB2-9C61-446F-8BEE-B18CA0E0936E}
{D703D7A0-EDC1-4FE6-9E22-56154155B24E} = {D703D7A0-EDC1-4FE6-9E22-56154155B24E}
@@ -1346,6 +1347,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WebKit", "..\webkit\build\W
{2F7EDFA2-EE27-4D83-8454-9EFBD5779203} = {2F7EDFA2-EE27-4D83-8454-9EFBD5779203}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "worker", "worker\worker.vcproj", "{C78D02D0-A366-4EC6-A248-AA8E64C4BA18}"
+ ProjectSection(WebsiteProperties) = preProject
+ Debug.AspNetCompiler.Debug = "True"
+ Release.AspNetCompiler.Debug = "False"
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Mixed Platforms = Debug|Mixed Platforms
@@ -2328,6 +2335,14 @@ Global
{C70D3509-57C4-4326-90C1-2EC0AE34848D}.Release|Mixed Platforms.Build.0 = Release|Win32
{C70D3509-57C4-4326-90C1-2EC0AE34848D}.Release|Win32.ActiveCfg = Release|Win32
{C70D3509-57C4-4326-90C1-2EC0AE34848D}.Release|Win32.Build.0 = Release|Win32
+ {C78D02D0-A366-4EC6-A248-AA8E64C4BA18}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+ {C78D02D0-A366-4EC6-A248-AA8E64C4BA18}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+ {C78D02D0-A366-4EC6-A248-AA8E64C4BA18}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C78D02D0-A366-4EC6-A248-AA8E64C4BA18}.Debug|Win32.Build.0 = Debug|Win32
+ {C78D02D0-A366-4EC6-A248-AA8E64C4BA18}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+ {C78D02D0-A366-4EC6-A248-AA8E64C4BA18}.Release|Mixed Platforms.Build.0 = Release|Win32
+ {C78D02D0-A366-4EC6-A248-AA8E64C4BA18}.Release|Win32.ActiveCfg = Release|Win32
+ {C78D02D0-A366-4EC6-A248-AA8E64C4BA18}.Release|Win32.Build.0 = Release|Win32
{C8C6183C-B03C-11DD-B471-DFD256D89593}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{C8C6183C-B03C-11DD-B471-DFD256D89593}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{C8C6183C-B03C-11DD-B471-DFD256D89593}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -2758,6 +2773,7 @@ Global
{C564F145-9172-42C3-BFCB-6014CA97DBCD} = {EF78C1F9-AA17-4CA5-B6CB-39B37A73A3DA}
{C66B126D-0ECE-4CA2-B6DC-FA780AFBBF09} = {CB43561E-A6F8-49E2-96A2-3F2BA1FFF21E}
{C70D3509-57C4-4326-90C1-2EC0AE34848D} = {2325D8C4-8EF5-42AC-8900-492225750DE4}
+ {C78D02D0-A366-4EC6-A248-AA8E64C4BA18} = {97555540-8163-4D0F-BCAC-EFA0FFED3453}
{C8C6183C-B03C-11DD-B471-DFD256D89593} = {1174D37F-6ABB-45DA-81B3-C631281273B7}
{C9E0BD1D-B175-4A91-8380-3FDC81FAB9D7} = {1174D37F-6ABB-45DA-81B3-C631281273B7}
{CAB69303-0F02-4C68-A12E-FFE55DB52526} = {2325D8C4-8EF5-42AC-8900-492225750DE4}
diff --git a/chrome/common/child_process_host.cc b/chrome/common/child_process_host.cc
index 66d3ebf..15d8daa 100644
--- a/chrome/common/child_process_host.cc
+++ b/chrome/common/child_process_host.cc
@@ -154,18 +154,20 @@ void ChildProcessHost::ListenerHook::OnChannelError() {
ChildProcessHost::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.";
+ iterator_ = Singleton<ChildProcessList>::get()->begin();
}
ChildProcessHost::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.";
+ iterator_ = Singleton<ChildProcessList>::get()->begin();
+ if (!Done() && (*iterator_)->type() != type_)
+ iterator_++;
}
ChildProcessInfo* ChildProcessHost::Iterator::operator++() {
diff --git a/chrome/common/child_thread.cc b/chrome/common/child_thread.cc
index bad15a6..ff73a7f 100644
--- a/chrome/common/child_thread.cc
+++ b/chrome/common/child_thread.cc
@@ -11,6 +11,9 @@
#include "chrome/common/ipc_logging.h"
#include "webkit/glue/webkit_glue.h"
+// V8 needs a 1MB stack size.
+const size_t ChildThread::kV8StackSize = 1024 * 1024;
+
ChildThread::ChildThread(Thread::Options options)
: Thread("Chrome_ChildThread"),
owner_loop_(MessageLoop::current()),
diff --git a/chrome/common/child_thread.h b/chrome/common/child_thread.h
index 5b13ab7..f97964c 100644
--- a/chrome/common/child_thread.h
+++ b/chrome/common/child_thread.h
@@ -37,6 +37,9 @@ class ChildThread : public IPC::Channel::Listener,
void SetChannelName(const std::wstring& name) { channel_name_ = name; }
protected:
+ // The required stack size if V8 runs on a thread.
+ static const size_t kV8StackSize;
+
virtual void OnControlMessageReceived(const IPC::Message& msg) { }
// Returns the one child thread.
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 53c7910..cf47946 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -74,9 +74,12 @@ const wchar_t kRendererProcess[] = L"renderer";
// Path to the exe to run for the renderer subprocess
const wchar_t kRendererPath[] = L"renderer-path";
-// Causes the process to run as plugin host
+// Causes the process to run as a plugin subprocess.
const wchar_t kPluginProcess[] = L"plugin";
+// Causes the process to run as a worker subprocess.
+const wchar_t kWorkerProcess[] = L"worker";
+
// Runs the renderer and plugins in the same process as the browser
const wchar_t kSingleProcess[] = L"single-process";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 93841cd..578fc71 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -30,6 +30,7 @@ extern const wchar_t kBrowserStartRenderersManually[];
extern const wchar_t kRendererProcess[];
extern const wchar_t kRendererPath[];
extern const wchar_t kPluginProcess[];
+extern const wchar_t kWorkerProcess[];
extern const wchar_t kSingleProcess[];
extern const wchar_t kProcessPerTab[];
extern const wchar_t kProcessPerSite[];
diff --git a/chrome/common/common.scons b/chrome/common/common.scons
index 86b43a9..7ebad2e 100644
--- a/chrome/common/common.scons
+++ b/chrome/common/common.scons
@@ -101,6 +101,8 @@ input_files = ChromeFileList([
'plugin_messages_internal.h',
'render_messages.h',
'render_messages_internal.h',
+ 'worker_messages.h',
+ 'worker_messages_internal.h',
]),
'accessibility.h',
'animation.cc',
diff --git a/chrome/common/common.vcproj b/chrome/common/common.vcproj
index d91438c..e409d1d 100644
--- a/chrome/common/common.vcproj
+++ b/chrome/common/common.vcproj
@@ -300,6 +300,14 @@
RelativePath=".\render_messages_internal.h"
>
</File>
+ <File
+ RelativePath=".\worker_messages.h"
+ >
+ </File>
+ <File
+ RelativePath=".\worker_messages_internal.h"
+ >
+ </File>
</Filter>
<Filter
Name="extensions"
diff --git a/chrome/common/ipc_message_utils.h b/chrome/common/ipc_message_utils.h
index 8f813f6..61243f5 100644
--- a/chrome/common/ipc_message_utils.h
+++ b/chrome/common/ipc_message_utils.h
@@ -11,6 +11,7 @@
#include "base/file_path.h"
#include "base/string_util.h"
+#include "base/string16.h"
#include "base/tuple.h"
#if defined(OS_POSIX)
#include "chrome/common/file_descriptor_set_posix.h"
@@ -56,6 +57,10 @@ enum IPCMessageStart {
TestMsgStart,
DevToolsAgentMsgStart,
DevToolsClientMsgStart,
+ WorkerProcessMsgStart,
+ WorkerProcessHostMsgStart,
+ WorkerMsgStart,
+ WorkerHostMsgStart,
// NOTE: When you add a new message class, also update
// IPCStatusView::IPCStatusView to ensure logging works.
// NOTE: this enum is used by IPC_MESSAGE_MACRO to generate a unique message
@@ -492,6 +497,7 @@ struct ParamTraits<std::map<K, V> > {
}
};
+
template <>
struct ParamTraits<std::wstring> {
typedef std::wstring param_type;
@@ -506,6 +512,34 @@ struct ParamTraits<std::wstring> {
}
};
+
+// If WCHAR_T_IS_UTF16 is defined, then string16 is a std::wstring so we don't
+// need this trait.
+#if !defined(WCHAR_T_IS_UTF16)
+
+template <>
+struct ParamTraits<string16> {
+ typedef string16 param_type;
+ static void Write(Message* m, const param_type& p) {
+ m->WriteData(reinterpret_cast<const char*>(p.data()),
+ static_cast<int>(p.size() * sizeof(char16)));
+ }
+ static bool Read(const Message* m, void** iter, param_type* r) {
+ const char *data;
+ int data_size = 0;
+ if (!m->ReadData(iter, &data, &data_size))
+ return false;
+ r->assign(reinterpret_cast<const char16*>(data),
+ data_size / sizeof(char16));
+ return true;
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(UTF16ToWide(p));
+ }
+};
+
+#endif
+
template <>
struct ParamTraits<GURL> {
typedef GURL param_type;
@@ -893,6 +927,66 @@ struct ParamTraits<LogData> {
}
};
+
+template <>
+struct ParamTraits<webkit_glue::WebApplicationInfo> {
+ typedef webkit_glue::WebApplicationInfo param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* r);
+ static void Log(const param_type& p, std::wstring* l);
+};
+
+
+#if defined(OS_WIN)
+template<>
+struct ParamTraits<TransportDIB::Id> {
+ typedef TransportDIB::Id param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.handle);
+ WriteParam(m, p.sequence_num);
+ }
+ static bool Read(const Message* m, void** iter, param_type* r) {
+ return (ReadParam(m, iter, &r->handle) &&
+ ReadParam(m, iter, &r->sequence_num));
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ l->append(L"TransportDIB(");
+ LogParam(p.handle, l);
+ l->append(L", ");
+ LogParam(p.sequence_num, l);
+ l->append(L")");
+ }
+};
+#endif
+
+template<typename A>
+struct ParamTraits<Maybe<A> > {
+ typedef struct Maybe<A> param_type;
+ static void Write(Message* m, const param_type& p) {
+ WriteParam(m, p.valid);
+ if (p.valid)
+ WriteParam(m, p.value);
+ }
+ static bool Read(const Message* m, void** iter, param_type* r) {
+ if (!ReadParam(m, iter, &r->valid))
+ return false;
+
+ if (r->valid)
+ return ReadParam(m, iter, &r->value);
+ return true;
+ }
+ static void Log(const param_type& p, std::wstring* l) {
+ if (p.valid) {
+ l->append(L"Just ");
+ ParamTraits<A>::Log(p.value, l);
+ } else {
+ l->append(L"Nothing");
+ }
+
+ }
+};
+
+
template <>
struct ParamTraits<Message> {
static void Write(Message* m, const Message& p) {
@@ -914,6 +1008,7 @@ struct ParamTraits<Message> {
}
};
+
template <>
struct ParamTraits<Tuple0> {
typedef Tuple0 param_type;
@@ -1070,62 +1165,6 @@ struct ParamTraits< Tuple6<A, B, C, D, E, F> > {
}
};
-#if defined(OS_WIN)
-template<>
-struct ParamTraits<TransportDIB::Id> {
- typedef TransportDIB::Id param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.handle);
- WriteParam(m, p.sequence_num);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- return (ReadParam(m, iter, &r->handle) &&
- ReadParam(m, iter, &r->sequence_num));
- }
- static void Log(const param_type& p, std::wstring* l) {
- l->append(L"TransportDIB(");
- LogParam(p.handle, l);
- l->append(L", ");
- LogParam(p.sequence_num, l);
- l->append(L")");
- }
-};
-#endif
-
-template<typename A>
-struct ParamTraits<Maybe<A> > {
- typedef struct Maybe<A> param_type;
- static void Write(Message* m, const param_type& p) {
- WriteParam(m, p.valid);
- if (p.valid)
- WriteParam(m, p.value);
- }
- static bool Read(const Message* m, void** iter, param_type* r) {
- if (!ReadParam(m, iter, &r->valid))
- return false;
-
- if (r->valid)
- return ReadParam(m, iter, &r->value);
- return true;
- }
- static void Log(const param_type& p, std::wstring* l) {
- if (p.valid) {
- l->append(L"Just ");
- ParamTraits<A>::Log(p.value, l);
- } else {
- l->append(L"Nothing");
- }
-
- }
-};
-
-template <>
-struct ParamTraits<webkit_glue::WebApplicationInfo> {
- typedef webkit_glue::WebApplicationInfo param_type;
- static void Write(Message* m, const param_type& p);
- static bool Read(const Message* m, void** iter, param_type* r);
- static void Log(const param_type& p, std::wstring* l);
-};
//-----------------------------------------------------------------------------
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 41b18a6..af42627 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -1196,4 +1196,16 @@ IPC_BEGIN_MESSAGES(ViewHost)
TransportDIB::Id /* DIB id */)
#endif
+ // A renderer sends this to the browser process when it wants to create a
+ // worker. The browser will create the worker process if necessary, and
+ // will return the route id on success. On error returns MSG_ROUTING_NONE.
+ IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_CreateDedicatedWorker,
+ GURL /* url */,
+ int /* route_id */)
+
+ // Wraps an IPC message that's destined to the worker on the renderer->browser
+ // hop.
+ IPC_MESSAGE_CONTROL1(ViewHostMsg_ForwardToWorker,
+ IPC::Message /* message */)
+
IPC_END_MESSAGES(ViewHost)
diff --git a/chrome/common/worker_messages.h b/chrome/common/worker_messages.h
new file mode 100644
index 0000000..e1f64a5
--- /dev/null
+++ b/chrome/common/worker_messages.h
@@ -0,0 +1,21 @@
+// 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.
+
+// Defines messages between the browser and worker process, as well as between
+// the renderer and worker process.
+
+#ifndef CHROME_COMMON_WORKER_MESSAGES_H_
+#define CHROME_COMMON_WORKER_MESSAGES_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "chrome/common/ipc_message_utils.h"
+
+
+#define MESSAGES_INTERNAL_FILE "chrome/common/worker_messages_internal.h"
+#include "chrome/common/ipc_message_macros.h"
+
+#endif // CHROME_COMMON_WORKER_MESSAGES_H_
+
diff --git a/chrome/common/worker_messages_internal.h b/chrome/common/worker_messages_internal.h
new file mode 100644
index 0000000..7691c79
--- /dev/null
+++ b/chrome/common/worker_messages_internal.h
@@ -0,0 +1,73 @@
+// 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 "base/string16.h"
+#include "chrome/common/ipc_message_macros.h"
+#include "googleurl/src/gurl.h"
+
+
+//-----------------------------------------------------------------------------
+// WorkerProcess messages
+// These are messages sent from the browser to the worker process.
+IPC_BEGIN_MESSAGES(WorkerProcess)
+ IPC_MESSAGE_CONTROL2(WorkerProcessMsg_CreateWorker,
+ GURL /* url */,
+ int /* route_id */)
+IPC_END_MESSAGES(WorkerProcess)
+
+
+//-----------------------------------------------------------------------------
+// WorkerProcessHost messages
+// These are messages sent from the worker process to the browser process.
+
+// No messages being sent in this direction for now.
+//IPC_BEGIN_MESSAGES(WorkerProcessHost)
+//IPC_END_MESSAGES(WorkerProcessHost)
+
+//-----------------------------------------------------------------------------
+// Worker messages
+// These are messages sent from the renderer process to the worker process.
+IPC_BEGIN_MESSAGES(Worker)
+ IPC_MESSAGE_ROUTED3(WorkerMsg_StartWorkerContext,
+ GURL /* url */,
+ string16 /* user_agent */,
+ string16 /* source_code */)
+
+ IPC_MESSAGE_ROUTED0(WorkerMsg_TerminateWorkerContext)
+
+ IPC_MESSAGE_ROUTED1(WorkerMsg_PostMessageToWorkerContext,
+ string16 /* message */)
+
+ IPC_MESSAGE_ROUTED0(WorkerMsg_WorkerObjectDestroyed)
+IPC_END_MESSAGES(Worker)
+
+
+//-----------------------------------------------------------------------------
+// WorkerHost messages
+// These are messages sent from the worker process to the renderer process.
+IPC_BEGIN_MESSAGES(WorkerHost)
+ IPC_MESSAGE_ROUTED1(WorkerHostMsg_PostMessageToWorkerObject,
+ string16 /* message */)
+
+ IPC_MESSAGE_ROUTED3(WorkerHostMsg_PostExceptionToWorkerObject,
+ string16 /* error_message */,
+ int /* line_number */,
+ string16 /* source_url*/)
+
+ IPC_MESSAGE_ROUTED6(WorkerHostMsg_PostConsoleMessageToWorkerObject,
+ int /* destination */,
+ int /* source */,
+ int /* level */,
+ string16 /* message */,
+ int /* line_number */,
+ string16 /* source_url */)
+
+ IPC_MESSAGE_ROUTED1(WorkerHostMsg_ConfirmMessageFromWorkerObject,
+ bool /* bool has_pending_activity */)
+
+ IPC_MESSAGE_ROUTED1(WorkerHostMsg_ReportPendingActivity,
+ bool /* bool has_pending_activity */)
+
+ IPC_MESSAGE_ROUTED0(WorkerHostMsg_WorkerContextDestroyed)
+IPC_END_MESSAGES(WorkerHost)
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_
diff --git a/chrome/worker/webworkerclient_proxy.cc b/chrome/worker/webworkerclient_proxy.cc
new file mode 100644
index 0000000..84cb2ed
--- /dev/null
+++ b/chrome/worker/webworkerclient_proxy.cc
@@ -0,0 +1,95 @@
+// 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/worker/webworkerclient_proxy.h"
+
+#include "chrome/common/ipc_logging.h"
+#include "chrome/common/worker_messages.h"
+#include "chrome/worker/worker_process.h"
+#include "chrome/worker/worker_thread.h"
+#include "webkit/glue/webworker.h"
+
+
+WebWorkerClientProxy::WebWorkerClientProxy(const GURL& url, int route_id)
+ : url_(url),
+ route_id_(route_id),
+ started_worker_(false),
+ ALLOW_THIS_IN_INITIALIZER_LIST(impl_(WebWorker::Create(this))) {
+ WorkerThread::current()->AddRoute(route_id_, this);
+ WorkerProcess::current()->AddRefProcess();
+}
+
+WebWorkerClientProxy::~WebWorkerClientProxy() {
+ WorkerThread::current()->RemoveRoute(route_id_);
+ WorkerProcess::current()->ReleaseProcess();
+}
+
+void WebWorkerClientProxy::PostMessageToWorkerObject(const string16& message) {
+ Send(new WorkerHostMsg_PostMessageToWorkerObject(route_id_, message));
+}
+
+void WebWorkerClientProxy::PostExceptionToWorkerObject(
+ const string16& error_message,
+ int line_number,
+ const string16& source_url) {
+ Send(new WorkerHostMsg_PostExceptionToWorkerObject(
+ route_id_, error_message, line_number, source_url));
+}
+
+void WebWorkerClientProxy::PostConsoleMessageToWorkerObject(
+ int destination,
+ int source,
+ int level,
+ const string16& message,
+ int line_number,
+ const string16& source_url) {
+ Send(new WorkerHostMsg_PostConsoleMessageToWorkerObject(
+ route_id_, destination, source, level,message, line_number, source_url));
+}
+
+void WebWorkerClientProxy::ConfirmMessageFromWorkerObject(bool has_pending_activity) {
+ Send(new WorkerHostMsg_ConfirmMessageFromWorkerObject(
+ route_id_, has_pending_activity));
+}
+
+void WebWorkerClientProxy::ReportPendingActivity(bool has_pending_activity) {
+ Send(new WorkerHostMsg_ReportPendingActivity(
+ route_id_, has_pending_activity));
+}
+
+void WebWorkerClientProxy::WorkerContextDestroyed() {
+ Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_));
+}
+
+bool WebWorkerClientProxy::Send(IPC::Message* message) {
+ return WorkerThread::current()->Send(message);
+}
+
+void WebWorkerClientProxy::OnMessageReceived(const IPC::Message& message) {
+ if (!started_worker_ &&
+ message.type() != WorkerMsg_StartWorkerContext::ID) {
+ queued_messages_.push_back(new IPC::Message(message));
+ return;
+ }
+
+ WebWorker* worker = impl_.get();
+ IPC_BEGIN_MESSAGE_MAP(WebWorkerClientProxy, message)
+ IPC_MESSAGE_FORWARD(WorkerMsg_StartWorkerContext, worker,
+ WebWorker::StartWorkerContext)
+ IPC_MESSAGE_FORWARD(WorkerMsg_TerminateWorkerContext, worker,
+ WebWorker::TerminateWorkerContext)
+ IPC_MESSAGE_FORWARD(WorkerMsg_PostMessageToWorkerContext, worker,
+ WebWorker::PostMessageToWorkerContext)
+ IPC_MESSAGE_FORWARD(WorkerMsg_WorkerObjectDestroyed, worker,
+ WebWorker::WorkerObjectDestroyed)
+ IPC_END_MESSAGE_MAP()
+
+ if (message.type() == WorkerMsg_StartWorkerContext::ID) {
+ started_worker_ = true;
+ for (size_t i = 0; i < queued_messages_.size(); ++i)
+ OnMessageReceived(*queued_messages_[i]);
+
+ queued_messages_.clear();
+ }
+}
diff --git a/chrome/worker/webworkerclient_proxy.h b/chrome/worker/webworkerclient_proxy.h
new file mode 100644
index 0000000..c744023
--- /dev/null
+++ b/chrome/worker/webworkerclient_proxy.h
@@ -0,0 +1,68 @@
+// 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_WORKER_WEBWORKERCLIENT_PROXY_H_
+#define CHROME_WORKER_WEBWORKERCLIENT_PROXY_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "chrome/common/ipc_channel.h"
+#include "googleurl/src/gurl.h"
+#include "webkit/glue/webworkerclient.h"
+
+class WebWorker;
+
+// This class receives IPCs from the renderer and calls the WebCore::Worker
+// implementation (after the data types have been converted by glue code). It
+// is also called by the worker code and converts these function calls into
+// IPCs that are sent to the renderer, where they're converted back to function
+// calls by WebWorkerProxy.
+class WebWorkerClientProxy : public WebWorkerClient,
+ public IPC::Channel::Listener {
+ public:
+ WebWorkerClientProxy (const GURL& url, int route_id);
+ ~WebWorkerClientProxy ();
+
+ // 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();
+
+ // IPC::Channel::Listener implementation.
+ void OnMessageReceived(const IPC::Message& message);
+
+ private:
+ bool Send(IPC::Message* message);
+
+ // The source url for this worker.
+ GURL url_;
+
+ int route_id_;
+
+ // Whether we've received StartWorkerContext message.
+ bool started_worker_;
+
+ scoped_ptr<WebWorker> impl_;
+
+ // Stores messages that arrived before the StartWorkerContext message.
+ std::vector<IPC::Message*> queued_messages_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebWorkerClientProxy);
+};
+
+#endif // CHROME_WORKER_WEBWORKERCLIENT_PROXY_H_
diff --git a/chrome/worker/worker.scons b/chrome/worker/worker.scons
new file mode 100644
index 0000000..e00c413
--- /dev/null
+++ b/chrome/worker/worker.scons
@@ -0,0 +1,102 @@
+# 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.
+
+Import('env')
+
+env = env.Clone()
+
+env.SConscript([
+# '$NPAPI_DIR/using_npapi.scons',
+# '$SKIA_DIR/using_skia.scons',
+], {'env':env})
+
+env.Prepend(
+ CPPPATH = [
+ '$CHROME_SRC_DIR',
+ ],
+)
+
+if env.Bit('windows'):
+ env.Prepend(
+ CPPPATH = [
+ '$CHROME_DIR/tools/build/win',
+ ],
+ )
+
+input_files = ChromeFileList([
+ 'webworkerclient_proxy.cc',
+ 'webworkerclient_proxy.h',
+ 'worker_main.cc',
+ 'worker_process.cc',
+ 'worker_process.h',
+ 'worker_thread.cc',
+ 'worker_thread.h',
+ '$CHROME_DIR/tools/build/win/precompiled$OBJSUFFIX',
+ '$CHROME_DIR/tools/build/win/precompiled.h',
+])
+
+if not env.Bit('windows'):
+ input_files.Remove(
+ '$CHROME_DIR/tools/build/win/precompiled$OBJSUFFIX',
+ )
+
+if env.Bit('posix'):
+ # TODO(port)
+ input_files.Remove(
+ 'webworker.cc',
+ 'worker_main.cc',
+ 'worker_process.cc',
+ 'worker_thread.cc',
+ )
+
+env.ChromeLibrary('worker', input_files)
+
+p = env.ChromeMSVSProject('worker.vcproj',
+ dest='$CHROME_SRC_DIR/chrome/worker/worker.vcproj',
+ guid='{C78D02D0-A366-4ec6-A248-AA8E64C4BA18}',
+ keyword='Win32Proj',
+ # TODO(sgk): when we can intuit the hierarchy
+ # from the built targets.
+ #buildtargets=TODO,
+ files=input_files,
+ local_directory_prefix='./',
+ tools=[
+ 'VCPreBuildEventTool',
+ 'VCCustomBuildTool',
+ 'VCXMLDataGeneratorTool',
+ 'VCWebServiceProxyGeneratorTool',
+ 'VCMIDLTool',
+ 'VCCLCompilerTool',
+ 'VCManagedResourceCompilerTool',
+ 'VCResourceCompilerTool',
+ 'VCPreLinkEventTool',
+ 'VCLibrarianTool',
+ 'VCALinkTool',
+ 'VCXDCMakeTool',
+ 'VCBscMakeTool',
+ 'VCFxCopTool',
+ 'VCPostBuildEventTool',
+ ],
+ ConfigurationType='4')
+
+
+p.AddConfig('Debug|Win32',
+ InheritedPropertySheets=[
+ '$(SolutionDir)../build/common.vsprops',
+ '$(SolutionDir)../build/debug.vsprops',
+ '../tools/build/win/precompiled.vsprops',
+ ])
+
+p.AddConfig('Release|Win32',
+ InheritedPropertySheets=[
+ '$(SolutionDir)../build/common.vsprops',
+ '$(SolutionDir)../build/release.vsprops',
+ ])
+
+p.AddFileConfig('../tools/build/win/precompiled.cc',
+ 'Debug|Win32',
+ tools=[
+ MSVSTool('VCCLCompilerTool',
+ UsePrecompiledHeader='1'),
+ ])
diff --git a/chrome/worker/worker.vcproj b/chrome/worker/worker.vcproj
new file mode 100644
index 0000000..ba82a39
--- /dev/null
+++ b/chrome/worker/worker.vcproj
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8.00"
+ Name="worker"
+ ProjectGUID="{C78D02D0-A366-4EC6-A248-AA8E64C4BA18}"
+ RootNamespace="worker"
+ Keyword="Win32Proj"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\build\debug.vsprops;..\tools\build\win\precompiled.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(SolutionDir)..\build\common.vsprops;$(SolutionDir)..\build\release.vsprops"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <File
+ RelativePath="..\tools\build\win\precompiled.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\tools\build\win\precompiled.h"
+ >
+ </File>
+ <File
+ RelativePath=".\webworkerclient_proxy.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\webworkerclient_proxy.h"
+ >
+ </File>
+ <File
+ RelativePath=".\worker_main.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\worker_process.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\worker_process.h"
+ >
+ </File>
+ <File
+ RelativePath=".\worker_thread.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\worker_thread.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/chrome/worker/worker_main.cc b/chrome/worker/worker_main.cc
new file mode 100644
index 0000000..b3c4256
--- /dev/null
+++ b/chrome/worker/worker_main.cc
@@ -0,0 +1,39 @@
+// 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 "base/command_line.h"
+#include "base/message_loop.h"
+#include "base/string_util.h"
+#include "base/system_monitor.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/logging_chrome.h"
+#include "chrome/common/main_function_params.h"
+#include "chrome/common/win_util.h"
+#include "chrome/worker/worker_process.h"
+#include "sandbox/src/sandbox.h"
+
+// Mainline routine for running as the worker process.
+int WorkerMain(const MainFunctionParams& parameters) {
+ const CommandLine& parsed_command_line = parameters.command_line_;
+
+ // The main thread of the render process.
+ MessageLoopForIO main_message_loop;
+ std::wstring app_name = chrome::kBrowserAppName;
+ PlatformThread::SetName(WideToASCII(app_name + L"_WorkerMain").c_str());
+
+ // Initialize the SystemMonitor
+ base::SystemMonitor::Start();
+
+ // TODO(jabdelmalek): refactor sandboxing code from renderer so that the
+ // workers are sandboxed.
+
+ WorkerProcess worker_process;
+
+ // Load the accelerator table from the browser executable and tell the
+ // message loop to use it when translating messages.
+ MessageLoop::current()->Run();
+
+ return 0;
+}
diff --git a/chrome/worker/worker_process.cc b/chrome/worker/worker_process.cc
new file mode 100644
index 0000000..4d319e3
--- /dev/null
+++ b/chrome/worker/worker_process.cc
@@ -0,0 +1,14 @@
+// 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/worker/worker_process.h"
+
+#include "chrome/worker/worker_thread.h"
+
+WorkerProcess::WorkerProcess()
+ : ChildProcess(new WorkerThread()) {
+}
+
+WorkerProcess::~WorkerProcess() {
+}
diff --git a/chrome/worker/worker_process.h b/chrome/worker/worker_process.h
new file mode 100644
index 0000000..da76781
--- /dev/null
+++ b/chrome/worker/worker_process.h
@@ -0,0 +1,28 @@
+// 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_WORKER_WORKER_PROCESS_H_
+#define CHROME_WORKER_WORKER_PROCESS_H_
+
+#include "chrome/common/child_process.h"
+
+// Represents the worker end of the renderer<->worker connection. The
+// opposite end is the WorkerProcessHost. This is a singleton object for
+// each worker process.
+class WorkerProcess : public ChildProcess {
+ public:
+ WorkerProcess();
+ virtual ~WorkerProcess();
+
+ // Returns a pointer to the PluginProcess singleton instance.
+ static WorkerProcess* current() {
+ return static_cast<WorkerProcess*>(ChildProcess::current());
+ }
+
+ private:
+
+ DISALLOW_COPY_AND_ASSIGN(WorkerProcess);
+};
+
+#endif // CHROME_WORKER_WORKER_PROCESS_H_
diff --git a/chrome/worker/worker_thread.cc b/chrome/worker/worker_thread.cc
new file mode 100644
index 0000000..daba38b
--- /dev/null
+++ b/chrome/worker/worker_thread.cc
@@ -0,0 +1,26 @@
+// 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/worker/worker_thread.h"
+
+#include "chrome/common/worker_messages.h"
+#include "chrome/worker/webworkerclient_proxy.h"
+#include "chrome/worker/worker_process.h"
+
+WorkerThread::WorkerThread()
+ : ChildThread(base::Thread::Options(MessageLoop::TYPE_DEFAULT, kV8StackSize)) {
+}
+
+WorkerThread::~WorkerThread() {
+}
+
+void WorkerThread::OnControlMessageReceived(const IPC::Message& msg) {
+ IPC_BEGIN_MESSAGE_MAP(WorkerThread, msg)
+ IPC_MESSAGE_HANDLER(WorkerProcessMsg_CreateWorker, OnCreateWorker)
+ IPC_END_MESSAGE_MAP()
+}
+
+void WorkerThread::OnCreateWorker(const GURL& url, int route_id) {
+ WebWorkerClientProxy* worker = new WebWorkerClientProxy(url, route_id);
+}
diff --git a/chrome/worker/worker_thread.h b/chrome/worker/worker_thread.h
new file mode 100644
index 0000000..25ae2f2
--- /dev/null
+++ b/chrome/worker/worker_thread.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 CHROME_WORKER_WORKER_THREAD_H_
+#define CHROME_WORKER_WORKER_THREAD_H_
+
+#include "base/thread.h"
+#include "chrome/common/child_thread.h"
+
+class GURL;
+
+class WorkerThread : public ChildThread {
+ public:
+ WorkerThread();
+ ~WorkerThread();
+
+ // Returns the one worker thread.
+ static WorkerThread* current() {
+ return static_cast<WorkerThread*>(ChildThread::current());
+ }
+
+ private:
+ virtual void OnControlMessageReceived(const IPC::Message& msg);
+
+ void OnCreateWorker(const GURL& url, int route_id);
+
+ DISALLOW_COPY_AND_ASSIGN(WorkerThread);
+};
+
+#endif // CHROME_WORKER_WORKER_THREAD_H_
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_