Chromium Code Reviews| Index: content/browser/service_worker/embedded_worker_instance.cc |
| diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc |
| index 68e473dcebc15d57c5ee825054bcb4a78ba2ea23..0046b21ad86c6a7bee4f2821feaf696f86b291de 100644 |
| --- a/content/browser/service_worker/embedded_worker_instance.cc |
| +++ b/content/browser/service_worker/embedded_worker_instance.cc |
| @@ -155,6 +155,7 @@ void EmbeddedWorkerInstance::Start(int64 service_worker_version_id, |
| const StatusCallback& callback) { |
| if (!context_) { |
| callback.Run(SERVICE_WORKER_ERROR_ABORT); |
| + // |this| may be destroyed by the callback. |
| return; |
| } |
| DCHECK(status_ == STOPPED); |
| @@ -284,11 +285,7 @@ void EmbeddedWorkerInstance::ProcessAllocated( |
| params.get(), |
| "Status", status); |
| if (status != SERVICE_WORKER_OK) { |
| - Status old_status = status_; |
| - status_ = STOPPED; |
| - service_registry_.reset(); |
| - callback.Run(status); |
| - FOR_EACH_OBSERVER(Listener, listener_list_, OnStopped(old_status)); |
| + OnStartFailed(status, callback); |
| return; |
| } |
| const int64 service_worker_version_id = params->service_worker_version_id; |
| @@ -318,8 +315,11 @@ void EmbeddedWorkerInstance::SendStartWorker( |
| // process, making process_id_ and other state invalid. If that happened, |
| // abort instead of trying to send the IPC. |
| if (status_ != STARTING) { |
| - callback.Run(SERVICE_WORKER_ERROR_ABORT); |
| + // Don't call OnStartFailed() since it calls OnStopped() which may have |
| + // 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
|
| ReleaseProcess(); |
| + callback.Run(SERVICE_WORKER_ERROR_ABORT); |
| + // |this| may be destroyed by the callback. |
| return; |
| } |
| @@ -354,7 +354,7 @@ void EmbeddedWorkerInstance::SendStartWorker( |
| ServiceWorkerStatusCode status = |
| registry_->SendStartWorker(params.Pass(), process_id_); |
| if (status != SERVICE_WORKER_OK) { |
| - callback.Run(status); |
| + OnStartFailed(status, callback); |
| return; |
| } |
| DCHECK(start_callback_.is_null()); |
| @@ -410,9 +410,11 @@ void EmbeddedWorkerInstance::OnScriptEvaluated(bool success) { |
| UMA_HISTOGRAM_TIMES("EmbeddedWorkerInstance.ScriptEvaluate", |
| base::TimeTicks::Now() - start_timing_); |
| } |
| - start_callback_.Run(success ? SERVICE_WORKER_OK |
| - : SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED); |
| + StatusCallback callback = start_callback_; |
| start_callback_.Reset(); |
| + callback.Run(success ? SERVICE_WORKER_OK |
| + : SERVICE_WORKER_ERROR_SCRIPT_EVALUATE_FAILED); |
| + // |this| may be destroyed by the callback. |
| } |
| void EmbeddedWorkerInstance::OnStarted() { |
| @@ -504,6 +506,15 @@ void EmbeddedWorkerInstance::ReleaseProcess() { |
| start_callback_.Reset(); |
| } |
| +void EmbeddedWorkerInstance::OnStartFailed(ServiceWorkerStatusCode status, |
| + const StatusCallback& callback) { |
| + ReleaseProcess(); |
| + base::WeakPtr<EmbeddedWorkerInstance> weak_this = weak_factory_.GetWeakPtr(); |
| + callback.Run(status); |
| + if (weak_this) |
| + FOR_EACH_OBSERVER(Listener, listener_list_, OnStopped(STARTING)); |
| +} |
| + |
| // static |
| std::string EmbeddedWorkerInstance::StatusToString(Status status) { |
| switch (status) { |