Chromium Code Reviews| Index: content/browser/service_worker/service_worker_version.cc |
| diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc |
| index 76f4ac91b35d3c4c1c8d625b2c66fcbb095ebf30..4ba6d7b77da8dd0673d544fec49f596a45808134 100644 |
| --- a/content/browser/service_worker/service_worker_version.cc |
| +++ b/content/browser/service_worker/service_worker_version.cc |
| @@ -113,6 +113,7 @@ ServiceWorkerVersion::ServiceWorkerVersion( |
| context_(context), |
| script_cache_map_(this, context), |
| is_doomed_(false), |
| + keep_alive_mode_(context->keep_alive_mode()), |
| weak_factory_(this) { |
| DCHECK(context_); |
| DCHECK(registration); |
| @@ -136,10 +137,6 @@ void ServiceWorkerVersion::SetStatus(Status status) { |
| if (status_ == status) |
| return; |
| - // Schedule to stop worker after registration successfully completed. |
| - if (status_ == ACTIVATING && status == ACTIVATED && !HasControllee()) |
| - ScheduleStopWorker(); |
| - |
| status_ = status; |
| std::vector<base::Closure> callbacks; |
| @@ -532,11 +529,19 @@ void ServiceWorkerVersion::Doom() { |
| DoomInternal(); |
| } |
| +void ServiceWorkerVersion::SetKeepAliveMode(bool keep_alive) { |
| + keep_alive_mode_ = keep_alive; |
| + |
| + if (keep_alive_mode_) |
| + CancelStopWorker(); |
| + else |
| + ScheduleStopWorker(); |
| +} |
| + |
| void ServiceWorkerVersion::OnStarted() { |
| DCHECK_EQ(RUNNING, running_status()); |
| DCHECK(cache_listener_.get()); |
| - if (status() == ACTIVATED && !HasControllee()) |
| - ScheduleStopWorker(); |
| + ScheduleStopWorker(); |
| // Fire all start callbacks. |
| RunCallbacks(this, &start_callbacks_, SERVICE_WORKER_OK); |
| FOR_EACH_OBSERVER(Listener, listeners_, OnWorkerStarted(this)); |
| @@ -846,17 +851,46 @@ void ServiceWorkerVersion::OnPostMessageToDocument( |
| } |
| void ServiceWorkerVersion::ScheduleStopWorker() { |
| - if (running_status() != RUNNING) |
| + if (running_status() != RUNNING || |
| + HasControllee() || |
|
falken
2014/12/08 02:30:16
My first reaction was we should still stop the wor
|
| + keep_alive_mode_) { |
| return; |
| + } |
| if (stop_worker_timer_.IsRunning()) { |
| stop_worker_timer_.Reset(); |
| return; |
| } |
| stop_worker_timer_.Start( |
| FROM_HERE, base::TimeDelta::FromSeconds(kStopWorkerDelay), |
| - base::Bind(&ServiceWorkerVersion::StopWorker, |
| - weak_factory_.GetWeakPtr(), |
| - base::Bind(&ServiceWorkerUtils::NoOpStatusCallback))); |
| + base::Bind(&ServiceWorkerVersion::MaybeStopWorker, |
| + weak_factory_.GetWeakPtr())); |
| +} |
| + |
| +void ServiceWorkerVersion::CancelStopWorker() { |
| + if (stop_worker_timer_.IsRunning()) |
| + stop_worker_timer_.Stop(); |
| +} |
| + |
| +void ServiceWorkerVersion::MaybeStopWorker() { |
| + // Reschedule the stop the worker while there're inflight requests. |
| + // (Note: we'll probably need to revisit this so that we can kill 'bad' SW. |
| + // See https://github.com/slightlyoff/ServiceWorker/issues/527) |
| + if (HasInflightRequests()) { |
| + ScheduleStopWorker(); |
| + return; |
| + } |
| + StopWorker(base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
| +} |
| + |
| +bool ServiceWorkerVersion::HasInflightRequests() const { |
| + return |
| + !activate_callbacks_.IsEmpty() || |
| + !install_callbacks_.IsEmpty() || |
| + !fetch_callbacks_.IsEmpty() || |
| + !sync_callbacks_.IsEmpty() || |
| + !notification_click_callbacks_.IsEmpty() || |
| + !push_callbacks_.IsEmpty() || |
| + !geofencing_callbacks_.IsEmpty(); |
| } |
| void ServiceWorkerVersion::DoomInternal() { |