Simplify IPC code between WebProcess and StorageProcess for serviceWorker.postMessage()
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Dec 2017 18:08:53 +0000 (18:08 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 12 Dec 2017 18:08:53 +0000 (18:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=180683

Reviewed by Brady Eidson.

Merge the 2 code paths from calling postMessage() from a ServiceWorkerClient and from
a ServiceWorker. Also, postMessage() now only IPCs an identifier from the WebContent
process to the StorageProcess. The ServiceWorkerClientData is looked up on Storage
process side from the identifier before being sent to the context process.

Source/WebCore:

* workers/service/SWClientConnection.h:
* workers/service/ServiceWorker.cpp:
(WebCore::ServiceWorker::postMessage):
* workers/service/ServiceWorkerTypes.h:
* workers/service/server/SWServer.cpp:
(WebCore::SWServer::clientByID const):
(WebCore::SWServer::matchAll):
(WebCore::SWServer::forEachClientForOrigin):
(WebCore::SWServer::claim):
(WebCore::SWServer::registerServiceWorkerClient):
(WebCore::SWServer::unregisterServiceWorkerClient):
* workers/service/server/SWServer.h:
* workers/service/server/SWServerWorker.cpp:
(WebCore::SWServerWorker::findClientByIdentifier):
* workers/service/server/SWServerWorker.h:

Source/WebKit:

* Scripts/webkit/messages.py:
(forward_declarations_and_headers):
(headers_for_type):
* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<ServiceWorkerOrClientIdentifier>::encode):
(IPC::ArgumentCoder<ServiceWorkerOrClientIdentifier>::decode):
* Shared/WebCoreArgumentCoders.h:
* StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::postMessageToServiceWorker):
* StorageProcess/ServiceWorker/WebSWServerConnection.h:
* StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
* WebProcess/Storage/WebSWClientConnection.cpp:
(WebKit::WebSWClientConnection::postMessageToServiceWorker):
* WebProcess/Storage/WebSWClientConnection.h:

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

18 files changed:
Source/WebCore/ChangeLog
Source/WebCore/dom/Document.cpp
Source/WebCore/workers/service/SWClientConnection.h
Source/WebCore/workers/service/ServiceWorker.cpp
Source/WebCore/workers/service/ServiceWorkerTypes.h
Source/WebCore/workers/service/server/SWServer.cpp
Source/WebCore/workers/service/server/SWServer.h
Source/WebCore/workers/service/server/SWServerWorker.cpp
Source/WebCore/workers/service/server/SWServerWorker.h
Source/WebKit/ChangeLog
Source/WebKit/Scripts/webkit/messages.py
Source/WebKit/Shared/WebCoreArgumentCoders.cpp
Source/WebKit/Shared/WebCoreArgumentCoders.h
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.cpp
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.h
Source/WebKit/StorageProcess/ServiceWorker/WebSWServerConnection.messages.in
Source/WebKit/WebProcess/Storage/WebSWClientConnection.cpp
Source/WebKit/WebProcess/Storage/WebSWClientConnection.h

index 94b8154..f00d161 100644 (file)
@@ -1,3 +1,31 @@
+2017-12-12  Chris Dumez  <cdumez@apple.com>
+
+        Simplify IPC code between WebProcess and StorageProcess for serviceWorker.postMessage()
+        https://bugs.webkit.org/show_bug.cgi?id=180683
+
+        Reviewed by Brady Eidson.
+
+        Merge the 2 code paths from calling postMessage() from a ServiceWorkerClient and from
+        a ServiceWorker. Also, postMessage() now only IPCs an identifier from the WebContent
+        process to the StorageProcess. The ServiceWorkerClientData is looked up on Storage
+        process side from the identifier before being sent to the context process.
+
+        * workers/service/SWClientConnection.h:
+        * workers/service/ServiceWorker.cpp:
+        (WebCore::ServiceWorker::postMessage):
+        * workers/service/ServiceWorkerTypes.h:
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::clientByID const):
+        (WebCore::SWServer::matchAll):
+        (WebCore::SWServer::forEachClientForOrigin):
+        (WebCore::SWServer::claim):
+        (WebCore::SWServer::registerServiceWorkerClient):
+        (WebCore::SWServer::unregisterServiceWorkerClient):
+        * workers/service/server/SWServer.h:
+        * workers/service/server/SWServerWorker.cpp:
+        (WebCore::SWServerWorker::findClientByIdentifier):
+        * workers/service/server/SWServerWorker.h:
+
 2017-12-12  Youenn Fablet  <youenn@apple.com>
 
         Allow AudioContext to start when getUserMedia is on
index cab860f..d0dfca2 100644 (file)
@@ -4965,6 +4965,11 @@ void Document::privateBrowsingStateDidChange()
 
     for (auto* element : m_privateBrowsingStateChangedElements)
         element->privateBrowsingStateDidChange();
+
+#if ENABLE(SERVICE_WORKER)
+    if (RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled())
+        setServiceWorkerConnection(&ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(sessionID()));
+#endif
 }
 
 void Document::registerForPrivateBrowsingStateChangedCallbacks(Element* e)
index 5c2d392..11c02ee 100644 (file)
@@ -74,8 +74,7 @@ public:
 
     virtual void didResolveRegistrationPromise(const ServiceWorkerRegistrationKey&) = 0;
 
-    virtual void postMessageToServiceWorker(ServiceWorkerIdentifier destination, Ref<SerializedScriptValue>&& message, ServiceWorkerClientIdentifier sourceIdentifier, ServiceWorkerClientData&& sourceData) = 0;
-    virtual void postMessageToServiceWorker(ServiceWorkerIdentifier destination, Ref<SerializedScriptValue>&& message, ServiceWorkerIdentifier source) = 0;
+    virtual void postMessageToServiceWorker(ServiceWorkerIdentifier destination, Ref<SerializedScriptValue>&& message, const ServiceWorkerOrClientIdentifier& source) = 0;
 
     virtual SWServerConnectionIdentifier serverConnectionIdentifier() const = 0;
     virtual bool mayHaveServiceWorkerRegisteredForOrigin(const SecurityOrigin&) const = 0;
index e477620..507358c 100644 (file)
@@ -114,21 +114,18 @@ ExceptionOr<void> ServiceWorker::postMessage(ScriptExecutionContext& context, JS
     if (channels && !channels->isEmpty())
         return Exception { NotSupportedError, ASCIILiteral("Passing MessagePort objects to postMessage is not yet supported") };
 
-    if (is<ServiceWorkerGlobalScope>(context)) {
-        auto sourceWorkerIdentifier = downcast<ServiceWorkerGlobalScope>(context).thread().identifier();
-        callOnMainThread([sessionID = context.sessionID(), destinationIdentifier = identifier(), sourceWorkerIdentifier, message = WTFMove(message)]() mutable {
-            auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(sessionID);
-            connection.postMessageToServiceWorker(destinationIdentifier, message.releaseReturnValue(), sourceWorkerIdentifier);
-        });
-        return { };
+    ServiceWorkerOrClientIdentifier sourceIdentifier;
+    if (is<ServiceWorkerGlobalScope>(context))
+        sourceIdentifier = downcast<ServiceWorkerGlobalScope>(context).thread().identifier();
+    else {
+        auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(context.sessionID());
+        sourceIdentifier = ServiceWorkerClientIdentifier { connection.serverConnectionIdentifier(), downcast<Document>(context).identifier() };
     }
 
-    auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(context.sessionID());
-    // FIXME: We should be able to send only the client identifier and look up the clientData on server side.
-    auto sourceClientData = ServiceWorkerClientData::from(context, connection);
-    ServiceWorkerClientIdentifier sourceClientIdentifier { connection.serverConnectionIdentifier(), downcast<Document>(context).identifier() };
-    connection.postMessageToServiceWorker(identifier(), message.releaseReturnValue(), WTFMove(sourceClientIdentifier), WTFMove(sourceClientData));
-
+    callOnMainThread([sessionID = context.sessionID(), destinationIdentifier = identifier(), message = WTFMove(message), sourceIdentifier = WTFMove(sourceIdentifier)]() mutable {
+        auto& connection = ServiceWorkerProvider::singleton().serviceWorkerConnectionForSession(sessionID);
+        connection.postMessageToServiceWorker(destinationIdentifier, message.releaseReturnValue(), sourceIdentifier);
+    });
     return { };
 }
 
index b9cab73..c0ff6de 100644 (file)
@@ -37,6 +37,7 @@ namespace WebCore {
 
 struct ServiceWorkerData;
 struct ServiceWorkerClientData;
+struct ServiceWorkerClientIdentifier;
 
 enum class ServiceWorkerRegistrationState {
     Installing = 0,
@@ -76,6 +77,7 @@ using SWServerConnectionIdentifier = ObjectIdentifier<SWServerConnectionIdentifi
 using DocumentOrWorkerIdentifier = Variant<DocumentIdentifier, ServiceWorkerIdentifier>;
 
 using ServiceWorkerOrClientData = Variant<ServiceWorkerData, ServiceWorkerClientData>;
+using ServiceWorkerOrClientIdentifier = Variant<ServiceWorkerIdentifier, ServiceWorkerClientIdentifier>;
 
 } // namespace WebCore
 
index 42c4711..a1b66d1 100644 (file)
@@ -93,6 +93,14 @@ SWServerWorker* SWServer::workerByID(ServiceWorkerIdentifier identifier) const
     return worker;
 }
 
+std::optional<ServiceWorkerClientData> SWServer::serviceWorkerClientByID(const ServiceWorkerClientIdentifier& clientIdentifier) const
+{
+    auto iterator = m_clientsById.find(clientIdentifier);
+    if (iterator == m_clientsById.end())
+        return std::nullopt;
+    return iterator->value;
+}
+
 SWServerRegistration* SWServer::getRegistration(const ServiceWorkerRegistrationKey& registrationKey)
 {
     return m_registrations.get(registrationKey);
@@ -332,67 +340,54 @@ void SWServer::didFinishActivation(SWServerWorker& worker)
         registration->didFinishActivation(worker.identifier());
 }
 
-// https://w3c.github.io/ServiceWorker/#clients-get
-std::optional<ServiceWorkerClientData> SWServer::findClientByIdentifier(const ClientOrigin& origin, ServiceWorkerClientIdentifier clientIdentifier)
+// https://w3c.github.io/ServiceWorker/#clients-getall
+void SWServer::matchAll(SWServerWorker& worker, const ServiceWorkerClientQueryOptions& options, ServiceWorkerClientsMatchAllCallback&& callback)
 {
+    // FIXME: Support reserved client filtering.
     // FIXME: Support WindowClient additional properties.
 
-    auto iterator = m_clients.find(origin);
-    if (iterator == m_clients.end())
-        return std::nullopt;
-
-    auto& clients = iterator->value.clients;
-    auto position = clients.findMatching([&] (const auto& client) {
-        return clientIdentifier == client.identifier;
+    Vector<ServiceWorkerClientData> matchingClients;
+    forEachClientForOrigin(worker.origin(), [&](auto& clientData) {
+        if (!options.includeUncontrolled && worker.identifier() != m_clientToControllingWorker.get(clientData.identifier))
+            return;
+        if (options.type != ServiceWorkerClientType::All && options.type != clientData.type)
+            return;
+        matchingClients.append(clientData);
     });
-
-    return (position != notFound) ? std::make_optional(clients[position]) : std::nullopt;
+    callback(WTFMove(matchingClients));
 }
 
-// https://w3c.github.io/ServiceWorker/#clients-getall
-void SWServer::matchAll(SWServerWorker& worker, const ServiceWorkerClientQueryOptions& options, ServiceWorkerClientsMatchAllCallback&& callback)
+void SWServer::forEachClientForOrigin(const ClientOrigin& origin, const WTF::Function<void(ServiceWorkerClientData&)>& apply)
 {
-    // FIXME: Support reserved client filtering.
-    // FIXME: Support WindowClient additional properties.
-
-    auto clients = m_clients.find(worker.origin())->value.clients;
+    auto iterator = m_clientIdentifiersPerOrigin.find(origin);
+    if (iterator == m_clientIdentifiersPerOrigin.end())
+        return;
 
-    if (!options.includeUncontrolled) {
-        clients.removeAllMatching([&] (const auto& clientData) {
-            return worker.identifier() != m_clientToControllingWorker.get(clientData.identifier);
-        });
+    for (auto& clientIdentifier : iterator->value.identifiers) {
+        auto clientIterator = m_clientsById.find(clientIdentifier);
+        ASSERT(clientIterator != m_clientsById.end());
+        apply(clientIterator->value);
     }
-    if (options.type != ServiceWorkerClientType::All) {
-        clients.removeAllMatching([&] (const auto& clientData) {
-            return options.type != clientData.type;
-        });
-    }
-    callback(WTFMove(clients));
 }
 
 void SWServer::claim(SWServerWorker& worker)
 {
     auto& origin = worker.origin();
-    auto iterator = m_clients.find(origin);
-    if (iterator == m_clients.end())
-        return;
-
-    auto& clients = iterator->value.clients;
-    for (auto& clientData : clients) {
+    forEachClientForOrigin(origin, [&](auto& clientData) {
         auto* registration = doRegistrationMatching(origin.topOrigin, clientData.url);
         if (!(registration && registration->key() == worker.registrationKey()))
-            continue;
+            return;
 
         auto result = m_clientToControllingWorker.add(clientData.identifier, worker.identifier());
         if (!result.isNewEntry) {
             if (result.iterator->value == worker.identifier())
-                continue;
+                return;
             if (auto* controllingRegistration = registrationFromServiceWorkerIdentifier(result.iterator->value))
                 controllingRegistration->removeClientUsingRegistration(clientData.identifier);
             result.iterator->value = worker.identifier();
         }
         registration->controlClient(clientData.identifier);
-    }
+    });
 }
 
 void SWServer::didResolveRegistrationPromise(Connection& connection, const ServiceWorkerRegistrationKey& registrationKey)
@@ -689,13 +684,15 @@ SWServerRegistration* SWServer::registrationFromServiceWorkerIdentifier(ServiceW
 
 void SWServer::registerServiceWorkerClient(ClientOrigin&& clientOrigin, ServiceWorkerClientData&& data, const std::optional<ServiceWorkerIdentifier>& controllingServiceWorkerIdentifier)
 {
-    auto& clientsData = m_clients.ensure(WTFMove(clientOrigin), [] {
+    auto clientIdentifier = data.identifier;
+    auto addResult = m_clientsById.add(clientIdentifier, WTFMove(data));
+    ASSERT_UNUSED(addResult, addResult.isNewEntry);
+
+    auto& clientIdentifiersForOrigin = m_clientIdentifiersPerOrigin.ensure(WTFMove(clientOrigin), [] {
         return Clients { };
     }).iterator->value;
-
-    auto clientIdentifier = data.identifier;
-    clientsData.clients.append(WTFMove(data));
-    clientsData.terminateServiceWorkersTimer = nullptr;
+    clientIdentifiersForOrigin.identifiers.append(clientIdentifier);
+    clientIdentifiersForOrigin.terminateServiceWorkersTimer = nullptr;
 
     if (!controllingServiceWorkerIdentifier)
         return;
@@ -709,23 +706,26 @@ void SWServer::registerServiceWorkerClient(ClientOrigin&& clientOrigin, ServiceW
 
 void SWServer::unregisterServiceWorkerClient(const ClientOrigin& clientOrigin, ServiceWorkerClientIdentifier clientIdentifier)
 {
-    auto clientIterator = m_clients.find(clientOrigin);
-    ASSERT(clientIterator != m_clients.end());
+    bool wasRemoved = m_clientsById.remove(clientIdentifier);
+    ASSERT_UNUSED(wasRemoved, wasRemoved);
+
+    auto iterator = m_clientIdentifiersPerOrigin.find(clientOrigin);
+    ASSERT(iterator != m_clientIdentifiersPerOrigin.end());
 
-    auto& clients = clientIterator->value.clients;
-    clients.removeFirstMatching([&] (const auto& client) {
-        return clientIdentifier == client.identifier;
+    auto& clientIdentifiers = iterator->value.identifiers;
+    clientIdentifiers.removeFirstMatching([&] (const auto& identifier) {
+        return clientIdentifier == identifier;
     });
-    if (clients.isEmpty()) {
-        ASSERT(!clientIterator->value.terminateServiceWorkersTimer);
-        clientIterator->value.terminateServiceWorkersTimer = std::make_unique<Timer>([clientOrigin, this] {
+    if (clientIdentifiers.isEmpty()) {
+        ASSERT(!iterator->value.terminateServiceWorkersTimer);
+        iterator->value.terminateServiceWorkersTimer = std::make_unique<Timer>([clientOrigin, this] {
             for (auto& worker : m_runningOrTerminatingWorkers.values()) {
                 if (worker->origin() == clientOrigin)
                     terminateWorker(worker);
             }
-            m_clients.remove(clientOrigin);
+            m_clientIdentifiersPerOrigin.remove(clientOrigin);
         });
-        clientIterator->value.terminateServiceWorkersTimer->startOneShot(terminationDelay);
+        iterator->value.terminateServiceWorkersTimer->startOneShot(terminationDelay);
     }
 
     auto workerIterator = m_clientToControllingWorker.find(clientIdentifier);
index 1b2f7dc..5c2e043 100644 (file)
@@ -139,7 +139,9 @@ public:
     void syncTerminateWorker(SWServerWorker&);
     void fireInstallEvent(SWServerWorker&);
     void fireActivateEvent(SWServerWorker&);
+
     WEBCORE_EXPORT SWServerWorker* workerByID(ServiceWorkerIdentifier) const;
+    WEBCORE_EXPORT std::optional<ServiceWorkerClientData> serviceWorkerClientByID(const ServiceWorkerClientIdentifier&) const;
 
     WEBCORE_EXPORT void markAllWorkersAsTerminated();
     
@@ -151,7 +153,6 @@ public:
     void didFinishInstall(const std::optional<ServiceWorkerJobDataIdentifier>&, SWServerWorker&, bool wasSuccessful);
     void didFinishActivation(SWServerWorker&);
     void workerContextTerminated(SWServerWorker&);
-    std::optional<ServiceWorkerClientData> findClientByIdentifier(const ClientOrigin&, ServiceWorkerClientIdentifier);
     void matchAll(SWServerWorker&, const ServiceWorkerClientQueryOptions&, ServiceWorkerClientsMatchAllCallback&&);
     void claim(SWServerWorker&);
 
@@ -192,6 +193,7 @@ private:
     void installContextData(const ServiceWorkerContextData&);
 
     SWServerRegistration* registrationFromServiceWorkerIdentifier(ServiceWorkerIdentifier);
+    void forEachClientForOrigin(const ClientOrigin&, const WTF::Function<void(ServiceWorkerClientData&)>&);
 
     enum TerminationMode {
         Synchronous,
@@ -207,10 +209,11 @@ private:
     HashMap<ServiceWorkerIdentifier, Ref<SWServerWorker>> m_runningOrTerminatingWorkers;
 
     struct Clients {
-        Vector<ServiceWorkerClientData> clients;
+        Vector<ServiceWorkerClientIdentifier> identifiers;
         std::unique_ptr<Timer> terminateServiceWorkersTimer;
     };
-    HashMap<ClientOrigin, Clients> m_clients;
+    HashMap<ClientOrigin, Clients> m_clientIdentifiersPerOrigin;
+    HashMap<ServiceWorkerClientIdentifier, ServiceWorkerClientData> m_clientsById;
     HashMap<ServiceWorkerClientIdentifier, ServiceWorkerIdentifier> m_clientToControllingWorker;
 
     RefPtr<Thread> m_taskThread;
index 929c063..e01154e 100644 (file)
@@ -107,9 +107,9 @@ void SWServerWorker::contextTerminated()
     m_server.workerContextTerminated(*this);
 }
 
-std::optional<ServiceWorkerClientData> SWServerWorker::findClientByIdentifier(ServiceWorkerClientIdentifier clientId)
+std::optional<ServiceWorkerClientData> SWServerWorker::findClientByIdentifier(const ServiceWorkerClientIdentifier& clientId) const
 {
-    return m_server.findClientByIdentifier(origin(), clientId);
+    return m_server.serviceWorkerClientByID(clientId);
 }
 
 void SWServerWorker::matchAll(const ServiceWorkerClientQueryOptions& options, ServiceWorkerClientsMatchAllCallback&& callback)
index 127a5d7..e1275c0 100644 (file)
@@ -88,7 +88,7 @@ public:
     void didFinishInstall(const std::optional<ServiceWorkerJobDataIdentifier>&, bool wasSuccessful);
     void didFinishActivation();
     void contextTerminated();
-    std::optional<ServiceWorkerClientData> findClientByIdentifier(ServiceWorkerClientIdentifier);
+    std::optional<ServiceWorkerClientData> findClientByIdentifier(const ServiceWorkerClientIdentifier&) const;
     void matchAll(const ServiceWorkerClientQueryOptions&, ServiceWorkerClientsMatchAllCallback&&);
     void claim();
 
index df05878..2cf09d3 100644 (file)
@@ -1,3 +1,30 @@
+2017-12-12  Chris Dumez  <cdumez@apple.com>
+
+        Simplify IPC code between WebProcess and StorageProcess for serviceWorker.postMessage()
+        https://bugs.webkit.org/show_bug.cgi?id=180683
+
+        Reviewed by Brady Eidson.
+
+        Merge the 2 code paths from calling postMessage() from a ServiceWorkerClient and from
+        a ServiceWorker. Also, postMessage() now only IPCs an identifier from the WebContent
+        process to the StorageProcess. The ServiceWorkerClientData is looked up on Storage
+        process side from the identifier before being sent to the context process.
+
+        * Scripts/webkit/messages.py:
+        (forward_declarations_and_headers):
+        (headers_for_type):
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<ServiceWorkerOrClientIdentifier>::encode):
+        (IPC::ArgumentCoder<ServiceWorkerOrClientIdentifier>::decode):
+        * Shared/WebCoreArgumentCoders.h:
+        * StorageProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::postMessageToServiceWorker):
+        * StorageProcess/ServiceWorker/WebSWServerConnection.h:
+        * StorageProcess/ServiceWorker/WebSWServerConnection.messages.in:
+        * WebProcess/Storage/WebSWClientConnection.cpp:
+        (WebKit::WebSWClientConnection::postMessageToServiceWorker):
+        * WebProcess/Storage/WebSWClientConnection.h:
+
 2017-12-12  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         [WTF] Thread::create should have Thread::tryCreate
index 5a73810..d1dd654 100644 (file)
@@ -187,6 +187,7 @@ def forward_declarations_and_headers(receiver):
         'WebCore::DocumentIdentifier',
         'WebCore::ServiceWorkerIdentifier',
         'WebCore::ServiceWorkerOrClientData',
+        'WebCore::ServiceWorkerOrClientIdentifier',
         'WebCore::ServiceWorkerRegistrationIdentifier',
         'WebCore::SWServerConnectionIdentifier',
     ])
@@ -384,6 +385,7 @@ def headers_for_type(type):
         'WebCore::RecentSearch': ['<WebCore/SearchPopupMenu.h>'],
         'WebCore::SWServerConnectionIdentifier': ['<WebCore/ServiceWorkerTypes.h>'],
         'WebCore::ServiceWorkerOrClientData': ['<WebCore/ServiceWorkerTypes.h>', '<WebCore/ServiceWorkerClientData.h>', '<WebCore/ServiceWorkerData.h>'],
+        'WebCore::ServiceWorkerOrClientIdentifier': ['<WebCore/ServiceWorkerTypes.h>', '<WebCore/ServiceWorkerClientIdentifier.h>'],
         'WebCore::ServiceWorkerRegistrationIdentifier': ['<WebCore/ServiceWorkerTypes.h>'],
         'WebCore::ServiceWorkerRegistrationState': ['<WebCore/ServiceWorkerTypes.h>'],
         'WebCore::ServiceWorkerState': ['<WebCore/ServiceWorkerTypes.h>'],
index 0830c9a..8a7d560 100644 (file)
@@ -66,6 +66,7 @@
 #include <WebCore/ScrollingCoordinator.h>
 #include <WebCore/SearchPopupMenu.h>
 #include <WebCore/ServiceWorkerClientData.h>
+#include <WebCore/ServiceWorkerClientIdentifier.h>
 #include <WebCore/ServiceWorkerData.h>
 #include <WebCore/TextCheckerClient.h>
 #include <WebCore/TextIndicator.h>
@@ -2719,6 +2720,39 @@ bool ArgumentCoder<ServiceWorkerOrClientData>::decode(Decoder& decoder, ServiceW
     }
     return true;
 }
+
+void ArgumentCoder<ServiceWorkerOrClientIdentifier>::encode(Encoder& encoder, const ServiceWorkerOrClientIdentifier& identifier)
+{
+    bool isServiceWorkerIdentifier = WTF::holds_alternative<ServiceWorkerIdentifier>(identifier);
+    encoder << isServiceWorkerIdentifier;
+    if (isServiceWorkerIdentifier)
+        encoder << WTF::get<ServiceWorkerIdentifier>(identifier);
+    else
+        encoder << WTF::get<ServiceWorkerClientIdentifier>(identifier);
+}
+
+bool ArgumentCoder<ServiceWorkerOrClientIdentifier>::decode(Decoder& decoder, ServiceWorkerOrClientIdentifier& identifier)
+{
+    bool isServiceWorkerIdentifier;
+    if (!decoder.decode(isServiceWorkerIdentifier))
+        return false;
+    if (isServiceWorkerIdentifier) {
+        std::optional<ServiceWorkerIdentifier> workerIdentifier;
+        decoder >> workerIdentifier;
+        if (!workerIdentifier)
+            return false;
+
+        identifier = WTFMove(*workerIdentifier);
+    } else {
+        std::optional<ServiceWorkerClientIdentifier> clientIdentifier;
+        decoder >> clientIdentifier;
+        if (!clientIdentifier)
+            return false;
+
+        identifier = WTFMove(*clientIdentifier);
+    }
+    return true;
+}
 #endif
 
 #if ENABLE(CSS_SCROLL_SNAP)
index 910a4ec..b624784 100644 (file)
@@ -675,6 +675,11 @@ template<> struct ArgumentCoder<WebCore::ServiceWorkerOrClientData> {
     static bool decode(Decoder&, WebCore::ServiceWorkerOrClientData&);
 };
 
+template<> struct ArgumentCoder<WebCore::ServiceWorkerOrClientIdentifier> {
+    static void encode(Encoder&, const WebCore::ServiceWorkerOrClientIdentifier&);
+    static bool decode(Decoder&, WebCore::ServiceWorkerOrClientIdentifier&);
+};
+
 #endif
 
 #if ENABLE(CSS_SCROLL_SNAP)
index 55ab719..b3ebd98 100644 (file)
@@ -127,28 +127,24 @@ void WebSWServerConnection::startFetch(uint64_t fetchIdentifier, ServiceWorkerId
     });
 }
 
-// FIXME: We should be able to only pass in the ServiceWorkerClientIdentifier here and look up the clientData from the SWServer.
-void WebSWServerConnection::postMessageToServiceWorkerFromClient(ServiceWorkerIdentifier destinationIdentifier, IPC::DataReference&& message, ServiceWorkerClientIdentifier, ServiceWorkerClientData&& sourceData)
-{
-    // It's possible this specific worker cannot be re-run (e.g. its registration has been removed)
-    server().runServiceWorkerIfNecessary(destinationIdentifier, [destinationIdentifier, message = message.vector(), sourceData = WTFMove(sourceData)](bool success, auto& contextConnection) mutable {
-        if (success)
-            sendToContextProcess(contextConnection, Messages::WebSWContextManagerConnection::PostMessageToServiceWorker { destinationIdentifier, message, WTFMove(sourceData) });
+void WebSWServerConnection::postMessageToServiceWorker(ServiceWorkerIdentifier destinationIdentifier, IPC::DataReference&& message, const ServiceWorkerOrClientIdentifier& sourceIdentifier)
+{
+    std::optional<ServiceWorkerOrClientData> sourceData;
+    WTF::switchOn(sourceIdentifier, [&](ServiceWorkerIdentifier identifier) {
+        if (auto* sourceWorker = server().workerByID(identifier))
+            sourceData = ServiceWorkerOrClientData { sourceWorker->data() };
+    }, [&](ServiceWorkerClientIdentifier identifier) {
+        if (auto clientData = server().serviceWorkerClientByID(identifier))
+            sourceData = ServiceWorkerOrClientData { *clientData };
     });
-}
 
-void WebSWServerConnection::postMessageToServiceWorkerFromServiceWorker(ServiceWorkerIdentifier destinationIdentifier, IPC::DataReference&& message, ServiceWorkerIdentifier sourceIdentifier)
-{
-    auto* sourceWorker = server().workerByID(sourceIdentifier);
-    if (!sourceWorker)
+    if (!sourceData)
         return;
 
     // It's possible this specific worker cannot be re-run (e.g. its registration has been removed)
-    server().runServiceWorkerIfNecessary(destinationIdentifier, [destinationIdentifier, message = message.vector(), sourceData = sourceWorker->data()](bool success, auto& contextConnection) mutable {
-        if (!success)
-            return;
-
-        sendToContextProcess(contextConnection, Messages::WebSWContextManagerConnection::PostMessageToServiceWorker { destinationIdentifier, message, WTFMove(sourceData) });
+    server().runServiceWorkerIfNecessary(destinationIdentifier, [destinationIdentifier, message = message.vector(), sourceData = WTFMove(*sourceData)](bool success, auto& contextConnection) mutable {
+        if (success)
+            sendToContextProcess(contextConnection, Messages::WebSWContextManagerConnection::PostMessageToServiceWorker { destinationIdentifier, message, WTFMove(sourceData) });
     });
 }
 
index a4e4997..d69dd5f 100644 (file)
@@ -83,8 +83,7 @@ private:
 
     void startFetch(uint64_t fetchIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::ResourceRequest&&, WebCore::FetchOptions&&, IPC::FormDataReference&&);
 
-    void postMessageToServiceWorkerFromClient(WebCore::ServiceWorkerIdentifier destination, IPC::DataReference&& message, WebCore::ServiceWorkerClientIdentifier sourceIdentifier, WebCore::ServiceWorkerClientData&& source);
-    void postMessageToServiceWorkerFromServiceWorker(WebCore::ServiceWorkerIdentifier destination, IPC::DataReference&& message, WebCore::ServiceWorkerIdentifier source);
+    void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, IPC::DataReference&& message, const WebCore::ServiceWorkerOrClientIdentifier& source);
 
     void matchRegistration(uint64_t registrationMatchRequestIdentifier, const WebCore::SecurityOriginData& topOrigin, const WebCore::URL& clientURL);
     void getRegistrations(uint64_t registrationMatchRequestIdentifier, const WebCore::SecurityOriginData& topOrigin, const WebCore::URL& clientURL);
index b4024ab..382a270 100644 (file)
@@ -31,9 +31,7 @@ messages -> WebSWServerConnection {
 
     StartFetch(uint64_t identifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options, IPC::FormDataReference requestBody)
 
-    # FIXME: We should be able to merge the 2 following messages and use a DocumentOrWorkerIdentifier as source identifier.
-    PostMessageToServiceWorkerFromClient(WebCore::ServiceWorkerIdentifier destinationServiceWorkerIdentifier, IPC::DataReference message, struct WebCore::ServiceWorkerClientIdentifier sourceIdentifier, struct WebCore::ServiceWorkerClientData sourceData)
-    PostMessageToServiceWorkerFromServiceWorker(WebCore::ServiceWorkerIdentifier destinationServiceWorkerIdentifier, IPC::DataReference message, struct WebCore::ServiceWorkerIdentifier sourceIdentifier)
+    PostMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destination, IPC::DataReference message, WebCore::ServiceWorkerOrClientIdentifier source)
 
     DidResolveRegistrationPromise(WebCore::ServiceWorkerRegistrationKey key)
 
index 701421e..b16a862 100644 (file)
@@ -82,14 +82,9 @@ void WebSWClientConnection::removeServiceWorkerRegistrationInServer(ServiceWorke
     send(Messages::WebSWServerConnection::RemoveServiceWorkerRegistrationInServer(identifier));
 }
 
-void WebSWClientConnection::postMessageToServiceWorker(ServiceWorkerIdentifier destinationIdentifier, Ref<SerializedScriptValue>&& scriptValue, ServiceWorkerClientIdentifier sourceIdentifier, ServiceWorkerClientData&& source)
+void WebSWClientConnection::postMessageToServiceWorker(ServiceWorkerIdentifier destinationIdentifier, Ref<SerializedScriptValue>&& scriptValue, const ServiceWorkerOrClientIdentifier& sourceIdentifier)
 {
-    send(Messages::WebSWServerConnection::PostMessageToServiceWorkerFromClient(destinationIdentifier, IPC::DataReference { scriptValue->data() }, sourceIdentifier, WTFMove(source)));
-}
-
-void WebSWClientConnection::postMessageToServiceWorker(ServiceWorkerIdentifier destinationIdentifier, Ref<SerializedScriptValue>&& scriptValue, ServiceWorkerIdentifier sourceWorkerIdentifier)
-{
-    send(Messages::WebSWServerConnection::PostMessageToServiceWorkerFromServiceWorker(destinationIdentifier, IPC::DataReference { scriptValue->data() }, sourceWorkerIdentifier));
+    send(Messages::WebSWServerConnection::PostMessageToServiceWorker(destinationIdentifier, IPC::DataReference { scriptValue->data() }, sourceIdentifier) );
 }
 
 void WebSWClientConnection::registerServiceWorkerClient(const SecurityOrigin& topOrigin, const WebCore::ServiceWorkerClientData& data, const std::optional<WebCore::ServiceWorkerIdentifier>& controllingServiceWorkerIdentifier)
index 737b141..46556ba 100644 (file)
@@ -73,8 +73,7 @@ private:
 
     void scheduleJobInServer(const WebCore::ServiceWorkerJobData&) final;
     void finishFetchingScriptInServer(const WebCore::ServiceWorkerFetchResult&) final;
-    void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destinationIdentifier, Ref<WebCore::SerializedScriptValue>&&, WebCore::ServiceWorkerClientIdentifier sourceIdentifier, WebCore::ServiceWorkerClientData&& source) final;
-    void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destinationIdentifier, Ref<WebCore::SerializedScriptValue>&&, WebCore::ServiceWorkerIdentifier sourceWorkerIdentifier) final;
+    void postMessageToServiceWorker(WebCore::ServiceWorkerIdentifier destinationIdentifier, Ref<WebCore::SerializedScriptValue>&&, const WebCore::ServiceWorkerOrClientIdentifier& source) final;
     void registerServiceWorkerClient(const WebCore::SecurityOrigin& topOrigin, const WebCore::ServiceWorkerClientData&, const std::optional<WebCore::ServiceWorkerIdentifier>&) final;
     void unregisterServiceWorkerClient(WebCore::DocumentIdentifier) final;