summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/worker_host/message_port_dispatcher.cc17
-rw-r--r--chrome/browser/worker_host/message_port_dispatcher.h6
-rw-r--r--chrome/browser/worker_host/worker_process_host.cc67
-rw-r--r--chrome/browser/worker_host/worker_process_host.h13
-rw-r--r--chrome/common/webmessageportchannel_impl.cc5
-rw-r--r--chrome/common/worker_messages_internal.h10
-rw-r--r--chrome/renderer/webworker_proxy.cc32
-rw-r--r--chrome/renderer/webworker_proxy.h7
-rw-r--r--chrome/worker/nativewebworker_impl.cc4
-rw-r--r--chrome/worker/nativewebworker_impl.h3
-rw-r--r--chrome/worker/webworkerclient_proxy.cc32
-rw-r--r--chrome/worker/webworkerclient_proxy.h7
-rw-r--r--chrome/worker/worker_uitest.cc3
-rw-r--r--webkit/api/public/WebWorker.h10
-rw-r--r--webkit/api/public/WebWorkerClient.h4
-rw-r--r--webkit/api/src/PlatformMessagePortChannel.cpp8
-rw-r--r--webkit/api/src/PlatformMessagePortChannel.h4
-rw-r--r--webkit/glue/webworker_impl.cc29
-rw-r--r--webkit/glue/webworker_impl.h4
-rw-r--r--webkit/glue/webworkerclient_impl.cc48
-rw-r--r--webkit/glue/webworkerclient_impl.h4
-rw-r--r--webkit/tools/layout_tests/test_expectations.txt32
-rw-r--r--webkit/tools/test_shell/test_worker/test_webworker.cc12
-rw-r--r--webkit/tools/test_shell/test_worker/test_webworker.h8
24 files changed, 283 insertions, 86 deletions
diff --git a/chrome/browser/worker_host/message_port_dispatcher.cc b/chrome/browser/worker_host/message_port_dispatcher.cc
index 9804e86..4d371de 100644
--- a/chrome/browser/worker_host/message_port_dispatcher.cc
+++ b/chrome/browser/worker_host/message_port_dispatcher.cc
@@ -58,6 +58,22 @@ bool MessagePortDispatcher::OnMessageReceived(
return handled;
}
+void MessagePortDispatcher::UpdateMessagePort(
+ int message_port_id,
+ IPC::Message::Sender* sender,
+ int routing_id,
+ CallbackWithReturnValue<int>::Type* next_routing_id) {
+ if (!message_ports_.count(message_port_id)) {
+ NOTREACHED();
+ return;
+ }
+
+ MessagePort& port = message_ports_[message_port_id];
+ port.sender = sender;
+ port.route_id = routing_id;
+ port.next_routing_id = next_routing_id;
+}
+
bool MessagePortDispatcher::Send(IPC::Message* message) {
return sender_->Send(message);
}
@@ -84,7 +100,6 @@ void MessagePortDispatcher::OnDestroy(int message_port_id) {
}
DCHECK(message_ports_[message_port_id].queued_messages.empty());
- delete message_ports_[message_port_id].next_routing_id;
message_ports_.erase(message_port_id);
}
diff --git a/chrome/browser/worker_host/message_port_dispatcher.h b/chrome/browser/worker_host/message_port_dispatcher.h
index d443b07..ae2536b 100644
--- a/chrome/browser/worker_host/message_port_dispatcher.h
+++ b/chrome/browser/worker_host/message_port_dispatcher.h
@@ -28,6 +28,12 @@ class MessagePortDispatcher : public NotificationObserver {
CallbackWithReturnValue<int>::Type* next_routing_id,
bool* message_was_ok);
+ void UpdateMessagePort(
+ int message_port_id,
+ IPC::Message::Sender* sender,
+ int routing_id,
+ CallbackWithReturnValue<int>::Type* next_routing_id);
+
bool Send(IPC::Message* message);
private:
diff --git a/chrome/browser/worker_host/worker_process_host.cc b/chrome/browser/worker_host/worker_process_host.cc
index ed3fd9f..09c9aa4 100644
--- a/chrome/browser/worker_host/worker_process_host.cc
+++ b/chrome/browser/worker_host/worker_process_host.cc
@@ -18,6 +18,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/child_process_security_policy.h"
#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/renderer_host/resource_message_filter.h"
#include "chrome/browser/worker_host/message_port_dispatcher.h"
#include "chrome/browser/worker_host/worker_service.h"
#include "chrome/common/chrome_switches.h"
@@ -62,8 +63,8 @@ class WorkerCrashTask : public Task {
WorkerProcessHost::WorkerProcessHost(
ResourceDispatcherHost* resource_dispatcher_host_)
: ChildProcessHost(WORKER_PROCESS, resource_dispatcher_host_) {
- next_route_id_ = NewCallbackWithReturnValue(
- WorkerService::GetInstance(), &WorkerService::next_worker_route_id);
+ next_route_id_callback_.reset(NewCallbackWithReturnValue(
+ WorkerService::GetInstance(), &WorkerService::next_worker_route_id));
}
WorkerProcessHost::~WorkerProcessHost() {
@@ -148,9 +149,8 @@ bool WorkerProcessHost::FilterMessage(const IPC::Message& message,
for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) {
if (i->sender_pid == sender_pid &&
i->sender_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);
+ RelayMessage(
+ message, this, i->worker_route_id, next_route_id_callback_.get());
return true;
}
}
@@ -167,7 +167,7 @@ URLRequestContext* WorkerProcessHost::GetRequestContext(
void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) {
bool msg_is_ok = true;
bool handled = MessagePortDispatcher::GetInstance()->OnMessageReceived(
- message, this, next_route_id_, &msg_is_ok);
+ message, this, next_route_id_callback_.get(), &msg_is_ok);
if (!handled) {
handled = true;
@@ -192,9 +192,9 @@ 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->sender_route_id);
- i->sender->Send(new_message);
+ CallbackWithReturnValue<int>::Type* next_route_id =
+ GetNextRouteIdCallback(i->sender);
+ RelayMessage(message, i->sender, i->sender_route_id, next_route_id);
if (message.type() == WorkerHostMsg_WorkerContextDestroyed::ID) {
instances_.erase(i);
@@ -205,6 +205,55 @@ void WorkerProcessHost::OnMessageReceived(const IPC::Message& message) {
}
}
+CallbackWithReturnValue<int>::Type* WorkerProcessHost::GetNextRouteIdCallback(
+ IPC::Message::Sender* sender) {
+ // We don't keep callbacks for senders associated with workers, so figure out
+ // what kind of sender this is, and cast it to the correct class to get the
+ // callback.
+ for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
+ !iter.Done(); ++iter) {
+ WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
+ if (static_cast<IPC::Message::Sender*>(worker) == sender)
+ return worker->next_route_id_callback_.get();
+ }
+
+ // Must be a ResourceMessageFilter.
+ return static_cast<ResourceMessageFilter*>(sender)->next_route_id_callback();
+}
+
+void WorkerProcessHost::RelayMessage(
+ const IPC::Message& message,
+ IPC::Message::Sender* sender,
+ int route_id,
+ CallbackWithReturnValue<int>::Type* next_route_id) {
+ IPC::Message* new_message;
+ 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;
+ int sent_message_port_id;
+ int new_routing_id; // Ignore the bogus value from the sender.
+ if (!WorkerMsg_PostMessage::Read(
+ &message, &msg, &sent_message_port_id, &new_routing_id)) {
+ return;
+ }
+
+ if (sent_message_port_id != MSG_ROUTING_NONE) {
+ new_routing_id = next_route_id->Run();
+ MessagePortDispatcher::GetInstance()->UpdateMessagePort(
+ sent_message_port_id, sender, new_routing_id, next_route_id);
+ }
+
+ new_message = new WorkerMsg_PostMessage(
+ route_id, msg, sent_message_port_id, new_routing_id);
+ } else {
+ new_message = new IPC::Message(message);
+ new_message->set_routing_id(route_id);
+ }
+
+ sender->Send(new_message);
+}
+
void WorkerProcessHost::SenderShutdown(IPC::Message::Sender* sender) {
for (Instances::iterator i = instances_.begin(); i != instances_.end();) {
if (i->sender == sender) {
diff --git a/chrome/browser/worker_host/worker_process_host.h b/chrome/browser/worker_host/worker_process_host.h
index 44bc676..648d731 100644
--- a/chrome/browser/worker_host/worker_process_host.h
+++ b/chrome/browser/worker_host/worker_process_host.h
@@ -57,6 +57,17 @@ class WorkerProcessHost : public ChildProcessHost {
// Called when a message arrives from the worker process.
void OnMessageReceived(const IPC::Message& message);
+ // Given a Sender, returns the callback that generates a new routing id.
+ static CallbackWithReturnValue<int>::Type* GetNextRouteIdCallback(
+ IPC::Message::Sender* sender);
+
+ // Relays a message to the given endpoint. Takes care of parsing the message
+ // if it contains a message port and sending it a valid route id.
+ static void RelayMessage(const IPC::Message& message,
+ IPC::Message::Sender* sender,
+ int route_id,
+ CallbackWithReturnValue<int>::Type* next_route_id);
+
virtual bool CanShutdown() { return instances_.empty(); }
// Updates the title shown in the task manager.
@@ -71,7 +82,7 @@ class WorkerProcessHost : public ChildProcessHost {
Instances instances_;
// A callback to create a routing id for the associated worker process.
- CallbackWithReturnValue<int>::Type* next_route_id_;
+ scoped_ptr<CallbackWithReturnValue<int>::Type> next_route_id_callback_;
DISALLOW_COPY_AND_ASSIGN(WorkerProcessHost);
};
diff --git a/chrome/common/webmessageportchannel_impl.cc b/chrome/common/webmessageportchannel_impl.cc
index a165db8..6e1b4e1 100644
--- a/chrome/common/webmessageportchannel_impl.cc
+++ b/chrome/common/webmessageportchannel_impl.cc
@@ -48,7 +48,10 @@ void WebMessagePortChannelImpl::setClient(WebMessagePortChannelClient* client) {
void WebMessagePortChannelImpl::destroy() {
setClient(NULL);
- Release();
+
+ // Release the object on the main thread, since the destructor might want to
+ // send an IPC, and that has to happen on the main thread.
+ ChildThread::current()->message_loop()->ReleaseSoon(FROM_HERE, this);
}
void WebMessagePortChannelImpl::entangle(WebMessagePortChannel* channel) {
diff --git a/chrome/common/worker_messages_internal.h b/chrome/common/worker_messages_internal.h
index eb536e8..16dab5d 100644
--- a/chrome/common/worker_messages_internal.h
+++ b/chrome/common/worker_messages_internal.h
@@ -88,8 +88,10 @@ IPC_BEGIN_MESSAGES(Worker)
IPC_MESSAGE_ROUTED0(WorkerMsg_TerminateWorkerContext)
- IPC_MESSAGE_ROUTED1(WorkerMsg_PostMessageToWorkerContext,
- string16 /* message */)
+ IPC_MESSAGE_ROUTED3(WorkerMsg_PostMessage,
+ string16 /* message */,
+ int /* sent_message_port_id */,
+ int /* new_routing_id */)
IPC_MESSAGE_ROUTED0(WorkerMsg_WorkerObjectDestroyed)
IPC_END_MESSAGES(Worker)
@@ -99,9 +101,7 @@ 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 */)
-
+ // WorkerMsg_PostMessage is also sent here.
IPC_MESSAGE_ROUTED3(WorkerHostMsg_PostExceptionToWorkerObject,
string16 /* error_message */,
int /* line_number */,
diff --git a/chrome/renderer/webworker_proxy.cc b/chrome/renderer/webworker_proxy.cc
index 54fcd47..5552546 100644
--- a/chrome/renderer/webworker_proxy.cc
+++ b/chrome/renderer/webworker_proxy.cc
@@ -6,10 +6,12 @@
#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::WebString;
using WebKit::WebURL;
using WebKit::WebWorkerClient;
@@ -73,8 +75,18 @@ void WebWorkerProxy::terminateWorkerContext() {
}
void WebWorkerProxy::postMessageToWorkerContext(
- const WebString& message) {
- Send(new WorkerMsg_PostMessageToWorkerContext(route_id_, message));
+ const WebString& message, WebMessagePortChannel* channel) {
+ int message_port_id = MSG_ROUTING_NONE;
+ if (channel) {
+ WebMessagePortChannelImpl* webchannel =
+ static_cast<WebMessagePortChannelImpl*>(channel);
+ message_port_id = webchannel->message_port_id();
+ webchannel->QueueMessages();
+ DCHECK(message_port_id != MSG_ROUTING_NONE);
+ }
+
+ Send(new WorkerMsg_PostMessage(
+ route_id_, message, message_port_id, MSG_ROUTING_NONE));
}
void WebWorkerProxy::workerObjectDestroyed() {
@@ -107,9 +119,7 @@ void WebWorkerProxy::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(WebWorkerProxy, message)
IPC_MESSAGE_HANDLER(ViewMsg_DedicatedWorkerCreated,
OnDedicatedWorkerCreated)
- IPC_MESSAGE_FORWARD(WorkerHostMsg_PostMessageToWorkerObject,
- client_,
- WebWorkerClient::postMessageToWorkerObject)
+ IPC_MESSAGE_HANDLER(WorkerMsg_PostMessage, OnPostMessage)
IPC_MESSAGE_FORWARD(WorkerHostMsg_PostExceptionToWorkerObject,
client_,
WebWorkerClient::postExceptionToWorkerObject)
@@ -137,6 +147,18 @@ void WebWorkerProxy::OnDedicatedWorkerCreated() {
}
}
+void WebWorkerProxy::OnPostMessage(const string16& message,
+ int sent_message_port_id,
+ int new_routing_id) {
+ WebMessagePortChannel* channel = NULL;
+ if (sent_message_port_id != MSG_ROUTING_NONE) {
+ channel = new WebMessagePortChannelImpl(
+ new_routing_id, sent_message_port_id);
+ }
+
+ client_->postMessageToWorkerObject(message, channel);
+}
+
void WebWorkerProxy::OnPostConsoleMessageToWorkerObject(
const WorkerHostMsg_PostConsoleMessageToWorkerObject_Params& params) {
client_->postConsoleMessageToWorkerObject(params.destination_identifier,
diff --git a/chrome/renderer/webworker_proxy.h b/chrome/renderer/webworker_proxy.h
index 7567060..5eeb416 100644
--- a/chrome/renderer/webworker_proxy.h
+++ b/chrome/renderer/webworker_proxy.h
@@ -34,7 +34,9 @@ class WebWorkerProxy : public WebKit::WebWorker,
const WebKit::WebString& user_agent,
const WebKit::WebString& source_code);
virtual void terminateWorkerContext();
- virtual void postMessageToWorkerContext(const WebKit::WebString& message);
+ virtual void postMessageToWorkerContext(
+ const WebKit::WebString& message,
+ WebKit::WebMessagePortChannel* channel);
virtual void workerObjectDestroyed();
// IPC::Channel::Listener implementation.
@@ -44,6 +46,9 @@ class WebWorkerProxy : public WebKit::WebWorker,
bool Send(IPC::Message* message);
void OnDedicatedWorkerCreated();
+ void OnPostMessage(const string16& message,
+ int sent_message_port_id,
+ int new_routing_id);
void OnPostConsoleMessageToWorkerObject(
const WorkerHostMsg_PostConsoleMessageToWorkerObject_Params& params);
diff --git a/chrome/worker/nativewebworker_impl.cc b/chrome/worker/nativewebworker_impl.cc
index 5f12041..5fc3ddc 100644
--- a/chrome/worker/nativewebworker_impl.cc
+++ b/chrome/worker/nativewebworker_impl.cc
@@ -35,7 +35,7 @@ class PostMessageTask : public Task {
}
~PostMessageTask() { }
void Run() {
- client_->postMessageToWorkerObject(message_string_);
+ client_->postMessageToWorkerObject(message_string_, NULL);
}
private:
@@ -147,7 +147,7 @@ void NativeWebWorkerImpl::terminateWorkerContext() {
}
void NativeWebWorkerImpl::postMessageToWorkerContext(
- const WebKit::WebString& message) {
+ const WebKit::WebString& message, WebKit::WebMessagePortChannel* channel) {
size_t len;
char* bufp = WebStringToCharp(message, &len);
// Send a message to NaCl object
diff --git a/chrome/worker/nativewebworker_impl.h b/chrome/worker/nativewebworker_impl.h
index 6e280cb..7d0944c 100644
--- a/chrome/worker/nativewebworker_impl.h
+++ b/chrome/worker/nativewebworker_impl.h
@@ -27,7 +27,8 @@ class NativeWebWorkerImpl : public WebKit::WebWorker {
const WebKit::WebString& user_agent,
const WebKit::WebString& source_code);
void terminateWorkerContext();
- void postMessageToWorkerContext(const WebKit::WebString& message);
+ void postMessageToWorkerContext(const WebKit::WebString& message,
+ WebKit::WebMessagePortChannel* channel);
void workerObjectDestroyed();
private:
diff --git a/chrome/worker/webworkerclient_proxy.cc b/chrome/worker/webworkerclient_proxy.cc
index 79ba379..fdbaf9a 100644
--- a/chrome/worker/webworkerclient_proxy.cc
+++ b/chrome/worker/webworkerclient_proxy.cc
@@ -7,6 +7,7 @@
#include "base/command_line.h"
#include "chrome/common/child_process.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/common/webmessageportchannel_impl.h"
#include "chrome/common/worker_messages.h"
#include "chrome/renderer/webworker_proxy.h"
#include "chrome/worker/worker_thread.h"
@@ -16,6 +17,7 @@
#include "webkit/api/public/WebURL.h"
#include "webkit/api/public/WebWorker.h"
+using WebKit::WebMessagePortChannel;
using WebKit::WebString;
using WebKit::WebWorker;
using WebKit::WebWorkerClient;
@@ -78,8 +80,19 @@ WebWorkerClientProxy::~WebWorkerClientProxy() {
}
void WebWorkerClientProxy::postMessageToWorkerObject(
- const WebString& message) {
- Send(new WorkerHostMsg_PostMessageToWorkerObject(route_id_, message));
+ const WebString& message,
+ WebMessagePortChannel* channel) {
+ int message_port_id = MSG_ROUTING_NONE;
+ if (channel) {
+ WebMessagePortChannelImpl* webchannel =
+ static_cast<WebMessagePortChannelImpl*>(channel);
+ message_port_id = webchannel->message_port_id();
+ webchannel->QueueMessages();
+ DCHECK(message_port_id != MSG_ROUTING_NONE);
+ }
+
+ Send(new WorkerMsg_PostMessage(
+ route_id_, message, message_port_id, MSG_ROUTING_NONE));
}
void WebWorkerClientProxy::postExceptionToWorkerObject(
@@ -144,8 +157,7 @@ void WebWorkerClientProxy::OnMessageReceived(const IPC::Message& message) {
WebWorker::startWorkerContext)
IPC_MESSAGE_HANDLER(WorkerMsg_TerminateWorkerContext,
OnTerminateWorkerContext)
- IPC_MESSAGE_FORWARD(WorkerMsg_PostMessageToWorkerContext, impl_,
- WebWorker::postMessageToWorkerContext)
+ IPC_MESSAGE_HANDLER(WorkerMsg_PostMessage, OnPostMessage)
IPC_MESSAGE_FORWARD(WorkerMsg_WorkerObjectDestroyed, impl_,
WebWorker::workerObjectDestroyed)
IPC_END_MESSAGE_MAP()
@@ -166,3 +178,15 @@ void WebWorkerClientProxy::OnTerminateWorkerContext() {
MessageLoop::current()->PostDelayedTask(FROM_HERE,
new KillProcessTask(this), kMaxTimeForRunawayWorkerMs);
}
+
+void WebWorkerClientProxy::OnPostMessage(const string16& message,
+ int sent_message_port_id,
+ int new_routing_id) {
+ WebMessagePortChannel* channel = NULL;
+ if (sent_message_port_id != MSG_ROUTING_NONE) {
+ channel = new WebMessagePortChannelImpl(
+ new_routing_id, sent_message_port_id);
+ }
+
+ impl_->postMessageToWorkerContext(message, channel);
+}
diff --git a/chrome/worker/webworkerclient_proxy.h b/chrome/worker/webworkerclient_proxy.h
index 0e74e41..aadbe07 100644
--- a/chrome/worker/webworkerclient_proxy.h
+++ b/chrome/worker/webworkerclient_proxy.h
@@ -25,7 +25,9 @@ class WebWorkerClientProxy : public WebKit::WebWorkerClient,
WebWorkerClientProxy(const GURL& url, int route_id);
// WebWorkerClient implementation.
- virtual void postMessageToWorkerObject(const WebKit::WebString& message);
+ virtual void postMessageToWorkerObject(
+ const WebKit::WebString& message,
+ WebKit::WebMessagePortChannel* channel);
virtual void postExceptionToWorkerObject(
const WebKit::WebString& error_message,
int line_number,
@@ -52,6 +54,9 @@ class WebWorkerClientProxy : public WebKit::WebWorkerClient,
bool Send(IPC::Message* message);
void OnTerminateWorkerContext();
+ void OnPostMessage(const string16& message,
+ int sent_message_port_id,
+ int new_routing_id);
// The source url for this worker.
GURL url_;
diff --git a/chrome/worker/worker_uitest.cc b/chrome/worker/worker_uitest.cc
index cd94fd4..965036d 100644
--- a/chrome/worker/worker_uitest.cc
+++ b/chrome/worker/worker_uitest.cc
@@ -46,6 +46,7 @@ TEST_F(WorkerTest, WorkerFastLayoutTests) {
"worker-event-listener.html",
"worker-gc.html",
"worker-location.html",
+ "worker-messageport.html",
"worker-navigator.html",
"worker-replace-global-constructor.html",
"worker-replace-self.html",
@@ -113,7 +114,7 @@ TEST_F(WorkerTest, WorkerXhrHttpLayoutTests) {
StopHttpServer();
}
-TEST_F(WorkerTest, DISABLED_MessagePorts) {
+TEST_F(WorkerTest, MessagePorts) {
static const char* kLayoutTestFiles[] = {
"message-channel-gc.html",
"message-channel-gc-2.html",
diff --git a/webkit/api/public/WebWorker.h b/webkit/api/public/WebWorker.h
index 908993e..480b34a 100644
--- a/webkit/api/public/WebWorker.h
+++ b/webkit/api/public/WebWorker.h
@@ -1,10 +1,10 @@
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
@@ -14,7 +14,7 @@
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +34,7 @@
#include "WebCommon.h"
namespace WebKit {
+ class WebMessagePortChannel;
class WebString;
class WebURL;
class WebWorkerClient;
@@ -49,7 +50,8 @@ namespace WebKit {
const WebString& userAgent,
const WebString& sourceCode) = 0;
virtual void terminateWorkerContext() = 0;
- virtual void postMessageToWorkerContext(const WebString&) = 0;
+ virtual void postMessageToWorkerContext(const WebString&,
+ WebMessagePortChannel*) = 0;
virtual void workerObjectDestroyed() = 0;
};
diff --git a/webkit/api/public/WebWorkerClient.h b/webkit/api/public/WebWorkerClient.h
index a5faddd..30c2afb 100644
--- a/webkit/api/public/WebWorkerClient.h
+++ b/webkit/api/public/WebWorkerClient.h
@@ -34,6 +34,7 @@
#include "WebCommon.h"
namespace WebKit {
+ class WebMessagePortChannel;
class WebString;
class WebWorker;
@@ -42,7 +43,8 @@ namespace WebKit {
// the Worker object, unless noted.
class WebWorkerClient {
public:
- virtual void postMessageToWorkerObject(const WebString&) = 0;
+ virtual void postMessageToWorkerObject(const WebString&,
+ WebMessagePortChannel*) = 0;
virtual void postExceptionToWorkerObject(
const WebString& errorString, int lineNumber,
diff --git a/webkit/api/src/PlatformMessagePortChannel.cpp b/webkit/api/src/PlatformMessagePortChannel.cpp
index 72a626a..cafbdea 100644
--- a/webkit/api/src/PlatformMessagePortChannel.cpp
+++ b/webkit/api/src/PlatformMessagePortChannel.cpp
@@ -122,7 +122,8 @@ PlatformMessagePortChannel::PlatformMessagePortChannel()
: m_localPort(0)
{
m_webChannel = webKitClient()->createMessagePortChannel();
- m_webChannel->setClient(this);
+ if (m_webChannel)
+ m_webChannel->setClient(this);
}
PlatformMessagePortChannel::PlatformMessagePortChannel(WebMessagePortChannel* channel)
@@ -174,7 +175,7 @@ void PlatformMessagePortChannel::disentangle()
void PlatformMessagePortChannel::postMessageToRemote(PassOwnPtr<MessagePortChannel::EventData> message)
{
- if (!m_localPort)
+ if (!m_localPort || !m_webChannel)
return;
WebString messageString = message->message();
@@ -232,7 +233,8 @@ bool PlatformMessagePortChannel::hasPendingActivity()
void PlatformMessagePortChannel::setEntangledChannel(PassRefPtr<PlatformMessagePortChannel> remote)
{
- m_webChannel->entangle(remote->m_webChannel);
+ if (m_webChannel)
+ m_webChannel->entangle(remote->m_webChannel);
MutexLocker lock(m_mutex);
m_entangledChannel = remote;
diff --git a/webkit/api/src/PlatformMessagePortChannel.h b/webkit/api/src/PlatformMessagePortChannel.h
index 08c6a5c..e668e8b 100644
--- a/webkit/api/src/PlatformMessagePortChannel.h
+++ b/webkit/api/src/PlatformMessagePortChannel.h
@@ -31,7 +31,9 @@
#ifndef PlatformMessagePortChannel_h
#define PlatformMessagePortChannel_h
-#include "WebMessagePortChannelClient.h"
+// FIXME: This relative path is a temporary hack to support using this
+// header from webkit/glue.
+#include "../public/WebMessagePortChannelClient.h"
#include "MessagePortChannel.h"
diff --git a/webkit/glue/webworker_impl.cc b/webkit/glue/webworker_impl.cc
index 6c38ae2..af1c652 100644
--- a/webkit/glue/webworker_impl.cc
+++ b/webkit/glue/webworker_impl.cc
@@ -21,10 +21,12 @@
#undef LOG
#include "base/logging.h"
+#include "webkit/api/public/WebMessagePortChannel.h"
#include "webkit/api/public/WebScreenInfo.h"
#include "webkit/api/public/WebString.h"
#include "webkit/api/public/WebURL.h"
#include "webkit/api/public/WebWorkerClient.h"
+#include "webkit/api/src/PlatformMessagePortChannel.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webdatasource_impl.h"
#include "webkit/glue/webframe_impl.h"
@@ -34,6 +36,7 @@
#include "webkit/glue/webworker_impl.h"
using WebKit::WebCursorInfo;
+using WebKit::WebMessagePortChannel;
using WebKit::WebNavigationPolicy;
using WebKit::WebRect;
using WebKit::WebScreenInfo;
@@ -190,13 +193,23 @@ void WebWorkerImpl::terminateWorkerContext() {
worker_thread_->stop();
}
-void WebWorkerImpl::postMessageToWorkerContext(const WebString& message) {
- // TODO(jam): Need to update these APIs to accept MessagePorts.
+void WebWorkerImpl::postMessageToWorkerContext(
+ const WebString& message,
+ WebMessagePortChannel* webchannel) {
+
+ OwnPtr<WebCore::MessagePortChannel> channel;
+ if (webchannel) {
+ RefPtr<WebCore::PlatformMessagePortChannel> platform_channel =
+ WebCore::PlatformMessagePortChannel::create(webchannel);
+ webchannel->setClient(platform_channel.get());
+ channel = WebCore::MessagePortChannel::create(platform_channel);
+ }
+
worker_thread_->runLoop().postTask(WebCore::createCallbackTask(
&PostMessageToWorkerContextTask,
this,
webkit_glue::WebStringToString(message),
- WTF::PassOwnPtr<WebCore::MessagePortChannel>(0)));
+ channel.release()));
}
void WebWorkerImpl::workerObjectDestroyed() {
@@ -236,10 +249,14 @@ void WebWorkerImpl::PostMessageTask(
WebWorkerImpl* this_ptr,
WebCore::String message,
WTF::PassOwnPtr<WebCore::MessagePortChannel> channel) {
- // TODO(jam): Update to pass a MessagePortChannel or
- // PlatformMessagePortChannel when we add MessagePort support to Chrome.
+ WebMessagePortChannel* webChannel = NULL;
+ if (channel.get()) {
+ webChannel = channel->channel()->webChannelRelease();
+ webChannel->setClient(0);
+ }
+
this_ptr->client_->postMessageToWorkerObject(
- webkit_glue::StringToWebString(message));
+ webkit_glue::StringToWebString(message), webChannel);
}
void WebWorkerImpl::postExceptionToWorkerObject(
diff --git a/webkit/glue/webworker_impl.h b/webkit/glue/webworker_impl.h
index 0a1a3db..9495ded 100644
--- a/webkit/glue/webworker_impl.h
+++ b/webkit/glue/webworker_impl.h
@@ -66,7 +66,9 @@ class WebWorkerImpl: public WebCore::WorkerObjectProxy,
const WebKit::WebString& user_agent,
const WebKit::WebString& source_code);
virtual void terminateWorkerContext();
- virtual void postMessageToWorkerContext(const WebKit::WebString& message);
+ virtual void postMessageToWorkerContext(
+ const WebKit::WebString& message,
+ WebKit::WebMessagePortChannel* channel);
virtual void workerObjectDestroyed();
WebKit::WebWorkerClient* client() { return client_; }
diff --git a/webkit/glue/webworkerclient_impl.cc b/webkit/glue/webworkerclient_impl.cc
index 8ac5662..db754aa 100644
--- a/webkit/glue/webworkerclient_impl.cc
+++ b/webkit/glue/webworkerclient_impl.cc
@@ -28,9 +28,11 @@
#include "base/command_line.h"
#include "webkit/api/public/WebKit.h"
#include "webkit/api/public/WebKitClient.h"
+#include "webkit/api/public/WebMessagePortChannel.h"
#include "webkit/api/public/WebString.h"
#include "webkit/api/public/WebURL.h"
#include "webkit/api/public/WebWorker.h"
+#include "webkit/api/src/PlatformMessagePortChannel.h"
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webframeloaderclient_impl.h"
#include "webkit/glue/webframe_impl.h"
@@ -38,6 +40,7 @@
#include "webkit/glue/webview_impl.h"
#include "webkit/glue/webworker_impl.h"
+using WebKit::WebMessagePortChannel;
using WebKit::WebString;
using WebKit::WebWorker;
using WebKit::WebWorkerClient;
@@ -151,7 +154,7 @@ void WebWorkerClientImpl::terminateWorkerContext() {
void WebWorkerClientImpl::postMessageToWorkerContext(
const WebCore::String& message,
- WTF::PassOwnPtr<WebCore::MessagePortChannel> port) {
+ WTF::PassOwnPtr<WebCore::MessagePortChannel> channel) {
// Worker.terminate() could be called from JS before the context is started.
if (asked_to_terminate_)
return;
@@ -161,14 +164,18 @@ void WebWorkerClientImpl::postMessageToWorkerContext(
if (!WTF::isMainThread()) {
WebWorkerImpl::DispatchTaskToMainThread(
WebCore::createCallbackTask(
- &PostMessageToWorkerContextTask, this, message, port));
+ &PostMessageToWorkerContextTask, this, message, channel));
return;
}
- // TODO(jam): Update to pass a MessagePortChannel or
- // PlatformMessagePortChannel when we add MessagePort support to Chrome.
+ WebMessagePortChannel* webchannel = NULL;
+ if (channel.get()) {
+ webchannel = channel->channel()->webChannelRelease();
+ webchannel->setClient(0);
+ }
+
webworker_->postMessageToWorkerContext(
- webkit_glue::StringToWebString(message));
+ webkit_glue::StringToWebString(message), webchannel);
}
bool WebWorkerClientImpl::hasPendingActivity() const {
@@ -188,18 +195,27 @@ void WebWorkerClientImpl::workerObjectDestroyed() {
WebCore::createCallbackTask(&WorkerObjectDestroyedTask, this));
}
-void WebWorkerClientImpl::postMessageToWorkerObject(const WebString& message) {
- // TODO(jam): Add support for passing MessagePorts when they are supported
- // in Chrome.
+void WebWorkerClientImpl::postMessageToWorkerObject(
+ const WebString& message,
+ WebMessagePortChannel* channel) {
+ WebCore::String message2 = webkit_glue::WebStringToString(message);
+ OwnPtr<WebCore::MessagePortChannel> channel2;
+ if (channel) {
+ RefPtr<WebCore::PlatformMessagePortChannel> platform_channel =
+ WebCore::PlatformMessagePortChannel::create(channel);
+ channel->setClient(platform_channel.get());
+ channel2 = WebCore::MessagePortChannel::create(platform_channel);
+ }
+
if (WTF::currentThread() != worker_thread_id_) {
script_execution_context_->postTask(
WebCore::createCallbackTask(&PostMessageToWorkerObjectTask, this,
- webkit_glue::WebStringToString(message),
- WTF::PassOwnPtr<WebCore::MessagePortChannel>(0)));
+ message2, channel2.release()));
return;
}
- worker_->dispatchMessage(webkit_glue::WebStringToString(message), 0);
+ PostMessageToWorkerObjectTask(
+ script_execution_context_.get(), this, message2, channel2.release());
}
void WebWorkerClientImpl::postExceptionToWorkerObject(
@@ -298,10 +314,14 @@ void WebWorkerClientImpl::PostMessageToWorkerContextTask(
WebWorkerClientImpl* this_ptr,
const WebCore::String& message,
WTF::PassOwnPtr<WebCore::MessagePortChannel> channel) {
- // TODO(jam): Update to pass a MessagePortChannel or
- // PlatformMessagePortChannel when we add MessagePort support to Chrome.
+ WebMessagePortChannel* webChannel = NULL;
+ if (channel.get()) {
+ webChannel = channel->channel()->webChannelRelease();
+ webChannel->setClient(0);
+ }
+
this_ptr->webworker_->postMessageToWorkerContext(
- webkit_glue::StringToWebString(message));
+ webkit_glue::StringToWebString(message), webChannel);
}
void WebWorkerClientImpl::WorkerObjectDestroyedTask(
diff --git a/webkit/glue/webworkerclient_impl.h b/webkit/glue/webworkerclient_impl.h
index 18422cf..420106b 100644
--- a/webkit/glue/webworkerclient_impl.h
+++ b/webkit/glue/webworkerclient_impl.h
@@ -48,7 +48,9 @@ class WebWorkerClientImpl : public WebCore::WorkerContextProxy,
// WebWorkerClient methods:
// These are called on the main WebKit thread.
- virtual void postMessageToWorkerObject(const WebKit::WebString& message);
+ virtual void postMessageToWorkerObject(
+ const WebKit::WebString& message,
+ WebKit::WebMessagePortChannel* channel);
virtual void postExceptionToWorkerObject(
const WebKit::WebString& error_message,
int line_number,
diff --git a/webkit/tools/layout_tests/test_expectations.txt b/webkit/tools/layout_tests/test_expectations.txt
index f0214f6..b29eac3 100644
--- a/webkit/tools/layout_tests/test_expectations.txt
+++ b/webkit/tools/layout_tests/test_expectations.txt
@@ -2786,22 +2786,22 @@ BUG16355 LINUX : LayoutTests/fast/forms/slider-delete-while-dragging-thumb.html
// Tests that rely on cross-process MessagePorts. No point in running them in
// test_shell, since we'd have to use a completely different implementation from
// what is used in the browser.
-BUG16410 SKIP : LayoutTests/fast/events/message-channel-gc-2.html = CRASH
-BUG16410 SKIP : LayoutTests/fast/events/message-channel-gc-3.html = CRASH
-BUG16410 SKIP : LayoutTests/fast/events/message-channel-gc-4.html = CRASH
-BUG16410 SKIP : LayoutTests/fast/events/message-channel-gc.html = CRASH
-BUG16410 SKIP : LayoutTests/fast/events/message-channel-listener-circular-ownership.html = CRASH
-BUG16410 SKIP : LayoutTests/fast/events/message-port-clone.html = CRASH
-BUG16410 SKIP : LayoutTests/fast/events/message-port-deleted-document.html = CRASH
-BUG16410 SKIP : LayoutTests/fast/events/message-port-deleted-frame.html = CRASH
-BUG16410 SKIP : LayoutTests/fast/events/message-port-inactive-document.html = CRASH
-BUG16410 SKIP : LayoutTests/fast/events/message-port-no-wrapper.html = CRASH
-BUG16410 SKIP : LayoutTests/fast/events/message-port.html = CRASH
-BUG16410 SKIP : LayoutTests/http/tests/security/MessagePort/event-listener-context.html = CRASH
-BUG16410 SKIP : chrome/fast/dom/messageport-gc.html = CRASH
-BUG16410 SKIP : LayoutTests/fast/workers/worker-cloneport.html = FAIL CRASH
-BUG16410 SKIP : LayoutTests/fast/workers/worker-messageport-gc.html = FAIL CRASH
-BUG16410 SKIP : LayoutTests/fast/workers/worker-messageport.html = FAIL CRASH
+WONTFIX SKIP : LayoutTests/fast/events/message-channel-gc-2.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/events/message-channel-gc-3.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/events/message-channel-gc-4.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/events/message-channel-gc.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/events/message-channel-listener-circular-ownership.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/events/message-port-clone.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/events/message-port-deleted-document.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/events/message-port-deleted-frame.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/events/message-port-inactive-document.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/events/message-port-no-wrapper.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/events/message-port.html = FAIL
+WONTFIX SKIP : LayoutTests/http/tests/security/MessagePort/event-listener-context.html = FAIL
+WONTFIX SKIP : chrome/fast/dom/messageport-gc.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/workers/worker-cloneport.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/workers/worker-messageport-gc.html = FAIL
+WONTFIX SKIP : LayoutTests/fast/workers/worker-messageport.html = FAIL
// WebKit merge 45685:45738
BUG16652 : LayoutTests/fast/replaced/embed-display-none.html = PASS CRASH
diff --git a/webkit/tools/test_shell/test_worker/test_webworker.cc b/webkit/tools/test_shell/test_worker/test_webworker.cc
index 9adacd8..6fdce06 100644
--- a/webkit/tools/test_shell/test_worker/test_webworker.cc
+++ b/webkit/tools/test_shell/test_worker/test_webworker.cc
@@ -41,7 +41,7 @@ void TestWebWorker::startWorkerContext(const WebURL& script_url,
webworker_impl_->startWorkerContext(script_url, user_agent, source_code);
for (size_t i = 0; i < queued_messages_.size(); ++i)
- webworker_impl_->postMessageToWorkerContext(queued_messages_[i]);
+ webworker_impl_->postMessageToWorkerContext(queued_messages_[i], NULL);
queued_messages_.clear();
}
@@ -50,9 +50,10 @@ void TestWebWorker::terminateWorkerContext() {
webworker_impl_->terminateWorkerContext();
}
-void TestWebWorker::postMessageToWorkerContext(const WebString& message) {
+void TestWebWorker::postMessageToWorkerContext(const WebString& message,
+ WebKit::WebMessagePortChannel*) {
if (webworker_impl_)
- webworker_impl_->postMessageToWorkerContext(message);
+ webworker_impl_->postMessageToWorkerContext(message, NULL);
else
queued_messages_.push_back(message);
}
@@ -65,14 +66,15 @@ void TestWebWorker::workerObjectDestroyed() {
Release(); // Releases the reference held for worker object.
}
-void TestWebWorker::postMessageToWorkerObject(const WebString& message) {
+void TestWebWorker::postMessageToWorkerObject(const WebString& message,
+ WebKit::WebMessagePortChannel*) {
if (!webworkerclient_delegate_)
return;
// The string was created in the dll's memory space as a result of a postTask.
// If we pass it to test shell's memory space, it'll cause problems when GC
// occurs. So duplicate it from the test shell's memory space first.
webworkerclient_delegate_->postMessageToWorkerObject(
- webworker_helper_->DuplicateString(message));
+ webworker_helper_->DuplicateString(message), NULL);
}
void TestWebWorker::postExceptionToWorkerObject(const WebString& error_message,
diff --git a/webkit/tools/test_shell/test_worker/test_webworker.h b/webkit/tools/test_shell/test_worker/test_webworker.h
index f0ee118..22ffecd 100644
--- a/webkit/tools/test_shell/test_worker/test_webworker.h
+++ b/webkit/tools/test_shell/test_worker/test_webworker.h
@@ -29,11 +29,15 @@ class TestWebWorker : public WebKit::WebWorker,
const WebKit::WebString& user_agent,
const WebKit::WebString& source_code);
virtual void terminateWorkerContext();
- virtual void postMessageToWorkerContext(const WebKit::WebString&);
+ virtual void postMessageToWorkerContext(
+ const WebKit::WebString& message,
+ WebKit::WebMessagePortChannel* channel);
virtual void workerObjectDestroyed();
// WebWorkerClient methods:
- virtual void postMessageToWorkerObject(const WebKit::WebString& message);
+ virtual void postMessageToWorkerObject(
+ const WebKit::WebString& message,
+ WebKit::WebMessagePortChannel* channel);
virtual void postExceptionToWorkerObject(
const WebKit::WebString& error_message,
int line_number,