15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/shared_worker/shared_worker_service_impl.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <algorithm>
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <iterator>
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <set>
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <vector>
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/callback.h"
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/memory/ref_counted.h"
14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/browser/devtools/embedded_worker_devtools_manager.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/renderer_host/render_process_host_impl.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/shared_worker/shared_worker_host.h"
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/browser/shared_worker/shared_worker_instance.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/shared_worker/shared_worker_message_filter.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/browser/shared_worker/worker_document_set.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/common/view_messages.h"
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/common/worker_messages.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/worker_service_observer.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content {
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)WorkerService* WorkerService::GetInstance() {
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return SharedWorkerServiceImpl::GetInstance();
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class ScopedWorkerDependencyChecker {
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public:
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  explicit ScopedWorkerDependencyChecker(SharedWorkerServiceImpl* service)
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      : service_(service) {}
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedWorkerDependencyChecker(SharedWorkerServiceImpl* service,
380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                base::Closure done_closure)
390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      : service_(service), done_closure_(done_closure) {}
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ~ScopedWorkerDependencyChecker() {
410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    service_->CheckWorkerDependency();
420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!done_closure_.is_null())
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      done_closure_.Run();
440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) private:
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SharedWorkerServiceImpl* service_;
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::Closure done_closure_;
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedWorkerDependencyChecker);
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)};
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void UpdateWorkerDependencyOnUI(const std::vector<int>& added_ids,
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                const std::vector<int>& removed_ids) {
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i < added_ids.size(); ++i) {
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RenderProcessHostImpl* render_process_host_impl =
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        static_cast<RenderProcessHostImpl*>(
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            RenderProcessHost::FromID(added_ids[i]));
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!render_process_host_impl)
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_process_host_impl->IncrementWorkerRefCount();
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i < removed_ids.size(); ++i) {
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RenderProcessHostImpl* render_process_host_impl =
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        static_cast<RenderProcessHostImpl*>(
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            RenderProcessHost::FromID(removed_ids[i]));
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!render_process_host_impl)
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    render_process_host_impl->DecrementWorkerRefCount();
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void UpdateWorkerDependency(const std::vector<int>& added_ids,
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                            const std::vector<int>& removed_ids) {
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  BrowserThread::PostTask(
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      BrowserThread::UI,
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      FROM_HERE,
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&UpdateWorkerDependencyOnUI, added_ids, removed_ids));
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid DecrementWorkerRefCount(int process_id) {
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    BrowserThread::PostTask(BrowserThread::UI,
830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                            FROM_HERE,
840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                            base::Bind(&DecrementWorkerRefCount, process_id));
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RenderProcessHostImpl* render_process_host_impl =
880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      static_cast<RenderProcessHostImpl*>(
890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          RenderProcessHost::FromID(process_id));
900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (render_process_host_impl)
910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    render_process_host_impl->DecrementWorkerRefCount();
92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool TryIncrementWorkerRefCount(int worker_process_id) {
950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  RenderProcessHostImpl* render_process = static_cast<RenderProcessHostImpl*>(
960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      RenderProcessHost::FromID(worker_process_id));
970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!render_process || render_process->FastShutdownStarted()) {
980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return false;
990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  render_process->IncrementWorkerRefCount();
1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return true;
102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass SharedWorkerServiceImpl::SharedWorkerPendingInstance {
1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public:
1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  struct SharedWorkerPendingRequest {
1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    SharedWorkerPendingRequest(SharedWorkerMessageFilter* filter,
1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               int route_id,
1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               unsigned long long document_id,
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               int render_process_id,
1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               int render_frame_route_id)
1140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        : filter(filter),
1150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          route_id(route_id),
1160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          document_id(document_id),
1170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          render_process_id(render_process_id),
1180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          render_frame_route_id(render_frame_route_id) {}
1190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    SharedWorkerMessageFilter* const filter;
1200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const int route_id;
1210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const unsigned long long document_id;
1220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const int render_process_id;
1230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const int render_frame_route_id;
1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  typedef ScopedVector<SharedWorkerPendingRequest> SharedWorkerPendingRequests;
1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  explicit SharedWorkerPendingInstance(
1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      scoped_ptr<SharedWorkerInstance> instance)
1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      : instance_(instance.Pass()) {}
1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ~SharedWorkerPendingInstance() {}
1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SharedWorkerInstance* instance() { return instance_.get(); }
1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SharedWorkerInstance* release_instance() { return instance_.release(); }
1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SharedWorkerPendingRequests* requests() { return &requests_; }
1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SharedWorkerMessageFilter* FindFilter(int process_id) {
1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    for (size_t i = 0; i < requests_.size(); ++i) {
1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (requests_[i]->render_process_id == process_id)
1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        return requests_[i]->filter;
1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
1400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return NULL;
1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void AddRequest(scoped_ptr<SharedWorkerPendingRequest> request_info) {
1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    requests_.push_back(request_info.release());
1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void RemoveRequest(int process_id) {
1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    for (SharedWorkerPendingRequests::iterator request_itr = requests_.begin();
1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch         request_itr != requests_.end();) {
1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if ((*request_itr)->render_process_id == process_id)
1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        request_itr = requests_.erase(request_itr);
1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      else
1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        ++request_itr;
1520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
1530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void RegisterToSharedWorkerHost(SharedWorkerHost* host) {
1550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    for (size_t i = 0; i < requests_.size(); ++i) {
1560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      SharedWorkerPendingRequest* request = requests_[i];
1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      host->AddFilter(request->filter, request->route_id);
1580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      host->worker_document_set()->Add(request->filter,
1590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                       request->document_id,
1600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                       request->render_process_id,
1610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                       request->render_frame_route_id);
1620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
1630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void SendWorkerCreatedMessages() {
1650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    for (size_t i = 0; i < requests_.size(); ++i) {
1660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      SharedWorkerPendingRequest* request = requests_[i];
1670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      request->filter->Send(new ViewMsg_WorkerCreated(request->route_id));
1680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
1690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private:
1720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<SharedWorkerInstance> instance_;
1730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SharedWorkerPendingRequests requests_;
1740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SharedWorkerPendingInstance);
1750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
1760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass SharedWorkerServiceImpl::SharedWorkerReserver
1780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    : public base::RefCountedThreadSafe<SharedWorkerReserver> {
1790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public:
1800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SharedWorkerReserver(int pending_instance_id,
1810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                       int worker_process_id,
1820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                       int worker_route_id,
1830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                       bool is_new_worker,
1840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                       const SharedWorkerInstance& instance)
1850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      : worker_process_id_(worker_process_id),
1860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        worker_route_id_(worker_route_id),
1870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        is_new_worker_(is_new_worker),
1880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        instance_(instance) {}
1890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void TryReserve(const base::Callback<void(bool)>& success_cb,
1910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                  const base::Closure& failure_cb,
1920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                  bool (*try_increment_worker_ref_count)(int)) {
1930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!try_increment_worker_ref_count(worker_process_id_)) {
1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, failure_cb);
1960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return;
1970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
1980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool pause_on_start = false;
1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (is_new_worker_) {
2000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      pause_on_start =
201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          EmbeddedWorkerDevToolsManager::GetInstance()->SharedWorkerCreated(
2020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              worker_process_id_, worker_route_id_, instance_);
2030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
2040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    BrowserThread::PostTask(
2050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        BrowserThread::IO, FROM_HERE, base::Bind(success_cb, pause_on_start));
2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private:
2090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  friend class base::RefCountedThreadSafe<SharedWorkerReserver>;
2100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ~SharedWorkerReserver() {}
2110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const int worker_process_id_;
2130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const int worker_route_id_;
2140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const bool is_new_worker_;
2150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const SharedWorkerInstance instance_;
2160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
2170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// static
2190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool (*SharedWorkerServiceImpl::s_try_increment_worker_ref_count_)(int) =
2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    TryIncrementWorkerRefCount;
2210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SharedWorkerServiceImpl* SharedWorkerServiceImpl::GetInstance() {
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return Singleton<SharedWorkerServiceImpl>::get();
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SharedWorkerServiceImpl::SharedWorkerServiceImpl()
2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    : update_worker_dependency_(UpdateWorkerDependency),
2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      next_pending_instance_id_(0) {
2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SharedWorkerServiceImpl::~SharedWorkerServiceImpl() {}
233a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SharedWorkerServiceImpl::ResetForTesting() {
235a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  last_worker_depended_renderers_.clear();
236a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  worker_hosts_.clear();
237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  observers_.Clear();
238a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  update_worker_dependency_ = UpdateWorkerDependency;
2390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  s_try_increment_worker_ref_count_ = TryIncrementWorkerRefCount;
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool SharedWorkerServiceImpl::TerminateWorker(int process_id, int route_id) {
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SharedWorkerHost* host =
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      worker_hosts_.get(std::make_pair(process_id, route_id));
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!host || !host->instance())
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  host->TerminateWorker();
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::vector<WorkerService::WorkerInfo> SharedWorkerServiceImpl::GetWorkers() {
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<WorkerService::WorkerInfo> results;
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (WorkerHostMap::const_iterator iter = worker_hosts_.begin();
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       iter != worker_hosts_.end();
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++iter) {
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SharedWorkerHost* host = iter->second;
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const SharedWorkerInstance* instance = host->instance();
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (instance) {
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      WorkerService::WorkerInfo info;
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      info.url = instance->url();
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      info.name = instance->name();
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      info.route_id = host->worker_route_id();
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      info.process_id = host->process_id();
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      info.handle = host->container_render_filter()->PeerHandle();
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      results.push_back(info);
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return results;
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::AddObserver(WorkerServiceObserver* observer) {
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  observers_.AddObserver(observer);
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::RemoveObserver(WorkerServiceObserver* observer) {
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  observers_.RemoveObserver(observer);
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::CreateWorker(
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const ViewHostMsg_CreateWorker_Params& params,
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int route_id,
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SharedWorkerMessageFilter* filter,
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ResourceContext* resource_context,
2865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const WorkerStoragePartitionId& partition_id,
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool* url_mismatch) {
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  *url_mismatch = false;
2900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<SharedWorkerInstance> instance(
2910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new SharedWorkerInstance(params.url,
2920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               params.name,
2930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               params.content_security_policy,
2940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               params.security_policy_type,
2950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               resource_context,
2965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                               partition_id));
2970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<SharedWorkerPendingInstance::SharedWorkerPendingRequest> request(
2980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new SharedWorkerPendingInstance::SharedWorkerPendingRequest(
2990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          filter,
3000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          route_id,
3010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          params.document_id,
3020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          filter->render_process_id(),
3030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          params.render_frame_route_id));
3040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (SharedWorkerPendingInstance* pending = FindPendingInstance(*instance)) {
3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (params.url != pending->instance()->url()) {
306a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      *url_mismatch = true;
307a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
308a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
3090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    pending->AddRequest(request.Pass());
310a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
3120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<SharedWorkerPendingInstance> pending_instance(
3130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new SharedWorkerPendingInstance(instance.Pass()));
3140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  pending_instance->AddRequest(request.Pass());
3150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ReserveRenderProcessToCreateWorker(pending_instance.Pass(), url_mismatch);
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::ForwardToWorker(
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const IPC::Message& message,
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SharedWorkerMessageFilter* filter) {
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (WorkerHostMap::const_iterator iter = worker_hosts_.begin();
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       iter != worker_hosts_.end();
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++iter) {
324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (iter->second->FilterMessage(message, filter))
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return;
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::DocumentDetached(
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    unsigned long long document_id,
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SharedWorkerMessageFilter* filter) {
332a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ScopedWorkerDependencyChecker checker(this);
333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (WorkerHostMap::const_iterator iter = worker_hosts_.begin();
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       iter != worker_hosts_.end();
335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++iter) {
336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    iter->second->DocumentDetached(filter, document_id);
337a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::WorkerContextClosed(
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int worker_route_id,
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SharedWorkerMessageFilter* filter) {
343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ScopedWorkerDependencyChecker checker(this);
344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    host->WorkerContextClosed();
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::WorkerContextDestroyed(
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int worker_route_id,
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SharedWorkerMessageFilter* filter) {
351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ScopedWorkerDependencyChecker checker(this);
352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<SharedWorkerHost> host =
353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      worker_hosts_.take_and_erase(std::make_pair(filter->render_process_id(),
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                  worker_route_id));
355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!host)
356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
357a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  host->WorkerContextDestroyed();
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
36003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void SharedWorkerServiceImpl::WorkerReadyForInspection(
36103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int worker_route_id,
36203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    SharedWorkerMessageFilter* filter) {
36303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
36403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    host->WorkerReadyForInspection();
36503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
36603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::WorkerScriptLoaded(
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int worker_route_id,
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SharedWorkerMessageFilter* filter) {
370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    host->WorkerScriptLoaded();
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::WorkerScriptLoadFailed(
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int worker_route_id,
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SharedWorkerMessageFilter* filter) {
377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ScopedWorkerDependencyChecker checker(this);
378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<SharedWorkerHost> host =
379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      worker_hosts_.take_and_erase(std::make_pair(filter->render_process_id(),
380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                  worker_route_id));
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!host)
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  host->WorkerScriptLoadFailed();
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::WorkerConnected(
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int message_port_id,
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int worker_route_id,
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SharedWorkerMessageFilter* filter) {
390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    host->WorkerConnected(message_port_id);
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::AllowDatabase(
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int worker_route_id,
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GURL& url,
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& name,
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& display_name,
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    unsigned long estimated_size,
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool* result,
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SharedWorkerMessageFilter* filter) {
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
403a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    host->AllowDatabase(url, name, display_name, estimated_size, result);
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::AllowFileSystem(
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int worker_route_id,
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GURL& url,
409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IPC::Message* reply_msg,
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SharedWorkerMessageFilter* filter) {
411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id)) {
412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    host->AllowFileSystem(url, make_scoped_ptr(reply_msg));
413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    filter->Send(reply_msg);
415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::AllowIndexedDB(
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int worker_route_id,
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const GURL& url,
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::string16& name,
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool* result,
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SharedWorkerMessageFilter* filter) {
425a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
426a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    host->AllowIndexedDB(url, name, result);
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SharedWorkerServiceImpl::OnSharedWorkerMessageFilterClosing(
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SharedWorkerMessageFilter* filter) {
431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ScopedWorkerDependencyChecker checker(this);
432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::vector<ProcessRouteIdPair> remove_list;
433a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (WorkerHostMap::iterator iter = worker_hosts_.begin();
434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       iter != worker_hosts_.end();
435a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++iter) {
436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    iter->second->FilterShutdown(filter);
437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (iter->first.first == filter->render_process_id())
438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      remove_list.push_back(iter->first);
439a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
440c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (size_t i = 0; i < remove_list.size(); ++i) {
441c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    scoped_ptr<SharedWorkerHost> host =
442c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        worker_hosts_.take_and_erase(remove_list[i]);
443c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
4440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
4450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::vector<int> remove_pending_instance_list;
4460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (PendingInstaneMap::iterator iter = pending_instances_.begin();
4470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       iter != pending_instances_.end();
4480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       ++iter) {
4490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    iter->second->RemoveRequest(filter->render_process_id());
4500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!iter->second->requests()->size())
4510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      remove_pending_instance_list.push_back(iter->first);
4520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (size_t i = 0; i < remove_pending_instance_list.size(); ++i)
4540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    pending_instances_.take_and_erase(remove_pending_instance_list[i]);
455c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
456c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
457c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid SharedWorkerServiceImpl::NotifyWorkerDestroyed(int worker_process_id,
458c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                                    int worker_route_id) {
459c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  FOR_EACH_OBSERVER(WorkerServiceObserver,
460c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                    observers_,
461c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                    WorkerDestroyed(worker_process_id, worker_route_id));
462a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
4640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid SharedWorkerServiceImpl::ReserveRenderProcessToCreateWorker(
4650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_ptr<SharedWorkerPendingInstance> pending_instance,
4660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool* url_mismatch) {
4670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
4680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(!FindPendingInstance(*pending_instance->instance()));
4690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (url_mismatch)
4700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    *url_mismatch = false;
4710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!pending_instance->requests()->size())
4720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
4730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int worker_process_id = -1;
4740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int worker_route_id = MSG_ROUTING_NONE;
4750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool is_new_worker = true;
4760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SharedWorkerHost* host = FindSharedWorkerHost(*pending_instance->instance());
4770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (host) {
4780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (pending_instance->instance()->url() != host->instance()->url()) {
4790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (url_mismatch)
4800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        *url_mismatch = true;
4810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return;
4820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
4830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    worker_process_id = host->process_id();
4840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    worker_route_id = host->worker_route_id();
4850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    is_new_worker = false;
4860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } else {
4870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    SharedWorkerMessageFilter* first_filter =
4880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        (*pending_instance->requests()->begin())->filter;
4890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    worker_process_id = first_filter->render_process_id();
4900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    worker_route_id = first_filter->GetNextRoutingID();
4910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
4920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const int pending_instance_id = next_pending_instance_id_++;
4930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<SharedWorkerReserver> reserver(
4940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new SharedWorkerReserver(pending_instance_id,
4950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               worker_process_id,
4960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               worker_route_id,
4970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               is_new_worker,
4980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                               *pending_instance->instance()));
4990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  BrowserThread::PostTask(
5000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      BrowserThread::UI,
5010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      FROM_HERE,
5020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::Bind(
5030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          &SharedWorkerReserver::TryReserve,
5040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          reserver,
5050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          base::Bind(&SharedWorkerServiceImpl::RenderProcessReservedCallback,
5060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                     base::Unretained(this),
5070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                     pending_instance_id,
5080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                     worker_process_id,
5090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                     worker_route_id,
5100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                     is_new_worker),
5110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          base::Bind(
5120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              &SharedWorkerServiceImpl::RenderProcessReserveFailedCallback,
5130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              base::Unretained(this),
5140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              pending_instance_id,
5150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              worker_process_id,
5160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              worker_route_id,
5170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              is_new_worker),
5180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          s_try_increment_worker_ref_count_));
5190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  pending_instances_.set(pending_instance_id, pending_instance.Pass());
5200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
5210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid SharedWorkerServiceImpl::RenderProcessReservedCallback(
5230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int pending_instance_id,
5240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int worker_process_id,
5250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int worker_route_id,
5260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool is_new_worker,
5270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool pause_on_start) {
5280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
5290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // To offset the TryIncrementWorkerRefCount called for the reservation,
5300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // calls DecrementWorkerRefCount after CheckWorkerDependency in
5310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // ScopeWorkerDependencyChecker's destructor.
5320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedWorkerDependencyChecker checker(
5330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      this, base::Bind(&DecrementWorkerRefCount, worker_process_id));
5340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<SharedWorkerPendingInstance> pending_instance =
5350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      pending_instances_.take_and_erase(pending_instance_id);
5360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!pending_instance)
5370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
5380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!is_new_worker) {
5390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    SharedWorkerHost* existing_host =
5400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        worker_hosts_.get(std::make_pair(worker_process_id, worker_route_id));
5410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!existing_host) {
5420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // Retry reserving a renderer process if the existed Shared Worker was
5430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // destroyed on IO thread while reserving the renderer process on UI
5440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      // thread.
5450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ReserveRenderProcessToCreateWorker(pending_instance.Pass(), NULL);
5460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return;
5470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
5480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    pending_instance->RegisterToSharedWorkerHost(existing_host);
5490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    pending_instance->SendWorkerCreatedMessages();
5500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
5510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
5520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SharedWorkerMessageFilter* filter =
5530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      pending_instance->FindFilter(worker_process_id);
5540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!filter) {
5550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    pending_instance->RemoveRequest(worker_process_id);
5560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Retry reserving a renderer process if the requested renderer process was
5570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // destroyed on IO thread while reserving the renderer process on UI thread.
5580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    ReserveRenderProcessToCreateWorker(pending_instance.Pass(), NULL);
5590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
5600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
5610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<SharedWorkerHost> host(new SharedWorkerHost(
5620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      pending_instance->release_instance(), filter, worker_route_id));
5630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  pending_instance->RegisterToSharedWorkerHost(host.get());
5640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const GURL url = host->instance()->url();
5650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const base::string16 name = host->instance()->name();
5660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  host->Start(pause_on_start);
5670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  worker_hosts_.set(std::make_pair(worker_process_id, worker_route_id),
5680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                    host.Pass());
5690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FOR_EACH_OBSERVER(
5700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      WorkerServiceObserver,
5710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      observers_,
5720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      WorkerCreated(url, name, worker_process_id, worker_route_id));
5730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
5740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
5750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid SharedWorkerServiceImpl::RenderProcessReserveFailedCallback(
5760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int pending_instance_id,
5770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int worker_process_id,
5780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    int worker_route_id,
5790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool is_new_worker) {
5805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  worker_hosts_.take_and_erase(
5815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      std::make_pair(worker_process_id, worker_route_id));
5820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<SharedWorkerPendingInstance> pending_instance =
5830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      pending_instances_.take_and_erase(pending_instance_id);
5840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!pending_instance)
5850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
5860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  pending_instance->RemoveRequest(worker_process_id);
5870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Retry reserving a renderer process.
5880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ReserveRenderProcessToCreateWorker(pending_instance.Pass(), NULL);
5890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
5900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
591a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SharedWorkerHost* SharedWorkerServiceImpl::FindSharedWorkerHost(
592a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    SharedWorkerMessageFilter* filter,
593a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    int worker_route_id) {
594a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return worker_hosts_.get(std::make_pair(filter->render_process_id(),
595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                          worker_route_id));
596a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
597a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5984ad1aa43a48567659193a298fad74f55e00b3dd9Ben MurdochSharedWorkerHost* SharedWorkerServiceImpl::FindSharedWorkerHost(
5990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const SharedWorkerInstance& instance) {
6000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (WorkerHostMap::const_iterator iter = worker_hosts_.begin();
6010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       iter != worker_hosts_.end();
602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++iter) {
6030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    SharedWorkerHost* host = iter->second;
6040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (host->instance() && !host->closed() &&
6050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        host->instance()->Matches(instance)) {
6060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      return iter->second;
6070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
6080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
6090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return NULL;
6100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
6110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6120529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochSharedWorkerServiceImpl::SharedWorkerPendingInstance*
6130529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochSharedWorkerServiceImpl::FindPendingInstance(
6140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const SharedWorkerInstance& instance) {
6150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (PendingInstaneMap::iterator iter = pending_instances_.begin();
6160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       iter != pending_instances_.end();
6170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       ++iter) {
6180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (iter->second->instance()->Matches(instance))
6194ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch      return iter->second;
620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return NULL;
622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
624a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const std::set<int>
625a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SharedWorkerServiceImpl::GetRenderersWithWorkerDependency() {
626a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::set<int> dependent_renderers;
627a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (WorkerHostMap::iterator host_iter = worker_hosts_.begin();
628a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       host_iter != worker_hosts_.end();
629a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++host_iter) {
630a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const int process_id = host_iter->first.first;
631a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (dependent_renderers.count(process_id))
632a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      continue;
6334ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch    if (host_iter->second->instance() &&
6344ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch        host_iter->second->worker_document_set()->ContainsExternalRenderer(
6354ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch            process_id)) {
636a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      dependent_renderers.insert(process_id);
637a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
638a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
639a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return dependent_renderers;
640a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
642a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SharedWorkerServiceImpl::CheckWorkerDependency() {
643a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const std::set<int> current_worker_depended_renderers =
644a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      GetRenderersWithWorkerDependency();
6455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::vector<int> added_items = base::STLSetDifference<std::vector<int> >(
6465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      current_worker_depended_renderers, last_worker_depended_renderers_);
6475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::vector<int> removed_items = base::STLSetDifference<std::vector<int> >(
6485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      last_worker_depended_renderers_, current_worker_depended_renderers);
649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!added_items.empty() || !removed_items.empty()) {
650a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    last_worker_depended_renderers_ = current_worker_depended_renderers;
651a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    update_worker_dependency_(added_items, removed_items);
652a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
653a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
654a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
655a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SharedWorkerServiceImpl::ChangeUpdateWorkerDependencyFuncForTesting(
656a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    UpdateWorkerDependencyFunc new_func) {
657a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  update_worker_dependency_ = new_func;
6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid SharedWorkerServiceImpl::ChangeTryIncrementWorkerRefCountFuncForTesting(
6610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool (*new_func)(int)) {
6620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  s_try_increment_worker_ref_count_ = new_func;
6630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
6640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace content
666