ServiceWorkerRegistration objects may get recycled for different SWServerRegistration...
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Nov 2017 06:26:40 +0000 (06:26 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 Nov 2017 06:26:40 +0000 (06:26 +0000)
commit591a10d962a127d5b39f2dd19082d8d64922b758
tree344deb4963db62d5a2e61a68e00b0e6c89f32e8f
parent32143645667ab099540fad9327763b9c5ec07058
ServiceWorkerRegistration objects may get recycled for different SWServerRegistration objects
https://bugs.webkit.org/show_bug.cgi?id=179517

Reviewed by Brady Eidson.

LayoutTests/imported/w3c:

* web-platform-tests/service-workers/service-worker/ready.https-expected.txt:
The test fails differently. The failure is expected here since we do not implement the
"Try Clear Registration" algorithm. As a result, we do not support resurrecting a
registration with the 'uninstalling' flag set. We always clear uninstalling registrations
on server side for now.

* web-platform-tests/service-workers/service-worker/unregister-then-register.https-expected.txt:
Same reason as above. The second checks calls unregister() for a registration that is "in use"
as expects it to get resurrected when calling register() again. We currently always clear
registrations that are unregistered on server side.

Source/WebCore:

ServiceWorkerRegistration objects could get recycled for different SWServerRegistration objects, leading to
flakiness in the tests. We uses ServiceWorkerRegistrationKey as key in the m_registration map on WebProcess
side. The lifetime of the ServiceWorkerRegistration objects is tied to the lifetime of their JS wrapper.
When a test does a registration for a given scope, then unregisters, then registers again for the same scope,
we would end up creating a new SWServerRegistration object on server side, but possibly reuse the same
ServiceWorkerRegistration object on WebProcess side, if its wrapper has not yet been garbage collected.
This is because the registrations have the same ServiceWorkerRegistrationKey in this case.

To address the issue, we now use the ServiceWorkerRegistrationIdentifier as key in the m_registration
hash map. A SWServerRegistration has a unique ServiceWorkerRegistrationIdentifier on server side.
All its clients ServiceWorkerRegistration also use the same ServiceWorkerRegistrationIdentifier.

Test: http/tests/workers/service/basic-unregister-then-register-again-no-reuse.html

* workers/service/ServiceWorkerContainer.cpp:
(WebCore::ServiceWorkerContainer::getRegistration):
(WebCore::ServiceWorkerContainer::scheduleTaskToUpdateRegistrationState):
(WebCore::ServiceWorkerContainer::scheduleTaskToFireUpdateFoundEvent):
(WebCore::ServiceWorkerContainer::jobResolvedWithRegistration):
(WebCore::ServiceWorkerContainer::addRegistration):
(WebCore::ServiceWorkerContainer::removeRegistration):
* workers/service/ServiceWorkerContainer.h:
* workers/service/ServiceWorkerRegistration.h:
* workers/service/ServiceWorkerRegistrationData.h:
(WebCore::ServiceWorkerRegistrationData::decode):
* workers/service/server/SWClientConnection.cpp:
(WebCore::SWClientConnection::updateRegistrationState):
(WebCore::SWClientConnection::fireUpdateFoundEvent):
* workers/service/server/SWClientConnection.h:
* workers/service/server/SWServer.cpp:
(WebCore::SWServer::Connection::addServiceWorkerRegistrationInServer):
(WebCore::SWServer::Connection::removeServiceWorkerRegistrationInServer):
(WebCore::SWServer::resolveRegistrationJob):
(WebCore::SWServer::addClientServiceWorkerRegistration):
(WebCore::SWServer::removeClientServiceWorkerRegistration):
* workers/service/server/SWServer.h:
* workers/service/server/SWServerRegistration.cpp:
(WebCore::generateServiceWorkerRegistrationIdentifier):
(WebCore::SWServerRegistration::SWServerRegistration):
(WebCore::SWServerRegistration::updateRegistrationState):
(WebCore::SWServerRegistration::fireUpdateFoundEvent):
(WebCore::SWServerRegistration::forEachConnection):
(WebCore::SWServerRegistration::addClientServiceWorkerRegistration):
(WebCore::SWServerRegistration::removeClientServiceWorkerRegistration):
* workers/service/server/SWServerRegistration.h:
(WebCore::SWServerRegistration::identifier const):

Source/WebKit:

* Scripts/webkit/messages.py:
(forward_declarations_and_headers):
* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::updateRegistrationStateInClient):
(WebKit::WebSWServerConnection::fireUpdateFoundEvent):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
* StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
* WebProcess/Storage/WebSWClientConnection.cpp:
(WebKit::WebSWClientConnection::addServiceWorkerRegistrationInServer):
(WebKit::WebSWClientConnection::removeServiceWorkerRegistrationInServer):
* WebProcess/Storage/WebSWClientConnection.h:
* WebProcess/Storage/WebSWClientConnection.messages.in:

LayoutTests:

Add layout test coverage.

* http/tests/workers/service/basic-unregister-then-register-again-no-reuse-expected.txt: Added.
* http/tests/workers/service/basic-unregister-then-register-again-no-reuse.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@224664 268f45cc-cd09-0410-ab3c-d52691b4dbfc
26 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/workers/service/basic-unregister-then-register-again-no-reuse-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/workers/service/basic-unregister-then-register-again-no-reuse.html [new file with mode: 0644]
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/ready.https-expected.txt
LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/unregister-then-register.https-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/workers/service/ServiceWorkerContainer.cpp
Source/WebCore/workers/service/ServiceWorkerContainer.h
Source/WebCore/workers/service/ServiceWorkerRegistration.h
Source/WebCore/workers/service/ServiceWorkerRegistrationData.h
Source/WebCore/workers/service/ServiceWorkerTypes.h
Source/WebCore/workers/service/server/SWClientConnection.cpp
Source/WebCore/workers/service/server/SWClientConnection.h
Source/WebCore/workers/service/server/SWServer.cpp
Source/WebCore/workers/service/server/SWServer.h
Source/WebCore/workers/service/server/SWServerRegistration.cpp
Source/WebCore/workers/service/server/SWServerRegistration.h
Source/WebKit/ChangeLog
Source/WebKit/Scripts/webkit/messages.py
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.messages.in
Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp
Source/WebKit/WebProcess/Storage/WebSWClientConnection.h
Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in