Title: [226252] trunk/Source/WebCore
Revision
226252
Author
beid...@apple.com
Date
2017-12-21 17:17:45 -0800 (Thu, 21 Dec 2017)

Log Message

Refactor MessagePortChannel family classes for an easier multi-process split.
https://bugs.webkit.org/show_bug.cgi?id=180981

Reviewed by Andy Estes.

No new tests (Refactor, no behavior change)

- Make MessagePortChannel an abstract class instead of a wrapper around a mysterious "platform" class.
- Implement the "in-process" channel for WK1 and WK2-for-now.
- Other random cleanup and modernization of this code.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:

* dom/InProcessMessagePortChannel.cpp: Added.
(WebCore::InProcessMessagePortChannel::createChannelBetweenPorts):
(WebCore::InProcessMessagePortChannel::create):
(WebCore::InProcessMessagePortChannel::InProcessMessagePortChannel):
(WebCore::InProcessMessagePortChannel::~InProcessMessagePortChannel):
(WebCore::InProcessMessagePortChannel::postMessageToRemote):
(WebCore::InProcessMessagePortChannel::takeAllMessagesFromRemote):
(WebCore::InProcessMessagePortChannel::isConnectedTo):
(WebCore::InProcessMessagePortChannel::entangleIfOpen):
(WebCore::InProcessMessagePortChannel::disentangle):
(WebCore::InProcessMessagePortChannel::hasPendingActivity):
(WebCore::InProcessMessagePortChannel::locallyEntangledPort):
(WebCore::InProcessMessagePortChannel::takeEntangledChannel):
(WebCore::InProcessMessagePortChannel::close):
(WebCore::InProcessMessagePortChannel::setRemotePort):
* dom/InProcessMessagePortChannel.h: Added.
(WebCore::InProcessMessagePortChannel::MessagePortQueue::create):
(WebCore::InProcessMessagePortChannel::MessagePortQueue::takeAllMessages):
(WebCore::InProcessMessagePortChannel::MessagePortQueue::appendAndCheckEmpty):
(WebCore::InProcessMessagePortChannel::MessagePortQueue::isEmpty):
(WebCore::InProcessMessagePortChannel::MessagePortQueue::MessagePortQueue):

* dom/MessageChannel.cpp:
(WebCore::MessageChannel::MessageChannel):
* dom/MessageChannel.h:
(WebCore::MessageChannel::create):
(WebCore::MessageChannel::port1 const):
(WebCore::MessageChannel::port2 const):

* dom/MessagePort.cpp:
(WebCore::MessagePort::postMessage):
(WebCore::MessagePort::disentangle):
(WebCore::MessagePort::entangle):
(WebCore::MessagePort::hasPendingActivity const):
* dom/MessagePort.h:

* dom/MessagePortChannel.cpp: Added.
(WebCore::MessagePortChannel::createChannelBetweenPorts):
(WebCore::MessagePortChannel::MessagePortChannel):
* dom/MessagePortChannel.h:
(WebCore::MessagePortChannel::EventData::EventData):
(WebCore::MessagePortChannel::~MessagePortChannel):

* dom/default/PlatformMessagePortChannel.cpp: Removed.
* dom/default/PlatformMessagePortChannel.h: Removed.
* workers/service/context/ServiceWorkerThread.h:

Modified Paths

Added Paths

Removed Paths

  • trunk/Source/WebCore/dom/default/

Diff

Modified: trunk/Source/WebCore/ChangeLog (226251 => 226252)


--- trunk/Source/WebCore/ChangeLog	2017-12-22 01:10:32 UTC (rev 226251)
+++ trunk/Source/WebCore/ChangeLog	2017-12-22 01:17:45 UTC (rev 226252)
@@ -1,3 +1,66 @@
+2017-12-21  Brady Eidson  <beid...@apple.com>
+
+        Refactor MessagePortChannel family classes for an easier multi-process split.
+        https://bugs.webkit.org/show_bug.cgi?id=180981
+
+        Reviewed by Andy Estes.
+
+        No new tests (Refactor, no behavior change)
+
+        - Make MessagePortChannel an abstract class instead of a wrapper around a mysterious "platform" class.
+        - Implement the "in-process" channel for WK1 and WK2-for-now.
+        - Other random cleanup and modernization of this code.
+        
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        
+        * dom/InProcessMessagePortChannel.cpp: Added.
+        (WebCore::InProcessMessagePortChannel::createChannelBetweenPorts):
+        (WebCore::InProcessMessagePortChannel::create):
+        (WebCore::InProcessMessagePortChannel::InProcessMessagePortChannel):
+        (WebCore::InProcessMessagePortChannel::~InProcessMessagePortChannel):
+        (WebCore::InProcessMessagePortChannel::postMessageToRemote):
+        (WebCore::InProcessMessagePortChannel::takeAllMessagesFromRemote):
+        (WebCore::InProcessMessagePortChannel::isConnectedTo):
+        (WebCore::InProcessMessagePortChannel::entangleIfOpen):
+        (WebCore::InProcessMessagePortChannel::disentangle):
+        (WebCore::InProcessMessagePortChannel::hasPendingActivity):
+        (WebCore::InProcessMessagePortChannel::locallyEntangledPort):
+        (WebCore::InProcessMessagePortChannel::takeEntangledChannel):
+        (WebCore::InProcessMessagePortChannel::close):
+        (WebCore::InProcessMessagePortChannel::setRemotePort):
+        * dom/InProcessMessagePortChannel.h: Added.
+        (WebCore::InProcessMessagePortChannel::MessagePortQueue::create):
+        (WebCore::InProcessMessagePortChannel::MessagePortQueue::takeAllMessages):
+        (WebCore::InProcessMessagePortChannel::MessagePortQueue::appendAndCheckEmpty):
+        (WebCore::InProcessMessagePortChannel::MessagePortQueue::isEmpty):
+        (WebCore::InProcessMessagePortChannel::MessagePortQueue::MessagePortQueue):
+        
+        * dom/MessageChannel.cpp:
+        (WebCore::MessageChannel::MessageChannel):
+        * dom/MessageChannel.h:
+        (WebCore::MessageChannel::create):
+        (WebCore::MessageChannel::port1 const):
+        (WebCore::MessageChannel::port2 const):
+        
+        * dom/MessagePort.cpp:
+        (WebCore::MessagePort::postMessage):
+        (WebCore::MessagePort::disentangle):
+        (WebCore::MessagePort::entangle):
+        (WebCore::MessagePort::hasPendingActivity const):
+        * dom/MessagePort.h:
+        
+        * dom/MessagePortChannel.cpp: Added.
+        (WebCore::MessagePortChannel::createChannelBetweenPorts):
+        (WebCore::MessagePortChannel::MessagePortChannel):
+        * dom/MessagePortChannel.h:
+        (WebCore::MessagePortChannel::EventData::EventData):
+        (WebCore::MessagePortChannel::~MessagePortChannel):
+        
+        * dom/default/PlatformMessagePortChannel.cpp: Removed.
+        * dom/default/PlatformMessagePortChannel.h: Removed.
+        * workers/service/context/ServiceWorkerThread.h:
+
 2017-12-21  Ryosuke Niwa  <rn...@webkit.org>
 
         Rename NoEventDispatchAssertion to ScriptDisallowedScope

Modified: trunk/Source/WebCore/Sources.txt (226251 => 226252)


--- trunk/Source/WebCore/Sources.txt	2017-12-22 01:10:32 UTC (rev 226251)
+++ trunk/Source/WebCore/Sources.txt	2017-12-22 01:17:45 UTC (rev 226252)
@@ -727,6 +727,7 @@
 dom/GenericEventQueue.cpp
 dom/IdTargetObserver.cpp
 dom/IdTargetObserverRegistry.cpp
+dom/InProcessMessagePortChannel.cpp
 dom/InlineClassicScript.cpp
 dom/InlineStyleSheetOwner.cpp
 dom/InputEvent.cpp
@@ -738,6 +739,7 @@
 dom/MessageChannel.cpp
 dom/MessageEvent.cpp
 dom/MessagePort.cpp
+dom/MessagePortChannel.cpp
 dom/Microtasks.cpp
 dom/MouseEvent.cpp
 dom/MouseRelatedEvent.cpp
@@ -812,8 +814,6 @@
 dom/WebKitTransitionEvent.cpp
 dom/WheelEvent.cpp
 
-dom/default/PlatformMessagePortChannel.cpp
-
 domjit/DOMJITHelpers.cpp
 domjit/JSDocumentDOMJIT.cpp
 domjit/JSDocumentFragmentDOMJIT.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (226251 => 226252)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-12-22 01:10:32 UTC (rev 226251)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2017-12-22 01:17:45 UTC (rev 226252)
@@ -1043,7 +1043,6 @@
 		41B28B3D1F860EF300FB52AC /* LibWebRTCProviderCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 41B28B361F860BD000FB52AC /* LibWebRTCProviderCocoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		41B2A6261EF1BF6D002B9D7A /* WebAudioSourceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 41B2A6251EF1BF60002B9D7A /* WebAudioSourceProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		41BF700C0FE86F49005E8DEC /* MessagePortChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 41BF700A0FE86F49005E8DEC /* MessagePortChannel.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		41BF70100FE86F61005E8DEC /* PlatformMessagePortChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 41BF700E0FE86F61005E8DEC /* PlatformMessagePortChannel.h */; };
 		41C760B10EDE03D300C1655F /* ScriptState.h in Headers */ = {isa = PBXBuildFile; fileRef = 41C760B00EDE03D300C1655F /* ScriptState.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		41CAD71E1EA090A100178164 /* VideoToolBoxEncoderFactory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 41CAD71C1EA0905700178164 /* VideoToolBoxEncoderFactory.cpp */; };
 		41D015CA0F4B5C71004A662F /* ContentType.h in Headers */ = {isa = PBXBuildFile; fileRef = 41D015C80F4B5C71004A662F /* ContentType.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1289,6 +1288,7 @@
 		511EC12C1C50ABBF0032F983 /* SQLiteIDBTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 511EC12A1C50ABBA0032F983 /* SQLiteIDBTransaction.h */; };
 		511EC1301C50ABF50032F983 /* SQLiteIDBCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 511EC12E1C50ABEC0032F983 /* SQLiteIDBCursor.h */; };
 		5120BBAF1F1CECE700EFEBF1 /* CookieStorageObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 5120BBAD1F1CE77000EFEBF1 /* CookieStorageObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		512B57C01FE99083000A1E5E /* InProcessMessagePortChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 512B57BC1FE9902C000A1E5E /* InProcessMessagePortChannel.h */; };
 		512BDB4B1C456FFA006494DF /* SQLiteIDBBackingStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 512BDB491C456FAB006494DF /* SQLiteIDBBackingStore.h */; };
 		512DD8F50D91E6AF000F89EE /* LegacyWebArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = 512DD8EB0D91E6AF000F89EE /* LegacyWebArchive.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		512DD8F60D91E6AF000F89EE /* Archive.h in Headers */ = {isa = PBXBuildFile; fileRef = 512DD8EC0D91E6AF000F89EE /* Archive.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -7060,8 +7060,6 @@
 		41B459DA1F4CADB90000F6FD /* ReadableStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReadableStream.h; sourceTree = "<group>"; };
 		41B459ED1F55EBC70000F6FD /* ReadableStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReadableStream.cpp; sourceTree = "<group>"; };
 		41BF700A0FE86F49005E8DEC /* MessagePortChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessagePortChannel.h; sourceTree = "<group>"; };
-		41BF700D0FE86F61005E8DEC /* PlatformMessagePortChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PlatformMessagePortChannel.cpp; path = default/PlatformMessagePortChannel.cpp; sourceTree = "<group>"; };
-		41BF700E0FE86F61005E8DEC /* PlatformMessagePortChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlatformMessagePortChannel.h; path = default/PlatformMessagePortChannel.h; sourceTree = "<group>"; };
 		41C760B00EDE03D300C1655F /* ScriptState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptState.h; sourceTree = "<group>"; };
 		41C7E1051E6A54360027B4DE /* CanvasCaptureMediaStreamTrack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CanvasCaptureMediaStreamTrack.cpp; sourceTree = "<group>"; };
 		41C7E1061E6A54360027B4DE /* CanvasCaptureMediaStreamTrack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CanvasCaptureMediaStreamTrack.h; sourceTree = "<group>"; };
@@ -7572,6 +7570,9 @@
 		5123AF161890A4CA0031CDC9 /* IDBKeyRangeData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBKeyRangeData.cpp; sourceTree = "<group>"; };
 		5123AF171890A4CA0031CDC9 /* IDBKeyRangeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBKeyRangeData.h; sourceTree = "<group>"; };
 		5123AF1C18918AE40031CDC9 /* IDBGetResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBGetResult.h; sourceTree = "<group>"; };
+		512B57BC1FE9902C000A1E5E /* InProcessMessagePortChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InProcessMessagePortChannel.h; sourceTree = "<group>"; };
+		512B57BE1FE9902D000A1E5E /* MessagePortChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MessagePortChannel.cpp; sourceTree = "<group>"; };
+		512B57BF1FE9902E000A1E5E /* InProcessMessagePortChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InProcessMessagePortChannel.cpp; sourceTree = "<group>"; };
 		512BDB481C456FAB006494DF /* SQLiteIDBBackingStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLiteIDBBackingStore.cpp; sourceTree = "<group>"; };
 		512BDB491C456FAB006494DF /* SQLiteIDBBackingStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLiteIDBBackingStore.h; sourceTree = "<group>"; };
 		512BDB4C1C46B0FF006494DF /* JSIDBCursorCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBCursorCustom.cpp; sourceTree = "<group>"; };
@@ -25372,6 +25373,8 @@
 				C3CF17A315B0063F00276D39 /* IdTargetObserverRegistry.h */,
 				8AB4BC76126FDB7100DEB727 /* IgnoreDestructiveWriteCountIncrementer.h */,
 				467302011C4EFE6600BCB357 /* IgnoreOpensDuringUnloadCountIncrementer.h */,
+				512B57BF1FE9902E000A1E5E /* InProcessMessagePortChannel.cpp */,
+				512B57BC1FE9902C000A1E5E /* InProcessMessagePortChannel.h */,
 				E30592611E27A38C00D57C98 /* InlineClassicScript.cpp */,
 				E30592621E27A38C00D57C98 /* InlineClassicScript.h */,
 				AA4C3A740B2B1679002334A2 /* InlineStyleSheetOwner.cpp */,
@@ -25402,6 +25405,7 @@
 				E1ADECBE0E76ACF1004A1A5E /* MessagePort.cpp */,
 				E1ADECBD0E76ACF1004A1A5E /* MessagePort.h */,
 				E1ADECC60E76AD1F004A1A5E /* MessagePort.idl */,
+				512B57BE1FE9902D000A1E5E /* MessagePortChannel.cpp */,
 				41BF700A0FE86F49005E8DEC /* MessagePortChannel.h */,
 				CB8CF0151A934B43000D510B /* Microtasks.cpp */,
 				53B895AD19DC7C37009CAA93 /* Microtasks.h */,
@@ -25466,8 +25470,6 @@
 				8A7CC96F12076F8A001D4588 /* PendingScript.cpp */,
 				8A7CC96A12076D73001D4588 /* PendingScript.h */,
 				E3FA38611D716E7600AA5950 /* PendingScriptClient.h */,
-				41BF700D0FE86F61005E8DEC /* PlatformMessagePortChannel.cpp */,
-				41BF700E0FE86F61005E8DEC /* PlatformMessagePortChannel.h */,
 				5189F0DD10B46B0E00F3C739 /* PopStateEvent.cpp */,
 				5174E20810A1F44F00F95E6F /* PopStateEvent.h */,
 				5174E20B10A1F49A00F95E6F /* PopStateEvent.idl */,
@@ -29756,6 +29758,7 @@
 				A5B81CB51FAA44620037D1E6 /* WebConsoleAgent.h in Headers */,
 				9BBA2CAB1F679E0C00FD1C1E /* WebContentReader.h in Headers */,
 				419BE7591BC7F42B00E1C85B /* WebCoreBuiltinNames.h in Headers */,
+				512B57C01FE99083000A1E5E /* InProcessMessagePortChannel.h in Headers */,
 				2D3EF44A1917915C00034184 /* WebCoreCALayerExtras.h in Headers */,
 				515F79541CFCA3D500CCED93 /* WebCoreCrossThreadCopier.h in Headers */,
 				CD5D27781E8318E000D80A3D /* WebCoreDecompressionSession.h in Headers */,

Added: trunk/Source/WebCore/dom/InProcessMessagePortChannel.cpp (0 => 226252)


--- trunk/Source/WebCore/dom/InProcessMessagePortChannel.cpp	                        (rev 0)
+++ trunk/Source/WebCore/dom/InProcessMessagePortChannel.cpp	2017-12-22 01:17:45 UTC (rev 226252)
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InProcessMessagePortChannel.h"
+
+#include "MessagePort.h"
+#include <wtf/Locker.h>
+
+namespace WebCore {
+
+void InProcessMessagePortChannel::createChannelBetweenPorts(MessagePort& port1, MessagePort& port2)
+{
+    auto queue1 = MessagePortQueue::create();
+    auto queue2 = MessagePortQueue::create();
+
+    auto channel1 = InProcessMessagePortChannel::create(queue1.get(), queue2.get());
+    auto channel2 = InProcessMessagePortChannel::create(queue2.get(), queue1.get());
+
+    channel1->m_entangledChannel = channel2.ptr();
+    channel2->m_entangledChannel = channel1.ptr();
+
+    port1.entangle(WTFMove(channel2));
+    port2.entangle(WTFMove(channel1));
+}
+
+Ref<InProcessMessagePortChannel> InProcessMessagePortChannel::create(MessagePortQueue& incoming, MessagePortQueue& outgoing)
+{
+    return adoptRef(*new InProcessMessagePortChannel(incoming, outgoing));
+}
+
+InProcessMessagePortChannel::InProcessMessagePortChannel(MessagePortQueue& incoming, MessagePortQueue& outgoing)
+    : m_incomingQueue(&incoming)
+    , m_outgoingQueue(&outgoing)
+{
+}
+
+InProcessMessagePortChannel::~InProcessMessagePortChannel()
+{
+    // Channels being destroyed should to have been closed.
+    ASSERT(!m_outgoingQueue);
+}
+
+void InProcessMessagePortChannel::postMessageToRemote(Ref<SerializedScriptValue>&& message, std::unique_ptr<MessagePortChannelArray>&& channels)
+{
+    Locker<Lock> locker(m_lock);
+
+    if (!m_outgoingQueue)
+        return;
+
+    bool wasEmpty = m_outgoingQueue->appendAndCheckEmpty(std::make_unique<EventData>(WTFMove(message), WTFMove(channels)));
+    if (wasEmpty && m_remotePort)
+        m_remotePort->messageAvailable();
+}
+
+Deque<std::unique_ptr<MessagePortChannel::EventData>> InProcessMessagePortChannel::takeAllMessagesFromRemote()
+{
+    Locker<Lock> locker(m_lock);
+    return m_incomingQueue->takeAllMessages();
+}
+
+bool InProcessMessagePortChannel::isConnectedTo(MessagePort& port)
+{
+    // FIXME: What guarantees that the result remains the same after we release the lock?
+    Locker<Lock> locker(m_lock);
+    return m_remotePort == &port;
+}
+
+bool InProcessMessagePortChannel::entangleIfOpen(MessagePort& port)
+{
+    // We can't call member functions on our remote pair while holding our mutex or we'll deadlock,
+    // but we need to guard against the remote port getting closed/freed, so create a standalone reference.
+    RefPtr<InProcessMessagePortChannel> remote;
+    {
+        Locker<Lock> locker(m_lock);
+        remote = m_entangledChannel;
+    }
+
+    if (!remote)
+        return false;
+
+    remote->setRemotePort(&port);
+
+    return true;
+}
+
+void InProcessMessagePortChannel::disentangle()
+{
+    Locker<Lock> locker(m_lock);
+
+    if (m_entangledChannel)
+        m_entangledChannel->setRemotePort(nullptr);
+}
+
+bool InProcessMessagePortChannel::hasPendingActivity()
+{
+    // FIXME: What guarantees that the result remains the same after we release the lock?
+    Locker<Lock> locker(m_lock);
+    return !m_incomingQueue->isEmpty();
+}
+
+MessagePort* InProcessMessagePortChannel::locallyEntangledPort(const ScriptExecutionContext* context)
+{
+    Locker<Lock> locker(m_lock);
+
+    // See if both contexts are run by the same thread (are the same context, or are both documents).
+    if (!m_remotePort)
+        return nullptr;
+
+    // The remote port's ScriptExecutionContext is guaranteed not to change here - MessagePort::contextDestroyed()
+    // will close the port before the context goes away, and close() will block because we are holding the mutex.
+    ScriptExecutionContext* remoteContext = m_remotePort->scriptExecutionContext();
+    if (remoteContext == context || (remoteContext && remoteContext->isDocument() && context->isDocument()))
+        return m_remotePort;
+
+    return nullptr;
+}
+
+RefPtr<InProcessMessagePortChannel> InProcessMessagePortChannel::takeEntangledChannel()
+{
+    RefPtr<InProcessMessagePortChannel> channel;
+
+    {
+        Locker<Lock> locker(m_lock);
+        channel = WTFMove(m_entangledChannel);
+    }
+
+    return channel;
+}
+
+void InProcessMessagePortChannel::close()
+{
+    Locker<Lock> locker(m_lock);
+
+    RefPtr<InProcessMessagePortChannel> channel;
+    if (m_entangledChannel) {
+        channel = m_entangledChannel->takeEntangledChannel();
+        ASSERT(channel == this);
+        m_entangledChannel->close();
+    }
+
+    // Disentangle ourselves from the other end. We still maintain a reference to our incoming queue, since previously-existing messages should still be delivered.
+    m_remotePort = nullptr;
+    m_outgoingQueue = nullptr;
+    m_entangledChannel = nullptr;
+}
+
+void InProcessMessagePortChannel::setRemotePort(MessagePort* port)
+{
+    Locker<Lock> locker(m_lock);
+
+    // Should never set port if it is already set.
+    ASSERT(!port || !m_remotePort);
+
+    m_remotePort = port;
+}
+
+} // namespace WebCore

Added: trunk/Source/WebCore/dom/InProcessMessagePortChannel.h (0 => 226252)


--- trunk/Source/WebCore/dom/InProcessMessagePortChannel.h	                        (rev 0)
+++ trunk/Source/WebCore/dom/InProcessMessagePortChannel.h	2017-12-22 01:17:45 UTC (rev 226252)
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "MessagePortChannel.h"
+#include <wtf/MessageQueue.h>
+
+namespace WebCore {
+
+class InProcessMessagePortChannel : public MessagePortChannel {
+public:
+    static void createChannelBetweenPorts(MessagePort&, MessagePort&);
+
+    ~InProcessMessagePortChannel() final;
+
+    void postMessageToRemote(Ref<SerializedScriptValue>&&, std::unique_ptr<MessagePortChannelArray>&&) final;
+    Deque<std::unique_ptr<EventData>> takeAllMessagesFromRemote() final;
+    bool isConnectedTo(MessagePort&) final;
+    bool entangleIfOpen(MessagePort&) final;
+    void disentangle() final;
+    bool hasPendingActivity() final;
+    MessagePort* locallyEntangledPort(const ScriptExecutionContext*) final;
+    void close() final;
+
+private:
+    // Wrapper for MessageQueue that allows us to do thread safe sharing by two proxies.
+    class MessagePortQueue : public ThreadSafeRefCounted<MessagePortQueue> {
+    public:
+        static Ref<MessagePortQueue> create() { return adoptRef(*new MessagePortQueue()); }
+
+        Deque<std::unique_ptr<MessagePortChannel::EventData>> takeAllMessages()
+        {
+            return m_queue.takeAllMessages();
+        }
+
+        bool appendAndCheckEmpty(std::unique_ptr<MessagePortChannel::EventData>&& message)
+        {
+            return m_queue.appendAndCheckEmpty(WTFMove(message));
+        }
+
+        bool isEmpty()
+        {
+            return m_queue.isEmpty();
+        }
+
+    private:
+        MessagePortQueue() { }
+
+        MessageQueue<MessagePortChannel::EventData> m_queue;
+    };
+
+    static Ref<InProcessMessagePortChannel> create(MessagePortQueue& incoming, MessagePortQueue& outgoing);
+    InProcessMessagePortChannel(MessagePortQueue& incoming, MessagePortQueue& outgoing);
+
+    void setRemotePort(MessagePort*);
+    RefPtr<InProcessMessagePortChannel> takeEntangledChannel();
+
+    Lock m_lock;
+
+    RefPtr<InProcessMessagePortChannel> m_entangledChannel;
+
+    RefPtr<MessagePortQueue> m_incomingQueue;
+    RefPtr<MessagePortQueue> m_outgoingQueue;
+
+    MessagePort* m_remotePort { nullptr };
+};
+
+} // namespace WebCore

Modified: trunk/Source/WebCore/dom/MessageChannel.cpp (226251 => 226252)


--- trunk/Source/WebCore/dom/MessageChannel.cpp	2017-12-22 01:10:32 UTC (rev 226251)
+++ trunk/Source/WebCore/dom/MessageChannel.cpp	2017-12-22 01:17:45 UTC (rev 226252)
@@ -36,7 +36,7 @@
     : m_port1(MessagePort::create(context))
     , m_port2(MessagePort::create(context))
 {
-    MessagePortChannel::createChannel(m_port1.get(), m_port2.get());
+    MessagePortChannel::createChannelBetweenPorts(*m_port1, *m_port2);
 }
 
 MessageChannel::~MessageChannel() = default;

Modified: trunk/Source/WebCore/dom/MessageChannel.h (226251 => 226252)


--- trunk/Source/WebCore/dom/MessageChannel.h	2017-12-22 01:10:32 UTC (rev 226251)
+++ trunk/Source/WebCore/dom/MessageChannel.h	2017-12-22 01:17:45 UTC (rev 226252)
@@ -31,22 +31,22 @@
 
 namespace WebCore {
 
-    class MessagePort;
-    class ScriptExecutionContext;
+class MessagePort;
+class ScriptExecutionContext;
 
-    class MessageChannel : public RefCounted<MessageChannel> {
-    public:
-        static Ref<MessageChannel> create(ScriptExecutionContext& context) { return adoptRef(*new MessageChannel(context)); }
-        ~MessageChannel();
+class MessageChannel : public RefCounted<MessageChannel> {
+public:
+    static Ref<MessageChannel> create(ScriptExecutionContext& context) { return adoptRef(*new MessageChannel(context)); }
+    ~MessageChannel();
 
-        MessagePort* port1() const { return m_port1.get(); }
-        MessagePort* port2() const { return m_port2.get(); }
+    MessagePort* port1() const { return m_port1.get(); }
+    MessagePort* port2() const { return m_port2.get(); }
 
-    private:
-        explicit MessageChannel(ScriptExecutionContext&);
+private:
+    explicit MessageChannel(ScriptExecutionContext&);
 
-        RefPtr<MessagePort> m_port1;
-        RefPtr<MessagePort> m_port2;
-    };
+    RefPtr<MessagePort> m_port1;
+    RefPtr<MessagePort> m_port2;
+};
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/dom/MessagePort.cpp (226251 => 226252)


--- trunk/Source/WebCore/dom/MessagePort.cpp	2017-12-22 01:10:32 UTC (rev 226251)
+++ trunk/Source/WebCore/dom/MessagePort.cpp	2017-12-22 01:17:45 UTC (rev 226252)
@@ -65,7 +65,7 @@
     // Make sure we aren't connected to any of the passed-in ports.
     if (!ports.isEmpty()) {
         for (auto& dataPort : ports) {
-            if (dataPort == this || m_entangledChannel->isConnectedTo(dataPort.get()))
+            if (dataPort == this || m_entangledChannel->isConnectedTo(*dataPort))
                 return Exception { DataCloneError };
         }
         auto disentangleResult = MessagePort::disentanglePorts(WTFMove(ports));
@@ -77,7 +77,7 @@
     return { };
 }
 
-std::unique_ptr<MessagePortChannel> MessagePort::disentangle()
+RefPtr<MessagePortChannel> MessagePort::disentangle()
 {
     ASSERT(m_entangledChannel);
 
@@ -123,7 +123,7 @@
     m_closed = true;
 }
 
-void MessagePort::entangle(std::unique_ptr<MessagePortChannel>&& remote)
+void MessagePort::entangle(RefPtr<MessagePortChannel>&& remote)
 {
     // Only invoked to set our initial entanglement.
     ASSERT(!m_entangledChannel);
@@ -130,7 +130,7 @@
     ASSERT(m_scriptExecutionContext);
 
     // Don't entangle the ports if the channel is closed.
-    if (remote->entangleIfOpen(this))
+    if (remote->entangleIfOpen(*this))
         m_entangledChannel = WTFMove(remote);
 }
 
@@ -171,8 +171,10 @@
     // We'll also stipulate that the queue needs to be open (if the app drops its reference to the port before start()-ing it, then it's not really entangled as it's unreachable).
     if (m_started && m_entangledChannel && m_entangledChannel->hasPendingActivity())
         return true;
+
     if (isEntangled() && !locallyEntangledPort())
         return true;
+
     return false;
 }
 

Modified: trunk/Source/WebCore/dom/MessagePort.h (226251 => 226252)


--- trunk/Source/WebCore/dom/MessagePort.h	2017-12-22 01:10:32 UTC (rev 226251)
+++ trunk/Source/WebCore/dom/MessagePort.h	2017-12-22 01:17:45 UTC (rev 226252)
@@ -41,7 +41,7 @@
 
 class Frame;
 
-class MessagePort final : public RefCounted<MessagePort>, public ActiveDOMObject, public EventTargetWithInlineData {
+class MessagePort final : public ThreadSafeRefCounted<MessagePort>, public ActiveDOMObject, public EventTargetWithInlineData {
 public:
     static Ref<MessagePort> create(ScriptExecutionContext& scriptExecutionContext) { return adoptRef(*new MessagePort(scriptExecutionContext)); }
     virtual ~MessagePort();
@@ -51,7 +51,7 @@
     void start();
     void close();
 
-    void entangle(std::unique_ptr<MessagePortChannel>&&);
+    void entangle(RefPtr<MessagePortChannel>&&);
 
     // Returns nullptr if the passed-in vector is empty.
     static ExceptionOr<std::unique_ptr<MessagePortChannelArray>> disentanglePorts(Vector<RefPtr<MessagePort>>&&);
@@ -68,8 +68,8 @@
     // of the remote port (since it may live cross-process) - those platforms may always return null.
     MessagePort* locallyEntangledPort() const;
 
-    using RefCounted::ref;
-    using RefCounted::deref;
+    using ThreadSafeRefCounted::ref;
+    using ThreadSafeRefCounted::deref;
 
     // ActiveDOMObject
     const char* activeDOMObjectName() const final;
@@ -89,7 +89,7 @@
 
     bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) final;
 
-    std::unique_ptr<MessagePortChannel> disentangle();
+    RefPtr<MessagePortChannel> disentangle();
 
     // A port starts out its life entangled, and remains entangled until it is closed or is cloned.
     bool isEntangled() const { return !m_closed && !isNeutered(); }
@@ -97,7 +97,8 @@
     // A port gets neutered when it is transferred to a new owner via postMessage().
     bool isNeutered() const { return !m_entangledChannel; }
 
-    std::unique_ptr<MessagePortChannel> m_entangledChannel;
+    RefPtr<MessagePortChannel> m_entangledChannel;
+    RefPtr<MessagePort> m_messageProtector;
     bool m_started { false };
     bool m_closed { false };
 };

Added: trunk/Source/WebCore/dom/MessagePortChannel.cpp (0 => 226252)


--- trunk/Source/WebCore/dom/MessagePortChannel.cpp	                        (rev 0)
+++ trunk/Source/WebCore/dom/MessagePortChannel.cpp	2017-12-22 01:17:45 UTC (rev 226252)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER OR 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 "MessagePortChannel.h"
+
+#include "InProcessMessagePortChannel.h"
+#include "MessagePort.h"
+#include "ScriptExecutionContext.h"
+
+namespace WebCore {
+
+void MessagePortChannel::createChannelBetweenPorts(MessagePort& port1, MessagePort& port2)
+{
+    // FIXME: Later this will become client-configurable.
+    // e.g. WK1 will use the InProcessMessagePortChannel, but WK2 will install a multi-process aware channel.
+    InProcessMessagePortChannel::createChannelBetweenPorts(port1, port2);
+}
+
+MessagePortChannel::MessagePortChannel()
+{
+}
+
+} // namespace WebCore
+

Modified: trunk/Source/WebCore/dom/MessagePortChannel.h (226251 => 226252)


--- trunk/Source/WebCore/dom/MessagePortChannel.h	2017-12-22 01:10:32 UTC (rev 226251)
+++ trunk/Source/WebCore/dom/MessagePortChannel.h	2017-12-22 01:17:45 UTC (rev 226252)
@@ -39,63 +39,41 @@
 
 namespace WebCore {
 
-    class MessagePort;
-    class MessagePortChannel;
-    class PlatformMessagePortChannel;
-    class ScriptExecutionContext;
+class MessagePort;
+class MessagePortChannel;
+class ScriptExecutionContext;
 
-    // The overwhelmingly common case is sending a single port, so handle that efficiently with an inline buffer of size 1.
-    typedef Vector<std::unique_ptr<MessagePortChannel>, 1> MessagePortChannelArray;
+// The overwhelmingly common case is sending a single port, so handle that efficiently with an inline buffer of size 1.
+typedef Vector<RefPtr<MessagePortChannel>, 1> MessagePortChannelArray;
 
-    // MessagePortChannel is a platform-independent interface to the remote side of a message channel.
-    // It acts as a wrapper around the platform-dependent PlatformMessagePortChannel implementation which ensures that the platform-dependent close() method is invoked before destruction.
-    class MessagePortChannel {
-        WTF_MAKE_NONCOPYABLE(MessagePortChannel); WTF_MAKE_FAST_ALLOCATED;
-    public:
-        struct EventData {
-            EventData(Ref<SerializedScriptValue>&& message, std::unique_ptr<MessagePortChannelArray>&& channels)
-                : message(WTFMove(message))
-                , channels(WTFMove(channels))
-            { }
+class MessagePortChannel : public ThreadSafeRefCounted<MessagePortChannel> {
+    WTF_MAKE_NONCOPYABLE(MessagePortChannel); WTF_MAKE_FAST_ALLOCATED;
+public:
+    struct EventData {
+        EventData(Ref<SerializedScriptValue>&& message, std::unique_ptr<MessagePortChannelArray>&& channels)
+            : message(WTFMove(message))
+            , channels(WTFMove(channels))
+        { }
 
-            Ref<SerializedScriptValue> message;
-            std::unique_ptr<MessagePortChannelArray> channels;
-        };
+        Ref<SerializedScriptValue> message;
+        std::unique_ptr<MessagePortChannelArray> channels;
+    };
 
-        explicit MessagePortChannel(RefPtr<PlatformMessagePortChannel>&&);
-        static void createChannel(MessagePort*, MessagePort*);
+    MessagePortChannel();
+    virtual ~MessagePortChannel() { }
 
-        // Entangles the channel with a port (called when a port has been cloned, after the clone has been marshaled to its new owning thread and is ready to receive messages).
-        // Returns false if the entanglement failed because the port was closed.
-        bool entangleIfOpen(MessagePort*);
+    static void createChannelBetweenPorts(MessagePort&, MessagePort&);
 
-        // Disentangles the channel from a given port so it no longer forwards messages to the port. Called when the port is being cloned and no new owning thread has yet been established.
-        void disentangle();
+    void setRemotePort(MessagePort*);
 
-        // Closes the port (ensures that no further messages can be added to either queue).
-        void close();
+    virtual void postMessageToRemote(Ref<SerializedScriptValue>&&, std::unique_ptr<MessagePortChannelArray>&&) = 0;
+    virtual Deque<std::unique_ptr<EventData>> takeAllMessagesFromRemote() = 0;
+    virtual bool isConnectedTo(MessagePort&) = 0;
+    virtual bool entangleIfOpen(MessagePort&) = 0;
+    virtual void disentangle() = 0;
+    virtual bool hasPendingActivity() = 0;
+    virtual MessagePort* locallyEntangledPort(const ScriptExecutionContext*) = 0;
+    virtual void close() = 0;
+};
 
-        // Used by MessagePort.postMessage() to prevent callers from passing a port's own entangled port.
-        bool isConnectedTo(MessagePort*);
-
-        // Returns true if the proxy currently contains messages for this port.
-        bool hasPendingActivity();
-
-        // Sends a message and optional cloned port to the remote port.
-        void postMessageToRemote(Ref<SerializedScriptValue>&&, std::unique_ptr<MessagePortChannelArray>&&);
-
-        // Extracts a message from the message queue for this port.
-        std::unique_ptr<EventData> takeMessageFromRemote();
-
-        Deque<std::unique_ptr<EventData>> takeAllMessagesFromRemote();
-
-        // Returns the entangled port if run by the same thread (see MessagePort::locallyEntangledPort() for more details).
-        MessagePort* locallyEntangledPort(const ScriptExecutionContext*);
-
-        WEBCORE_EXPORT ~MessagePortChannel();
-
-    private:
-        RefPtr<PlatformMessagePortChannel> m_channel;
-    };
-
 } // namespace WebCore

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h (226251 => 226252)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h	2017-12-22 01:10:32 UTC (rev 226251)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThread.h	2017-12-22 01:17:45 UTC (rev 226252)
@@ -44,7 +44,7 @@
 struct ServiceWorkerClientIdentifier;
 struct ServiceWorkerContextData;
 
-using MessagePortChannelArray = Vector<std::unique_ptr<MessagePortChannel>, 1>;
+using MessagePortChannelArray = Vector<RefPtr<MessagePortChannel>, 1>;
 
 class ServiceWorkerThread : public WorkerThread {
 public:
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to