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

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: fix asan 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(callback, status);
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) {
321 callback.Run(SERVICE_WORKER_ERROR_ABORT); 318 OnStartFailed(callback, SERVICE_WORKER_ERROR_ABORT);
322 ReleaseProcess();
323 return; 319 return;
324 } 320 }
325 321
326 if (worker_devtools_agent_route_id != MSG_ROUTING_NONE) { 322 if (worker_devtools_agent_route_id != MSG_ROUTING_NONE) {
327 DCHECK(!devtools_proxy_); 323 DCHECK(!devtools_proxy_);
328 devtools_proxy_.reset(new DevToolsProxy(process_id_, 324 devtools_proxy_.reset(new DevToolsProxy(process_id_,
329 worker_devtools_agent_route_id)); 325 worker_devtools_agent_route_id));
330 } 326 }
331 params->worker_devtools_agent_route_id = worker_devtools_agent_route_id; 327 params->worker_devtools_agent_route_id = worker_devtools_agent_route_id;
332 params->wait_for_debugger = wait_for_debugger; 328 params->wait_for_debugger = wait_for_debugger;
(...skipping 14 matching lines...) Expand all
347 is_new_process); 343 is_new_process);
348 // Reset |start_timing_| to measure the time excluding the process 344 // Reset |start_timing_| to measure the time excluding the process
349 // allocation time. 345 // allocation time.
350 start_timing_ = base::TimeTicks::Now(); 346 start_timing_ = base::TimeTicks::Now();
351 } 347 }
352 348
353 starting_phase_ = SENT_START_WORKER; 349 starting_phase_ = SENT_START_WORKER;
354 ServiceWorkerStatusCode status = 350 ServiceWorkerStatusCode status =
355 registry_->SendStartWorker(params.Pass(), process_id_); 351 registry_->SendStartWorker(params.Pass(), process_id_);
356 if (status != SERVICE_WORKER_OK) { 352 if (status != SERVICE_WORKER_OK) {
357 callback.Run(status); 353 OnStartFailed(callback, status);
nhiroki 2015/09/17 06:14:13 I guess this could fix issue 531345. Before this p
358 return; 354 return;
359 } 355 }
360 DCHECK(start_callback_.is_null()); 356 DCHECK(start_callback_.is_null());
361 start_callback_ = callback; 357 start_callback_ = callback;
362 } 358 }
363 359
364 void EmbeddedWorkerInstance::OnReadyForInspection() { 360 void EmbeddedWorkerInstance::OnReadyForInspection() {
365 if (devtools_proxy_) 361 if (devtools_proxy_)
366 devtools_proxy_->NotifyWorkerReadyForInspection(); 362 devtools_proxy_->NotifyWorkerReadyForInspection();
367 } 363 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 void EmbeddedWorkerInstance::OnScriptEvaluated(bool success) { 399 void EmbeddedWorkerInstance::OnScriptEvaluated(bool success) {
404 starting_phase_ = SCRIPT_EVALUATED; 400 starting_phase_ = SCRIPT_EVALUATED;
405 if (start_callback_.is_null()) { 401 if (start_callback_.is_null()) {
406 DVLOG(1) << "Received unexpected OnScriptEvaluated message."; 402 DVLOG(1) << "Received unexpected OnScriptEvaluated message.";
407 return; 403 return;
408 } 404 }
409 if (success && !start_timing_.is_null()) { 405 if (success && !start_timing_.is_null()) {
410 UMA_HISTOGRAM_TIMES("EmbeddedWorkerInstance.ScriptEvaluate", 406 UMA_HISTOGRAM_TIMES("EmbeddedWorkerInstance.ScriptEvaluate",
411 base::TimeTicks::Now() - start_timing_); 407 base::TimeTicks::Now() - start_timing_);
412 } 408 }
413 start_callback_.Run(success ? SERVICE_WORKER_OK 409 StatusCallback callback = start_callback_;
414 : SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED);
415 start_callback_.Reset(); 410 start_callback_.Reset();
411 callback.Run(success ? SERVICE_WORKER_OK
412 : SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED);
413 // |this| may be destroyed by the callback.
416 } 414 }
417 415
418 void EmbeddedWorkerInstance::OnStarted() { 416 void EmbeddedWorkerInstance::OnStarted() {
419 // Stop is requested before OnStarted is sent back from the worker. 417 // Stop is requested before OnStarted is sent back from the worker.
420 if (status_ == STOPPING) 418 if (status_ == STOPPING)
421 return; 419 return;
422 DCHECK(status_ == STARTING); 420 DCHECK(status_ == STARTING);
423 status_ = RUNNING; 421 status_ = RUNNING;
424 FOR_EACH_OBSERVER(Listener, listener_list_, OnStarted()); 422 FOR_EACH_OBSERVER(Listener, listener_list_, OnStarted());
425 } 423 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 devtools_proxy_.reset(); 495 devtools_proxy_.reset();
498 if (context_ && process_id_ != -1) 496 if (context_ && process_id_ != -1)
499 context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_); 497 context_->process_manager()->ReleaseWorkerProcess(embedded_worker_id_);
500 status_ = STOPPED; 498 status_ = STOPPED;
501 process_id_ = -1; 499 process_id_ = -1;
502 thread_id_ = -1; 500 thread_id_ = -1;
503 service_registry_.reset(); 501 service_registry_.reset();
504 start_callback_.Reset(); 502 start_callback_.Reset();
505 } 503 }
506 504
505 void EmbeddedWorkerInstance::OnStartFailed(const StatusCallback& callback,
506 ServiceWorkerStatusCode status) {
507 Status old_status = status_;
508 ReleaseProcess();
509 base::WeakPtr<EmbeddedWorkerInstance> weak_this = weak_factory_.GetWeakPtr();
510 callback.Run(status);
511 if (weak_this && old_status != STOPPED)
512 FOR_EACH_OBSERVER(Listener, weak_this->listener_list_,
513 OnStopped(old_status));
kinuko 2015/09/13 08:41:11 nit: would be better to update the comment for Lis
514 }
515
507 // static 516 // static
508 std::string EmbeddedWorkerInstance::StatusToString(Status status) { 517 std::string EmbeddedWorkerInstance::StatusToString(Status status) {
509 switch (status) { 518 switch (status) {
510 case STOPPED: 519 case STOPPED:
511 return "STOPPED"; 520 return "STOPPED";
512 case STARTING: 521 case STARTING:
513 return "STARTING"; 522 return "STARTING";
514 case RUNNING: 523 case RUNNING:
515 return "RUNNING"; 524 return "RUNNING";
516 case STOPPING: 525 case STOPPING:
(...skipping 21 matching lines...) Expand all
538 case SCRIPT_EVALUATED: 547 case SCRIPT_EVALUATED:
539 return "Script evaluated"; 548 return "Script evaluated";
540 case STARTING_PHASE_MAX_VALUE: 549 case STARTING_PHASE_MAX_VALUE:
541 NOTREACHED(); 550 NOTREACHED();
542 } 551 }
543 NOTREACHED() << phase; 552 NOTREACHED() << phase;
544 return std::string(); 553 return std::string();
545 } 554 }
546 555
547 } // namespace content 556 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698