summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoratwilson@chromium.org <atwilson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-30 18:11:47 +0000
committeratwilson@chromium.org <atwilson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-30 18:11:47 +0000
commitab3505360bf6612d18915a39a0fec74b00642e82 (patch)
tree7a39d15a688b8e52c839fb9151851b2a37533ed0 /chrome
parent06b9e3b77773477b5ee889ded41d10741d6b0647 (diff)
downloadchromium_src-ab3505360bf6612d18915a39a0fec74b00642e82.zip
chromium_src-ab3505360bf6612d18915a39a0fec74b00642e82.tar.gz
chromium_src-ab3505360bf6612d18915a39a0fec74b00642e82.tar.bz2
Initial pass of shared workers renderer-side code
Added initial interface hooks betweek WebKit code and renderer-side worker code. The proper messages are generated to fire off a shared worker, but they are currently ignored by the browser process. BUG=26233 TEST=none (will enable layout tests when basic functionality available) Review URL: http://codereview.chromium.org/340036 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30599 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/in_process_webkit/browser_webkitclient_impl.cc6
-rw-r--r--chrome/browser/in_process_webkit/browser_webkitclient_impl.h1
-rw-r--r--chrome/browser/worker_host/worker_process_host.cc78
-rwxr-xr-xchrome/chrome.gyp6
-rw-r--r--chrome/common/render_messages_internal.h18
-rw-r--r--chrome/common/worker_messages_internal.h4
-rw-r--r--chrome/renderer/renderer_webkitclient_impl.cc5
-rw-r--r--chrome/renderer/renderer_webkitclient_impl.h8
-rw-r--r--chrome/renderer/websharedworker_impl.cc58
-rw-r--r--chrome/renderer/websharedworker_impl.h49
-rw-r--r--chrome/renderer/websharedworkerrepository_impl.cc24
-rw-r--r--chrome/renderer/websharedworkerrepository_impl.h22
-rw-r--r--chrome/renderer/webworker_base.cc102
-rw-r--r--chrome/renderer/webworker_base.h64
-rw-r--r--chrome/renderer/webworker_proxy.cc69
-rw-r--r--chrome/renderer/webworker_proxy.h21
-rw-r--r--chrome/worker/worker_webkitclient_impl.cc5
-rw-r--r--chrome/worker/worker_webkitclient_impl.h1
18 files changed, 434 insertions, 107 deletions
diff --git a/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc b/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc
index 6a13013..ec893fb 100644
--- a/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc
+++ b/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc
@@ -123,3 +123,9 @@ void BrowserWebKitClientImpl::dispatchStorageEvent(
DOMStorageDispatcherHost::DispatchStorageEvent(key, old_value, new_value,
origin, is_local_storage);
}
+
+WebKit::WebSharedWorkerRepository*
+BrowserWebKitClientImpl::sharedWorkerRepository() {
+ NOTREACHED();
+ return NULL;
+}
diff --git a/chrome/browser/in_process_webkit/browser_webkitclient_impl.h b/chrome/browser/in_process_webkit/browser_webkitclient_impl.h
index 0024bfb..ff79350 100644
--- a/chrome/browser/in_process_webkit/browser_webkitclient_impl.h
+++ b/chrome/browser/in_process_webkit/browser_webkitclient_impl.h
@@ -36,6 +36,7 @@ class BrowserWebKitClientImpl : public webkit_glue::WebKitClientImpl {
virtual void dispatchStorageEvent(const WebKit::WebString& key,
const WebKit::WebString& oldValue, const WebKit::WebString& newValue,
const WebKit::WebString& origin, bool isLocalStorage);
+ virtual WebKit::WebSharedWorkerRepository* sharedWorkerRepository();
};
#endif // CHROME_BROWSER_IN_PROCESS_WEBKIT_WEBKIT_CLIENT_IMPL_H_
diff --git a/chrome/browser/worker_host/worker_process_host.cc b/chrome/browser/worker_host/worker_process_host.cc
index 094a2fd..54446b3 100644
--- a/chrome/browser/worker_host/worker_process_host.cc
+++ b/chrome/browser/worker_host/worker_process_host.cc
@@ -144,7 +144,7 @@ void WorkerProcessHost::CreateWorker(const WorkerInstance& instance) {
UpdateTitle();
instances_.back().sender->Send(
- new ViewMsg_DedicatedWorkerCreated(instance.sender_route_id));
+ new ViewMsg_WorkerCreated(instance.sender_route_id));
}
bool WorkerProcessHost::FilterMessage(const IPC::Message& message,
@@ -229,39 +229,59 @@ void WorkerProcessHost::RelayMessage(
IPC::Message::Sender* sender,
int route_id,
CallbackWithReturnValue<int>::Type* next_route_id) {
- if (message.type() != WorkerMsg_PostMessage::ID) {
- IPC::Message* new_message = new IPC::Message(message);
- new_message->set_routing_id(route_id);
- sender->Send(new_message);
- return;
- }
- // We want to send the receiver a routing id for the new channel, so
- // crack the message first.
- string16 msg;
- std::vector<int> sent_message_port_ids;
- std::vector<int> new_routing_ids;
- if (!WorkerMsg_PostMessage::Read(
- &message, &msg, &sent_message_port_ids, &new_routing_ids)) {
- return;
- }
- DCHECK(sent_message_port_ids.size() == new_routing_ids.size());
+ if (message.type() == WorkerMsg_PostMessage::ID) {
+ // We want to send the receiver a routing id for the new channel, so
+ // crack the message first.
+ string16 msg;
+ std::vector<int> sent_message_port_ids;
+ std::vector<int> new_routing_ids;
+ if (!WorkerMsg_PostMessage::Read(
+ &message, &msg, &sent_message_port_ids, &new_routing_ids)) {
+ return;
+ }
+ DCHECK(sent_message_port_ids.size() == new_routing_ids.size());
+
+ for (size_t i = 0; i < sent_message_port_ids.size(); ++i) {
+ new_routing_ids[i] = next_route_id->Run();
+ MessagePortDispatcher::GetInstance()->UpdateMessagePort(
+ sent_message_port_ids[i], sender, new_routing_ids[i], next_route_id);
+ }
+
+ sender->Send(new WorkerMsg_PostMessage(
+ route_id, msg, sent_message_port_ids, new_routing_ids));
- for (size_t i = 0; i < sent_message_port_ids.size(); ++i) {
- new_routing_ids[i] = next_route_id->Run();
+ // Send any queued messages to the sent message ports. We can only do this
+ // after sending the above message, since it's the one that sets up the
+ // message port route which the queued messages are sent to.
+ for (size_t i = 0; i < sent_message_port_ids.size(); ++i) {
+ MessagePortDispatcher::GetInstance()->
+ SendQueuedMessagesIfPossible(sent_message_port_ids[i]);
+ }
+ } else if (message.type() == WorkerMsg_Connect::ID) {
+ // Crack the SharedWorker Connect message to setup routing for the port.
+ int sent_message_port_id;
+ int new_routing_id;
+ if (!WorkerMsg_Connect::Read(
+ &message, &sent_message_port_id, &new_routing_id)) {
+ return;
+ }
+ new_routing_id = next_route_id->Run();
MessagePortDispatcher::GetInstance()->UpdateMessagePort(
- sent_message_port_ids[i], sender, new_routing_ids[i], next_route_id);
- }
+ sent_message_port_id, sender, new_routing_id, next_route_id);
- sender->Send(new WorkerMsg_PostMessage(
- route_id, msg, sent_message_port_ids, new_routing_ids));
+ // Resend the message with the new routing id.
+ sender->Send(new WorkerMsg_Connect(
+ route_id, sent_message_port_id, new_routing_id));
- // Send any queued messages to the sent message ports. We can only do this
- // after sending the above message, since it's the one that sets up the
- // message port route which the queued messages are sent to.
- for (size_t i = 0; i < sent_message_port_ids.size(); ++i) {
- MessagePortDispatcher::GetInstance()->
- SendQueuedMessagesIfPossible(sent_message_port_ids[i]);
+ // Send any queued messages for the sent port.
+ MessagePortDispatcher::GetInstance()->SendQueuedMessagesIfPossible(
+ sent_message_port_id);
+ } else {
+ IPC::Message* new_message = new IPC::Message(message);
+ new_message->set_routing_id(route_id);
+ sender->Send(new_message);
+ return;
}
}
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 91fcfab..32ecdb5 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -3306,6 +3306,12 @@
'renderer/webplugin_delegate_proxy.h',
'renderer/webplugin_delegate_pepper.cc',
'renderer/webplugin_delegate_pepper.h',
+ 'renderer/websharedworker_impl.cc',
+ 'renderer/websharedworker_impl.h',
+ 'renderer/websharedworkerrepository_impl.cc',
+ 'renderer/websharedworkerrepository_impl.h',
+ 'renderer/webworker_base.cc',
+ 'renderer/webworker_base.h',
'renderer/webworker_proxy.cc',
'renderer/webworker_proxy.h',
],
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index cecc9fc6..81f9c1f 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -720,9 +720,9 @@ IPC_BEGIN_MESSAGES(View)
IPC_MESSAGE_ROUTED1(ViewMsg_SetActive,
bool /* active */)
- // Response message to ViewHostMsg_CreateDedicatedWorker. Sent when the
- // worker has started.
- IPC_MESSAGE_ROUTED0(ViewMsg_DedicatedWorkerCreated)
+ // Response message to ViewHostMsg_CreateShared/DedicatedWorker.
+ // Sent when the worker has started.
+ IPC_MESSAGE_ROUTED0(ViewMsg_WorkerCreated)
// Tell the renderer which browser window it's being attached to.
IPC_MESSAGE_ROUTED1(ViewMsg_UpdateBrowserWindowId,
@@ -1710,6 +1710,16 @@ IPC_BEGIN_MESSAGES(ViewHost)
int /* render_view_route_id */,
int /* route_id */)
+ // A renderer sends this to the browser process when it wants to create a
+ // shared 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_CONTROL3_1(ViewHostMsg_CreateSharedWorker,
+ GURL /* url */,
+ string16 /* name */,
+ int /* render_view_route_id */,
+ int /* route_id */)
+
// A message sent to the browser on behalf of a renderer which wants to show
// a desktop notification.
IPC_MESSAGE_ROUTED3(ViewHostMsg_ShowDesktopNotification,
@@ -1732,7 +1742,7 @@ IPC_BEGIN_MESSAGES(ViewHost)
int /* permission_result */)
// Sent if the worker object has sent a ViewHostMsg_CreateDedicatedWorker
- // message and not received a ViewMsg_DedicatedWorkerCreated reply, but in the
+ // message and not received a ViewMsg_WorkerCreated reply, but in the
// mean time it's destroyed. This tells the browser to not create the queued
// worker.
IPC_MESSAGE_CONTROL1(ViewHostMsg_CancelCreateDedicatedWorker,
diff --git a/chrome/common/worker_messages_internal.h b/chrome/common/worker_messages_internal.h
index 9b1cac2..6ed4d09 100644
--- a/chrome/common/worker_messages_internal.h
+++ b/chrome/common/worker_messages_internal.h
@@ -94,6 +94,10 @@ IPC_BEGIN_MESSAGES(Worker)
std::vector<int> /* sent_message_port_ids */,
std::vector<int> /* new_routing_ids */)
+ IPC_MESSAGE_ROUTED2(WorkerMsg_Connect,
+ int /* sent_message_port_id */,
+ int /* routing_id */)
+
IPC_MESSAGE_ROUTED0(WorkerMsg_WorkerObjectDestroyed)
IPC_END_MESSAGES(Worker)
diff --git a/chrome/renderer/renderer_webkitclient_impl.cc b/chrome/renderer/renderer_webkitclient_impl.cc
index 8203bb5..52d4a24 100644
--- a/chrome/renderer/renderer_webkitclient_impl.cc
+++ b/chrome/renderer/renderer_webkitclient_impl.cc
@@ -352,6 +352,11 @@ long long RendererWebKitClientImpl::databaseGetFileSize(
message_id, 0LL);
}
+WebKit::WebSharedWorkerRepository*
+RendererWebKitClientImpl::sharedWorkerRepository() {
+ return &shared_worker_repository_;
+}
+
//------------------------------------------------------------------------------
WebKit::WebString RendererWebKitClientImpl::signedPublicKeyAndChallengeString(
diff --git a/chrome/renderer/renderer_webkitclient_impl.h b/chrome/renderer/renderer_webkitclient_impl.h
index 79e56fc..28056c3 100644
--- a/chrome/renderer/renderer_webkitclient_impl.h
+++ b/chrome/renderer/renderer_webkitclient_impl.h
@@ -6,6 +6,7 @@
#define CHROME_RENDERER_RENDERER_WEBKIT_CLIENT_IMPL_H_
#include "base/platform_file.h"
+#include "chrome/renderer/websharedworkerrepository_impl.h"
#include "webkit/glue/simple_webmimeregistry_impl.h"
#include "webkit/glue/webclipboard_impl.h"
#include "webkit/glue/webkitclient_impl.h"
@@ -64,6 +65,8 @@ class RendererWebKitClientImpl : public webkit_glue::WebKitClientImpl {
virtual WebKit::WebApplicationCacheHost* createApplicationCacheHost(
WebKit::WebApplicationCacheHostClient*);
+ virtual WebKit::WebSharedWorkerRepository* sharedWorkerRepository();
+
private:
class MimeRegistry : public webkit_glue::SimpleWebMimeRegistryImpl {
public:
@@ -106,6 +109,11 @@ class RendererWebKitClientImpl : public webkit_glue::WebKitClientImpl {
// increments by 1, for every enable decrements by 1. When it reaches 0,
// we tell the browser to enable fast termination.
int sudden_termination_disables_;
+
+ // Implementation of the WebSharedWorkerRepository APIs (provides an interface
+ // to WorkerService on the browser thread.
+ WebSharedWorkerRepositoryImpl shared_worker_repository_;
+
};
#endif // CHROME_RENDERER_WEBKIT_CLIENT_IMPL_H_
diff --git a/chrome/renderer/websharedworker_impl.cc b/chrome/renderer/websharedworker_impl.cc
new file mode 100644
index 0000000..f5e20ce
--- /dev/null
+++ b/chrome/renderer/websharedworker_impl.cc
@@ -0,0 +1,58 @@
+// 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/websharedworker_impl.h"
+
+#include "chrome/common/render_messages.h"
+#include "chrome/common/webmessageportchannel_impl.h"
+#include "chrome/common/worker_messages.h"
+#include "webkit/api/public/WebURL.h"
+
+WebSharedWorkerImpl::WebSharedWorkerImpl(const GURL& url,
+ const string16& name,
+ ChildThread* child_thread,
+ int route_id,
+ int render_view_route_id)
+ : WebWorkerBase(child_thread, route_id, render_view_route_id),
+ url_(url),
+ name_(name) {
+}
+
+bool WebSharedWorkerImpl::isStarted() {
+ return IsStarted();
+}
+
+void WebSharedWorkerImpl::startWorkerContext(
+ const WebKit::WebURL& script_url,
+ const WebKit::WebString& user_agent,
+ const WebKit::WebString& source_code) {
+ DCHECK(url_ == script_url);
+ IPC::Message* create_message = new ViewHostMsg_CreateSharedWorker(
+ url_, name_, render_view_route_id_, &route_id_);
+ CreateWorkerContext(create_message, script_url, user_agent, source_code);
+}
+
+void WebSharedWorkerImpl::connect(WebKit::WebMessagePortChannel* channel) {
+ WebMessagePortChannelImpl* webchannel =
+ static_cast<WebMessagePortChannelImpl*>(channel);
+
+ int message_port_id = webchannel->message_port_id();
+ DCHECK(message_port_id != MSG_ROUTING_NONE);
+ webchannel->QueueMessages();
+
+ Send(new WorkerMsg_Connect(route_id_, message_port_id, MSG_ROUTING_NONE));
+}
+
+void WebSharedWorkerImpl::OnMessageReceived(const IPC::Message& message) {
+ IPC_BEGIN_MESSAGE_MAP(WebSharedWorkerImpl, message)
+ IPC_MESSAGE_HANDLER(ViewMsg_WorkerCreated, OnWorkerCreated)
+ IPC_END_MESSAGE_MAP()
+}
+
+void WebSharedWorkerImpl::OnWorkerCreated() {
+ // The worker is created - now send off the CreateWorkerContext message and
+ // any other queued messages
+ SendQueuedMessages();
+}
+
diff --git a/chrome/renderer/websharedworker_impl.h b/chrome/renderer/websharedworker_impl.h
new file mode 100644
index 0000000..14d122d89
--- /dev/null
+++ b/chrome/renderer/websharedworker_impl.h
@@ -0,0 +1,49 @@
+// 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_WEBSHAREDWORKER_IMPL_H_
+#define CHROME_RENDERER_WEBSHAREDWORKER_IMPL_H_
+
+#include "base/basictypes.h"
+#include "chrome/renderer/webworker_base.h"
+#include "googleurl/src/gurl.h"
+#include "webkit/api/public/WebSharedWorker.h"
+
+class ChildThread;
+
+// Implementation of the WebSharedWorker APIs. This object is intended to only
+// live long enough to allow the caller to send a "connect" event to the worker
+// thread. Once the connect event has been sent, all future communication will
+// happen via the WebMessagePortChannel, and the WebSharedWorker instance will
+// be freed.
+class WebSharedWorkerImpl : public WebKit::WebSharedWorker,
+ private WebWorkerBase {
+ public:
+ WebSharedWorkerImpl(const GURL& url,
+ const string16& name,
+ ChildThread* child_thread,
+ int route_id,
+ int render_view_route_id);
+
+ // Implementations of WebSharedWorker APIs
+ virtual bool isStarted();
+ virtual void connect(WebKit::WebMessagePortChannel* channel);
+ virtual void startWorkerContext(const WebKit::WebURL& script_url,
+ const WebKit::WebString& user_agent,
+ const WebKit::WebString& source_code);
+
+ // IPC::Channel::Listener implementation.
+ void OnMessageReceived(const IPC::Message& message);
+
+ private:
+ void OnWorkerCreated();
+
+ // The name and URL that uniquely identify this worker.
+ GURL url_;
+ string16 name_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebSharedWorkerImpl);
+};
+
+#endif // CHROME_RENDERER_WEBSHAREDWORKER_IMPL_H_
diff --git a/chrome/renderer/websharedworkerrepository_impl.cc b/chrome/renderer/websharedworkerrepository_impl.cc
new file mode 100644
index 0000000..15aea07
--- /dev/null
+++ b/chrome/renderer/websharedworkerrepository_impl.cc
@@ -0,0 +1,24 @@
+// 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/websharedworkerrepository_impl.h"
+
+WebKit::WebSharedWorker* WebSharedWorkerRepositoryImpl::lookup(
+ const WebKit::WebURL& url,
+ const WebKit::WebString& name,
+ DocumentID document) {
+ return NULL;
+}
+
+void WebSharedWorkerRepositoryImpl::documentDetached(
+ DocumentID document) {
+ // TODO(atwilson): Update this to call to WorkerService to shutdown any
+ // associated SharedWorkers.
+}
+
+bool WebSharedWorkerRepositoryImpl::hasSharedWorkers(
+ DocumentID document) {
+ // TODO(atwilson): Update this when we track shared worker creation.
+ return false;
+}
diff --git a/chrome/renderer/websharedworkerrepository_impl.h b/chrome/renderer/websharedworkerrepository_impl.h
new file mode 100644
index 0000000..bf6369c
--- /dev/null
+++ b/chrome/renderer/websharedworkerrepository_impl.h
@@ -0,0 +1,22 @@
+// 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_WEB_SHARED_WORKER_REPOSITORY_IMPL_H_
+#define CHROME_RENDERER_WEB_SHARED_WORKER_REPOSITORY_IMPL_H_
+
+#include "webkit/api/public/WebSharedWorkerRepository.h"
+
+class WebKit::WebSharedWorker;
+
+class WebSharedWorkerRepositoryImpl : public WebKit::WebSharedWorkerRepository {
+ virtual WebKit::WebSharedWorker* lookup(const WebKit::WebURL& url,
+ const WebKit::WebString& name,
+ DocumentID document);
+
+ virtual void documentDetached(DocumentID document);
+
+ virtual bool hasSharedWorkers(DocumentID document);
+};
+
+#endif // CHROME_RENDERER_WEB_SHARED_WORKER_REPOSITORY_IMPL_H_
diff --git a/chrome/renderer/webworker_base.cc b/chrome/renderer/webworker_base.cc
new file mode 100644
index 0000000..98365cd
--- /dev/null
+++ b/chrome/renderer/webworker_base.cc
@@ -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.
+
+#include "chrome/renderer/webworker_base.h"
+
+#include "chrome/common/child_thread.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/common/webmessageportchannel_impl.h"
+#include "chrome/common/worker_messages.h"
+#include "webkit/api/public/WebURL.h"
+#include "webkit/api/public/WebWorkerClient.h"
+
+using WebKit::WebMessagePortChannel;
+using WebKit::WebMessagePortChannelArray;
+using WebKit::WebString;
+using WebKit::WebURL;
+using WebKit::WebWorkerClient;
+
+WebWorkerBase::WebWorkerBase(
+ ChildThread* child_thread,
+ int route_id,
+ int render_view_route_id)
+ : route_id_(route_id),
+ render_view_route_id_(render_view_route_id),
+ child_thread_(child_thread) {
+ if (route_id_ != MSG_ROUTING_NONE)
+ child_thread_->AddRoute(route_id_, this);
+}
+
+WebWorkerBase::~WebWorkerBase() {
+ Disconnect();
+
+ // Free up any unsent queued messages.
+ for (size_t i = 0; i < queued_messages_.size(); ++i)
+ delete queued_messages_[i];
+}
+
+void WebWorkerBase::Disconnect() {
+ if (route_id_ == MSG_ROUTING_NONE)
+ return;
+
+ // So the messages from WorkerContext (like WorkerContextDestroyed) do not
+ // come after nobody is listening. Since Worker and WorkerContext can
+ // terminate independently, already sent messages may still be in the pipe.
+ child_thread_->RemoveRoute(route_id_);
+
+ route_id_ = MSG_ROUTING_NONE;
+}
+
+void WebWorkerBase::CreateWorkerContext(IPC::Message* create_message,
+ const GURL& script_url,
+ const string16& user_agent,
+ const string16& source_code) {
+ DCHECK(route_id_ == MSG_ROUTING_NONE);
+ // create_message is a sync message that sets route_id_
+ child_thread_->Send(create_message);
+ if (route_id_ == MSG_ROUTING_NONE)
+ return;
+
+ child_thread_->AddRoute(route_id_, this);
+
+ // We make sure that the start message is the first, since postMessage or
+ // connect might have already been called.
+ queued_messages_.insert(queued_messages_.begin(),
+ new WorkerMsg_StartWorkerContext(
+ route_id_, script_url, user_agent, source_code));
+}
+
+bool WebWorkerBase::IsStarted() {
+ // Worker is started if we have a route ID and there are no queued messages
+ // (meaning we've sent the WorkerMsg_StartWorkerContext already).
+ return (route_id_ != MSG_ROUTING_NONE && queued_messages_.empty());
+}
+
+bool WebWorkerBase::Send(IPC::Message* message) {
+ // It's possible that messages will be sent before the worker is created, in
+ // which case route_id_ will be none. Or the worker object can be interacted
+ // with before the browser process told us that it started, in which case we
+ // also want to queue the message.
+ if (!IsStarted()) {
+ queued_messages_.push_back(message);
+ return true;
+ }
+
+ // 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 child_thread_->Send(wrapped_msg);
+}
+
+void WebWorkerBase::SendQueuedMessages() {
+ DCHECK(queued_messages_.size());
+ std::vector<IPC::Message*> queued_messages = queued_messages_;
+ queued_messages_.clear();
+ for (size_t i = 0; i < queued_messages.size(); ++i) {
+ queued_messages[i]->set_routing_id(route_id_);
+ Send(queued_messages[i]);
+ }
+}
diff --git a/chrome/renderer/webworker_base.h b/chrome/renderer/webworker_base.h
new file mode 100644
index 0000000..c7c6c62
--- /dev/null
+++ b/chrome/renderer/webworker_base.h
@@ -0,0 +1,64 @@
+// 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_BASE_H_
+#define CHROME_RENDERER_WEBWORKER_BASE_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "ipc/ipc_channel.h"
+
+class ChildThread;
+class GURL;
+
+// WebWorkerBase is the common base class used by both WebWorkerProxy and
+// WebSharedWorker. It contains logic to support starting up both dedicated
+// and shared workers, and handling message queueing while waiting for the
+// worker process to start.
+class WebWorkerBase : public IPC::Channel::Listener {
+ public:
+ WebWorkerBase(ChildThread* child_thread,
+ int route_id,
+ int render_view_route_id);
+
+ virtual ~WebWorkerBase();
+
+ // Creates and initializes a new worker context.
+ void CreateWorkerContext(IPC::Message* create_message,
+ const GURL& script_url,
+ const string16& user_agent,
+ const string16& source_code);
+
+ // Returns true if the worker is running (can send messages to it).
+ bool IsStarted();
+
+ // Disconnects the worker (stops listening for incoming messages).
+ virtual void Disconnect();
+
+ // Sends a message to the worker thread (forwarded via the RenderViewHost).
+ // If WorkerStarted() has not yet been called, message is queued.
+ bool Send(IPC::Message*);
+
+ // Sends any messages currently in the queue.
+ void SendQueuedMessages();
+
+ protected:
+ // Routing id associated with this worker - used to receive messages from the
+ // worker, and also to route messages to the worker (WorkerService contains
+ // a map that maps between these renderer-side route IDs and worker-side
+ // routing ids).
+ int route_id_;
+
+ // The routing id for the RenderView that created this worker.
+ int render_view_route_id_;
+
+ ChildThread* child_thread_;
+
+ private:
+ // Stores messages that were sent before the StartWorkerContext message.
+ std::vector<IPC::Message*> queued_messages_;
+};
+
+#endif // CHROME_RENDERER_WEBWORKER_BASE_H_
diff --git a/chrome/renderer/webworker_proxy.cc b/chrome/renderer/webworker_proxy.cc
index 3932d6e..5a24c41 100644
--- a/chrome/renderer/webworker_proxy.cc
+++ b/chrome/renderer/webworker_proxy.cc
@@ -21,51 +21,29 @@ WebWorkerProxy::WebWorkerProxy(
WebWorkerClient* client,
ChildThread* child_thread,
int render_view_route_id)
- : route_id_(MSG_ROUTING_NONE),
- child_thread_(child_thread),
- render_view_route_id_(render_view_route_id),
+ : WebWorkerBase(child_thread, MSG_ROUTING_NONE, render_view_route_id),
client_(client) {
}
-WebWorkerProxy::~WebWorkerProxy() {
- Disconnect();
-
- for (size_t i = 0; i < queued_messages_.size(); ++i)
- delete queued_messages_[i];
-}
-
void WebWorkerProxy::Disconnect() {
if (route_id_ == MSG_ROUTING_NONE)
return;
- // So the messages from WorkerContext (like WorkerContextDestroyed) do not
- // come after nobody is listening. Since Worker and WorkerContext can
- // terminate independently, already sent messages may still be in the pipe.
- child_thread_->RemoveRoute(route_id_);
-
// Tell the browser to not start our queued worker.
- if (!queued_messages_.empty())
+ if (!IsStarted())
child_thread_->Send(new ViewHostMsg_CancelCreateDedicatedWorker(route_id_));
- route_id_ = MSG_ROUTING_NONE;
+ // Call our superclass to shutdown the routing
+ WebWorkerBase::Disconnect();
}
void WebWorkerProxy::startWorkerContext(
const WebURL& script_url,
const WebString& user_agent,
const WebString& source_code) {
- child_thread_->Send(new ViewHostMsg_CreateDedicatedWorker(
- script_url, render_view_route_id_, &route_id_));
- if (route_id_ == MSG_ROUTING_NONE)
- return;
-
- child_thread_->AddRoute(route_id_, this);
-
- // We make sure that the start message is the first, since postMessage might
- // have already been called.
- queued_messages_.insert(queued_messages_.begin(),
- new WorkerMsg_StartWorkerContext(
- route_id_, script_url, user_agent, source_code));
+ IPC::Message* create_message = new ViewHostMsg_CreateDedicatedWorker(
+ script_url, render_view_route_id_, &route_id_);
+ CreateWorkerContext(create_message, script_url, user_agent, source_code);
}
void WebWorkerProxy::terminateWorkerContext() {
@@ -100,31 +78,12 @@ void WebWorkerProxy::workerObjectDestroyed() {
void WebWorkerProxy::clientDestroyed() {
}
-bool WebWorkerProxy::Send(IPC::Message* message) {
- // It's possible that postMessage is called before the worker is created, in
- // which case route_id_ will be none. Or the worker object can be interacted
- // with before the browser process told us that it started, in which case we
- // also want to queue the message.
- if (route_id_ == MSG_ROUTING_NONE || !queued_messages_.empty()) {
- queued_messages_.push_back(message);
- return true;
- }
-
- // 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 child_thread_->Send(wrapped_msg);
-}
-
void WebWorkerProxy::OnMessageReceived(const IPC::Message& message) {
if (!client_)
return;
IPC_BEGIN_MESSAGE_MAP(WebWorkerProxy, message)
- IPC_MESSAGE_HANDLER(ViewMsg_DedicatedWorkerCreated,
- OnDedicatedWorkerCreated)
+ IPC_MESSAGE_HANDLER(ViewMsg_WorkerCreated, OnWorkerCreated)
IPC_MESSAGE_HANDLER(WorkerMsg_PostMessage, OnPostMessage)
IPC_MESSAGE_FORWARD(WorkerHostMsg_PostExceptionToWorkerObject,
client_,
@@ -143,14 +102,10 @@ void WebWorkerProxy::OnMessageReceived(const IPC::Message& message) {
IPC_END_MESSAGE_MAP()
}
-void WebWorkerProxy::OnDedicatedWorkerCreated() {
- DCHECK(queued_messages_.size());
- std::vector<IPC::Message*> queued_messages = queued_messages_;
- queued_messages_.clear();
- for (size_t i = 0; i < queued_messages.size(); ++i) {
- queued_messages[i]->set_routing_id(route_id_);
- Send(queued_messages[i]);
- }
+void WebWorkerProxy::OnWorkerCreated() {
+ // The worker is created - now send off the CreateWorkerContext message and
+ // any other queued messages
+ SendQueuedMessages();
}
void WebWorkerProxy::OnPostMessage(
diff --git a/chrome/renderer/webworker_proxy.h b/chrome/renderer/webworker_proxy.h
index 8c53a67..686669a 100644
--- a/chrome/renderer/webworker_proxy.h
+++ b/chrome/renderer/webworker_proxy.h
@@ -8,6 +8,7 @@
#include <vector>
#include "base/basictypes.h"
+#include "chrome/renderer/webworker_base.h"
#include "ipc/ipc_channel.h"
#include "webkit/api/public/WebWorker.h"
@@ -21,13 +22,11 @@ struct WorkerHostMsg_PostConsoleMessageToWorkerObject_Params;
// 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 WebKit::WebWorker,
- public IPC::Channel::Listener {
+class WebWorkerProxy : public WebKit::WebWorker, private WebWorkerBase {
public:
WebWorkerProxy(WebKit::WebWorkerClient* client,
ChildThread* child_thread,
int render_view_route_id);
- virtual ~WebWorkerProxy();
// WebWorker implementation.
virtual void startWorkerContext(const WebKit::WebURL& script_url,
@@ -44,32 +43,20 @@ class WebWorkerProxy : public WebKit::WebWorker,
void OnMessageReceived(const IPC::Message& message);
private:
- bool Send(IPC::Message* message);
+ virtual void Disconnect();
- void OnDedicatedWorkerCreated();
+ void OnWorkerCreated();
void OnPostMessage(const string16& message,
const std::vector<int>& sent_message_port_ids,
const std::vector<int>& new_routing_ids);
void OnPostConsoleMessageToWorkerObject(
const WorkerHostMsg_PostConsoleMessageToWorkerObject_Params& params);
- void Disconnect();
-
- // The routing id used to reach WebWorkerClientProxy in the worker process.
- int route_id_;
-
- ChildThread* child_thread_;
-
- // The routing id for the RenderView that created this worker.
- int render_view_route_id_;
// Used to communicate to the WebCore::Worker object in response to IPC
// messages.
WebKit::WebWorkerClient* client_;
- // Stores messages that were sent before the StartWorkerContext message.
- std::vector<IPC::Message*> queued_messages_;
-
DISALLOW_COPY_AND_ASSIGN(WebWorkerProxy);
};
diff --git a/chrome/worker/worker_webkitclient_impl.cc b/chrome/worker/worker_webkitclient_impl.cc
index 2d60954..fdb20f3 100644
--- a/chrome/worker/worker_webkitclient_impl.cc
+++ b/chrome/worker/worker_webkitclient_impl.cc
@@ -74,3 +74,8 @@ WebKit::WebString WorkerWebKitClientImpl::defaultLocale() {
NOTREACHED();
return WebKit::WebString();
}
+
+WebKit::WebSharedWorkerRepository*
+WorkerWebKitClientImpl::sharedWorkerRepository() {
+ return 0;
+}
diff --git a/chrome/worker/worker_webkitclient_impl.h b/chrome/worker/worker_webkitclient_impl.h
index a9ccb36..c89f0fa 100644
--- a/chrome/worker/worker_webkitclient_impl.h
+++ b/chrome/worker/worker_webkitclient_impl.h
@@ -26,6 +26,7 @@ class WorkerWebKitClientImpl : public webkit_glue::WebKitClientImpl {
virtual void prefetchHostName(const WebKit::WebString&);
virtual bool getFileSize(const WebKit::WebString& path, long long& result);
virtual WebKit::WebString defaultLocale();
+ virtual WebKit::WebSharedWorkerRepository* sharedWorkerRepository();
};
#endif // CHROME_WORKER_WORKER_WEBKIT_CLIENT_IMPL_H_