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

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

Issue 1223193009: WIP attempt to replace StartWorker/StopWorker IPCs with a new mojo EmbeddedWorker service. Base URL: https://chromium.googlesource.com/chromium/src.git@mojo-event-dispatching-option2
Patch Set: Created 5 years, 5 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
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/embedded_worker_instance.h" 5 #include "content/browser/service_worker/embedded_worker_instance.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
12 #include "base/threading/non_thread_safe.h" 12 #include "base/threading/non_thread_safe.h"
13 #include "base/trace_event/trace_event.h" 13 #include "base/trace_event/trace_event.h"
14 #include "content/browser/devtools/service_worker_devtools_manager.h" 14 #include "content/browser/devtools/service_worker_devtools_manager.h"
15 #include "content/browser/service_worker/embedded_worker_registry.h" 15 #include "content/browser/service_worker/embedded_worker_registry.h"
16 #include "content/browser/service_worker/service_worker_context_core.h" 16 #include "content/browser/service_worker/service_worker_context_core.h"
17 #include "content/common/content_switches_internal.h" 17 #include "content/common/content_switches_internal.h"
18 #include "content/common/mojo/service_registry_impl.h" 18 #include "content/common/mojo/service_registry_impl.h"
19 #include "content/common/service_worker/embedded_worker_messages.h" 19 #include "content/common/service_worker/embedded_worker_messages.h"
20 #include "content/common/service_worker/embedded_worker_setup.mojom.h" 20 #include "content/common/service_worker/embedded_worker_setup.mojom.h"
21 #include "content/common/service_worker/service_worker_types.h" 21 #include "content/common/service_worker/service_worker_types.h"
22 #include "content/public/browser/browser_thread.h" 22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/render_process_host.h" 23 #include "content/public/browser/render_process_host.h"
24 #include "ipc/ipc_message.h" 24 #include "ipc/ipc_message.h"
25 #include "mojo/common/url_type_converters.h"
25 #include "url/gurl.h" 26 #include "url/gurl.h"
26 27
27 namespace content { 28 namespace content {
28 29
29 namespace { 30 namespace {
30 31
31 // Functor to sort by the .second element of a struct. 32 // Functor to sort by the .second element of a struct.
32 struct SecondGreater { 33 struct SecondGreater {
33 template <typename Value> 34 template <typename Value>
34 bool operator()(const Value& lhs, const Value& rhs) { 35 bool operator()(const Value& lhs, const Value& rhs) {
(...skipping 13 matching lines...) Expand all
48 ServiceWorkerDevToolsManager::GetInstance()->WorkerDestroyed( 49 ServiceWorkerDevToolsManager::GetInstance()->WorkerDestroyed(
49 worker_process_id, worker_route_id); 50 worker_process_id, worker_route_id);
50 } 51 }
51 52
52 void NotifyWorkerStopIgnoredOnUI(int worker_process_id, int worker_route_id) { 53 void NotifyWorkerStopIgnoredOnUI(int worker_process_id, int worker_route_id) {
53 DCHECK_CURRENTLY_ON(BrowserThread::UI); 54 DCHECK_CURRENTLY_ON(BrowserThread::UI);
54 ServiceWorkerDevToolsManager::GetInstance()->WorkerStopIgnored( 55 ServiceWorkerDevToolsManager::GetInstance()->WorkerStopIgnored(
55 worker_process_id, worker_route_id); 56 worker_process_id, worker_route_id);
56 } 57 }
57 58
58 void RegisterToWorkerDevToolsManagerOnUI( 59 /*void RegisterToWorkerDevToolsManagerOnUI(
59 int process_id, 60 int process_id,
60 const ServiceWorkerContextCore* service_worker_context, 61 const ServiceWorkerContextCore* service_worker_context,
61 const base::WeakPtr<ServiceWorkerContextCore>& service_worker_context_weak, 62 const base::WeakPtr<ServiceWorkerContextCore>& service_worker_context_weak,
62 int64 service_worker_version_id, 63 int64 service_worker_version_id,
63 const GURL& url, 64 const GURL& url,
64 const base::Callback<void(int worker_devtools_agent_route_id, 65 const base::Callback<void(int worker_devtools_agent_route_id,
65 bool wait_for_debugger)>& callback) { 66 bool wait_for_debugger)>& callback) {
66 DCHECK_CURRENTLY_ON(BrowserThread::UI); 67 DCHECK_CURRENTLY_ON(BrowserThread::UI);
67 int worker_devtools_agent_route_id = MSG_ROUTING_NONE; 68 int worker_devtools_agent_route_id = MSG_ROUTING_NONE;
68 bool wait_for_debugger = false; 69 bool wait_for_debugger = false;
69 if (RenderProcessHost* rph = RenderProcessHost::FromID(process_id)) { 70 if (RenderProcessHost* rph = RenderProcessHost::FromID(process_id)) {
70 // |rph| may be NULL in unit tests. 71 // |rph| may be NULL in unit tests.
71 worker_devtools_agent_route_id = rph->GetNextRoutingID(); 72 worker_devtools_agent_route_id = rph->GetNextRoutingID();
72 wait_for_debugger = 73 wait_for_debugger =
73 ServiceWorkerDevToolsManager::GetInstance()->WorkerCreated( 74 ServiceWorkerDevToolsManager::GetInstance()->WorkerCreated(
74 process_id, 75 process_id,
75 worker_devtools_agent_route_id, 76 worker_devtools_agent_route_id,
76 ServiceWorkerDevToolsManager::ServiceWorkerIdentifier( 77 ServiceWorkerDevToolsManager::ServiceWorkerIdentifier(
77 service_worker_context, 78 service_worker_context,
78 service_worker_context_weak, 79 service_worker_context_weak,
79 service_worker_version_id, 80 service_worker_version_id,
80 url)); 81 url));
81 } 82 }
82 BrowserThread::PostTask( 83 BrowserThread::PostTask(
83 BrowserThread::IO, 84 BrowserThread::IO,
84 FROM_HERE, 85 FROM_HERE,
85 base::Bind(callback, worker_devtools_agent_route_id, wait_for_debugger)); 86 base::Bind(callback, worker_devtools_agent_route_id, wait_for_debugger));
86 } 87 }
88 */
89 void RegisterToWorkerDevToolsManagerAndConnectToWorkerOnUI(
90 int process_id,
91 const ServiceWorkerContextCore* service_worker_context,
92 const base::WeakPtr<ServiceWorkerContextCore>& service_worker_context_weak,
93 int64 service_worker_version_id,
94 const GURL& url,
95 mojo::InterfaceRequest<EmbeddedWorker> embedded_worker,
96 const base::Callback<void(int worker_devtools_agent_route_id,
97 bool wait_for_debugger)>& callback) {
98 DCHECK_CURRENTLY_ON(BrowserThread::UI);
99 int worker_devtools_agent_route_id = MSG_ROUTING_NONE;
100 bool wait_for_debugger = false;
101 if (RenderProcessHost* rph = RenderProcessHost::FromID(process_id)) {
102 // |rph| may be NULL in unit tests.
103 worker_devtools_agent_route_id = rph->GetNextRoutingID();
104 wait_for_debugger =
105 ServiceWorkerDevToolsManager::GetInstance()->WorkerCreated(
106 process_id, worker_devtools_agent_route_id,
107 ServiceWorkerDevToolsManager::ServiceWorkerIdentifier(
108 service_worker_context, service_worker_context_weak,
109 service_worker_version_id, url));
110 rph->GetServiceRegistry()->ConnectToRemoteService(embedded_worker.Pass());
111 }
112 BrowserThread::PostTask(
113 BrowserThread::IO, FROM_HERE,
114 base::Bind(callback, worker_devtools_agent_route_id, wait_for_debugger));
115 }
87 116
88 void SetupMojoOnUIThread(int process_id, 117 void SetupMojoOnUIThread(int process_id,
89 int thread_id, 118 int thread_id,
90 mojo::InterfaceRequest<mojo::ServiceProvider> services, 119 mojo::InterfaceRequest<mojo::ServiceProvider> services,
91 mojo::ServiceProviderPtr exposed_services) { 120 mojo::ServiceProviderPtr exposed_services) {
92 RenderProcessHost* rph = RenderProcessHost::FromID(process_id); 121 RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
93 // |rph| may be NULL in unit tests. 122 // |rph| may be NULL in unit tests.
94 if (!rph) 123 if (!rph)
95 return; 124 return;
96 EmbeddedWorkerSetupPtr setup; 125 EmbeddedWorkerSetupPtr setup;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 if (!context_) { 184 if (!context_) {
156 callback.Run(SERVICE_WORKER_ERROR_ABORT); 185 callback.Run(SERVICE_WORKER_ERROR_ABORT);
157 return; 186 return;
158 } 187 }
159 DCHECK(status_ == STOPPED); 188 DCHECK(status_ == STOPPED);
160 start_timing_ = base::TimeTicks::Now(); 189 start_timing_ = base::TimeTicks::Now();
161 status_ = STARTING; 190 status_ = STARTING;
162 starting_phase_ = ALLOCATING_PROCESS; 191 starting_phase_ = ALLOCATING_PROCESS;
163 network_accessed_for_script_ = false; 192 network_accessed_for_script_ = false;
164 FOR_EACH_OBSERVER(Listener, listener_list_, OnStarting()); 193 FOR_EACH_OBSERVER(Listener, listener_list_, OnStarting());
165 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( 194 EmbeddedWorkerStartWorkerParamsPtr params =
166 new EmbeddedWorkerMsg_StartWorker_Params()); 195 EmbeddedWorkerStartWorkerParams::New();
167 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker", 196 TRACE_EVENT_ASYNC_BEGIN2("ServiceWorker",
168 "EmbeddedWorkerInstance::ProcessAllocate", 197 "EmbeddedWorkerInstance::ProcessAllocate",
169 params.get(), 198 params.get(),
170 "Scope", scope.spec(), 199 "Scope", scope.spec(),
171 "Script URL", script_url.spec()); 200 "Script URL", script_url.spec());
172 params->embedded_worker_id = embedded_worker_id_; 201 params->embedded_worker_id = embedded_worker_id_;
173 params->service_worker_version_id = service_worker_version_id; 202 params->service_worker_version_id = service_worker_version_id;
174 params->scope = scope; 203 params->scope = mojo::String::From(scope);
175 params->script_url = script_url; 204 params->script_url = mojo::String::From(script_url);
176 params->worker_devtools_agent_route_id = MSG_ROUTING_NONE; 205 params->worker_devtools_agent_route_id = MSG_ROUTING_NONE;
177 params->wait_for_debugger = false; 206 params->wait_for_debugger = false;
178 params->v8_cache_options = GetV8CacheOptions(); 207 params->v8_cache_options = GetV8CacheOptions();
179 context_->process_manager()->AllocateWorkerProcess( 208 context_->process_manager()->AllocateWorkerProcess(
180 embedded_worker_id_, 209 embedded_worker_id_, scope, script_url,
181 scope,
182 script_url,
183 base::Bind(&EmbeddedWorkerInstance::RunProcessAllocated, 210 base::Bind(&EmbeddedWorkerInstance::RunProcessAllocated,
184 weak_factory_.GetWeakPtr(), 211 weak_factory_.GetWeakPtr(), context_, base::Passed(&params),
185 context_,
186 base::Passed(&params),
187 callback)); 212 callback));
188 } 213 }
189 214
190 ServiceWorkerStatusCode EmbeddedWorkerInstance::Stop() { 215 ServiceWorkerStatusCode EmbeddedWorkerInstance::Stop() {
191 DCHECK(status_ == STARTING || status_ == RUNNING) << status_; 216 DCHECK(status_ == STARTING || status_ == RUNNING) << status_;
192 ServiceWorkerStatusCode status = 217 ServiceWorkerStatusCode status = SERVICE_WORKER_OK;
193 registry_->StopWorker(process_id_, embedded_worker_id_); 218 // registry_->StopWorker(process_id_, embedded_worker_id_);
219 worker_.reset();
194 // StopWorker could fail if we can't talk to the worker, which should 220 // StopWorker could fail if we can't talk to the worker, which should
195 // basically means it's being terminated, so unconditionally change 221 // basically means it's being terminated, so unconditionally change
196 // the status to STOPPING. 222 // the status to STOPPING.
197 status_ = STOPPING; 223 status_ = STOPPING;
198 FOR_EACH_OBSERVER(Listener, listener_list_, OnStopping()); 224 FOR_EACH_OBSERVER(Listener, listener_list_, OnStopping());
199 return status; 225 return status;
200 } 226 }
201 227
202 void EmbeddedWorkerInstance::StopIfIdle() { 228 void EmbeddedWorkerInstance::StopIfIdle() {
203 if (devtools_attached_) { 229 if (devtools_attached_) {
(...skipping 30 matching lines...) Expand all
234 thread_id_(kInvalidEmbeddedWorkerThreadId), 260 thread_id_(kInvalidEmbeddedWorkerThreadId),
235 devtools_attached_(false), 261 devtools_attached_(false),
236 network_accessed_for_script_(false), 262 network_accessed_for_script_(false),
237 weak_factory_(this) { 263 weak_factory_(this) {
238 } 264 }
239 265
240 // static 266 // static
241 void EmbeddedWorkerInstance::RunProcessAllocated( 267 void EmbeddedWorkerInstance::RunProcessAllocated(
242 base::WeakPtr<EmbeddedWorkerInstance> instance, 268 base::WeakPtr<EmbeddedWorkerInstance> instance,
243 base::WeakPtr<ServiceWorkerContextCore> context, 269 base::WeakPtr<ServiceWorkerContextCore> context,
244 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, 270 EmbeddedWorkerStartWorkerParamsPtr params,
245 const EmbeddedWorkerInstance::StatusCallback& callback, 271 const EmbeddedWorkerInstance::StatusCallback& callback,
246 ServiceWorkerStatusCode status, 272 ServiceWorkerStatusCode status,
247 int process_id, 273 int process_id,
248 bool is_new_process) { 274 bool is_new_process) {
249 if (!context) { 275 if (!context) {
250 callback.Run(SERVICE_WORKER_ERROR_ABORT); 276 callback.Run(SERVICE_WORKER_ERROR_ABORT);
251 return; 277 return;
252 } 278 }
253 if (!instance) { 279 if (!instance) {
254 if (status == SERVICE_WORKER_OK) { 280 if (status == SERVICE_WORKER_OK) {
255 // We only have a process allocated if the status is OK. 281 // We only have a process allocated if the status is OK.
256 context->process_manager()->ReleaseWorkerProcess( 282 context->process_manager()->ReleaseWorkerProcess(
257 params->embedded_worker_id); 283 params->embedded_worker_id);
258 } 284 }
259 callback.Run(SERVICE_WORKER_ERROR_ABORT); 285 callback.Run(SERVICE_WORKER_ERROR_ABORT);
260 return; 286 return;
261 } 287 }
262 instance->ProcessAllocated(params.Pass(), callback, process_id, 288 instance->ProcessAllocated(params.Pass(), callback, process_id,
263 is_new_process, status); 289 is_new_process, status);
264 } 290 }
265 291
266 void EmbeddedWorkerInstance::ProcessAllocated( 292 void EmbeddedWorkerInstance::ProcessAllocated(
267 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, 293 EmbeddedWorkerStartWorkerParamsPtr params,
268 const StatusCallback& callback, 294 const StatusCallback& callback,
269 int process_id, 295 int process_id,
270 bool is_new_process, 296 bool is_new_process,
271 ServiceWorkerStatusCode status) { 297 ServiceWorkerStatusCode status) {
272 DCHECK_EQ(process_id_, -1); 298 DCHECK_EQ(process_id_, -1);
273 TRACE_EVENT_ASYNC_END1("ServiceWorker", 299 TRACE_EVENT_ASYNC_END1("ServiceWorker",
274 "EmbeddedWorkerInstance::ProcessAllocate", 300 "EmbeddedWorkerInstance::ProcessAllocate",
275 params.get(), 301 params.get(),
276 "Status", status); 302 "Status", status);
277 if (status != SERVICE_WORKER_OK) { 303 if (status != SERVICE_WORKER_OK) {
278 Status old_status = status_; 304 Status old_status = status_;
279 status_ = STOPPED; 305 status_ = STOPPED;
280 callback.Run(status); 306 callback.Run(status);
281 FOR_EACH_OBSERVER(Listener, listener_list_, OnStopped(old_status)); 307 FOR_EACH_OBSERVER(Listener, listener_list_, OnStopped(old_status));
282 return; 308 return;
283 } 309 }
284 const int64 service_worker_version_id = params->service_worker_version_id; 310 const int64 service_worker_version_id = params->service_worker_version_id;
285 process_id_ = process_id; 311 process_id_ = process_id;
286 GURL script_url(params->script_url); 312 GURL script_url(params->script_url);
287 313
288 // Register this worker to DevToolsManager on UI thread, then continue to 314 // Register this worker to DevToolsManager on UI thread, then continue to
289 // call SendStartWorker on IO thread. 315 // call SendStartWorker on IO thread.
290 starting_phase_ = REGISTERING_TO_DEVTOOLS; 316 starting_phase_ = REGISTERING_TO_DEVTOOLS;
317 mojo::InterfaceRequest<EmbeddedWorker> request = mojo::GetProxy(&worker_);
291 BrowserThread::PostTask( 318 BrowserThread::PostTask(
292 BrowserThread::UI, FROM_HERE, 319 BrowserThread::UI, FROM_HERE,
293 base::Bind(RegisterToWorkerDevToolsManagerOnUI, process_id_, 320 base::Bind(RegisterToWorkerDevToolsManagerAndConnectToWorkerOnUI,
294 context_.get(), context_, service_worker_version_id, 321 process_id_, context_.get(), context_,
295 script_url, 322 service_worker_version_id, script_url, base::Passed(&request),
296 base::Bind(&EmbeddedWorkerInstance::SendStartWorker, 323 base::Bind(&EmbeddedWorkerInstance::SendStartWorker,
297 weak_factory_.GetWeakPtr(), base::Passed(&params), 324 weak_factory_.GetWeakPtr(), base::Passed(&params),
298 callback, is_new_process))); 325 callback, is_new_process)));
299 } 326 }
300 327
301 void EmbeddedWorkerInstance::SendStartWorker( 328 void EmbeddedWorkerInstance::SendStartWorker(
302 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, 329 EmbeddedWorkerStartWorkerParamsPtr params,
303 const StatusCallback& callback, 330 const StatusCallback& callback,
304 bool is_new_process, 331 bool is_new_process,
305 int worker_devtools_agent_route_id, 332 int worker_devtools_agent_route_id,
306 bool wait_for_debugger) { 333 bool wait_for_debugger) {
307 if (worker_devtools_agent_route_id != MSG_ROUTING_NONE) { 334 if (worker_devtools_agent_route_id != MSG_ROUTING_NONE) {
308 DCHECK(!devtools_proxy_); 335 DCHECK(!devtools_proxy_);
309 devtools_proxy_.reset(new DevToolsProxy(process_id_, 336 devtools_proxy_.reset(
310 worker_devtools_agent_route_id)); 337 new DevToolsProxy(process_id_, worker_devtools_agent_route_id));
311 } 338 }
312 params->worker_devtools_agent_route_id = worker_devtools_agent_route_id; 339 params->worker_devtools_agent_route_id = worker_devtools_agent_route_id;
313 params->wait_for_debugger = wait_for_debugger; 340 params->wait_for_debugger = wait_for_debugger;
314 if (params->wait_for_debugger) { 341 if (params->wait_for_debugger) {
315 // We don't measure the start time when wait_for_debugger flag is set. So we 342 // We don't measure the start time when wait_for_debugger flag is set. So we
316 // set the NULL time here. 343 // set the NULL time here.
317 start_timing_ = base::TimeTicks(); 344 start_timing_ = base::TimeTicks();
318 } else { 345 } else {
319 DCHECK(!start_timing_.is_null()); 346 DCHECK(!start_timing_.is_null());
320 if (is_new_process) { 347 if (is_new_process) {
321 UMA_HISTOGRAM_TIMES("EmbeddedWorkerInstance.NewProcessAllocation", 348 UMA_HISTOGRAM_TIMES("EmbeddedWorkerInstance.NewProcessAllocation",
322 base::TimeTicks::Now() - start_timing_); 349 base::TimeTicks::Now() - start_timing_);
323 } else { 350 } else {
324 UMA_HISTOGRAM_TIMES("EmbeddedWorkerInstance.ExistingProcessAllocation", 351 UMA_HISTOGRAM_TIMES("EmbeddedWorkerInstance.ExistingProcessAllocation",
325 base::TimeTicks::Now() - start_timing_); 352 base::TimeTicks::Now() - start_timing_);
326 } 353 }
327 UMA_HISTOGRAM_BOOLEAN("EmbeddedWorkerInstance.ProcessCreated", 354 UMA_HISTOGRAM_BOOLEAN("EmbeddedWorkerInstance.ProcessCreated",
328 is_new_process); 355 is_new_process);
329 // Reset |start_timing_| to measure the time excluding the process 356 // Reset |start_timing_| to measure the time excluding the process
330 // allocation time. 357 // allocation time.
331 start_timing_ = base::TimeTicks::Now(); 358 start_timing_ = base::TimeTicks::Now();
332 } 359 }
333 360
334 starting_phase_ = SENT_START_WORKER; 361 starting_phase_ = SENT_START_WORKER;
335 ServiceWorkerStatusCode status = 362 registry_->WorkerStarting(embedded_worker_id_, process_id_);
336 registry_->SendStartWorker(params.Pass(), process_id_); 363 worker_->Initialize(params.Pass());
337 if (status != SERVICE_WORKER_OK) {
338 callback.Run(status);
339 return;
340 }
341 DCHECK(start_callback_.is_null()); 364 DCHECK(start_callback_.is_null());
342 start_callback_ = callback; 365 start_callback_ = callback;
343 } 366 }
344 367
345 void EmbeddedWorkerInstance::OnReadyForInspection() { 368 void EmbeddedWorkerInstance::OnReadyForInspection() {
346 if (devtools_proxy_) 369 if (devtools_proxy_)
347 devtools_proxy_->NotifyWorkerReadyForInspection(); 370 devtools_proxy_->NotifyWorkerReadyForInspection();
348 } 371 }
349 372
350 void EmbeddedWorkerInstance::OnScriptLoaded(int thread_id) { 373 void EmbeddedWorkerInstance::OnScriptLoaded(int thread_id) {
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 case SCRIPT_EVALUATED: 543 case SCRIPT_EVALUATED:
521 return "Script evaluated"; 544 return "Script evaluated";
522 case STARTING_PHASE_MAX_VALUE: 545 case STARTING_PHASE_MAX_VALUE:
523 NOTREACHED(); 546 NOTREACHED();
524 } 547 }
525 NOTREACHED() << phase; 548 NOTREACHED() << phase;
526 return std::string(); 549 return std::string();
527 } 550 }
528 551
529 } // namespace content 552 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698