Changeset 242372 in webkit
- Timestamp:
- Mar 4, 2019, 12:30:58 PM (7 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
-
ChangeLog (modified) (1 diff)
-
workers/service/ServiceWorkerContainer.cpp (modified) (4 diffs)
-
workers/service/ServiceWorkerContainer.h (modified) (2 diffs)
-
workers/service/ServiceWorkerJob.cpp (modified) (1 diff)
-
workers/service/ServiceWorkerJob.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r242369 r242372 1 2019-03-04 Youenn Fablet <youenn@apple.com> 2 3 Make sure to correctly notify of end of a ServiceWorkerJob when the context is stopped 4 https://bugs.webkit.org/show_bug.cgi?id=195195 5 6 Reviewed by Chris Dumez. 7 8 Before the patch, we were notifying that some jobs were finished too aggressively at context stop time. 9 This was confusing the Network Process. 10 Only notify such jobs that have pending loads. 11 Improve the tracking of jobs doing registration resolution to ensure the Network Process gets notified 12 in case of a registration promise being resolved but the settling callback being not yet called while the context is stopped. 13 14 Covered by existing tests not crashing anymore, in particular imported/w3c/web-platform-tests/service-workers/service-worker/skip-waiting.https.html. 15 16 * workers/service/ServiceWorkerContainer.cpp: 17 (WebCore::ServiceWorkerContainer::jobResolvedWithRegistration): 18 (WebCore::ServiceWorkerContainer::notifyRegistrationIsSettled): 19 (WebCore::ServiceWorkerContainer::stop): 20 * workers/service/ServiceWorkerContainer.h: 21 * workers/service/ServiceWorkerJob.cpp: 22 (WebCore::ServiceWorkerJob::cancelPendingLoad): 23 * workers/service/ServiceWorkerJob.h: 24 (WebCore::ServiceWorkerJob::isLoading const): 25 1 26 2019-03-04 Chris Dumez <cdumez@apple.com> 2 27 -
trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp
r240727 r242372 422 422 ASSERT_WITH_MESSAGE(job.hasPromise() || job.data().type == ServiceWorkerJobType::Update, "Only soft updates have no promise"); 423 423 424 auto guard = WTF::makeScopeExit([this, &job] {425 destroyJob(job);426 });427 428 424 if (job.data().type == ServiceWorkerJobType::Register) 429 425 CONTAINER_RELEASE_LOG_IF_ALLOWED("jobResolvedWithRegistration: Registration job %" PRIu64 " succeeded", job.identifier().toUInt64()); … … 433 429 } 434 430 435 std::function<void()> notifyWhenResolvedIfNeeded; 436 if (shouldNotifyWhenResolved == ShouldNotifyWhenResolved::Yes) { 437 notifyWhenResolvedIfNeeded = [connection = m_swConnection, registrationKey = data.key]() mutable { 438 callOnMainThread([connection = WTFMove(connection), registrationKey = registrationKey.isolatedCopy()] { 439 connection->didResolveRegistrationPromise(registrationKey); 440 }); 441 }; 442 } 443 444 if (isStopped()) { 445 if (notifyWhenResolvedIfNeeded) 446 notifyWhenResolvedIfNeeded(); 447 return; 448 } 431 auto guard = WTF::makeScopeExit([this, &job] { 432 destroyJob(job); 433 }); 434 435 auto notifyIfExitEarly = WTF::makeScopeExit([this, &data, &shouldNotifyWhenResolved] { 436 if (shouldNotifyWhenResolved == ShouldNotifyWhenResolved::Yes) 437 notifyRegistrationIsSettled(data.key); 438 }); 439 440 if (isStopped()) 441 return; 449 442 450 443 auto promise = job.takePromise(); 451 if (!promise) { 452 if (notifyWhenResolvedIfNeeded) 453 notifyWhenResolvedIfNeeded(); 454 return; 455 } 456 457 scriptExecutionContext()->postTask([this, protectedThis = makeRef(*this), promise = WTFMove(promise), jobIdentifier = job.identifier(), data = WTFMove(data), notifyWhenResolvedIfNeeded = WTFMove(notifyWhenResolvedIfNeeded)](ScriptExecutionContext& context) mutable { 444 if (!promise) 445 return; 446 447 notifyIfExitEarly.release(); 448 449 scriptExecutionContext()->postTask([this, protectedThis = RefPtr<ServiceWorkerContainer>(this), promise = WTFMove(promise), jobIdentifier = job.identifier(), data = WTFMove(data), shouldNotifyWhenResolved](ScriptExecutionContext& context) mutable { 458 450 if (isStopped() || !context.sessionID().isValid()) { 459 if ( notifyWhenResolvedIfNeeded)460 notify WhenResolvedIfNeeded();451 if (shouldNotifyWhenResolved == ShouldNotifyWhenResolved::Yes) 452 notifyRegistrationIsSettled(data.key); 461 453 return; 462 454 } … … 466 458 CONTAINER_RELEASE_LOG_IF_ALLOWED("jobResolvedWithRegistration: Resolving promise for job %" PRIu64 ". Registration ID: %" PRIu64, jobIdentifier.toUInt64(), registration->identifier().toUInt64()); 467 459 468 if (notifyWhenResolvedIfNeeded) { 469 promise->whenSettled([notifyWhenResolvedIfNeeded = WTFMove(notifyWhenResolvedIfNeeded)] { 470 notifyWhenResolvedIfNeeded(); 460 if (shouldNotifyWhenResolved == ShouldNotifyWhenResolved::Yes) { 461 m_ongoingSettledRegistrations.add(++m_lastOngoingSettledRegistrationIdentifier, registration->data().key); 462 promise->whenSettled([this, protectedThis = WTFMove(protectedThis), identifier = m_lastOngoingSettledRegistrationIdentifier] { 463 notifyRegistrationIsSettled(m_ongoingSettledRegistrations.take(identifier)); 471 464 }); 472 465 } 473 466 474 467 promise->resolve<IDLInterface<ServiceWorkerRegistration>>(WTFMove(registration)); 468 }); 469 } 470 471 void ServiceWorkerContainer::notifyRegistrationIsSettled(const ServiceWorkerRegistrationKey& registrationKey) 472 { 473 callOnMainThread([connection = m_swConnection, registrationKey = registrationKey.isolatedCopy()] { 474 connection->didResolveRegistrationPromise(registrationKey); 475 475 }); 476 476 } … … 640 640 auto jobMap = WTFMove(m_jobMap); 641 641 for (auto& ongoingJob : jobMap.values()) { 642 notifyFailedFetchingScript(*ongoingJob.job.get(), ResourceError { errorDomainWebKitInternal, 0, ongoingJob.job->data().scriptURL, "Job cancelled"_s, ResourceError::Type::Cancellation }); 643 ongoingJob.job->cancelPendingLoad(); 644 } 642 if (ongoingJob.job->cancelPendingLoad()) 643 notifyFailedFetchingScript(*ongoingJob.job.get(), ResourceError { errorDomainWebKitInternal, 0, ongoingJob.job->data().scriptURL, "Job cancelled"_s, ResourceError::Type::Cancellation }); 644 } 645 646 auto registrationMap = WTFMove(m_ongoingSettledRegistrations); 647 for (auto& registration : registrationMap.values()) 648 notifyRegistrationIsSettled(registration); 645 649 } 646 650 -
trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h
r240727 r242372 115 115 void stop() final; 116 116 117 void notifyRegistrationIsSettled(const ServiceWorkerRegistrationKey&); 118 117 119 std::unique_ptr<ReadyPromise> m_readyPromise; 118 120 … … 146 148 uint64_t m_lastPendingPromiseIdentifier { 0 }; 147 149 HashMap<uint64_t, std::unique_ptr<PendingPromise>> m_pendingPromises; 150 151 uint64_t m_lastOngoingSettledRegistrationIdentifier { 0 }; 152 HashMap<uint64_t, ServiceWorkerRegistrationKey> m_ongoingSettledRegistrations; 153 148 154 }; 149 155 -
trunk/Source/WebCore/workers/service/ServiceWorkerJob.cpp
r240727 r242372 167 167 } 168 168 169 voidServiceWorkerJob::cancelPendingLoad()169 bool ServiceWorkerJob::cancelPendingLoad() 170 170 { 171 171 if (!m_scriptLoader) 172 return; 172 return false; 173 173 174 m_scriptLoader->cancel(); 174 175 m_scriptLoader = nullptr; 176 return true; 175 177 } 176 178 -
trunk/Source/WebCore/workers/service/ServiceWorkerJob.h
r240727 r242372 70 70 const DocumentOrWorkerIdentifier& contextIdentifier() { return m_contextIdentifier; } 71 71 72 voidcancelPendingLoad();72 bool cancelPendingLoad(); 73 73 74 74 private:
Note:
See TracChangeset
for help on using the changeset viewer.