Title: [282377] trunk
Revision
282377
Author
[email protected]
Date
2021-09-13 21:15:43 -0700 (Mon, 13 Sep 2021)

Log Message

[WK2] Reduce amount of IPC needed by BroadcastChannel
https://bugs.webkit.org/show_bug.cgi?id=230181

Reviewed by Alex Christensen.

Source/WebCore:

Introduce ScriptExecutionContext::ensureOnContextThread() which is similar to
ScriptExecutionContext::postTaskTo() but doesn't call postTask() if we're already
on the ScriptExecutionContext's context thread. Use it in BroadcastChannel::dispatchMessageTo()
to avoid unnecessary thread hopping when the BroadcastChannel belongs to a Window
environment.

* dom/BroadcastChannel.cpp:
(WebCore::BroadcastChannel::dispatchMessageTo):
* dom/ScriptExecutionContext.cpp:
(WebCore::ScriptExecutionContext::ensureOnContextThread):
* dom/ScriptExecutionContext.h:

Source/WebKit:

Reduce amount of IPC needed by BroadcastChannel for both registration / unregistration
and communication. Each WebBroadcastChannelRegistry in the WebProcess now maintains
a map of BroadcastChannels within the WebProcess. As a result, we are able to dispatch
messages to other BroadcastChannels within the same process without going via the
NetworkProcess.

Also, the NetworkBroadcastChannelRegistry on the NetworkProcess side no longer needs
to store individual BroadcastChannelIdentifiers. It merely needs to know which
WebProcesses have one or more BroadcastChannels for a given ClientOrigin / name.
When NetworkBroadcastChannelRegistry::postMessage() is called, we no longer send
IPC to the source process in case there are other BroadcastChannels than the source
with the given ClientOrigin / name in that process. Also, if there is more than
one BroadcastChannel for the given ClientOrigin / name within a given destination
WebProcess, we now send a single IPC message instead of sending one per BroadcastChannel.

* NetworkProcess/NetworkBroadcastChannelRegistry.cpp:
(WebKit::NetworkBroadcastChannelRegistry::registerChannel):
(WebKit::NetworkBroadcastChannelRegistry::unregisterChannel):
(WebKit::NetworkBroadcastChannelRegistry::postMessage):
(WebKit::NetworkBroadcastChannelRegistry::removeConnection):
* NetworkProcess/NetworkBroadcastChannelRegistry.h:
* NetworkProcess/NetworkBroadcastChannelRegistry.messages.in:
* WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp:
(WebKit::WebBroadcastChannelRegistry::registerChannel):
(WebKit::WebBroadcastChannelRegistry::unregisterChannel):
(WebKit::WebBroadcastChannelRegistry::postMessage):
(WebKit::WebBroadcastChannelRegistry::postMessageLocally):
(WebKit::WebBroadcastChannelRegistry::postMessageToRemote):
* WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h:
* WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.messages.in:

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-navigated-history-popup.https-expected.txt (282376 => 282377)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-navigated-history-popup.https-expected.txt	2021-09-14 03:55:56 UTC (rev 282376)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/cross-origin-opener-policy/coop-navigated-history-popup.https-expected.txt	2021-09-14 04:15:43 UTC (rev 282377)
@@ -1,3 +1,4 @@
+CONSOLE MESSAGE: Can't close the window since it was not opened by _javascript_
 
 PASS Popup navigating to other origin with COOP: same-origin and back in history
 

Modified: trunk/Source/WebCore/ChangeLog (282376 => 282377)


--- trunk/Source/WebCore/ChangeLog	2021-09-14 03:55:56 UTC (rev 282376)
+++ trunk/Source/WebCore/ChangeLog	2021-09-14 04:15:43 UTC (rev 282377)
@@ -1,3 +1,22 @@
+2021-09-13  Chris Dumez  <[email protected]>
+
+        [WK2] Reduce amount of IPC needed by BroadcastChannel
+        https://bugs.webkit.org/show_bug.cgi?id=230181
+
+        Reviewed by Alex Christensen.
+
+        Introduce ScriptExecutionContext::ensureOnContextThread() which is similar to
+        ScriptExecutionContext::postTaskTo() but doesn't call postTask() if we're already
+        on the ScriptExecutionContext's context thread. Use it in BroadcastChannel::dispatchMessageTo()
+        to avoid unnecessary thread hopping when the BroadcastChannel belongs to a Window
+        environment.
+
+        * dom/BroadcastChannel.cpp:
+        (WebCore::BroadcastChannel::dispatchMessageTo):
+        * dom/ScriptExecutionContext.cpp:
+        (WebCore::ScriptExecutionContext::ensureOnContextThread):
+        * dom/ScriptExecutionContext.h:
+
 2021-09-13  Jean-Yves Avenard  <[email protected]>
 
         Playback stops although the progress bar moves

Modified: trunk/Source/WebCore/dom/BroadcastChannel.cpp (282376 => 282377)


--- trunk/Source/WebCore/dom/BroadcastChannel.cpp	2021-09-14 03:55:56 UTC (rev 282376)
+++ trunk/Source/WebCore/dom/BroadcastChannel.cpp	2021-09-14 04:15:43 UTC (rev 282377)
@@ -226,7 +226,7 @@
         return completionHandler();
 
     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
-    ScriptExecutionContext::postTaskTo(contextIdentifier, [channelIdentifier, message = WTFMove(message), callbackAggregator = WTFMove(callbackAggregator)](auto&) mutable {
+    ScriptExecutionContext::ensureOnContextThread(contextIdentifier, [channelIdentifier, message = WTFMove(message), callbackAggregator = WTFMove(callbackAggregator)](auto&) mutable {
         RefPtr<BroadcastChannel> channel;
         {
             Locker locker { allBroadcastChannelsLock };

Modified: trunk/Source/WebCore/dom/ScriptExecutionContext.cpp (282376 => 282377)


--- trunk/Source/WebCore/dom/ScriptExecutionContext.cpp	2021-09-14 03:55:56 UTC (rev 282376)
+++ trunk/Source/WebCore/dom/ScriptExecutionContext.cpp	2021-09-14 04:15:43 UTC (rev 282377)
@@ -650,4 +650,24 @@
     return true;
 }
 
+bool ScriptExecutionContext::ensureOnContextThread(ScriptExecutionContextIdentifier identifier, Task&& task)
+{
+    ScriptExecutionContext* context = nullptr;
+    {
+        Locker locker { allScriptExecutionContextsMapLock };
+        context = allScriptExecutionContextsMap().get(identifier);
+
+        if (!context)
+            return false;
+
+        if (!context->isContextThread()) {
+            context->postTask(WTFMove(task));
+            return true;
+        }
+    }
+
+    task.performTask(*context);
+    return true;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/dom/ScriptExecutionContext.h (282376 => 282377)


--- trunk/Source/WebCore/dom/ScriptExecutionContext.h	2021-09-14 03:55:56 UTC (rev 282376)
+++ trunk/Source/WebCore/dom/ScriptExecutionContext.h	2021-09-14 04:15:43 UTC (rev 282377)
@@ -281,6 +281,7 @@
     ServiceWorkerContainer* ensureServiceWorkerContainer();
 #endif
     WEBCORE_EXPORT static bool postTaskTo(ScriptExecutionContextIdentifier, Task&&);
+    WEBCORE_EXPORT static bool ensureOnContextThread(ScriptExecutionContextIdentifier, Task&&);
 
     ScriptExecutionContextIdentifier contextIdentifier() const;
 

Modified: trunk/Source/WebKit/ChangeLog (282376 => 282377)


--- trunk/Source/WebKit/ChangeLog	2021-09-14 03:55:56 UTC (rev 282376)
+++ trunk/Source/WebKit/ChangeLog	2021-09-14 04:15:43 UTC (rev 282377)
@@ -1,3 +1,41 @@
+2021-09-13  Chris Dumez  <[email protected]>
+
+        [WK2] Reduce amount of IPC needed by BroadcastChannel
+        https://bugs.webkit.org/show_bug.cgi?id=230181
+
+        Reviewed by Alex Christensen.
+
+        Reduce amount of IPC needed by BroadcastChannel for both registration / unregistration
+        and communication. Each WebBroadcastChannelRegistry in the WebProcess now maintains
+        a map of BroadcastChannels within the WebProcess. As a result, we are able to dispatch
+        messages to other BroadcastChannels within the same process without going via the
+        NetworkProcess.
+
+        Also, the NetworkBroadcastChannelRegistry on the NetworkProcess side no longer needs
+        to store individual BroadcastChannelIdentifiers. It merely needs to know which
+        WebProcesses have one or more BroadcastChannels for a given ClientOrigin / name.
+        When NetworkBroadcastChannelRegistry::postMessage() is called, we no longer send
+        IPC to the source process in case there are other BroadcastChannels than the source
+        with the given ClientOrigin / name in that process. Also, if there is more than
+        one BroadcastChannel for the given ClientOrigin / name within a given destination
+        WebProcess, we now send a single IPC message instead of sending one per BroadcastChannel.
+
+        * NetworkProcess/NetworkBroadcastChannelRegistry.cpp:
+        (WebKit::NetworkBroadcastChannelRegistry::registerChannel):
+        (WebKit::NetworkBroadcastChannelRegistry::unregisterChannel):
+        (WebKit::NetworkBroadcastChannelRegistry::postMessage):
+        (WebKit::NetworkBroadcastChannelRegistry::removeConnection):
+        * NetworkProcess/NetworkBroadcastChannelRegistry.h:
+        * NetworkProcess/NetworkBroadcastChannelRegistry.messages.in:
+        * WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp:
+        (WebKit::WebBroadcastChannelRegistry::registerChannel):
+        (WebKit::WebBroadcastChannelRegistry::unregisterChannel):
+        (WebKit::WebBroadcastChannelRegistry::postMessage):
+        (WebKit::WebBroadcastChannelRegistry::postMessageLocally):
+        (WebKit::WebBroadcastChannelRegistry::postMessageToRemote):
+        * WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h:
+        * WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.messages.in:
+
 2021-09-13  Wenson Hsieh  <[email protected]>
 
         Refactor -[WKWebViewConfiguration _setRequiresUserActionForEditingControlsManager:] to use API::PageConfiguration

Modified: trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.cpp (282376 => 282377)


--- trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.cpp	2021-09-14 03:55:56 UTC (rev 282376)
+++ trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.cpp	2021-09-14 04:15:43 UTC (rev 282377)
@@ -34,53 +34,51 @@
 
 NetworkBroadcastChannelRegistry::NetworkBroadcastChannelRegistry() = default;
 
-void NetworkBroadcastChannelRegistry::registerChannel(IPC::Connection& connection, const WebCore::ClientOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier channelIdentifier)
+void NetworkBroadcastChannelRegistry::registerChannel(IPC::Connection& connection, const WebCore::ClientOrigin& origin, const String& name)
 {
-    auto& channelsForOrigin = m_broadcastChannels.ensure(origin, [] { return NameToChannelIdentifiersMap { }; }).iterator->value;
-    auto& channelsForName = channelsForOrigin.ensure(name, [] { return Vector<GlobalBroadcastChannelIdentifier> { }; }).iterator->value;
-    GlobalBroadcastChannelIdentifier globalChannelIdentifier { connection.uniqueID(), channelIdentifier };
-    ASSERT(!channelsForName.contains(globalChannelIdentifier));
-    channelsForName.append(WTFMove(globalChannelIdentifier));
+    auto& channelsForOrigin = m_broadcastChannels.ensure(origin, [] { return NameToConnectionIdentifiersMap { }; }).iterator->value;
+    auto& connectionIdentifiersForName = channelsForOrigin.ensure(name, [] { return Vector<IPC::Connection::UniqueID> { }; }).iterator->value;
+    ASSERT(!connectionIdentifiersForName.contains(connection.uniqueID()));
+    connectionIdentifiersForName.append(connection.uniqueID());
 }
 
-void NetworkBroadcastChannelRegistry::unregisterChannel(IPC::Connection& connection, const WebCore::ClientOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier channelIdentifier)
+void NetworkBroadcastChannelRegistry::unregisterChannel(IPC::Connection& connection, const WebCore::ClientOrigin& origin, const String& name)
 {
     auto channelsForOriginIterator = m_broadcastChannels.find(origin);
     ASSERT(channelsForOriginIterator != m_broadcastChannels.end());
     if (channelsForOriginIterator == m_broadcastChannels.end())
         return;
-    auto channelsForNameIterator = channelsForOriginIterator->value.find(name);
-    ASSERT(channelsForNameIterator != channelsForOriginIterator->value.end());
-    if (channelsForNameIterator == channelsForOriginIterator->value.end())
+    auto connectionIdentifiersForNameIterator = channelsForOriginIterator->value.find(name);
+    ASSERT(connectionIdentifiersForNameIterator != channelsForOriginIterator->value.end());
+    if (connectionIdentifiersForNameIterator == channelsForOriginIterator->value.end())
         return;
 
-    GlobalBroadcastChannelIdentifier globalChannelIdentifier { connection.uniqueID(), channelIdentifier };
-    ASSERT(channelsForNameIterator->value.contains(globalChannelIdentifier));
-    channelsForNameIterator->value.removeFirst(globalChannelIdentifier);
+    ASSERT(connectionIdentifiersForNameIterator->value.contains(connection.uniqueID()));
+    connectionIdentifiersForNameIterator->value.removeFirst(connection.uniqueID());
 }
 
-void NetworkBroadcastChannelRegistry::postMessage(IPC::Connection& connection, const WebCore::ClientOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier source, WebCore::MessageWithMessagePorts&& message, CompletionHandler<void()>&& completionHandler)
+void NetworkBroadcastChannelRegistry::postMessage(IPC::Connection& connection, const WebCore::ClientOrigin& origin, const String& name, WebCore::MessageWithMessagePorts&& message, CompletionHandler<void()>&& completionHandler)
 {
     auto channelsForOriginIterator = m_broadcastChannels.find(origin);
     ASSERT(channelsForOriginIterator != m_broadcastChannels.end());
     if (channelsForOriginIterator == m_broadcastChannels.end())
         return completionHandler();
-    auto channelsForNameIterator = channelsForOriginIterator->value.find(name);
-    ASSERT(channelsForNameIterator != channelsForOriginIterator->value.end());
-    if (channelsForNameIterator == channelsForOriginIterator->value.end())
+    auto connectionIdentifiersForNameIterator = channelsForOriginIterator->value.find(name);
+    ASSERT(connectionIdentifiersForNameIterator != channelsForOriginIterator->value.end());
+    if (connectionIdentifiersForNameIterator == channelsForOriginIterator->value.end())
         return completionHandler();
 
     auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
-    GlobalBroadcastChannelIdentifier sourceGlobalChannelIdentifier { connection.uniqueID(), source };
-    for (auto& globalIdentifier : channelsForNameIterator->value) {
-        if (globalIdentifier == sourceGlobalChannelIdentifier)
+    for (auto& connectionID : connectionIdentifiersForNameIterator->value) {
+        // Only dispatch the post the messages to BroadcastChannels outside the source process.
+        if (connectionID == connection.uniqueID())
             continue;
 
-        RefPtr connection = IPC::Connection::connection(globalIdentifier.connectionIdentifier);
+        RefPtr connection = IPC::Connection::connection(connectionID);
         if (!connection)
             continue;
 
-        connection->sendWithAsyncReply(Messages::WebBroadcastChannelRegistry::PostMessageToRemote(globalIdentifier.channelIndentifierInProcess, message), [callbackAggregator] { }, 0);
+        connection->sendWithAsyncReply(Messages::WebBroadcastChannelRegistry::PostMessageToRemote(origin, name, message), [callbackAggregator] { }, 0);
     }
 }
 
@@ -90,9 +88,7 @@
     for (auto& entry : m_broadcastChannels) {
         Vector<String> namesToRemove;
         for (auto& innerEntry : entry.value) {
-            innerEntry.value.removeAllMatching([connectionIdentifier = connection.uniqueID()](auto& globalIdentifier) {
-                return globalIdentifier.connectionIdentifier == connectionIdentifier;
-            });
+            innerEntry.value.removeFirst(connection.uniqueID());
             if (innerEntry.value.isEmpty())
                 namesToRemove.append(innerEntry.key);
         }

Modified: trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.h (282376 => 282377)


--- trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.h	2021-09-14 03:55:56 UTC (rev 282376)
+++ trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.h	2021-09-14 04:15:43 UTC (rev 282377)
@@ -45,23 +45,13 @@
 
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
 
-    void registerChannel(IPC::Connection&, const WebCore::ClientOrigin&, const String& name, WebCore::BroadcastChannelIdentifier);
-    void unregisterChannel(IPC::Connection&, const WebCore::ClientOrigin&, const String& name, WebCore::BroadcastChannelIdentifier);
-    void postMessage(IPC::Connection&, const WebCore::ClientOrigin&, const String& name, WebCore::BroadcastChannelIdentifier source, WebCore::MessageWithMessagePorts&&, CompletionHandler<void()>&&);
+    void registerChannel(IPC::Connection&, const WebCore::ClientOrigin&, const String& name);
+    void unregisterChannel(IPC::Connection&, const WebCore::ClientOrigin&, const String& name);
+    void postMessage(IPC::Connection&, const WebCore::ClientOrigin&, const String& name, WebCore::MessageWithMessagePorts&&, CompletionHandler<void()>&&);
 
 private:
-    struct GlobalBroadcastChannelIdentifier {
-        IPC::Connection::UniqueID connectionIdentifier;
-        WebCore::BroadcastChannelIdentifier channelIndentifierInProcess;
-
-        bool operator==(const GlobalBroadcastChannelIdentifier& other) const
-        {
-            return connectionIdentifier == other.connectionIdentifier && channelIndentifierInProcess == other.channelIndentifierInProcess;
-        }
-    };
-
-    using NameToChannelIdentifiersMap = HashMap<String, Vector<GlobalBroadcastChannelIdentifier>>;
-    HashMap<WebCore::ClientOrigin, NameToChannelIdentifiersMap> m_broadcastChannels;
+    using NameToConnectionIdentifiersMap = HashMap<String, Vector<IPC::Connection::UniqueID>>;
+    HashMap<WebCore::ClientOrigin, NameToConnectionIdentifiersMap> m_broadcastChannels;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.messages.in (282376 => 282377)


--- trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.messages.in	2021-09-14 03:55:56 UTC (rev 282376)
+++ trunk/Source/WebKit/NetworkProcess/NetworkBroadcastChannelRegistry.messages.in	2021-09-14 04:15:43 UTC (rev 282377)
@@ -21,7 +21,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 messages -> NetworkBroadcastChannelRegistry NotRefCounted {
-    RegisterChannel(struct WebCore::ClientOrigin origin, String name, WebCore::BroadcastChannelIdentifier channelIdentifier) WantsConnection
-    UnregisterChannel(struct WebCore::ClientOrigin origin, String name, WebCore::BroadcastChannelIdentifier channelIdentifier) WantsConnection
-    PostMessage(struct WebCore::ClientOrigin origin, String name, WebCore::BroadcastChannelIdentifier source, struct WebCore::MessageWithMessagePorts message) -> () Async WantsConnection
+    RegisterChannel(struct WebCore::ClientOrigin origin, String name) WantsConnection
+    UnregisterChannel(struct WebCore::ClientOrigin origin, String name) WantsConnection
+    PostMessage(struct WebCore::ClientOrigin origin, String name, struct WebCore::MessageWithMessagePorts message) -> () Async WantsConnection
 }

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp (282376 => 282377)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp	2021-09-14 03:55:56 UTC (rev 282376)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.cpp	2021-09-14 04:15:43 UTC (rev 282377)
@@ -31,6 +31,7 @@
 #include "WebProcess.h"
 #include <WebCore/BroadcastChannel.h>
 #include <WebCore/MessageWithMessagePorts.h>
+#include <wtf/CallbackAggregator.h>
 
 namespace WebKit {
 
@@ -41,22 +42,68 @@
 
 void WebBroadcastChannelRegistry::registerChannel(const WebCore::ClientOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier identifier)
 {
-    networkProcessConnection().send(Messages::NetworkBroadcastChannelRegistry::RegisterChannel { origin, name, identifier }, 0);
+    auto& channelsForOrigin = m_channelsPerOrigin.ensure(origin, [] { return HashMap<String, Vector<WebCore::BroadcastChannelIdentifier>> { }; }).iterator->value;
+    auto& channelsForName = channelsForOrigin.ensure(name, [] { return Vector<WebCore::BroadcastChannelIdentifier> { }; }).iterator->value;
+    channelsForName.append(identifier);
+
+    if (channelsForName.size() == 1)
+        networkProcessConnection().send(Messages::NetworkBroadcastChannelRegistry::RegisterChannel { origin, name }, 0);
 }
 
 void WebBroadcastChannelRegistry::unregisterChannel(const WebCore::ClientOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier identifier)
 {
-    networkProcessConnection().send(Messages::NetworkBroadcastChannelRegistry::UnregisterChannel { origin, name, identifier }, 0);
+    auto channelsPerOriginIterator = m_channelsPerOrigin.find(origin);
+    if (channelsPerOriginIterator == m_channelsPerOrigin.end())
+        return;
+
+    auto& channelsForOrigin = channelsPerOriginIterator->value;
+    auto channelsForOriginIterator = channelsForOrigin.find(name);
+    if (channelsForOriginIterator == channelsForOrigin.end())
+        return;
+
+    auto& channelIdentifiersForName = channelsForOriginIterator->value;
+    if (!channelIdentifiersForName.removeFirst(identifier))
+        return;
+    if (!channelIdentifiersForName.isEmpty())
+        return;
+
+    channelsForOrigin.remove(channelsForOriginIterator);
+    networkProcessConnection().send(Messages::NetworkBroadcastChannelRegistry::UnregisterChannel { origin, name }, 0);
+
+    if (channelsForOrigin.isEmpty())
+        m_channelsPerOrigin.remove(channelsPerOriginIterator);
 }
 
 void WebBroadcastChannelRegistry::postMessage(const WebCore::ClientOrigin& origin, const String& name, WebCore::BroadcastChannelIdentifier source, Ref<WebCore::SerializedScriptValue>&& message, CompletionHandler<void()>&& completionHandler)
 {
-    networkProcessConnection().sendWithAsyncReply(Messages::NetworkBroadcastChannelRegistry::PostMessage { origin, name, source, WebCore::MessageWithMessagePorts { WTFMove(message), { } } }, WTFMove(completionHandler), 0);
+    auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
+    postMessageLocally(origin, name, source, message.copyRef(), callbackAggregator.copyRef());
+    networkProcessConnection().sendWithAsyncReply(Messages::NetworkBroadcastChannelRegistry::PostMessage { origin, name, WebCore::MessageWithMessagePorts { WTFMove(message), { } } }, [callbackAggregator] { }, 0);
 }
 
-void WebBroadcastChannelRegistry::postMessageToRemote(WebCore::BroadcastChannelIdentifier identifier, WebCore::MessageWithMessagePorts&& message, CompletionHandler<void()>&& completionHandler)
+void WebBroadcastChannelRegistry::postMessageLocally(const WebCore::ClientOrigin& origin, const String& name, std::optional<WebCore::BroadcastChannelIdentifier> sourceInProcess, Ref<WebCore::SerializedScriptValue>&& message, Ref<WTF::CallbackAggregator>&& callbackAggregator)
 {
-    WebCore::BroadcastChannel::dispatchMessageTo(identifier, message.message.releaseNonNull(), WTFMove(completionHandler));
+    auto channelsPerOriginIterator = m_channelsPerOrigin.find(origin);
+    if (channelsPerOriginIterator == m_channelsPerOrigin.end())
+        return;
+
+    auto& channelsForOrigin = channelsPerOriginIterator->value;
+    auto channelsForOriginIterator = channelsForOrigin.find(name);
+    if (channelsForOriginIterator == channelsForOrigin.end())
+        return;
+
+    auto channelIdentifiersForName = channelsForOriginIterator->value;
+    for (auto& channelIdentier : channelIdentifiersForName) {
+        if (channelIdentier == sourceInProcess)
+            continue;
+        WebCore::BroadcastChannel::dispatchMessageTo(channelIdentier, message.copyRef(), [callbackAggregator] { });
+    }
 }
 
+void WebBroadcastChannelRegistry::postMessageToRemote(const WebCore::ClientOrigin& origin, const String& name, WebCore::MessageWithMessagePorts&& message, CompletionHandler<void()>&& completionHandler)
+{
+    auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));
+    postMessageLocally(origin, name, std::nullopt, *message.message, callbackAggregator.copyRef());
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h (282376 => 282377)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h	2021-09-14 03:55:56 UTC (rev 282376)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.h	2021-09-14 04:15:43 UTC (rev 282377)
@@ -27,7 +27,14 @@
 
 #include "Connection.h"
 #include <WebCore/BroadcastChannelRegistry.h>
+#include <WebCore/ClientOrigin.h>
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
 
+namespace WTF {
+class CallbackAggregator;
+}
+
 namespace WebCore {
 struct MessageWithMessagePorts;
 }
@@ -50,7 +57,10 @@
 private:
     WebBroadcastChannelRegistry() = default;
 
-    void postMessageToRemote(WebCore::BroadcastChannelIdentifier, WebCore::MessageWithMessagePorts&&, CompletionHandler<void()>&&);
+    void postMessageToRemote(const WebCore::ClientOrigin&, const String& name, WebCore::MessageWithMessagePorts&&, CompletionHandler<void()>&&);
+    void postMessageLocally(const WebCore::ClientOrigin&, const String& name, std::optional<WebCore::BroadcastChannelIdentifier> sourceInProcess, Ref<WebCore::SerializedScriptValue>&&, Ref<WTF::CallbackAggregator>&&);
+
+    HashMap<WebCore::ClientOrigin, HashMap<String, Vector<WebCore::BroadcastChannelIdentifier>>> m_channelsPerOrigin;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.messages.in (282376 => 282377)


--- trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.messages.in	2021-09-14 03:55:56 UTC (rev 282376)
+++ trunk/Source/WebKit/WebProcess/WebCoreSupport/WebBroadcastChannelRegistry.messages.in	2021-09-14 04:15:43 UTC (rev 282377)
@@ -21,5 +21,5 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 messages -> WebBroadcastChannelRegistry {
-    PostMessageToRemote(WebCore::BroadcastChannelIdentifier destination, struct WebCore::MessageWithMessagePorts message) -> () Async
+    PostMessageToRemote(struct WebCore::ClientOrigin origin, String name, struct WebCore::MessageWithMessagePorts message) -> () Async
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to