diff options
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, |