Skip to content

Commit

Permalink
SWServerJobQueue::scriptContextStarted might have a null registration
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=259591
rdar://112997411

Reviewed by Alex Christensen.

From logs, it appears SWServerJobQueue::scriptContextStarted might have a nullptr registration.
One possibility is the following:
- A main thread service worker page is created.
- The service worker is being installed (in main thread) and succeeds. This triggers a callOnMainThread to execute the callback that will notify network process to continue its processing
- Before the callback is executed, the service worker page is closed and the network process is notified about this.
- The network process removes the registration from its map in SWServer::unregisterServiceWorkerClient.
- The network process processes the message to continue installing the service worker and continue with the current job.

To prevent this, we are now making sure to cancel the job of a preinstalling service worker whose registration is removed in SWServer::unregisterServiceWorkerClient.
Since this is a speculative fix, we transform the ASSERT(registration) in an if+ASSERT.
We add logging to make sure to keep track of this, in case this might trigger job queue hangs.

* Source/WebCore/workers/service/server/SWServer.cpp:
(WebCore::SWServer::unregisterServiceWorkerClient):
* Source/WebCore/workers/service/server/SWServerJobQueue.cpp:
(WebCore::SWServerJobQueue::scriptContextFailedToStart):
(WebCore::SWServerJobQueue::scriptContextStarted):

Canonical link: https://commits.webkit.org/266419@main
  • Loading branch information
youennf committed Jul 30, 2023
1 parent 57717fd commit 3cb928b
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Source/WebCore/workers/service/server/SWServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,10 @@ void SWServer::unregisterServiceWorkerClient(const ClientOrigin& clientOrigin, S
bool didUnregister = false;
if (auto registration = m_serviceWorkerPageIdentifierToRegistrationMap.get(clientIdentifier)) {
removeFromScopeToRegistrationMap(registration->key());
if (auto* preinstallingServiceWorker = registration->preInstallationWorker()) {
if (auto* jobQueue = m_jobQueues.get(registration->key()))
jobQueue->cancelJobsFromServiceWorker(preinstallingServiceWorker->identifier());
}
registration->clear();
ASSERT(!m_serviceWorkerPageIdentifierToRegistrationMap.contains(clientIdentifier));
didUnregister = true;
Expand Down
8 changes: 8 additions & 0 deletions Source/WebCore/workers/service/server/SWServerJobQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ void SWServerJobQueue::scriptContextFailedToStart(const ServiceWorkerJobDataIden
// If an uncaught runtime script error occurs during the above step, then:
auto* registration = m_server.getRegistration(m_registrationKey);
ASSERT(registration);
if (!registration || !registration->preInstallationWorker()) {
RELEASE_LOG_ERROR(ServiceWorker, "SWServerJobQueue::scriptContextFailedToStart registration is null (%d) or pre installation worker is null", !registration);
return;
}

ASSERT(registration->preInstallationWorker());
registration->preInstallationWorker()->terminate();
Expand All @@ -181,6 +185,10 @@ void SWServerJobQueue::scriptContextStarted(const ServiceWorkerJobDataIdentifier

auto* registration = m_server.getRegistration(m_registrationKey);
ASSERT(registration);
if (!registration) {
RELEASE_LOG_ERROR(ServiceWorker, "SWServerJobQueue::scriptContextStarted registration is null");
return;
}

install(*registration, identifier);
}
Expand Down

0 comments on commit 3cb928b

Please sign in to comment.