<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[224772] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/224772">224772</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2017-11-13 13:06:23 -0800 (Mon, 13 Nov 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Implement "Service Worker Has No Pending Events" / "Update Service Worker Extended Events Set" algorithms
https://bugs.webkit.org/show_bug.cgi?id=179618

Reviewed by Brady Eidson.

Source/WebCore:

Implement "Service Worker Has No Pending Events" / "Update Service Worker Extended Events Set" algorithms:
- https://w3c.github.io/ServiceWorker/#service-worker-has-no-pending-events-algorithm
- https://w3c.github.io/ServiceWorker/#update-service-worker-extended-events-set-algorithm

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

* workers/service/context/SWContextManager.h:
* workers/service/context/ServiceWorkerFetch.cpp:
(WebCore::ServiceWorkerFetch::dispatchFetchEvent):
* workers/service/context/ServiceWorkerFetch.h:
* workers/service/context/ServiceWorkerThread.cpp:
(WebCore::ServiceWorkerThread::postFetchTask):
(WebCore::ServiceWorkerThread::postMessageToServiceWorkerGlobalScope):
(WebCore::ServiceWorkerThread::updateExtendedEventsSet):
* workers/service/context/ServiceWorkerThread.h:
* workers/service/server/SWServer.cpp:
(WebCore::SWServer::Connection::setServiceWorkerHasPendingEvents):
(WebCore::SWServer::setServiceWorkerHasPendingEvents):
* workers/service/server/SWServer.h:
* workers/service/server/SWServerJobQueue.cpp:
(WebCore::SWServerJobQueue::tryActivate):
(WebCore::SWServerJobQueue::tryClearRegistration):
* workers/service/server/SWServerWorker.h:
(WebCore::SWServerWorker::hasPendingEvents const):
(WebCore::SWServerWorker::setHasPendingEvents):

Source/WebKit:

* StorageProcess/StorageProcess.cpp:
(WebKit::StorageProcess::setServiceWorkerHasPendingEvents):
* StorageProcess/StorageProcess.h:
* StorageProcess/StorageProcess.messages.in:
* WebProcess/Storage/WebSWContextManagerConnection.cpp:
(WebKit::WebSWContextManagerConnection::setServiceWorkerHasPendingEvents):
* WebProcess/Storage/WebSWContextManagerConnection.h:

LayoutTests:

Add layout test coverage.

* http/tests/workers/service/basic-unregister-then-register-again-reuse-expected.txt: Added.
* http/tests/workers/service/basic-unregister-then-register-again-reuse.html: Added.
* http/tests/workers/service/resources/basic-unregister-then-register-again-reuse-worker.js: Added.
(event.waitUntil.new.Promise):
(setTimeout):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreworkersservicecontextSWContextManagerh">trunk/Source/WebCore/workers/service/context/SWContextManager.h</a></li>
<li><a href="#trunkSourceWebCoreworkersservicecontextServiceWorkerFetchcpp">trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersservicecontextServiceWorkerFetchh">trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h</a></li>
<li><a href="#trunkSourceWebCoreworkersservicecontextServiceWorkerThreadcpp">trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersservicecontextServiceWorkerThreadh">trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceserverSWServercpp">trunk/Source/WebCore/workers/service/server/SWServer.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceserverSWServerh">trunk/Source/WebCore/workers/service/server/SWServer.h</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceserverSWServerJobQueuecpp">trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersserviceserverSWServerWorkerh">trunk/Source/WebCore/workers/service/server/SWServerWorker.h</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitStorageProcessStorageProcesscpp">trunk/Source/WebKit/StorageProcess/StorageProcess.cpp</a></li>
<li><a href="#trunkSourceWebKitStorageProcessStorageProcessh">trunk/Source/WebKit/StorageProcess/StorageProcess.h</a></li>
<li><a href="#trunkSourceWebKitStorageProcessStorageProcessmessagesin">trunk/Source/WebKit/StorageProcess/StorageProcess.messages.in</a></li>
<li><a href="#trunkSourceWebKitWebProcessStorageWebSWContextManagerConnectioncpp">trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp</a></li>
<li><a href="#trunkSourceWebKitWebProcessStorageWebSWContextManagerConnectionh">trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestshttptestsworkersservicebasicunregisterthenregisteragainreuseexpectedtxt">trunk/LayoutTests/http/tests/workers/service/basic-unregister-then-register-again-reuse-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestsworkersservicebasicunregisterthenregisteragainreusehtml">trunk/LayoutTests/http/tests/workers/service/basic-unregister-then-register-again-reuse.html</a></li>
<li><a href="#trunkLayoutTestshttptestsworkersserviceresourcesbasicunregisterthenregisteragainreuseworkerjs">trunk/LayoutTests/http/tests/workers/service/resources/basic-unregister-then-register-again-reuse-worker.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/LayoutTests/ChangeLog 2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-11-13  Chris Dumez  <cdumez@apple.com>
+
+        Implement "Service Worker Has No Pending Events" / "Update Service Worker Extended Events Set" algorithms
+        https://bugs.webkit.org/show_bug.cgi?id=179618
+
+        Reviewed by Brady Eidson.
+
+        Add layout test coverage.
+
+        * http/tests/workers/service/basic-unregister-then-register-again-reuse-expected.txt: Added.
+        * http/tests/workers/service/basic-unregister-then-register-again-reuse.html: Added.
+        * http/tests/workers/service/resources/basic-unregister-then-register-again-reuse-worker.js: Added.
+        (event.waitUntil.new.Promise):
+        (setTimeout):
+
</ins><span class="cx"> 2017-11-13  Ryan Haddad  <ryanhaddad@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Adjust TestExpectation for js/intl-datetimeformat.html.
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsworkersservicebasicunregisterthenregisteragainreuseexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/workers/service/basic-unregister-then-register-again-reuse-expected.txt (0 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/workers/service/basic-unregister-then-register-again-reuse-expected.txt                             (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/basic-unregister-then-register-again-reuse-expected.txt        2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+PASS: registration1 should not have an installing worker
+PASS: registration1 should not have a waiting worker
+PASS: registration1 should have an active worker
+PASS: Registration was reused
+
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsworkersservicebasicunregisterthenregisteragainreusehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/workers/service/basic-unregister-then-register-again-reuse.html (0 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/workers/service/basic-unregister-then-register-again-reuse.html                             (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/basic-unregister-then-register-again-reuse.html        2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+<html>
+<head>
+<script src="resources/sw-test-pre.js"></script>
+</head>
+<body>
+<script>
+
+function waitForMessageEvent()
+{
+    return new Promise(resolve => {
+        navigator.serviceWorker.addEventListener('message', resolve, { once: true });
+    });
+}
+
+async function test()
+{
+    try {
+         let registration1 = await navigator.serviceWorker.register("resources/basic-unregister-then-register-again-reuse-worker.js", { });
+         await waitForState(registration1.installing, "activated");
+         if (registration1.installing)
+             log("FAIL: registration1 should not have an installing worker");
+         else
+             log("PASS: registration1 should not have an installing worker");
+
+         if (registration1.waiting)
+             log("FAIL: registration1 should not have a waiting worker");
+         else
+             log("PASS: registration1 should not have a waiting worker");
+
+         if (registration1.active)
+             log("PASS: registration1 should have an active worker");
+         else
+             log("FAIL: registration1 should have an active worker");
+
+         // Service worker will use waitUntil() on the received ExtendableMessageEvent to extend its lifetime.
+         registration1.active.postMessage("ExtendLifetime");
+
+         await waitForMessageEvent();
+         await registration1.unregister();
+
+         let registration2 = await navigator.serviceWorker.register("resources/basic-unregister-then-register-again-reuse-worker.js", { });
+         if (registration1 === registration2)
+             log("PASS: Registration was reused");
+         else
+             log("FAIL: Registration was not reused");
+    } catch (e) {
+        log("FAIL: Got exception " + e);
+    }
+    finishSWTest();
+}
+
+test();
+</script>
+</body>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestshttptestsworkersserviceresourcesbasicunregisterthenregisteragainreuseworkerjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/http/tests/workers/service/resources/basic-unregister-then-register-again-reuse-worker.js (0 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/workers/service/resources/basic-unregister-then-register-again-reuse-worker.js                              (rev 0)
+++ trunk/LayoutTests/http/tests/workers/service/resources/basic-unregister-then-register-again-reuse-worker.js 2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -0,0 +1,11 @@
</span><ins>+self.addEventListener("message", function(event) {
+    event.waitUntil(new Promise((resolve, reject) => {
+        setTimeout(() => {
+            resolve();
+        }, 10000);
+    }));
+    client = event.source;
+    setTimeout(function() {
+        client.postMessage("ExtendedLifetime");
+    }, 0);
+});
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebCore/ChangeLog      2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2017-11-13  Chris Dumez  <cdumez@apple.com>
+
+        Implement "Service Worker Has No Pending Events" / "Update Service Worker Extended Events Set" algorithms
+        https://bugs.webkit.org/show_bug.cgi?id=179618
+
+        Reviewed by Brady Eidson.
+
+        Implement "Service Worker Has No Pending Events" / "Update Service Worker Extended Events Set" algorithms:
+        - https://w3c.github.io/ServiceWorker/#service-worker-has-no-pending-events-algorithm
+        - https://w3c.github.io/ServiceWorker/#update-service-worker-extended-events-set-algorithm
+
+        Test: http/tests/workers/service/basic-unregister-then-register-again-reuse.html
+
+        * workers/service/context/SWContextManager.h:
+        * workers/service/context/ServiceWorkerFetch.cpp:
+        (WebCore::ServiceWorkerFetch::dispatchFetchEvent):
+        * workers/service/context/ServiceWorkerFetch.h:
+        * workers/service/context/ServiceWorkerThread.cpp:
+        (WebCore::ServiceWorkerThread::postFetchTask):
+        (WebCore::ServiceWorkerThread::postMessageToServiceWorkerGlobalScope):
+        (WebCore::ServiceWorkerThread::updateExtendedEventsSet):
+        * workers/service/context/ServiceWorkerThread.h:
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::Connection::setServiceWorkerHasPendingEvents):
+        (WebCore::SWServer::setServiceWorkerHasPendingEvents):
+        * workers/service/server/SWServer.h:
+        * workers/service/server/SWServerJobQueue.cpp:
+        (WebCore::SWServerJobQueue::tryActivate):
+        (WebCore::SWServerJobQueue::tryClearRegistration):
+        * workers/service/server/SWServerWorker.h:
+        (WebCore::SWServerWorker::hasPendingEvents const):
+        (WebCore::SWServerWorker::setHasPendingEvents):
+
</ins><span class="cx"> 2017-11-13  Colin Bendell  <colin@bendell.ca>
</span><span class="cx"> 
</span><span class="cx">         Added mime type check to the picture source preloader to avoid downloading incompatible resources.
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersservicecontextSWContextManagerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/context/SWContextManager.h (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/context/SWContextManager.h  2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebCore/workers/service/context/SWContextManager.h     2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx">         virtual void serviceWorkerStartedWithMessage(ServiceWorkerIdentifier, const String& exceptionMessage) = 0;
</span><span class="cx">         virtual void didFinishInstall(ServiceWorkerIdentifier, bool wasSuccessful) = 0;
</span><span class="cx">         virtual void didFinishActivation(ServiceWorkerIdentifier) = 0;
</span><ins>+        virtual void setServiceWorkerHasPendingEvents(ServiceWorkerIdentifier, bool) = 0;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT void setConnection(std::unique_ptr<Connection>&&);
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersservicecontextServiceWorkerFetchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp      2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.cpp 2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -85,7 +85,7 @@
</span><span class="cx">     client->didFinish();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void dispatchFetchEvent(Ref<Client>&& client, WorkerGlobalScope& globalScope, ResourceRequest&& request, FetchOptions&& options)
</del><ins>+Ref<FetchEvent> dispatchFetchEvent(Ref<Client>&& client, WorkerGlobalScope& globalScope, ResourceRequest&& request, FetchOptions&& options)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(globalScope.isServiceWorkerGlobalScope());
</span><span class="cx"> 
</span><span class="lines">@@ -108,11 +108,12 @@
</span><span class="cx">     if (!event->respondWithEntered()) {
</span><span class="cx">         if (event->defaultPrevented()) {
</span><span class="cx">             client->didFail();
</span><del>-            return;
</del><ins>+            return event;
</ins><span class="cx">         }
</span><span class="cx">         client->didNotHandle();
</span><span class="cx">         // FIXME: Handle soft update.
</span><span class="cx">     }
</span><ins>+    return event;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace ServiceWorkerFetch
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersservicecontextServiceWorkerFetchh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h        2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerFetch.h   2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include <wtf/ThreadSafeRefCounted.h>
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><ins>+class FetchEvent;
</ins><span class="cx"> struct FetchOptions;
</span><span class="cx"> class FetchResponse;
</span><span class="cx"> class ResourceRequest;
</span><span class="lines">@@ -50,7 +51,7 @@
</span><span class="cx">     virtual void didNotHandle() = 0;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-void dispatchFetchEvent(Ref<Client>&&, WorkerGlobalScope&, ResourceRequest&&, FetchOptions&&);
</del><ins>+Ref<FetchEvent> dispatchFetchEvent(Ref<Client>&&, WorkerGlobalScope&, ResourceRequest&&, FetchOptions&&);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersservicecontextServiceWorkerThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp     2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.cpp        2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -99,19 +99,22 @@
</span><span class="cx"> {
</span><span class="cx">     // FIXME: instead of directly using runLoop(), we should be using something like WorkerGlobalScopeProxy.
</span><span class="cx">     // FIXME: request and options come straigth from IPC so are already isolated. We should be able to take benefit of that.
</span><del>-    runLoop().postTaskForMode([client = WTFMove(client), request = request.isolatedCopy(), options = options.isolatedCopy()] (ScriptExecutionContext& context) mutable {
-        ServiceWorkerFetch::dispatchFetchEvent(WTFMove(client), downcast<WorkerGlobalScope>(context), WTFMove(request), WTFMove(options));
</del><ins>+    runLoop().postTaskForMode([this, client = WTFMove(client), request = request.isolatedCopy(), options = options.isolatedCopy()] (ScriptExecutionContext& context) mutable {
+        auto fetchEvent = ServiceWorkerFetch::dispatchFetchEvent(WTFMove(client), downcast<WorkerGlobalScope>(context), WTFMove(request), WTFMove(options));
+        updateExtendedEventsSet(fetchEvent.ptr());
</ins><span class="cx">     }, WorkerRunLoop::defaultMode());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ServiceWorkerThread::postMessageToServiceWorkerGlobalScope(Ref<SerializedScriptValue>&& message, std::unique_ptr<MessagePortChannelArray>&& channels, const ServiceWorkerClientIdentifier& sourceIdentifier, const String& sourceOrigin)
</span><span class="cx"> {
</span><del>-    ScriptExecutionContext::Task task([channels = WTFMove(channels), message = WTFMove(message), sourceIdentifier, sourceOrigin = sourceOrigin.isolatedCopy()] (ScriptExecutionContext& context) mutable {
</del><ins>+    ScriptExecutionContext::Task task([this, channels = WTFMove(channels), message = WTFMove(message), sourceIdentifier, sourceOrigin = sourceOrigin.isolatedCopy()] (ScriptExecutionContext& context) mutable {
</ins><span class="cx">         auto& serviceWorkerGlobalScope = downcast<ServiceWorkerGlobalScope>(context);
</span><span class="cx">         auto ports = MessagePort::entanglePorts(serviceWorkerGlobalScope, WTFMove(channels));
</span><span class="cx">         ExtendableMessageEventSource source = RefPtr<ServiceWorkerClient> { ServiceWorkerWindowClient::create(context, sourceIdentifier) };
</span><del>-        serviceWorkerGlobalScope.dispatchEvent(ExtendableMessageEvent::create(WTFMove(ports), WTFMove(message), sourceOrigin, { }, WTFMove(source)));
</del><ins>+        auto messageEvent = ExtendableMessageEvent::create(WTFMove(ports), WTFMove(message), sourceOrigin, { }, WTFMove(source));
+        serviceWorkerGlobalScope.dispatchEvent(messageEvent);
</ins><span class="cx">         serviceWorkerGlobalScope.thread().workerObjectProxy().confirmMessageFromWorkerObject(serviceWorkerGlobalScope.hasPendingActivity());
</span><ins>+        updateExtendedEventsSet(messageEvent.ptr());
</ins><span class="cx">     });
</span><span class="cx">     runLoop().postTask(WTFMove(task));
</span><span class="cx"> }
</span><span class="lines">@@ -157,6 +160,33 @@
</span><span class="cx">     runLoop().postTask(WTFMove(task));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// https://w3c.github.io/ServiceWorker/#update-service-worker-extended-events-set-algorithm
+void ServiceWorkerThread::updateExtendedEventsSet(ExtendableEvent* newEvent)
+{
+    ASSERT(!isMainThread());
+    ASSERT(!newEvent || !newEvent->isBeingDispatched());
+    bool hadPendingEvents = hasPendingEvents();
+    m_extendedEvents.removeAllMatching([](auto& event) {
+        return !event->pendingPromiseCount();
+    });
+
+    if (newEvent && newEvent->pendingPromiseCount()) {
+        m_extendedEvents.append(*newEvent);
+        newEvent->whenAllExtendLifetimePromisesAreSettled([this](auto&&) {
+            updateExtendedEventsSet();
+        });
+    }
+
+    bool hasPendingEvents = this->hasPendingEvents();
+    if (hasPendingEvents == hadPendingEvents)
+        return;
+
+    callOnMainThread([identifier = this->identifier(), hasPendingEvents] {
+        if (auto* connection = SWContextManager::singleton().connection())
+            connection->setServiceWorkerHasPendingEvents(identifier, hasPendingEvents);
+    });
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(SERVICE_WORKER)
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersservicecontextServiceWorkerThreadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h       2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h  2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> 
</span><span class="cx"> class CacheStorageProvider;
</span><span class="cx"> class ContentSecurityPolicyResponseHeaders;
</span><ins>+class ExtendableEvent;
</ins><span class="cx"> class MessagePortChannel;
</span><span class="cx"> class SerializedScriptValue;
</span><span class="cx"> class WorkerObjectProxy;
</span><span class="lines">@@ -71,9 +72,13 @@
</span><span class="cx"> private:
</span><span class="cx">     WEBCORE_EXPORT ServiceWorkerThread(uint64_t serverConnectionIdentifier, const ServiceWorkerContextData&, PAL::SessionID, WorkerLoaderProxy&, WorkerDebuggerProxy&);
</span><span class="cx"> 
</span><ins>+    void updateExtendedEventsSet(ExtendableEvent* newEvent = nullptr);
+    bool hasPendingEvents() const { return !m_extendedEvents.isEmpty(); }
+
</ins><span class="cx">     uint64_t m_serverConnectionIdentifier;
</span><span class="cx">     ServiceWorkerContextData m_data;
</span><span class="cx">     WorkerObjectProxy& m_workerObjectProxy;
</span><ins>+    Vector<Ref<ExtendableEvent>> m_extendedEvents;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceserverSWServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/server/SWServer.cpp 2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp    2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -122,6 +122,11 @@
</span><span class="cx">     m_server.didFinishActivation(*this, key, serviceWorkerIdentifier);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SWServer::Connection::setServiceWorkerHasPendingEvents(ServiceWorkerIdentifier serviceWorkerIdentifier, bool hasPendingEvents)
+{
+    m_server.setServiceWorkerHasPendingEvents(*this, serviceWorkerIdentifier, hasPendingEvents);
+}
+
</ins><span class="cx"> void SWServer::Connection::didResolveRegistrationPromise(const ServiceWorkerRegistrationKey& key)
</span><span class="cx"> {
</span><span class="cx">     m_server.didResolveRegistrationPromise(*this, key);
</span><span class="lines">@@ -255,6 +260,14 @@
</span><span class="cx">         SWServerJobQueue::didFinishActivation(*registration, serviceWorkerIdentifier);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SWServer::setServiceWorkerHasPendingEvents(Connection& connection, ServiceWorkerIdentifier serviceWorkerIdentifier, bool hasPendingEvents)
+{
+    ASSERT_UNUSED(connection, m_connections.contains(connection.identifier()));
+
+    if (auto* serviceWorker = m_workersByID.get(serviceWorkerIdentifier))
+        serviceWorker->setHasPendingEvents(hasPendingEvents);
+}
+
</ins><span class="cx"> void SWServer::didResolveRegistrationPromise(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_connections.contains(connection.identifier()));
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceserverSWServerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/server/SWServer.h   2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h      2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -63,6 +63,7 @@
</span><span class="cx">         WEBCORE_EXPORT void scriptContextStarted(const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier);
</span><span class="cx">         WEBCORE_EXPORT void didFinishInstall(const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier, bool wasSuccessful);
</span><span class="cx">         WEBCORE_EXPORT void didFinishActivation(const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier);
</span><ins>+        WEBCORE_EXPORT void setServiceWorkerHasPendingEvents(ServiceWorkerIdentifier, bool hasPendingEvents);
</ins><span class="cx">         WEBCORE_EXPORT void didResolveRegistrationPromise(const ServiceWorkerRegistrationKey&);
</span><span class="cx">         const SWServerRegistration* doRegistrationMatching(const SecurityOriginData& topOrigin, const URL& clientURL) const { return m_server.doRegistrationMatching(topOrigin, clientURL); }
</span><span class="cx"> 
</span><span class="lines">@@ -132,6 +133,7 @@
</span><span class="cx">     void scriptContextStarted(Connection&, const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier);
</span><span class="cx">     void didFinishInstall(Connection&, const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier, bool wasSuccessful);
</span><span class="cx">     void didFinishActivation(Connection&, const ServiceWorkerRegistrationKey&, ServiceWorkerIdentifier);
</span><ins>+    void setServiceWorkerHasPendingEvents(Connection&, ServiceWorkerIdentifier, bool hasPendingEvents);
</ins><span class="cx">     void didResolveRegistrationPromise(Connection&, const ServiceWorkerRegistrationKey&);
</span><span class="cx"> 
</span><span class="cx">     void addClientServiceWorkerRegistration(Connection&, const ServiceWorkerRegistrationKey&, ServiceWorkerRegistrationIdentifier);
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceserverSWServerJobQueuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp 2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebCore/workers/service/server/SWServerJobQueue.cpp    2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -189,12 +189,13 @@
</span><span class="cx">     if (registration.activeWorker() && registration.activeWorker()->state() == ServiceWorkerState::Activating)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    // FIXME: Invoke Activate with registration if either of the following is true:
</del><ins>+    // Invoke Activate with registration if either of the following is true:
</ins><span class="cx">     // - registration's active worker is null.
</span><span class="cx">     // - The result of running Service Worker Has No Pending Events with registration's active worker is true,
</span><del>-    //   and no service worker client is using registration or registration's waiting worker's skip waiting
-    //   flag is set.
-    activate(server, connection, registration);
</del><ins>+    //   and no service worker client is using registration
+    // FIXME: Check for the skip waiting flag.
+    if (!registration.activeWorker() || !registration.activeWorker()->hasPendingEvents())
+        activate(server, connection, registration);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // https://w3c.github.io/ServiceWorker/#activate
</span><span class="lines">@@ -328,8 +329,13 @@
</span><span class="cx"> {
</span><span class="cx">     // FIXME: Make sure that the registration has no service worker client.
</span><span class="cx"> 
</span><del>-    // FIXME: The specification has more complex logic here. We currently clear registrations
-    // too aggressively.
</del><ins>+    if (registration.installingWorker() && registration.installingWorker()->hasPendingEvents())
+        return;
+    if (registration.waitingWorker() && registration.waitingWorker()->hasPendingEvents())
+        return;
+    if (registration.activeWorker() && registration.activeWorker()->hasPendingEvents())
+        return;
+
</ins><span class="cx">     clearRegistration(registration);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersserviceserverSWServerWorkerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.h (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/service/server/SWServerWorker.h     2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.h        2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -58,6 +58,9 @@
</span><span class="cx">     ServiceWorkerState state() const { return m_state; }
</span><span class="cx">     void setState(ServiceWorkerState state) { m_state = state; }
</span><span class="cx"> 
</span><ins>+    bool hasPendingEvents() const { return m_hasPendingEvents; }
+    void setHasPendingEvents(bool value) { m_hasPendingEvents = value; }
+
</ins><span class="cx"> private:
</span><span class="cx">     SWServerWorker(const ServiceWorkerRegistrationKey&, const URL&, const String& script, WorkerType, ServiceWorkerIdentifier);
</span><span class="cx"> 
</span><span class="lines">@@ -68,6 +71,7 @@
</span><span class="cx">     WorkerType m_type;
</span><span class="cx">     
</span><span class="cx">     ServiceWorkerState m_state { ServiceWorkerState::Redundant };
</span><ins>+    bool m_hasPendingEvents { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebKit/ChangeLog       2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-11-13  Chris Dumez  <cdumez@apple.com>
+
+        Implement "Service Worker Has No Pending Events" / "Update Service Worker Extended Events Set" algorithms
+        https://bugs.webkit.org/show_bug.cgi?id=179618
+
+        Reviewed by Brady Eidson.
+
+        * StorageProcess/StorageProcess.cpp:
+        (WebKit::StorageProcess::setServiceWorkerHasPendingEvents):
+        * StorageProcess/StorageProcess.h:
+        * StorageProcess/StorageProcess.messages.in:
+        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+        (WebKit::WebSWContextManagerConnection::setServiceWorkerHasPendingEvents):
+        * WebProcess/Storage/WebSWContextManagerConnection.h:
+
</ins><span class="cx"> 2017-11-13  Wenson Hsieh  <wenson_hsieh@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Attachment Support] Implement SPI for clients to request data for a given attachment
</span></span></pre></div>
<a id="trunkSourceWebKitStorageProcessStorageProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/StorageProcess/StorageProcess.cpp (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/StorageProcess/StorageProcess.cpp    2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebKit/StorageProcess/StorageProcess.cpp       2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -465,6 +465,13 @@
</span><span class="cx">         connection->didFinishActivation(registrationKey, serviceWorkerIdentifier);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+
+void StorageProcess::setServiceWorkerHasPendingEvents(uint64_t serverConnectionIdentifier, ServiceWorkerIdentifier serviceWorkerIdentifier, bool hasPendingEvents)
+{
+    if (auto* connection = m_swServerConnections.get(serverConnectionIdentifier))
+        connection->setServiceWorkerHasPendingEvents(serviceWorkerIdentifier, hasPendingEvents);
+}
+
</ins><span class="cx"> void StorageProcess::registerSWServerConnection(WebSWServerConnection& connection)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!m_swServerConnections.contains(connection.identifier()));
</span></span></pre></div>
<a id="trunkSourceWebKitStorageProcessStorageProcessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/StorageProcess/StorageProcess.h (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/StorageProcess/StorageProcess.h      2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebKit/StorageProcess/StorageProcess.h 2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -130,6 +130,7 @@
</span><span class="cx"> 
</span><span class="cx">     void didFinishServiceWorkerInstall(uint64_t serverConnectionIdentifier, const WebCore::ServiceWorkerRegistrationKey&, WebCore::ServiceWorkerIdentifier, bool wasSuccessful);
</span><span class="cx">     void didFinishServiceWorkerActivation(uint64_t serverConnectionIdentifier, const WebCore::ServiceWorkerRegistrationKey&, WebCore::ServiceWorkerIdentifier);
</span><ins>+    void setServiceWorkerHasPendingEvents(uint64_t serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier, bool hasPendingEvents);
</ins><span class="cx">     void postMessageToServiceWorkerClient(const WebCore::ServiceWorkerClientIdentifier& destinationIdentifier, const IPC::DataReference& message, WebCore::ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin);
</span><span class="cx"> #endif
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span></span></pre></div>
<a id="trunkSourceWebKitStorageProcessStorageProcessmessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/StorageProcess/StorageProcess.messages.in (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/StorageProcess/StorageProcess.messages.in    2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebKit/StorageProcess/StorageProcess.messages.in       2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -42,6 +42,7 @@
</span><span class="cx">     ServiceWorkerContextStarted(uint64_t serverConnectionIdentifier, WebCore::ServiceWorkerRegistrationKey registrationKey, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier)
</span><span class="cx">     DidFinishServiceWorkerInstall(uint64_t serverConnectionIdentifier, WebCore::ServiceWorkerRegistrationKey registrationKey, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, bool wasSuccessful);
</span><span class="cx">     DidFinishServiceWorkerActivation(uint64_t serverConnectionIdentifier, WebCore::ServiceWorkerRegistrationKey registrationKey, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier);
</span><ins>+    SetServiceWorkerHasPendingEvents(uint64_t serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, bool hasPendingEvents);
</ins><span class="cx"> 
</span><span class="cx">     DidNotHandleFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier)
</span><span class="cx">     DidFailFetch(uint64_t serverConnectionIdentifier, uint64_t fetchIdentifier)
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessStorageWebSWContextManagerConnectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp 2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp    2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -184,6 +184,14 @@
</span><span class="cx">     m_connectionToStorageProcess->send(Messages::StorageProcess::DidFinishServiceWorkerActivation(threadProxy->thread().serverConnectionIdentifier(), data.registrationKey, serviceWorkerIdentifier), 0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebSWContextManagerConnection::setServiceWorkerHasPendingEvents(ServiceWorkerIdentifier serviceWorkerIdentifier, bool hasPendingEvents)
+{
+    auto* threadProxy = SWContextManager::singleton().serviceWorkerThreadProxy(serviceWorkerIdentifier);
+    ASSERT(threadProxy);
+
+    m_connectionToStorageProcess->send(Messages::StorageProcess::SetServiceWorkerHasPendingEvents(threadProxy->thread().serverConnectionIdentifier(), serviceWorkerIdentifier, hasPendingEvents), 0);
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(SERVICE_WORKER)
</span></span></pre></div>
<a id="trunkSourceWebKitWebProcessStorageWebSWContextManagerConnectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h (224771 => 224772)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h   2017-11-13 21:02:58 UTC (rev 224771)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h      2017-11-13 21:06:23 UTC (rev 224772)
</span><span class="lines">@@ -54,6 +54,7 @@
</span><span class="cx">     void postMessageToServiceWorkerClient(const WebCore::ServiceWorkerClientIdentifier& destinationIdentifier, Ref<WebCore::SerializedScriptValue>&& message, WebCore::ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin) final;
</span><span class="cx">     void didFinishInstall(WebCore::ServiceWorkerIdentifier, bool wasSuccessful) final;
</span><span class="cx">     void didFinishActivation(WebCore::ServiceWorkerIdentifier) final;
</span><ins>+    void setServiceWorkerHasPendingEvents(WebCore::ServiceWorkerIdentifier, bool) final;
</ins><span class="cx"> 
</span><span class="cx">     // IPC messages.
</span><span class="cx">     void serviceWorkerStartedWithMessage(WebCore::ServiceWorkerIdentifier, const String& exceptionMessage) final;
</span></span></pre>
</div>
</div>

</body>
</html>