<!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>[283713] trunk/Source/WebKit</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/283713">283713</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2021-10-07 08:16:51 -0700 (Thu, 07 Oct 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add the ability to dispatch messages to multiple receiver types in IPC::StreamServerConnection
https://bugs.webkit.org/show_bug.cgi?id=231305

Reviewed by Kimmo Kinnunen.

In preparation for using streamable IPC for display list rendering in the GPU process (i.e. 2D canvas and DOM
rendering), refactor StreamServerConnection such that it is capable of dispatching stream messages to generic
StreamMessageReceivers. This has the disadvantage of performing a vtable lookup with each message dispatch, but
I did not measure this to be a significant performance regression on any of the canvas subtests in MotionMark.

* GPUProcess/graphics/RemoteGraphicsContextGL.cpp:
(WebKit::RemoteGraphicsContextGL::RemoteGraphicsContextGL):
* GPUProcess/graphics/RemoteGraphicsContextGL.h:

Make RemoteGraphicsContextGL subclass StreamMessageReceiver.

* Platform/IPC/StreamMessageReceiver.h: Added.
(IPC::StreamMessageReceiver::~StreamMessageReceiver):
* Platform/IPC/StreamServerConnection.cpp:
(IPC::StreamServerConnection::startReceivingMessages):
(IPC::StreamServerConnection::stopReceivingMessages):
(IPC::StreamServerConnection::dispatchStreamMessages):
(IPC::StreamServerConnection::processSetStreamDestinationID):
(IPC::StreamServerConnection::dispatchStreamMessage):
(IPC::StreamServerConnection::dispatchOutOfStreamMessage):

Now that these methods are no longer templated, we can move their implementations from the header to the
implementation file.

* Platform/IPC/StreamServerConnection.h:

Remove the template argument from StreamServerConnection, and instead make this start and stop receiving
messages for generic StreamMessageReceiver objects.

(IPC::StreamServerConnection<Receiver>::startReceivingMessages): Deleted.
(IPC::StreamServerConnection<Receiver>::stopReceivingMessages): Deleted.
(IPC::StreamServerConnection<Receiver>::dispatchStreamMessages): Deleted.
(IPC::StreamServerConnection<Receiver>::processSetStreamDestinationID): Deleted.
(IPC::StreamServerConnection<Receiver>::dispatchStreamMessage): Deleted.
(IPC::StreamServerConnection<Receiver>::dispatchOutOfStreamMessage): Deleted.
* WebKit.xcodeproj/project.pbxproj:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitGPUProcessgraphicsRemoteGraphicsContextGLcpp">trunk/Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.cpp</a></li>
<li><a href="#trunkSourceWebKitGPUProcessgraphicsRemoteGraphicsContextGLh">trunk/Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.h</a></li>
<li><a href="#trunkSourceWebKitPlatformIPCStreamServerConnectioncpp">trunk/Source/WebKit/Platform/IPC/StreamServerConnection.cpp</a></li>
<li><a href="#trunkSourceWebKitPlatformIPCStreamServerConnectionh">trunk/Source/WebKit/Platform/IPC/StreamServerConnection.h</a></li>
<li><a href="#trunkSourceWebKitWebKitxcodeprojprojectpbxproj">trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebKitPlatformIPCStreamMessageReceiverh">trunk/Source/WebKit/Platform/IPC/StreamMessageReceiver.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (283712 => 283713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog    2021-10-07 15:02:25 UTC (rev 283712)
+++ trunk/Source/WebKit/ChangeLog       2021-10-07 15:16:51 UTC (rev 283713)
</span><span class="lines">@@ -1,3 +1,47 @@
</span><ins>+2021-10-07  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        Add the ability to dispatch messages to multiple receiver types in IPC::StreamServerConnection
+        https://bugs.webkit.org/show_bug.cgi?id=231305
+
+        Reviewed by Kimmo Kinnunen.
+
+        In preparation for using streamable IPC for display list rendering in the GPU process (i.e. 2D canvas and DOM
+        rendering), refactor StreamServerConnection such that it is capable of dispatching stream messages to generic
+        StreamMessageReceivers. This has the disadvantage of performing a vtable lookup with each message dispatch, but
+        I did not measure this to be a significant performance regression on any of the canvas subtests in MotionMark.
+
+        * GPUProcess/graphics/RemoteGraphicsContextGL.cpp:
+        (WebKit::RemoteGraphicsContextGL::RemoteGraphicsContextGL):
+        * GPUProcess/graphics/RemoteGraphicsContextGL.h:
+
+        Make RemoteGraphicsContextGL subclass StreamMessageReceiver.
+
+        * Platform/IPC/StreamMessageReceiver.h: Added.
+        (IPC::StreamMessageReceiver::~StreamMessageReceiver):
+        * Platform/IPC/StreamServerConnection.cpp:
+        (IPC::StreamServerConnection::startReceivingMessages):
+        (IPC::StreamServerConnection::stopReceivingMessages):
+        (IPC::StreamServerConnection::dispatchStreamMessages):
+        (IPC::StreamServerConnection::processSetStreamDestinationID):
+        (IPC::StreamServerConnection::dispatchStreamMessage):
+        (IPC::StreamServerConnection::dispatchOutOfStreamMessage):
+
+        Now that these methods are no longer templated, we can move their implementations from the header to the
+        implementation file.
+
+        * Platform/IPC/StreamServerConnection.h:
+
+        Remove the template argument from StreamServerConnection, and instead make this start and stop receiving
+        messages for generic StreamMessageReceiver objects.
+
+        (IPC::StreamServerConnection<Receiver>::startReceivingMessages): Deleted.
+        (IPC::StreamServerConnection<Receiver>::stopReceivingMessages): Deleted.
+        (IPC::StreamServerConnection<Receiver>::dispatchStreamMessages): Deleted.
+        (IPC::StreamServerConnection<Receiver>::processSetStreamDestinationID): Deleted.
+        (IPC::StreamServerConnection<Receiver>::dispatchStreamMessage): Deleted.
+        (IPC::StreamServerConnection<Receiver>::dispatchOutOfStreamMessage): Deleted.
+        * WebKit.xcodeproj/project.pbxproj:
+
</ins><span class="cx"> 2021-10-07  Kimmo Kinnunen  <kkinnunen@apple.com>
</span><span class="cx"> 
</span><span class="cx">         ScopedEGLDefaultDisplay should be removed
</span></span></pre></div>
<a id="trunkSourceWebKitGPUProcessgraphicsRemoteGraphicsContextGLcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.cpp (283712 => 283713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.cpp      2021-10-07 15:02:25 UTC (rev 283712)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.cpp 2021-10-07 15:16:51 UTC (rev 283713)
</span><span class="lines">@@ -64,7 +64,7 @@
</span><span class="cx"> 
</span><span class="cx"> RemoteGraphicsContextGL::RemoteGraphicsContextGL(GPUConnectionToWebProcess& gpuConnectionToWebProcess, GraphicsContextGLIdentifier graphicsContextGLIdentifier, RemoteRenderingBackend& renderingBackend, IPC::StreamConnectionBuffer&& stream)
</span><span class="cx">     : m_gpuConnectionToWebProcess(makeWeakPtr(gpuConnectionToWebProcess))
</span><del>-    , m_streamConnection(IPC::StreamServerConnection<RemoteGraphicsContextGL>::create(gpuConnectionToWebProcess.connection(), WTFMove(stream), remoteGraphicsContextGLStreamWorkQueue()))
</del><ins>+    , m_streamConnection(IPC::StreamServerConnection::create(gpuConnectionToWebProcess.connection(), WTFMove(stream), remoteGraphicsContextGLStreamWorkQueue()))
</ins><span class="cx">     , m_graphicsContextGLIdentifier(graphicsContextGLIdentifier)
</span><span class="cx">     , m_renderingBackend(renderingBackend)
</span><span class="cx">     , m_renderingResourcesRequest(ScopedWebGLRenderingResourcesRequest::acquire())
</span></span></pre></div>
<a id="trunkSourceWebKitGPUProcessgraphicsRemoteGraphicsContextGLh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.h (283712 => 283713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.h        2021-10-07 15:02:25 UTC (rev 283712)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.h   2021-10-07 15:16:51 UTC (rev 283713)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include "GraphicsContextGLIdentifier.h"
</span><span class="cx"> #include "RemoteRenderingBackend.h"
</span><span class="cx"> #include "ScopedWebGLRenderingResourcesRequest.h"
</span><ins>+#include "StreamMessageReceiver.h"
</ins><span class="cx"> #include "StreamServerConnection.h"
</span><span class="cx"> #include <WebCore/ExtensionsGL.h>
</span><span class="cx"> #include <WebCore/GraphicsContextGLOpenGL.h>
</span><span class="lines">@@ -58,7 +59,7 @@
</span><span class="cx"> // GPU process side implementation of that receives messages about GraphicsContextGL calls
</span><span class="cx"> // and issues real GraphicsContextGL calls based on the received messages.
</span><span class="cx"> // The implementation is largely generated by running Tools/Scripts/generate-gpup-webgl.
</span><del>-class RemoteGraphicsContextGL : public ThreadSafeRefCounted<RemoteGraphicsContextGL>, private WebCore::GraphicsContextGL::Client {
</del><ins>+class RemoteGraphicsContextGL : private WebCore::GraphicsContextGL::Client, public IPC::StreamMessageReceiver {
</ins><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="cx">     static Ref<RemoteGraphicsContextGL> create(GPUConnectionToWebProcess&, WebCore::GraphicsContextGLAttributes&&, GraphicsContextGLIdentifier, RemoteRenderingBackend&, IPC::StreamConnectionBuffer&&);
</span><span class="lines">@@ -65,8 +66,7 @@
</span><span class="cx">     ~RemoteGraphicsContextGL() override;
</span><span class="cx">     void stopListeningForIPC(Ref<RemoteGraphicsContextGL>&& refFromConnection);
</span><span class="cx"> 
</span><del>-    // IPC::StreamServerConnection<RemoteGraphicsContextGL> template contract implementation.
-    void didReceiveStreamMessage(IPC::StreamServerConnectionBase&, IPC::Decoder&);
</del><ins>+    void didReceiveStreamMessage(IPC::StreamServerConnectionBase&, IPC::Decoder&) final;
</ins><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     void displayWasReconfigured();
</span><span class="cx"> #endif
</span><span class="lines">@@ -108,7 +108,7 @@
</span><span class="cx">     void paintPixelBufferToImageBuffer(std::optional<WebCore::PixelBuffer>&&, WebCore::RenderingResourceIdentifier, CompletionHandler<void()>&&);
</span><span class="cx"> 
</span><span class="cx">     WeakPtr<GPUConnectionToWebProcess> m_gpuConnectionToWebProcess;
</span><del>-    RefPtr<IPC::StreamServerConnection<RemoteGraphicsContextGL>> m_streamConnection;
</del><ins>+    RefPtr<IPC::StreamServerConnection> m_streamConnection;
</ins><span class="cx">     RefPtr<WebCore::GraphicsContextGLOpenGL> m_context WTF_GUARDED_BY_LOCK(m_streamThread);
</span><span class="cx">     GraphicsContextGLIdentifier m_graphicsContextGLIdentifier;
</span><span class="cx">     Ref<RemoteRenderingBackend> m_renderingBackend;
</span></span></pre></div>
<a id="trunkSourceWebKitPlatformIPCStreamMessageReceiverh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit/Platform/IPC/StreamMessageReceiver.h (0 => 283713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Platform/IPC/StreamMessageReceiver.h                         (rev 0)
+++ trunk/Source/WebKit/Platform/IPC/StreamMessageReceiver.h    2021-10-07 15:16:51 UTC (rev 283713)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/ThreadSafeRefCounted.h>
+
+namespace IPC {
+
+class StreamServerConnectionBase;
+class Decoder;
+
+class StreamMessageReceiver : public ThreadSafeRefCounted<StreamMessageReceiver> {
+public:
+    virtual ~StreamMessageReceiver() { }
+
+    virtual void didReceiveStreamMessage(StreamServerConnectionBase&, Decoder&) = 0;
+};
+
+} // namespace IPC
</ins></span></pre></div>
<a id="trunkSourceWebKitPlatformIPCStreamServerConnectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Platform/IPC/StreamServerConnection.cpp (283712 => 283713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Platform/IPC/StreamServerConnection.cpp      2021-10-07 15:02:25 UTC (rev 283712)
+++ trunk/Source/WebKit/Platform/IPC/StreamServerConnection.cpp 2021-10-07 15:16:51 UTC (rev 283713)
</span><span class="lines">@@ -141,4 +141,142 @@
</span><span class="cx">     return std::min(limit, dataSize() - 1);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void StreamServerConnection::startReceivingMessages(StreamMessageReceiver& receiver, ReceiverName receiverName, uint64_t destinationID)
+{
+    {
+        auto key = std::make_pair(static_cast<uint8_t>(receiverName), destinationID);
+        Locker locker { m_receiversLock };
+        ASSERT(!m_receivers.contains(key));
+        m_receivers.add(key, receiver);
+    }
+    StreamServerConnectionBase::startReceivingMessagesImpl(receiverName, destinationID);
</ins><span class="cx"> }
</span><ins>+
+void StreamServerConnection::stopReceivingMessages(ReceiverName receiverName, uint64_t destinationID)
+{
+    StreamServerConnectionBase::stopReceivingMessagesImpl(receiverName, destinationID);
+    auto key = std::make_pair(static_cast<uint8_t>(receiverName), destinationID);
+    Locker locker { m_receiversLock };
+    ASSERT(m_receivers.contains(key));
+    m_receivers.remove(key);
+}
+
+StreamServerConnectionBase::DispatchResult StreamServerConnection::dispatchStreamMessages(size_t messageLimit)
+{
+    RefPtr<StreamMessageReceiver> currentReceiver;
+    // FIXME: Implement WTF::isValid(ReceiverName).
+    uint8_t currentReceiverName = static_cast<uint8_t>(ReceiverName::Invalid);
+
+    for (size_t i = 0; i < messageLimit; ++i) {
+        auto span = tryAcquire();
+        if (!span)
+            return DispatchResult::HasNoMessages;
+        IPC::Decoder decoder { span->data, span->size, m_currentDestinationID };
+        if (!decoder.isValid()) {
+            m_connection->dispatchDidReceiveInvalidMessage(decoder.messageName());
+            return DispatchResult::HasNoMessages;
+        }
+        if (decoder.messageName() == MessageName::SetStreamDestinationID) {
+            if (!processSetStreamDestinationID(WTFMove(decoder), currentReceiver))
+                return DispatchResult::HasNoMessages;
+            continue;
+        }
+        if (decoder.messageName() == MessageName::ProcessOutOfStreamMessage) {
+            if (!dispatchOutOfStreamMessage(WTFMove(decoder)))
+                return DispatchResult::HasNoMessages;
+            continue;
+        }
+        if (currentReceiverName != static_cast<uint8_t>(decoder.messageReceiverName())) {
+            currentReceiverName = static_cast<uint8_t>(decoder.messageReceiverName());
+            currentReceiver = nullptr;
+        }
+        if (!currentReceiver) {
+            auto key = std::make_pair(static_cast<uint8_t>(currentReceiverName), m_currentDestinationID);
+            if (!ReceiversMap::isValidKey(key)) {
+                m_connection->dispatchDidReceiveInvalidMessage(decoder.messageName());
+                return DispatchResult::HasNoMessages;
+            }
+            Locker locker { m_receiversLock };
+            currentReceiver = m_receivers.get(key);
+        }
+        if (!currentReceiver) {
+            // Valid scenario is when receiver has been removed, but there are messages for it in the buffer.
+            // FIXME: Since we do not have a receiver, we don't know how to decode the message.
+            // This means we must timeout every receiver in the stream connection.
+            // Currently we assert that the receivers are empty, as we only have up to one receiver in
+            // a stream connection until possibility of skipping is implemented properly.
+            Locker locker { m_receiversLock };
+            ASSERT(m_receivers.isEmpty());
+            return DispatchResult::HasNoMessages;
+        }
+        if (!dispatchStreamMessage(WTFMove(decoder), *currentReceiver))
+            return DispatchResult::HasNoMessages;
+    }
+    return DispatchResult::HasMoreMessages;
+}
+
+bool StreamServerConnection::processSetStreamDestinationID(Decoder&& decoder, RefPtr<StreamMessageReceiver>& currentReceiver)
+{
+    uint64_t destinationID = 0;
+    if (!decoder.decode(destinationID)) {
+        m_connection->dispatchDidReceiveInvalidMessage(decoder.messageName());
+        return false;
+    }
+    if (m_currentDestinationID != destinationID) {
+        m_currentDestinationID = destinationID;
+        currentReceiver = nullptr;
+    }
+    release(decoder.currentBufferPosition());
+    return true;
+}
+
+bool StreamServerConnection::dispatchStreamMessage(Decoder&& decoder, StreamMessageReceiver& receiver)
+{
+    ASSERT(!m_isDispatchingStreamMessage);
+    m_isDispatchingStreamMessage = true;
+    receiver.didReceiveStreamMessage(*this, decoder);
+    m_isDispatchingStreamMessage = false;
+    if (!decoder.isValid()) {
+        m_connection->dispatchDidReceiveInvalidMessage(decoder.messageName());
+        return false;
+    }
+    if (decoder.isSyncMessage())
+        releaseAll();
+    else
+        release(decoder.currentBufferPosition());
+    return true;
+}
+
+bool StreamServerConnection::dispatchOutOfStreamMessage(Decoder&& decoder)
+{
+    std::unique_ptr<Decoder> message;
+    {
+        Locker locker { m_outOfStreamMessagesLock };
+        if (m_outOfStreamMessages.isEmpty())
+            return false;
+        message = m_outOfStreamMessages.takeFirst();
+    }
+    if (!message)
+        return false;
+
+    RefPtr<StreamMessageReceiver> receiver;
+    {
+        auto key = std::make_pair(static_cast<uint8_t>(message->messageReceiverName()), message->destinationID());
+        Locker locker { m_receiversLock };
+        receiver = m_receivers.get(key);
+    }
+    if (receiver) {
+        receiver->didReceiveStreamMessage(*this, *message);
+        if (!message->isValid()) {
+            m_connection->dispatchDidReceiveInvalidMessage(message->messageName());
+            return false;
+        }
+    }
+    // If receiver does not exist if it has been removed but messages are still pending to be
+    // processed. It's ok to skip such messages.
+    // FIXME: Note, corresponding skip is not possible at the moment for stream messages.
+    release(decoder.currentBufferPosition());
+    return true;
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebKitPlatformIPCStreamServerConnectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Platform/IPC/StreamServerConnection.h (283712 => 283713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Platform/IPC/StreamServerConnection.h        2021-10-07 15:02:25 UTC (rev 283712)
+++ trunk/Source/WebKit/Platform/IPC/StreamServerConnection.h   2021-10-07 15:16:51 UTC (rev 283713)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include "MessageNames.h"
</span><span class="cx"> #include "StreamConnectionBuffer.h"
</span><span class="cx"> #include "StreamConnectionEncoder.h"
</span><ins>+#include "StreamMessageReceiver.h"
</ins><span class="cx"> #include <wtf/Deque.h>
</span><span class="cx"> #include <wtf/Lock.h>
</span><span class="cx"> #include <wtf/Threading.h>
</span><span class="lines">@@ -131,7 +132,6 @@
</span><span class="cx"> //   void didReceiveStreamMessage(StreamServerConnectionBase&, Decoder&);
</span><span class="cx"> //
</span><span class="cx"> // The StreamServerConnection does not trust the StreamClientConnection.
</span><del>-template<typename Receiver>
</del><span class="cx"> class StreamServerConnection final : public StreamServerConnectionBase {
</span><span class="cx"> public:
</span><span class="cx">     static Ref<StreamServerConnection> create(Connection& connection, StreamConnectionBuffer&& streamBuffer, StreamConnectionWorkQueue& workQueue)
</span><span class="lines">@@ -140,7 +140,7 @@
</span><span class="cx">     }
</span><span class="cx">     ~StreamServerConnection() final = default;
</span><span class="cx"> 
</span><del>-    void startReceivingMessages(Receiver&, ReceiverName, uint64_t destinationID);
</del><ins>+    void startReceivingMessages(StreamMessageReceiver&, ReceiverName, uint64_t destinationID);
</ins><span class="cx">     // Stops the message receipt. Note: already received messages might still be delivered.
</span><span class="cx">     void stopReceivingMessages(ReceiverName, uint64_t destinationID);
</span><span class="cx"> 
</span><span class="lines">@@ -152,157 +152,13 @@
</span><span class="cx">         : StreamServerConnectionBase(connection, WTFMove(streamBuffer), workQueue)
</span><span class="cx">     {
</span><span class="cx">     }
</span><del>-    bool processSetStreamDestinationID(Decoder&&, RefPtr<Receiver>& currentReceiver);
-    bool dispatchStreamMessage(Decoder&&, Receiver&);
</del><ins>+    bool processSetStreamDestinationID(Decoder&&, RefPtr<StreamMessageReceiver>& currentReceiver);
+    bool dispatchStreamMessage(Decoder&&, StreamMessageReceiver&);
</ins><span class="cx">     bool dispatchOutOfStreamMessage(Decoder&&);
</span><span class="cx">     Lock m_receiversLock;
</span><del>-    using ReceiversMap = HashMap<std::pair<uint8_t, uint64_t>, Ref<Receiver>>;
</del><ins>+    using ReceiversMap = HashMap<std::pair<uint8_t, uint64_t>, Ref<StreamMessageReceiver>>;
</ins><span class="cx">     ReceiversMap m_receivers WTF_GUARDED_BY_LOCK(m_receiversLock);
</span><span class="cx">     uint64_t m_currentDestinationID { 0 };
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-template<typename Receiver>
-void StreamServerConnection<Receiver>::startReceivingMessages(Receiver& receiver, ReceiverName receiverName, uint64_t destinationID)
-{
-    {
-        auto key = std::make_pair(static_cast<uint8_t>(receiverName), destinationID);
-        Locker locker { m_receiversLock };
-        ASSERT(!m_receivers.contains(key));
-        m_receivers.add(key, receiver);
-    }
-    StreamServerConnectionBase::startReceivingMessagesImpl(receiverName, destinationID);
</del><span class="cx"> }
</span><del>-
-template<typename Receiver>
-void StreamServerConnection<Receiver>::stopReceivingMessages(ReceiverName receiverName, uint64_t destinationID)
-{
-    StreamServerConnectionBase::stopReceivingMessagesImpl(receiverName, destinationID);
-    auto key = std::make_pair(static_cast<uint8_t>(receiverName), destinationID);
-    Locker locker { m_receiversLock };
-    ASSERT(m_receivers.contains(key));
-    m_receivers.remove(key);
-}
-
-template<typename Receiver>
-StreamServerConnectionBase::DispatchResult StreamServerConnection<Receiver>::dispatchStreamMessages(size_t messageLimit)
-{
-    RefPtr<Receiver> currentReceiver;
-    // FIXME: Implement WTF::isValid(ReceiverName).
-    uint8_t currentReceiverName = static_cast<uint8_t>(ReceiverName::Invalid);
-
-    for (size_t i = 0; i < messageLimit; ++i) {
-        auto span = tryAcquire();
-        if (!span)
-            return DispatchResult::HasNoMessages;
-        IPC::Decoder decoder { span->data, span->size, m_currentDestinationID };
-        if (!decoder.isValid()) {
-            m_connection->dispatchDidReceiveInvalidMessage(decoder.messageName());
-            return DispatchResult::HasNoMessages;
-        }
-        if (decoder.messageName() == MessageName::SetStreamDestinationID) {
-            if (!processSetStreamDestinationID(WTFMove(decoder), currentReceiver))
-                return DispatchResult::HasNoMessages;
-            continue;
-        }
-        if (decoder.messageName() == MessageName::ProcessOutOfStreamMessage) {
-            if (!dispatchOutOfStreamMessage(WTFMove(decoder)))
-                return DispatchResult::HasNoMessages;
-            continue;
-        }
-        if (currentReceiverName != static_cast<uint8_t>(decoder.messageReceiverName())) {
-            currentReceiverName = static_cast<uint8_t>(decoder.messageReceiverName());
-            currentReceiver = nullptr;
-        }
-        if (!currentReceiver) {
-            auto key = std::make_pair(static_cast<uint8_t>(currentReceiverName), m_currentDestinationID);
-            if (!ReceiversMap::isValidKey(key)) {
-                m_connection->dispatchDidReceiveInvalidMessage(decoder.messageName());
-                return DispatchResult::HasNoMessages;
-            }
-            Locker locker { m_receiversLock };
-            currentReceiver = m_receivers.get(key);
-        }
-        if (!currentReceiver) {
-            // Valid scenario is when receiver has been removed, but there are messages for it in the buffer.
-            // FIXME: Since we do not have a receiver, we don't know how to decode the message.
-            // This means we must timeout every receiver in the stream connection.
-            // Currently we assert that the receivers are empty, as we only have up to one receiver in
-            // a stream connection until possibility of skipping is implemented properly.
-            Locker locker { m_receiversLock };
-            ASSERT(m_receivers.isEmpty());
-            return DispatchResult::HasNoMessages;
-        }
-        if (!dispatchStreamMessage(WTFMove(decoder), *currentReceiver))
-            return DispatchResult::HasNoMessages;
-    }
-    return DispatchResult::HasMoreMessages;
-}
-
-template<typename Receiver>
-bool StreamServerConnection<Receiver>::processSetStreamDestinationID(Decoder&& decoder, RefPtr<Receiver>& currentReceiver)
-{
-    uint64_t destinationID = 0;
-    if (!decoder.decode(destinationID)) {
-        m_connection->dispatchDidReceiveInvalidMessage(decoder.messageName());
-        return false;
-    }
-    if (m_currentDestinationID != destinationID) {
-        m_currentDestinationID = destinationID;
-        currentReceiver = nullptr;
-    }
-    release(decoder.currentBufferPosition());
-    return true;
-}
-
-template<typename Receiver>
-bool StreamServerConnection<Receiver>::dispatchStreamMessage(Decoder&& decoder, Receiver& receiver)
-{
-    ASSERT(!m_isDispatchingStreamMessage);
-    m_isDispatchingStreamMessage = true;
-    receiver.didReceiveStreamMessage(*this, decoder);
-    m_isDispatchingStreamMessage = false;
-    if (!decoder.isValid()) {
-        m_connection->dispatchDidReceiveInvalidMessage(decoder.messageName());
-        return false;
-    }
-    if (decoder.isSyncMessage())
-        releaseAll();
-    else
-        release(decoder.currentBufferPosition());
-    return true;
-}
-
-template<typename Receiver>
-bool StreamServerConnection<Receiver>::dispatchOutOfStreamMessage(Decoder&& decoder)
-{
-    std::unique_ptr<Decoder> message;
-    {
-        Locker locker { m_outOfStreamMessagesLock };
-        if (m_outOfStreamMessages.isEmpty())
-            return false;
-        message = m_outOfStreamMessages.takeFirst();
-    }
-    if (!message)
-        return false;
-
-    RefPtr<Receiver> receiver;
-    {
-        auto key = std::make_pair(static_cast<uint8_t>(message->messageReceiverName()), message->destinationID());
-        Locker locker { m_receiversLock };
-        receiver = m_receivers.get(key);
-    }
-    if (receiver) {
-        receiver->didReceiveStreamMessage(*this, *message);
-        if (!message->isValid()) {
-            m_connection->dispatchDidReceiveInvalidMessage(message->messageName());
-            return false;
-        }
-    }
-    // If receiver does not exist if it has been removed but messages are still pending to be
-    // processed. It's ok to skip such messages.
-    // FIXME: Note, corresponding skip is not possible at the moment for stream messages.
-    release(decoder.currentBufferPosition());
-    return true;
-}
-
-}
</del></span></pre></div>
<a id="trunkSourceWebKitWebKitxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (283712 => 283713)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj     2021-10-07 15:02:25 UTC (rev 283712)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj        2021-10-07 15:16:51 UTC (rev 283713)
</span><span class="lines">@@ -2040,6 +2040,7 @@
</span><span class="cx">          F409BA181E6E64BC009DA28E /* WKDragDestinationAction.h in Headers */ = {isa = PBXBuildFile; fileRef = F409BA171E6E64B3009DA28E /* WKDragDestinationAction.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          F40BBB41257FF46E0067463A /* GPUProcessWakeupMessageArguments.h in Headers */ = {isa = PBXBuildFile; fileRef = F40BBB40257FF46E0067463A /* GPUProcessWakeupMessageArguments.h */; };
</span><span class="cx">          F414CE2D269DE6EA00BD216A /* RemoteRenderingBackendState.h in Headers */ = {isa = PBXBuildFile; fileRef = F414CE2C269DE6EA00BD216A /* RemoteRenderingBackendState.h */; };
</span><ins>+               F4299507270E234D0032298B /* StreamMessageReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = F4299506270E234C0032298B /* StreamMessageReceiver.h */; };
</ins><span class="cx">           F42D634122A0EFDF00D2FB3A /* WebAutocorrectionData.h in Headers */ = {isa = PBXBuildFile; fileRef = F42D633F22A0EFD300D2FB3A /* WebAutocorrectionData.h */; };
</span><span class="cx">          F430E9422247335F005FE053 /* WebsiteMetaViewportPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = F430E941224732A9005FE053 /* WebsiteMetaViewportPolicy.h */; };
</span><span class="cx">          F430E94422473DFF005FE053 /* WebContentMode.h in Headers */ = {isa = PBXBuildFile; fileRef = F430E94322473DB8005FE053 /* WebContentMode.h */; };
</span><span class="lines">@@ -6105,6 +6106,7 @@
</span><span class="cx">          F40D1B68220BDC0F00B49A01 /* WebAutocorrectionContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WebAutocorrectionContext.h; path = ios/WebAutocorrectionContext.h; sourceTree = "<group>"; };
</span><span class="cx">          F41056612130699A0092281D /* APIAttachmentCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = APIAttachmentCocoa.mm; sourceTree = "<group>"; };
</span><span class="cx">          F414CE2C269DE6EA00BD216A /* RemoteRenderingBackendState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RemoteRenderingBackendState.h; sourceTree = "<group>"; };
</span><ins>+               F4299506270E234C0032298B /* StreamMessageReceiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamMessageReceiver.h; sourceTree = "<group>"; };
</ins><span class="cx">           F42D633F22A0EFD300D2FB3A /* WebAutocorrectionData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAutocorrectionData.h; path = ios/WebAutocorrectionData.h; sourceTree = "<group>"; };
</span><span class="cx">          F42D634022A0EFD300D2FB3A /* WebAutocorrectionData.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WebAutocorrectionData.mm; path = ios/WebAutocorrectionData.mm; sourceTree = "<group>"; };
</span><span class="cx">          F430E941224732A9005FE053 /* WebsiteMetaViewportPolicy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebsiteMetaViewportPolicy.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -7350,6 +7352,7 @@
</span><span class="cx">                          7B73123925CC8525003B2796 /* StreamConnectionEncoder.h */,
</span><span class="cx">                          7B73123225CC8523003B2796 /* StreamConnectionWorkQueue.cpp */,
</span><span class="cx">                          7B73123525CC8524003B2796 /* StreamConnectionWorkQueue.h */,
</span><ins>+                               F4299506270E234C0032298B /* StreamMessageReceiver.h */,
</ins><span class="cx">                           7B73123725CC8524003B2796 /* StreamServerConnection.cpp */,
</span><span class="cx">                          7B73123825CC8524003B2796 /* StreamServerConnection.h */,
</span><span class="cx">                          1AE00D6918327C1200087DD7 /* StringReference.cpp */,
</span><span class="lines">@@ -12659,6 +12662,7 @@
</span><span class="cx">                          7B73123A25CC8525003B2796 /* StreamConnectionBuffer.h in Headers */,
</span><span class="cx">                          7B73124225CC8525003B2796 /* StreamConnectionEncoder.h in Headers */,
</span><span class="cx">                          7B73123E25CC8525003B2796 /* StreamConnectionWorkQueue.h in Headers */,
</span><ins>+                               F4299507270E234D0032298B /* StreamMessageReceiver.h in Headers */,
</ins><span class="cx">                           7B73124125CC8525003B2796 /* StreamServerConnection.h in Headers */,
</span><span class="cx">                          1AE00D6C18327C1200087DD7 /* StringReference.h in Headers */,
</span><span class="cx">                          296BD85D15019BC30071F424 /* StringUtilities.h in Headers */,
</span></span></pre>
</div>
</div>

</body>
</html>