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 4fd441b8058715f9586bf91b372e1d6f08006a12..8ed5740da400d2a62c13f1cb13387517d660c280 100644 |
--- a/content/browser/service_worker/service_worker_version.cc |
+++ b/content/browser/service_worker/service_worker_version.cc |
@@ -329,6 +329,12 @@ void RestartTick(base::TimeTicks* time) { |
*time = base::TimeTicks().Now(); |
} |
+bool RequestExpired(const base::TimeTicks& expiration) { |
+ if (expiration.is_null()) |
+ return false; |
+ return base::TimeTicks().Now() >= expiration; |
+} |
+ |
base::TimeDelta GetTickDuration(const base::TimeTicks& time) { |
if (time.is_null()) |
return base::TimeDelta(); |
@@ -803,6 +809,7 @@ void ServiceWorkerVersion::DispatchFetchEvent( |
void ServiceWorkerVersion::DispatchSyncEvent( |
BackgroundSyncRegistrationHandle::HandleId handle_id, |
BackgroundSyncEventLastChance last_chance, |
+ base::TimeTicks expiration, |
const StatusCallback& callback) { |
OnBeginEvent(); |
DCHECK_EQ(ACTIVATED, status()) << status(); |
@@ -811,11 +818,12 @@ void ServiceWorkerVersion::DispatchSyncEvent( |
StartWorker(base::Bind( |
&RunTaskAfterStartWorker, weak_factory_.GetWeakPtr(), callback, |
base::Bind(&self::DispatchSyncEvent, weak_factory_.GetWeakPtr(), |
- handle_id, last_chance, callback))); |
+ handle_id, last_chance, expiration, callback))); |
return; |
} |
- int request_id = AddRequest(callback, &sync_requests_, REQUEST_SYNC); |
+ int request_id = AddRequestWithExpiration(callback, &sync_requests_, |
+ REQUEST_SYNC, expiration); |
if (!background_sync_dispatcher_) { |
embedded_worker_->GetServiceRegistry()->ConnectToRemoteService( |
mojo::GetProxy(&background_sync_dispatcher_)); |
@@ -1079,7 +1087,7 @@ void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { |
skip_recording_startup_time_ = true; |
// Cancel request timeouts. |
- SetAllRequestTimes(base::TimeTicks()); |
+ SetAllRequestExpirations(base::TimeTicks()); |
return; |
} |
if (!start_callbacks_.empty()) { |
@@ -1090,8 +1098,10 @@ void ServiceWorkerVersion::SetDevToolsAttached(bool attached) { |
RestartTick(&start_time_); |
} |
- // Reactivate request timeouts. |
- SetAllRequestTimes(base::TimeTicks::Now()); |
+ // Reactivate request timeouts, setting them all to the same expiration time. |
+ SetAllRequestExpirations( |
+ base::TimeTicks::Now() + |
+ base::TimeDelta::FromMinutes(kRequestTimeoutMinutes)); |
} |
void ServiceWorkerVersion::SetMainScriptHttpResponseInfo( |
@@ -1110,15 +1120,20 @@ ServiceWorkerVersion::GetMainScriptHttpResponseInfo() { |
return main_script_http_info_.get(); |
} |
-ServiceWorkerVersion::RequestInfo::RequestInfo(int id, |
- RequestType type, |
- const base::TimeTicks& now) |
- : id(id), type(type), time(now) { |
-} |
+ServiceWorkerVersion::RequestInfo::RequestInfo( |
+ int id, |
+ RequestType type, |
+ const base::TimeTicks& expiration) |
+ : id(id), type(type), expiration(expiration) {} |
ServiceWorkerVersion::RequestInfo::~RequestInfo() { |
} |
+bool ServiceWorkerVersion::RequestInfo::operator>( |
+ const RequestInfo& other) const { |
+ return expiration > other.expiration; |
+} |
+ |
template <typename CallbackType> |
ServiceWorkerVersion::PendingRequest<CallbackType>::PendingRequest( |
const CallbackType& callback, |
@@ -2119,12 +2134,11 @@ void ServiceWorkerVersion::OnTimeoutTimer() { |
return; |
} |
- // Requests have not finished within a certain period. |
+ // Requests have not finished before their expiration. |
bool request_timed_out = false; |
while (!requests_.empty()) { |
- RequestInfo info = requests_.front(); |
- if (GetTickDuration(info.time) < |
- base::TimeDelta::FromMinutes(kRequestTimeoutMinutes)) |
+ RequestInfo info = requests_.top(); |
+ if (!RequestExpired(info.expiration)) |
break; |
if (MaybeTimeOutRequest(info)) { |
request_timed_out = true; |
@@ -2133,7 +2147,7 @@ void ServiceWorkerVersion::OnTimeoutTimer() { |
} |
requests_.pop(); |
} |
- if (request_timed_out && running_status() != STOPPING) |
+ if (requests_.empty() && request_timed_out && running_status() != STOPPING) |
Marijn Kruisselbrink
2015/12/16 19:09:57
Not stopping the worker when a request was timed o
jkarlin
2015/12/16 19:29:56
Good catch. It seems reasonable to me to remove th
jkarlin
2015/12/16 20:44:27
I've changed it to only allow the service worker t
|
embedded_worker_->Stop(); |
// For the timeouts below, there are no callbacks to timeout so there is |
@@ -2240,10 +2254,22 @@ int ServiceWorkerVersion::AddRequest( |
const CallbackType& callback, |
IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map, |
RequestType request_type) { |
- base::TimeTicks now = base::TimeTicks::Now(); |
- int request_id = |
- callback_map->Add(new PendingRequest<CallbackType>(callback, now)); |
- requests_.push(RequestInfo(request_id, request_type, now)); |
+ base::TimeTicks expiration_time = |
+ base::TimeTicks::Now() + |
+ base::TimeDelta::FromMinutes(kRequestTimeoutMinutes); |
+ return AddRequestWithExpiration(callback, callback_map, request_type, |
+ expiration_time); |
+} |
+ |
+template <typename CallbackType> |
+int ServiceWorkerVersion::AddRequestWithExpiration( |
+ const CallbackType& callback, |
+ IDMap<PendingRequest<CallbackType>, IDMapOwnPointer>* callback_map, |
+ RequestType request_type, |
+ base::TimeTicks expiration) { |
+ int request_id = callback_map->Add( |
+ new PendingRequest<CallbackType>(callback, base::TimeTicks::Now())); |
+ requests_.push(RequestInfo(request_id, request_type, expiration)); |
return request_id; |
} |
@@ -2284,11 +2310,12 @@ bool ServiceWorkerVersion::MaybeTimeOutRequest(const RequestInfo& info) { |
return false; |
} |
-void ServiceWorkerVersion::SetAllRequestTimes(const base::TimeTicks& ticks) { |
- std::queue<RequestInfo> new_requests; |
+void ServiceWorkerVersion::SetAllRequestExpirations( |
+ const base::TimeTicks& expiration) { |
+ RequestInfoPriorityQueue new_requests; |
while (!requests_.empty()) { |
- RequestInfo info = requests_.front(); |
- info.time = ticks; |
+ RequestInfo info = requests_.top(); |
+ info.expiration = expiration; |
new_requests.push(info); |
requests_.pop(); |
} |