Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: content/browser/service_worker/service_worker_register_job.cc

Issue 360123002: ServiceWorker: some more groundwork in support of the update process (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_register_job.h" 5 #include "content/browser/service_worker/service_worker_register_job.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "content/browser/service_worker/service_worker_context_core.h" 10 #include "content/browser/service_worker/service_worker_context_core.h"
(...skipping 29 matching lines...) Expand all
40 ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() { 40 ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() {
41 DCHECK(!context_ || 41 DCHECK(!context_ ||
42 phase_ == INITIAL || phase_ == COMPLETE || phase_ == ABORT) 42 phase_ == INITIAL || phase_ == COMPLETE || phase_ == ABORT)
43 << "Jobs should only be interrupted during shutdown."; 43 << "Jobs should only be interrupted during shutdown.";
44 } 44 }
45 45
46 void ServiceWorkerRegisterJob::AddCallback(const RegistrationCallback& callback, 46 void ServiceWorkerRegisterJob::AddCallback(const RegistrationCallback& callback,
47 int process_id) { 47 int process_id) {
48 if (!is_promise_resolved_) { 48 if (!is_promise_resolved_) {
49 callbacks_.push_back(callback); 49 callbacks_.push_back(callback);
50 if (process_id != -1 && (phase_ < UPDATE || !pending_version())) 50 if (process_id != -1 && (phase_ < UPDATE || !new_version()))
51 pending_process_ids_.push_back(process_id); 51 pending_process_ids_.push_back(process_id);
52 return; 52 return;
53 } 53 }
54 RunSoon(base::Bind( 54 RunSoon(base::Bind(
55 callback, promise_resolved_status_, 55 callback, promise_resolved_status_,
56 promise_resolved_registration_, promise_resolved_version_)); 56 promise_resolved_registration_, promise_resolved_version_));
57 } 57 }
58 58
59 void ServiceWorkerRegisterJob::Start() { 59 void ServiceWorkerRegisterJob::Start() {
60 SetPhase(START); 60 SetPhase(START);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 DCHECK(phase_ == START || phase_ == REGISTER) << phase_; 94 DCHECK(phase_ == START || phase_ == REGISTER) << phase_;
95 DCHECK(!internal_.registration); 95 DCHECK(!internal_.registration);
96 internal_.registration = registration; 96 internal_.registration = registration;
97 } 97 }
98 98
99 ServiceWorkerRegistration* ServiceWorkerRegisterJob::registration() { 99 ServiceWorkerRegistration* ServiceWorkerRegisterJob::registration() {
100 DCHECK(phase_ >= REGISTER) << phase_; 100 DCHECK(phase_ >= REGISTER) << phase_;
101 return internal_.registration; 101 return internal_.registration;
102 } 102 }
103 103
104 void ServiceWorkerRegisterJob::set_pending_version( 104 void ServiceWorkerRegisterJob::set_new_version(
105 ServiceWorkerVersion* version) { 105 ServiceWorkerVersion* version) {
106 DCHECK(phase_ == UPDATE) << phase_; 106 DCHECK(phase_ == UPDATE) << phase_;
107 DCHECK(!internal_.pending_version); 107 DCHECK(!internal_.new_version);
108 internal_.pending_version = version; 108 internal_.new_version = version;
109 } 109 }
110 110
111 ServiceWorkerVersion* ServiceWorkerRegisterJob::pending_version() { 111 ServiceWorkerVersion* ServiceWorkerRegisterJob::new_version() {
112 DCHECK(phase_ >= UPDATE) << phase_; 112 DCHECK(phase_ >= UPDATE) << phase_;
113 return internal_.pending_version; 113 return internal_.new_version;
114 } 114 }
115 115
116 void ServiceWorkerRegisterJob::SetPhase(Phase phase) { 116 void ServiceWorkerRegisterJob::SetPhase(Phase phase) {
117 switch (phase) { 117 switch (phase) {
118 case INITIAL: 118 case INITIAL:
119 NOTREACHED(); 119 NOTREACHED();
120 break; 120 break;
121 case START: 121 case START:
122 DCHECK(phase_ == INITIAL) << phase_; 122 DCHECK(phase_ == INITIAL) << phase_;
123 break; 123 break;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 // Abort this registration job. 223 // Abort this registration job.
224 Complete(status); 224 Complete(status);
225 return; 225 return;
226 } 226 }
227 227
228 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." 228 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.."
229 // then terminate the installing worker. It doesn't make sense to implement 229 // then terminate the installing worker. It doesn't make sense to implement
230 // yet since we always activate the worker if install completed, so there can 230 // yet since we always activate the worker if install completed, so there can
231 // be no installing worker at this point. 231 // be no installing worker at this point.
232 // TODO(nhiroki): Check 'installing_version()' instead when it's supported. 232 // TODO(nhiroki): Check 'installing_version()' instead when it's supported.
233 DCHECK(!registration()->waiting_version()); 233 DCHECK(!registration()->waiting_version());
nhiroki 2014/07/02 07:25:12 Can you check installing_version() instead of wait
michaeln 2014/07/02 23:17:14 Done.
234 234
235 // "Let serviceWorker be a newly-created ServiceWorker object..." and start 235 // "Let serviceWorker be a newly-created ServiceWorker object..." and start
236 // the worker. 236 // the worker.
237 set_pending_version(new ServiceWorkerVersion( 237 set_new_version(new ServiceWorkerVersion(
238 registration(), context_->storage()->NewVersionId(), context_)); 238 registration(), context_->storage()->NewVersionId(), context_));
239 239
240 // TODO(michaeln): Pause after downloading when performing an update. 240 // TODO(michaeln): Pause after downloading when performing an update.
241 bool pause_after_download = false; 241 bool pause_after_download = false;
242 if (pause_after_download) 242 if (pause_after_download)
243 pending_version()->embedded_worker()->AddListener(this); 243 new_version()->embedded_worker()->AddListener(this);
244 pending_version()->StartWorkerWithCandidateProcesses( 244 new_version()->StartWorkerWithCandidateProcesses(
245 pending_process_ids_, 245 pending_process_ids_,
246 pause_after_download, 246 pause_after_download,
247 base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished, 247 base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished,
248 weak_factory_.GetWeakPtr())); 248 weak_factory_.GetWeakPtr()));
249 } 249 }
250 250
251 void ServiceWorkerRegisterJob::OnStartWorkerFinished( 251 void ServiceWorkerRegisterJob::OnStartWorkerFinished(
252 ServiceWorkerStatusCode status) { 252 ServiceWorkerStatusCode status) {
253 // "If serviceWorker fails to start up..." then reject the promise with an 253 // "If serviceWorker fails to start up..." then reject the promise with an
254 // error and abort. 254 // error and abort.
255 if (status != SERVICE_WORKER_OK) { 255 if (status != SERVICE_WORKER_OK) {
256 Complete(status); 256 Complete(status);
257 return; 257 return;
258 } 258 }
259 259
260 // TODO(michaeln): Compare the old and new script.
261 // If different unpause the worker and continue with
262 // the job. If the same ResolvePromise with the current
263 // version and complete the job, throwing away the new version
264 // since there's nothing new.
265
260 // "Resolve promise with serviceWorker." 266 // "Resolve promise with serviceWorker."
261 // Although the spec doesn't set waitingWorker until after resolving the 267 DCHECK(!registration()->installing_version());
262 // promise, our system's resolving works by passing ServiceWorkerRegistration 268 ResolvePromise(status, registration(), new_version());
263 // to the callbacks, so waitingWorker must be set first. 269 registration()->SetInstallingVersion(new_version());
264 DCHECK(!registration()->waiting_version()); 270 AssociateInstallingVersionToDocuments(context_, new_version());
265 registration()->set_waiting_version(pending_version());
266 ResolvePromise(status, registration(), pending_version());
267
268 AssociateWaitingVersionToDocuments(context_, pending_version());
269
270 InstallAndContinue(); 271 InstallAndContinue();
271 } 272 }
272 273
273 // This function corresponds to the spec's _Install algorithm. 274 // This function corresponds to the spec's _Install algorithm.
274 void ServiceWorkerRegisterJob::InstallAndContinue() { 275 void ServiceWorkerRegisterJob::InstallAndContinue() {
275 SetPhase(INSTALL); 276 SetPhase(INSTALL);
276 // "Set serviceWorkerRegistration.installingWorker._state to installing." 277 // "Set serviceWorkerRegistration.installingWorker._state to installing."
277 // "Fire install event on the associated ServiceWorkerGlobalScope object." 278 // "Fire install event on the associated ServiceWorkerGlobalScope object."
278 pending_version()->DispatchInstallEvent( 279 new_version()->DispatchInstallEvent(
279 -1, 280 -1,
280 base::Bind(&ServiceWorkerRegisterJob::OnInstallFinished, 281 base::Bind(&ServiceWorkerRegisterJob::OnInstallFinished,
281 weak_factory_.GetWeakPtr())); 282 weak_factory_.GetWeakPtr()));
282 } 283 }
283 284
284 void ServiceWorkerRegisterJob::OnInstallFinished( 285 void ServiceWorkerRegisterJob::OnInstallFinished(
285 ServiceWorkerStatusCode status) { 286 ServiceWorkerStatusCode status) {
286 // "If any handler called waitUntil()..." and the resulting promise 287 // "If any handler called waitUntil()..." and the resulting promise
287 // is rejected, abort. 288 // is rejected, abort.
288 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is 289 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is
289 // unexpectedly terminated) we may want to retry sending the event again. 290 // unexpectedly terminated) we may want to retry sending the event again.
290 if (status != SERVICE_WORKER_OK) { 291 if (status != SERVICE_WORKER_OK) {
291 Complete(status); 292 Complete(status);
292 return; 293 return;
293 } 294 }
294 295
295 SetPhase(STORE); 296 SetPhase(STORE);
296 context_->storage()->StoreRegistration( 297 context_->storage()->StoreRegistration(
297 registration(), 298 registration(),
298 pending_version(), 299 new_version(),
299 base::Bind(&ServiceWorkerRegisterJob::OnStoreRegistrationComplete, 300 base::Bind(&ServiceWorkerRegisterJob::OnStoreRegistrationComplete,
300 weak_factory_.GetWeakPtr())); 301 weak_factory_.GetWeakPtr()));
301 } 302 }
302 303
303 void ServiceWorkerRegisterJob::OnStoreRegistrationComplete( 304 void ServiceWorkerRegisterJob::OnStoreRegistrationComplete(
304 ServiceWorkerStatusCode status) { 305 ServiceWorkerStatusCode status) {
305 if (status != SERVICE_WORKER_OK) { 306 if (status != SERVICE_WORKER_OK) {
306 Complete(status); 307 Complete(status);
307 return; 308 return;
308 } 309 }
309 310 registration()->SetWaitingVersion(new_version());
310 ActivateAndContinue(); 311 ActivateAndContinue();
311 } 312 }
312 313
313 // This function corresponds to the spec's _Activate algorithm. 314 // This function corresponds to the spec's _Activate algorithm.
314 void ServiceWorkerRegisterJob::ActivateAndContinue() { 315 void ServiceWorkerRegisterJob::ActivateAndContinue() {
315 SetPhase(ACTIVATE); 316 SetPhase(ACTIVATE);
316 317
317 // "If existingWorker is not null, then: wait for exitingWorker to finish 318 // "If existingWorker is not null, then: wait for exitingWorker to finish
318 // handling any in-progress requests." 319 // handling any in-progress requests."
319 // See if we already have an active_version for the scope and it has 320 // See if we already have an active_version for the scope and it has
320 // controllee documents (if so activating the new version should wait 321 // controllee documents (if so activating the new version should wait
321 // until we have no documents controlled by the version). 322 // until we have no documents controlled by the version).
322 if (registration()->active_version() && 323 if (registration()->active_version() &&
323 registration()->active_version()->HasControllee()) { 324 registration()->active_version()->HasControllee()) {
324 // TODO(kinuko,falken): Currently we immediately return if the existing 325 // TODO(kinuko,falken): Currently we immediately return if the existing
325 // registration already has an active version, so we shouldn't come 326 // registration already has an active version, so we shouldn't come
326 // this way. 327 // this way.
327 NOTREACHED(); 328 NOTREACHED();
328 // TODO(falken): Register an continuation task to wait for NoControllees 329 // TODO(falken): Register an continuation task to wait for NoControllees
329 // notification so that we can resume activation later (see comments 330 // notification so that we can resume activation later (see comments
330 // in ServiceWorkerVersion::RemoveControllee). 331 // in ServiceWorkerVersion::RemoveControllee).
331 Complete(SERVICE_WORKER_OK); 332 Complete(SERVICE_WORKER_OK);
332 return; 333 return;
333 } 334 }
334 335
335 // "Set serviceWorkerRegistration.waitingWorker to null." 336 // "Set serviceWorkerRegistration.waitingWorker to null."
336 // "Set serviceWorkerRegistration.activeWorker to activatingWorker." 337 // "Set serviceWorkerRegistration.activeWorker to activatingWorker."
337 DisassociateWaitingVersionFromDocuments( 338 registration()->SetActiveVersion(new_version());
338 context_, pending_version()->version_id());
339 registration()->set_waiting_version(NULL);
340 DCHECK(!registration()->active_version());
341 registration()->set_active_version(pending_version());
342 339
343 // "Set serviceWorkerRegistration.activeWorker._state to activating." 340 // "Set serviceWorkerRegistration.activeWorker._state to activating."
344 // "Fire activate event on the associated ServiceWorkerGlobalScope object." 341 // "Fire activate event on the associated ServiceWorkerGlobalScope object."
345 // "Set serviceWorkerRegistration.activeWorker._state to active." 342 // "Set serviceWorkerRegistration.activeWorker._state to active."
346 pending_version()->DispatchActivateEvent( 343 new_version()->DispatchActivateEvent(
347 base::Bind(&ServiceWorkerRegisterJob::OnActivateFinished, 344 base::Bind(&ServiceWorkerRegisterJob::OnActivateFinished,
348 weak_factory_.GetWeakPtr())); 345 weak_factory_.GetWeakPtr()));
349 } 346 }
350 347
351 void ServiceWorkerRegisterJob::OnActivateFinished( 348 void ServiceWorkerRegisterJob::OnActivateFinished(
352 ServiceWorkerStatusCode status) { 349 ServiceWorkerStatusCode status) {
353 // "If any handler called waitUntil()..." and the resulting promise 350 // "If any handler called waitUntil()..." and the resulting promise
354 // is rejected, abort. 351 // is rejected, abort.
355 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is 352 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is
356 // unexpectedly terminated) we may want to retry sending the event again. 353 // unexpectedly terminated) we may want to retry sending the event again.
357 if (status != SERVICE_WORKER_OK) { 354 if (status != SERVICE_WORKER_OK) {
358 registration()->set_active_version(NULL); 355 registration()->SetActiveVersion(NULL);
359 Complete(status); 356 Complete(status);
360 return; 357 return;
361 } 358 }
362 context_->storage()->UpdateToActiveState( 359 context_->storage()->UpdateToActiveState(
363 registration(), 360 registration(),
364 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 361 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
365 Complete(SERVICE_WORKER_OK); 362 Complete(SERVICE_WORKER_OK);
366 } 363 }
367 364
368 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { 365 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) {
369 CompleteInternal(status); 366 CompleteInternal(status);
370 context_->job_coordinator()->FinishJob(pattern_, this); 367 context_->job_coordinator()->FinishJob(pattern_, this);
371 } 368 }
372 369
373 void ServiceWorkerRegisterJob::CompleteInternal( 370 void ServiceWorkerRegisterJob::CompleteInternal(
374 ServiceWorkerStatusCode status) { 371 ServiceWorkerStatusCode status) {
375 SetPhase(COMPLETE); 372 SetPhase(COMPLETE);
376 if (status != SERVICE_WORKER_OK) { 373 if (status != SERVICE_WORKER_OK) {
377 if (registration() && registration()->waiting_version()) { 374 if (registration()) {
378 DisassociateWaitingVersionFromDocuments( 375 if (new_version()) {
379 context_, registration()->waiting_version()->version_id()); 376 DisassociateVersionFromDocuments(context_, new_version());
380 registration()->set_waiting_version(NULL); 377 registration()->UnsetVersion(new_version());
381 } 378 }
382 if (registration() && !registration()->active_version()) { 379 if (!registration()->active_version()) {
383 context_->storage()->DeleteRegistration( 380 context_->storage()->DeleteRegistration(
384 registration()->id(), 381 registration()->id(),
385 registration()->script_url().GetOrigin(), 382 registration()->script_url().GetOrigin(),
386 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 383 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
384 }
387 } 385 }
388 if (!is_promise_resolved_) 386 if (!is_promise_resolved_)
389 ResolvePromise(status, NULL, NULL); 387 ResolvePromise(status, NULL, NULL);
390 } 388 }
391 DCHECK(callbacks_.empty()); 389 DCHECK(callbacks_.empty());
392 if (registration()) { 390 if (registration()) {
393 context_->storage()->NotifyDoneInstallingRegistration( 391 context_->storage()->NotifyDoneInstallingRegistration(
394 registration(), pending_version(), status); 392 registration(), new_version(), status);
395 } 393 }
396 if (pending_version()) 394 if (new_version())
397 pending_version()->embedded_worker()->RemoveListener(this); 395 new_version()->embedded_worker()->RemoveListener(this);
398 } 396 }
399 397
400 void ServiceWorkerRegisterJob::ResolvePromise( 398 void ServiceWorkerRegisterJob::ResolvePromise(
401 ServiceWorkerStatusCode status, 399 ServiceWorkerStatusCode status,
402 ServiceWorkerRegistration* registration, 400 ServiceWorkerRegistration* registration,
403 ServiceWorkerVersion* version) { 401 ServiceWorkerVersion* version) {
404 DCHECK(!is_promise_resolved_); 402 DCHECK(!is_promise_resolved_);
405 is_promise_resolved_ = true; 403 is_promise_resolved_ = true;
406 promise_resolved_status_ = status; 404 promise_resolved_status_ = status;
407 promise_resolved_registration_ = registration; 405 promise_resolved_registration_ = registration;
408 promise_resolved_version_ = version; 406 promise_resolved_version_ = version;
409 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin(); 407 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin();
410 it != callbacks_.end(); 408 it != callbacks_.end();
411 ++it) { 409 ++it) {
412 it->Run(status, registration, version); 410 it->Run(status, registration, version);
413 } 411 }
414 callbacks_.clear(); 412 callbacks_.clear();
415 } 413 }
416 414
417 void ServiceWorkerRegisterJob::OnPausedAfterDownload() { 415 void ServiceWorkerRegisterJob::OnPausedAfterDownload() {
418 // TODO(michaeln): Compare the old and new script. 416 // TODO(michaeln): Compare the old and new script.
419 // If different unpause the worker and continue with 417 // If different unpause the worker and continue with
420 // the job. If the same ResolvePromise with the current 418 // the job. If the same ResolvePromise with the current
421 // version and complete the job, throwing away the new version 419 // version and complete the job, throwing away the new version
422 // since there's nothing new. 420 // since there's nothing new.
falken 2014/07/02 05:42:11 Now we have this comment twice.
michaeln 2014/07/02 23:17:14 Done.
423 pending_version()->embedded_worker()->RemoveListener(this); 421 new_version()->embedded_worker()->RemoveListener(this);
424 pending_version()->embedded_worker()->ResumeAfterDownload(); 422 new_version()->embedded_worker()->ResumeAfterDownload();
425 } 423 }
426 424
427 bool ServiceWorkerRegisterJob::OnMessageReceived(const IPC::Message& message) { 425 bool ServiceWorkerRegisterJob::OnMessageReceived(const IPC::Message& message) {
428 return false; 426 return false;
429 } 427 }
430 428
431 // static 429 // static
432 void ServiceWorkerRegisterJob::AssociateWaitingVersionToDocuments( 430 void ServiceWorkerRegisterJob::AssociateInstallingVersionToDocuments(
433 base::WeakPtr<ServiceWorkerContextCore> context, 431 base::WeakPtr<ServiceWorkerContextCore> context,
434 ServiceWorkerVersion* version) { 432 ServiceWorkerVersion* version) {
435 DCHECK(context); 433 DCHECK(context);
436 DCHECK(version); 434 DCHECK(version);
437 435
438 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = 436 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it =
439 context->GetProviderHostIterator(); 437 context->GetProviderHostIterator();
440 !it->IsAtEnd(); 438 !it->IsAtEnd(); it->Advance()) {
441 it->Advance()) {
442 ServiceWorkerProviderHost* host = it->GetProviderHost(); 439 ServiceWorkerProviderHost* host = it->GetProviderHost();
443 if (!host->IsContextAlive())
444 continue;
falken 2014/07/02 05:42:11 I wonder why this was here. Is it possible the pro
nhiroki 2014/07/02 07:25:12 Right. After the corruption recovery, there can be
445 if (ServiceWorkerUtils::ScopeMatches(version->scope(), 440 if (ServiceWorkerUtils::ScopeMatches(version->scope(),
446 host->document_url())) { 441 host->document_url())) {
447 // The spec's _Update algorithm says, "upgrades active version to a new 442 if (!host->CanAssociateVersion(version))
448 // version for the same URL scope.", so skip if the scope (registration)
449 // of |version| is different from that of the current active/waiting
450 // version.
451 if (!host->ValidateVersionForAssociation(version))
452 continue; 443 continue;
453 444 host->SetInstallingVersion(version);
454 // TODO(nhiroki): Keep |host->waiting_version()| to be replaced and set
455 // status of them to 'redandunt' after breaking the loop.
456
457 host->SetWaitingVersion(version);
458 // TODO(nhiroki): Set |host|'s installing version to null.
459 } 445 }
460 } 446 }
461 } 447 }
462 448
463 // static 449 // static
464 void ServiceWorkerRegisterJob::DisassociateWaitingVersionFromDocuments( 450 void ServiceWorkerRegisterJob::DisassociateVersionFromDocuments(
465 base::WeakPtr<ServiceWorkerContextCore> context, 451 base::WeakPtr<ServiceWorkerContextCore> context,
466 int64 version_id) { 452 ServiceWorkerVersion* version) {
467 DCHECK(context); 453 DCHECK(context);
468 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = 454 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it =
469 context->GetProviderHostIterator(); 455 context->GetProviderHostIterator();
470 !it->IsAtEnd(); 456 !it->IsAtEnd(); it->Advance()) {
471 it->Advance()) {
472 ServiceWorkerProviderHost* host = it->GetProviderHost(); 457 ServiceWorkerProviderHost* host = it->GetProviderHost();
473 if (!host->IsContextAlive()) 458 host->UnsetVersion(version);
474 continue;
475 if (host->waiting_version() &&
476 host->waiting_version()->version_id() == version_id) {
477 host->SetWaitingVersion(NULL);
478 }
479 } 459 }
480 } 460 }
481 461
482 } // namespace content 462 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698