embedded_worker_registry.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
14fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor// Copyright 2013 The Chromium Authors. All rights reserved.
24fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor// Use of this source code is governed by a BSD-style license that can be
34fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor// found in the LICENSE file.
44fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor
54fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor#include "content/browser/service_worker/embedded_worker_registry.h"
64fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor
74fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor#include "base/stl_util.h"
84fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor#include "content/browser/service_worker/embedded_worker_instance.h"
94fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor#include "content/browser/service_worker/service_worker_context_core.h"
104fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor#include "content/common/service_worker/embedded_worker_messages.h"
114fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor#include "content/common/service_worker/service_worker_messages.h"
124fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor#include "ipc/ipc_message.h"
134fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor#include "ipc/ipc_sender.h"
144fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor
154fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregornamespace content {
164fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor
174fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas GregorEmbeddedWorkerRegistry::EmbeddedWorkerRegistry(
184fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    base::WeakPtr<ServiceWorkerContextCore> context)
194fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    : context_(context),
209db7dbb918ca49f4ee6c181e4917e7b6ec547353Douglas Gregor      next_embedded_worker_id_(0) {}
214fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor
2215de72cf580840c61e5704c2f8a2b56f9d0638e1Douglas Gregorscoped_ptr<EmbeddedWorkerInstance> EmbeddedWorkerRegistry::CreateWorker() {
234fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  scoped_ptr<EmbeddedWorkerInstance> worker(
244fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor      new EmbeddedWorkerInstance(this, next_embedded_worker_id_));
254fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  worker_map_[next_embedded_worker_id_++] = worker.get();
264fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  return worker.Pass();
27770b4a8834670e9427d3ce5a1a8472eb86f45fd2Benjamin Kramer}
285f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner
294fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas GregorServiceWorkerStatusCode EmbeddedWorkerRegistry::StartWorker(
304fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    int process_id,
314fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    int embedded_worker_id,
325cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu    int64 service_worker_version_id,
334fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    const GURL& script_url) {
345f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  return Send(process_id,
355f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner              new EmbeddedWorkerMsg_StartWorker(embedded_worker_id,
365f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner                                               service_worker_version_id,
374fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor                                               script_url));
380d59292581dbaa4203451709077de40e0ad72c18Anders Carlsson}
391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
404fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas GregorServiceWorkerStatusCode EmbeddedWorkerRegistry::StopWorker(
415f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    int process_id, int embedded_worker_id) {
424fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  return Send(process_id,
435cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu              new EmbeddedWorkerMsg_StopWorker(embedded_worker_id));
445cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu}
455cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu
465cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieuvoid EmbeddedWorkerRegistry::OnWorkerStarted(
474fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    int process_id, int thread_id, int embedded_worker_id) {
484fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  DCHECK(!ContainsKey(worker_process_map_, process_id) ||
494fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor         worker_process_map_[process_id].count(embedded_worker_id) == 0);
504fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
514fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  if (found == worker_map_.end()) {
52162e1c1b487352434552147967c3dd296ebee2f7Richard Smith    LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
534fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    return;
544fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  }
554fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  worker_process_map_[process_id].insert(embedded_worker_id);
564fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  DCHECK_EQ(found->second->process_id(), process_id);
574fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  found->second->OnStarted(thread_id);
584fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor}
5957ad37823e198f977cac605dbfbaefb4daf325e9Chris Lattner
604fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregorvoid EmbeddedWorkerRegistry::OnWorkerStopped(
614fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    int process_id, int embedded_worker_id) {
6215de72cf580840c61e5704c2f8a2b56f9d0638e1Douglas Gregor  WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
6328ac87e1a22ee15f284643d9007640d25b1aab5bPeter Collingbourne  if (found == worker_map_.end()) {
6459e63570359b8adb9eb257759fe766d7aac1995aDouglas Gregor    LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
658419fa3af97208eb00f0cd6c62354ce4ff986677Douglas Gregor    return;
666c9c94053132e5ca0655124b70f1c386a332e71dDouglas Gregor  }
6759e63570359b8adb9eb257759fe766d7aac1995aDouglas Gregor  DCHECK_EQ(found->second->process_id(), process_id);
684fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  worker_process_map_[process_id].erase(embedded_worker_id);
6998a57868d696cb5faf6195a609ad084a711c6bbeRichard Smith  found->second->OnStopped();
705cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu}
715cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu
724fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregorvoid EmbeddedWorkerRegistry::OnSendMessageToBrowser(
734fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    int embedded_worker_id, int request_id, const IPC::Message& message) {
744fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
754fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  if (found == worker_map_.end()) {
764fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    LOG(ERROR) << "Worker " << embedded_worker_id << " not registered";
774fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    return;
784fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  }
794fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  // Perform security check to filter out any unexpected (and non-test)
804fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  // messages. This must list up all message types that can go through here.
817ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall  if (message.type() == ServiceWorkerHostMsg_InstallEventFinished::ID ||
827ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall      IPC_MESSAGE_CLASS(message) == TestMsgStart) {
83f53eaa59c4936f9b095e69557ce7366b26ca90cbAnders Carlsson    found->second->OnMessageReceived(request_id, message);
849488ea120e093068021f944176c3d610dd540914John McCall    return;
855cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu  }
865cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu  NOTREACHED() << "Got unexpected message: " << message.type();
875cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu}
881bea8807bcd2be10bf6309a3a848489434464cedDouglas Gregor
894fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregorvoid EmbeddedWorkerRegistry::AddChildProcessSender(
904fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    int process_id, IPC::Sender* sender) {
914fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  process_sender_map_[process_id] = sender;
925cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu  DCHECK(!ContainsKey(worker_process_map_, process_id));
935cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu}
9430c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor
954fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregorvoid EmbeddedWorkerRegistry::RemoveChildProcessSender(int process_id) {
964fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor  process_sender_map_.erase(process_id);
975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  std::map<int, std::set<int> >::iterator found =
985cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu      worker_process_map_.find(process_id);
995cb3d699f0e37de1767eb23d26d03953a46cf1ffRichard Trieu  if (found != worker_process_map_.end()) {
100f88df8652e0726fe9eee5d78f92e3c5b34d0a537Anders Carlsson    const std::set<int>& worker_set = worker_process_map_[process_id];
1014fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor    for (std::set<int>::const_iterator it = worker_set.begin();
1024fe0c8e9c76b96e7aff21696a40dacc09d0237bcDouglas Gregor         it != worker_set.end();
10342f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman         ++it) {
10442f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman      int embedded_worker_id = *it;
10542f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman      DCHECK(ContainsKey(worker_map_, embedded_worker_id));
10642f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman      worker_map_[embedded_worker_id]->OnStopped();
10742f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman    }
10842f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman    worker_process_map_.erase(found);
1096217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  }
11042f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman}
11142f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman
11242f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli FriedmanEmbeddedWorkerInstance* EmbeddedWorkerRegistry::GetWorker(
113183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall    int embedded_worker_id) {
11442f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  WorkerInstanceMap::iterator found = worker_map_.find(embedded_worker_id);
115183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  if (found == worker_map_.end())
1165068ab669970ba62020541251f1193b237d24ae3Douglas Gregor    return NULL;
11742f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  return found->second;
118b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie}
11942f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman
12042f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli FriedmanEmbeddedWorkerRegistry::~EmbeddedWorkerRegistry() {}
12142f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman
12242f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli FriedmanServiceWorkerStatusCode EmbeddedWorkerRegistry::Send(
12342f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman    int process_id, IPC::Message* message) {
124162e1c1b487352434552147967c3dd296ebee2f7Richard Smith  if (!context_)
12542f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman    return SERVICE_WORKER_ERROR_ABORT;
12642f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  ProcessToSenderMap::iterator found = process_sender_map_.find(process_id);
12742f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  if (found == process_sender_map_.end())
12842f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman    return SERVICE_WORKER_ERROR_PROCESS_NOT_FOUND;
12942f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  if (!found->second->Send(message))
13042f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman    return SERVICE_WORKER_ERROR_IPC_FAILED;
13142f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  return SERVICE_WORKER_OK;
1325f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner}
13342f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman
13442f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedmanvoid EmbeddedWorkerRegistry::RemoveWorker(int process_id,
135f1d60eaf3f70975ee262852af2d6aeabd140ed58Argyrios Kyrtzidis                                          int embedded_worker_id) {
13642f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  DCHECK(ContainsKey(worker_map_, embedded_worker_id));
13742f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  worker_map_.erase(embedded_worker_id);
13842f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman  worker_process_map_.erase(process_id);
13942f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman}
14042f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman
14142f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman}  // namespace content
14242f42c0dd5cf71fbfc6fa282d03079a902f6e342Eli Friedman