summaryrefslogtreecommitdiffstats
path: root/chrome/browser/worker_host/worker_service.h
blob: 97891b5944f77bb9677b6de0334788113d900634 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// 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.

#ifndef CHROME_BROWSER_WORKER_HOST_WORKER_SERVICE_H_
#define CHROME_BROWSER_WORKER_HOST_WORKER_SERVICE_H_

#include <list>

#include "base/basictypes.h"
#include "base/singleton.h"
#include "chrome/browser/worker_host/worker_process_host.h"
#include "chrome/common/notification_registrar.h"
#include "googleurl/src/gurl.h"
#include "ipc/ipc_message.h"

class WorkerProcessHost;
class ResourceDispatcherHost;

class WorkerService : public NotificationObserver {
 public:
  // Returns the WorkerService singleton.
  static WorkerService* GetInstance();

  // Initialize the WorkerService.  OK to be called multiple times.
  void Initialize(ResourceDispatcherHost* rdh);

  // Creates a dedicated worker.  Returns true on success.
  bool CreateWorker(const GURL &url,
                    bool is_shared,
                    bool is_off_the_record,
                    const string16& name,
                    unsigned long long document_id,
                    int renderer_pid,
                    int render_view_route_id,
                    IPC::Message::Sender* sender,
                    int sender_route_id);

  // Validates the passed URL and checks for the existence of matching shared
  // worker. Returns true if the url was found, and sets the url_mismatch out
  // param to true/false depending on whether there's a url mismatch with an
  // existing shared worker with the same name.
  bool LookupSharedWorker(const GURL &url,
                          const string16& name,
                          bool off_the_record,
                          unsigned long long document_id,
                          int renderer_pid,
                          int render_view_route_id,
                          IPC::Message::Sender* sender,
                          int sender_route_id,
                          bool* url_mismatch);

  // Notification from the renderer that a given document has detached, so any
  // associated shared workers can be shut down.
  void DocumentDetached(IPC::Message::Sender* sender,
                        unsigned long long document_id);

  // Cancel creation of a dedicated worker that hasn't started yet.
  void CancelCreateDedicatedWorker(IPC::Message::Sender* sender,
                                   int sender_route_id);

  // Called by the worker creator when a message arrives that should be
  // forwarded to the worker process.
  void ForwardMessage(const IPC::Message& message,
                      IPC::Message::Sender* sender);

  int next_worker_route_id() { return ++next_worker_route_id_; }

  // TODO(dimich): This code assumes there is 1 worker per worker process, which
  // is how it is today until V8 can run in separate threads.
  const WorkerProcessHost::WorkerInstance* FindWorkerInstance(
      int worker_process_id);

  WorkerProcessHost::WorkerInstance* FindSharedWorkerInstance(
      const GURL& url, const string16& name, bool off_the_record);

  // Used when multiple workers can run in the same process.
  static const int kMaxWorkerProcessesWhenSharing;

  // Used when we run each worker in a separate process.
  static const int kMaxWorkersWhenSeparate;
  static const int kMaxWorkersPerTabWhenSeparate;

 private:
  friend struct DefaultSingletonTraits<WorkerService>;

  WorkerService();
  ~WorkerService();

  // Given a WorkerInstance, create an associated worker process.
  bool CreateWorkerFromInstance(WorkerProcessHost::WorkerInstance instance);

  // Returns a WorkerProcessHost object if one exists for the given domain, or
  // NULL if there are no such workers yet.
  WorkerProcessHost* GetProcessForDomain(const GURL& url);

  // Returns a WorkerProcessHost based on a strategy of creating one worker per
  // core.
  WorkerProcessHost* GetProcessToFillUpCores();

  // Returns the WorkerProcessHost from the existing set that has the least
  // number of worker instance running.
  WorkerProcessHost* GetLeastLoadedWorker();

  // Checks if we can create a worker process based on the process limit when
  // we're using a strategy of one process per core.
  bool CanCreateWorkerProcess(
      const WorkerProcessHost::WorkerInstance& instance);

  // Checks if the tab associated with the passed RenderView can create a
  // worker process based on the process limit when we're using a strategy of
  // one worker per process.
  bool TabCanCreateWorkerProcess(
      int renderer_id, int render_view_route_id, bool* hit_total_worker_limit);

  // NotificationObserver interface.
  void Observe(NotificationType type,
               const NotificationSource& source,
               const NotificationDetails& details);

  // Notifies us that a process that's talking to a worker has shut down.
  void SenderShutdown(IPC::Message::Sender* sender);

  // Notifies us that a worker process has closed.
  void WorkerProcessDestroyed(WorkerProcessHost* process);

  // APIs for manipulating our set of pending shared worker instances.
  WorkerProcessHost::WorkerInstance* CreatePendingInstance(
      const GURL& url, const string16& name, bool off_the_record);
  WorkerProcessHost::WorkerInstance* FindPendingInstance(
      const GURL& url, const string16& name, bool off_the_record);
  void RemovePendingInstances(
      const GURL& url, const string16& name, bool off_the_record);

  NotificationRegistrar registrar_;
  int next_worker_route_id_;
  ResourceDispatcherHost* resource_dispatcher_host_;

  WorkerProcessHost::Instances queued_workers_;

  // These are shared workers that have been looked up, but not created yet.
  // We need to keep a list of these to synchronously detect shared worker
  // URL mismatches when two pages launch shared workers simultaneously.
  WorkerProcessHost::Instances pending_shared_workers_;

  DISALLOW_COPY_AND_ASSIGN(WorkerService);
};

#endif  // CHROME_BROWSER_WORKER_HOST_WORKER_SERVICE_H_