Title: [224584] trunk
Revision
224584
Author
[email protected]
Date
2017-11-08 09:26:22 -0800 (Wed, 08 Nov 2017)

Log Message

[Service Workers] Support waitUntil() on the 'install' event
https://bugs.webkit.org/show_bug.cgi?id=179396

Reviewed by Brady Eidson.

LayoutTests/imported/w3c:

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:

Source/WebCore:

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):

LayoutTests:

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:

Modified Paths

Added Paths

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, &registration);
+}
+
+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, &registration); }
-    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);
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to