OLD | NEW |
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/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/strings/string16.h" | 10 #include "base/strings/string16.h" |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 embedded_worker_->RemoveListener(this); | 186 embedded_worker_->RemoveListener(this); |
187 if (context_) | 187 if (context_) |
188 context_->RemoveLiveVersion(version_id_); | 188 context_->RemoveLiveVersion(version_id_); |
189 // EmbeddedWorker's dtor sends StopWorker if it's still running. | 189 // EmbeddedWorker's dtor sends StopWorker if it's still running. |
190 } | 190 } |
191 | 191 |
192 void ServiceWorkerVersion::SetStatus(Status status) { | 192 void ServiceWorkerVersion::SetStatus(Status status) { |
193 if (status_ == status) | 193 if (status_ == status) |
194 return; | 194 return; |
195 | 195 |
196 // Schedule to stop worker after registration successfully completed. | |
197 if (status_ == ACTIVATING && status == ACTIVATED && !HasControllee()) | |
198 ScheduleStopWorker(); | |
199 | |
200 status_ = status; | 196 status_ = status; |
201 | 197 |
202 if (skip_waiting_ && status_ == ACTIVATED) { | 198 if (skip_waiting_ && status_ == ACTIVATED) { |
203 for (int request_id : pending_skip_waiting_requests_) | 199 for (int request_id : pending_skip_waiting_requests_) |
204 DidSkipWaiting(request_id); | 200 DidSkipWaiting(request_id); |
205 pending_skip_waiting_requests_.clear(); | 201 pending_skip_waiting_requests_.clear(); |
206 } | 202 } |
207 | 203 |
208 std::vector<base::Closure> callbacks; | 204 std::vector<base::Closure> callbacks; |
209 callbacks.swap(status_change_callbacks_); | 205 callbacks.swap(status_change_callbacks_); |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 } | 588 } |
593 | 589 |
594 void ServiceWorkerVersion::Doom() { | 590 void ServiceWorkerVersion::Doom() { |
595 if (is_doomed_) | 591 if (is_doomed_) |
596 return; | 592 return; |
597 is_doomed_ = true; | 593 is_doomed_ = true; |
598 if (!HasControllee()) | 594 if (!HasControllee()) |
599 DoomInternal(); | 595 DoomInternal(); |
600 } | 596 } |
601 | 597 |
| 598 void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { |
| 599 embedded_worker()->set_devtools_attached(attached); |
| 600 if (!attached && !stop_worker_timer_.IsRunning()) { |
| 601 // If devtools is detached from this version and stop-worker-timer is not |
| 602 // running, try scheduling stop-worker-timer now. |
| 603 ScheduleStopWorker(); |
| 604 } |
| 605 } |
| 606 |
602 void ServiceWorkerVersion::OnStarted() { | 607 void ServiceWorkerVersion::OnStarted() { |
603 DCHECK_EQ(RUNNING, running_status()); | 608 DCHECK_EQ(RUNNING, running_status()); |
604 DCHECK(cache_listener_.get()); | 609 DCHECK(cache_listener_.get()); |
605 if (status() == ACTIVATED && !HasControllee()) | 610 ScheduleStopWorker(); |
606 ScheduleStopWorker(); | |
607 // Fire all start callbacks. | 611 // Fire all start callbacks. |
608 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); | 612 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); |
609 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this)); | 613 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this)); |
610 } | 614 } |
611 | 615 |
612 void ServiceWorkerVersion::OnStopped( | 616 void ServiceWorkerVersion::OnStopped( |
613 EmbeddedWorkerInstance::Status old_status) { | 617 EmbeddedWorkerInstance::Status old_status) { |
614 DCHECK_EQ(STOPPED, running_status()); | 618 DCHECK_EQ(STOPPED, running_status()); |
615 scoped_refptr<ServiceWorkerVersion> protect(this); | 619 scoped_refptr<ServiceWorkerVersion> protect(this); |
616 | 620 |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 if (pending_skip_waiting_requests_.size() == 1) | 1000 if (pending_skip_waiting_requests_.size() == 1) |
997 registration->ActivateWaitingVersionWhenReady(); | 1001 registration->ActivateWaitingVersionWhenReady(); |
998 } | 1002 } |
999 | 1003 |
1000 void ServiceWorkerVersion::DidSkipWaiting(int request_id) { | 1004 void ServiceWorkerVersion::DidSkipWaiting(int request_id) { |
1001 if (running_status() == STARTING || running_status() == RUNNING) | 1005 if (running_status() == STARTING || running_status() == RUNNING) |
1002 embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id)); | 1006 embedded_worker_->SendMessage(ServiceWorkerMsg_DidSkipWaiting(request_id)); |
1003 } | 1007 } |
1004 | 1008 |
1005 void ServiceWorkerVersion::ScheduleStopWorker() { | 1009 void ServiceWorkerVersion::ScheduleStopWorker() { |
1006 if (running_status() != RUNNING) | 1010 // TODO(kinuko): Currently we don't schedule stop-time-worker when the SW has |
| 1011 // controllee, but we should change this default behavior (crbug.com/440259) |
| 1012 if (running_status() != RUNNING || HasControllee()) |
1007 return; | 1013 return; |
1008 if (stop_worker_timer_.IsRunning()) { | 1014 if (stop_worker_timer_.IsRunning()) { |
1009 stop_worker_timer_.Reset(); | 1015 stop_worker_timer_.Reset(); |
1010 return; | 1016 return; |
1011 } | 1017 } |
1012 stop_worker_timer_.Start( | 1018 stop_worker_timer_.Start( |
1013 FROM_HERE, base::TimeDelta::FromSeconds(kStopWorkerDelay), | 1019 FROM_HERE, base::TimeDelta::FromSeconds(kStopWorkerDelay), |
1014 base::Bind(&ServiceWorkerVersion::StopWorker, | 1020 base::Bind(&ServiceWorkerVersion::StopWorkerIfIdle, |
1015 weak_factory_.GetWeakPtr(), | 1021 weak_factory_.GetWeakPtr())); |
1016 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback))); | 1022 } |
| 1023 |
| 1024 void ServiceWorkerVersion::StopWorkerIfIdle() { |
| 1025 // Reschedule the stop the worker while there're inflight requests. |
| 1026 // (Note: we'll probably need to revisit this so that we can kill 'bad' SW. |
| 1027 // See https://github.com/slightlyoff/ServiceWorker/issues/527) |
| 1028 if (HasInflightRequests()) { |
| 1029 ScheduleStopWorker(); |
| 1030 return; |
| 1031 } |
| 1032 if (running_status() == STOPPED || !stop_callbacks_.empty()) |
| 1033 return; |
| 1034 embedded_worker_->StopIfIdle(); |
| 1035 } |
| 1036 |
| 1037 bool ServiceWorkerVersion::HasInflightRequests() const { |
| 1038 return |
| 1039 !activate_callbacks_.IsEmpty() || |
| 1040 !install_callbacks_.IsEmpty() || |
| 1041 !fetch_callbacks_.IsEmpty() || |
| 1042 !sync_callbacks_.IsEmpty() || |
| 1043 !notification_click_callbacks_.IsEmpty() || |
| 1044 !push_callbacks_.IsEmpty() || |
| 1045 !geofencing_callbacks_.IsEmpty(); |
1017 } | 1046 } |
1018 | 1047 |
1019 void ServiceWorkerVersion::DoomInternal() { | 1048 void ServiceWorkerVersion::DoomInternal() { |
1020 DCHECK(!HasControllee()); | 1049 DCHECK(!HasControllee()); |
1021 SetStatus(REDUNDANT); | 1050 SetStatus(REDUNDANT); |
1022 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 1051 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
1023 if (!context_) | 1052 if (!context_) |
1024 return; | 1053 return; |
1025 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; | 1054 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; |
1026 script_cache_map_.GetResources(&resources); | 1055 script_cache_map_.GetResources(&resources); |
1027 context_->storage()->PurgeResources(resources); | 1056 context_->storage()->PurgeResources(resources); |
1028 } | 1057 } |
1029 | 1058 |
1030 } // namespace content | 1059 } // namespace content |
OLD | NEW |