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