Commit 769adb17 authored by Makoto Shimazu's avatar Makoto Shimazu Committed by Commit Bot

ServiceWorker: Clear event timeouts when restarting the worker

Currently ServiceWorkerVersion clears |pending_requests_| but not
|request_timeouts_|, and it causes inconsistency after restart. This patch fixes
it.

Bug: 791451
Change-Id: I50778a81ab31d1094db5776a49137c0196c1fb5f
Reviewed-on: https://chromium-review.googlesource.com/807835
Commit-Queue: Makoto Shimazu <shimazu@chromium.org>
Reviewed-by: default avatarHiroki Nakagawa <nhiroki@chromium.org>
Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#522384}
parent 80eddae9
...@@ -1496,6 +1496,8 @@ void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker( ...@@ -1496,6 +1496,8 @@ void ServiceWorkerVersion::DidEnsureLiveRegistrationForStartWorker(
void ServiceWorkerVersion::StartWorkerInternal() { void ServiceWorkerVersion::StartWorkerInternal() {
DCHECK_EQ(EmbeddedWorkerStatus::STOPPED, running_status()); DCHECK_EQ(EmbeddedWorkerStatus::STOPPED, running_status());
DCHECK(pending_requests_.IsEmpty());
DCHECK(request_timeouts_.empty());
DCHECK(start_worker_first_purpose_); DCHECK(start_worker_first_purpose_);
if (!ServiceWorkerMetrics::ShouldExcludeSiteFromHistogram(site_for_uma_)) { if (!ServiceWorkerMetrics::ShouldExcludeSiteFromHistogram(site_for_uma_)) {
...@@ -1932,6 +1934,7 @@ void ServiceWorkerVersion::OnStoppedInternal(EmbeddedWorkerStatus old_status) { ...@@ -1932,6 +1934,7 @@ void ServiceWorkerVersion::OnStoppedInternal(EmbeddedWorkerStatus old_status) {
iter.Advance(); iter.Advance();
} }
pending_requests_.Clear(); pending_requests_.Clear();
request_timeouts_.clear();
external_request_uuid_to_request_id_.clear(); external_request_uuid_to_request_id_.clear();
event_dispatcher_.reset(); event_dispatcher_.reset();
controller_ptr_.reset(); controller_ptr_.reset();
......
...@@ -450,6 +450,7 @@ class CONTENT_EXPORT ServiceWorkerVersion ...@@ -450,6 +450,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestNowTimeout); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestNowTimeout);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestNowTimeoutKill); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestNowTimeoutKill);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestCustomizedTimeout); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RequestCustomizedTimeout);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, RestartWorker);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, MixedRequestTimeouts); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, MixedRequestTimeouts);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerURLRequestJobTest, EarlyResponse); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerURLRequestJobTest, EarlyResponse);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerURLRequestJobTest, CancelRequest); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerURLRequestJobTest, CancelRequest);
......
...@@ -917,6 +917,37 @@ TEST_F(ServiceWorkerVersionTest, UpdateCachedMetadata) { ...@@ -917,6 +917,37 @@ TEST_F(ServiceWorkerVersionTest, UpdateCachedMetadata) {
version_->RemoveListener(&listener); version_->RemoveListener(&listener);
} }
TEST_F(ServiceWorkerVersionTest, RestartWorker) {
StartWorker(version_.get(),
ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME);
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
ServiceWorkerStatusCode event_status = SERVICE_WORKER_ERROR_MAX_VALUE;
version_->StartRequest(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME,
CreateReceiverOnCurrentThread(&event_status));
// Restart the worker. The inflight event should have been failed.
bool has_stopped = false;
version_->StopWorker(base::BindOnce(&VerifyCalled, &has_stopped));
EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, version_->running_status());
ServiceWorkerStatusCode start_status = SERVICE_WORKER_ERROR_MAX_VALUE;
version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN,
CreateReceiverOnCurrentThread(&start_status));
base::RunLoop().RunUntilIdle();
// All inflight events should have been aborted.
EXPECT_EQ(event_status, SERVICE_WORKER_ERROR_FAILED);
// The worker should have been stopped.
EXPECT_TRUE(has_stopped);
// The worker should have been successfully re-started after stopped.
EXPECT_EQ(SERVICE_WORKER_OK, start_status);
EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
// SetAllRequestExpirations() after restarting should not crash since all
// events should have been removed at this point: crbug.com/791451.
version_->SetAllRequestExpirations(base::TimeTicks());
}
class MessageReceiverControlEvents : public MessageReceiver { class MessageReceiverControlEvents : public MessageReceiver {
public: public:
MessageReceiverControlEvents() : MessageReceiver() {} MessageReceiverControlEvents() : MessageReceiver() {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment