Index: chrome/renderer/webworker_base.cc |
diff --git a/chrome/renderer/webworker_base.cc b/chrome/renderer/webworker_base.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..98365cd649cbf21263d3c03cfa6fdb8fb34b5d2d |
--- /dev/null |
+++ b/chrome/renderer/webworker_base.cc |
@@ -0,0 +1,102 @@ |
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/renderer/webworker_base.h" |
+ |
+#include "chrome/common/child_thread.h" |
+#include "chrome/common/render_messages.h" |
+#include "chrome/common/webmessageportchannel_impl.h" |
+#include "chrome/common/worker_messages.h" |
+#include "webkit/api/public/WebURL.h" |
+#include "webkit/api/public/WebWorkerClient.h" |
+ |
+using WebKit::WebMessagePortChannel; |
+using WebKit::WebMessagePortChannelArray; |
+using WebKit::WebString; |
+using WebKit::WebURL; |
+using WebKit::WebWorkerClient; |
+ |
+WebWorkerBase::WebWorkerBase( |
+ ChildThread* child_thread, |
+ int route_id, |
+ int render_view_route_id) |
+ : route_id_(route_id), |
+ render_view_route_id_(render_view_route_id), |
+ child_thread_(child_thread) { |
+ if (route_id_ != MSG_ROUTING_NONE) |
+ child_thread_->AddRoute(route_id_, this); |
+} |
+ |
+WebWorkerBase::~WebWorkerBase() { |
+ Disconnect(); |
+ |
+ // Free up any unsent queued messages. |
+ for (size_t i = 0; i < queued_messages_.size(); ++i) |
+ delete queued_messages_[i]; |
+} |
+ |
+void WebWorkerBase::Disconnect() { |
+ if (route_id_ == MSG_ROUTING_NONE) |
+ return; |
+ |
+ // So the messages from WorkerContext (like WorkerContextDestroyed) do not |
+ // come after nobody is listening. Since Worker and WorkerContext can |
+ // terminate independently, already sent messages may still be in the pipe. |
+ child_thread_->RemoveRoute(route_id_); |
+ |
+ route_id_ = MSG_ROUTING_NONE; |
+} |
+ |
+void WebWorkerBase::CreateWorkerContext(IPC::Message* create_message, |
+ const GURL& script_url, |
+ const string16& user_agent, |
+ const string16& source_code) { |
+ DCHECK(route_id_ == MSG_ROUTING_NONE); |
+ // create_message is a sync message that sets route_id_ |
+ child_thread_->Send(create_message); |
+ if (route_id_ == MSG_ROUTING_NONE) |
+ return; |
+ |
+ child_thread_->AddRoute(route_id_, this); |
+ |
+ // We make sure that the start message is the first, since postMessage or |
+ // connect might have already been called. |
+ queued_messages_.insert(queued_messages_.begin(), |
+ new WorkerMsg_StartWorkerContext( |
+ route_id_, script_url, user_agent, source_code)); |
+} |
+ |
+bool WebWorkerBase::IsStarted() { |
+ // Worker is started if we have a route ID and there are no queued messages |
+ // (meaning we've sent the WorkerMsg_StartWorkerContext already). |
+ return (route_id_ != MSG_ROUTING_NONE && queued_messages_.empty()); |
+} |
+ |
+bool WebWorkerBase::Send(IPC::Message* message) { |
+ // It's possible that messages will be sent before the worker is created, in |
+ // which case route_id_ will be none. Or the worker object can be interacted |
+ // with before the browser process told us that it started, in which case we |
+ // also want to queue the message. |
+ if (!IsStarted()) { |
+ queued_messages_.push_back(message); |
+ return true; |
+ } |
+ |
+ // For now we proxy all messages to the worker process through the browser. |
+ // Revisit if we find this slow. |
+ // TODO(jabdelmalek): handle sync messages if we need them. |
+ IPC::Message* wrapped_msg = new ViewHostMsg_ForwardToWorker(*message); |
+ delete message; |
+ return child_thread_->Send(wrapped_msg); |
+} |
+ |
+void WebWorkerBase::SendQueuedMessages() { |
+ DCHECK(queued_messages_.size()); |
+ std::vector<IPC::Message*> queued_messages = queued_messages_; |
+ queued_messages_.clear(); |
+ for (size_t i = 0; i < queued_messages.size(); ++i) { |
+ queued_messages[i]->set_routing_id(route_id_); |
+ Send(queued_messages[i]); |
+ } |
+} |