summaryrefslogtreecommitdiffstats
path: root/chrome/browser/worker_host/message_port_dispatcher.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/worker_host/message_port_dispatcher.cc')
-rw-r--r--chrome/browser/worker_host/message_port_dispatcher.cc292
1 files changed, 0 insertions, 292 deletions
diff --git a/chrome/browser/worker_host/message_port_dispatcher.cc b/chrome/browser/worker_host/message_port_dispatcher.cc
deleted file mode 100644
index 3fedd67..0000000
--- a/chrome/browser/worker_host/message_port_dispatcher.cc
+++ /dev/null
@@ -1,292 +0,0 @@
-// 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/browser/worker_host/message_port_dispatcher.h"
-
-#include "base/callback.h"
-#include "base/singleton.h"
-#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/renderer_host/resource_message_filter.h"
-#include "chrome/browser/worker_host/worker_process_host.h"
-#include "chrome/common/notification_service.h"
-#include "chrome/common/worker_messages.h"
-
-struct MessagePortDispatcher::MessagePort {
- // sender and route_id are what we need to send messages to the port.
- IPC::Message::Sender* sender;
- int route_id;
- // A function pointer to generate a new route id for the sender above.
- // Owned by "sender" above, so don't delete.
- CallbackWithReturnValue<int>::Type* next_routing_id;
- // A globally unique id for this message port.
- int message_port_id;
- // The globally unique id of the entangled message port.
- int entangled_message_port_id;
- // If true, all messages to this message port are queued and not delivered.
- bool queue_messages;
- QueuedMessages queued_messages;
-};
-
-MessagePortDispatcher* MessagePortDispatcher::GetInstance() {
- return Singleton<MessagePortDispatcher>::get();
-}
-
-MessagePortDispatcher::MessagePortDispatcher()
- : next_message_port_id_(0),
- sender_(NULL),
- next_routing_id_(NULL) {
- // Receive a notification if a message filter or WorkerProcessHost is deleted.
- registrar_.Add(this, NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN,
- NotificationService::AllSources());
-
- registrar_.Add(this, NotificationType::WORKER_PROCESS_HOST_SHUTDOWN,
- NotificationService::AllSources());
-}
-
-MessagePortDispatcher::~MessagePortDispatcher() {
-}
-
-bool MessagePortDispatcher::OnMessageReceived(
- const IPC::Message& message,
- IPC::Message::Sender* sender,
- CallbackWithReturnValue<int>::Type* next_routing_id,
- bool* message_was_ok) {
- sender_ = sender;
- next_routing_id_ = next_routing_id;
-
- bool handled = true;
- *message_was_ok = true;
-
- IPC_BEGIN_MESSAGE_MAP_EX(MessagePortDispatcher, message, *message_was_ok)
- IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_CreateMessagePort, OnCreate)
- IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_DestroyMessagePort, OnDestroy)
- IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_Entangle, OnEntangle)
- IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_PostMessage, OnPostMessage)
- IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_QueueMessages, OnQueueMessages)
- IPC_MESSAGE_HANDLER(WorkerProcessHostMsg_SendQueuedMessages,
- OnSendQueuedMessages)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP_EX()
-
- sender_ = NULL;
- next_routing_id_ = NULL;
-
- 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);
-}
-
-void MessagePortDispatcher::OnCreate(int *route_id,
- int* message_port_id) {
- *message_port_id = ++next_message_port_id_;
- *route_id = next_routing_id_->Run();
-
- MessagePort port;
- port.sender = sender_;
- port.route_id = *route_id;
- port.next_routing_id = next_routing_id_;
- port.message_port_id = *message_port_id;
- port.entangled_message_port_id = MSG_ROUTING_NONE;
- port.queue_messages = false;
- message_ports_[*message_port_id] = port;
-}
-
-void MessagePortDispatcher::OnDestroy(int message_port_id) {
- if (!message_ports_.count(message_port_id)) {
- NOTREACHED();
- return;
- }
-
- DCHECK(message_ports_[message_port_id].queued_messages.empty());
- Erase(message_port_id);
-}
-
-void MessagePortDispatcher::OnEntangle(int local_message_port_id,
- int remote_message_port_id) {
- if (!message_ports_.count(local_message_port_id) ||
- !message_ports_.count(remote_message_port_id)) {
- NOTREACHED();
- return;
- }
-
- DCHECK(message_ports_[remote_message_port_id].entangled_message_port_id ==
- MSG_ROUTING_NONE);
- message_ports_[remote_message_port_id].entangled_message_port_id =
- local_message_port_id;
-}
-
-void MessagePortDispatcher::OnPostMessage(
- int sender_message_port_id,
- const string16& message,
- const std::vector<int>& sent_message_port_ids) {
- if (!message_ports_.count(sender_message_port_id)) {
- NOTREACHED();
- return;
- }
-
- int entangled_message_port_id =
- message_ports_[sender_message_port_id].entangled_message_port_id;
- if (entangled_message_port_id == MSG_ROUTING_NONE)
- return; // Process could have crashed.
-
- if (!message_ports_.count(entangled_message_port_id)) {
- NOTREACHED();
- return;
- }
-
- PostMessageTo(entangled_message_port_id, message, sent_message_port_ids);
-}
-
-void MessagePortDispatcher::PostMessageTo(
- int message_port_id,
- const string16& message,
- const std::vector<int>& 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];
-
- std::vector<MessagePort*> 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_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.
- std::vector<int> 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_ports[i]->route_id = new_routing_ids[i];
- }
-
- if (entangled_port.sender) {
- // Now send the message to the entangled port.
- IPC::Message* ipc_msg = new WorkerProcessMsg_Message(
- entangled_port.route_id, message, sent_message_port_ids,
- new_routing_ids);
- entangled_port.sender->Send(ipc_msg);
- }
- }
-}
-
-void MessagePortDispatcher::OnQueueMessages(int message_port_id) {
- if (!message_ports_.count(message_port_id)) {
- NOTREACHED();
- return;
- }
-
- MessagePort& port = message_ports_[message_port_id];
- if (port.sender) {
- port.sender->Send(new WorkerProcessMsg_MessagesQueued(port.route_id));
- port.queue_messages = true;
- port.sender = NULL;
- }
-}
-
-void MessagePortDispatcher::OnSendQueuedMessages(
- int message_port_id,
- const QueuedMessages& queued_messages) {
- if (!message_ports_.count(message_port_id)) {
- NOTREACHED();
- return;
- }
-
- // Send the queued messages to the port again. This time they'll reach the
- // new location.
- MessagePort& port = message_ports_[message_port_id];
- port.queue_messages = false;
- port.queued_messages.insert(port.queued_messages.begin(),
- queued_messages.begin(),
- queued_messages.end());
- SendQueuedMessagesIfPossible(message_port_id);
-}
-
-void MessagePortDispatcher::SendQueuedMessagesIfPossible(int message_port_id) {
- if (!message_ports_.count(message_port_id)) {
- NOTREACHED();
- return;
- }
-
- MessagePort& port = message_ports_[message_port_id];
- if (port.queue_messages || !port.sender)
- return;
-
- for (QueuedMessages::iterator iter = port.queued_messages.begin();
- iter != port.queued_messages.end(); ++iter) {
- PostMessageTo(message_port_id, iter->first, iter->second);
- }
- port.queued_messages.clear();
-}
-
-void MessagePortDispatcher::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- IPC::Message::Sender* sender = NULL;
- if (type.value == NotificationType::RESOURCE_MESSAGE_FILTER_SHUTDOWN) {
- sender = Source<ResourceMessageFilter>(source).ptr();
- } else if (type.value == NotificationType::WORKER_PROCESS_HOST_SHUTDOWN) {
- sender = Source<WorkerProcessHost>(source).ptr();
- } else {
- NOTREACHED();
- }
-
- // Check if the (possibly) crashed process had any message ports.
- for (MessagePorts::iterator iter = message_ports_.begin();
- iter != message_ports_.end();) {
- MessagePorts::iterator cur_item = iter++;
- if (cur_item->second.sender == sender) {
- Erase(cur_item->first);
- }
- }
-}
-
-void MessagePortDispatcher::Erase(int message_port_id) {
- MessagePorts::iterator erase_item = message_ports_.find(message_port_id);
- DCHECK(erase_item != message_ports_.end());
-
- int entangled_id = erase_item->second.entangled_message_port_id;
- if (entangled_id != MSG_ROUTING_NONE) {
- // Do the disentanglement (and be paranoid about the other side existing
- // just in case something unusual happened during entanglement).
- if (message_ports_.count(entangled_id)) {
- message_ports_[entangled_id].entangled_message_port_id = MSG_ROUTING_NONE;
- }
- }
- message_ports_.erase(erase_item);
-}