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

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: address nit Created 6 years 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/message_port_message_filter.h" 10 #include "content/browser/message_port_message_filter.h"
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 embedded_worker()->worker_devtools_agent_route_id()); 170 embedded_worker()->worker_devtools_agent_route_id());
171 } 171 }
172 172
173 void ServiceWorkerVersion::StartWorker(const StatusCallback& callback) { 173 void ServiceWorkerVersion::StartWorker(const StatusCallback& callback) {
174 StartWorker(false, callback); 174 StartWorker(false, callback);
175 } 175 }
176 176
177 void ServiceWorkerVersion::StartWorker( 177 void ServiceWorkerVersion::StartWorker(
178 bool pause_after_download, 178 bool pause_after_download,
179 const StatusCallback& callback) { 179 const StatusCallback& callback) {
180 if (is_doomed()) {
181 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED));
182 return;
183 }
180 switch (running_status()) { 184 switch (running_status()) {
181 case RUNNING: 185 case RUNNING:
182 RunSoon(base::Bind(callback, SERVICE_WORKER_OK)); 186 RunSoon(base::Bind(callback, SERVICE_WORKER_OK));
183 return; 187 return;
184 case STOPPING: 188 case STOPPING:
185 RunSoon(base::Bind(callback, SERVICE_WORKER_ERROR_START_WORKER_FAILED));
186 return;
187 case STOPPED: 189 case STOPPED:
188 case STARTING: 190 case STARTING:
189 start_callbacks_.push_back(callback); 191 start_callbacks_.push_back(callback);
190 if (running_status() == STOPPED) { 192 if (running_status() == STOPPED) {
191 DCHECK(!cache_listener_.get()); 193 DCHECK(!cache_listener_.get());
192 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_)); 194 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_));
193 embedded_worker_->Start( 195 embedded_worker_->Start(
194 version_id_, 196 version_id_,
195 scope_, 197 scope_,
196 script_url_, 198 script_url_,
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 void ServiceWorkerVersion::OnStarted() { 538 void ServiceWorkerVersion::OnStarted() {
537 DCHECK_EQ(RUNNING, running_status()); 539 DCHECK_EQ(RUNNING, running_status());
538 DCHECK(cache_listener_.get()); 540 DCHECK(cache_listener_.get());
539 if (status() == ACTIVATED && !HasControllee()) 541 if (status() == ACTIVATED && !HasControllee())
540 ScheduleStopWorker(); 542 ScheduleStopWorker();
541 // Fire all start callbacks. 543 // Fire all start callbacks.
542 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); 544 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK);
543 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this)); 545 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this));
544 } 546 }
545 547
546 void ServiceWorkerVersion::OnStopped() { 548 void ServiceWorkerVersion::OnStopped(
549 EmbeddedWorkerInstance::Status old_status) {
547 DCHECK_EQ(STOPPED, running_status()); 550 DCHECK_EQ(STOPPED, running_status());
548 scoped_refptr<ServiceWorkerVersion> protect(this); 551 scoped_refptr<ServiceWorkerVersion> protect(this);
549 552
553 bool should_restart = !is_doomed() && !start_callbacks_.empty() &&
554 (old_status != EmbeddedWorkerInstance::STARTING);
555
550 // Fire all stop callbacks. 556 // Fire all stop callbacks.
551 RunCallbacks(this, &stop_callbacks_, SERVICE_WORKER_OK); 557 RunCallbacks(this, &stop_callbacks_, SERVICE_WORKER_OK);
552 558
553 // Let all start callbacks fail. 559 if (!should_restart) {
554 RunCallbacks( 560 // Let all start callbacks fail.
555 this, &start_callbacks_, SERVICE_WORKER_ERROR_START_WORKER_FAILED); 561 RunCallbacks(this, &start_callbacks_,
562 SERVICE_WORKER_ERROR_START_WORKER_FAILED);
563 }
556 564
557 // Let all message callbacks fail (this will also fire and clear all 565 // Let all message callbacks fail (this will also fire and clear all
558 // callbacks for events). 566 // callbacks for events).
559 // TODO(kinuko): Consider if we want to add queue+resend mechanism here. 567 // TODO(kinuko): Consider if we want to add queue+resend mechanism here.
560 RunIDMapCallbacks(&activate_callbacks_, 568 RunIDMapCallbacks(&activate_callbacks_,
561 &StatusCallback::Run, 569 &StatusCallback::Run,
562 MakeTuple(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED)); 570 MakeTuple(SERVICE_WORKER_ERROR_ACTIVATE_WORKER_FAILED));
563 RunIDMapCallbacks(&install_callbacks_, 571 RunIDMapCallbacks(&install_callbacks_,
564 &StatusCallback::Run, 572 &StatusCallback::Run,
565 MakeTuple(SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED)); 573 MakeTuple(SERVICE_WORKER_ERROR_INSTALL_WORKER_FAILED));
(...skipping 11 matching lines...) Expand all
577 RunIDMapCallbacks(&geofencing_callbacks_, 585 RunIDMapCallbacks(&geofencing_callbacks_,
578 &StatusCallback::Run, 586 &StatusCallback::Run,
579 MakeTuple(SERVICE_WORKER_ERROR_FAILED)); 587 MakeTuple(SERVICE_WORKER_ERROR_FAILED));
580 588
581 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this)); 589 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStopped(this));
582 590
583 // There should be no more communication from/to a stopped worker. Deleting 591 // There should be no more communication from/to a stopped worker. Deleting
584 // the listener prevents any pending completion callbacks from causing 592 // the listener prevents any pending completion callbacks from causing
585 // messages to be sent to the stopped worker. 593 // messages to be sent to the stopped worker.
586 cache_listener_.reset(); 594 cache_listener_.reset();
595
596 // Restart worker if we have any start callbacks and the worker isn't doomed.
597 if (should_restart) {
598 cache_listener_.reset(new ServiceWorkerCacheListener(this, context_));
599 embedded_worker_->Start(
600 version_id_, scope_, script_url_, false /* pause_after_download */,
601 base::Bind(&ServiceWorkerVersion::OnStartMessageSent,
602 weak_factory_.GetWeakPtr()));
603 }
587 } 604 }
588 605
589 void ServiceWorkerVersion::OnReportException( 606 void ServiceWorkerVersion::OnReportException(
590 const base::string16& error_message, 607 const base::string16& error_message,
591 int line_number, 608 int line_number,
592 int column_number, 609 int column_number,
593 const GURL& source_url) { 610 const GURL& source_url) {
594 FOR_EACH_OBSERVER( 611 FOR_EACH_OBSERVER(
595 Listener, 612 Listener,
596 listeners_, 613 listeners_,
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 SetStatus(REDUNDANT); 873 SetStatus(REDUNDANT);
857 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 874 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
858 if (!context_) 875 if (!context_)
859 return; 876 return;
860 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; 877 std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
861 script_cache_map_.GetResources(&resources); 878 script_cache_map_.GetResources(&resources);
862 context_->storage()->PurgeResources(resources); 879 context_->storage()->PurgeResources(resources);
863 } 880 }
864 881
865 } // namespace content 882 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698