Title: [213031] releases/WebKitGTK/webkit-2.16/Source/WebKit2
Revision
213031
Author
[email protected]
Date
2017-02-26 23:52:15 -0800 (Sun, 26 Feb 2017)

Log Message

Merge r213030 - [GTK] Hangs when showing Google search results
https://bugs.webkit.org/show_bug.cgi?id=168699

Reviewed by Žan Doberšek.

Connection::sendOutgoingMessage() can poll forever if sendmsg fails with EAGAIN or EWOULDBLOCK. For example if
socket read buffers are full, poll will be blocked until we read the pending data, but we can't read because
the thread is blocked in the poll. In case of EAGAIN/EWOULDBLOCK we should poll using the run loop, to allow
reads to happen in thread while we wait for the socket to be writable again. In the GTK+ port we use
GSocketMonitor to poll socket file descriptor without blocking, using the run loop. This patch renames the
socket monitor as readSocketMonitor and adds another one for polling output. When sendmsg fails with
EAGAIN/EWOULDBLOCK, the pending message is saved and the write monitor starts polling. Once the socket is
writable again we send the pending message. Helper class MessageInfo and a new one UnixMessage have been moved
to its own header file to be able to use std::unique_ptr member to save the pending message.

* Platform/IPC/Connection.cpp: Include UnixMessage.h as required by std::unique_ptr.
* Platform/IPC/Connection.h: Add write socket monitor and also keep the GSocket as a member to reuse it.
* Platform/IPC/glib/GSocketMonitor.cpp: Use Function instead of std::function.
(IPC::GSocketMonitor::start):
* Platform/IPC/glib/GSocketMonitor.h:
* Platform/IPC/unix/ConnectionUnix.cpp:
(IPC::Connection::platformInitialize): Initialize the GSocket here since we rely on it to take the ownership of
the descriptor. We were leaking it if the connection was invalidated without being opened.
(IPC::Connection::platformInvalidate): Destroy the GSocket even when not connected. Also stop the write monitor.
(IPC::Connection::processMessage):
(IPC::Connection::open):
(IPC::Connection::platformCanSendOutgoingMessages): Return false if we have a pending message to ensure
Connection doesn't try to send more messages until the pending message is dispatched. We don't need to check
m_isConnected because the caller already checks that.
(IPC::Connection::sendOutgoingMessage): Split it in two. This creates and prepares a UnixMessage and then calls
sendOutputMessage() to do the rest.
(IPC::Connection::sendOutputMessage): Send the message, or save it if sendmsg fails with EAGAIN or EWOULDBLOCK
to be sent later when the socket is writable.
* Platform/IPC/unix/UnixMessage.h: Added.
(IPC::MessageInfo::MessageInfo):
(IPC::MessageInfo::setMessageBodyIsOutOfLine):
(IPC::MessageInfo::isMessageBodyIsOutOfLine):
(IPC::MessageInfo::bodySize):
(IPC::MessageInfo::attachmentCount):
(IPC::UnixMessage::UnixMessage):
(IPC::UnixMessage::~UnixMessage):
(IPC::UnixMessage::attachments):
(IPC::UnixMessage::messageInfo):
(IPC::UnixMessage::body):
(IPC::UnixMessage::bodySize):
(IPC::UnixMessage::appendAttachment):
* PlatformGTK.cmake:

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.16/Source/WebKit2/ChangeLog (213030 => 213031)


--- releases/WebKitGTK/webkit-2.16/Source/WebKit2/ChangeLog	2017-02-27 07:50:31 UTC (rev 213030)
+++ releases/WebKitGTK/webkit-2.16/Source/WebKit2/ChangeLog	2017-02-27 07:52:15 UTC (rev 213031)
@@ -1,3 +1,53 @@
+2017-02-26  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Hangs when showing Google search results
+        https://bugs.webkit.org/show_bug.cgi?id=168699
+
+        Reviewed by Žan Doberšek.
+
+        Connection::sendOutgoingMessage() can poll forever if sendmsg fails with EAGAIN or EWOULDBLOCK. For example if
+        socket read buffers are full, poll will be blocked until we read the pending data, but we can't read because
+        the thread is blocked in the poll. In case of EAGAIN/EWOULDBLOCK we should poll using the run loop, to allow
+        reads to happen in thread while we wait for the socket to be writable again. In the GTK+ port we use
+        GSocketMonitor to poll socket file descriptor without blocking, using the run loop. This patch renames the
+        socket monitor as readSocketMonitor and adds another one for polling output. When sendmsg fails with
+        EAGAIN/EWOULDBLOCK, the pending message is saved and the write monitor starts polling. Once the socket is
+        writable again we send the pending message. Helper class MessageInfo and a new one UnixMessage have been moved
+        to its own header file to be able to use std::unique_ptr member to save the pending message.
+
+        * Platform/IPC/Connection.cpp: Include UnixMessage.h as required by std::unique_ptr.
+        * Platform/IPC/Connection.h: Add write socket monitor and also keep the GSocket as a member to reuse it.
+        * Platform/IPC/glib/GSocketMonitor.cpp: Use Function instead of std::function.
+        (IPC::GSocketMonitor::start):
+        * Platform/IPC/glib/GSocketMonitor.h:
+        * Platform/IPC/unix/ConnectionUnix.cpp:
+        (IPC::Connection::platformInitialize): Initialize the GSocket here since we rely on it to take the ownership of
+        the descriptor. We were leaking it if the connection was invalidated without being opened.
+        (IPC::Connection::platformInvalidate): Destroy the GSocket even when not connected. Also stop the write monitor.
+        (IPC::Connection::processMessage):
+        (IPC::Connection::open):
+        (IPC::Connection::platformCanSendOutgoingMessages): Return false if we have a pending message to ensure
+        Connection doesn't try to send more messages until the pending message is dispatched. We don't need to check
+        m_isConnected because the caller already checks that.
+        (IPC::Connection::sendOutgoingMessage): Split it in two. This creates and prepares a UnixMessage and then calls
+        sendOutputMessage() to do the rest.
+        (IPC::Connection::sendOutputMessage): Send the message, or save it if sendmsg fails with EAGAIN or EWOULDBLOCK
+        to be sent later when the socket is writable.
+        * Platform/IPC/unix/UnixMessage.h: Added.
+        (IPC::MessageInfo::MessageInfo):
+        (IPC::MessageInfo::setMessageBodyIsOutOfLine):
+        (IPC::MessageInfo::isMessageBodyIsOutOfLine):
+        (IPC::MessageInfo::bodySize):
+        (IPC::MessageInfo::attachmentCount):
+        (IPC::UnixMessage::UnixMessage):
+        (IPC::UnixMessage::~UnixMessage):
+        (IPC::UnixMessage::attachments):
+        (IPC::UnixMessage::messageInfo):
+        (IPC::UnixMessage::body):
+        (IPC::UnixMessage::bodySize):
+        (IPC::UnixMessage::appendAttachment):
+        * PlatformGTK.cmake:
+
 2017-02-20  Carlos Garcia Campos  <[email protected]>
 
         Remove code under USE(GRAPHICS_SURFACE)

Modified: releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/Connection.cpp (213030 => 213031)


--- releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/Connection.cpp	2017-02-27 07:50:31 UTC (rev 213030)
+++ releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/Connection.cpp	2017-02-27 07:52:15 UTC (rev 213031)
@@ -39,6 +39,10 @@
 #include "MachMessage.h"
 #endif
 
+#if USE(UNIX_DOMAIN_SOCKETS)
+#include "UnixMessage.h"
+#endif
+
 namespace IPC {
 
 struct Connection::ReplyHandler {

Modified: releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/Connection.h (213030 => 213031)


--- releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/Connection.h	2017-02-27 07:50:31 UTC (rev 213030)
+++ releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/Connection.h	2017-02-27 07:52:15 UTC (rev 213031)
@@ -79,6 +79,7 @@
 while (0)
 
 class MachMessage;
+class UnixMessage;
 
 class Connection : public ThreadSafeRefCounted<Connection> {
 public:
@@ -308,12 +309,16 @@
     // Called on the connection queue.
     void readyReadHandler();
     bool processMessage();
+    bool sendOutputMessage(UnixMessage&);
 
     Vector<uint8_t> m_readBuffer;
     Vector<int> m_fileDescriptors;
     int m_socketDescriptor;
+    std::unique_ptr<UnixMessage> m_pendingOutputMessage;
 #if PLATFORM(GTK)
-    GSocketMonitor m_socketMonitor;
+    GRefPtr<GSocket> m_socket;
+    GSocketMonitor m_readSocketMonitor;
+    GSocketMonitor m_writeSocketMonitor;
 #endif
 #elif OS(DARWIN)
     // Called on the connection queue.

Modified: releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/glib/GSocketMonitor.cpp (213030 => 213031)


--- releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/glib/GSocketMonitor.cpp	2017-02-27 07:50:31 UTC (rev 213030)
+++ releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/glib/GSocketMonitor.cpp	2017-02-27 07:52:15 UTC (rev 213031)
@@ -42,7 +42,7 @@
     return monitor->m_callback(condition);
 }
 
-void GSocketMonitor::start(GSocket* socket, GIOCondition condition, RunLoop& runLoop, std::function<gboolean (GIOCondition)>&& callback)
+void GSocketMonitor::start(GSocket* socket, GIOCondition condition, RunLoop& runLoop, Function<gboolean (GIOCondition)>&& callback)
 {
     stop();
 

Modified: releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/glib/GSocketMonitor.h (213030 => 213031)


--- releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/glib/GSocketMonitor.h	2017-02-27 07:50:31 UTC (rev 213030)
+++ releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/glib/GSocketMonitor.h	2017-02-27 07:52:15 UTC (rev 213031)
@@ -43,7 +43,7 @@
     GSocketMonitor() = default;
     ~GSocketMonitor();
 
-    void start(GSocket*, GIOCondition, RunLoop&, std::function<gboolean (GIOCondition)>&&);
+    void start(GSocket*, GIOCondition, RunLoop&, Function<gboolean (GIOCondition)>&&);
     void stop();
 
 private:
@@ -51,7 +51,7 @@
 
     GRefPtr<GSource> m_source;
     GRefPtr<GCancellable> m_cancellable;
-    std::function<gboolean (GIOCondition)> m_callback;
+    Function<gboolean (GIOCondition)> m_callback;
 };
 
 } // namespace IPC

Modified: releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/unix/ConnectionUnix.cpp (213030 => 213031)


--- releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/unix/ConnectionUnix.cpp	2017-02-27 07:50:31 UTC (rev 213030)
+++ releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/unix/ConnectionUnix.cpp	2017-02-27 07:52:15 UTC (rev 213031)
@@ -30,6 +30,7 @@
 
 #include "DataReference.h"
 #include "SharedMemory.h"
+#include "UnixMessage.h"
 #include <sys/socket.h>
 #include <unistd.h>
 #include <errno.h>
@@ -60,53 +61,13 @@
 static const size_t messageMaxSize = 4096;
 static const size_t attachmentMaxAmount = 255;
 
-enum {
-    MessageBodyIsOutOfLine = 1U << 31
-};
-
-class MessageInfo {
-public:
-    MessageInfo() { }
-
-    MessageInfo(size_t bodySize, size_t initialAttachmentCount)
-        : m_bodySize(bodySize)
-        , m_attachmentCount(initialAttachmentCount)
-        , m_isMessageBodyOutOfLine(false)
-    {
-    }
-
-    void setMessageBodyIsOutOfLine()
-    {
-        ASSERT(!isMessageBodyIsOutOfLine());
-
-        m_isMessageBodyOutOfLine = true;
-        m_attachmentCount++;
-    }
-
-    bool isMessageBodyIsOutOfLine() const { return m_isMessageBodyOutOfLine; }
-
-    size_t bodySize() const { return m_bodySize; }
-
-    size_t attachmentCount() const { return m_attachmentCount; }
-
-private:
-    size_t m_bodySize;
-    size_t m_attachmentCount;
-    bool m_isMessageBodyOutOfLine;
-};
-
 class AttachmentInfo {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    AttachmentInfo()
-        : m_type(Attachment::Uninitialized)
-        , m_size(0)
-        , m_isNull(false)
-    {
-    }
+    AttachmentInfo() = default;
 
     void setType(Attachment::Type type) { m_type = type; }
-    Attachment::Type getType() { return m_type; }
+    Attachment::Type type() const { return m_type; }
     void setSize(size_t size)
     {
         ASSERT(m_type == Attachment::MappedMemoryType);
@@ -113,7 +74,7 @@
         m_size = size;
     }
 
-    size_t getSize()
+    size_t size() const
     {
         ASSERT(m_type == Attachment::MappedMemoryType);
         return m_size;
@@ -121,17 +82,20 @@
 
     // The attachment is not null unless explicitly set.
     void setNull() { m_isNull = true; }
-    bool isNull() { return m_isNull; }
+    bool isNull() const { return m_isNull; }
 
 private:
-    Attachment::Type m_type;
-    size_t m_size;
-    bool m_isNull;
+    Attachment::Type m_type { Attachment::Uninitialized };
+    size_t m_size { 0 };
+    bool m_isNull { false };
 };
 
 void Connection::platformInitialize(Identifier identifier)
 {
     m_socketDescriptor = identifier;
+#if PLATFORM(GTK)
+    m_socket = adoptGRef(g_socket_new_from_fd(m_socketDescriptor, nullptr));
+#endif
     m_readBuffer.reserveInitialCapacity(messageMaxSize);
     m_fileDescriptors.reserveInitialCapacity(attachmentMaxAmount);
 }
@@ -138,8 +102,10 @@
 
 void Connection::platformInvalidate()
 {
-    // In GTK+ platform the socket is closed by the work queue.
-#if !PLATFORM(GTK)
+#if PLATFORM(GTK)
+    // In GTK+ platform the socket descriptor is owned by GSocket.
+    m_socket = nullptr;
+#else
     if (m_socketDescriptor != -1)
         closeWithRetry(m_socketDescriptor);
 #endif
@@ -148,7 +114,8 @@
         return;
 
 #if PLATFORM(GTK)
-    m_socketMonitor.stop();
+    m_readSocketMonitor.stop();
+    m_writeSocketMonitor.stop();
 #endif
 
     m_socketDescriptor = -1;
@@ -165,7 +132,7 @@
     memcpy(&messageInfo, messageData, sizeof(messageInfo));
     messageData += sizeof(messageInfo);
 
-    size_t messageLength = sizeof(MessageInfo) + messageInfo.attachmentCount() * sizeof(AttachmentInfo) + (messageInfo.isMessageBodyIsOutOfLine() ? 0 : messageInfo.bodySize());
+    size_t messageLength = sizeof(MessageInfo) + messageInfo.attachmentCount() * sizeof(AttachmentInfo) + (messageInfo.isBodyOutOfLine() ? 0 : messageInfo.bodySize());
     if (m_readBuffer.size() < messageLength)
         return false;
 
@@ -179,7 +146,7 @@
         messageData += sizeof(AttachmentInfo) * attachmentCount;
 
         for (size_t i = 0; i < attachmentCount; ++i) {
-            switch (attachmentInfo[i].getType()) {
+            switch (attachmentInfo[i].type()) {
             case Attachment::MappedMemoryType:
             case Attachment::SocketType:
                 if (!attachmentInfo[i].isNull())
@@ -191,7 +158,7 @@
             }
         }
 
-        if (messageInfo.isMessageBodyIsOutOfLine())
+        if (messageInfo.isBodyOutOfLine())
             attachmentCount--;
     }
 
@@ -201,11 +168,11 @@
     size_t fdIndex = 0;
     for (size_t i = 0; i < attachmentCount; ++i) {
         int fd = -1;
-        switch (attachmentInfo[i].getType()) {
+        switch (attachmentInfo[i].type()) {
         case Attachment::MappedMemoryType:
             if (!attachmentInfo[i].isNull())
                 fd = m_fileDescriptors[fdIndex++];
-            attachments[attachmentCount - i - 1] = Attachment(fd, attachmentInfo[i].getSize());
+            attachments[attachmentCount - i - 1] = Attachment(fd, attachmentInfo[i].size());
             break;
         case Attachment::SocketType:
             if (!attachmentInfo[i].isNull())
@@ -219,7 +186,7 @@
         }
     }
 
-    if (messageInfo.isMessageBodyIsOutOfLine()) {
+    if (messageInfo.isBodyOutOfLine()) {
         ASSERT(messageInfo.bodySize());
 
         if (attachmentInfo[attachmentCount].isNull()) {
@@ -228,7 +195,7 @@
         }
 
         WebKit::SharedMemory::Handle handle;
-        handle.adoptAttachment(IPC::Attachment(m_fileDescriptors[attachmentFileDescriptorCount - 1], attachmentInfo[attachmentCount].getSize()));
+        handle.adoptAttachment(IPC::Attachment(m_fileDescriptors[attachmentFileDescriptorCount - 1], attachmentInfo[attachmentCount].size()));
 
         oolMessageBody = WebKit::SharedMemory::map(handle, WebKit::SharedMemory::Protection::ReadOnly);
         if (!oolMessageBody) {
@@ -237,10 +204,10 @@
         }
     }
 
-    ASSERT(attachments.size() == (messageInfo.isMessageBodyIsOutOfLine() ? messageInfo.attachmentCount() - 1 : messageInfo.attachmentCount()));
+    ASSERT(attachments.size() == (messageInfo.isBodyOutOfLine() ? messageInfo.attachmentCount() - 1 : messageInfo.attachmentCount()));
 
     uint8_t* messageBody = messageData;
-    if (messageInfo.isMessageBodyIsOutOfLine())
+    if (messageInfo.isBodyOutOfLine())
         messageBody = reinterpret_cast<uint8_t*>(oolMessageBody->data());
 
     auto decoder = std::make_unique<Decoder>(messageBody, messageInfo.bodySize(), nullptr, WTFMove(attachments));
@@ -365,8 +332,7 @@
     RefPtr<Connection> protectedThis(this);
     m_isConnected = true;
 #if PLATFORM(GTK)
-    GRefPtr<GSocket> socket = adoptGRef(g_socket_new_from_fd(m_socketDescriptor, nullptr));
-    m_socketMonitor.start(socket.get(), G_IO_IN, m_connectionQueue->runLoop(), [protectedThis] (GIOCondition condition) -> gboolean {
+    m_readSocketMonitor.start(m_socket.get(), G_IO_IN, m_connectionQueue->runLoop(), [protectedThis] (GIOCondition condition) -> gboolean {
         if (condition & G_IO_HUP || condition & G_IO_ERR || condition & G_IO_NVAL) {
             protectedThis->connectionDidClose();
             return G_SOURCE_REMOVE;
@@ -392,7 +358,7 @@
 
 bool Connection::platformCanSendOutgoingMessages() const
 {
-    return m_isConnected;
+    return !m_pendingOutputMessage;
 }
 
 bool Connection::sendOutgoingMessage(std::unique_ptr<Encoder> encoder)
@@ -399,15 +365,14 @@
 {
     COMPILE_ASSERT(sizeof(MessageInfo) + attachmentMaxAmount * sizeof(size_t) <= messageMaxSize, AttachmentsFitToMessageInline);
 
-    Vector<Attachment> attachments = encoder->releaseAttachments();
-    if (attachments.size() > (attachmentMaxAmount - 1)) {
+    UnixMessage outputMessage(*encoder);
+    if (outputMessage.attachments().size() > (attachmentMaxAmount - 1)) {
         ASSERT_NOT_REACHED();
         return false;
     }
 
-    MessageInfo messageInfo(encoder->bufferSize(), attachments.size());
-    size_t messageSizeWithBodyInline = sizeof(messageInfo) + (attachments.size() * sizeof(AttachmentInfo)) + encoder->bufferSize();
-    if (messageSizeWithBodyInline > messageMaxSize && encoder->bufferSize()) {
+    size_t messageSizeWithBodyInline = sizeof(MessageInfo) + (outputMessage.attachments().size() * sizeof(AttachmentInfo)) + outputMessage.bodySize();
+    if (messageSizeWithBodyInline > messageMaxSize && outputMessage.bodySize()) {
         RefPtr<WebKit::SharedMemory> oolMessageBody = WebKit::SharedMemory::allocate(encoder->bufferSize());
         if (!oolMessageBody)
             return false;
@@ -416,13 +381,21 @@
         if (!oolMessageBody->createHandle(handle, WebKit::SharedMemory::Protection::ReadOnly))
             return false;
 
-        messageInfo.setMessageBodyIsOutOfLine();
+        outputMessage.messageInfo().setBodyOutOfLine();
 
-        memcpy(oolMessageBody->data(), encoder->buffer(), encoder->bufferSize());
+        memcpy(oolMessageBody->data(), outputMessage.body(), outputMessage.bodySize());
 
-        attachments.append(handle.releaseAttachment());
+        outputMessage.appendAttachment(handle.releaseAttachment());
     }
 
+    return sendOutputMessage(outputMessage);
+}
+
+bool Connection::sendOutputMessage(UnixMessage& outputMessage)
+{
+    ASSERT(!m_pendingOutputMessage);
+
+    auto& messageInfo = outputMessage.messageInfo();
     struct msghdr message;
     memset(&message, 0, sizeof(message));
 
@@ -438,6 +411,7 @@
     std::unique_ptr<AttachmentInfo[]> attachmentInfo;
     MallocPtr<char> attachmentFDBuffer;
 
+    auto& attachments = outputMessage.attachments();
     if (!attachments.isEmpty()) {
         int* fdPtr = 0;
 
@@ -488,9 +462,9 @@
         ++iovLength;
     }
 
-    if (!messageInfo.isMessageBodyIsOutOfLine() && encoder->bufferSize()) {
-        iov[iovLength].iov_base = reinterpret_cast<void*>(encoder->buffer());
-        iov[iovLength].iov_len = encoder->bufferSize();
+    if (!messageInfo.isBodyOutOfLine() && outputMessage.bodySize()) {
+        iov[iovLength].iov_base = reinterpret_cast<void*>(outputMessage.body());
+        iov[iovLength].iov_len = outputMessage.bodySize();
         ++iovLength;
     }
 
@@ -500,6 +474,25 @@
         if (errno == EINTR)
             continue;
         if (errno == EAGAIN || errno == EWOULDBLOCK) {
+#if PLATFORM(GTK)
+            m_pendingOutputMessage = std::make_unique<UnixMessage>(WTFMove(outputMessage));
+            m_writeSocketMonitor.start(m_socket.get(), G_IO_OUT, m_connectionQueue->runLoop(), [this, protectedThis = makeRef(*this)] (GIOCondition condition) -> gboolean {
+                if (condition & G_IO_OUT) {
+                    ASSERT(m_pendingOutputMessage);
+                    // We can't stop the monitor from this lambda, because stop destroys the lambda.
+                    m_connectionQueue->dispatch([this, protectedThis = makeRef(*this)] {
+                        m_writeSocketMonitor.stop();
+                        auto message = WTFMove(m_pendingOutputMessage);
+                        if (m_isConnected) {
+                            sendOutputMessage(*message);
+                            sendOutgoingMessages();
+                        }
+                    });
+                }
+                return G_SOURCE_REMOVE;
+            });
+            return false;
+#else
             struct pollfd pollfd;
 
             pollfd.fd = m_socketDescriptor;
@@ -507,6 +500,7 @@
             pollfd.revents = 0;
             poll(&pollfd, 1, -1);
             continue;
+#endif
         }
 
         if (m_isConnected)

Added: releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/unix/UnixMessage.h (0 => 213031)


--- releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/unix/UnixMessage.h	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/Source/WebKit2/Platform/IPC/unix/UnixMessage.h	2017-02-27 07:52:15 UTC (rev 213031)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2011,2017 Igalia S.L.
+ *
+ * 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 "Attachment.h"
+#include <wtf/Vector.h>
+
+namespace IPC {
+
+class MessageInfo {
+public:
+    MessageInfo() = default;
+
+    MessageInfo(size_t bodySize, size_t initialAttachmentCount)
+        : m_bodySize(bodySize)
+        , m_attachmentCount(initialAttachmentCount)
+    {
+    }
+
+    void setBodyOutOfLine()
+    {
+        ASSERT(!isBodyOutOfLine());
+
+        m_isBodyOutOfLine = true;
+        m_attachmentCount++;
+    }
+
+    bool isBodyOutOfLine() const { return m_isBodyOutOfLine; }
+    size_t bodySize() const { return m_bodySize; }
+    size_t attachmentCount() const { return m_attachmentCount; }
+
+private:
+    size_t m_bodySize { 0 };
+    size_t m_attachmentCount { 0 };
+    bool m_isBodyOutOfLine { false };
+};
+
+class UnixMessage {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    UnixMessage(Encoder& encoder)
+        : m_attachments(encoder.releaseAttachments())
+        , m_messageInfo(encoder.bufferSize(), m_attachments.size())
+        , m_body(encoder.buffer())
+    {
+    }
+
+    UnixMessage(UnixMessage&& other)
+    {
+        m_attachments = WTFMove(other.m_attachments);
+        m_messageInfo = WTFMove(other.m_messageInfo);
+        if (other.m_bodyOwned) {
+            std::swap(m_body, other.m_body);
+            std::swap(m_bodyOwned, other.m_bodyOwned);
+        } else if (!m_messageInfo.isBodyOutOfLine()) {
+            m_body = static_cast<uint8_t*>(fastMalloc(m_messageInfo.bodySize()));
+            memcpy(m_body, other.m_body, m_messageInfo.bodySize());
+            m_bodyOwned = true;
+            other.m_body = nullptr;
+            other.m_bodyOwned = false;
+        }
+    }
+
+    ~UnixMessage()
+    {
+        if (m_bodyOwned)
+            fastFree(m_body);
+    }
+
+    const Vector<Attachment>& attachments() const { return m_attachments; }
+    MessageInfo& messageInfo() { return m_messageInfo; }
+
+    uint8_t* body() const { return m_body; }
+    size_t bodySize() const  { return m_messageInfo.bodySize(); }
+
+    void appendAttachment(Attachment&& attachment)
+    {
+        m_attachments.append(WTFMove(attachment));
+    }
+
+private:
+    Vector<Attachment> m_attachments;
+    MessageInfo m_messageInfo;
+    uint8_t* m_body { nullptr };
+    bool m_bodyOwned { false };
+};
+
+} // namespace IPC

Modified: releases/WebKitGTK/webkit-2.16/Source/WebKit2/PlatformGTK.cmake (213030 => 213031)


--- releases/WebKitGTK/webkit-2.16/Source/WebKit2/PlatformGTK.cmake	2017-02-27 07:50:31 UTC (rev 213030)
+++ releases/WebKitGTK/webkit-2.16/Source/WebKit2/PlatformGTK.cmake	2017-02-27 07:52:15 UTC (rev 213031)
@@ -850,6 +850,7 @@
     "${WEBKIT2_DIR}/NetworkProcess/soup"
     "${WEBKIT2_DIR}/NetworkProcess/unix"
     "${WEBKIT2_DIR}/Platform/IPC/glib"
+    "${WEBKIT2_DIR}/Platform/IPC/unix"
     "${WEBKIT2_DIR}/Shared/API/c/gtk"
     "${WEBKIT2_DIR}/Shared/Plugins/unix"
     "${WEBKIT2_DIR}/Shared/glib"
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to