| 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]);
|
| + }
|
| +}
|
|
|