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

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

Issue 1327723005: Fix crash during EmbeddedWorkerInstance startup sequence failures (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: added unittests Created 5 years, 3 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 <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_); 148 context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_);
149 registry_->RemoveWorker(process_id_, embedded_worker_id_); 149 registry_->RemoveWorker(process_id_, embedded_worker_id_);
150 } 150 }
151 151
152 void EmbeddedWorkerInstance::Start(int64 service_worker_version_id, 152 void EmbeddedWorkerInstance::Start(int64 service_worker_version_id,
153 const GURL& scope, 153 const GURL& scope,
154 const GURL& script_url, 154 const GURL& script_url,
155 const StatusCallback& callback) { 155 const StatusCallback& callback) {
156 if (!context_) { 156 if (!context_) {
157 callback.Run(SERVICE_WORKER_ERROR_ABORT); 157 callback.Run(SERVICE_WORKER_ERROR_ABORT);
158 // |this| may be destroyed by the callback.
158 return; 159 return;
159 } 160 }
160 DCHECK(status_ == STOPPED); 161 DCHECK(status_ == STOPPED);
161 start_timing_ = base::TimeTicks::Now(); 162 start_timing_ = base::TimeTicks::Now();
162 status_ = STARTING; 163 status_ = STARTING;
163 starting_phase_ = ALLOCATING_PROCESS; 164 starting_phase_ = ALLOCATING_PROCESS;
164 network_accessed_for_script_ = false; 165 network_accessed_for_script_ = false;
165 service_registry_.reset(new ServiceRegistryImpl()); 166 service_registry_.reset(new ServiceRegistryImpl());
166 FOR_EACH_OBSERVER(Listener, listener_list_, OnStarting()); 167 FOR_EACH_OBSERVER(Listener, listener_list_, OnStarting());
167 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params( 168 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params(
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 const StatusCallback& callback, 278 const StatusCallback& callback,
278 int process_id, 279 int process_id,
279 bool is_new_process, 280 bool is_new_process,
280 ServiceWorkerStatusCode status) { 281 ServiceWorkerStatusCode status) {
281 DCHECK_EQ(process_id_, -1); 282 DCHECK_EQ(process_id_, -1);
282 TRACE_EVENT_ASYNC_END1("ServiceWorker", 283 TRACE_EVENT_ASYNC_END1("ServiceWorker",
283 "EmbeddedWorkerInstance::ProcessAllocate", 284 "EmbeddedWorkerInstance::ProcessAllocate",
284 params.get(), 285 params.get(),
285 "Status", status); 286 "Status", status);
286 if (status != SERVICE_WORKER_OK) { 287 if (status != SERVICE_WORKER_OK) {
287 Status old_status = status_; 288 OnStartFailed(status, callback);
288 status_ = STOPPED;
289 service_registry_.reset();
290 callback.Run(status);
291 FOR_EACH_OBSERVER(Listener, listener_list_, OnStopped(old_status));
292 return; 289 return;
293 } 290 }
294 const int64 service_worker_version_id = params->service_worker_version_id; 291 const int64 service_worker_version_id = params->service_worker_version_id;
295 process_id_ = process_id; 292 process_id_ = process_id;
296 GURL script_url(params->script_url); 293 GURL script_url(params->script_url);
297 294
298 // Register this worker to DevToolsManager on UI thread, then continue to 295 // Register this worker to DevToolsManager on UI thread, then continue to
299 // call SendStartWorker on IO thread. 296 // call SendStartWorker on IO thread.
300 starting_phase_ = REGISTERING_TO_DEVTOOLS; 297 starting_phase_ = REGISTERING_TO_DEVTOOLS;
301 BrowserThread::PostTask( 298 BrowserThread::PostTask(
302 BrowserThread::UI, FROM_HERE, 299 BrowserThread::UI, FROM_HERE,
303 base::Bind(RegisterToWorkerDevToolsManagerOnUI, process_id_, 300 base::Bind(RegisterToWorkerDevToolsManagerOnUI, process_id_,
304 context_.get(), context_, service_worker_version_id, 301 context_.get(), context_, service_worker_version_id,
305 script_url, 302 script_url,
306 base::Bind(&EmbeddedWorkerInstance::SendStartWorker, 303 base::Bind(&EmbeddedWorkerInstance::SendStartWorker,
307 weak_factory_.GetWeakPtr(), base::Passed(&params), 304 weak_factory_.GetWeakPtr(), base::Passed(&params),
308 callback, is_new_process))); 305 callback, is_new_process)));
309 } 306 }
310 307
311 void EmbeddedWorkerInstance::SendStartWorker( 308 void EmbeddedWorkerInstance::SendStartWorker(
312 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params, 309 scoped_ptr<EmbeddedWorkerMsg_StartWorker_Params> params,
313 const StatusCallback& callback, 310 const StatusCallback& callback,
314 bool is_new_process, 311 bool is_new_process,
315 int worker_devtools_agent_route_id, 312 int worker_devtools_agent_route_id,
316 bool wait_for_debugger) { 313 bool wait_for_debugger) {
317 // We may have been detached or stopped at some point during the start up 314 // We may have been detached or stopped at some point during the start up
318 // process, making process_id_ and other state invalid. If that happened, 315 // process, making process_id_ and other state invalid. If that happened,
319 // abort instead of trying to send the IPC. 316 // abort instead of trying to send the IPC.
320 if (status_ != STARTING) { 317 if (status_ != STARTING) {
318 // Don't call OnStartFailed() since it calls OnStopped() which may have
319 // already been called.
nhiroki 2015/09/11 04:33:02 The following code might work? // Here OnStartF
falken 2015/09/11 09:48:16 I like this, done, with the minor exception of cal
320 ReleaseProcess();
321 callback.Run(SERVICE_WORKER_ERROR_ABORT); 321 callback.Run(SERVICE_WORKER_ERROR_ABORT);
322 ReleaseProcess(); 322 // |this| may be destroyed by the callback.
323 return; 323 return;
324 } 324 }
325 325
326 if (worker_devtools_agent_route_id != MSG_ROUTING_NONE) { 326 if (worker_devtools_agent_route_id != MSG_ROUTING_NONE) {
327 DCHECK(!devtools_proxy_); 327 DCHECK(!devtools_proxy_);
328 devtools_proxy_.reset(new DevToolsProxy(process_id_, 328 devtools_proxy_.reset(new DevToolsProxy(process_id_,
329 worker_devtools_agent_route_id)); 329 worker_devtools_agent_route_id));
330 } 330 }
331 params->worker_devtools_agent_route_id = worker_devtools_agent_route_id; 331 params->worker_devtools_agent_route_id = worker_devtools_agent_route_id;
332 params->wait_for_debugger = wait_for_debugger; 332 params->wait_for_debugger = wait_for_debugger;
(...skipping 14 matching lines...) Expand all
347 is_new_process); 347 is_new_process);
348 // Reset |start_timing_| to measure the time excluding the process 348 // Reset |start_timing_| to measure the time excluding the process
349 // allocation time. 349 // allocation time.
350 start_timing_ = base::TimeTicks::Now(); 350 start_timing_ = base::TimeTicks::Now();
351 } 351 }
352 352
353 starting_phase_ = SENT_START_WORKER; 353 starting_phase_ = SENT_START_WORKER;
354 ServiceWorkerStatusCode status = 354 ServiceWorkerStatusCode status =
355 registry_->SendStartWorker(params.Pass(), process_id_); 355 registry_->SendStartWorker(params.Pass(), process_id_);
356 if (status != SERVICE_WORKER_OK) { 356 if (status != SERVICE_WORKER_OK) {
357 callback.Run(status); 357 OnStartFailed(status, callback);
358 return; 358 return;
359 } 359 }
360 DCHECK(start_callback_.is_null()); 360 DCHECK(start_callback_.is_null());
361 start_callback_ = callback; 361 start_callback_ = callback;
362 } 362 }
363 363
364 void EmbeddedWorkerInstance::OnReadyForInspection() { 364 void EmbeddedWorkerInstance::OnReadyForInspection() {
365 if (devtools_proxy_) 365 if (devtools_proxy_)
366 devtools_proxy_->NotifyWorkerReadyForInspection(); 366 devtools_proxy_->NotifyWorkerReadyForInspection();
367 } 367 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 void EmbeddedWorkerInstance::OnScriptEvaluated(bool success) { 403 void EmbeddedWorkerInstance::OnScriptEvaluated(bool success) {
404 starting_phase_ = SCRIPT_EVALUATED; 404 starting_phase_ = SCRIPT_EVALUATED;
405 if (start_callback_.is_null()) { 405 if (start_callback_.is_null()) {
406 DVLOG(1) << "Received unexpected OnScriptEvaluated message."; 406 DVLOG(1) << "Received unexpected OnScriptEvaluated message.";
407 return; 407 return;
408 } 408 }
409 if (success && !start_timing_.is_null()) { 409 if (success && !start_timing_.is_null()) {
410 UMA_HISTOGRAM_TIMES("EmbeddedWorkerInstance.ScriptEvaluate", 410 UMA_HISTOGRAM_TIMES("EmbeddedWorkerInstance.ScriptEvaluate",
411 base::TimeTicks::Now() - start_timing_); 411 base::TimeTicks::Now() - start_timing_);
412 } 412 }
413 start_callback_.Run(success ? SERVICE_WORKER_OK 413 StatusCallback callback = start_callback_;
414 : SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED);
415 start_callback_.Reset(); 414 start_callback_.Reset();
415 callback.Run(success ? SERVICE_WORKER_OK
416 : SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED);
417 // |this| may be destroyed by the callback.
416 } 418 }
417 419
418 void EmbeddedWorkerInstance::OnStarted() { 420 void EmbeddedWorkerInstance::OnStarted() {
419 // Stop is requested before OnStarted is sent back from the worker. 421 // Stop is requested before OnStarted is sent back from the worker.
420 if (status_ == STOPPING) 422 if (status_ == STOPPING)
421 return; 423 return;
422 DCHECK(status_ == STARTING); 424 DCHECK(status_ == STARTING);
423 status_ = RUNNING; 425 status_ = RUNNING;
424 FOR_EACH_OBSERVER(Listener, listener_list_, OnStarted()); 426 FOR_EACH_OBSERVER(Listener, listener_list_, OnStarted());
425 } 427 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 devtools_proxy_.reset(); 499 devtools_proxy_.reset();
498 if (context_ && process_id_ != -1) 500 if (context_ && process_id_ != -1)
499 context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_); 501 context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_);
500 status_ = STOPPED; 502 status_ = STOPPED;
501 process_id_ = -1; 503 process_id_ = -1;
502 thread_id_ = -1; 504 thread_id_ = -1;
503 service_registry_.reset(); 505 service_registry_.reset();
504 start_callback_.Reset(); 506 start_callback_.Reset();
505 } 507 }
506 508
509 void EmbeddedWorkerInstance::OnStartFailed(ServiceWorkerStatusCode status,
510 const StatusCallback& callback) {
511 ReleaseProcess();
512 base::WeakPtr<EmbeddedWorkerInstance> weak_this = weak_factory_.GetWeakPtr();
513 callback.Run(status);
514 if (weak_this)
515 FOR_EACH_OBSERVER(Listener, listener_list_, OnStopped(STARTING));
516 }
517
507 // static 518 // static
508 std::string EmbeddedWorkerInstance::StatusToString(Status status) { 519 std::string EmbeddedWorkerInstance::StatusToString(Status status) {
509 switch (status) { 520 switch (status) {
510 case STOPPED: 521 case STOPPED:
511 return "STOPPED"; 522 return "STOPPED";
512 case STARTING: 523 case STARTING:
513 return "STARTING"; 524 return "STARTING";
514 case RUNNING: 525 case RUNNING:
515 return "RUNNING"; 526 return "RUNNING";
516 case STOPPING: 527 case STOPPING:
(...skipping 21 matching lines...) Expand all
538 case SCRIPT_EVALUATED: 549 case SCRIPT_EVALUATED:
539 return "Script evaluated"; 550 return "Script evaluated";
540 case STARTING_PHASE_MAX_VALUE: 551 case STARTING_PHASE_MAX_VALUE:
541 NOTREACHED(); 552 NOTREACHED();
542 } 553 }
543 NOTREACHED() << phase; 554 NOTREACHED() << phase;
544 return std::string(); 555 return std::string();
545 } 556 }
546 557
547 } // namespace content 558 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698