Title: [224351] trunk/Source/WebKit
Revision
224351
Author
[email protected]
Date
2017-11-02 13:18:31 -0700 (Thu, 02 Nov 2017)

Log Message

[WinCairo] Add IPC files for wincairo webkit
https://bugs.webkit.org/show_bug.cgi?id=177919

Patch by Yousuke Kimoto <[email protected]> on 2017-11-02
Reviewed by Alex Christensen.

* Platform/IPC/Attachment.cpp:
* Platform/IPC/Attachment.h:
(IPC::Attachment::Attachment):
(IPC::Attachment::handle):
* Platform/IPC/Connection.h:
(IPC::Connection::identifierIsNull):
(IPC::Connection::sendWithReply):
* Platform/IPC/win/AttachmentWin.cpp: Added.
(IPC::Attachment::encode const):
(IPC::getDuplicatedHandle):
(IPC::Attachment::decode):
* Platform/IPC/win/ConnectionWin.cpp: Added.
(IPC::Connection::createServerAndClientIdentifiers):
(IPC::Connection::platformInitialize):
(IPC::Connection::platformInvalidate):
(IPC::Connection::readEventHandler):
(IPC::Connection::writeEventHandler):
(IPC::Connection::open):
(IPC::Connection::platformCanSendOutgoingMessages const):
(IPC::Connection::sendOutgoingMessage):
(IPC::Connection::willSendSyncMessage):
(IPC::Connection::didReceiveSyncReply):
* PlatformWin.cmake:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (224350 => 224351)


--- trunk/Source/WebKit/ChangeLog	2017-11-02 19:24:42 UTC (rev 224350)
+++ trunk/Source/WebKit/ChangeLog	2017-11-02 20:18:31 UTC (rev 224351)
@@ -1,3 +1,34 @@
+2017-11-02  Yousuke Kimoto  <[email protected]>
+
+        [WinCairo] Add IPC files for wincairo webkit
+        https://bugs.webkit.org/show_bug.cgi?id=177919
+
+        Reviewed by Alex Christensen.
+
+        * Platform/IPC/Attachment.cpp:
+        * Platform/IPC/Attachment.h:
+        (IPC::Attachment::Attachment):
+        (IPC::Attachment::handle):
+        * Platform/IPC/Connection.h:
+        (IPC::Connection::identifierIsNull):
+        (IPC::Connection::sendWithReply):
+        * Platform/IPC/win/AttachmentWin.cpp: Added.
+        (IPC::Attachment::encode const):
+        (IPC::getDuplicatedHandle):
+        (IPC::Attachment::decode):
+        * Platform/IPC/win/ConnectionWin.cpp: Added.
+        (IPC::Connection::createServerAndClientIdentifiers):
+        (IPC::Connection::platformInitialize):
+        (IPC::Connection::platformInvalidate):
+        (IPC::Connection::readEventHandler):
+        (IPC::Connection::writeEventHandler):
+        (IPC::Connection::open):
+        (IPC::Connection::platformCanSendOutgoingMessages const):
+        (IPC::Connection::sendOutgoingMessage):
+        (IPC::Connection::willSendSyncMessage):
+        (IPC::Connection::didReceiveSyncReply):
+        * PlatformWin.cmake:
+
 2017-11-02  Megan Gardner  <[email protected]>
 
         Early out selection update when data is not present

Modified: trunk/Source/WebKit/Platform/IPC/Attachment.cpp (224350 => 224351)


--- trunk/Source/WebKit/Platform/IPC/Attachment.cpp	2017-11-02 19:24:42 UTC (rev 224350)
+++ trunk/Source/WebKit/Platform/IPC/Attachment.cpp	2017-11-02 20:18:31 UTC (rev 224351)
@@ -50,6 +50,7 @@
 }
 #endif
 
+#if !OS(WINDOWS)
 void Attachment::encode(Encoder& encoder) const
 {
     encoder.addAttachment(WTFMove(*const_cast<Attachment*>(this)));
@@ -61,5 +62,6 @@
         return false;
     return true;
 }
+#endif
 
 } // namespace IPC

Modified: trunk/Source/WebKit/Platform/IPC/Attachment.h (224350 => 224351)


--- trunk/Source/WebKit/Platform/IPC/Attachment.h	2017-11-02 19:24:42 UTC (rev 224350)
+++ trunk/Source/WebKit/Platform/IPC/Attachment.h	2017-11-02 20:18:31 UTC (rev 224351)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2017 Sony Interactive Entertainment Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,8 +24,7 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef Attachment_h
-#define Attachment_h
+# pragma once
 
 #if OS(DARWIN) && !USE(UNIX_DOMAIN_SOCKETS)
 #include <mach/mach_init.h>
@@ -58,6 +58,10 @@
     ~Attachment();
 #elif OS(DARWIN)
     Attachment(mach_port_name_t, mach_msg_type_name_t disposition);
+#elif OS(WINDOWS)
+    Attachment(HANDLE handle)
+        : m_handle(handle)
+    { }
 #endif
 
     Type type() const { return m_type; }
@@ -73,6 +77,8 @@
     // MachPortType
     mach_port_name_t port() const { return m_port; }
     mach_msg_type_name_t disposition() const { return m_disposition; }
+#elif OS(WINDOWS)
+    HANDLE handle() { return m_handle; }
 #endif
 
     void encode(Encoder&) const;
@@ -87,9 +93,9 @@
 #elif OS(DARWIN)
     mach_port_name_t m_port;
     mach_msg_type_name_t m_disposition;
+#elif OS(WINDOWS)
+    HANDLE m_handle;
 #endif
 };
 
 } // namespace IPC
-
-#endif // Attachment_h

Modified: trunk/Source/WebKit/Platform/IPC/Connection.h (224350 => 224351)


--- trunk/Source/WebKit/Platform/IPC/Connection.h	2017-11-02 19:24:42 UTC (rev 224350)
+++ trunk/Source/WebKit/Platform/IPC/Connection.h	2017-11-02 20:18:31 UTC (rev 224351)
@@ -2,6 +2,7 @@
  * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
  * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
+ * Copyright (C) 2017 Sony Interactive Entertainment Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -135,6 +136,10 @@
     xpc_connection_t xpcConnection() const { return m_xpcConnection.get(); }
     bool getAuditToken(audit_token_t&);
     pid_t remoteProcessID() const;
+#elif OS(WINDOWS)
+    typedef HANDLE Identifier;
+    static bool createServerAndClientIdentifiers(Identifier& serverIdentifier, Identifier& clientIdentifier);
+    static bool identifierIsNull(Identifier identifier) { return !identifier; }
 #endif
 
     static Ref<Connection> createServerConnection(Identifier, Client&);
@@ -144,7 +149,7 @@
     Client& client() const { return m_client; }
 
     void setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(bool);
-    void setShouldExitOnSyncMessageSendFailure(bool shouldExitOnSyncMessageSendFailure);
+    void setShouldExitOnSyncMessageSendFailure(bool);
 
     // The set callback will be called on the connection work queue when the connection is closed, 
     // before didCall is called on the client thread. Must be called before the connection is opened.
@@ -152,7 +157,7 @@
     // on the work queue, for example if we want to handle them on some other thread we could avoid
     // handling the message on the client thread first.
     typedef void (*DidCloseOnConnectionWorkQueueCallback)(Connection*);
-    void setDidCloseOnConnectionWorkQueueCallback(DidCloseOnConnectionWorkQueueCallback callback);
+    void setDidCloseOnConnectionWorkQueueCallback(DidCloseOnConnectionWorkQueueCallback);
 
     void addWorkQueueMessageReceiver(StringReference messageReceiverName, WorkQueue&, WorkQueueMessageReceiver*);
     void removeWorkQueueMessageReceiver(StringReference messageReceiverName);
@@ -164,12 +169,12 @@
     void postConnectionDidCloseOnConnectionWorkQueue();
 
     template<typename T> bool send(T&& message, uint64_t destinationID, OptionSet<SendOption> sendOptions = { });
-    template<typename T> void sendWithReply(T&& message, uint64_t destinationID, FunctionDispatcher& replyDispatcher, Function<void (std::optional<typename CodingType<typename T::Reply>::Type>)>&& replyHandler);
+    template<typename T> void sendWithReply(T&& message, uint64_t destinationID, FunctionDispatcher& replyDispatcher, Function<void(std::optional<typename CodingType<typename T::Reply>::Type>)>&& replyHandler);
     template<typename T> bool sendSync(T&& message, typename T::Reply&& reply, uint64_t destinationID, Seconds timeout = Seconds::infinity(), OptionSet<SendSyncOption> sendSyncOptions = { });
     template<typename T> bool waitForAndDispatchImmediately(uint64_t destinationID, Seconds timeout, OptionSet<WaitForOption> waitForOptions = { });
 
     bool sendMessage(std::unique_ptr<Encoder>, OptionSet<SendOption> sendOptions);
-    void sendMessageWithReply(uint64_t requestID, std::unique_ptr<Encoder>, FunctionDispatcher& replyDispatcher, Function<void (std::unique_ptr<Decoder>)>&& replyHandler);
+    void sendMessageWithReply(uint64_t requestID, std::unique_ptr<Encoder>, FunctionDispatcher& replyDispatcher, Function<void(std::unique_ptr<Decoder>)>&& replyHandler);
     std::unique_ptr<Encoder> createSyncMessageEncoder(StringReference messageReceiverName, StringReference messageName, uint64_t destinationID, uint64_t& syncRequestID);
     std::unique_ptr<Decoder> sendSyncMessage(uint64_t syncRequestID, std::unique_ptr<Encoder>, Seconds timeout, OptionSet<SendSyncOption> sendSyncOptions);
     bool sendSyncReply(std::unique_ptr<Encoder>);
@@ -194,7 +199,7 @@
     void setShouldBoostMainThreadOnSyncMessage(bool b) { m_shouldBoostMainThreadOnSyncMessage = b; }
 #endif
 
-    uint64_t installIncomingSyncMessageCallback(WTF::Function<void ()>&&);
+    uint64_t installIncomingSyncMessageCallback(WTF::Function<void()>&&);
     void uninstallIncomingSyncMessageCallback(uint64_t);
     bool hasIncomingSyncMessage();
 
@@ -292,7 +297,7 @@
     Vector<PendingSyncReply> m_pendingSyncReplies;
 
     Lock m_incomingSyncMessageCallbackMutex;
-    HashMap<uint64_t, WTF::Function<void ()>> m_incomingSyncMessageCallbacks;
+    HashMap<uint64_t, WTF::Function<void()>> m_incomingSyncMessageCallbacks;
     RefPtr<WorkQueue> m_incomingSyncMessageCallbackQueue;
     uint64_t m_nextIncomingSyncMessageCallbackID { 0 };
 
@@ -330,6 +335,16 @@
     std::unique_ptr<MachMessage> m_pendingOutgoingMachMessage;
 
     OSObjectPtr<xpc_connection_t> m_xpcConnection;
+#elif OS(WINDOWS)
+    // Called on the connection queue.
+    void readEventHandler();
+    void writeEventHandler();
+
+    Vector<uint8_t> m_readBuffer;
+    OVERLAPPED m_readState;
+    std::unique_ptr<Encoder> m_pendingWriteEncoder;
+    OVERLAPPED m_writeState;
+    HANDLE m_connectionPipe;
 #endif
 };
 
@@ -345,7 +360,7 @@
 }
 
 template<typename T>
-void Connection::sendWithReply(T&& message, uint64_t destinationID, FunctionDispatcher& replyDispatcher, Function<void (std::optional<typename CodingType<typename T::Reply>::Type>)>&& replyHandler)
+void Connection::sendWithReply(T&& message, uint64_t destinationID, FunctionDispatcher& replyDispatcher, Function<void(std::optional<typename CodingType<typename T::Reply>::Type>)>&& replyHandler)
 {
     uint64_t requestID = 0;
     std::unique_ptr<Encoder> encoder = createSyncMessageEncoder(T::receiverName(), T::name(), destinationID, requestID);

Added: trunk/Source/WebKit/Platform/IPC/win/AttachmentWin.cpp (0 => 224351)


--- trunk/Source/WebKit/Platform/IPC/win/AttachmentWin.cpp	                        (rev 0)
+++ trunk/Source/WebKit/Platform/IPC/win/AttachmentWin.cpp	2017-11-02 20:18:31 UTC (rev 224351)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2017 Konstantin Tokarev <[email protected]>
+ * Copyright (C) 2017 Sony Interactive Entertainment Inc.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "Attachment.h"
+
+#include "Decoder.h"
+#include "Encoder.h"
+
+// FIXME: This code is duplicated with SharedMemory::Handle implementation for Win
+
+namespace IPC {
+
+void Attachment::encode(Encoder& encoder) const
+{
+    // Hand off ownership of our HANDLE to the receiving process. It will close it for us.
+    // FIXME: If the receiving process crashes before it receives the memory, the memory will be
+    // leaked. See <http://webkit.org/b/47502>.
+    encoder << reinterpret_cast<uint64_t>(m_handle);
+
+    // Send along our PID so that the receiving process can duplicate the HANDLE for its own use.
+    encoder << static_cast<uint32_t>(::GetCurrentProcessId());
+}
+
+static bool getDuplicatedHandle(HANDLE sourceHandle, DWORD sourcePID, HANDLE& duplicatedHandle)
+{
+    duplicatedHandle = 0;
+    if (!sourceHandle)
+        return true;
+
+    HANDLE sourceProcess = ::OpenProcess(PROCESS_DUP_HANDLE, FALSE, sourcePID);
+    if (!sourceProcess)
+        return false;
+
+    // Copy the handle into our process and close the handle that the sending process created for us.
+    BOOL success = ::DuplicateHandle(sourceProcess, sourceHandle, ::GetCurrentProcess(), &duplicatedHandle, 0, FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
+    ASSERT_WITH_MESSAGE(success, "::DuplicateHandle failed with error %lu", ::GetLastError());
+
+    ::CloseHandle(sourceProcess);
+
+    return success;
+}
+
+bool Attachment::decode(Decoder& decoder, Attachment& attachment)
+{
+    ASSERT_ARG(attachment, !attachment.m_handle);
+
+    uint64_t sourceHandle;
+    if (!decoder.decode(sourceHandle))
+        return false;
+
+    uint32_t sourcePID;
+    if (!decoder.decode(sourcePID))
+        return false;
+
+    HANDLE duplicatedHandle;
+    if (!getDuplicatedHandle(reinterpret_cast<HANDLE>(sourceHandle), sourcePID, duplicatedHandle))
+        return false;
+
+    attachment.m_handle = duplicatedHandle;
+    return true;
+}
+
+} // namespace IPC

Added: trunk/Source/WebKit/Platform/IPC/win/ConnectionWin.cpp (0 => 224351)


--- trunk/Source/WebKit/Platform/IPC/win/ConnectionWin.cpp	                        (rev 0)
+++ trunk/Source/WebKit/Platform/IPC/win/ConnectionWin.cpp	2017-11-02 20:18:31 UTC (rev 224351)
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2017 Sony Interactive Entertainment Inc.
+ *
+ * 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.
+ */
+
+#include "config.h"
+#include "Connection.h"
+
+#include "DataReference.h"
+#include <wtf/RandomNumber.h>
+#include <wtf/text/WTFString.h>
+#include <wtf/threads/BinarySemaphore.h>
+
+using namespace std;
+
+namespace IPC {
+
+// FIXME: Rename this or use a different constant on windows.
+static const size_t inlineMessageMaxSize = 4096;
+
+bool Connection::createServerAndClientIdentifiers(HANDLE& serverIdentifier, HANDLE& clientIdentifier)
+{
+    String pipeName;
+
+    do {
+        unsigned uniqueID = randomNumber() * std::numeric_limits<unsigned>::max();
+        pipeName = String::format("\\\\.\\pipe\\com.apple.WebKit.%x", uniqueID);
+
+        serverIdentifier = ::CreateNamedPipe(pipeName.charactersWithNullTermination().data(),
+            PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
+            PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1, inlineMessageMaxSize, inlineMessageMaxSize,
+            0, 0);
+    } while (!serverIdentifier && ::GetLastError() == ERROR_PIPE_BUSY);
+
+    if (!serverIdentifier)
+        return false;
+
+    clientIdentifier = ::CreateFileW(pipeName.charactersWithNullTermination().data(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
+    if (!clientIdentifier) {
+        ::CloseHandle(serverIdentifier);
+        return false;
+    }
+
+    DWORD mode = PIPE_READMODE_MESSAGE;
+    if (!::SetNamedPipeHandleState(clientIdentifier, &mode, 0, 0)) {
+        ::CloseHandle(serverIdentifier);
+        ::CloseHandle(clientIdentifier);
+        return false;
+    }
+
+    return true;
+}
+
+void Connection::platformInitialize(Identifier identifier)
+{
+    memset(&m_readState, 0, sizeof(m_readState));
+    m_readState.hEvent = ::CreateEventW(0, FALSE, FALSE, 0);
+
+    memset(&m_writeState, 0, sizeof(m_writeState));
+    m_writeState.hEvent = ::CreateEventW(0, FALSE, FALSE, 0);
+
+    m_connectionPipe = identifier;
+}
+
+void Connection::platformInvalidate()
+{
+    if (m_connectionPipe == INVALID_HANDLE_VALUE)
+        return;
+
+    m_isConnected = false;
+
+    m_connectionQueue->unregisterAndCloseHandle(m_readState.hEvent);
+    m_readState.hEvent = 0;
+
+    m_connectionQueue->unregisterAndCloseHandle(m_writeState.hEvent);
+    m_writeState.hEvent = 0;
+
+    ::CloseHandle(m_connectionPipe);
+    m_connectionPipe = INVALID_HANDLE_VALUE;
+}
+
+void Connection::readEventHandler()
+{
+    if (m_connectionPipe == INVALID_HANDLE_VALUE)
+        return;
+
+    while (true) {
+        // Check if we got some data.
+        DWORD numberOfBytesRead = 0;
+        if (!::GetOverlappedResult(m_connectionPipe, &m_readState, &numberOfBytesRead, FALSE)) {
+            DWORD error = ::GetLastError();
+            switch (error) {
+            case ERROR_BROKEN_PIPE:
+                connectionDidClose();
+                return;
+            case ERROR_MORE_DATA: {
+                // Read the rest of the message out of the pipe.
+
+                DWORD bytesToRead = 0;
+                if (!::PeekNamedPipe(m_connectionPipe, 0, 0, 0, 0, &bytesToRead)) {
+                    DWORD error = ::GetLastError();
+                    if (error == ERROR_BROKEN_PIPE) {
+                        connectionDidClose();
+                        return;
+                    }
+                    ASSERT_NOT_REACHED();
+                    return;
+                }
+
+                // ::GetOverlappedResult told us there's more data. ::PeekNamedPipe shouldn't
+                // contradict it!
+                ASSERT(bytesToRead);
+                if (!bytesToRead)
+                    break;
+
+                m_readBuffer.grow(m_readBuffer.size() + bytesToRead);
+                if (!::ReadFile(m_connectionPipe, m_readBuffer.data() + numberOfBytesRead, bytesToRead, 0, &m_readState)) {
+                    DWORD error = ::GetLastError();
+                    ASSERT_NOT_REACHED();
+                    return;
+                }
+                continue;
+            }
+
+            // FIXME: We should figure out why we're getting this error.
+            case ERROR_IO_INCOMPLETE:
+                return;
+            default:
+                ASSERT_NOT_REACHED();
+            }
+        }
+
+        if (!m_readBuffer.isEmpty()) {
+            // We have a message, let's dispatch it.
+            Vector<Attachment> attachments(0);
+            auto decoder = std::make_unique<Decoder>(m_readBuffer.data(), m_readBuffer.size(), nullptr, WTFMove(attachments));
+            processIncomingMessage(WTFMove(decoder));
+        }
+
+        // Find out the size of the next message in the pipe (if there is one) so that we can read
+        // it all in one operation. (This is just an optimization to avoid an extra pass through the
+        // loop (if we chose a buffer size that was too small) or allocating extra memory (if we
+        // chose a buffer size that was too large).)
+        DWORD bytesToRead = 0;
+        if (!::PeekNamedPipe(m_connectionPipe, 0, 0, 0, 0, &bytesToRead)) {
+            DWORD error = ::GetLastError();
+            if (error == ERROR_BROKEN_PIPE) {
+                connectionDidClose();
+                return;
+            }
+            ASSERT_NOT_REACHED();
+        }
+        if (!bytesToRead) {
+            // There's no message waiting in the pipe. Schedule a read of the first byte of the
+            // next message. We'll find out the message's actual size when it arrives. (If we
+            // change this to read more than a single byte for performance reasons, we'll have to
+            // deal with m_readBuffer potentially being larger than the message we read after
+            // calling ::GetOverlappedResult above.)
+            bytesToRead = 1;
+        }
+
+        m_readBuffer.resize(bytesToRead);
+
+        // Either read the next available message (which should occur synchronously), or start an
+        // asynchronous read of the next message that becomes available.
+        BOOL result = ::ReadFile(m_connectionPipe, m_readBuffer.data(), m_readBuffer.size(), 0, &m_readState);
+        if (result) {
+            // There was already a message waiting in the pipe, and we read it synchronously.
+            // Process it.
+            continue;
+        }
+
+        DWORD error = ::GetLastError();
+
+        if (error == ERROR_IO_PENDING) {
+            // There are no messages in the pipe currently. readEventHandler will be called again once there is a message.
+            return;
+        }
+
+        if (error == ERROR_MORE_DATA) {
+            // Either a message is available when we didn't think one was, or the message is larger
+            // than ::PeekNamedPipe told us. The former seems far more likely. Probably the message
+            // became available between our calls to ::PeekNamedPipe and ::ReadFile above. Go back
+            // to the top of the loop to use ::GetOverlappedResult to retrieve the available data.
+            continue;
+        }
+
+        // FIXME: We need to handle other errors here.
+        ASSERT_NOT_REACHED();
+    }
+}
+
+void Connection::writeEventHandler()
+{
+    if (m_connectionPipe == INVALID_HANDLE_VALUE)
+        return;
+
+    DWORD numberOfBytesWritten = 0;
+    if (!::GetOverlappedResult(m_connectionPipe, &m_writeState, &numberOfBytesWritten, FALSE)) {
+        DWORD error = ::GetLastError();
+
+        if (error == ERROR_IO_INCOMPLETE) {
+            // FIXME: We should figure out why we're getting this error.
+            return;
+        }
+        if (error == ERROR_BROKEN_PIPE) {
+            connectionDidClose();
+            return;
+        }
+        ASSERT_NOT_REACHED();
+    }
+
+    // The pending write has finished, so we are now done with its encoder. Clearing this member
+    // will allow us to send messages again.
+    m_pendingWriteEncoder = nullptr;
+
+    // Now that the pending write has finished, we can try to send a new message.
+    sendOutgoingMessages();
+}
+
+bool Connection::open()
+{
+    // We connected the two ends of the pipe in createServerAndClientIdentifiers.
+    m_isConnected = true;
+
+    RefPtr<Connection> protectedThis(this);
+
+    // Start listening for read and write state events.
+    m_connectionQueue->registerHandle(m_readState.hEvent, [protectedThis] {
+        protectedThis->readEventHandler();
+    });
+
+    m_connectionQueue->registerHandle(m_writeState.hEvent, [protectedThis] {
+        protectedThis->writeEventHandler();
+    });
+
+    // Schedule a read.
+    m_connectionQueue->dispatch([protectedThis] {
+        protectedThis->readEventHandler();
+    });
+    return true;
+}
+
+bool Connection::platformCanSendOutgoingMessages() const
+{
+    // We only allow sending one asynchronous message at a time. If we wanted to send more than one
+    // at once, we'd have to use multiple OVERLAPPED structures and hold onto multiple pending
+    // MessageEncoders (one of each for each simultaneous asynchronous message).
+    return !m_pendingWriteEncoder;
+}
+
+bool Connection::sendOutgoingMessage(std::unique_ptr<Encoder> encoder)
+{
+    ASSERT(!m_pendingWriteEncoder);
+
+    // Just bail if the handle has been closed.
+    if (m_connectionPipe == INVALID_HANDLE_VALUE)
+        return false;
+
+    // We put the message ID last.
+    *encoder << 0;
+
+    // Write the outgoing message.
+
+    if (::WriteFile(m_connectionPipe, encoder->buffer(), encoder->bufferSize(), 0, &m_writeState)) {
+        // We successfully sent this message.
+        return true;
+    }
+
+    DWORD error = ::GetLastError();
+
+    if (error == ERROR_NO_DATA) {
+        // The pipe is being closed.
+        connectionDidClose();
+        return false;
+    }
+
+    if (error != ERROR_IO_PENDING) {
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+
+    // The message will be sent soon. Hold onto the encoder so that it won't be destroyed
+    // before the write completes.
+    m_pendingWriteEncoder = WTFMove(encoder);
+
+    // We can only send one asynchronous message at a time (see comment in platformCanSendOutgoingMessages).
+    return false;
+}
+
+void Connection::willSendSyncMessage(OptionSet<SendSyncOption>)
+{
+}
+
+void Connection::didReceiveSyncReply(OptionSet<SendSyncOption>)
+{
+}
+
+} // namespace IPC

Modified: trunk/Source/WebKit/PlatformWin.cmake (224350 => 224351)


--- trunk/Source/WebKit/PlatformWin.cmake	2017-11-02 19:24:42 UTC (rev 224350)
+++ trunk/Source/WebKit/PlatformWin.cmake	2017-11-02 20:18:31 UTC (rev 224351)
@@ -25,6 +25,9 @@
 
     Shared/curl/WebCoreArgumentCodersCurl.cpp
 
+    Platform/IPC/win/AttachmentWin.cpp
+    Platform/IPC/win/ConnectionWin.cpp
+
     StorageProcess/win/StorageProcessMainWin.cpp
 
     WebProcess/Cookies/curl/WebCookieManagerCurl.cpp
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to