• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROCESS_MANAGER_H_
6 #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROCESS_MANAGER_H_
7 
8 #include <map>
9 #include <vector>
10 
11 #include "base/callback.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "content/common/service_worker/service_worker_status_code.h"
15 
16 class GURL;
17 
18 namespace content {
19 
20 class BrowserContext;
21 class SiteInstance;
22 
23 // Interacts with the UI thread to keep RenderProcessHosts alive while the
24 // ServiceWorker system is using them. Each instance of
25 // ServiceWorkerProcessManager is destroyed on the UI thread shortly after its
26 // ServiceWorkerContextWrapper is destroyed.
27 class CONTENT_EXPORT ServiceWorkerProcessManager {
28  public:
29   // |*this| must be owned by a ServiceWorkerContextWrapper in a
30   // StoragePartition within |browser_context|.
31   explicit ServiceWorkerProcessManager(BrowserContext* browser_context);
32 
33   // Shutdown must be called before the ProcessManager is destroyed.
34   ~ServiceWorkerProcessManager();
35 
36   // Synchronously prevents new processes from being allocated.
37   // TODO(jyasskin): Drop references to RenderProcessHosts too.
38   void Shutdown();
39 
40   // Returns a reference to a running process suitable for starting the Service
41   // Worker at |script_url|. Processes in |process_ids| will be checked in order
42   // for existence, and if none exist, then a new process will be created. Posts
43   // |callback| to the IO thread to indicate whether creation succeeded and the
44   // process ID that has a new reference.
45   //
46   // Allocation can fail with SERVICE_WORKER_ERROR_START_WORKER_FAILED if
47   // RenderProcessHost::Init fails.
48   void AllocateWorkerProcess(
49       int embedded_worker_id,
50       const std::vector<int>& process_ids,
51       const GURL& script_url,
52       const base::Callback<void(ServiceWorkerStatusCode, int process_id)>&
53           callback);
54 
55   // Drops a reference to a process that was running a Service Worker, and its
56   // SiteInstance.  This must match a call to AllocateWorkerProcess.
57   void ReleaseWorkerProcess(int embedded_worker_id);
58 
59   // Sets a single process ID that will be used for all embedded workers.  This
60   // bypasses the work of creating a process and managing its worker refcount so
61   // that unittests can run without a BrowserContext.  The test is in charge of
62   // making sure this is only called on the same thread as runs the UI message
63   // loop.
SetProcessIdForTest(int process_id)64   void SetProcessIdForTest(int process_id) {
65     process_id_for_test_ = process_id;
66   }
67 
68  private:
69   // Information about the process for an EmbeddedWorkerInstance.
70   struct ProcessInfo {
71     explicit ProcessInfo(const scoped_refptr<SiteInstance>& site_instance);
72     explicit ProcessInfo(int process_id);
73     ~ProcessInfo();
74 
75     // Stores the SiteInstance the Worker lives inside. This needs to outlive
76     // the instance's use of its RPH to uphold assumptions in the
77     // ContentBrowserClient interface.
78     scoped_refptr<SiteInstance> site_instance;
79 
80     // In case the process was allocated without using a SiteInstance, we need
81     // to store a process ID to decrement a worker reference on shutdown.
82     // TODO(jyasskin): Implement http://crbug.com/372045 or thread a frame_id in
83     // so all processes can be allocated with a SiteInstance.
84     int process_id;
85   };
86 
87   // These fields are only accessed on the UI thread.
88   BrowserContext* browser_context_;
89 
90   // Maps the ID of a running EmbeddedWorkerInstance to information about the
91   // process it's running inside. Since the Instances themselves live on the IO
92   // thread, this can be slightly out of date:
93   //  * instance_info_ is populated while an Instance is STARTING and before
94   //    it's RUNNING.
95   //  * instance_info_ is depopulated in a message sent as the Instance becomes
96   //    STOPPED.
97   std::map<int, ProcessInfo> instance_info_;
98 
99   // In unit tests, this will be returned as the process for all
100   // EmbeddedWorkerInstances.
101   int process_id_for_test_;
102 
103   // Used to double-check that we don't access *this after it's destroyed.
104   base::WeakPtrFactory<ServiceWorkerProcessManager> weak_this_factory_;
105   const base::WeakPtr<ServiceWorkerProcessManager> weak_this_;
106 };
107 
108 }  // namespace content
109 
110 namespace base {
111 // Specialized to post the deletion to the UI thread.
112 template <>
113 struct CONTENT_EXPORT DefaultDeleter<content::ServiceWorkerProcessManager> {
114   void operator()(content::ServiceWorkerProcessManager* ptr) const;
115 };
116 }  // namespace base
117 
118 #endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROCESS_MANAGER_H_
119