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

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

Issue 739383002: Don't drop messages/events send to a service worker that is stopping. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@termnate_sw
Patch Set: Created 6 years, 1 month 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/service_worker_version.h" 5 #include "content/browser/service_worker/service_worker_version.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "base/strings/string16.h" 9 #include "base/strings/string16.h"
10 #include "content/browser/service_worker/embedded_worker_instance.h" 10 #include "content/browser/service_worker/embedded_worker_instance.h"
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 embedded_worker()->worker_devtools_agent_route_id()); 157 embedded_worker()->worker_devtools_agent_route_id());
158 } 158 }
159 159
160 void ServiceWorkerVersion::StartWorker(const StatusCallback& callback) { 160 void ServiceWorkerVersion::StartWorker(const StatusCallback& callback) {
161 StartWorker(false, callback); 161 StartWorker(false, callback);
162 } 162 }
163 163
164 void ServiceWorkerVersion::StartWorker( 164 void ServiceWorkerVersion::StartWorker(
165 bool pause_after_download, 165 bool pause_after_download,
166 const StatusCallback& callback) { 166 const StatusCallback& callback) {
167 if (is_doomed()) {
168 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED));
169 return;
170 }
167 switch (running_status()) { 171 switch (running_status()) {
168 case RUNNING: 172 case RUNNING:
169 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); 173 RunSoon(base::Bind(callback, SERVICE_WORKER_OK));
170 return; 174 return;
171 case STOPPING: 175 case STOPPING:
172 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED));
173 return;
174 case STOPPED: 176 case STOPPED:
175 case STARTING: 177 case STARTING:
176 start_callbacks_.push_back(callback); 178 start_callbacks_.push_back(callback);
177 if (running_status() == STOPPED) { 179 if (running_status() == STOPPED) {
178 DCHECK(!cache_listener_.get()); 180 DCHECK(!cache_listener_.get());
179 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_)); 181 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_));
180 embedded_worker_->Start( 182 embedded_worker_->Start(
181 version_id_, 183 version_id_,
182 scope_, 184 scope_,
183 script_url_, 185 script_url_,
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 void ServiceWorkerVersion::OnStarted() { 457 void ServiceWorkerVersion::OnStarted() {
456 DCHECK_EQ(RUNNING, running_status()); 458 DCHECK_EQ(RUNNING, running_status());
457 DCHECK(cache_listener_.get()); 459 DCHECK(cache_listener_.get());
458 if (status() == ACTIVATED && !HasControllee()) 460 if (status() == ACTIVATED && !HasControllee())
459 ScheduleStopWorker(); 461 ScheduleStopWorker();
460 // Fire all start callbacks. 462 // Fire all start callbacks.
461 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); 463 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK);
462 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this)); 464 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this));
463 } 465 }
464 466
465 void ServiceWorkerVersion::OnStopped() { 467 void ServiceWorkerVersion::OnStopped(
468 EmbeddedWorkerInstance::Status old_status) {
466 DCHECK_EQ(STOPPED, running_status()); 469 DCHECK_EQ(STOPPED, running_status());
467 scoped_refptr<ServiceWorkerVersion> protect(this); 470 scoped_refptr<ServiceWorkerVersion> protect(this);
468 471
472 bool should_restart = !is_doomed() && !start_callbacks_.empty() &&
473 (old_status != EmbeddedWorkerInstance::STARTING);
474
469 // Fire all stop callbacks. 475 // Fire all stop callbacks.
470 RunCallbacks(this, &stop_callbacks_, SERVICE_WORKER_OK); 476 RunCallbacks(this, &stop_callbacks_, SERVICE_WORKER_OK);
471 477
472 // Let all start callbacks fail. 478 if (!should_restart) {
473 RunCallbacks( 479 // Let all start callbacks fail.
474 this, &start_callbacks_, SERVICE_WORKER_ERROR_START_WORKER_FAILED); 480 RunCallbacks(this, &start_callbacks_,
481 SERVICE_WORKER_ERROR_START_WORKER_FAILED);
482 }
475 483
476 // Let all message callbacks fail (this will also fire and clear all 484 // Let all message callbacks fail (this will also fire and clear all
477 // callbacks for events). 485 // callbacks for events).
478 // TODO(kinuko): Consider if we want to add queue+resend mechanism here. 486 // TODO(kinuko): Consider if we want to add queue+resend mechanism here.
479 RunIDMapCallbacks(&activate_callbacks_, 487 RunIDMapCallbacks(&activate_callbacks_,
480 &StatusCallback::Run, 488 &StatusCallback::Run,
481 MakeTuple(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED)); 489 MakeTuple(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED));
482 RunIDMapCallbacks(&install_callbacks_, 490 RunIDMapCallbacks(&install_callbacks_,
483 &StatusCallback::Run, 491 &StatusCallback::Run,
484 MakeTuple(SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED)); 492 MakeTuple(SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED));
(...skipping 11 matching lines...) Expand all
496 RunIDMapCallbacks(&geofencing_callbacks_, 504 RunIDMapCallbacks(&geofencing_callbacks_,
497 &StatusCallback::Run, 505 &StatusCallback::Run,
498 MakeTuple(SERVICE_WORKER_ERROR_FAILED)); 506 MakeTuple(SERVICE_WORKER_ERROR_FAILED));
499 507
500 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this)); 508 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this));
501 509
502 // There should be no more communication from/to a stopped worker. Deleting 510 // There should be no more communication from/to a stopped worker. Deleting
503 // the listener prevents any pending completion callbacks from causing 511 // the listener prevents any pending completion callbacks from causing
504 // messages to be sent to the stopped worker. 512 // messages to be sent to the stopped worker.
505 cache_listener_.reset(); 513 cache_listener_.reset();
514
515 // Restart worker if we have any start callbacks and the worker isn't doomed.
516 if (should_restart) {
517 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_));
518 embedded_worker_->Start(
519 version_id_, scope_, script_url_, false /* pause_after_download */,
520 base::Bind(&ServiceWorkerVersion::OnStartMessageSent,
521 weak_factory_.GetWeakPtr()));
522 }
506 } 523 }
507 524
508 void ServiceWorkerVersion::OnReportException( 525 void ServiceWorkerVersion::OnReportException(
509 const base::string16& error_message, 526 const base::string16& error_message,
510 int line_number, 527 int line_number,
511 int column_number, 528 int column_number,
512 const GURL& source_url) { 529 const GURL& source_url) {
513 FOR_EACH_OBSERVER( 530 FOR_EACH_OBSERVER(
514 Listener, 531 Listener,
515 listeners_, 532 listeners_,
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 SetStatus(REDUNDANT); 770 SetStatus(REDUNDANT);
754 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 771 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
755 if (!context_) 772 if (!context_)
756 return; 773 return;
757 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; 774 std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
758 script_cache_map_.GetResources(&resources); 775 script_cache_map_.GetResources(&resources);
759 context_->storage()->PurgeResources(resources); 776 context_->storage()->PurgeResources(resources);
760 } 777 }
761 778
762 } // namespace content 779 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698