Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: content/browser/service_worker/service_worker_context_wrapper.cc

Issue 238043002: Teach EmbeddedWorkerInstance to create a process when it needs one. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Null out browser_context_ in Shutdown Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/service_worker/service_worker_context_wrapper.h" 5 #include "content/browser/service_worker/service_worker_context_wrapper.h"
6 6
7 #include "base/callback.h"
7 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/lazy_instance.h"
10 #include "content/browser/renderer_host/render_process_host_impl.h"
8 #include "content/browser/service_worker/service_worker_context_core.h" 11 #include "content/browser/service_worker/service_worker_context_core.h"
9 #include "content/browser/service_worker/service_worker_context_observer.h" 12 #include "content/browser/service_worker/service_worker_context_observer.h"
10 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/site_instance.h"
11 #include "webkit/browser/quota/quota_manager_proxy.h" 15 #include "webkit/browser/quota/quota_manager_proxy.h"
12 16
13 namespace content { 17 namespace content {
18 namespace {
19 base::LazyInstance<base::Callback<bool(int)> > s_increment_worker_refcount;
20 base::LazyInstance<base::Callback<bool(int)> > s_decrement_worker_refcount;
kinuko 2014/04/25 13:46:35 Whoa... ah ok it's for testing.
Jeffrey Yasskin 2014/04/26 03:52:19 And gone now.
21
22 bool IncrementWorkerRefcountByPid(int process_id) {
23 if (!s_increment_worker_refcount.Get().is_null())
24 return s_increment_worker_refcount.Get().Run(process_id);
25
26 RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
27 if (rph)
kinuko 2014/04/25 13:46:35 Probably also check if (!rph->FastShutdownStarted(
Jeffrey Yasskin 2014/04/26 03:52:19 Done.
28 static_cast<RenderProcessHostImpl*>(rph)->IncrementWorkerRefCount();
29
30 return rph;
kinuko 2014/04/25 13:46:35 I prefer explicitly return a boolean value.
Jeffrey Yasskin 2014/04/26 03:52:19 Done.
31 }
32
33 bool DecrementWorkerRefcountByPid(int process_id) {
34 if (!s_decrement_worker_refcount.Get().is_null())
35 return s_decrement_worker_refcount.Get().Run(process_id);
36
37 RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
38 if (rph)
39 static_cast<RenderProcessHostImpl*>(rph)->DecrementWorkerRefCount();
40
41 return rph;
42 }
43 } // namespace
14 44
15 ServiceWorkerContextWrapper::ServiceWorkerContextWrapper() 45 ServiceWorkerContextWrapper::ServiceWorkerContextWrapper()
16 : observer_list_( 46 : browser_context_(NULL),
17 new ObserverListThreadSafe<ServiceWorkerContextObserver>()) {} 47 observer_list_(
48 new ObserverListThreadSafe<ServiceWorkerContextObserver>()) {
49 }
18 50
19 ServiceWorkerContextWrapper::~ServiceWorkerContextWrapper() { 51 ServiceWorkerContextWrapper::~ServiceWorkerContextWrapper() {
20 } 52 }
21 53
22 void ServiceWorkerContextWrapper::Init( 54 void ServiceWorkerContextWrapper::Init(
23 const base::FilePath& user_data_directory, 55 const base::FilePath& user_data_directory,
24 quota::QuotaManagerProxy* quota_manager_proxy) { 56 quota::QuotaManagerProxy* quota_manager_proxy) {
25 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 57 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
26 BrowserThread::PostTask( 58 BrowserThread::PostTask(
27 BrowserThread::IO, FROM_HERE, 59 BrowserThread::IO, FROM_HERE,
28 base::Bind(&ServiceWorkerContextWrapper::Init, this, 60 base::Bind(&ServiceWorkerContextWrapper::Init, this,
29 user_data_directory, 61 user_data_directory,
30 make_scoped_refptr(quota_manager_proxy))); 62 make_scoped_refptr(quota_manager_proxy)));
31 return; 63 return;
32 } 64 }
33 DCHECK(!context_core_); 65 DCHECK(!context_core_);
34 context_core_.reset(new ServiceWorkerContextCore( 66 context_core_.reset(new ServiceWorkerContextCore(
35 user_data_directory, quota_manager_proxy, observer_list_)); 67 this, user_data_directory, quota_manager_proxy, observer_list_));
36 } 68 }
37 69
38 void ServiceWorkerContextWrapper::Shutdown() { 70 void ServiceWorkerContextWrapper::Shutdown() {
39 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 71 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
72 DCHECK_CURRENTLY_ON(BrowserThread::UI);
73 browser_context_ = NULL;
40 BrowserThread::PostTask( 74 BrowserThread::PostTask(
41 BrowserThread::IO, FROM_HERE, 75 BrowserThread::IO, FROM_HERE,
42 base::Bind(&ServiceWorkerContextWrapper::Shutdown, this)); 76 base::Bind(&ServiceWorkerContextWrapper::Shutdown, this));
43 return; 77 return;
44 } 78 }
79 // This breaks a reference cycle from Core::wrapper_ back to this object.
45 context_core_.reset(); 80 context_core_.reset();
46 } 81 }
47 82
48 ServiceWorkerContextCore* ServiceWorkerContextWrapper::context() { 83 ServiceWorkerContextCore* ServiceWorkerContextWrapper::context() {
49 DCHECK_CURRENTLY_ON(BrowserThread::IO); 84 DCHECK_CURRENTLY_ON(BrowserThread::IO);
50 return context_core_.get(); 85 return context_core_.get();
51 } 86 }
52 87
88 void ServiceWorkerContextWrapper::IncrementWorkerRef(
89 const std::vector<int>& process_ids,
90 const GURL& script_url,
91 const base::Callback<void(ServiceWorkerStatusCode, int process_id)>&
92 callback) const {
93 DCHECK_CURRENTLY_ON(BrowserThread::UI);
94
95 for (std::vector<int>::const_iterator it = process_ids.begin();
96 it != process_ids.end();
97 ++it) {
98 if (IncrementWorkerRefcountByPid(*it)) {
99 BrowserThread::PostTask(BrowserThread::IO,
100 FROM_HERE,
101 base::Bind(callback, SERVICE_WORKER_OK, *it));
102 return;
103 }
104 }
105
106 if (!browser_context_) {
107 // If all of the processes that requested a SW went away before it was
108 // created, we should just ignore the request.
109 LOG(ERROR) << "Couldn't start a new process!";
110 BrowserThread::PostTask(
111 BrowserThread::IO,
112 FROM_HERE,
113 base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED, -1));
114 return;
115 }
116
117 // No existing processes available; start a new one.
118 scoped_refptr<SiteInstance> site_instance =
119 SiteInstance::CreateForURL(browser_context_, script_url);
120 RenderProcessHost* rph = site_instance->GetProcess();
121 // This Init() call posts a task to the IO thread that adds the RPH's
122 // ServiceWorkerDispatcherHost to the
123 // EmbeddedWorkerRegistry::process_sender_map_.
124 if (!rph->Init()) {
125 LOG(ERROR) << "Couldn't start a new process!";
126 BrowserThread::PostTask(
127 BrowserThread::IO,
128 FROM_HERE,
129 base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED, -1));
130 return;
131 }
132
133 static_cast<RenderProcessHostImpl*>(rph)->IncrementWorkerRefCount();
134 BrowserThread::PostTask(
135 BrowserThread::IO,
136 FROM_HERE,
137 base::Bind(callback, SERVICE_WORKER_OK, rph->GetID()));
138 }
139
140 void ServiceWorkerContextWrapper::DecrementWorkerRef(int process_id) {
141 DCHECK_CURRENTLY_ON(BrowserThread::UI);
142 if (!DecrementWorkerRefcountByPid(process_id)) {
143 DCHECK(false) << "DecrementWorkerRef(" << process_id
144 << ") doesn't match a previous IncrementWorkerRef";
145 }
146 }
147
53 static void FinishRegistrationOnIO( 148 static void FinishRegistrationOnIO(
54 const ServiceWorkerContext::ResultCallback& continuation, 149 const ServiceWorkerContext::ResultCallback& continuation,
55 ServiceWorkerStatusCode status, 150 ServiceWorkerStatusCode status,
56 int64 registration_id, 151 int64 registration_id,
57 int64 version_id) { 152 int64 version_id) {
58 DCHECK_CURRENTLY_ON(BrowserThread::IO); 153 DCHECK_CURRENTLY_ON(BrowserThread::IO);
154 if (status != SERVICE_WORKER_OK)
155 LOG(ERROR) << ServiceWorkerStatusToString(status);
59 BrowserThread::PostTask( 156 BrowserThread::PostTask(
60 BrowserThread::UI, 157 BrowserThread::UI,
61 FROM_HERE, 158 FROM_HERE,
62 base::Bind(continuation, status == SERVICE_WORKER_OK)); 159 base::Bind(continuation, status == SERVICE_WORKER_OK));
63 } 160 }
64 161
65 void ServiceWorkerContextWrapper::RegisterServiceWorker( 162 void ServiceWorkerContextWrapper::RegisterServiceWorker(
66 const GURL& pattern, 163 const GURL& pattern,
67 const GURL& script_url, 164 const GURL& script_url,
68 int source_process_id, 165 BrowserContext* browser_context,
69 const ResultCallback& continuation) { 166 const ResultCallback& continuation) {
70 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 167 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
168 DCHECK(browser_context != NULL);
169 if (browser_context_ != NULL) {
170 DCHECK_EQ(browser_context_, browser_context)
171 << "|context| must be the BrowserContext containing *this.";
172 }
173 browser_context_ = browser_context;
71 BrowserThread::PostTask( 174 BrowserThread::PostTask(
72 BrowserThread::IO, 175 BrowserThread::IO,
73 FROM_HERE, 176 FROM_HERE,
74 base::Bind(&ServiceWorkerContextWrapper::RegisterServiceWorker, 177 base::Bind(&ServiceWorkerContextWrapper::RegisterServiceWorker,
75 this, 178 this,
76 pattern, 179 pattern,
77 script_url, 180 script_url,
78 source_process_id, 181 browser_context,
79 continuation)); 182 continuation));
80 return; 183 return;
81 } 184 }
185 DCHECK_CURRENTLY_ON(BrowserThread::IO);
82 186
83 context()->RegisterServiceWorker( 187 context()->RegisterServiceWorker(
84 pattern, 188 pattern,
85 script_url, 189 script_url,
86 source_process_id, 190 -1,
87 NULL /* provider_host */, 191 NULL /* provider_host */,
88 base::Bind(&FinishRegistrationOnIO, continuation)); 192 base::Bind(&FinishRegistrationOnIO, continuation));
89 } 193 }
90 194
91 static void FinishUnregistrationOnIO( 195 static void FinishUnregistrationOnIO(
92 const ServiceWorkerContext::ResultCallback& continuation, 196 const ServiceWorkerContext::ResultCallback& continuation,
93 ServiceWorkerStatusCode status) { 197 ServiceWorkerStatusCode status) {
94 DCHECK_CURRENTLY_ON(BrowserThread::IO); 198 DCHECK_CURRENTLY_ON(BrowserThread::IO);
199 if (status != SERVICE_WORKER_OK)
200 LOG(ERROR) << ServiceWorkerStatusToString(status);
95 BrowserThread::PostTask( 201 BrowserThread::PostTask(
96 BrowserThread::UI, 202 BrowserThread::UI,
97 FROM_HERE, 203 FROM_HERE,
98 base::Bind(continuation, status == SERVICE_WORKER_OK)); 204 base::Bind(continuation, status == SERVICE_WORKER_OK));
99 } 205 }
100 206
101 void ServiceWorkerContextWrapper::UnregisterServiceWorker( 207 void ServiceWorkerContextWrapper::UnregisterServiceWorker(
102 const GURL& pattern, 208 const GURL& pattern,
103 int source_process_id, 209 int source_process_id,
104 const ResultCallback& continuation) { 210 const ResultCallback& continuation) {
(...skipping 19 matching lines...) Expand all
124 void ServiceWorkerContextWrapper::AddObserver( 230 void ServiceWorkerContextWrapper::AddObserver(
125 ServiceWorkerContextObserver* observer) { 231 ServiceWorkerContextObserver* observer) {
126 observer_list_->AddObserver(observer); 232 observer_list_->AddObserver(observer);
127 } 233 }
128 234
129 void ServiceWorkerContextWrapper::RemoveObserver( 235 void ServiceWorkerContextWrapper::RemoveObserver(
130 ServiceWorkerContextObserver* observer) { 236 ServiceWorkerContextObserver* observer) {
131 observer_list_->RemoveObserver(observer); 237 observer_list_->RemoveObserver(observer);
132 } 238 }
133 239
240 void ServiceWorkerContextWrapper::ResetWorkerRefCountOperationsForTest(
241 const base::Callback<bool(int)>& increment,
242 const base::Callback<bool(int)>& decrement) {
243 s_increment_worker_refcount.Get() = increment;
244 s_decrement_worker_refcount.Get() = decrement;
245 }
246
134 } // namespace content 247 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698