Title: [274433] trunk
Revision
274433
Author
commit-qu...@webkit.org
Date
2021-03-15 13:02:03 -0700 (Mon, 15 Mar 2021)

Log Message

WebGL IPC should use shared memory for synchronous messages
https://bugs.webkit.org/show_bug.cgi?id=220974
<rdar://problem/73876947>

Patch by Kimmo Kinnunen <kkinnu...@apple.com> on 2021-03-15
Reviewed by Geoffrey Garen.

Source/WebKit:

Send synchronous messages via the stream shared memory.
Improves MotionMark on iMac1,1 from 5000 to ~5300 pts.

If the message is encodable as a value, try to do so.
If the reply is encodable as a value, try to do so.
A message or a reply is not encodable if an argument in the message
must be passed by reference via the OS specific mechanism
(e.g. a iosurface or a file handle cannot be sent as a value).

Similar to asynchronous messages, if the synchronous message fits to
the stream buffer, the message is sent via the buffer. Same with the
reply.

If the message or reply is not sent via the stream buffer, it is sent via
the normal IPC.

The client protocol is:
1) Write the message to the buffer and release it.
2) Wait until the server releases the whole buffer back to the client.
3) Read the reply from index 0.
4) Continue sending next message from index 0.

The server protocol is upon receiving a message that is synchronous:
1) Read the message from the message position, dispatch it.
2) Write the reply to index 0.
3) Release the whole buffer back to the client.
4) Continue reading next message from index 0.

The client will not know at the send time whether the server will reply
via the stream or via normal IPC message. The client will reserve
a IPC sync request ID for normal IPC reply purposes.

In case a message or a reply does not fit to the stream buffer, the
ProcessOutOfStreamMessage message is written to the buffer instead.
This will make the reader to wait for the normal IPC message.

Changes temporarily so that the creation of the context waits for the
confirmation that the creation was done. This is due to synchrononous
stream send unable to deliver the WasCreated message during
wait for reply, at the moment.

* GPUProcess/graphics/RemoteGraphicsContextGL.messages.in:
* Platform/IPC/ArgumentCoder.h:
* Platform/IPC/ArgumentCoders.h:
* Platform/IPC/Connection.cpp:
(IPC::Connection::createSyncMessageEncoder):
(IPC::Connection::pushPendingSyncRequestID):
(IPC::Connection::popPendingSyncRequestID):
(IPC::Connection::sendSyncMessage):
* Platform/IPC/Connection.h:
(IPC::Connection::makeSyncRequestID):
Move the code from sendSyncMessage to individual functions so
that the client can reserve a sync request ID for reply purposes.

* Platform/IPC/StreamClientConnection.h:
(IPC::StreamClientConnection::send):
(IPC::StreamClientConnection::trySendStream):
(IPC::StreamClientConnection::sendSync):
(IPC::StreamClientConnection::trySendSyncStream):
(IPC::StreamClientConnection::tryAcquireAll):
* Platform/IPC/StreamConnectionBuffer.h:
* Platform/IPC/StreamServerConnection.cpp:
(IPC::StreamServerConnectionBase::acquireAll):
(IPC::StreamServerConnectionBase::release):
(IPC::StreamServerConnectionBase::releaseAll):
* Platform/IPC/StreamServerConnection.h:
(IPC::StreamServerConnectionBase::sendSyncReply):
The implementation.

(IPC::StreamServerConnectionBase::tryAcquire):
(IPC::StreamServerConnection<Receiver>::dispatchStreamMessages):
Fix a typo StreamServerConnectionBase::tryAquire

(IPC::StreamServerConnection<Receiver>::dispatchStreamMessage):
If the message comes in as normal IPC message, it must be replied
via normal IPC.

Add a flag m_isDispatchingStreamMessage to indicate whether the
message being processed comes as a normal IPC message or a
stream message. This information must be stateful in the connection
class, as it is not passable as arguments when the execution goes through:
    StreamServerConnection<Receiver>::dispatchStreamMessage()
    Receiver::didReceiveStreamMessage()
    handleMessageSynchronous()
    StreamServerConnection<Receiver>::sendSyncReply()

* Scripts/webkit/messages.py:
Add properties NotStreamEncodable, NotStreamEncodableReply
that indicate if the message parameters are such that they
cannot be encoded into plain data buffer as values.
This is encoded as 'constexpr bool isStreamEncodable' and
'constexpr bool isStreamEncodableReply' for the stream messages.

* Scripts/webkit/tests/MessageArgumentDescriptions.cpp:
(IPC::jsValueForArguments):
(IPC::messageArgumentDescriptions):
* Scripts/webkit/tests/MessageNames.cpp:
(IPC::description):
(IPC::receiverName):
(IPC::isValidMessageName):
* Scripts/webkit/tests/MessageNames.h:
* Scripts/webkit/tests/TestWithIfMessageMessages.h:
* Scripts/webkit/tests/TestWithImageDataMessages.h:
* Scripts/webkit/tests/TestWithLegacyReceiverMessages.h:
* Scripts/webkit/tests/TestWithSemaphoreMessages.h:
* Scripts/webkit/tests/TestWithStream.messages.in:
* Scripts/webkit/tests/TestWithStreamBufferMessages.h:
* Scripts/webkit/tests/TestWithStreamMessageReceiver.cpp:
(WebKit::TestWithStream::didReceiveStreamMessage):
* Scripts/webkit/tests/TestWithStreamMessages.h:
(Messages::TestWithStream::SendMachSendRight::name):
(Messages::TestWithStream::SendMachSendRight::SendMachSendRight):
(Messages::TestWithStream::SendMachSendRight::arguments const):
(Messages::TestWithStream::ReceiveMachSendRight::name):
(Messages::TestWithStream::ReceiveMachSendRight::arguments const):
(Messages::TestWithStream::SendAndReceiveMachSendRight::name):
(Messages::TestWithStream::SendAndReceiveMachSendRight::SendAndReceiveMachSendRight):
(Messages::TestWithStream::SendAndReceiveMachSendRight::arguments const):
* Scripts/webkit/tests/TestWithSuperclassMessages.h:
* Scripts/webkit/tests/TestWithoutAttributesMessages.h:
Test changes related to NotStreamEncodable, NotStreamEncodableReply.

Other changes indicate an auxiliary change to message structs:
changing 'const bool isSync' to 'constexpr bool isSync'.
This is done for consistency, since 'isStreamEncodable*' properties
are also added as constexpr.

* Shared/WebCoreArgumentCoders.cpp:
* Shared/WebCoreArgumentCoders.h:
Make types that are WebGL sync message parameters or reply parameters
now encodable to a stream by making the encoder part a template.
Previously these were sent only by normal IPC, and did not need
to be polymorphic to the encoder.

Tools:

Mark PrepareForDisplay() as "not replyable through the stream"
since it replies with MachSendRight.

* Scripts/generate-gpup-webgl:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (274432 => 274433)


--- trunk/Source/WebKit/ChangeLog	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/ChangeLog	2021-03-15 20:02:03 UTC (rev 274433)
@@ -1,3 +1,145 @@
+2021-03-15  Kimmo Kinnunen  <kkinnu...@apple.com>
+
+        WebGL IPC should use shared memory for synchronous messages
+        https://bugs.webkit.org/show_bug.cgi?id=220974
+        <rdar://problem/73876947>
+
+        Reviewed by Geoffrey Garen.
+
+        Send synchronous messages via the stream shared memory.
+        Improves MotionMark on iMac1,1 from 5000 to ~5300 pts.
+
+        If the message is encodable as a value, try to do so.
+        If the reply is encodable as a value, try to do so.
+        A message or a reply is not encodable if an argument in the message
+        must be passed by reference via the OS specific mechanism
+        (e.g. a iosurface or a file handle cannot be sent as a value).
+
+        Similar to asynchronous messages, if the synchronous message fits to
+        the stream buffer, the message is sent via the buffer. Same with the
+        reply.
+
+        If the message or reply is not sent via the stream buffer, it is sent via
+        the normal IPC.
+
+        The client protocol is:
+        1) Write the message to the buffer and release it.
+        2) Wait until the server releases the whole buffer back to the client.
+        3) Read the reply from index 0.
+        4) Continue sending next message from index 0.
+
+        The server protocol is upon receiving a message that is synchronous:
+        1) Read the message from the message position, dispatch it.
+        2) Write the reply to index 0.
+        3) Release the whole buffer back to the client.
+        4) Continue reading next message from index 0.
+
+        The client will not know at the send time whether the server will reply
+        via the stream or via normal IPC message. The client will reserve
+        a IPC sync request ID for normal IPC reply purposes.
+
+        In case a message or a reply does not fit to the stream buffer, the
+        ProcessOutOfStreamMessage message is written to the buffer instead.
+        This will make the reader to wait for the normal IPC message.
+
+        Changes temporarily so that the creation of the context waits for the
+        confirmation that the creation was done. This is due to synchrononous
+        stream send unable to deliver the WasCreated message during
+        wait for reply, at the moment.
+
+        * GPUProcess/graphics/RemoteGraphicsContextGL.messages.in:
+        * Platform/IPC/ArgumentCoder.h:
+        * Platform/IPC/ArgumentCoders.h:
+        * Platform/IPC/Connection.cpp:
+        (IPC::Connection::createSyncMessageEncoder):
+        (IPC::Connection::pushPendingSyncRequestID):
+        (IPC::Connection::popPendingSyncRequestID):
+        (IPC::Connection::sendSyncMessage):
+        * Platform/IPC/Connection.h:
+        (IPC::Connection::makeSyncRequestID):
+        Move the code from sendSyncMessage to individual functions so
+        that the client can reserve a sync request ID for reply purposes.
+
+        * Platform/IPC/StreamClientConnection.h:
+        (IPC::StreamClientConnection::send):
+        (IPC::StreamClientConnection::trySendStream):
+        (IPC::StreamClientConnection::sendSync):
+        (IPC::StreamClientConnection::trySendSyncStream):
+        (IPC::StreamClientConnection::tryAcquireAll):
+        * Platform/IPC/StreamConnectionBuffer.h:
+        * Platform/IPC/StreamServerConnection.cpp:
+        (IPC::StreamServerConnectionBase::acquireAll):
+        (IPC::StreamServerConnectionBase::release):
+        (IPC::StreamServerConnectionBase::releaseAll):
+        * Platform/IPC/StreamServerConnection.h:
+        (IPC::StreamServerConnectionBase::sendSyncReply):
+        The implementation.
+
+        (IPC::StreamServerConnectionBase::tryAcquire):
+        (IPC::StreamServerConnection<Receiver>::dispatchStreamMessages):
+        Fix a typo StreamServerConnectionBase::tryAquire
+
+        (IPC::StreamServerConnection<Receiver>::dispatchStreamMessage):
+        If the message comes in as normal IPC message, it must be replied
+        via normal IPC.
+
+        Add a flag m_isDispatchingStreamMessage to indicate whether the
+        message being processed comes as a normal IPC message or a
+        stream message. This information must be stateful in the connection
+        class, as it is not passable as arguments when the execution goes through:
+            StreamServerConnection<Receiver>::dispatchStreamMessage()
+            Receiver::didReceiveStreamMessage()
+            handleMessageSynchronous()
+            StreamServerConnection<Receiver>::sendSyncReply()
+
+        * Scripts/webkit/messages.py:
+        Add properties NotStreamEncodable, NotStreamEncodableReply
+        that indicate if the message parameters are such that they
+        cannot be encoded into plain data buffer as values.
+        This is encoded as 'constexpr bool isStreamEncodable' and
+        'constexpr bool isStreamEncodableReply' for the stream messages.
+
+        * Scripts/webkit/tests/MessageArgumentDescriptions.cpp:
+        (IPC::jsValueForArguments):
+        (IPC::messageArgumentDescriptions):
+        * Scripts/webkit/tests/MessageNames.cpp:
+        (IPC::description):
+        (IPC::receiverName):
+        (IPC::isValidMessageName):
+        * Scripts/webkit/tests/MessageNames.h:
+        * Scripts/webkit/tests/TestWithIfMessageMessages.h:
+        * Scripts/webkit/tests/TestWithImageDataMessages.h:
+        * Scripts/webkit/tests/TestWithLegacyReceiverMessages.h:
+        * Scripts/webkit/tests/TestWithSemaphoreMessages.h:
+        * Scripts/webkit/tests/TestWithStream.messages.in:
+        * Scripts/webkit/tests/TestWithStreamBufferMessages.h:
+        * Scripts/webkit/tests/TestWithStreamMessageReceiver.cpp:
+        (WebKit::TestWithStream::didReceiveStreamMessage):
+        * Scripts/webkit/tests/TestWithStreamMessages.h:
+        (Messages::TestWithStream::SendMachSendRight::name):
+        (Messages::TestWithStream::SendMachSendRight::SendMachSendRight):
+        (Messages::TestWithStream::SendMachSendRight::arguments const):
+        (Messages::TestWithStream::ReceiveMachSendRight::name):
+        (Messages::TestWithStream::ReceiveMachSendRight::arguments const):
+        (Messages::TestWithStream::SendAndReceiveMachSendRight::name):
+        (Messages::TestWithStream::SendAndReceiveMachSendRight::SendAndReceiveMachSendRight):
+        (Messages::TestWithStream::SendAndReceiveMachSendRight::arguments const):
+        * Scripts/webkit/tests/TestWithSuperclassMessages.h:
+        * Scripts/webkit/tests/TestWithoutAttributesMessages.h:
+        Test changes related to NotStreamEncodable, NotStreamEncodableReply.
+
+        Other changes indicate an auxiliary change to message structs:
+        changing 'const bool isSync' to 'constexpr bool isSync'.
+        This is done for consistency, since 'isStreamEncodable*' properties
+        are also added as constexpr.
+
+        * Shared/WebCoreArgumentCoders.cpp:
+        * Shared/WebCoreArgumentCoders.h:
+        Make types that are WebGL sync message parameters or reply parameters
+        now encodable to a stream by making the encoder part a template.
+        Previously these were sent only by normal IPC, and did not need
+        to be polymorphic to the encoder.
+
 2021-03-15  Youenn Fablet  <you...@apple.com>
 
         Update getUserMedia delegate to expose frame info

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.messages.in (274432 => 274433)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.messages.in	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteGraphicsContextGL.messages.in	2021-03-15 20:02:03 UTC (rev 274433)
@@ -27,7 +27,7 @@
 messages -> RemoteGraphicsContextGL NotRefCounted Stream {
     void Reshape(int32_t width, int32_t height)
 #if PLATFORM(COCOA)
-    void PrepareForDisplay() -> (MachSendRight displayBuffer) Synchronous
+    void PrepareForDisplay() -> (MachSendRight displayBuffer) Synchronous NotStreamEncodableReply
 #endif
 #if !PLATFORM(COCOA)
     void PrepareForDisplay() -> () Synchronous

Modified: trunk/Source/WebKit/Platform/IPC/ArgumentCoder.h (274432 => 274433)


--- trunk/Source/WebKit/Platform/IPC/ArgumentCoder.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Platform/IPC/ArgumentCoder.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -43,6 +43,7 @@
 template<typename T, typename I = T> inline constexpr bool HasModernDecoderV = HasModernDecoder<T, I>::value;
 
 template<typename T, typename = void> struct ArgumentCoder {
+    template<typename Encoder>
     static void encode(Encoder& encoder, const T& t)
     {
         t.encode(encoder);

Modified: trunk/Source/WebKit/Platform/IPC/ArgumentCoders.h (274432 => 274433)


--- trunk/Source/WebKit/Platform/IPC/ArgumentCoders.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Platform/IPC/ArgumentCoders.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -42,6 +42,7 @@
 
 // An argument coder works on POD types
 template<typename T> struct SimpleArgumentCoder {
+    template<typename Encoder>
     static void encode(Encoder& encoder, const T& t)
     {
         encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(&t), sizeof(T), alignof(T));

Modified: trunk/Source/WebKit/Platform/IPC/Connection.cpp (274432 => 274433)


--- trunk/Source/WebKit/Platform/IPC/Connection.cpp	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Platform/IPC/Connection.cpp	2021-03-15 20:02:03 UTC (rev 274433)
@@ -420,7 +420,7 @@
     auto encoder = makeUniqueRef<Encoder>(messageName, destinationID);
 
     // Encode the sync request ID.
-    syncRequestID = ++m_syncRequestID;
+    syncRequestID = makeSyncRequestID();
     encoder.get() << syncRequestID;
 
     return encoder;
@@ -564,8 +564,29 @@
     return nullptr;
 }
 
+bool Connection::pushPendingSyncRequestID(uint64_t syncRequestID)
+{
+    {
+        LockHolder locker(m_syncReplyStateMutex);
+        if (!m_shouldWaitForSyncReplies)
+            return false;
+        m_pendingSyncReplies.append(PendingSyncReply(syncRequestID));
+    }
+    ++m_inSendSyncCount;
+    return true;
+}
+
+void Connection::popPendingSyncRequestID(uint64_t syncRequestID)
+{
+    --m_inSendSyncCount;
+    LockHolder locker(m_syncReplyStateMutex);
+    ASSERT_UNUSED(syncRequestID, m_pendingSyncReplies.last().syncRequestID == syncRequestID);
+    m_pendingSyncReplies.removeLast();
+}
+
 std::unique_ptr<Decoder> Connection::sendSyncMessage(uint64_t syncRequestID, UniqueRef<Encoder>&& encoder, Timeout timeout, OptionSet<SendSyncOption> sendSyncOptions)
 {
+    ASSERT(syncRequestID);
     ASSERT(RunLoop::isMain());
 
     if (!isValid()) {
@@ -572,20 +593,11 @@
         didFailToSendSyncMessage();
         return nullptr;
     }
-
-    // Push the pending sync reply information on our stack.
-    {
-        LockHolder locker(m_syncReplyStateMutex);
-        if (!m_shouldWaitForSyncReplies) {
-            didFailToSendSyncMessage();
-            return nullptr;
-        }
-
-        m_pendingSyncReplies.append(PendingSyncReply(syncRequestID));
+    if (!pushPendingSyncRequestID(syncRequestID)) {
+        didFailToSendSyncMessage();
+        return nullptr;
     }
 
-    ++m_inSendSyncCount;
-
     // First send the message.
     OptionSet<SendOption> sendOptions = IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply;
     if (sendSyncOptions.contains(SendSyncOption::ForceDispatchWhenDestinationIsWaitingForUnboundedSyncReply))
@@ -599,15 +611,8 @@
     Ref<Connection> protect(*this);
     std::unique_ptr<Decoder> reply = waitForSyncReply(syncRequestID, messageName, timeout, sendSyncOptions);
 
-    --m_inSendSyncCount;
+    popPendingSyncRequestID(syncRequestID);
 
-    // Finally, pop the pending sync reply information.
-    {
-        LockHolder locker(m_syncReplyStateMutex);
-        ASSERT(m_pendingSyncReplies.last().syncRequestID == syncRequestID);
-        m_pendingSyncReplies.removeLast();
-    }
-
     if (!reply)
         didFailToSendSyncMessage();
 

Modified: trunk/Source/WebKit/Platform/IPC/Connection.h (274432 => 274433)


--- trunk/Source/WebKit/Platform/IPC/Connection.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Platform/IPC/Connection.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -323,7 +323,9 @@
     bool isIncomingMessagesThrottlingEnabled() const { return !!m_incomingMessagesThrottler; }
     
     std::unique_ptr<Decoder> waitForMessage(MessageName, uint64_t destinationID, Timeout, OptionSet<WaitForOption>);
-    
+    uint64_t makeSyncRequestID() { return ++m_syncRequestID; }
+    bool pushPendingSyncRequestID(uint64_t syncRequestID);
+    void popPendingSyncRequestID(uint64_t syncRequestID);
     std::unique_ptr<Decoder> waitForSyncReply(uint64_t syncRequestID, MessageName, Timeout, OptionSet<SendSyncOption>);
 
     // Called on the connection work queue.
@@ -496,6 +498,7 @@
     EventListener m_writeListener;
     HANDLE m_connectionPipe { INVALID_HANDLE_VALUE };
 #endif
+    friend class StreamClientConnection;
 };
 
 template<typename T>

Modified: trunk/Source/WebKit/Platform/IPC/HandleMessage.h (274432 => 274433)


--- trunk/Source/WebKit/Platform/IPC/HandleMessage.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Platform/IPC/HandleMessage.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -184,7 +184,7 @@
     }
 
     typename T::DelayedReply completionHandler = [syncRequestID, connection = makeRef(connection)] (auto&&... args) mutable {
-        connection->sendSyncReply(syncRequestID, args...);
+        connection->sendSyncReply<T>(syncRequestID, args...);
     };
     callMemberFunction(WTFMove(*arguments), WTFMove(completionHandler), object, function);
 }

Modified: trunk/Source/WebKit/Platform/IPC/StreamClientConnection.h (274432 => 274433)


--- trunk/Source/WebKit/Platform/IPC/StreamClientConnection.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Platform/IPC/StreamClientConnection.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -67,10 +67,16 @@
     };
     static constexpr size_t minimumMessageSize = StreamConnectionEncoder::minimumMessageSize;
     static constexpr size_t messageAlignment = StreamConnectionEncoder::messageAlignment;
+    template<typename T>
+    bool trySendStream(T& message, Span&);
+    template<typename T>
+    Optional<SendSyncResult> trySendSyncStream(T& message, typename T::Reply&, Timeout, Span&);
     bool trySendDestinationIDIfNeeded(uint64_t destinationID, Timeout);
     void sendProcessOutOfStreamMessage(Span&&);
 
     Optional<Span> tryAcquire(Timeout);
+    Optional<Span> tryAcquireAll(Timeout);
+
     enum class WakeUpServer : bool {
         No,
         Yes
@@ -110,14 +116,9 @@
     auto span = tryAcquire(timeout);
     if (!span)
         return false;
-    {
-        StreamConnectionEncoder messageEncoder { T::name(), span->data, span->size };
-        if (messageEncoder << message.arguments()) {
-            auto wakeupResult = release(messageEncoder.size());
-            if (wakeupResult == StreamClientConnection::WakeUpServer::Yes)
-                wakeUpServer();
+    if constexpr(T::isStreamEncodable) {
+        if (trySendStream(message, *span))
             return true;
-        }
     }
     sendProcessOutOfStreamMessage(WTFMove(*span));
     if (!m_connection.send(WTFMove(message), destinationID, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply))
@@ -125,6 +126,19 @@
     return true;
 }
 
+template<typename T>
+bool StreamClientConnection::trySendStream(T& message, Span& span)
+{
+    StreamConnectionEncoder messageEncoder { T::name(), span.data, span.size };
+    if (messageEncoder << message.arguments()) {
+        auto wakeupResult = release(messageEncoder.size());
+        if (wakeupResult == StreamClientConnection::WakeUpServer::Yes)
+            wakeUpServer();
+        return true;
+    }
+    return false;
+}
+
 template<typename T, typename U>
 StreamClientConnection::SendSyncResult StreamClientConnection::sendSync(T&& message, typename T::Reply&& reply, ObjectIdentifier<U> destinationID, Timeout timeout)
 {
@@ -134,12 +148,57 @@
     auto span = tryAcquire(timeout);
     if (!span)
         return { };
-    // FIXME: implement send through stream.
-    // FIXME: implement receive through stream.
+    if constexpr(T::isStreamEncodable) {
+        auto maybeSendResult = trySendSyncStream(message, reply, timeout, *span);
+        if (maybeSendResult)
+            return WTFMove(*maybeSendResult);
+    }
     sendProcessOutOfStreamMessage(WTFMove(*span));
     return m_connection.sendSync(WTFMove(message), WTFMove(reply), destinationID.toUInt64(), timeout);
 }
 
+template<typename T>
+Optional<StreamClientConnection::SendSyncResult> StreamClientConnection::trySendSyncStream(T& message, typename T::Reply& reply, Timeout timeout, Span& span)
+{
+    // In this function, SendSyncResult { } means error happened and caller should stop processing.
+    // WTF::nullopt means we couldn't send through the stream, so try sending out of stream.
+    auto syncRequestID = m_connection.makeSyncRequestID();
+    if (!m_connection.pushPendingSyncRequestID(syncRequestID))
+        return SendSyncResult { };
+
+    auto result = [&]() -> Optional<SendSyncResult> {
+        StreamConnectionEncoder messageEncoder { T::name(), span.data, span.size };
+        if (!(messageEncoder << syncRequestID << message.arguments()))
+            return WTF::nullopt;
+        auto wakeupResult = release(messageEncoder.size());
+
+        if (wakeupResult == StreamClientConnection::WakeUpServer::Yes)
+            wakeUpServer();
+        if constexpr(T::isReplyStreamEncodable) {
+            auto replySpan = tryAcquireAll(timeout);
+            if (!replySpan)
+                return SendSyncResult { };
+            auto decoder = std::unique_ptr<Decoder> { new Decoder(replySpan->data, replySpan->size, m_currentDestinationID) };
+            if (decoder->messageName() != MessageName::ProcessOutOfStreamMessage) {
+                ASSERT(decoder->messageName() == MessageName::SyncMessageReply);
+                return decoder;
+            }
+        } else
+            m_clientOffset = 0;
+        return m_connection.waitForSyncReply(syncRequestID, T::name(), timeout, { });
+    }();
+    m_connection.popPendingSyncRequestID(syncRequestID);
+    if (result && *result) {
+        auto& decoder = **result;
+        Optional<typename T::ReplyArguments> replyArguments;
+        decoder >> replyArguments;
+        if (!replyArguments)
+            return SendSyncResult { };
+        moveTuple(WTFMove(*replyArguments), reply);
+    }
+    return result;
+}
+
 inline bool StreamClientConnection::trySendDestinationIDIfNeeded(uint64_t destinationID, Timeout timeout)
 {
     if (destinationID == m_currentDestinationID)
@@ -201,6 +260,45 @@
     return WTF::nullopt;
 }
 
+inline Optional<StreamClientConnection::Span> StreamClientConnection::tryAcquireAll(Timeout timeout)
+{
+    // This would mean we try to send messages after a timeout. It is a programming error.
+    // Since the value is trusted, we only assert.
+    ASSERT(sharedClientLimit().load(std::memory_order_acquire) != ClientLimit::clientIsWaitingTag);
+
+    // The server acknowledges that sync message has been processed by setting clientOffset == clientLimit == 0.
+    // Wait for this condition, or then the condition where server says that it started to sleep after setting that condition.
+    // The wait sequence involves two variables, so form a transaction by setting clientLimit == clientIsWaitingTag.
+    // The transaction is cancelled if the server has already set clientOffset == clientLimit == 0, otherwise it commits.
+    // If the transaction commits, server is guaranteed to signal.
+
+    for (;;) {
+#if PLATFORM(COCOA)
+        ClientLimit clientLimit = sharedClientLimit().exchange(ClientLimit::clientIsWaitingTag, std::memory_order_acq_rel);
+        ClientOffset clientOffset = sharedClientOffset().load(std::memory_order_acquire);
+#else
+        ClientLimit clientLimit = sharedClientLimit().load(std::memory_order_acquire);
+        ClientOffset clientOffset = sharedClientOffset().load(std::memory_order_acquire);
+#endif
+        if (!clientLimit && (clientOffset == ClientOffset::serverIsSleepingTag || !clientOffset))
+            break;
+
+#if PLATFORM(COCOA)
+        m_buffer.clientWaitSemaphore().waitFor(timeout);
+#else
+        Thread::yield();
+#endif
+        if (timeout.didTimeOut())
+            return WTF::nullopt;
+    }
+#if PLATFORM(COCOA)
+    // In case the transaction was cancelled, undo the transaction marker.
+    sharedClientLimit().store(static_cast<ClientLimit>(0), std::memory_order_release);
+#endif
+    m_clientOffset = 0;
+    return alignedSpan(m_clientOffset, 0);
+}
+
 inline StreamClientConnection::WakeUpServer StreamClientConnection::release(size_t size)
 {
     size = std::max(size, minimumMessageSize);

Modified: trunk/Source/WebKit/Platform/IPC/StreamConnectionBuffer.h (274432 => 274433)


--- trunk/Source/WebKit/Platform/IPC/StreamConnectionBuffer.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Platform/IPC/StreamConnectionBuffer.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -49,10 +49,20 @@
 // and then upon the second acquire 166 bytes. Due to how alignment and minimum length affect the position at which the
 // memory can be referred to, the server cannot "read two times simultaneously" and release 174 bytes.
 //
+// The buffer also supports synchronous replies via "releaseAll/acquireAll" call pattern. The communication protocol can
+// establish cases where the client transfers ownership of the data to the server. In these cases the server will
+// acknowledge the read with "releaseAll" operation. The client will then read the reply via "acquireAll" operation. The
+// reply will be written to the beginning of the buffer. This mandates that in-place data references in the buffer
+// cannot be used simultaneously for message data and the reply data. In current IPC implementation, the message
+// processing uses the in-place data references, while the reply data is first constructed to allocated memory and then
+// copied to the message buffer.
+//
 // The circular buffer has following implementation:
 // * The client owns the data between [clientOffset, serverOffset[. When clientOffset == serverOffset, the client owns
 //   all the data.
 // * The server owns the data between [serverOffset, clientOffset[.
+// * The exception to the above is when communication protocol can contain messages that denote that the server will own
+//   all the data.
 // * The buffer can hold maximum of size - 1 values. The last value is reserved for indicating that the buffer is full.
 //   FIXME: Maybe would be simpler implementation if it would use the "wrap" flag instead of the hole as the indicator.
 //   This would move the alignedSpan implementation to the StreamConnectionBuffer.

Modified: trunk/Source/WebKit/Platform/IPC/StreamServerConnection.cpp (274432 => 274433)


--- trunk/Source/WebKit/Platform/IPC/StreamServerConnection.cpp	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Platform/IPC/StreamServerConnection.cpp	2021-03-15 20:02:03 UTC (rev 274433)
@@ -59,7 +59,7 @@
     m_workQueue.wakeUp();
 }
 
-Optional<StreamServerConnectionBase::Span> StreamServerConnectionBase::tryAquire()
+Optional<StreamServerConnectionBase::Span> StreamServerConnectionBase::tryAcquire()
 {
     ServerLimit serverLimit = sharedServerLimit().load(std::memory_order_acquire);
     if (serverLimit == ServerLimit::serverIsSleepingTag)
@@ -77,6 +77,11 @@
     return result;
 }
 
+StreamServerConnectionBase::Span StreamServerConnectionBase::acquireAll()
+{
+    return alignedSpan(0, dataSize() - 1);
+}
+
 void StreamServerConnectionBase::release(size_t readSize)
 {
     ASSERT(readSize);
@@ -85,7 +90,7 @@
 
 #if PLATFORM(COCOA)
     ServerOffset oldServerOffset = sharedServerOffset().exchange(serverOffset, std::memory_order_acq_rel);
-    // If the sender wrote over serverOffset, it means the sender is waiting.
+    // If the client wrote over serverOffset, it means the client is waiting.
     if (oldServerOffset == ServerOffset::clientIsWaitingTag)
         m_buffer.clientWaitSemaphore().signal();
     else
@@ -98,6 +103,23 @@
     m_serverOffset = serverOffset;
 }
 
+void StreamServerConnectionBase::releaseAll()
+{
+    sharedServerLimit().store(static_cast<ServerLimit>(0), std::memory_order_release);
+#if PLATFORM(COCOA)
+    ServerOffset oldServerOffset = sharedServerOffset().exchange(static_cast<ServerOffset>(0), std::memory_order_acq_rel);
+    // If the client wrote over serverOffset, it means the client is waiting.
+    if (oldServerOffset == ServerOffset::clientIsWaitingTag)
+        m_buffer.clientWaitSemaphore().signal();
+    else
+        ASSERT(!(oldServerOffset & ServerOffset::clientIsWaitingTag));
+#else
+    sharedServerOffset().store(static_cast<ServerOffset>(0), std::memory_order_release);
+    // IPC::Semaphore not implemented for the platform. Client will poll and yield.
+#endif
+    m_serverOffset = 0;
+}
+
 StreamServerConnectionBase::Span StreamServerConnectionBase::alignedSpan(size_t offset, size_t limit)
 {
     ASSERT(offset < dataSize());

Modified: trunk/Source/WebKit/Platform/IPC/StreamServerConnection.h (274432 => 274433)


--- trunk/Source/WebKit/Platform/IPC/StreamServerConnection.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Platform/IPC/StreamServerConnection.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -51,7 +51,7 @@
     };
     virtual DispatchResult dispatchStreamMessages(size_t messageLimit) = 0;
 
-    template<typename... Arguments>
+    template<typename T, typename... Arguments>
     void sendSyncReply(uint64_t syncRequestID, Arguments&&...);
 
 protected:
@@ -67,9 +67,11 @@
         uint8_t* data;
         size_t size;
     };
-    Optional<Span> tryAquire();
+    Optional<Span> tryAcquire();
+    Span acquireAll();
 
     void release(size_t readSize);
+    void releaseAll();
     static constexpr size_t minimumMessageSize = StreamConnectionEncoder::minimumMessageSize;
     static constexpr size_t messageAlignment = StreamConnectionEncoder::messageAlignment;
     Span alignedSpan(size_t offset, size_t limit);
@@ -92,15 +94,27 @@
 
     Lock m_outOfStreamMessagesLock;
     Deque<std::unique_ptr<Decoder>> m_outOfStreamMessages;
+    bool m_isDispatchingStreamMessage { false };
 
     friend class StreamConnectionWorkQueue;
 };
 
-template<typename... Arguments>
+template<typename T, typename... Arguments>
 void StreamServerConnectionBase::sendSyncReply(uint64_t syncRequestID, Arguments&&... arguments)
 {
-    // FIXME: implement sending to buffer.
-    auto encoder = makeUniqueRef<IPC::Encoder>(IPC::MessageName::SyncMessageReply, syncRequestID);
+    if constexpr(T::isReplyStreamEncodable) {
+        if (m_isDispatchingStreamMessage) {
+            auto span = acquireAll();
+            {
+                StreamConnectionEncoder messageEncoder { MessageName::SyncMessageReply, span.data, span.size };
+                if ((messageEncoder << ... << arguments))
+                    return;
+            }
+            StreamConnectionEncoder outOfStreamEncoder { MessageName::ProcessOutOfStreamMessage, span.data, span.size };
+        }
+    }
+    auto encoder = makeUniqueRef<Encoder>(MessageName::SyncMessageReply, syncRequestID);
+
     (encoder.get() << ... << arguments);
     m_connection->sendSyncReply(WTFMove(encoder));
 }
@@ -142,8 +156,7 @@
     Lock m_receiversLock;
     using ReceiversMap = HashMap<std::pair<uint8_t, uint64_t>, Ref<Receiver>>;
     ReceiversMap m_receivers;
-
-    uint64_t m_currentDestinationID = 0;
+    uint64_t m_currentDestinationID { 0 };
 };
 
 template<typename Receiver>
@@ -176,7 +189,7 @@
     uint8_t currentReceiverName = static_cast<uint8_t>(ReceiverName::Invalid);
 
     for (size_t i = 0; i < messageLimit; ++i) {
-        auto span = tryAquire();
+        auto span = tryAcquire();
         if (!span)
             return DispatchResult::HasNoMessages;
         IPC::Decoder decoder { span->data, span->size, m_currentDestinationID };
@@ -242,12 +255,18 @@
 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;
     }
-    release(decoder.currentBufferPosition());
+    if (decoder.isSyncMessage())
+        releaseAll();
+    else
+        release(decoder.currentBufferPosition());
     return true;
 }
 

Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/messages.py	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py	2021-03-15 20:02:03 UTC (rev 274433)
@@ -57,6 +57,8 @@
 WANTS_ASYNC_DISPATCH_MESSAGE_ATTRIBUTE = 'WantsAsyncDispatchMessage'
 LEGACY_RECEIVER_ATTRIBUTE = 'LegacyReceiver'
 NOT_REFCOUNTED_RECEIVER_ATTRIBUTE = 'NotRefCounted'
+NOT_STREAM_ENCODABLE_ATTRIBUTE = 'NotStreamEncodable'
+NOT_STREAM_ENCODABLE_REPLY_ATTRIBUTE = 'NotStreamEncodableReply'
 
 def receiver_enumerator_order_key(receiver_name):
     if receiver_name == 'IPC':
@@ -194,7 +196,12 @@
     result.append('    using Arguments = %s;\n' % arguments_type(message))
     result.append('\n')
     result.append('    static IPC::MessageName name() { return IPC::MessageName::%s_%s; }\n' % (receiver.name, message.name))
-    result.append('    static const bool isSync = %s;\n' % ('false', 'true')[message.reply_parameters != None and not message.has_attribute(ASYNC_ATTRIBUTE)])
+    result.append('    static constexpr bool isSync = %s;\n' % ('false', 'true')[message.reply_parameters is not None and not message.has_attribute(ASYNC_ATTRIBUTE)])
+    if receiver.has_attribute(STREAM_ATTRIBUTE):
+        result.append('    static constexpr bool isStreamEncodable = %s;\n' % ('true', 'false')[message.has_attribute(NOT_STREAM_ENCODABLE_ATTRIBUTE)])
+        if message.reply_parameters is not None:
+            result.append('    static constexpr bool isReplyStreamEncodable = %s;\n' % ('true', 'false')[message.has_attribute(NOT_STREAM_ENCODABLE_REPLY_ATTRIBUTE)])
+
     result.append('\n')
     if message.reply_parameters != None:
         send_parameters = [(function_parameter_type(x.type, x.kind), x.name) for x in message.reply_parameters]

Modified: trunk/Source/WebKit/Scripts/webkit/tests/MessageArgumentDescriptions.cpp (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/MessageArgumentDescriptions.cpp	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/MessageArgumentDescriptions.cpp	2021-03-15 20:02:03 UTC (rev 274433)
@@ -67,6 +67,9 @@
 #include <WebCore/PluginData.h>
 #include <utility>
 #include <wtf/HashMap.h>
+#if PLATFORM(COCOA)
+#include <wtf/MachSendRight.h>
+#endif
 #if PLATFORM(MAC)
 #include <wtf/OptionSet.h>
 #endif
@@ -236,6 +239,14 @@
         return jsValueForDecodedArguments<Messages::TestWithStream::SendString::Arguments>(globalObject, decoder);
     case MessageName::TestWithStream_SendStringSynchronized:
         return jsValueForDecodedArguments<Messages::TestWithStream::SendStringSynchronized::Arguments>(globalObject, decoder);
+#if PLATFORM(COCOA)
+    case MessageName::TestWithStream_SendMachSendRight:
+        return jsValueForDecodedArguments<Messages::TestWithStream::SendMachSendRight::Arguments>(globalObject, decoder);
+    case MessageName::TestWithStream_ReceiveMachSendRight:
+        return jsValueForDecodedArguments<Messages::TestWithStream::ReceiveMachSendRight::Arguments>(globalObject, decoder);
+    case MessageName::TestWithStream_SendAndReceiveMachSendRight:
+        return jsValueForDecodedArguments<Messages::TestWithStream::SendAndReceiveMachSendRight::Arguments>(globalObject, decoder);
+#endif
     case MessageName::TestWithStreamBuffer_SendStreamBuffer:
         return jsValueForDecodedArguments<Messages::TestWithStreamBuffer::SendStreamBuffer::Arguments>(globalObject, decoder);
     default:
@@ -559,6 +570,18 @@
         return Vector<ArgumentDescription> {
             {"url", "String", nullptr, false},
         };
+#if PLATFORM(COCOA)
+    case MessageName::TestWithStream_SendMachSendRight:
+        return Vector<ArgumentDescription> {
+            {"a1", "MachSendRight", nullptr, false},
+        };
+    case MessageName::TestWithStream_ReceiveMachSendRight:
+        return Vector<ArgumentDescription> { };
+    case MessageName::TestWithStream_SendAndReceiveMachSendRight:
+        return Vector<ArgumentDescription> {
+            {"a1", "MachSendRight", nullptr, false},
+        };
+#endif
     case MessageName::TestWithStreamBuffer_SendStreamBuffer:
         return Vector<ArgumentDescription> {
             {"stream", "IPC::StreamConnectionBuffer", nullptr, false},

Modified: trunk/Source/WebKit/Scripts/webkit/tests/MessageNames.cpp (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/MessageNames.cpp	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/MessageNames.cpp	2021-03-15 20:02:03 UTC (rev 274433)
@@ -82,6 +82,12 @@
         return "TestWithSemaphore_SendSemaphore";
     case MessageName::TestWithStreamBuffer_SendStreamBuffer:
         return "TestWithStreamBuffer_SendStreamBuffer";
+    case MessageName::TestWithStream_ReceiveMachSendRight:
+        return "TestWithStream_ReceiveMachSendRight";
+    case MessageName::TestWithStream_SendAndReceiveMachSendRight:
+        return "TestWithStream_SendAndReceiveMachSendRight";
+    case MessageName::TestWithStream_SendMachSendRight:
+        return "TestWithStream_SendMachSendRight";
     case MessageName::TestWithStream_SendString:
         return "TestWithStream_SendString";
     case MessageName::TestWithStream_SendStringSynchronized:
@@ -207,6 +213,9 @@
         return ReceiverName::TestWithSemaphore;
     case MessageName::TestWithStreamBuffer_SendStreamBuffer:
         return ReceiverName::TestWithStreamBuffer;
+    case MessageName::TestWithStream_ReceiveMachSendRight:
+    case MessageName::TestWithStream_SendAndReceiveMachSendRight:
+    case MessageName::TestWithStream_SendMachSendRight:
     case MessageName::TestWithStream_SendString:
     case MessageName::TestWithStream_SendStringSynchronized:
         return ReceiverName::TestWithStream;
@@ -340,6 +349,18 @@
         return true;
     if (messageName == IPC::MessageName::TestWithStreamBuffer_SendStreamBuffer)
         return true;
+#if PLATFORM(COCOA)
+    if (messageName == IPC::MessageName::TestWithStream_ReceiveMachSendRight)
+        return true;
+#endif
+#if PLATFORM(COCOA)
+    if (messageName == IPC::MessageName::TestWithStream_SendAndReceiveMachSendRight)
+        return true;
+#endif
+#if PLATFORM(COCOA)
+    if (messageName == IPC::MessageName::TestWithStream_SendMachSendRight)
+        return true;
+#endif
     if (messageName == IPC::MessageName::TestWithStream_SendString)
         return true;
     if (messageName == IPC::MessageName::TestWithStream_SendStringSynchronized)

Modified: trunk/Source/WebKit/Scripts/webkit/tests/MessageNames.h (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/MessageNames.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/MessageNames.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -69,6 +69,9 @@
     , TestWithSemaphore_ReceiveSemaphore
     , TestWithSemaphore_SendSemaphore
     , TestWithStreamBuffer_SendStreamBuffer
+    , TestWithStream_ReceiveMachSendRight
+    , TestWithStream_SendAndReceiveMachSendRight
+    , TestWithStream_SendMachSendRight
     , TestWithStream_SendString
     , TestWithStream_SendStringSynchronized
     , TestWithSuperclass_LoadURL

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithIfMessageMessages.h (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithIfMessageMessages.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithIfMessageMessages.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -47,7 +47,7 @@
     using Arguments = std::tuple<const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithIfMessage_LoadURL; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit LoadURL(const String& url)
         : m_arguments(url)
@@ -70,7 +70,7 @@
     using Arguments = std::tuple<const String&, int64_t>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithIfMessage_LoadURL; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     LoadURL(const String& url, int64_t value)
         : m_arguments(url, value)

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithImageDataMessages.h (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithImageDataMessages.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithImageDataMessages.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -47,7 +47,7 @@
     using Arguments = std::tuple<const RefPtr<WebCore::ImageData>&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithImageData_SendImageData; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit SendImageData(const RefPtr<WebCore::ImageData>& s0)
         : m_arguments(s0)
@@ -68,7 +68,7 @@
     using Arguments = std::tuple<>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithImageData_ReceiveImageData; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
     using Reply = std::tuple<RefPtr<WebCore::ImageData>&>;

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithLegacyReceiverMessages.h (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithLegacyReceiverMessages.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithLegacyReceiverMessages.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -68,7 +68,7 @@
     using Arguments = std::tuple<const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_LoadURL; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit LoadURL(const String& url)
         : m_arguments(url)
@@ -90,7 +90,7 @@
     using Arguments = std::tuple<const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_LoadSomething; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit LoadSomething(const String& url)
         : m_arguments(url)
@@ -113,7 +113,7 @@
     using Arguments = std::tuple<const WebKit::WebTouchEvent&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_TouchEvent; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit TouchEvent(const WebKit::WebTouchEvent& event)
         : m_arguments(event)
@@ -136,7 +136,7 @@
     using Arguments = std::tuple<const WebKit::WebTouchEvent&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_AddEvent; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit AddEvent(const WebKit::WebTouchEvent& event)
         : m_arguments(event)
@@ -159,7 +159,7 @@
     using Arguments = std::tuple<const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_LoadSomethingElse; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit LoadSomethingElse(const String& url)
         : m_arguments(url)
@@ -181,7 +181,7 @@
     using Arguments = std::tuple<uint64_t, uint64_t, uint32_t>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_DidReceivePolicyDecision; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction)
         : m_arguments(frameID, listenerID, policyAction)
@@ -202,7 +202,7 @@
     using Arguments = std::tuple<>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_Close; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     const Arguments& arguments() const
     {
@@ -218,7 +218,7 @@
     using Arguments = std::tuple<const WebKit::WebPreferencesStore&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_PreferencesDidChange; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit PreferencesDidChange(const WebKit::WebPreferencesStore& store)
         : m_arguments(store)
@@ -239,7 +239,7 @@
     using Arguments = std::tuple<double, float>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_SendDoubleAndFloat; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     SendDoubleAndFloat(double d, float f)
         : m_arguments(d, f)
@@ -260,7 +260,7 @@
     using Arguments = std::tuple<const Vector<uint64_t>&, const Vector<Vector<uint64_t>>&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_SendInts; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     SendInts(const Vector<uint64_t>& ints, const Vector<Vector<uint64_t>>& intVectors)
         : m_arguments(ints, intVectors)
@@ -281,7 +281,7 @@
     using Arguments = std::tuple<uint64_t, const WebKit::Plugin::Parameters&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_CreatePlugin; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
     using Reply = std::tuple<bool&>;
@@ -305,7 +305,7 @@
     using Arguments = std::tuple<uint64_t, const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_RunJavaScriptAlert; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
     using Reply = std::tuple<>;
@@ -329,7 +329,7 @@
     using Arguments = std::tuple<bool>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_GetPlugins; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
     using Reply = std::tuple<Vector<WebCore::PluginInfo>&>;
@@ -353,7 +353,7 @@
     using Arguments = std::tuple<const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_GetPluginProcessConnection; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     using DelayedReply = GetPluginProcessConnectionDelayedReply;
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
@@ -379,7 +379,7 @@
     using Arguments = std::tuple<>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_TestMultipleAttributes; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     using DelayedReply = TestMultipleAttributesDelayedReply;
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
@@ -400,7 +400,7 @@
     using Arguments = std::tuple<uint64_t, double, double>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_TestParameterAttributes; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     TestParameterAttributes(uint64_t foo, double bar, double baz)
         : m_arguments(foo, bar, baz)
@@ -421,7 +421,7 @@
     using Arguments = std::tuple<const HashMap<String, std::pair<String, uint64_t>>&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_TemplateTest; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit TemplateTest(const HashMap<String, std::pair<String, uint64_t>>& a)
         : m_arguments(a)
@@ -442,7 +442,7 @@
     using Arguments = std::tuple<const WebCore::GraphicsLayer::PlatformLayerID&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_SetVideoLayerID; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit SetVideoLayerID(const WebCore::GraphicsLayer::PlatformLayerID& videoLayerID)
         : m_arguments(videoLayerID)
@@ -464,7 +464,7 @@
     using Arguments = std::tuple<const IPC::MachPort&, const OptionSet<WebKit::SelectionFlags>&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_DidCreateWebProcessConnection; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     DidCreateWebProcessConnection(const IPC::MachPort& connectionIdentifier, const OptionSet<WebKit::SelectionFlags>& flags)
         : m_arguments(connectionIdentifier, flags)
@@ -487,7 +487,7 @@
     using Arguments = std::tuple<uint32_t>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_InterpretKeyEvent; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
     using Reply = std::tuple<Vector<WebCore::KeypressCommand>&>;
@@ -513,7 +513,7 @@
     using Arguments = std::tuple<const IPC::DummyType&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_DeprecatedOperation; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit DeprecatedOperation(const IPC::DummyType& dummy)
         : m_arguments(dummy)
@@ -536,7 +536,7 @@
     using Arguments = std::tuple<const IPC::DummyType&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithLegacyReceiver_ExperimentalOperation; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit ExperimentalOperation(const IPC::DummyType& dummy)
         : m_arguments(dummy)

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithSemaphoreMessages.h (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithSemaphoreMessages.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithSemaphoreMessages.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -46,7 +46,7 @@
     using Arguments = std::tuple<const IPC::Semaphore&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithSemaphore_SendSemaphore; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit SendSemaphore(const IPC::Semaphore& s0)
         : m_arguments(s0)
@@ -67,7 +67,7 @@
     using Arguments = std::tuple<>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithSemaphore_ReceiveSemaphore; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
     using Reply = std::tuple<IPC::Semaphore&>;

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithStream.messages.in (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithStream.messages.in	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithStream.messages.in	2021-03-15 20:02:03 UTC (rev 274433)
@@ -23,5 +23,10 @@
 # Tests Stream receiver attribute.
 messages -> TestWithStream NotRefCounted Stream {
     void SendString(String url)
-    void SendStringSynchronized(String url) -> (int64_t return)
+    void SendStringSynchronized(String url) -> (int64_t returnValue)
+#if PLATFORM(COCOA)
+    void SendMachSendRight(MachSendRight a1) NotStreamEncodable
+    void ReceiveMachSendRight() -> (MachSendRight r1) NotStreamEncodableReply
+    void SendAndReceiveMachSendRight(MachSendRight a1) -> (MachSendRight r1) NotStreamEncodable NotStreamEncodableReply
+#endif
 }

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamBufferMessages.h (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamBufferMessages.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamBufferMessages.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -48,7 +48,7 @@
     using Arguments = std::tuple<const IPC::StreamConnectionBuffer&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithStreamBuffer_SendStreamBuffer; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit SendStreamBuffer(const IPC::StreamConnectionBuffer& stream)
         : m_arguments(stream)

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamMessageReceiver.cpp (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamMessageReceiver.cpp	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamMessageReceiver.cpp	2021-03-15 20:02:03 UTC (rev 274433)
@@ -29,6 +29,9 @@
 #include "Decoder.h"
 #include "HandleMessage.h"
 #include "TestWithStreamMessages.h"
+#if PLATFORM(COCOA)
+#include <wtf/MachSendRight.h>
+#endif
 #include <wtf/text/WTFString.h>
 
 namespace WebKit {
@@ -37,8 +40,20 @@
 {
     if (decoder.messageName() == Messages::TestWithStream::SendString::name())
         return IPC::handleMessage<Messages::TestWithStream::SendString>(decoder, this, &TestWithStream::sendString);
+#if PLATFORM(COCOA)
+    if (decoder.messageName() == Messages::TestWithStream::SendMachSendRight::name())
+        return IPC::handleMessage<Messages::TestWithStream::SendMachSendRight>(decoder, this, &TestWithStream::sendMachSendRight);
+#endif
     if (decoder.messageName() == Messages::TestWithStream::SendStringSynchronized::name())
         return IPC::handleMessage<Messages::TestWithStream::SendStringSynchronized>(decoder, this, &TestWithStream::sendStringSynchronized);
+#if PLATFORM(COCOA)
+    if (decoder.messageName() == Messages::TestWithStream::ReceiveMachSendRight::name())
+        return IPC::handleMessage<Messages::TestWithStream::ReceiveMachSendRight>(decoder, this, &TestWithStream::receiveMachSendRight);
+#endif
+#if PLATFORM(COCOA)
+    if (decoder.messageName() == Messages::TestWithStream::SendAndReceiveMachSendRight::name())
+        return IPC::handleMessage<Messages::TestWithStream::SendAndReceiveMachSendRight>(decoder, this, &TestWithStream::sendAndReceiveMachSendRight);
+#endif
     UNUSED_PARAM(decoder);
     UNUSED_PARAM(connection);
     ASSERT_NOT_REACHED();

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamMessages.h (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamMessages.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithStreamMessages.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -29,6 +29,7 @@
 #include "MessageNames.h"
 #include "TestWithStreamMessagesReplies.h"
 #include <wtf/Forward.h>
+#include <wtf/MachSendRight.h>
 #include <wtf/ThreadSafeRefCounted.h>
 #include <wtf/text/WTFString.h>
 
@@ -46,7 +47,8 @@
     using Arguments = std::tuple<const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithStream_SendString; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
+    static constexpr bool isStreamEncodable = true;
 
     explicit SendString(const String& url)
         : m_arguments(url)
@@ -67,7 +69,9 @@
     using Arguments = std::tuple<const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithStream_SendStringSynchronized; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
+    static constexpr bool isStreamEncodable = true;
+    static constexpr bool isReplyStreamEncodable = true;
 
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
     using Reply = std::tuple<int64_t&>;
@@ -86,5 +90,80 @@
     Arguments m_arguments;
 };
 
+#if PLATFORM(COCOA)
+class SendMachSendRight {
+public:
+    using Arguments = std::tuple<const MachSendRight&>;
+
+    static IPC::MessageName name() { return IPC::MessageName::TestWithStream_SendMachSendRight; }
+    static constexpr bool isSync = false;
+    static constexpr bool isStreamEncodable = false;
+
+    explicit SendMachSendRight(const MachSendRight& a1)
+        : m_arguments(a1)
+    {
+    }
+
+    const Arguments& arguments() const
+    {
+        return m_arguments;
+    }
+
+private:
+    Arguments m_arguments;
+};
+#endif
+
+#if PLATFORM(COCOA)
+class ReceiveMachSendRight {
+public:
+    using Arguments = std::tuple<>;
+
+    static IPC::MessageName name() { return IPC::MessageName::TestWithStream_ReceiveMachSendRight; }
+    static constexpr bool isSync = true;
+    static constexpr bool isStreamEncodable = true;
+    static constexpr bool isReplyStreamEncodable = false;
+
+    static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
+    using Reply = std::tuple<MachSendRight&>;
+    using ReplyArguments = std::tuple<MachSendRight>;
+    const Arguments& arguments() const
+    {
+        return m_arguments;
+    }
+
+private:
+    Arguments m_arguments;
+};
+#endif
+
+#if PLATFORM(COCOA)
+class SendAndReceiveMachSendRight {
+public:
+    using Arguments = std::tuple<const MachSendRight&>;
+
+    static IPC::MessageName name() { return IPC::MessageName::TestWithStream_SendAndReceiveMachSendRight; }
+    static constexpr bool isSync = true;
+    static constexpr bool isStreamEncodable = false;
+    static constexpr bool isReplyStreamEncodable = false;
+
+    static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
+    using Reply = std::tuple<MachSendRight&>;
+    using ReplyArguments = std::tuple<MachSendRight>;
+    explicit SendAndReceiveMachSendRight(const MachSendRight& a1)
+        : m_arguments(a1)
+    {
+    }
+
+    const Arguments& arguments() const
+    {
+        return m_arguments;
+    }
+
+private:
+    Arguments m_arguments;
+};
+#endif
+
 } // namespace TestWithStream
 } // namespace Messages

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithSuperclassMessages.h (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithSuperclassMessages.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithSuperclassMessages.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -51,7 +51,7 @@
     using Arguments = std::tuple<const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithSuperclass_LoadURL; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit LoadURL(const String& url)
         : m_arguments(url)
@@ -73,7 +73,7 @@
     using Arguments = std::tuple<WebKit::TestTwoStateEnum>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithSuperclass_TestAsyncMessage; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     static void callReply(IPC::Decoder&, CompletionHandler<void(uint64_t&&)>&&);
     static void cancelReply(CompletionHandler<void(uint64_t&&)>&&);
@@ -104,7 +104,7 @@
     using Arguments = std::tuple<>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithSuperclass_TestAsyncMessageWithNoArguments; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     static void callReply(IPC::Decoder&, CompletionHandler<void()>&&);
     static void cancelReply(CompletionHandler<void()>&&);
@@ -130,7 +130,7 @@
     using Arguments = std::tuple<>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithSuperclass_TestAsyncMessageWithMultipleArguments; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     static void callReply(IPC::Decoder&, CompletionHandler<void(bool&&, uint64_t&&)>&&);
     static void cancelReply(CompletionHandler<void(bool&&, uint64_t&&)>&&);
@@ -156,7 +156,7 @@
     using Arguments = std::tuple<const int&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithSuperclass_TestAsyncMessageWithConnection; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     static void callReply(IPC::Decoder&, CompletionHandler<void(bool&&)>&&);
     static void cancelReply(CompletionHandler<void(bool&&)>&&);
@@ -186,7 +186,7 @@
     using Arguments = std::tuple<uint32_t>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithSuperclass_TestSyncMessage; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     using DelayedReply = TestSyncMessageDelayedReply;
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
@@ -212,7 +212,7 @@
     using Arguments = std::tuple<bool>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithSuperclass_TestSynchronousMessage; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     using DelayedReply = TestSynchronousMessageDelayedReply;
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;

Modified: trunk/Source/WebKit/Scripts/webkit/tests/TestWithoutAttributesMessages.h (274432 => 274433)


--- trunk/Source/WebKit/Scripts/webkit/tests/TestWithoutAttributesMessages.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Scripts/webkit/tests/TestWithoutAttributesMessages.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -68,7 +68,7 @@
     using Arguments = std::tuple<const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_LoadURL; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit LoadURL(const String& url)
         : m_arguments(url)
@@ -90,7 +90,7 @@
     using Arguments = std::tuple<const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_LoadSomething; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit LoadSomething(const String& url)
         : m_arguments(url)
@@ -113,7 +113,7 @@
     using Arguments = std::tuple<const WebKit::WebTouchEvent&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_TouchEvent; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit TouchEvent(const WebKit::WebTouchEvent& event)
         : m_arguments(event)
@@ -136,7 +136,7 @@
     using Arguments = std::tuple<const WebKit::WebTouchEvent&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_AddEvent; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit AddEvent(const WebKit::WebTouchEvent& event)
         : m_arguments(event)
@@ -159,7 +159,7 @@
     using Arguments = std::tuple<const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_LoadSomethingElse; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit LoadSomethingElse(const String& url)
         : m_arguments(url)
@@ -181,7 +181,7 @@
     using Arguments = std::tuple<uint64_t, uint64_t, uint32_t>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_DidReceivePolicyDecision; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     DidReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction)
         : m_arguments(frameID, listenerID, policyAction)
@@ -202,7 +202,7 @@
     using Arguments = std::tuple<>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_Close; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     const Arguments& arguments() const
     {
@@ -218,7 +218,7 @@
     using Arguments = std::tuple<const WebKit::WebPreferencesStore&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_PreferencesDidChange; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit PreferencesDidChange(const WebKit::WebPreferencesStore& store)
         : m_arguments(store)
@@ -239,7 +239,7 @@
     using Arguments = std::tuple<double, float>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_SendDoubleAndFloat; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     SendDoubleAndFloat(double d, float f)
         : m_arguments(d, f)
@@ -260,7 +260,7 @@
     using Arguments = std::tuple<const Vector<uint64_t>&, const Vector<Vector<uint64_t>>&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_SendInts; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     SendInts(const Vector<uint64_t>& ints, const Vector<Vector<uint64_t>>& intVectors)
         : m_arguments(ints, intVectors)
@@ -281,7 +281,7 @@
     using Arguments = std::tuple<uint64_t, const WebKit::Plugin::Parameters&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_CreatePlugin; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
     using Reply = std::tuple<bool&>;
@@ -305,7 +305,7 @@
     using Arguments = std::tuple<uint64_t, const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_RunJavaScriptAlert; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
     using Reply = std::tuple<>;
@@ -329,7 +329,7 @@
     using Arguments = std::tuple<bool>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_GetPlugins; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
     using Reply = std::tuple<Vector<WebCore::PluginInfo>&>;
@@ -353,7 +353,7 @@
     using Arguments = std::tuple<const String&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_GetPluginProcessConnection; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     using DelayedReply = GetPluginProcessConnectionDelayedReply;
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
@@ -379,7 +379,7 @@
     using Arguments = std::tuple<>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_TestMultipleAttributes; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     using DelayedReply = TestMultipleAttributesDelayedReply;
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
@@ -400,7 +400,7 @@
     using Arguments = std::tuple<uint64_t, double, double>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_TestParameterAttributes; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     TestParameterAttributes(uint64_t foo, double bar, double baz)
         : m_arguments(foo, bar, baz)
@@ -421,7 +421,7 @@
     using Arguments = std::tuple<const HashMap<String, std::pair<String, uint64_t>>&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_TemplateTest; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit TemplateTest(const HashMap<String, std::pair<String, uint64_t>>& a)
         : m_arguments(a)
@@ -442,7 +442,7 @@
     using Arguments = std::tuple<const WebCore::GraphicsLayer::PlatformLayerID&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_SetVideoLayerID; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit SetVideoLayerID(const WebCore::GraphicsLayer::PlatformLayerID& videoLayerID)
         : m_arguments(videoLayerID)
@@ -464,7 +464,7 @@
     using Arguments = std::tuple<const IPC::MachPort&, const OptionSet<WebKit::SelectionFlags>&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_DidCreateWebProcessConnection; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     DidCreateWebProcessConnection(const IPC::MachPort& connectionIdentifier, const OptionSet<WebKit::SelectionFlags>& flags)
         : m_arguments(connectionIdentifier, flags)
@@ -487,7 +487,7 @@
     using Arguments = std::tuple<uint32_t>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_InterpretKeyEvent; }
-    static const bool isSync = true;
+    static constexpr bool isSync = true;
 
     static constexpr auto callbackThread = WTF::CompletionHandlerCallThread::ConstructionThread;
     using Reply = std::tuple<Vector<WebCore::KeypressCommand>&>;
@@ -513,7 +513,7 @@
     using Arguments = std::tuple<const IPC::DummyType&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_DeprecatedOperation; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit DeprecatedOperation(const IPC::DummyType& dummy)
         : m_arguments(dummy)
@@ -536,7 +536,7 @@
     using Arguments = std::tuple<const IPC::DummyType&>;
 
     static IPC::MessageName name() { return IPC::MessageName::TestWithoutAttributes_ExperimentalOperation; }
-    static const bool isSync = false;
+    static constexpr bool isSync = false;
 
     explicit ExperimentalOperation(const IPC::DummyType& dummy)
         : m_arguments(dummy)

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (274432 => 274433)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp	2021-03-15 20:02:03 UTC (rev 274433)
@@ -29,6 +29,7 @@
 #include "DataReference.h"
 #include "ShareableBitmap.h"
 #include "SharedBufferDataReference.h"
+#include "StreamConnectionEncoder.h"
 #include <_javascript_Core/GenericTypedArrayViewInlines.h>
 #include <_javascript_Core/JSGenericTypedArrayViewInlines.h>
 #include <WebCore/AuthenticationChallenge.h>
@@ -741,11 +742,17 @@
     return rect;
 }
 
+template<typename Encoder>
 void ArgumentCoder<IntSize>::encode(Encoder& encoder, const IntSize& intSize)
 {
     SimpleArgumentCoder<IntSize>::encode(encoder, intSize);
 }
 
+template
+void ArgumentCoder<IntSize>::encode<Encoder>(Encoder&, const IntSize&);
+template
+void ArgumentCoder<IntSize>::encode<StreamConnectionEncoder>(StreamConnectionEncoder&, const IntSize&);
+
 bool ArgumentCoder<IntSize>::decode(Decoder& decoder, IntSize& intSize)
 {
     return SimpleArgumentCoder<IntSize>::decode(decoder, intSize);
@@ -3096,6 +3103,7 @@
 }
 #endif // ENABLE(ENCRYPTED_MEDIA)
 
+template<typename Encoder>
 void ArgumentCoder<Ref<WebCore::ImageData>>::encode(Encoder& encoder, const Ref<WebCore::ImageData>& imageData)
 {
     encoder << imageData->size();
@@ -3105,6 +3113,11 @@
     encoder.encodeFixedLengthData(rawData->data(), rawData->byteLength(), 1);
 }
 
+template
+void ArgumentCoder<Ref<WebCore::ImageData>>::encode<Encoder>(Encoder&, const Ref<WebCore::ImageData>&);
+template
+void ArgumentCoder<Ref<WebCore::ImageData>>::encode<StreamConnectionEncoder>(StreamConnectionEncoder&, const Ref<WebCore::ImageData>&);
+
 Optional<Ref<WebCore::ImageData>> ArgumentCoder<Ref<WebCore::ImageData>>::decode(Decoder& decoder)
 {
     Optional<IntSize> imageDataSize;
@@ -3128,6 +3141,7 @@
     return { imageData.releaseNonNull() };
 }
 
+template<typename Encoder>
 void ArgumentCoder<RefPtr<WebCore::ImageData>>::encode(Encoder& encoder, const RefPtr<WebCore::ImageData>& imageData)
 {
     if (!imageData) {
@@ -3139,6 +3153,12 @@
     ArgumentCoder<Ref<WebCore::ImageData>>::encode(encoder, imageData.copyRef().releaseNonNull());
 }
 
+template
+void ArgumentCoder<RefPtr<WebCore::ImageData>>::encode(Encoder&, const RefPtr<WebCore::ImageData>&);
+
+template
+void ArgumentCoder<RefPtr<WebCore::ImageData>>::encode(StreamConnectionEncoder&, const RefPtr<WebCore::ImageData>&);
+
 Optional<RefPtr<WebCore::ImageData>> ArgumentCoder<RefPtr<WebCore::ImageData>>::decode(Decoder& decoder)
 {
     bool isEngaged;
@@ -3211,6 +3231,7 @@
     return attributes;
 }
 
+template<typename Encoder>
 void ArgumentCoder<WebCore::GraphicsContextGL::ActiveInfo>::encode(Encoder& encoder, const WebCore::GraphicsContextGL::ActiveInfo& activeInfo)
 {
     encoder << activeInfo.name;
@@ -3218,6 +3239,11 @@
     encoder << activeInfo.size;
 }
 
+template
+void ArgumentCoder<WebCore::GraphicsContextGL::ActiveInfo>::encode<Encoder>(Encoder&, const WebCore::GraphicsContextGL::ActiveInfo&);
+template
+void ArgumentCoder<WebCore::GraphicsContextGL::ActiveInfo>::encode<StreamConnectionEncoder>(StreamConnectionEncoder&, const WebCore::GraphicsContextGL::ActiveInfo&);
+
 Optional<WebCore::GraphicsContextGL::ActiveInfo> ArgumentCoder<WebCore::GraphicsContextGL::ActiveInfo>::decode(Decoder& decoder)
 {
     WebCore::GraphicsContextGL::ActiveInfo activeInfo;

Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h (274432 => 274433)


--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.h	2021-03-15 20:02:03 UTC (rev 274433)
@@ -347,6 +347,7 @@
 };
 
 template<> struct ArgumentCoder<WebCore::IntSize> {
+    template<typename Encoder>
     static void encode(Encoder&, const WebCore::IntSize&);
     static WARN_UNUSED_RETURN bool decode(Decoder&, WebCore::IntSize&);
     static Optional<WebCore::IntSize> decode(Decoder&);
@@ -815,11 +816,13 @@
 #endif
 
 template<> struct ArgumentCoder<RefPtr<WebCore::ImageData>> {
+    template<typename Encoder>
     static void encode(Encoder&, const RefPtr<WebCore::ImageData>&);
     static Optional<RefPtr<WebCore::ImageData>> decode(Decoder&);
 };
 
 template<> struct ArgumentCoder<Ref<WebCore::ImageData>> {
+    template<typename Encoder>
     static void encode(Encoder&, const Ref<WebCore::ImageData>&);
     static Optional<Ref<WebCore::ImageData>> decode(Decoder&);
 };
@@ -839,6 +842,7 @@
 };
 
 template<> struct ArgumentCoder<WebCore::GraphicsContextGL::ActiveInfo> {
+    template<typename Encoder>
     static void encode(Encoder&, const WebCore::GraphicsContextGL::ActiveInfo&);
     static Optional<WebCore::GraphicsContextGL::ActiveInfo> decode(Decoder&);
 };

Modified: trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteGraphicsContextGLProxy.cpp (274432 => 274433)


--- trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteGraphicsContextGLProxy.cpp	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Source/WebKit/WebProcess/GPU/graphics/RemoteGraphicsContextGLProxy.cpp	2021-03-15 20:02:03 UTC (rev 274433)
@@ -59,6 +59,9 @@
     m_gpuProcessConnection->addClient(*this);
     m_gpuProcessConnection->messageReceiverMap().addMessageReceiver(Messages::RemoteGraphicsContextGLProxy::messageReceiverName(), m_graphicsContextGLIdentifier.toUInt64(), *this);
     connection().send(Messages::GPUConnectionToWebProcess::CreateGraphicsContextGL(attributes, m_graphicsContextGLIdentifier, renderingBackend, m_streamConnection.streamBuffer()), 0, IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply);
+    // TODO: We must wait until initialized, because at the moment we cannot receive IPC messages
+    // during wait while in synchronous stream send. Should be fixed as part of https://bugs.webkit.org/show_bug.cgi?id=217211.
+    waitUntilInitialized();
 }
 
 RemoteGraphicsContextGLProxy::~RemoteGraphicsContextGLProxy()

Modified: trunk/Tools/ChangeLog (274432 => 274433)


--- trunk/Tools/ChangeLog	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Tools/ChangeLog	2021-03-15 20:02:03 UTC (rev 274433)
@@ -1,3 +1,16 @@
+2021-03-15  Kimmo Kinnunen  <kkinnu...@apple.com>
+
+        WebGL IPC should use shared memory for synchronous messages
+        https://bugs.webkit.org/show_bug.cgi?id=220974
+        <rdar://problem/73876947>
+
+        Reviewed by Geoffrey Garen.
+
+        Mark PrepareForDisplay() as "not replyable through the stream"
+        since it replies with MachSendRight.
+
+        * Scripts/generate-gpup-webgl:
+
 2021-03-15  Youenn Fablet  <you...@apple.com>
 
         Update getUserMedia delegate to expose frame info

Modified: trunk/Tools/Scripts/generate-gpup-webgl (274432 => 274433)


--- trunk/Tools/Scripts/generate-gpup-webgl	2021-03-15 19:51:21 UTC (rev 274432)
+++ trunk/Tools/Scripts/generate-gpup-webgl	2021-03-15 20:02:03 UTC (rev 274433)
@@ -92,7 +92,7 @@
 messages -> RemoteGraphicsContextGL NotRefCounted Stream {{
     void Reshape(int32_t width, int32_t height)
 #if PLATFORM(COCOA)
-    void PrepareForDisplay() -> (MachSendRight displayBuffer) Synchronous
+    void PrepareForDisplay() -> (MachSendRight displayBuffer) Synchronous NotStreamEncodableReply
 #endif
 #if !PLATFORM(COCOA)
     void PrepareForDisplay() -> () Synchronous
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to