From c36a24cbfdc6cb945f104d65174ef2aaa59e5dd3 Mon Sep 17 00:00:00 2001 From: "jorlow@chromium.org" Date: Wed, 26 Aug 2009 21:38:03 +0000 Subject: First half of updating Worker.postMessage(), DOMWindow.postMessage(), and MessagePort.postMessage() to accept multiple MessagePorts. Original review: http://codereview.chromium.org/173193 TBR=atwilson TEST=None (new functionality not yet exposed via bindings, so existing tests suffice) BUG=19948 Review URL: http://codereview.chromium.org/174566 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24536 0039d316-1c4b-4281-b951-d872f2087c98 --- DEPS | 2 +- .../browser/worker_host/message_port_dispatcher.cc | 50 +++++++------- .../browser/worker_host/message_port_dispatcher.h | 6 +- chrome/browser/worker_host/worker_process_host.cc | 16 +++-- chrome/common/webmessageportchannel_impl.cc | 77 ++++++++++++++-------- chrome/common/webmessageportchannel_impl.h | 11 ++-- chrome/common/worker_messages.h | 3 +- chrome/common/worker_messages_internal.h | 11 ++-- chrome/renderer/webworker_proxy.cc | 35 +++++----- chrome/renderer/webworker_proxy.h | 6 +- chrome/worker/nativewebworker_impl.cc | 6 +- chrome/worker/nativewebworker_impl.h | 5 +- chrome/worker/webworkerclient_proxy.cc | 34 +++++----- chrome/worker/webworkerclient_proxy.h | 10 +-- webkit/api/public/WebMessagePortChannel.h | 9 ++- webkit/api/public/WebVector.h | 2 +- webkit/api/public/WebWorker.h | 8 +-- webkit/api/public/WebWorkerClient.h | 8 +-- webkit/api/src/PlatformMessagePortChannel.cpp | 36 +++++----- webkit/glue/webworker_impl.cc | 50 +++++++------- webkit/glue/webworker_impl.h | 10 ++- webkit/glue/webworkerclient_impl.cc | 62 +++++++++-------- webkit/glue/webworkerclient_impl.h | 9 ++- .../tools/test_shell/test_worker/test_webworker.cc | 17 +++-- .../tools/test_shell/test_worker/test_webworker.h | 4 +- 25 files changed, 275 insertions(+), 212 deletions(-) diff --git a/DEPS b/DEPS index ddddc82..626eea8 100644 --- a/DEPS +++ b/DEPS @@ -1,7 +1,7 @@ vars = { "webkit_trunk": "http://svn.webkit.org/repository/webkit/trunk", - "webkit_revision": "47790", + "webkit_revision": "47791", } diff --git a/chrome/browser/worker_host/message_port_dispatcher.cc b/chrome/browser/worker_host/message_port_dispatcher.cc index 4d371de..41ebc37 100644 --- a/chrome/browser/worker_host/message_port_dispatcher.cc +++ b/chrome/browser/worker_host/message_port_dispatcher.cc @@ -117,9 +117,10 @@ void MessagePortDispatcher::OnEntangle(int local_message_port_id, local_message_port_id; } -void MessagePortDispatcher::OnPostMessage(int sender_message_port_id, - const string16& message, - int sent_message_port_id) { +void MessagePortDispatcher::OnPostMessage( + int sender_message_port_id, + const string16& message, + const std::vector& sent_message_port_ids) { if (!message_ports_.count(sender_message_port_id)) { NOTREACHED(); return; @@ -135,47 +136,52 @@ void MessagePortDispatcher::OnPostMessage(int sender_message_port_id, return; } - PostMessageTo(entangled_message_port_id, message, sent_message_port_id); + PostMessageTo(entangled_message_port_id, message, sent_message_port_ids); } -void MessagePortDispatcher::PostMessageTo(int message_port_id, - const string16& message, - int sent_message_port_id) { - if (!message_ports_.count(message_port_id) || - (sent_message_port_id != MSG_ROUTING_NONE && - !message_ports_.count(sent_message_port_id))) { +void MessagePortDispatcher::PostMessageTo( + int message_port_id, + const string16& message, + const std::vector& sent_message_port_ids) { + if (!message_ports_.count(message_port_id)) { NOTREACHED(); return; } + for (size_t i = 0; i < sent_message_port_ids.size(); ++i) { + if (!message_ports_.count(sent_message_port_ids[i])) { + NOTREACHED(); + return; + } + } MessagePort& entangled_port = message_ports_[message_port_id]; - MessagePort* sent_port = NULL; - if (sent_message_port_id != MSG_ROUTING_NONE) { - sent_port = &message_ports_[sent_message_port_id]; - sent_port->queue_messages = true; + std::vector sent_ports(sent_message_port_ids.size()); + for (size_t i = 0; i < sent_message_port_ids.size(); ++i) { + sent_ports[i] = &message_ports_[sent_message_port_ids[i]]; + sent_ports[i]->queue_messages = true; } if (entangled_port.queue_messages) { entangled_port.queued_messages.push_back( - std::make_pair(message, sent_message_port_id)); + std::make_pair(message, sent_message_port_ids)); } else { // If a message port was sent around, the new location will need a routing // id. Instead of having the created port send us a sync message to get it, // send along with the message. - int new_routing_id = MSG_ROUTING_NONE; - if (sent_message_port_id != MSG_ROUTING_NONE) { - new_routing_id = entangled_port.next_routing_id->Run(); - sent_port->sender = entangled_port.sender; + std::vector new_routing_ids(sent_message_port_ids.size()); + for (size_t i = 0; i < sent_message_port_ids.size(); ++i) { + new_routing_ids[i] = entangled_port.next_routing_id->Run(); + sent_ports[i]->sender = entangled_port.sender; // Update the entry for the sent port as it can be in a different process. - sent_port->route_id = new_routing_id; + sent_ports[i]->route_id = new_routing_ids[i]; } // Now send the message to the entangled port. IPC::Message* ipc_msg = new WorkerProcessMsg_Message( - entangled_port.route_id, message, sent_message_port_id, - new_routing_id); + entangled_port.route_id, message, sent_message_port_ids, + new_routing_ids); entangled_port.sender->Send(ipc_msg); } } diff --git a/chrome/browser/worker_host/message_port_dispatcher.h b/chrome/browser/worker_host/message_port_dispatcher.h index ae2536b..c728f38 100644 --- a/chrome/browser/worker_host/message_port_dispatcher.h +++ b/chrome/browser/worker_host/message_port_dispatcher.h @@ -18,7 +18,7 @@ class MessagePortDispatcher : public NotificationObserver { public: - typedef std::vector > QueuedMessages; + typedef std::vector > > QueuedMessages; // Returns the MessagePortDispatcher singleton. static MessagePortDispatcher* GetInstance(); @@ -48,14 +48,14 @@ class MessagePortDispatcher : public NotificationObserver { void OnEntangle(int local_message_port_id, int remote_message_port_id); void OnPostMessage(int sender_message_port_id, const string16& message, - int sent_message_port_id); + const std::vector& sent_message_port_ids); void OnQueueMessages(int message_port_id); void OnSendQueuedMessages(int message_port_id, const QueuedMessages& queued_messages); void PostMessageTo(int message_port_id, const string16& message, - int sent_message_port_id); + const std::vector& sent_message_port_ids); // NotificationObserver interface. void Observe(NotificationType type, diff --git a/chrome/browser/worker_host/worker_process_host.cc b/chrome/browser/worker_host/worker_process_host.cc index 3de362cf..69d3a96 100644 --- a/chrome/browser/worker_host/worker_process_host.cc +++ b/chrome/browser/worker_host/worker_process_host.cc @@ -5,6 +5,7 @@ #include "chrome/browser/worker_host/worker_process_host.h" #include +#include #include "base/command_line.h" #include "base/debug_util.h" @@ -232,21 +233,22 @@ void WorkerProcessHost::RelayMessage( // 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 = MSG_ROUTING_NONE; - int new_routing_id = MSG_ROUTING_NONE; + std::vector sent_message_port_ids; + std::vector new_routing_ids; if (!WorkerMsg_PostMessage::Read( - &message, &msg, &sent_message_port_id, &new_routing_id)) { + &message, &msg, &sent_message_port_ids, &new_routing_ids)) { return; } + DCHECK(sent_message_port_ids.size() == new_routing_ids.size()); - if (sent_message_port_id != MSG_ROUTING_NONE) { - new_routing_id = next_route_id->Run(); + 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_id, sender, new_routing_id, next_route_id); + sent_message_port_ids[i], sender, new_routing_ids[i], next_route_id); } new_message = new WorkerMsg_PostMessage( - route_id, msg, sent_message_port_id, new_routing_id); + route_id, msg, sent_message_port_ids, new_routing_ids); } else { new_message = new IPC::Message(message); new_message->set_routing_id(route_id); diff --git a/chrome/common/webmessageportchannel_impl.cc b/chrome/common/webmessageportchannel_impl.cc index 6e1b4e1..f585355 100644 --- a/chrome/common/webmessageportchannel_impl.cc +++ b/chrome/common/webmessageportchannel_impl.cc @@ -11,6 +11,7 @@ #include "webkit/api/public/WebMessagePortChannelClient.h" using WebKit::WebMessagePortChannel; +using WebKit::WebMessagePortChannelArray; using WebKit::WebMessagePortChannelClient; using WebKit::WebString; @@ -33,6 +34,16 @@ WebMessagePortChannelImpl::WebMessagePortChannelImpl( } WebMessagePortChannelImpl::~WebMessagePortChannelImpl() { + // If we have any queued messages with attached ports, manually destroy them. + while (!message_queue_.empty()) { + const std::vector& channel_array = + message_queue_.front().ports; + for (size_t i = 0; i < channel_array.size(); i++) { + channel_array[i]->destroy(); + } + message_queue_.pop(); + } + if (message_port_id_ != MSG_ROUTING_NONE) Send(new WorkerProcessHostMsg_DestroyMessagePort(message_port_id_)); @@ -65,39 +76,46 @@ void WebMessagePortChannelImpl::entangle(WebMessagePortChannel* channel) { void WebMessagePortChannelImpl::postMessage( const WebString& message, - WebMessagePortChannel* channel) { + WebMessagePortChannelArray* channels) { if (MessageLoop::current() != ChildThread::current()->message_loop()) { ChildThread::current()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &WebMessagePortChannelImpl::postMessage, - message, channel)); + message, channels)); return; } - WebMessagePortChannelImpl* webchannel = - static_cast(channel); - - int message_port_id = MSG_ROUTING_NONE; - if (webchannel) { - message_port_id = webchannel->message_port_id(); - webchannel->QueueMessages(); - DCHECK(message_port_id != MSG_ROUTING_NONE); + std::vector message_port_ids(channels ? channels->size() : 0); + if (channels) { + for (size_t i = 0; i < channels->size(); ++i) { + WebMessagePortChannelImpl* webchannel = + static_cast((*channels)[i]); + message_port_ids[i] = webchannel->message_port_id(); + webchannel->QueueMessages(); + DCHECK(message_port_ids[i] != MSG_ROUTING_NONE); + } } IPC::Message* msg = new WorkerProcessHostMsg_PostMessage( - message_port_id_, message, message_port_id); - + message_port_id_, message, message_port_ids); Send(msg); } bool WebMessagePortChannelImpl::tryGetMessage( WebString* message, - WebMessagePortChannel** channel) { + WebMessagePortChannelArray& channels) { AutoLock auto_lock(lock_); if (message_queue_.empty()) return false; *message = message_queue_.front().message; - *channel = message_queue_.front().port.release(); + const std::vector& channel_array = + message_queue_.front().ports; + WebMessagePortChannelArray result_ports(channel_array.size()); + for (size_t i = 0; i < channel_array.size(); i++) { + result_ports[i] = channel_array[i]; + } + + channels.swap(result_ports); message_queue_.pop(); return true; } @@ -162,16 +180,19 @@ void WebMessagePortChannelImpl::OnMessageReceived(const IPC::Message& message) { IPC_END_MESSAGE_MAP() } -void WebMessagePortChannelImpl::OnMessage(const string16& message, - int sent_message_port_id, - int new_routing_id) { +void WebMessagePortChannelImpl::OnMessage( + const string16& message, + const std::vector& sent_message_port_ids, + const std::vector& new_routing_ids) { AutoLock auto_lock(lock_); Message msg; msg.message = message; - msg.port = NULL; - if (sent_message_port_id != MSG_ROUTING_NONE) { - msg.port = new WebMessagePortChannelImpl( - new_routing_id, sent_message_port_id); + if (!sent_message_port_ids.empty()) { + msg.ports.resize(sent_message_port_ids.size()); + for (size_t i = 0; i < sent_message_port_ids.size(); ++i) { + msg.ports[i] = new WebMessagePortChannelImpl( + new_routing_ids[i], sent_message_port_ids[i]); + } } bool was_empty = message_queue_.empty(); @@ -181,18 +202,20 @@ void WebMessagePortChannelImpl::OnMessage(const string16& message, } void WebMessagePortChannelImpl::OnMessagedQueued() { - std::vector > queued_messages; + std::vector queued_messages; { AutoLock auto_lock(lock_); queued_messages.reserve(message_queue_.size()); while (!message_queue_.empty()) { string16 message = message_queue_.front().message; - int port = MSG_ROUTING_NONE; - if (message_queue_.front().port) - port = message_queue_.front().port->message_port_id(); - - queued_messages.push_back(std::make_pair(message, port)); + const std::vector& channel_array = + message_queue_.front().ports; + std::vector port_ids(channel_array.size()); + for (size_t i = 0; i < channel_array.size(); ++i) { + port_ids[i] = channel_array[i]->message_port_id(); + } + queued_messages.push_back(std::make_pair(message, port_ids)); message_queue_.pop(); } } diff --git a/chrome/common/webmessageportchannel_impl.h b/chrome/common/webmessageportchannel_impl.h index ee26e66..89a36b0 100644 --- a/chrome/common/webmessageportchannel_impl.h +++ b/chrome/common/webmessageportchannel_impl.h @@ -6,6 +6,7 @@ #define CHROME_COMMON_WEBMESSAGEPORTCHANNEL_IMPL_H_ #include +#include #include "base/basictypes.h" #include "base/lock.h" @@ -37,9 +38,9 @@ class WebMessagePortChannelImpl virtual void destroy(); virtual void entangle(WebKit::WebMessagePortChannel* channel); virtual void postMessage(const WebKit::WebString& message, - WebKit::WebMessagePortChannel* channel); + WebKit::WebMessagePortChannelArray* channels); virtual bool tryGetMessage(WebKit::WebString* message, - WebKit::WebMessagePortChannel** channel); + WebKit::WebMessagePortChannelArray& channels); void Init(); void Entangle(scoped_refptr channel); @@ -49,13 +50,13 @@ class WebMessagePortChannelImpl virtual void OnMessageReceived(const IPC::Message& message); void OnMessage(const string16& message, - int sent_message_port_id, - int new_routing_id); + const std::vector& sent_message_port_ids, + const std::vector& new_routing_ids); void OnMessagedQueued(); struct Message { string16 message; - scoped_refptr port; + std::vector ports; }; typedef std::queue MessageQueue; diff --git a/chrome/common/worker_messages.h b/chrome/common/worker_messages.h index b929d2c..4af15c4 100644 --- a/chrome/common/worker_messages.h +++ b/chrome/common/worker_messages.h @@ -9,12 +9,13 @@ #define CHROME_COMMON_WORKER_MESSAGES_H_ #include +#include #include "base/basictypes.h" #include "chrome/common/common_param_traits.h" #include "ipc/ipc_message_utils.h" -typedef std::pair QueuedMessage; +typedef std::pair > QueuedMessage; // Parameters structure for WorkerHostMsg_PostConsoleMessageToWorkerObject, // which has too many data parameters to be reasonably put in a predefined diff --git a/chrome/common/worker_messages_internal.h b/chrome/common/worker_messages_internal.h index 16dab5d..9b1cac2 100644 --- a/chrome/common/worker_messages_internal.h +++ b/chrome/common/worker_messages_internal.h @@ -3,6 +3,7 @@ // found in the LICENSE file. #include +#include #include "base/string16.h" #include "googleurl/src/gurl.h" #include "ipc/ipc_message_macros.h" @@ -21,8 +22,8 @@ IPC_BEGIN_MESSAGES(WorkerProcess) // like common_messages_internal.h IPC_MESSAGE_ROUTED3(WorkerProcessMsg_Message, string16 /* message */, - int /* sent_message_port_id */, - int /* new_routing_id */) + std::vector /* sent_message_port_ids */, + std::vector /* new_routing_ids */) // Tells the Message Port Channel object that there are no more in-flight // messages arriving. @@ -55,7 +56,7 @@ IPC_BEGIN_MESSAGES(WorkerProcessHost) IPC_MESSAGE_CONTROL3(WorkerProcessHostMsg_PostMessage, int /* sender_message_port_id */, string16 /* message */, - int /* sent_message_port_id */) + std::vector /* sent_message_port_ids */) // Causes messages sent to the remote port to be delivered to this local port. IPC_MESSAGE_CONTROL2(WorkerProcessHostMsg_Entangle, @@ -90,8 +91,8 @@ IPC_BEGIN_MESSAGES(Worker) IPC_MESSAGE_ROUTED3(WorkerMsg_PostMessage, string16 /* message */, - int /* sent_message_port_id */, - int /* new_routing_id */) + std::vector /* sent_message_port_ids */, + std::vector /* new_routing_ids */) IPC_MESSAGE_ROUTED0(WorkerMsg_WorkerObjectDestroyed) IPC_END_MESSAGES(Worker) diff --git a/chrome/renderer/webworker_proxy.cc b/chrome/renderer/webworker_proxy.cc index 5552546..b350470 100644 --- a/chrome/renderer/webworker_proxy.cc +++ b/chrome/renderer/webworker_proxy.cc @@ -12,6 +12,7 @@ #include "webkit/api/public/WebWorkerClient.h" using WebKit::WebMessagePortChannel; +using WebKit::WebMessagePortChannelArray; using WebKit::WebString; using WebKit::WebURL; using WebKit::WebWorkerClient; @@ -75,18 +76,20 @@ void WebWorkerProxy::terminateWorkerContext() { } void WebWorkerProxy::postMessageToWorkerContext( - const WebString& message, WebMessagePortChannel* channel) { - int message_port_id = MSG_ROUTING_NONE; - if (channel) { + const WebString& message, const WebMessagePortChannelArray& channels) { + std::vector message_port_ids(channels.size()); + std::vector routing_ids(channels.size()); + for (size_t i = 0; i < channels.size(); ++i) { WebMessagePortChannelImpl* webchannel = - static_cast(channel); - message_port_id = webchannel->message_port_id(); + static_cast(channels[i]); + message_port_ids[i] = webchannel->message_port_id(); webchannel->QueueMessages(); - DCHECK(message_port_id != MSG_ROUTING_NONE); + routing_ids[i] = MSG_ROUTING_NONE; + DCHECK(message_port_ids[i] != MSG_ROUTING_NONE); } Send(new WorkerMsg_PostMessage( - route_id_, message, message_port_id, MSG_ROUTING_NONE)); + route_id_, message, message_port_ids, routing_ids)); } void WebWorkerProxy::workerObjectDestroyed() { @@ -147,16 +150,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); +void WebWorkerProxy::OnPostMessage( + const string16& message, + const std::vector& sent_message_port_ids, + const std::vector& new_routing_ids) { + DCHECK(new_routing_ids.size() == sent_message_port_ids.size()); + WebMessagePortChannelArray channels(sent_message_port_ids.size()); + for (size_t i = 0; i < sent_message_port_ids.size(); ++i) { + channels[i] = new WebMessagePortChannelImpl( + new_routing_ids[i], sent_message_port_ids[i]); } - client_->postMessageToWorkerObject(message, channel); + client_->postMessageToWorkerObject(message, channels); } void WebWorkerProxy::OnPostConsoleMessageToWorkerObject( diff --git a/chrome/renderer/webworker_proxy.h b/chrome/renderer/webworker_proxy.h index 5eeb416..d47f3fb 100644 --- a/chrome/renderer/webworker_proxy.h +++ b/chrome/renderer/webworker_proxy.h @@ -36,7 +36,7 @@ class WebWorkerProxy : public WebKit::WebWorker, virtual void terminateWorkerContext(); virtual void postMessageToWorkerContext( const WebKit::WebString& message, - WebKit::WebMessagePortChannel* channel); + const WebKit::WebMessagePortChannelArray& channel_array); virtual void workerObjectDestroyed(); // IPC::Channel::Listener implementation. @@ -47,8 +47,8 @@ class WebWorkerProxy : public WebKit::WebWorker, void OnDedicatedWorkerCreated(); void OnPostMessage(const string16& message, - int sent_message_port_id, - int new_routing_id); + const std::vector& sent_message_port_ids, + const std::vector& new_routing_ids); void OnPostConsoleMessageToWorkerObject( const WorkerHostMsg_PostConsoleMessageToWorkerObject_Params& params); diff --git a/chrome/worker/nativewebworker_impl.cc b/chrome/worker/nativewebworker_impl.cc index 5fc3ddc..9dfd739 100644 --- a/chrome/worker/nativewebworker_impl.cc +++ b/chrome/worker/nativewebworker_impl.cc @@ -35,7 +35,8 @@ class PostMessageTask : public Task { } ~PostMessageTask() { } void Run() { - client_->postMessageToWorkerObject(message_string_, NULL); + WebKit::WebMessagePortChannelArray empty_array; + client_->postMessageToWorkerObject(message_string_, empty_array); } private: @@ -147,7 +148,8 @@ void NativeWebWorkerImpl::terminateWorkerContext() { } void NativeWebWorkerImpl::postMessageToWorkerContext( - const WebKit::WebString& message, WebKit::WebMessagePortChannel* channel) { + const WebKit::WebString& message, + const WebKit::WebMessagePortChannelArray& 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 7d0944c..29d85c9 100644 --- a/chrome/worker/nativewebworker_impl.h +++ b/chrome/worker/nativewebworker_impl.h @@ -27,8 +27,9 @@ class NativeWebWorkerImpl : public WebKit::WebWorker { const WebKit::WebString& user_agent, const WebKit::WebString& source_code); void terminateWorkerContext(); - void postMessageToWorkerContext(const WebKit::WebString& message, - WebKit::WebMessagePortChannel* channel); + void postMessageToWorkerContext( + const WebKit::WebString& message, + const WebKit::WebMessagePortChannelArray& channels); void workerObjectDestroyed(); private: diff --git a/chrome/worker/webworkerclient_proxy.cc b/chrome/worker/webworkerclient_proxy.cc index fdbaf9a..f0c6571 100644 --- a/chrome/worker/webworkerclient_proxy.cc +++ b/chrome/worker/webworkerclient_proxy.cc @@ -18,6 +18,7 @@ #include "webkit/api/public/WebWorker.h" using WebKit::WebMessagePortChannel; +using WebKit::WebMessagePortChannelArray; using WebKit::WebString; using WebKit::WebWorker; using WebKit::WebWorkerClient; @@ -81,18 +82,20 @@ WebWorkerClientProxy::~WebWorkerClientProxy() { void WebWorkerClientProxy::postMessageToWorkerObject( const WebString& message, - WebMessagePortChannel* channel) { - int message_port_id = MSG_ROUTING_NONE; - if (channel) { + const WebMessagePortChannelArray& channels) { + std::vector message_port_ids(channels.size()); + std::vector routing_ids(channels.size()); + for (size_t i = 0; i < channels.size(); ++i) { WebMessagePortChannelImpl* webchannel = - static_cast(channel); - message_port_id = webchannel->message_port_id(); + static_cast(channels[i]); + message_port_ids[i] = webchannel->message_port_id(); webchannel->QueueMessages(); - DCHECK(message_port_id != MSG_ROUTING_NONE); + DCHECK(message_port_ids[i] != MSG_ROUTING_NONE); + routing_ids[i] = MSG_ROUTING_NONE; } Send(new WorkerMsg_PostMessage( - route_id_, message, message_port_id, MSG_ROUTING_NONE)); + route_id_, message, message_port_ids, routing_ids)); } void WebWorkerClientProxy::postExceptionToWorkerObject( @@ -179,14 +182,15 @@ void WebWorkerClientProxy::OnTerminateWorkerContext() { 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); +void WebWorkerClientProxy::OnPostMessage( + const string16& message, + const std::vector& sent_message_port_ids, + const std::vector& new_routing_ids) { + WebMessagePortChannelArray channels(sent_message_port_ids.size()); + for (size_t i = 0; i < sent_message_port_ids.size(); i++) { + channels[i] = new WebMessagePortChannelImpl( + new_routing_ids[i], sent_message_port_ids[i]); } - impl_->postMessageToWorkerContext(message, channel); + impl_->postMessageToWorkerContext(message, channels); } diff --git a/chrome/worker/webworkerclient_proxy.h b/chrome/worker/webworkerclient_proxy.h index aadbe07..8807d63 100644 --- a/chrome/worker/webworkerclient_proxy.h +++ b/chrome/worker/webworkerclient_proxy.h @@ -5,6 +5,8 @@ #ifndef CHROME_WORKER_WEBWORKERCLIENT_PROXY_H_ #define CHROME_WORKER_WEBWORKERCLIENT_PROXY_H_ +#include + #include "base/basictypes.h" #include "googleurl/src/gurl.h" #include "ipc/ipc_channel.h" @@ -27,7 +29,7 @@ class WebWorkerClientProxy : public WebKit::WebWorkerClient, // WebWorkerClient implementation. virtual void postMessageToWorkerObject( const WebKit::WebString& message, - WebKit::WebMessagePortChannel* channel); + const WebKit::WebMessagePortChannelArray& channel); virtual void postExceptionToWorkerObject( const WebKit::WebString& error_message, int line_number, @@ -49,14 +51,14 @@ class WebWorkerClientProxy : public WebKit::WebWorkerClient, virtual void OnMessageReceived(const IPC::Message& message); private: - ~WebWorkerClientProxy (); + ~WebWorkerClientProxy(); bool Send(IPC::Message* message); void OnTerminateWorkerContext(); void OnPostMessage(const string16& message, - int sent_message_port_id, - int new_routing_id); + const std::vector& sent_message_port_ids, + const std::vector& new_routing_ids); // The source url for this worker. GURL url_; diff --git a/webkit/api/public/WebMessagePortChannel.h b/webkit/api/public/WebMessagePortChannel.h index ef20df4..20c0a33 100644 --- a/webkit/api/public/WebMessagePortChannel.h +++ b/webkit/api/public/WebMessagePortChannel.h @@ -32,11 +32,14 @@ #define WebMessagePortChannel_h #include "WebCommon.h" +#include "WebVector.h" namespace WebKit { class WebMessagePortChannelClient; class WebString; + typedef WebVector WebMessagePortChannelArray; + // Provides an interface to a Message Port Channel implementation. The object owns itself and // is signalled that its not needed anymore with the destroy() call. class WebMessagePortChannel { @@ -45,9 +48,9 @@ namespace WebKit { virtual void destroy() = 0; // WebKit versions of WebCore::MessagePortChannel. virtual void entangle(WebMessagePortChannel*) = 0; - // If sending a message port, callee receives ownership of the object. - virtual void postMessage(const WebString&, WebMessagePortChannel*) = 0; - virtual bool tryGetMessage(WebString*, WebMessagePortChannel**) = 0; + // Callee receives ownership of the passed vector. + virtual void postMessage(const WebString&, WebMessagePortChannelArray*) = 0; + virtual bool tryGetMessage(WebString*, WebMessagePortChannelArray&) = 0; protected: ~WebMessagePortChannel() { } diff --git a/webkit/api/public/WebVector.h b/webkit/api/public/WebVector.h index af811d6..4919c85 100644 --- a/webkit/api/public/WebVector.h +++ b/webkit/api/public/WebVector.h @@ -31,7 +31,7 @@ #ifndef WebVector_h #define WebVector_h -#include +#include #include "WebCommon.h" diff --git a/webkit/api/public/WebWorker.h b/webkit/api/public/WebWorker.h index 480b34a..1424161 100644 --- a/webkit/api/public/WebWorker.h +++ b/webkit/api/public/WebWorker.h @@ -31,10 +31,9 @@ #ifndef WebWorker_h #define WebWorker_h -#include "WebCommon.h" +#include "WebMessagePortChannel.h" namespace WebKit { - class WebMessagePortChannel; class WebString; class WebURL; class WebWorkerClient; @@ -50,8 +49,9 @@ namespace WebKit { const WebString& userAgent, const WebString& sourceCode) = 0; virtual void terminateWorkerContext() = 0; - virtual void postMessageToWorkerContext(const WebString&, - WebMessagePortChannel*) = 0; + virtual void postMessageToWorkerContext( + const WebString&, + const WebMessagePortChannelArray&) = 0; virtual void workerObjectDestroyed() = 0; }; diff --git a/webkit/api/public/WebWorkerClient.h b/webkit/api/public/WebWorkerClient.h index 3e89ed7..b9d8cef 100644 --- a/webkit/api/public/WebWorkerClient.h +++ b/webkit/api/public/WebWorkerClient.h @@ -31,10 +31,9 @@ #ifndef WebWorkerClient_h #define WebWorkerClient_h -#include "WebCommon.h" +#include "WebMessagePortChannel.h" namespace WebKit { - class WebMessagePortChannel; class WebString; class WebWorker; @@ -43,8 +42,9 @@ namespace WebKit { // the Worker object, unless noted. class WebWorkerClient { public: - virtual void postMessageToWorkerObject(const WebString&, - WebMessagePortChannel*) = 0; + virtual void postMessageToWorkerObject( + const WebString&, + const WebMessagePortChannelArray&) = 0; virtual void postExceptionToWorkerObject( const WebString& errorString, int lineNumber, diff --git a/webkit/api/src/PlatformMessagePortChannel.cpp b/webkit/api/src/PlatformMessagePortChannel.cpp index cafbdea..ee67806 100644 --- a/webkit/api/src/PlatformMessagePortChannel.cpp +++ b/webkit/api/src/PlatformMessagePortChannel.cpp @@ -179,14 +179,17 @@ void PlatformMessagePortChannel::postMessageToRemote(PassOwnPtrmessage(); - OwnPtr channel = message->channel(); - WebMessagePortChannel* webChannel = NULL; - if (channel.get()) { - WebCore::PlatformMessagePortChannel* platformChannel = channel->channel(); - webChannel = platformChannel->webChannelRelease(); - webChannel->setClient(0); + OwnPtr channels = message->channels(); + WebMessagePortChannelArray* webChannels = NULL; + if (channels.get() && channels->size()) { + webChannels = new WebMessagePortChannelArray(channels->size()); + for (size_t i = 0; i < channels->size(); ++i) { + WebCore::PlatformMessagePortChannel* platformChannel = (*channels)[i]->channel(); + (*webChannels)[i] = platformChannel->webChannelRelease(); + (*webChannels)[i]->setClient(0); + } } - m_webChannel->postMessage(messageString, webChannel); + m_webChannel->postMessage(messageString, webChannels); } bool PlatformMessagePortChannel::tryGetMessageFromRemote(OwnPtr& result) @@ -195,16 +198,19 @@ bool PlatformMessagePortChannel::tryGetMessageFromRemote(OwnPtrtryGetMessage(&message, &webChannel); + WebMessagePortChannelArray webChannels; + bool rv = m_webChannel->tryGetMessage(&message, webChannels); if (rv) { - OwnPtr channel; - if (webChannel) { - RefPtr platformChannel = create(webChannel); - webChannel->setClient(platformChannel.get()); - channel = MessagePortChannel::create(platformChannel); + OwnPtr channels; + if (webChannels.size()) { + channels = new MessagePortChannelArray(webChannels.size()); + for (size_t i = 0; i < webChannels.size(); ++i) { + RefPtr platformChannel = create(webChannels[i]); + webChannels[i]->setClient(platformChannel.get()); + (*channels)[i] = MessagePortChannel::create(platformChannel); + } } - result = MessagePortChannel::EventData::create(message, channel.release()); + result = MessagePortChannel::EventData::create(message, channels.release()); } return rv; diff --git a/webkit/glue/webworker_impl.cc b/webkit/glue/webworker_impl.cc index 3b33614..76f4400 100644 --- a/webkit/glue/webworker_impl.cc +++ b/webkit/glue/webworker_impl.cc @@ -38,6 +38,7 @@ using WebKit::WebCursorInfo; using WebKit::WebFrame; using WebKit::WebMessagePortChannel; +using WebKit::WebMessagePortChannelArray; using WebKit::WebNavigationPolicy; using WebKit::WebRect; using WebKit::WebScreenInfo; @@ -124,17 +125,14 @@ void WebWorkerImpl::PostMessageToWorkerContextTask( WebCore::ScriptExecutionContext* context, WebWorkerImpl* this_ptr, const WebCore::String& message, - WTF::PassOwnPtr channel) { + WTF::PassOwnPtr channels) { DCHECK(context->isWorkerContext()); WebCore::DedicatedWorkerContext* worker_context = static_cast(context); - WTF::RefPtr port; - if (channel) { - port = WebCore::MessagePort::create(*context); - port->entangle(channel.release()); - } - worker_context->dispatchMessage(message, port.release()); + WTF::OwnPtr ports = + WebCore::MessagePort::entanglePorts(*context, channels.release()); + worker_context->dispatchMessage(message, ports.release()); this_ptr->confirmMessageFromWorkerObject( worker_context->hasPendingActivity()); @@ -197,21 +195,24 @@ void WebWorkerImpl::terminateWorkerContext() { void WebWorkerImpl::postMessageToWorkerContext( const WebString& message, - WebMessagePortChannel* webchannel) { - - OwnPtr channel; - if (webchannel) { - RefPtr platform_channel = - WebCore::PlatformMessagePortChannel::create(webchannel); - webchannel->setClient(platform_channel.get()); - channel = WebCore::MessagePortChannel::create(platform_channel); + const WebMessagePortChannelArray& webchannels) { + + WTF::OwnPtr channels; + if (webchannels.size()) { + channels = new WebCore::MessagePortChannelArray(webchannels.size()); + for (size_t i = 0; i < webchannels.size(); ++i) { + RefPtr platform_channel = + WebCore::PlatformMessagePortChannel::create(webchannels[i]); + webchannels[i]->setClient(platform_channel.get()); + (*channels)[i] = WebCore::MessagePortChannel::create(platform_channel); + } } worker_thread_->runLoop().postTask(WebCore::createCallbackTask( &PostMessageToWorkerContextTask, this, webkit_glue::WebStringToString(message), - channel.release())); + channels.release())); } void WebWorkerImpl::workerObjectDestroyed() { @@ -238,27 +239,28 @@ void WebWorkerImpl::InvokeTaskMethod(void* param) { void WebWorkerImpl::postMessageToWorkerObject( const WebCore::String& message, - WTF::PassOwnPtr channel) { + WTF::PassOwnPtr channels) { DispatchTaskToMainThread(WebCore::createCallbackTask( &PostMessageTask, this, message, - channel)); + channels)); } void WebWorkerImpl::PostMessageTask( WebCore::ScriptExecutionContext* context, WebWorkerImpl* this_ptr, WebCore::String message, - WTF::PassOwnPtr channel) { - WebMessagePortChannel* webChannel = NULL; - if (channel.get()) { - webChannel = channel->channel()->webChannelRelease(); - webChannel->setClient(0); + WTF::PassOwnPtr channels) { + WebMessagePortChannelArray web_channels( + channels.get() ? channels->size() : 0); + for (size_t i = 0; i < web_channels.size(); ++i) { + web_channels[i] = (*channels)[i]->channel()->webChannelRelease(); + web_channels[i]->setClient(0); } this_ptr->client_->postMessageToWorkerObject( - webkit_glue::StringToWebString(message), webChannel); + webkit_glue::StringToWebString(message), web_channels); } void WebWorkerImpl::postExceptionToWorkerObject( diff --git a/webkit/glue/webworker_impl.h b/webkit/glue/webworker_impl.h index 9495ded..321334f 100644 --- a/webkit/glue/webworker_impl.h +++ b/webkit/glue/webworker_impl.h @@ -16,8 +16,6 @@ #include namespace WebCore { -class Strng; -class MessagePortChannel; class WorkerThread; }; @@ -37,7 +35,7 @@ class WebWorkerImpl: public WebCore::WorkerObjectProxy, // WebCore::WorkerObjectProxy methods: virtual void postMessageToWorkerObject( const WebCore::String& message, - WTF::PassOwnPtr channel); + WTF::PassOwnPtr channels); virtual void postExceptionToWorkerObject( const WebCore::String& error_message, int line_number, @@ -68,7 +66,7 @@ class WebWorkerImpl: public WebCore::WorkerObjectProxy, virtual void terminateWorkerContext(); virtual void postMessageToWorkerContext( const WebKit::WebString& message, - WebKit::WebMessagePortChannel* channel); + const WebKit::WebMessagePortChannelArray& channel); virtual void workerObjectDestroyed(); WebKit::WebWorkerClient* client() { return client_; } @@ -85,7 +83,7 @@ class WebWorkerImpl: public WebCore::WorkerObjectProxy, WebCore::ScriptExecutionContext* context, WebWorkerImpl* this_ptr, const WebCore::String& message, - WTF::PassOwnPtr channel); + WTF::PassOwnPtr channels); // Function used to invoke tasks on the main thread. static void InvokeTaskMethod(void* param); @@ -95,7 +93,7 @@ class WebWorkerImpl: public WebCore::WorkerObjectProxy, WebCore::ScriptExecutionContext* context, WebWorkerImpl* this_ptr, WebCore::String message, - WTF::PassOwnPtr channel); + WTF::PassOwnPtr channels); static void PostExceptionTask( WebCore::ScriptExecutionContext* context, WebWorkerImpl* this_ptr, diff --git a/webkit/glue/webworkerclient_impl.cc b/webkit/glue/webworkerclient_impl.cc index db754aa..0139509 100644 --- a/webkit/glue/webworkerclient_impl.cc +++ b/webkit/glue/webworkerclient_impl.cc @@ -41,6 +41,7 @@ #include "webkit/glue/webworker_impl.h" using WebKit::WebMessagePortChannel; +using WebKit::WebMessagePortChannelArray; using WebKit::WebString; using WebKit::WebWorker; using WebKit::WebWorkerClient; @@ -154,7 +155,7 @@ void WebWorkerClientImpl::terminateWorkerContext() { void WebWorkerClientImpl::postMessageToWorkerContext( const WebCore::String& message, - WTF::PassOwnPtr channel) { + WTF::PassOwnPtr channels) { // Worker.terminate() could be called from JS before the context is started. if (asked_to_terminate_) return; @@ -164,18 +165,21 @@ void WebWorkerClientImpl::postMessageToWorkerContext( if (!WTF::isMainThread()) { WebWorkerImpl::DispatchTaskToMainThread( WebCore::createCallbackTask( - &PostMessageToWorkerContextTask, this, message, channel)); + &PostMessageToWorkerContextTask, this, message, channels)); return; } - WebMessagePortChannel* webchannel = NULL; - if (channel.get()) { - webchannel = channel->channel()->webChannelRelease(); + WebMessagePortChannelArray webchannels(channels.get() ? channels->size() : 0); + + for (size_t i = 0; i < webchannels.size(); ++i) { + WebMessagePortChannel* webchannel = + (*channels)[i]->channel()->webChannelRelease(); webchannel->setClient(0); + webchannels[i] = webchannel; } webworker_->postMessageToWorkerContext( - webkit_glue::StringToWebString(message), webchannel); + webkit_glue::StringToWebString(message), webchannels); } bool WebWorkerClientImpl::hasPendingActivity() const { @@ -197,25 +201,28 @@ void WebWorkerClientImpl::workerObjectDestroyed() { void WebWorkerClientImpl::postMessageToWorkerObject( const WebString& message, - WebMessagePortChannel* channel) { + const WebMessagePortChannelArray& channels) { WebCore::String message2 = webkit_glue::WebStringToString(message); - OwnPtr channel2; - if (channel) { - RefPtr platform_channel = - WebCore::PlatformMessagePortChannel::create(channel); - channel->setClient(platform_channel.get()); - channel2 = WebCore::MessagePortChannel::create(platform_channel); + OwnPtr channels2; + if (channels.size()) { + channels2 = new WebCore::MessagePortChannelArray(channels.size()); + for (size_t i = 0; i < channels.size(); ++i) { + RefPtr platform_channel = + WebCore::PlatformMessagePortChannel::create(channels[i]); + channels[i]->setClient(platform_channel.get()); + (*channels2)[i] = WebCore::MessagePortChannel::create(platform_channel); + } } if (WTF::currentThread() != worker_thread_id_) { script_execution_context_->postTask( WebCore::createCallbackTask(&PostMessageToWorkerObjectTask, this, - message2, channel2.release())); + message2, channels2.release())); return; } PostMessageToWorkerObjectTask( - script_execution_context_.get(), this, message2, channel2.release()); + script_execution_context_.get(), this, message2, channels2.release()); } void WebWorkerClientImpl::postExceptionToWorkerObject( @@ -313,15 +320,16 @@ void WebWorkerClientImpl::PostMessageToWorkerContextTask( WebCore::ScriptExecutionContext* context, WebWorkerClientImpl* this_ptr, const WebCore::String& message, - WTF::PassOwnPtr channel) { - WebMessagePortChannel* webChannel = NULL; - if (channel.get()) { - webChannel = channel->channel()->webChannelRelease(); - webChannel->setClient(0); + WTF::PassOwnPtr channels) { + WebMessagePortChannelArray web_channels(channels.get() ? channels->size() : 0); + + for (size_t i = 0; i < web_channels.size(); ++i) { + web_channels[i] = (*channels)[i]->channel()->webChannelRelease(); + web_channels[i]->setClient(0); } this_ptr->webworker_->postMessageToWorkerContext( - webkit_glue::StringToWebString(message), webChannel); + webkit_glue::StringToWebString(message), web_channels); } void WebWorkerClientImpl::WorkerObjectDestroyedTask( @@ -336,16 +344,12 @@ void WebWorkerClientImpl::PostMessageToWorkerObjectTask( WebCore::ScriptExecutionContext* context, WebWorkerClientImpl* this_ptr, const WebCore::String& message, - WTF::PassOwnPtr channel) { + WTF::PassOwnPtr channels) { if (this_ptr->worker_) { - WTF::RefPtr port; - if (channel) { - port = WebCore::MessagePort::create(*context); - port->entangle(channel.release()); - } - - this_ptr->worker_->dispatchMessage(message, port.release()); + WTF::OwnPtr ports = + WebCore::MessagePort::entanglePorts(*context, channels.release()); + this_ptr->worker_->dispatchMessage(message, ports.release()); } } diff --git a/webkit/glue/webworkerclient_impl.h b/webkit/glue/webworkerclient_impl.h index 420106b..b9110ef 100644 --- a/webkit/glue/webworkerclient_impl.h +++ b/webkit/glue/webworkerclient_impl.h @@ -14,7 +14,6 @@ #include namespace WebCore { -class MessagePortChannel; class ScriptExecutionContext; } namespace WebKit { @@ -42,7 +41,7 @@ class WebWorkerClientImpl : public WebCore::WorkerContextProxy, virtual void terminateWorkerContext(); virtual void postMessageToWorkerContext( const WebCore::String& message, - WTF::PassOwnPtr channel); + WTF::PassOwnPtr channels); virtual bool hasPendingActivity() const; virtual void workerObjectDestroyed(); @@ -50,7 +49,7 @@ class WebWorkerClientImpl : public WebCore::WorkerContextProxy, // These are called on the main WebKit thread. virtual void postMessageToWorkerObject( const WebKit::WebString& message, - WebKit::WebMessagePortChannel* channel); + const WebKit::WebMessagePortChannelArray& channels); virtual void postExceptionToWorkerObject( const WebKit::WebString& error_message, int line_number, @@ -89,7 +88,7 @@ class WebWorkerClientImpl : public WebCore::WorkerContextProxy, WebCore::ScriptExecutionContext* context, WebWorkerClientImpl* this_ptr, const WebCore::String& message, - WTF::PassOwnPtr channel); + WTF::PassOwnPtr channels); static void WorkerObjectDestroyedTask( WebCore::ScriptExecutionContext* context, WebWorkerClientImpl* this_ptr); @@ -101,7 +100,7 @@ class WebWorkerClientImpl : public WebCore::WorkerContextProxy, WebCore::ScriptExecutionContext* context, WebWorkerClientImpl* this_ptr, const WebCore::String& message, - WTF::PassOwnPtr channel); + WTF::PassOwnPtr channels); static void PostExceptionToWorkerObjectTask( WebCore::ScriptExecutionContext* context, WebWorkerClientImpl* this_ptr, diff --git a/webkit/tools/test_shell/test_worker/test_webworker.cc b/webkit/tools/test_shell/test_worker/test_webworker.cc index 6fdce06..7becc88 100644 --- a/webkit/tools/test_shell/test_worker/test_webworker.cc +++ b/webkit/tools/test_shell/test_worker/test_webworker.cc @@ -40,8 +40,9 @@ void TestWebWorker::startWorkerContext(const WebURL& script_url, webworker_impl_->startWorkerContext(script_url, user_agent, source_code); + WebKit::WebMessagePortChannelArray emptyArray; for (size_t i = 0; i < queued_messages_.size(); ++i) - webworker_impl_->postMessageToWorkerContext(queued_messages_[i], NULL); + webworker_impl_->postMessageToWorkerContext(queued_messages_[i], emptyArray); queued_messages_.clear(); } @@ -50,10 +51,11 @@ void TestWebWorker::terminateWorkerContext() { webworker_impl_->terminateWorkerContext(); } -void TestWebWorker::postMessageToWorkerContext(const WebString& message, - WebKit::WebMessagePortChannel*) { +void TestWebWorker::postMessageToWorkerContext( + const WebString& message, + const WebKit::WebMessagePortChannelArray& channels) { if (webworker_impl_) - webworker_impl_->postMessageToWorkerContext(message, NULL); + webworker_impl_->postMessageToWorkerContext(message, channels); else queued_messages_.push_back(message); } @@ -66,15 +68,16 @@ void TestWebWorker::workerObjectDestroyed() { Release(); // Releases the reference held for worker object. } -void TestWebWorker::postMessageToWorkerObject(const WebString& message, - WebKit::WebMessagePortChannel*) { +void TestWebWorker::postMessageToWorkerObject( + const WebString& message, + const WebKit::WebMessagePortChannelArray& channels) { 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), NULL); + webworker_helper_->DuplicateString(message), channels); } 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 22ffecd..3e987c0 100644 --- a/webkit/tools/test_shell/test_worker/test_webworker.h +++ b/webkit/tools/test_shell/test_worker/test_webworker.h @@ -31,13 +31,13 @@ class TestWebWorker : public WebKit::WebWorker, virtual void terminateWorkerContext(); virtual void postMessageToWorkerContext( const WebKit::WebString& message, - WebKit::WebMessagePortChannel* channel); + const WebKit::WebMessagePortChannelArray& channel); virtual void workerObjectDestroyed(); // WebWorkerClient methods: virtual void postMessageToWorkerObject( const WebKit::WebString& message, - WebKit::WebMessagePortChannel* channel); + const WebKit::WebMessagePortChannelArray& channel); virtual void postExceptionToWorkerObject( const WebKit::WebString& error_message, int line_number, -- cgit v1.1