Simplify WebProcess handling of unregistering of service workers
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 15 Feb 2020 02:36:11 +0000 (02:36 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 15 Feb 2020 02:36:11 +0000 (02:36 +0000)
https://bugs.webkit.org/show_bug.cgi?id=207669

Reviewed by Chris Dumez.

Source/WebCore:

Instead of creating a job in WebProcess, we now create it at SWServer level.
This allows the ServiceWorkerContainer to only provide the service worker registration identifier
to start the unregistering process.
To simplify things, a completion handler is used to resolve the promise once the unregister job run.

This allows to send less information from ServiceWorkerContainer to SWServer through IPC.

No observable change of behavior.

* workers/service/SWClientConnection.cpp:
(WebCore::SWClientConnection::unregistrationJobResolvedInServer): Deleted.
* workers/service/SWClientConnection.h:
* workers/service/ServiceWorkerContainer.cpp:
(WebCore::ServiceWorkerContainer::unregisterRegistration):
* workers/service/ServiceWorkerContainer.h:
* workers/service/ServiceWorkerJobData.cpp:
(WebCore::serviceWorkerOrClientIdentifier):
(WebCore::ServiceWorkerJobData::ServiceWorkerJobData):
* workers/service/ServiceWorkerJobData.h:
* workers/service/ServiceWorkerRegistration.cpp:
(WebCore::ServiceWorkerRegistration::unregister):
* workers/service/WorkerSWClientConnection.cpp:
(WebCore::WorkerSWClientConnection::scheduleUnregisterJobInServer):
* workers/service/WorkerSWClientConnection.h:
* workers/service/server/SWServer.cpp:
(WebCore::SWServer::scheduleUnregisterJob):
* workers/service/server/SWServer.h:

Source/WebKit:

Use Async Reply IPC for scheduling an unregister job.

Make WebSWServerConnection own a map of CompletionHandler keyed by unregister job identifiers.
WebSWServerConnection then asks SWServer to schedule the unregister job.
When job is run, WebSWServerConnection will call the corresponding completion handler.
The completion handler will trigger an IPC response that will trigger the unregister promise to be resolved.

* NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::resolveUnregistrationJobInClient):
(WebKit::WebSWServerConnection::scheduleUnregisterJobInServer):
* NetworkProcess/ServiceWorker/WebSWServerConnection.h:
* NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in:
* Scripts/webkit/messages.py:
* WebProcess/Storage/WebSWClientConnection.cpp:
(WebKit::WebSWClientConnection::scheduleUnregisterJobInServer):
* WebProcess/Storage/WebSWClientConnection.h:
* WebProcess/Storage/WebSWClientConnection.messages.in:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@256664 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
Source/WebCore/ChangeLog
Source/WebCore/workers/service/SWClientConnection.cpp
Source/WebCore/workers/service/SWClientConnection.h
Source/WebCore/workers/service/ServiceWorkerContainer.cpp
Source/WebCore/workers/service/ServiceWorkerContainer.h
Source/WebCore/workers/service/ServiceWorkerJobData.cpp
Source/WebCore/workers/service/ServiceWorkerJobData.h
Source/WebCore/workers/service/ServiceWorkerRegistration.cpp
Source/WebCore/workers/service/WorkerSWClientConnection.cpp
Source/WebCore/workers/service/WorkerSWClientConnection.h
Source/WebCore/workers/service/server/SWServer.cpp
Source/WebCore/workers/service/server/SWServer.h
Source/WebKit/ChangeLog
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.h
Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in
Source/WebKit/Scripts/webkit/messages.py
Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp
Source/WebKit/WebProcess/Storage/WebSWClientConnection.h
Source/WebKit/WebProcess/Storage/WebSWClientConnection.messages.in

index f4e45e7..717b9d9 100644 (file)
@@ -1,3 +1,38 @@
+2020-02-14  Youenn Fablet  <youenn@apple.com>
+
+        Simplify WebProcess handling of unregistering of service workers
+        https://bugs.webkit.org/show_bug.cgi?id=207669
+
+        Reviewed by Chris Dumez.
+
+        Instead of creating a job in WebProcess, we now create it at SWServer level.
+        This allows the ServiceWorkerContainer to only provide the service worker registration identifier
+        to start the unregistering process.
+        To simplify things, a completion handler is used to resolve the promise once the unregister job run.
+
+        This allows to send less information from ServiceWorkerContainer to SWServer through IPC.
+
+        No observable change of behavior.
+
+        * workers/service/SWClientConnection.cpp:
+        (WebCore::SWClientConnection::unregistrationJobResolvedInServer): Deleted.
+        * workers/service/SWClientConnection.h:
+        * workers/service/ServiceWorkerContainer.cpp:
+        (WebCore::ServiceWorkerContainer::unregisterRegistration):
+        * workers/service/ServiceWorkerContainer.h:
+        * workers/service/ServiceWorkerJobData.cpp:
+        (WebCore::serviceWorkerOrClientIdentifier):
+        (WebCore::ServiceWorkerJobData::ServiceWorkerJobData):
+        * workers/service/ServiceWorkerJobData.h:
+        * workers/service/ServiceWorkerRegistration.cpp:
+        (WebCore::ServiceWorkerRegistration::unregister):
+        * workers/service/WorkerSWClientConnection.cpp:
+        (WebCore::WorkerSWClientConnection::scheduleUnregisterJobInServer):
+        * workers/service/WorkerSWClientConnection.h:
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::scheduleUnregisterJob):
+        * workers/service/server/SWServer.h:
+
 2020-02-14  Nikos Mouchtaris  <nmouchtaris@apple.com>
 
         new FontFace() should not throw when failing to parse arguments
index dac90ae..119f3cf 100644 (file)
@@ -108,13 +108,6 @@ void SWClientConnection::registrationJobResolvedInServer(ServiceWorkerJobIdentif
         didResolveRegistrationPromise(registrationData.key);
 }
 
-void SWClientConnection::unregistrationJobResolvedInServer(ServiceWorkerJobIdentifier jobIdentifier, bool unregistrationResult)
-{
-    postTaskForJob(jobIdentifier, IsJobComplete::Yes, [unregistrationResult] (auto& job) {
-        job.resolvedWithUnregistrationResult(unregistrationResult);
-    });
-}
-
 void SWClientConnection::startScriptFetchForServer(ServiceWorkerJobIdentifier jobIdentifier, const ServiceWorkerRegistrationKey& registrationKey, FetchOptions::Cache cachePolicy)
 {
     bool isPosted = postTaskForJob(jobIdentifier, IsJobComplete::No, [cachePolicy] (auto& job) {
index 440047d..465208b 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(SERVICE_WORKER)
 
 #include "DocumentIdentifier.h"
+#include "ExceptionOr.h"
 #include "ServiceWorkerJob.h"
 #include "ServiceWorkerTypes.h"
 #include <wtf/CompletionHandler.h>
@@ -68,6 +69,7 @@ public:
 
     virtual void addServiceWorkerRegistrationInServer(ServiceWorkerRegistrationIdentifier) = 0;
     virtual void removeServiceWorkerRegistrationInServer(ServiceWorkerRegistrationIdentifier) = 0;
+    virtual void scheduleUnregisterJobInServer(ServiceWorkerRegistrationIdentifier, DocumentOrWorkerIdentifier, const URL& /* clientCreationURL */, CompletionHandler<void(ExceptionOr<bool>&&)>&&) = 0;
 
     WEBCORE_EXPORT virtual void scheduleJob(DocumentOrWorkerIdentifier, const ServiceWorkerJobData&);
 
@@ -94,7 +96,6 @@ protected:
 
     WEBCORE_EXPORT void jobRejectedInServer(ServiceWorkerJobIdentifier, const ExceptionData&);
     WEBCORE_EXPORT void registrationJobResolvedInServer(ServiceWorkerJobIdentifier, ServiceWorkerRegistrationData&&, ShouldNotifyWhenResolved);
-    WEBCORE_EXPORT void unregistrationJobResolvedInServer(ServiceWorkerJobIdentifier, bool unregistrationResult);
     WEBCORE_EXPORT void startScriptFetchForServer(ServiceWorkerJobIdentifier, const ServiceWorkerRegistrationKey&, FetchOptions::Cache);
     WEBCORE_EXPORT void postMessageToServiceWorkerClient(DocumentIdentifier destinationContextIdentifier, MessageWithMessagePorts&&, ServiceWorkerData&& source, String&& sourceOrigin);
     WEBCORE_EXPORT void updateRegistrationState(ServiceWorkerRegistrationIdentifier, ServiceWorkerRegistrationState, const Optional<ServiceWorkerData>&);
index e9ec8ec..e80a7e8 100644 (file)
@@ -187,30 +187,25 @@ void ServiceWorkerContainer::addRegistration(const String& relativeScriptURL, co
     scheduleJob(makeUnique<ServiceWorkerJob>(*this, WTFMove(promise), WTFMove(jobData)));
 }
 
-void ServiceWorkerContainer::removeRegistration(const URL& scopeURL, Ref<DeferredPromise>&& promise)
+void ServiceWorkerContainer::unregisterRegistration(ServiceWorkerRegistrationIdentifier registrationIdentifier, DOMPromiseDeferred<IDLBoolean>&& promise)
 {
     auto* context = scriptExecutionContext();
     if (!context) {
         ASSERT_NOT_REACHED();
-        promise->reject(Exception(InvalidStateError));
+        promise.reject(Exception(InvalidStateError));
         return;
     }
 
     if (!m_swConnection) {
         ASSERT_NOT_REACHED();
-        promise->reject(Exception(InvalidStateError));
+        promise.reject(Exception(InvalidStateError));
         return;
     }
 
-    ServiceWorkerJobData jobData(m_swConnection->serverConnectionIdentifier(), contextIdentifier());
-    jobData.clientCreationURL = context->url();
-    jobData.topOrigin = context->topOrigin().data();
-    jobData.type = ServiceWorkerJobType::Unregister;
-    jobData.scopeURL = scopeURL;
-
-    CONTAINER_RELEASE_LOG_IF_ALLOWED("removeRegistration: Unregistering service worker. Job ID: %" PRIu64, jobData.identifier().jobIdentifier.toUInt64());
-
-    scheduleJob(makeUnique<ServiceWorkerJob>(*this, WTFMove(promise), WTFMove(jobData)));
+    CONTAINER_RELEASE_LOG_IF_ALLOWED("unregisterRegistration: Unregistering service worker.");
+    m_swConnection->scheduleUnregisterJobInServer(registrationIdentifier, contextIdentifier(), context->url(), [promise = WTFMove(promise)](auto&& result) mutable {
+        promise.settle(WTFMove(result));
+    });
 }
 
 void ServiceWorkerContainer::updateRegistration(const URL& scopeURL, const URL& scriptURL, WorkerType, RefPtr<DeferredPromise>&& promise)
index 4182558..71e1d72 100644 (file)
@@ -30,6 +30,7 @@
 #include "ActiveDOMObject.h"
 #include "EventTarget.h"
 #include "IDLTypes.h"
+#include "JSDOMPromiseDeferred.h"
 #include "SWClientConnection.h"
 #include "SWServer.h"
 #include "ServiceWorkerJobClient.h"
@@ -63,7 +64,7 @@ public:
 
     using RegistrationOptions = ServiceWorkerRegistrationOptions;
     void addRegistration(const String& scriptURL, const RegistrationOptions&, Ref<DeferredPromise>&&);
-    void removeRegistration(const URL& scopeURL, Ref<DeferredPromise>&&);
+    void unregisterRegistration(ServiceWorkerRegistrationIdentifier, DOMPromiseDeferred<IDLBoolean>&&);
     void updateRegistration(const URL& scopeURL, const URL& scriptURL, WorkerType, RefPtr<DeferredPromise>&&);
 
     void getRegistration(const String& clientURL, Ref<DeferredPromise>&&);
index 3697e07..b2b7978 100644 (file)
 
 namespace WebCore {
 
-ServiceWorkerJobData::ServiceWorkerJobData(SWServerConnectionIdentifier connectionIdentifier, const DocumentOrWorkerIdentifier& localSourceContext)
-    : m_identifier { connectionIdentifier, ServiceWorkerJobIdentifier::generateThreadSafe() }
+static inline ServiceWorkerOrClientIdentifier serviceWorkerOrClientIdentifier(SWServerConnectionIdentifier connectionIdentifier, const DocumentOrWorkerIdentifier& localSourceContext)
 {
-    WTF::switchOn(localSourceContext, [&](DocumentIdentifier documentIdentifier) {
-        sourceContext = ServiceWorkerClientIdentifier { connectionIdentifier, documentIdentifier };
-    }, [&](ServiceWorkerIdentifier serviceWorkerIdentifier) {
-        sourceContext = serviceWorkerIdentifier;
+    return WTF::switchOn(localSourceContext, [&](DocumentIdentifier documentIdentifier) -> ServiceWorkerOrClientIdentifier {
+        return ServiceWorkerClientIdentifier { connectionIdentifier, documentIdentifier };
+    }, [&](ServiceWorkerIdentifier serviceWorkerIdentifier) -> ServiceWorkerOrClientIdentifier {
+        return serviceWorkerIdentifier;
     });
 }
 
+ServiceWorkerJobData::ServiceWorkerJobData(SWServerConnectionIdentifier connectionIdentifier, const DocumentOrWorkerIdentifier& localSourceContext)
+    : sourceContext(serviceWorkerOrClientIdentifier(connectionIdentifier, localSourceContext))
+    , m_identifier { connectionIdentifier, ServiceWorkerJobIdentifier::generateThreadSafe() }
+{
+}
+
+ServiceWorkerJobData::ServiceWorkerJobData(Identifier identifier, const DocumentOrWorkerIdentifier& localSourceContext)
+    : sourceContext(serviceWorkerOrClientIdentifier(identifier.connectionIdentifier, localSourceContext))
+    , m_identifier { identifier }
+{
+}
+
 ServiceWorkerRegistrationKey ServiceWorkerJobData::registrationKey() const
 {
     URL scope = scopeURL;
index cc0b41d..16ec29f 100644 (file)
@@ -41,6 +41,7 @@ namespace WebCore {
 struct ServiceWorkerJobData {
     using Identifier = ServiceWorkerJobDataIdentifier;
     ServiceWorkerJobData(SWServerConnectionIdentifier, const DocumentOrWorkerIdentifier& sourceContext);
+    ServiceWorkerJobData(Identifier, const DocumentOrWorkerIdentifier& sourceContext);
 
     SWServerConnectionIdentifier connectionIdentifier() const { return m_identifier.connectionIdentifier; }
 
index 048005c..466e9fc 100644 (file)
@@ -159,7 +159,7 @@ void ServiceWorkerRegistration::unregister(Ref<DeferredPromise>&& promise)
         return;
     }
 
-    m_container->removeRegistration(m_registrationData.scopeURL, WTFMove(promise));
+    m_container->unregisterRegistration(identifier(), WTFMove(promise));
 }
 
 void ServiceWorkerRegistration::updateStateFromServer(ServiceWorkerRegistrationState state, RefPtr<ServiceWorker>&& serviceWorker)
index 4ae81e3..2ed4c25 100644 (file)
@@ -57,6 +57,10 @@ WorkerSWClientConnection::~WorkerSWClientConnection()
     auto whenRegistrationReadyRequests = WTFMove(m_whenRegistrationReadyRequests);
     for (auto& callback : whenRegistrationReadyRequests.values())
         callback({ });
+
+    auto unregisterRequests = WTFMove(m_unregisterRequests);
+    for (auto& callback : unregisterRequests.values())
+        callback(Exception { TypeError, "context stopped"_s });
 }
 
 void WorkerSWClientConnection::matchRegistration(SecurityOriginData&& topOrigin, const URL& clientURL, RegistrationCallback&& callback)
@@ -192,6 +196,22 @@ void WorkerSWClientConnection::scheduleJob(DocumentOrWorkerIdentifier identifier
     });
 }
 
+void WorkerSWClientConnection::scheduleUnregisterJobInServer(ServiceWorkerRegistrationIdentifier registrationIdentifier, DocumentOrWorkerIdentifier contextIdentifier, const URL& clientCreationURL, CompletionHandler<void(ExceptionOr<bool>&&)>&& callback)
+{
+    uint64_t requestIdentifier = ++m_lastRequestIdentifier;
+    m_unregisterRequests.add(requestIdentifier, WTFMove(callback));
+
+    callOnMainThread([thread = m_thread.copyRef(), requestIdentifier, registrationIdentifier, contextIdentifier, clientCreationURL = crossThreadCopy(clientCreationURL)]() mutable {
+        auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
+        connection.scheduleUnregisterJobInServer(registrationIdentifier, contextIdentifier, clientCreationURL, [thread = WTFMove(thread), requestIdentifier](auto&& result) {
+            thread->runLoop().postTaskForMode([requestIdentifier, result = crossThreadCopy(result)](auto& scope) mutable {
+                auto callback = downcast<WorkerGlobalScope>(scope).swClientConnection().m_unregisterRequests.take(requestIdentifier);
+                callback(WTFMove(result));
+            }, WorkerRunLoop::defaultMode());
+        });
+    });
+}
+
 void WorkerSWClientConnection::scheduleJobInServer(const ServiceWorkerJobData&)
 {
     ASSERT_NOT_REACHED();
index d09b160..c033773 100644 (file)
@@ -57,6 +57,7 @@ private:
     void finishFetchingScriptInServer(const ServiceWorkerFetchResult&) final;
     void scheduleJobInServer(const ServiceWorkerJobData&) final;
     void scheduleJob(DocumentOrWorkerIdentifier, const ServiceWorkerJobData&) final;
+    void scheduleUnregisterJobInServer(ServiceWorkerRegistrationIdentifier, DocumentOrWorkerIdentifier, const URL& /* clientCreationURL */, CompletionHandler<void(ExceptionOr<bool>&&)>&&) final;
 
     Ref<WorkerThread> m_thread;
 
@@ -64,6 +65,7 @@ private:
     HashMap<uint64_t, RegistrationCallback> m_matchRegistrationRequests;
     HashMap<uint64_t, GetRegistrationsCallback> m_getRegistrationsRequests;
     HashMap<uint64_t, WhenRegistrationReadyCallback> m_whenRegistrationReadyRequests;
+    HashMap<uint64_t, CompletionHandler<void(ExceptionOr<bool>&&)>> m_unregisterRequests;
 };
 
 } // namespace WebCore
index 4dd8f85..0ca56db 100644 (file)
@@ -357,6 +357,17 @@ void SWServer::scheduleJob(ServiceWorkerJobData&& jobData)
         jobQueue.runNextJob();
 }
 
+void SWServer::scheduleUnregisterJob(ServiceWorkerJobDataIdentifier jobDataIdentifier, SWServerRegistration& registration, DocumentOrWorkerIdentifier contextIdentifier, URL&& clientCreationURL)
+{
+    ServiceWorkerJobData jobData { jobDataIdentifier, contextIdentifier };
+    jobData.clientCreationURL = WTFMove(clientCreationURL);
+    jobData.topOrigin = registration.data().key.topOrigin();
+    jobData.type = ServiceWorkerJobType::Unregister;
+    jobData.scopeURL = registration.data().scopeURL;
+
+    scheduleJob(WTFMove(jobData));
+}
+
 void SWServer::rejectJob(const ServiceWorkerJobData& jobData, const ExceptionData& exceptionData)
 {
     LOG(ServiceWorker, "Rejected ServiceWorker job %s in server", jobData.identifier().loggingString().utf8().data());
index cdbd1d1..9ef3511 100644 (file)
@@ -143,6 +143,8 @@ public:
     WEBCORE_EXPORT Vector<ServiceWorkerRegistrationData> getRegistrations(const SecurityOriginData& topOrigin, const URL& clientURL);
 
     WEBCORE_EXPORT void scheduleJob(ServiceWorkerJobData&&);
+    WEBCORE_EXPORT void scheduleUnregisterJob(ServiceWorkerJobDataIdentifier, SWServerRegistration&, DocumentOrWorkerIdentifier, URL&& /* clientCreationURL */);
+
     void rejectJob(const ServiceWorkerJobData&, const ExceptionData&);
     void resolveRegistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationData&, ShouldNotifyWhenResolved);
     void resolveUnregistrationJob(const ServiceWorkerJobData&, const ServiceWorkerRegistrationKey&, bool unregistrationResult);
index e6e048d..fde1a44 100644 (file)
@@ -1,5 +1,30 @@
 2020-02-14  Youenn Fablet  <youenn@apple.com>
 
+        Simplify WebProcess handling of unregistering of service workers
+        https://bugs.webkit.org/show_bug.cgi?id=207669
+
+        Reviewed by Chris Dumez.
+
+        Use Async Reply IPC for scheduling an unregister job.
+
+        Make WebSWServerConnection own a map of CompletionHandler keyed by unregister job identifiers.
+        WebSWServerConnection then asks SWServer to schedule the unregister job.
+        When job is run, WebSWServerConnection will call the corresponding completion handler.
+        The completion handler will trigger an IPC response that will trigger the unregister promise to be resolved.
+
+        * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::resolveUnregistrationJobInClient):
+        (WebKit::WebSWServerConnection::scheduleUnregisterJobInServer):
+        * NetworkProcess/ServiceWorker/WebSWServerConnection.h:
+        * NetworkProcess/ServiceWorker/WebSWServerConnection.messages.in:
+        * Scripts/webkit/messages.py:
+        * WebProcess/Storage/WebSWClientConnection.cpp:
+        (WebKit::WebSWClientConnection::scheduleUnregisterJobInServer):
+        * WebProcess/Storage/WebSWClientConnection.h:
+        * WebProcess/Storage/WebSWClientConnection.messages.in:
+
+2020-02-14  Youenn Fablet  <youenn@apple.com>
+
         Improve NSURLSession WebSocket message handling in case of error
         https://bugs.webkit.org/show_bug.cgi?id=207799
 
index c491c00..c6b1624 100644 (file)
@@ -81,6 +81,8 @@ WebSWServerConnection::~WebSWServerConnection()
 
 void WebSWServerConnection::rejectJobInClient(ServiceWorkerJobIdentifier jobIdentifier, const ExceptionData& exceptionData)
 {
+    if (auto completionHandler = m_unregisterJobs.take(jobIdentifier))
+        return completionHandler(makeUnexpected(exceptionData));
     send(Messages::WebSWClientConnection::JobRejectedInServer(jobIdentifier, exceptionData));
 }
 
@@ -91,7 +93,9 @@ void WebSWServerConnection::resolveRegistrationJobInClient(ServiceWorkerJobIdent
 
 void WebSWServerConnection::resolveUnregistrationJobInClient(ServiceWorkerJobIdentifier jobIdentifier, const ServiceWorkerRegistrationKey& registrationKey, bool unregistrationResult)
 {
-    send(Messages::WebSWClientConnection::UnregistrationJobResolvedInServer(jobIdentifier, unregistrationResult));
+    ASSERT(m_unregisterJobs.contains(jobIdentifier));
+    if (auto completionHandler = m_unregisterJobs.take(jobIdentifier))
+        completionHandler(unregistrationResult);
 }
 
 void WebSWServerConnection::startScriptFetchInClient(ServiceWorkerJobIdentifier jobIdentifier, const ServiceWorkerRegistrationKey& registrationKey, FetchOptions::Cache cachePolicy)
@@ -284,6 +288,20 @@ void WebSWServerConnection::scheduleJobInServer(ServiceWorkerJobData&& jobData)
     server().scheduleJob(WTFMove(jobData));
 }
 
+void WebSWServerConnection::scheduleUnregisterJobInServer(WebCore::ServiceWorkerJobIdentifier jobIdentifier, WebCore::ServiceWorkerRegistrationIdentifier registrationIdentifier, WebCore::DocumentOrWorkerIdentifier contextIdentifier, URL&& clientCreationURL, CompletionHandler<void(UnregisterJobResult&&)>&& completionHandler)
+{
+    SWSERVERCONNECTION_RELEASE_LOG_IF_ALLOWED("Scheduling unregister ServiceWorker job in server");
+
+    auto* registration = server().getRegistration(registrationIdentifier);
+    if (!registration)
+        return completionHandler(false);
+
+    ASSERT(!m_unregisterJobs.contains(jobIdentifier));
+    m_unregisterJobs.add(jobIdentifier, WTFMove(completionHandler));
+
+    server().scheduleUnregisterJob(ServiceWorkerJobDataIdentifier { identifier(), jobIdentifier }, *registration, contextIdentifier, WTFMove(clientCreationURL));
+}
+
 void WebSWServerConnection::postMessageToServiceWorkerClient(DocumentIdentifier destinationContextIdentifier, const MessageWithMessagePorts& message, ServiceWorkerIdentifier sourceIdentifier, const String& sourceOrigin)
 {
     auto* sourceServiceWorker = server().workerByID(sourceIdentifier);
index 7ee3b18..38be2f6 100644 (file)
@@ -30,6 +30,7 @@
 #include "MessageReceiver.h"
 #include "MessageSender.h"
 #include "ServiceWorkerFetchTask.h"
+#include <WebCore/ExceptionOr.h>
 #include <WebCore/FetchIdentifier.h>
 #include <WebCore/ProcessIdentifier.h>
 #include <WebCore/SWServer.h>
 
 namespace IPC {
 class FormDataReference;
+
+template<> struct AsyncReplyError<WebCore::ExceptionOr<bool>> {
+    static WebCore::ExceptionOr<bool> create() { return WebCore::Exception { WebCore::TypeError, "Internal error"_s }; }
+};
+
 }
 
 namespace WebCore {
@@ -87,6 +93,9 @@ private:
 
     void scheduleJobInServer(WebCore::ServiceWorkerJobData&&);
 
+    using UnregisterJobResult = Expected<bool, WebCore::ExceptionData>;
+    void scheduleUnregisterJobInServer(WebCore::ServiceWorkerJobIdentifier, WebCore::ServiceWorkerRegistrationIdentifier, WebCore::DocumentOrWorkerIdentifier, URL&&, CompletionHandler<void(UnregisterJobResult&&)>&&);
+
     void startFetch(ServiceWorkerFetchTask&, WebCore::SWServerWorker&);
 
     void matchRegistration(uint64_t registrationMatchRequestIdentifier, const WebCore::SecurityOriginData& topOrigin, const URL& clientURL);
@@ -118,6 +127,7 @@ private:
     Ref<IPC::Connection> m_contentConnection;
     Ref<NetworkProcess> m_networkProcess;
     HashMap<WebCore::ServiceWorkerClientIdentifier, WebCore::ClientOrigin> m_clientOrigins;
+    HashMap<WebCore::ServiceWorkerJobIdentifier, CompletionHandler<void(UnregisterJobResult&&)>> m_unregisterJobs;
     bool m_isThrottleable { true };
 };
 
index fdbceb8..90ba0a2 100644 (file)
@@ -25,6 +25,8 @@
 messages -> WebSWServerConnection NotRefCounted {
     # When possible, these messages can be implemented directly by WebCore::SWClientConnection
     ScheduleJobInServer(struct WebCore::ServiceWorkerJobData jobData)
+    ScheduleUnregisterJobInServer(WebCore::ServiceWorkerJobIdentifier jobIdentifier, WebCore::ServiceWorkerRegistrationIdentifier identifier, WebCore::DocumentOrWorkerIdentifier documentIdentifier, URL clientCreationURL) -> (Expected<bool, WebCore::ExceptionData> result) Async
+
     FinishFetchingScriptInServer(struct WebCore::ServiceWorkerFetchResult result)
     AddServiceWorkerRegistrationInServer(WebCore::ServiceWorkerRegistrationIdentifier identifier)
     RemoveServiceWorkerRegistrationInServer(WebCore::ServiceWorkerRegistrationIdentifier identifier)
index c8200de..7f1cf9c 100644 (file)
@@ -205,6 +205,7 @@ def types_that_cannot_be_forward_declared():
         'MachSendRight',
         'String',
         'WebCore::DocumentIdentifier',
+        'WebCore::DocumentOrWorkerIdentifier',
         'WebCore::FetchIdentifier',
         'WebCore::FrameIdentifier',
         'WebCore::LibWebRTCSocketIdentifier',
@@ -480,6 +481,7 @@ def class_template_headers(template_string):
 
     class_template_types = {
         'WebCore::RectEdges': {'headers': ['<WebCore/RectEdges.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
+        'Expected': {'headers': ['<wtf/Expected.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
         'HashMap': {'headers': ['<wtf/HashMap.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
         'HashSet': {'headers': ['<wtf/HashSet.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
         'Optional': {'headers': ['<wtf/Optional.h>'], 'argument_coder_headers': ['"ArgumentCoders.h"']},
@@ -552,6 +554,7 @@ def headers_for_type(type):
         'PAL::SessionID': ['<pal/SessionID.h>'],
         'WebCore::AutoplayEventFlags': ['<WebCore/AutoplayEvent.h>'],
         'WebCore::DOMPasteAccessResponse': ['<WebCore/DOMPasteAccess.h>'],
+        'WebCore::DocumentOrWorkerIdentifier': ['<WebCore/ServiceWorkerTypes.h>'],
         'WebKit::DocumentEditingContextRequest': ['"DocumentEditingContext.h"'],
         'WebCore::DragHandlingMethod': ['<WebCore/DragActions.h>'],
         'WebCore::ExceptionDetails': ['<WebCore/JSDOMExceptionHandling.h>'],
index 50a2e1d..7edda09 100644 (file)
@@ -96,6 +96,15 @@ void WebSWClientConnection::removeServiceWorkerRegistrationInServer(ServiceWorke
         send(Messages::WebSWServerConnection::RemoveServiceWorkerRegistrationInServer { identifier });
 }
 
+void WebSWClientConnection::scheduleUnregisterJobInServer(ServiceWorkerRegistrationIdentifier registrationIdentifier, WebCore::DocumentOrWorkerIdentifier documentIdentifier, const URL& clientCreationURL, CompletionHandler<void(ExceptionOr<bool>&&)>&& completionHandler)
+{
+    sendWithAsyncReply(Messages::WebSWServerConnection::ScheduleUnregisterJobInServer { ServiceWorkerJobIdentifier::generateThreadSafe(), registrationIdentifier, documentIdentifier, clientCreationURL }, [completionHandler = WTFMove(completionHandler)](auto&& result) mutable {
+        if (!result.has_value())
+            return completionHandler(result.error().toException());
+        completionHandler(result.value());
+    });
+}
+
 void WebSWClientConnection::postMessageToServiceWorker(ServiceWorkerIdentifier destinationIdentifier, MessageWithMessagePorts&& message, const ServiceWorkerOrClientIdentifier& sourceIdentifier)
 {
     send(Messages::WebSWServerConnection::PostMessageToServiceWorker { destinationIdentifier, WTFMove(message), sourceIdentifier });
index 9dbfbab..7dbb9a0 100644 (file)
@@ -75,6 +75,7 @@ private:
     void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destinationIdentifier, WebCore::MessageWithMessagePorts&&, const WebCore::ServiceWorkerOrClientIdentifier& source) final;
     void registerServiceWorkerClient(const WebCore::SecurityOrigin& topOrigin, const WebCore::ServiceWorkerClientData&, const Optional<WebCore::ServiceWorkerRegistrationIdentifier>&, const String& userAgent) final;
     void unregisterServiceWorkerClient(WebCore::DocumentIdentifier) final;
+    void scheduleUnregisterJobInServer(WebCore::ServiceWorkerRegistrationIdentifier, WebCore::DocumentOrWorkerIdentifier, const URL& /* clientCreationURL */, CompletionHandler<void(WebCore::ExceptionOr<bool>&&)>&&) final;
 
     void matchRegistration(WebCore::SecurityOriginData&& topOrigin, const URL& clientURL, RegistrationCallback&&) final;
     void didMatchRegistration(uint64_t matchRequestIdentifier, Optional<WebCore::ServiceWorkerRegistrationData>&&);
index 9406971..6460bcc 100644 (file)
@@ -26,7 +26,6 @@ messages -> WebSWClientConnection {
     # When possible, these messages can be implemented directly by WebCore::SWServer::Connection
     JobRejectedInServer(WebCore::ServiceWorkerJobIdentifier jobDataIdentifier, struct WebCore::ExceptionData exception)
     RegistrationJobResolvedInServer(WebCore::ServiceWorkerJobIdentifier jobDataIdentifier, struct WebCore::ServiceWorkerRegistrationData registration, enum:bool WebCore::ShouldNotifyWhenResolved shouldNotifyWhenResolved)
-    UnregistrationJobResolvedInServer(WebCore::ServiceWorkerJobIdentifier jobDataIdentifier, bool unregistrationResult)
     StartScriptFetchForServer(WebCore::ServiceWorkerJobIdentifier jobDataIdentifier, WebCore::ServiceWorkerRegistrationKey registrationKey, WebCore::FetchOptions::Cache cachePolicy)
     UpdateRegistrationState(WebCore::ServiceWorkerRegistrationIdentifier identifier, enum:uint8_t WebCore::ServiceWorkerRegistrationState state, Optional<WebCore::ServiceWorkerData> serviceWorkerIdentifier)
     UpdateWorkerState(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, enum:uint8_t WebCore::ServiceWorkerState state)