Commit 17f72bbd authored by falken's avatar falken Committed by Commit bot

Service Worker: Reset "idle" timer upon completion of an event.

Otherwise the worker could get stopped if the timer happens to expire between
events while it's in a flurry of events.

BUG=462096

Review URL: https://codereview.chromium.org/1038763005

Cr-Commit-Position: refs/heads/master@{#322341}
parent 8a132a4f
...@@ -1693,6 +1693,7 @@ template <typename IDMAP> ...@@ -1693,6 +1693,7 @@ template <typename IDMAP>
void ServiceWorkerVersion::RemoveCallbackAndStopIfDoomed( void ServiceWorkerVersion::RemoveCallbackAndStopIfDoomed(
IDMAP* callbacks, IDMAP* callbacks,
int request_id) { int request_id) {
RestartTick(&idle_time_);
callbacks->Remove(request_id); callbacks->Remove(request_id);
if (is_doomed_) { if (is_doomed_) {
// The stop should be already scheduled, but try to stop immediately, in // The stop should be already scheduled, but try to stop immediately, in
......
...@@ -302,7 +302,7 @@ class CONTENT_EXPORT ServiceWorkerVersion ...@@ -302,7 +302,7 @@ class CONTENT_EXPORT ServiceWorkerVersion
friend class ServiceWorkerURLRequestJobTest; friend class ServiceWorkerURLRequestJobTest;
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerControlleeRequestHandlerTest, FRIEND_TEST_ALL_PREFIXES(ServiceWorkerControlleeRequestHandlerTest,
ActivateWaitingVersion); ActivateWaitingVersion);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, ScheduleStopWorker); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, IdleTimeout);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, KeepAlive); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, KeepAlive);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, ListenerAvailability); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, ListenerAvailability);
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, SetDevToolsAttached); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerVersionTest, SetDevToolsAttached);
......
...@@ -411,7 +411,11 @@ TEST_F(ServiceWorkerVersionTest, RepeatedlyObserveStatusChanges) { ...@@ -411,7 +411,11 @@ TEST_F(ServiceWorkerVersionTest, RepeatedlyObserveStatusChanges) {
ASSERT_EQ(ServiceWorkerVersion::REDUNDANT, statuses[4]); ASSERT_EQ(ServiceWorkerVersion::REDUNDANT, statuses[4]);
} }
TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) { TEST_F(ServiceWorkerVersionTest, IdleTimeout) {
// Used to reliably test when the idle time gets reset regardless of clock
// granularity.
const base::TimeDelta kOneSecond = base::TimeDelta::FromSeconds(1);
// Verify the timer is not running when version initializes its status. // Verify the timer is not running when version initializes its status.
version_->SetStatus(ServiceWorkerVersion::ACTIVATED); version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
EXPECT_FALSE(version_->timeout_timer_.IsRunning()); EXPECT_FALSE(version_->timeout_timer_.IsRunning());
...@@ -422,9 +426,13 @@ TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) { ...@@ -422,9 +426,13 @@ TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status); EXPECT_EQ(SERVICE_WORKER_OK, status);
EXPECT_TRUE(version_->timeout_timer_.IsRunning()); EXPECT_TRUE(version_->timeout_timer_.IsRunning());
EXPECT_FALSE(version_->idle_time_.is_null());
// The timer should be running if the worker is restarted without controllee. // The idle time should be reset if the worker is restarted without
// controllee.
status = SERVICE_WORKER_ERROR_FAILED; status = SERVICE_WORKER_ERROR_FAILED;
version_->idle_time_ -= kOneSecond;
base::TimeTicks idle_time = version_->idle_time_;
version_->StopWorker(CreateReceiverOnCurrentThread(&status)); version_->StopWorker(CreateReceiverOnCurrentThread(&status));
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status); EXPECT_EQ(SERVICE_WORKER_OK, status);
...@@ -433,8 +441,11 @@ TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) { ...@@ -433,8 +441,11 @@ TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status); EXPECT_EQ(SERVICE_WORKER_OK, status);
EXPECT_TRUE(version_->timeout_timer_.IsRunning()); EXPECT_TRUE(version_->timeout_timer_.IsRunning());
EXPECT_LT(idle_time, version_->idle_time_);
// Adding controllee doesn't stop the stop-worker-timer. // Adding a controllee resets the idle time.
version_->idle_time_ -= kOneSecond;
idle_time = version_->idle_time_;
scoped_ptr<ServiceWorkerProviderHost> host( scoped_ptr<ServiceWorkerProviderHost> host(
new ServiceWorkerProviderHost(33 /* dummy render process id */, new ServiceWorkerProviderHost(33 /* dummy render process id */,
MSG_ROUTING_NONE /* render_frame_id */, MSG_ROUTING_NONE /* render_frame_id */,
...@@ -444,6 +455,19 @@ TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) { ...@@ -444,6 +455,19 @@ TEST_F(ServiceWorkerVersionTest, ScheduleStopWorker) {
NULL)); NULL));
version_->AddControllee(host.get()); version_->AddControllee(host.get());
EXPECT_TRUE(version_->timeout_timer_.IsRunning()); EXPECT_TRUE(version_->timeout_timer_.IsRunning());
EXPECT_LT(idle_time, version_->idle_time_);
// Completing an event resets the idle time.
status = SERVICE_WORKER_ERROR_FAILED;
version_->idle_time_ -= kOneSecond;
idle_time = version_->idle_time_;
version_->DispatchFetchEvent(ServiceWorkerFetchRequest(),
base::Bind(&base::DoNothing),
base::Bind(&ReceiveFetchResult, &status));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(SERVICE_WORKER_OK, status);
EXPECT_LT(idle_time, version_->idle_time_);
} }
......
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