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.
5 #include "content/browser/service_worker/service_worker_process_manager.h"
7 #include "content/browser/renderer_host/render_process_host_impl.h"
8 #include "content/browser/service_worker/service_worker_context_wrapper.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/browser/site_instance.h"
15 ServiceWorkerProcessManager::ServiceWorkerProcessManager(
16 ServiceWorkerContextWrapper
* context_wrapper
)
17 : context_wrapper_(context_wrapper
),
18 weak_this_factory_(this),
19 weak_this_(weak_this_factory_
.GetWeakPtr()) {
22 ServiceWorkerProcessManager::~ServiceWorkerProcessManager() {
23 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
26 void ServiceWorkerProcessManager::AllocateWorkerProcess(
27 const std::vector
<int>& process_ids
,
28 const GURL
& script_url
,
29 const base::Callback
<void(ServiceWorkerStatusCode
, int process_id
)>&
31 if (!BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
32 BrowserThread::PostTask(
35 base::Bind(&ServiceWorkerProcessManager::AllocateWorkerProcess
,
43 for (std::vector
<int>::const_iterator it
= process_ids
.begin();
44 it
!= process_ids
.end();
46 if (IncrementWorkerRefcountByPid(*it
)) {
47 BrowserThread::PostTask(BrowserThread::IO
,
49 base::Bind(callback
, SERVICE_WORKER_OK
, *it
));
54 if (!context_wrapper_
->browser_context_
) {
55 // Shutdown has started.
56 BrowserThread::PostTask(
59 base::Bind(callback
, SERVICE_WORKER_ERROR_START_WORKER_FAILED
, -1));
62 // No existing processes available; start a new one.
63 scoped_refptr
<SiteInstance
> site_instance
= SiteInstance::CreateForURL(
64 context_wrapper_
->browser_context_
, script_url
);
65 RenderProcessHost
* rph
= site_instance
->GetProcess();
66 // This Init() call posts a task to the IO thread that adds the RPH's
67 // ServiceWorkerDispatcherHost to the
68 // EmbeddedWorkerRegistry::process_sender_map_.
70 LOG(ERROR
) << "Couldn't start a new process!";
71 BrowserThread::PostTask(
74 base::Bind(callback
, SERVICE_WORKER_ERROR_START_WORKER_FAILED
, -1));
78 static_cast<RenderProcessHostImpl
*>(rph
)->IncrementWorkerRefCount();
79 BrowserThread::PostTask(
82 base::Bind(callback
, SERVICE_WORKER_OK
, rph
->GetID()));
85 void ServiceWorkerProcessManager::ReleaseWorkerProcess(int process_id
) {
86 if (!BrowserThread::CurrentlyOn(BrowserThread::UI
)) {
87 BrowserThread::PostTask(
90 base::Bind(&ServiceWorkerProcessManager::ReleaseWorkerProcess
,
95 if (!DecrementWorkerRefcountByPid(process_id
)) {
96 DCHECK(false) << "DecrementWorkerRef(" << process_id
97 << ") doesn't match a previous IncrementWorkerRef";
101 void ServiceWorkerProcessManager::SetProcessRefcountOpsForTest(
102 const base::Callback
<bool(int)>& increment_for_test
,
103 const base::Callback
<bool(int)>& decrement_for_test
) {
104 increment_for_test_
= increment_for_test
;
105 decrement_for_test_
= decrement_for_test
;
108 bool ServiceWorkerProcessManager::IncrementWorkerRefcountByPid(
109 int process_id
) const {
110 if (!increment_for_test_
.is_null())
111 return increment_for_test_
.Run(process_id
);
113 RenderProcessHost
* rph
= RenderProcessHost::FromID(process_id
);
114 if (rph
&& !rph
->FastShutdownStarted()) {
115 static_cast<RenderProcessHostImpl
*>(rph
)->IncrementWorkerRefCount();
122 bool ServiceWorkerProcessManager::DecrementWorkerRefcountByPid(
123 int process_id
) const {
124 if (!decrement_for_test_
.is_null())
125 return decrement_for_test_
.Run(process_id
);
127 RenderProcessHost
* rph
= RenderProcessHost::FromID(process_id
);
129 static_cast<RenderProcessHostImpl
*>(rph
)->DecrementWorkerRefCount();
134 } // namespace content
137 // Destroying ServiceWorkerProcessManagers only on the UI thread allows the
138 // member WeakPtr to safely guard the object's lifetime when used on that
140 void DefaultDeleter
<content::ServiceWorkerProcessManager
>::operator()(
141 content::ServiceWorkerProcessManager
* ptr
) const {
142 content::BrowserThread::DeleteSoon(
143 content::BrowserThread::UI
, FROM_HERE
, ptr
);