Diff
Modified: trunk/LayoutTests/ChangeLog (224583 => 224584)
--- trunk/LayoutTests/ChangeLog 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/LayoutTests/ChangeLog 2017-11-08 17:26:22 UTC (rev 224584)
@@ -1,3 +1,27 @@
+2017-11-08 Chris Dumez <[email protected]>
+
+ [Service Workers] Support waitUntil() on the 'install' event
+ https://bugs.webkit.org/show_bug.cgi?id=179396
+
+ Reviewed by Brady Eidson.
+
+ Add layout test coverage.
+
+ * http/tests/workers/service/basic-install-event-waitUntil-multiple-promises-expected.txt: Added.
+ * http/tests/workers/service/basic-install-event-waitUntil-multiple-promises.html: Added.
+ * http/tests/workers/service/basic-install-event-waitUntil-reject-expected.txt: Added.
+ * http/tests/workers/service/basic-install-event-waitUntil-reject.html: Added.
+ * http/tests/workers/service/basic-install-event-waitUntil-resolve-expected.txt: Added.
+ * http/tests/workers/service/basic-install-event-waitUntil-resolve.html: Added.
+ * http/tests/workers/service/resources/basic-install-event-waitUntil-multiple-promises-worker.js: Added.
+ (event.i.event.waitUntil.new.Promise):
+ * http/tests/workers/service/resources/basic-install-event-waitUntil-reject-worker.js: Added.
+ (event.event.waitUntil.new.Promise):
+ * http/tests/workers/service/resources/basic-install-event-waitUntil-resolve-worker.js: Added.
+ (event.event.waitUntil.new.Promise):
+ * http/wpt/service-workers/extendableEvent.https-expected.txt:
+ * http/wpt/service-workers/extendableEvent.https.html:
+
2017-11-08 David Hyatt <[email protected]>
[Experiment] Implement code to detect high frequency painting
Added: trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-multiple-promises-expected.txt (0 => 224584)
--- trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-multiple-promises-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-multiple-promises-expected.txt 2017-11-08 17:26:22 UTC (rev 224584)
@@ -0,0 +1,2 @@
+PASS: service worker resolved all extend lifetime promises
+
Added: trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-multiple-promises.html (0 => 224584)
--- trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-multiple-promises.html (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-multiple-promises.html 2017-11-08 17:26:22 UTC (rev 224584)
@@ -0,0 +1,26 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+navigator.serviceWorker.addEventListener("message", function(event) {
+ if (event.data == 10)
+ log("PASS: service worker resolved all extend lifetime promises");
+ else
+ log("FAIL: service worker resolved only " + event.data + " promises");
+
+ finishSWTest();
+});
+
+navigator.serviceWorker.register("resources/basic-install-event-waitUntil-multiple-promises-worker.js", { }).then(function(registration) {
+ waitForState(registration.installing, "installed").then(function() {
+ registration.waiting.postMessage("CheckResolvedExtendLifetimePromises");
+ });
+}, function() {
+ log("FAIL: Failed to register the service worker");
+ finishSWTest();
+});
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-reject-expected.txt (0 => 224584)
--- trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-reject-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-reject-expected.txt 2017-11-08 17:26:22 UTC (rev 224584)
@@ -0,0 +1,2 @@
+PASS: installing worker has become redundant
+
Added: trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-reject.html (0 => 224584)
--- trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-reject.html (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-reject.html 2017-11-08 17:26:22 UTC (rev 224584)
@@ -0,0 +1,18 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+navigator.serviceWorker.register("resources/basic-install-event-waitUntil-reject-worker.js", { }).then(function(registration) {
+ waitForState(registration.installing, "redundant").then(function() {
+ log("PASS: installing worker has become redundant");
+ finishSWTest();
+ });
+}, function() {
+ log("FAIL: Failed to register the service worker");
+ finishSWTest();
+});
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-resolve-expected.txt (0 => 224584)
--- trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-resolve-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-resolve-expected.txt 2017-11-08 17:26:22 UTC (rev 224584)
@@ -0,0 +1,2 @@
+PASS: service worker received install event and resolved the extend lifetime promise
+
Added: trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-resolve.html (0 => 224584)
--- trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-resolve.html (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/basic-install-event-waitUntil-resolve.html 2017-11-08 17:26:22 UTC (rev 224584)
@@ -0,0 +1,26 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+navigator.serviceWorker.addEventListener("message", function(event) {
+ if (event.data)
+ log("PASS: service worker received install event and resolved the extend lifetime promise");
+ else
+ log("FAIL: service worker did not receive install event or did not resolve the extend lifetime promise");
+
+ finishSWTest();
+});
+
+navigator.serviceWorker.register("resources/basic-install-event-waitUntil-resolve-worker.js", { }).then(function(registration) {
+ waitForState(registration.installing, "installed").then(function() {
+ registration.waiting.postMessage("CheckResolvedExtendLifetimePromise");
+ });
+}, function() {
+ log("FAIL: Failed to register the service worker");
+ finishSWTest();
+});
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/workers/service/resources/basic-install-event-waitUntil-multiple-promises-worker.js (0 => 224584)
--- trunk/LayoutTests/http/tests/workers/service/resources/basic-install-event-waitUntil-multiple-promises-worker.js (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/resources/basic-install-event-waitUntil-multiple-promises-worker.js 2017-11-08 17:26:22 UTC (rev 224584)
@@ -0,0 +1,17 @@
+let resolvedPromiseCount = 0;
+
+self.addEventListener("install", (event) => {
+ for (let i = 0; i < 10; i++) {
+ event.waitUntil(new Promise((resolve, reject) => {
+ setTimeout(() => {
+ resolvedPromiseCount++;
+ resolve();
+ }, 50 + i);
+ }));
+ }
+});
+
+self.addEventListener("message", (event) => {
+ event.source.postMessage(resolvedPromiseCount);
+});
+
Added: trunk/LayoutTests/http/tests/workers/service/resources/basic-install-event-waitUntil-reject-worker.js (0 => 224584)
--- trunk/LayoutTests/http/tests/workers/service/resources/basic-install-event-waitUntil-reject-worker.js (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/resources/basic-install-event-waitUntil-reject-worker.js 2017-11-08 17:26:22 UTC (rev 224584)
@@ -0,0 +1,8 @@
+self.addEventListener("install", (event) => {
+ event.waitUntil(new Promise((resolve, reject) => {
+ setTimeout(() => {
+ reject();
+ }, 50);
+ }));
+});
+
Added: trunk/LayoutTests/http/tests/workers/service/resources/basic-install-event-waitUntil-resolve-worker.js (0 => 224584)
--- trunk/LayoutTests/http/tests/workers/service/resources/basic-install-event-waitUntil-resolve-worker.js (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/resources/basic-install-event-waitUntil-resolve-worker.js 2017-11-08 17:26:22 UTC (rev 224584)
@@ -0,0 +1,15 @@
+let resolvedExtendLifetimePromise = false;
+
+self.addEventListener("install", (event) => {
+ event.waitUntil(new Promise((resolve, reject) => {
+ setTimeout(() => {
+ resolvedExtendLifetimePromise = true;
+ resolve();
+ }, 50);
+ }));
+});
+
+self.addEventListener("message", (event) => {
+ event.source.postMessage(resolvedExtendLifetimePromise);
+});
+
Modified: trunk/LayoutTests/http/wpt/service-workers/extendableEvent.https-expected.txt (224583 => 224584)
--- trunk/LayoutTests/http/wpt/service-workers/extendableEvent.https-expected.txt 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/LayoutTests/http/wpt/service-workers/extendableEvent.https-expected.txt 2017-11-08 17:26:22 UTC (rev 224584)
@@ -1,6 +1,4 @@
PASS ExtendableEvent waitUntil should support non promise parameters
-PASS ExtendableEvent should wait for given promise to resolve
-PASS ExtendableEvent should wait for given promise to reject
PASS Event constructors
Modified: trunk/LayoutTests/http/wpt/service-workers/extendableEvent.https.html (224583 => 224584)
--- trunk/LayoutTests/http/wpt/service-workers/extendableEvent.https.html 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/LayoutTests/http/wpt/service-workers/extendableEvent.https.html 2017-11-08 17:26:22 UTC (rev 224584)
@@ -11,38 +11,6 @@
assert_throws('InvalidStateError', () => event.waitUntil(new Request('')));
}, "ExtendableEvent waitUntil should support non promise parameters");
-promise_test(async t => {
- if (!window.internals)
- return Promise.reject("test require internals");
- var event = internals.createTrustedExtendableEvent();
- var promise = internals.waitForExtendableEventToFinish(event);
- var shouldWait = true;
- event.waitUntil(new Promise((resolve, reject) => {
- setTimeout(() => {
- shouldWait = false;
- resolve(new Request(''));
- }, 50);
- }));
- await promise;
- assert_false(shouldWait);
-}, "ExtendableEvent should wait for given promise to resolve");
-
-promise_test(async t => {
- if (!window.internals)
- return Promise.reject("test require internals");
- var event = internals.createTrustedExtendableEvent();
- var promise = internals.waitForExtendableEventToFinish(event);
- var shouldWait = true;
- event.waitUntil(new Promise((resolve, reject) => {
- setTimeout(() => {
- shouldWait = false;
- reject(new Request(''));
- }, 50);
- }));
- await promise;
- assert_false(shouldWait);
-}, "ExtendableEvent should wait for given promise to reject");
-
test(function() {
assert_equals(
new ExtendableEvent('ExtendableEvent').type,
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (224583 => 224584)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2017-11-08 17:26:22 UTC (rev 224584)
@@ -1,3 +1,15 @@
+2017-11-08 Chris Dumez <[email protected]>
+
+ [Service Workers] Support waitUntil() on the 'install' event
+ https://bugs.webkit.org/show_bug.cgi?id=179396
+
+ Reviewed by Brady Eidson.
+
+ Rebaseline a few WPT tests.
+
+ * web-platform-tests/service-workers/service-worker/oninstall-script-error.https-expected.txt:
+ * web-platform-tests/service-workers/service-worker/register-wait-forever-in-install-worker.https-expected.txt:
+
2017-11-08 Ms2ger <[email protected]>
Update XMLHttpRequest tests.
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/oninstall-script-error.https-expected.txt (224583 => 224584)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/oninstall-script-error.https-expected.txt 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/oninstall-script-error.https-expected.txt 2017-11-08 17:26:22 UTC (rev 224584)
@@ -2,7 +2,7 @@
PASS install handler throws an error
PASS install handler throws an error, error handler does not cancel
PASS install handler dispatches an event that throws an error
-FAIL install handler throws an error in the waitUntil assert_equals: The worker was installed expected false but got true
+PASS install handler throws an error in the waitUntil
PASS install handler throws an error that is cancelled
PASS install handler throws an error and prevents default
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/register-wait-forever-in-install-worker.https-expected.txt (224583 => 224584)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/register-wait-forever-in-install-worker.https-expected.txt 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/service-workers/service-worker/register-wait-forever-in-install-worker.https-expected.txt 2017-11-08 17:26:22 UTC (rev 224584)
@@ -1,3 +1,3 @@
-FAIL register worker that calls waitUntil with a promise that never resolves in oninstall promise_test: Unhandled rejection with value: object "TypeError: null is not an object (evaluating 'registration.installing.scriptURL')"
+FAIL register worker that calls waitUntil with a promise that never resolves in oninstall assert_equals: expected "https://localhost:9443/service-workers/service-worker/resources/empty-worker.js" but got "https://localhost:9443/service-workers/service-worker/resources/wait-forever-in-install-worker.js"
Modified: trunk/Source/WebCore/ChangeLog (224583 => 224584)
--- trunk/Source/WebCore/ChangeLog 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/ChangeLog 2017-11-08 17:26:22 UTC (rev 224584)
@@ -1,3 +1,41 @@
+2017-11-08 Chris Dumez <[email protected]>
+
+ [Service Workers] Support waitUntil() on the 'install' event
+ https://bugs.webkit.org/show_bug.cgi?id=179396
+
+ Reviewed by Brady Eidson.
+
+ Support waitUntil() on the 'install' event:
+ - https://w3c.github.io/ServiceWorker/#installation-algorithm (step 10.4)
+ - https://w3c.github.io/ServiceWorker/#wait-until-method
+
+ Tests: http/tests/workers/service/basic-install-event-waitUntil-multiple-promises.html
+ http/tests/workers/service/basic-install-event-waitUntil-reject.html
+ http/tests/workers/service/basic-install-event-waitUntil-resolve.html
+
+ * testing/Internals.cpp:
+ * testing/Internals.h:
+ * testing/Internals.idl:
+ * workers/service/ExtendableEvent.cpp:
+ (WebCore::ExtendableEvent::waitUntil):
+ (WebCore::ExtendableEvent::addExtendLifetimePromise):
+ (WebCore::ExtendableEvent::whenAllExtendLifetimePromisesAreSettled):
+ * workers/service/ExtendableEvent.h:
+ (WebCore::ExtendableEvent::pendingPromiseCount const):
+ * workers/service/FetchEvent.cpp:
+ (WebCore::FetchEvent::respondWith):
+ * workers/service/ServiceWorkerContainer.cpp:
+ (WebCore::ServiceWorkerContainer::addRegistration):
+ (WebCore::ServiceWorkerContainer::removeRegistration):
+ * workers/service/ServiceWorkerContainer.h:
+ * workers/service/context/ServiceWorkerThread.cpp:
+ (WebCore::ServiceWorkerThread::fireInstallEvent):
+ * workers/service/server/SWClientConnection.h:
+ * workers/service/server/SWServerJobQueue.cpp:
+ (WebCore::SWServerJobQueue::didFinishInstall):
+ * workers/service/server/SWServerRegistration.cpp:
+ (WebCore::SWServerRegistration::firePostInstallEvents):
+
2017-11-08 Antti Koivisto <[email protected]>
Remove Element::isInlineElementContinuation
Modified: trunk/Source/WebCore/testing/Internals.cpp (224583 => 224584)
--- trunk/Source/WebCore/testing/Internals.cpp 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/testing/Internals.cpp 2017-11-08 17:26:22 UTC (rev 224584)
@@ -4258,18 +4258,6 @@
});
}
-void Internals::waitForExtendableEventToFinish(ExtendableEvent& event, DOMPromiseDeferred<void>&& promise)
-{
- event.onFinishedWaitingForTesting([promise = WTFMove(promise)] () mutable {
- promise.resolve();
- });
-}
-
-Ref<ExtendableEvent> Internals::createTrustedExtendableEvent()
-{
- return ExtendableEvent::create("ExtendableEvent", { }, Event::IsTrusted::Yes);
-}
-
Ref<FetchEvent> Internals::createBeingDispatchedFetchEvent(ScriptExecutionContext& context)
{
auto event = FetchEvent::createForTesting(context);
Modified: trunk/Source/WebCore/testing/Internals.h (224583 => 224584)
--- trunk/Source/WebCore/testing/Internals.h 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/testing/Internals.h 2017-11-08 17:26:22 UTC (rev 224584)
@@ -617,9 +617,7 @@
#if ENABLE(SERVICE_WORKER)
void waitForFetchEventToFinish(FetchEvent&, DOMPromiseDeferred<IDLInterface<FetchResponse>>&&);
- void waitForExtendableEventToFinish(ExtendableEvent&, DOMPromiseDeferred<void>&&);
Ref<FetchEvent> createBeingDispatchedFetchEvent(ScriptExecutionContext&);
- Ref<ExtendableEvent> createTrustedExtendableEvent();
using HasRegistrationPromise = DOMPromiseDeferred<IDLBoolean>;
void hasServiceWorkerRegistration(const String& clientURL, HasRegistrationPromise&&);
#endif
Modified: trunk/Source/WebCore/testing/Internals.idl (224583 => 224584)
--- trunk/Source/WebCore/testing/Internals.idl 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/testing/Internals.idl 2017-11-08 17:26:22 UTC (rev 224584)
@@ -563,9 +563,7 @@
DOMString audioSessionCategory();
[Conditional=SERVICE_WORKER] Promise<Response> waitForFetchEventToFinish(FetchEvent event);
- [Conditional=SERVICE_WORKER] Promise<void> waitForExtendableEventToFinish(ExtendableEvent event);
[Conditional=SERVICE_WORKER, CallWith=ScriptExecutionContext] FetchEvent createBeingDispatchedFetchEvent();
- [Conditional=SERVICE_WORKER] ExtendableEvent createTrustedExtendableEvent();
[Conditional=SERVICE_WORKER] Promise<boolean> hasServiceWorkerRegistration(DOMString scopeURL);
boolean hasServiceWorkerRegisteredForOrigin(DOMString origin);
Modified: trunk/Source/WebCore/workers/service/ExtendableEvent.cpp (224583 => 224584)
--- trunk/Source/WebCore/workers/service/ExtendableEvent.cpp 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/workers/service/ExtendableEvent.cpp 2017-11-08 17:26:22 UTC (rev 224584)
@@ -46,41 +46,52 @@
{
}
+// https://w3c.github.io/ServiceWorker/#dom-extendableevent-waituntil
ExceptionOr<void> ExtendableEvent::waitUntil(Ref<DOMPromise>&& promise)
{
if (!isTrusted())
return Exception { InvalidStateError, ASCIILiteral("Event is not trusted") };
- if (m_pendingPromises.isEmpty() && isBeingDispatched())
- return Exception { InvalidStateError, ASCIILiteral("Event is being dispatched") };
+ // If the pending promises count is zero and the dispatch flag is unset, throw an "InvalidStateError" DOMException.
+ if (!m_pendingPromiseCount && !isBeingDispatched())
+ return Exception { InvalidStateError, ASCIILiteral("Event is no longer being dispatched and has no pending promises") };
- addPendingPromise(WTFMove(promise));
+ addExtendLifetimePromise(WTFMove(promise));
return { };
}
-void ExtendableEvent::onFinishedWaitingForTesting(WTF::Function<void()>&& callback)
+void ExtendableEvent::addExtendLifetimePromise(Ref<DOMPromise>&& promise)
{
- ASSERT(!m_onFinishedWaitingForTesting);
- m_onFinishedWaitingForTesting = WTFMove(callback);
-}
+ promise->whenSettled([this, protectedThis = makeRefPtr(this), settledPromise = promise.ptr()] () {
+ --m_pendingPromiseCount;
-void ExtendableEvent::addPendingPromise(Ref<DOMPromise>&& promise)
-{
- promise->whenSettled([this, weakThis = createWeakPtr(), settledPromise = promise.ptr()] () {
- if (!weakThis)
+ // FIXME: Let registration be the context object's relevant global object's associated service worker's containing service worker registration.
+ // FIXME: If registration's uninstalling flag is set, invoke Try Clear Registration with registration.
+ // FIXME: If registration is not null, invoke Try Activate with registration.
+
+ if (m_pendingPromiseCount)
return;
- auto promise = m_pendingPromises.take(*settledPromise);
+ auto settledPromises = WTFMove(m_extendLifetimePromises);
+ if (auto handler = WTFMove(m_whenAllExtendLifetimePromisesAreSettledHandler))
+ handler(WTFMove(settledPromises));
+ });
- // FIXME: Implement registration handling as per https://w3c.github.io/ServiceWorker/v1/#dom-extendableevent-waituntil.
+ m_extendLifetimePromises.add(WTFMove(promise));
+ ++m_pendingPromiseCount;
+}
- if (!m_pendingPromises.isEmpty())
- return;
+void ExtendableEvent::whenAllExtendLifetimePromisesAreSettled(WTF::Function<void(HashSet<Ref<DOMPromise>>&&)>&& handler)
+{
+ ASSERT_WITH_MESSAGE(target(), "Event has not been dispatched yet");
+ ASSERT(!m_whenAllExtendLifetimePromisesAreSettledHandler);
- if (auto callback = WTFMove(m_onFinishedWaitingForTesting))
- callback();
- });
- m_pendingPromises.add(WTFMove(promise));
+ if (!m_pendingPromiseCount) {
+ handler(WTFMove(m_extendLifetimePromises));
+ return;
+ }
+
+ m_whenAllExtendLifetimePromisesAreSettledHandler = WTFMove(handler);
}
} // namespace WebCore
Modified: trunk/Source/WebCore/workers/service/ExtendableEvent.h (224583 => 224584)
--- trunk/Source/WebCore/workers/service/ExtendableEvent.h 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/workers/service/ExtendableEvent.h 2017-11-08 17:26:22 UTC (rev 224584)
@@ -47,8 +47,9 @@
EventInterface eventInterface() const override { return ExtendableEventInterfaceType; }
ExceptionOr<void> waitUntil(Ref<DOMPromise>&&);
+ unsigned pendingPromiseCount() const { return m_pendingPromiseCount; }
- WEBCORE_EXPORT void onFinishedWaitingForTesting(WTF::Function<void()>&&);
+ WEBCORE_EXPORT void whenAllExtendLifetimePromisesAreSettled(WTF::Function<void(HashSet<Ref<DOMPromise>>&&)>&&);
protected:
WEBCORE_EXPORT ExtendableEvent(const AtomicString&, const ExtendableEventInit&, IsTrusted);
@@ -56,12 +57,13 @@
WeakPtr<ExtendableEvent> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(*this); }
- void addPendingPromise(Ref<DOMPromise>&&);
+ void addExtendLifetimePromise(Ref<DOMPromise>&&);
private:
- HashSet<Ref<DOMPromise>> m_pendingPromises;
+ unsigned m_pendingPromiseCount { 0 };
+ HashSet<Ref<DOMPromise>> m_extendLifetimePromises;
WeakPtrFactory<ExtendableEvent> m_weakPtrFactory;
- WTF::Function<void()> m_onFinishedWaitingForTesting;
+ WTF::Function<void(HashSet<Ref<DOMPromise>>&&)> m_whenAllExtendLifetimePromisesAreSettledHandler;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/workers/service/FetchEvent.cpp (224583 => 224584)
--- trunk/Source/WebCore/workers/service/FetchEvent.cpp 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/workers/service/FetchEvent.cpp 2017-11-08 17:26:22 UTC (rev 224584)
@@ -64,7 +64,7 @@
return Exception { InvalidStateError, ASCIILiteral("Event respondWith flag is set") };
m_respondPromise = WTFMove(promise);
- addPendingPromise(*m_respondPromise);
+ addExtendLifetimePromise(*m_respondPromise);
m_respondPromise->whenSettled([this, weakThis = createWeakPtr()] () {
if (!weakThis)
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp (224583 => 224584)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.cpp 2017-11-08 17:26:22 UTC (rev 224584)
@@ -449,6 +449,18 @@
return !hasPendingActivity();
}
+void ServiceWorkerContainer::addRegistration(ServiceWorkerRegistration& registration)
+{
+ m_swConnection->addServiceWorkerRegistrationInServer(registration.data().key, registration.identifier());
+ m_registrations.add(registration.data().key, ®istration);
+}
+
+void ServiceWorkerContainer::removeRegistration(ServiceWorkerRegistration& registration)
+{
+ m_swConnection->removeServiceWorkerRegistrationInServer(registration.data().key, registration.identifier());
+ m_registrations.remove(registration.data().key);
+}
+
} // namespace WebCore
#endif // ENABLE(SERVICE_WORKER)
Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h (224583 => 224584)
--- trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContainer.h 2017-11-08 17:26:22 UTC (rev 224584)
@@ -72,8 +72,8 @@
using RegistrationsPromise = DOMPromiseDeferred<IDLSequence<IDLInterface<ServiceWorkerRegistration>>>;
void getRegistrations(RegistrationsPromise&&);
- void addRegistration(ServiceWorkerRegistration& registration) { m_registrations.add(registration.data().key, ®istration); }
- void removeRegistration(ServiceWorkerRegistration& registration) { m_registrations.remove(registration.data().key); }
+ void addRegistration(ServiceWorkerRegistration&);
+ void removeRegistration(ServiceWorkerRegistration&);
void startMessages();
Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp (224583 => 224584)
--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp 2017-11-08 17:26:22 UTC (rev 224584)
@@ -32,6 +32,7 @@
#include "ContentSecurityPolicyResponseHeaders.h"
#include "EventNames.h"
#include "ExtendableMessageEvent.h"
+#include "JSDOMPromise.h"
#include "SecurityOrigin.h"
#include "ServiceWorkerFetch.h"
#include "ServiceWorkerGlobalScope.h"
@@ -122,10 +123,18 @@
auto installEvent = ExtendableEvent::create(eventNames().installEvent, { }, ExtendableEvent::IsTrusted::Yes);
serviceWorkerGlobalScope.dispatchEvent(installEvent);
- // FIXME: We are supposed to wait for all installEvent's extend lifetime promises.
- callOnMainThread([serviceWorkerIdentifier] () mutable {
- if (auto* connection = SWContextManager::singleton().connection())
- connection->didFinishInstall(serviceWorkerIdentifier, true);
+ installEvent->whenAllExtendLifetimePromisesAreSettled([serviceWorkerIdentifier](HashSet<Ref<DOMPromise>>&& extendLifetimePromises) {
+ bool hasRejectedAnyPromise = false;
+ for (auto& promise : extendLifetimePromises) {
+ if (promise->status() == DOMPromise::Status::Rejected) {
+ hasRejectedAnyPromise = true;
+ break;
+ }
+ }
+ callOnMainThread([serviceWorkerIdentifier, hasRejectedAnyPromise] () mutable {
+ if (auto* connection = SWContextManager::singleton().connection())
+ connection->didFinishInstall(serviceWorkerIdentifier, !hasRejectedAnyPromise);
+ });
});
});
runLoop().postTask(WTFMove(task));
Modified: trunk/Source/WebCore/workers/service/server/SWClientConnection.h (224583 => 224584)
--- trunk/Source/WebCore/workers/service/server/SWClientConnection.h 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/workers/service/server/SWClientConnection.h 2017-11-08 17:26:22 UTC (rev 224584)
@@ -52,6 +52,9 @@
using RegistrationCallback = WTF::CompletionHandler<void(std::optional<ServiceWorkerRegistrationData>&&)>;
virtual void matchRegistration(const SecurityOrigin& topOrigin, const URL& clientURL, RegistrationCallback&&) = 0;
+ virtual void addServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier) = 0;
+ virtual void removeServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier) = 0;
+
void scheduleJob(ServiceWorkerJob&);
void finishedFetchingScript(ServiceWorkerJob&, const String&);
void failedFetchingScript(ServiceWorkerJob&, const ResourceError&);
@@ -76,8 +79,6 @@
private:
virtual void scheduleJobInServer(const ServiceWorkerJobData&) = 0;
virtual void finishFetchingScriptInServer(const ServiceWorkerFetchResult&) = 0;
- virtual void addServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier) = 0;
- virtual void removeServiceWorkerRegistrationInServer(const ServiceWorkerRegistrationKey&, uint64_t registrationIdentifier) = 0;
void forEachContainer(const WTF::Function<void(ServiceWorkerContainer&)>& apply);
HashMap<uint64_t, RefPtr<ServiceWorkerJob>> m_scheduledJobs;
Modified: trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp (224583 => 224584)
--- trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp 2017-11-08 17:26:22 UTC (rev 224584)
@@ -131,15 +131,20 @@
}
// https://w3c.github.io/ServiceWorker/#install
-void SWServerJobQueue::didFinishInstall(SWServer::Connection&, ServiceWorkerIdentifier, bool wasSuccessful)
+void SWServerJobQueue::didFinishInstall(SWServer::Connection&, ServiceWorkerIdentifier identifier, bool wasSuccessful)
{
auto* registration = m_server.getRegistration(m_registrationKey);
ASSERT(registration);
if (!wasSuccessful) {
- // FIXME: Run the Update Worker State algorithm passing registration's installing worker and redundant as the arguments.
- // FIXME: Run the Update Registration State algorithm passing registration, "installing" and null as the arguments.
+ auto* worker = m_server.workerByID(identifier);
+ RELEASE_ASSERT(worker);
+ // Run the Update Worker State algorithm passing registration's installing worker and redundant as the arguments.
+ registration->updateWorkerState(*worker, ServiceWorkerState::Redundant);
+ // Run the Update Registration State algorithm passing registration, "installing" and null as the arguments.
+ registration->updateRegistrationState(ServiceWorkerRegistrationState::Installing, nullptr);
+
// If newestWorker is null, invoke Clear Registration algorithm passing registration as its argument.
if (!registration->getNewestWorker())
clearRegistration(*registration);
Modified: trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp (224583 => 224584)
--- trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp 2017-11-08 16:39:02 UTC (rev 224583)
+++ trunk/Source/WebCore/workers/service/server/SWServerRegistration.cpp 2017-11-08 17:26:22 UTC (rev 224584)
@@ -122,6 +122,9 @@
connection->firePostInstallEvents(m_registrationKey);
for (auto& connectionIdentifierWithClients : m_clientRegistrationsByConnection.keys()) {
+ if (connectionIdentifierWithClients == connectionIdentifier)
+ continue;
+
if (auto* connection = m_server.getConnection(connectionIdentifierWithClients))
connection->firePostInstallEvents(m_registrationKey);
}