summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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_