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