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/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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
106 const GURL& script_url, | 106 const GURL& script_url, |
107 int64 version_id, | 107 int64 version_id, |
108 base::WeakPtr<ServiceWorkerContextCore> context) | 108 base::WeakPtr<ServiceWorkerContextCore> context) |
109 : version_id_(version_id), | 109 : version_id_(version_id), |
110 registration_id_(kInvalidServiceWorkerVersionId), | 110 registration_id_(kInvalidServiceWorkerVersionId), |
111 script_url_(script_url), | 111 script_url_(script_url), |
112 status_(NEW), | 112 status_(NEW), |
113 context_(context), | 113 context_(context), |
114 script_cache_map_(this, context), | 114 script_cache_map_(this, context), |
115 is_doomed_(false), | 115 is_doomed_(false), |
116 keep_alive_mode_(context->keep_alive_mode()), | |
116 weak_factory_(this) { | 117 weak_factory_(this) { |
117 DCHECK(context_); | 118 DCHECK(context_); |
118 DCHECK(registration); | 119 DCHECK(registration); |
119 if (registration) { | 120 if (registration) { |
120 registration_id_ = registration->id(); | 121 registration_id_ = registration->id(); |
121 scope_ = registration->pattern(); | 122 scope_ = registration->pattern(); |
122 } | 123 } |
123 context_->AddLiveVersion(this); | 124 context_->AddLiveVersion(this); |
124 embedded_worker_ = context_->embedded_worker_registry()->CreateWorker(); | 125 embedded_worker_ = context_->embedded_worker_registry()->CreateWorker(); |
125 embedded_worker_->AddListener(this); | 126 embedded_worker_->AddListener(this); |
126 } | 127 } |
127 | 128 |
128 ServiceWorkerVersion::~ServiceWorkerVersion() { | 129 ServiceWorkerVersion::~ServiceWorkerVersion() { |
129 embedded_worker_->RemoveListener(this); | 130 embedded_worker_->RemoveListener(this); |
130 if (context_) | 131 if (context_) |
131 context_->RemoveLiveVersion(version_id_); | 132 context_->RemoveLiveVersion(version_id_); |
132 // EmbeddedWorker's dtor sends StopWorker if it's still running. | 133 // EmbeddedWorker's dtor sends StopWorker if it's still running. |
133 } | 134 } |
134 | 135 |
135 void ServiceWorkerVersion::SetStatus(Status status) { | 136 void ServiceWorkerVersion::SetStatus(Status status) { |
136 if (status_ == status) | 137 if (status_ == status) |
137 return; | 138 return; |
138 | 139 |
139 // Schedule to stop worker after registration successfully completed. | |
140 if (status_ == ACTIVATING && status == ACTIVATED && !HasControllee()) | |
141 ScheduleStopWorker(); | |
142 | |
143 status_ = status; | 140 status_ = status; |
144 | 141 |
145 std::vector<base::Closure> callbacks; | 142 std::vector<base::Closure> callbacks; |
146 callbacks.swap(status_change_callbacks_); | 143 callbacks.swap(status_change_callbacks_); |
147 for (const auto& callback : callbacks) | 144 for (const auto& callback : callbacks) |
148 callback.Run(); | 145 callback.Run(); |
149 | 146 |
150 FOR_EACH_OBSERVER(Listener, listeners_, OnVersionStateChanged(this)); | 147 FOR_EACH_OBSERVER(Listener, listeners_, OnVersionStateChanged(this)); |
151 } | 148 } |
152 | 149 |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
525 } | 522 } |
526 | 523 |
527 void ServiceWorkerVersion::Doom() { | 524 void ServiceWorkerVersion::Doom() { |
528 if (is_doomed_) | 525 if (is_doomed_) |
529 return; | 526 return; |
530 is_doomed_ = true; | 527 is_doomed_ = true; |
531 if (!HasControllee()) | 528 if (!HasControllee()) |
532 DoomInternal(); | 529 DoomInternal(); |
533 } | 530 } |
534 | 531 |
532 void ServiceWorkerVersion::SetKeepAliveMode(bool keep_alive) { | |
533 keep_alive_mode_ = keep_alive; | |
534 | |
535 if (keep_alive_mode_) | |
536 CancelStopWorker(); | |
537 else | |
538 ScheduleStopWorker(); | |
539 } | |
540 | |
535 void ServiceWorkerVersion::OnStarted() { | 541 void ServiceWorkerVersion::OnStarted() { |
536 DCHECK_EQ(RUNNING, running_status()); | 542 DCHECK_EQ(RUNNING, running_status()); |
537 DCHECK(cache_listener_.get()); | 543 DCHECK(cache_listener_.get()); |
538 if (status() == ACTIVATED && !HasControllee()) | 544 ScheduleStopWorker(); |
539 ScheduleStopWorker(); | |
540 // Fire all start callbacks. | 545 // Fire all start callbacks. |
541 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); | 546 RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); |
542 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this)); | 547 FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this)); |
543 } | 548 } |
544 | 549 |
545 void ServiceWorkerVersion::OnStopped( | 550 void ServiceWorkerVersion::OnStopped( |
546 EmbeddedWorkerInstance::Status old_status) { | 551 EmbeddedWorkerInstance::Status old_status) { |
547 DCHECK_EQ(STOPPED, running_status()); | 552 DCHECK_EQ(STOPPED, running_status()); |
548 scoped_refptr<ServiceWorkerVersion> protect(this); | 553 scoped_refptr<ServiceWorkerVersion> protect(this); |
549 | 554 |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
839 ServiceWorkerProviderHost* provider_host = | 844 ServiceWorkerProviderHost* provider_host = |
840 controllee_by_id_.Lookup(client_id); | 845 controllee_by_id_.Lookup(client_id); |
841 if (!provider_host) { | 846 if (!provider_host) { |
842 // The client may already have been closed, just ignore. | 847 // The client may already have been closed, just ignore. |
843 return; | 848 return; |
844 } | 849 } |
845 provider_host->PostMessage(message, sent_message_port_ids); | 850 provider_host->PostMessage(message, sent_message_port_ids); |
846 } | 851 } |
847 | 852 |
848 void ServiceWorkerVersion::ScheduleStopWorker() { | 853 void ServiceWorkerVersion::ScheduleStopWorker() { |
849 if (running_status() != RUNNING) | 854 if (running_status() != RUNNING || |
855 HasControllee() || | |
falken
2014/12/08 02:30:16
My first reaction was we should still stop the wor
| |
856 keep_alive_mode_) { | |
850 return; | 857 return; |
858 } | |
851 if (stop_worker_timer_.IsRunning()) { | 859 if (stop_worker_timer_.IsRunning()) { |
852 stop_worker_timer_.Reset(); | 860 stop_worker_timer_.Reset(); |
853 return; | 861 return; |
854 } | 862 } |
855 stop_worker_timer_.Start( | 863 stop_worker_timer_.Start( |
856 FROM_HERE, base::TimeDelta::FromSeconds(kStopWorkerDelay), | 864 FROM_HERE, base::TimeDelta::FromSeconds(kStopWorkerDelay), |
857 base::Bind(&ServiceWorkerVersion::StopWorker, | 865 base::Bind(&ServiceWorkerVersion::MaybeStopWorker, |
858 weak_factory_.GetWeakPtr(), | 866 weak_factory_.GetWeakPtr())); |
859 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback))); | 867 } |
868 | |
869 void ServiceWorkerVersion::CancelStopWorker() { | |
870 if (stop_worker_timer_.IsRunning()) | |
871 stop_worker_timer_.Stop(); | |
872 } | |
873 | |
874 void ServiceWorkerVersion::MaybeStopWorker() { | |
875 // Reschedule the stop the worker while there're inflight requests. | |
876 // (Note: we'll probably need to revisit this so that we can kill 'bad' SW. | |
877 // See https://github.com/slightlyoff/ServiceWorker/issues/527) | |
878 if (HasInflightRequests()) { | |
879 ScheduleStopWorker(); | |
880 return; | |
881 } | |
882 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | |
883 } | |
884 | |
885 bool ServiceWorkerVersion::HasInflightRequests() const { | |
886 return | |
887 !activate_callbacks_.IsEmpty() || | |
888 !install_callbacks_.IsEmpty() || | |
889 !fetch_callbacks_.IsEmpty() || | |
890 !sync_callbacks_.IsEmpty() || | |
891 !notification_click_callbacks_.IsEmpty() || | |
892 !push_callbacks_.IsEmpty() || | |
893 !geofencing_callbacks_.IsEmpty(); | |
860 } | 894 } |
861 | 895 |
862 void ServiceWorkerVersion::DoomInternal() { | 896 void ServiceWorkerVersion::DoomInternal() { |
863 DCHECK(!HasControllee()); | 897 DCHECK(!HasControllee()); |
864 SetStatus(REDUNDANT); | 898 SetStatus(REDUNDANT); |
865 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 899 StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
866 if (!context_) | 900 if (!context_) |
867 return; | 901 return; |
868 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; | 902 std::vector<ServiceWorkerDatabase::ResourceRecord> resources; |
869 script_cache_map_.GetResources(&resources); | 903 script_cache_map_.GetResources(&resources); |
870 context_->storage()->PurgeResources(resources); | 904 context_->storage()->PurgeResources(resources); |
871 } | 905 } |
872 | 906 |
873 } // namespace content | 907 } // namespace content |
OLD | NEW |