Refactor MessagePortChannel family classes for an easier multi-process split.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Dec 2017 01:17:45 +0000 (01:17 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Dec 2017 01:17:45 +0000 (01:17 +0000)
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:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226252 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/InProcessMessagePortChannel.cpp [new file with mode: 0644]
Source/WebCore/dom/InProcessMessagePortChannel.h [new file with mode: 0644]
Source/WebCore/dom/MessageChannel.cpp
Source/WebCore/dom/MessageChannel.h
Source/WebCore/dom/MessagePort.cpp
Source/WebCore/dom/MessagePort.h
Source/WebCore/dom/MessagePortChannel.cpp [new file with mode: 0644]
Source/WebCore/dom/MessagePortChannel.h
Source/WebCore/dom/default/PlatformMessagePortChannel.cpp [deleted file]
Source/WebCore/dom/default/PlatformMessagePortChannel.h [deleted file]
Source/WebCore/workers/service/context/ServiceWorkerThread.h

index f20fa7f..f6102db 100644 (file)
@@ -1,3 +1,66 @@
+2017-12-21  Brady Eidson  <beidson@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  <rniwa@webkit.org>
 
         Rename NoEventDispatchAssertion to ScriptDisallowedScope
index 78f3a86..913ef35 100644 (file)
@@ -727,6 +727,7 @@ dom/FocusEvent.cpp
 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/LoadableScript.cpp
 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/WebKitAnimationEvent.cpp
 dom/WebKitTransitionEvent.cpp
 dom/WheelEvent.cpp
 
-dom/default/PlatformMessagePortChannel.cpp
-
 domjit/DOMJITHelpers.cpp
 domjit/JSDocumentDOMJIT.cpp
 domjit/JSDocumentFragmentDOMJIT.cpp
index d6ab5f9..a2a957f 100644 (file)
                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, ); }; };
                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, ); }; };
                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>"; };
                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>"; };
                                C3CF17A315B0063F00276D39 /* IdTargetObserverRegistry.h */,
                                8AB4BC76126FDB7100DEB727 /* IgnoreDestructiveWriteCountIncrementer.h */,
                                467302011C4EFE6600BCB357 /* IgnoreOpensDuringUnloadCountIncrementer.h */,
+                               512B57BF1FE9902E000A1E5E /* InProcessMessagePortChannel.cpp */,
+                               512B57BC1FE9902C000A1E5E /* InProcessMessagePortChannel.h */,
                                E30592611E27A38C00D57C98 /* InlineClassicScript.cpp */,
                                E30592621E27A38C00D57C98 /* InlineClassicScript.h */,
                                AA4C3A740B2B1679002334A2 /* InlineStyleSheetOwner.cpp */,
                                E1ADECBE0E76ACF1004A1A5E /* MessagePort.cpp */,
                                E1ADECBD0E76ACF1004A1A5E /* MessagePort.h */,
                                E1ADECC60E76AD1F004A1A5E /* MessagePort.idl */,
+                               512B57BE1FE9902D000A1E5E /* MessagePortChannel.cpp */,
                                41BF700A0FE86F49005E8DEC /* MessagePortChannel.h */,
                                CB8CF0151A934B43000D510B /* Microtasks.cpp */,
                                53B895AD19DC7C37009CAA93 /* Microtasks.h */,
                                8A7CC96F12076F8A001D4588 /* PendingScript.cpp */,
                                8A7CC96A12076D73001D4588 /* PendingScript.h */,
                                E3FA38611D716E7600AA5950 /* PendingScriptClient.h */,
-                               41BF700D0FE86F61005E8DEC /* PlatformMessagePortChannel.cpp */,
-                               41BF700E0FE86F61005E8DEC /* PlatformMessagePortChannel.h */,
                                5189F0DD10B46B0E00F3C739 /* PopStateEvent.cpp */,
                                5174E20810A1F44F00F95E6F /* PopStateEvent.h */,
                                5174E20B10A1F49A00F95E6F /* PopStateEvent.idl */,
                                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 */,
diff --git a/Source/WebCore/dom/InProcessMessagePortChannel.cpp b/Source/WebCore/dom/InProcessMessagePortChannel.cpp
new file mode 100644 (file)
index 0000000..c215df8
--- /dev/null
@@ -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
diff --git a/Source/WebCore/dom/InProcessMessagePortChannel.h b/Source/WebCore/dom/InProcessMessagePortChannel.h
new file mode 100644 (file)
index 0000000..44bd9d1
--- /dev/null
@@ -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
index a140953..5808025 100644 (file)
@@ -36,7 +36,7 @@ MessageChannel::MessageChannel(ScriptExecutionContext& context)
     : 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;
index 33779b6..ead9c2c 100644 (file)
 
 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
index 585bdb1..de1de88 100644 (file)
@@ -65,7 +65,7 @@ ExceptionOr<void> MessagePort::postMessage(JSC::ExecState& state, JSC::JSValue m
     // 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 @@ ExceptionOr<void> MessagePort::postMessage(JSC::ExecState& state, JSC::JSValue m
     return { };
 }
 
-std::unique_ptr<MessagePortChannel> MessagePort::disentangle()
+RefPtr<MessagePortChannel> MessagePort::disentangle()
 {
     ASSERT(m_entangledChannel);
 
@@ -123,14 +123,14 @@ void MessagePort::close()
     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);
     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 @@ bool MessagePort::hasPendingActivity() const
     // 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;
 }
 
index ffb28c5..e567859 100644 (file)
@@ -41,7 +41,7 @@ namespace WebCore {
 
 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 @@ public:
     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 @@ public:
     // 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 @@ private:
 
     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 @@ private:
     // 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 };
 };
diff --git a/Source/WebCore/dom/MessagePortChannel.cpp b/Source/WebCore/dom/MessagePortChannel.cpp
new file mode 100644 (file)
index 0000000..2cf42b9
--- /dev/null
@@ -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
+
index a09628c..e2ff7af 100644 (file)
 
 namespace WebCore {
 
-    class MessagePort;
-    class MessagePortChannel;
-    class PlatformMessagePortChannel;
-    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;
-
-    // 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))
-            { }
-
-            Ref<SerializedScriptValue> message;
-            std::unique_ptr<MessagePortChannelArray> channels;
-        };
-
-        explicit MessagePortChannel(RefPtr<PlatformMessagePortChannel>&&);
-        static void createChannel(MessagePort*, MessagePort*);
-
-        // 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*);
-
-        // 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();
-
-        // Closes the port (ensures that no further messages can be added to either queue).
-        void close();
-
-        // 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();
+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<RefPtr<MessagePortChannel>, 1> MessagePortChannelArray;
+
+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;
+    };
 
-        Deque<std::unique_ptr<EventData>> takeAllMessagesFromRemote();
+    MessagePortChannel();
+    virtual ~MessagePortChannel() { }
 
-        // Returns the entangled port if run by the same thread (see MessagePort::locallyEntangledPort() for more details).
-        MessagePort* locallyEntangledPort(const ScriptExecutionContext*);
+    static void createChannelBetweenPorts(MessagePort&, MessagePort&);
 
-        WEBCORE_EXPORT ~MessagePortChannel();
+    void setRemotePort(MessagePort*);
 
-    private:
-        RefPtr<PlatformMessagePortChannel> m_channel;
-    };
+    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;
+};
 
 } // namespace WebCore
diff --git a/Source/WebCore/dom/default/PlatformMessagePortChannel.cpp b/Source/WebCore/dom/default/PlatformMessagePortChannel.cpp
deleted file mode 100644 (file)
index 64151ce..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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 "PlatformMessagePortChannel.h"
-
-#include "MessagePort.h"
-#include "ScriptExecutionContext.h"
-
-namespace WebCore {
-
-void MessagePortChannel::createChannel(MessagePort* port1, MessagePort* port2)
-{
-    Ref<PlatformMessagePortChannel::MessagePortQueue> queue1 = PlatformMessagePortChannel::MessagePortQueue::create();
-    Ref<PlatformMessagePortChannel::MessagePortQueue> queue2 = PlatformMessagePortChannel::MessagePortQueue::create();
-
-    auto channel1 = std::make_unique<MessagePortChannel>(PlatformMessagePortChannel::create(queue1.ptr(), queue2.ptr()));
-    auto channel2 = std::make_unique<MessagePortChannel>(PlatformMessagePortChannel::create(queue2.ptr(), queue1.ptr()));
-
-    channel1->m_channel->m_entangledChannel = channel2->m_channel;
-    channel2->m_channel->m_entangledChannel = channel1->m_channel;
-
-    port1->entangle(WTFMove(channel2));
-    port2->entangle(WTFMove(channel1));
-}
-
-MessagePortChannel::MessagePortChannel(RefPtr<PlatformMessagePortChannel>&& channel)
-    : m_channel(WTFMove(channel))
-{
-}
-
-MessagePortChannel::~MessagePortChannel()
-{
-    close();
-}
-
-bool MessagePortChannel::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<PlatformMessagePortChannel> remote = m_channel->entangledChannel();
-    if (!remote)
-        return false;
-    remote->setRemotePort(port);
-    return true;
-}
-
-void MessagePortChannel::disentangle()
-{
-    RefPtr<PlatformMessagePortChannel> remote = m_channel->entangledChannel();
-    if (remote)
-        remote->setRemotePort(nullptr);
-}
-
-void MessagePortChannel::postMessageToRemote(Ref<SerializedScriptValue>&& message, std::unique_ptr<MessagePortChannelArray>&& channels)
-{
-    LockHolder lock(m_channel->m_mutex);
-    if (!m_channel->m_outgoingQueue)
-        return;
-    bool wasEmpty = m_channel->m_outgoingQueue->appendAndCheckEmpty(std::make_unique<EventData>(WTFMove(message), WTFMove(channels)));
-    if (wasEmpty && m_channel->m_remotePort)
-        m_channel->m_remotePort->messageAvailable();
-}
-
-auto MessagePortChannel::takeMessageFromRemote() -> std::unique_ptr<EventData>
-{
-    LockHolder lock(m_channel->m_mutex);
-    return m_channel->m_incomingQueue->takeMessage();
-}
-
-auto MessagePortChannel::takeAllMessagesFromRemote() -> Deque<std::unique_ptr<EventData>>
-{
-    LockHolder lock(m_channel->m_mutex);
-    return m_channel->m_incomingQueue->takeAllMessages();
-}
-
-void MessagePortChannel::close()
-{
-    RefPtr<PlatformMessagePortChannel> remote = m_channel->entangledChannel();
-    if (!remote)
-        return;
-    m_channel->closeInternal();
-    remote->closeInternal();
-}
-
-bool MessagePortChannel::isConnectedTo(MessagePort* port)
-{
-    // FIXME: What guarantees that the result remains the same after we release the lock?
-    LockHolder lock(m_channel->m_mutex);
-    return m_channel->m_remotePort == port;
-}
-
-bool MessagePortChannel::hasPendingActivity()
-{
-    // FIXME: What guarantees that the result remains the same after we release the lock?
-    LockHolder lock(m_channel->m_mutex);
-    return !m_channel->m_incomingQueue->isEmpty();
-}
-
-MessagePort* MessagePortChannel::locallyEntangledPort(const ScriptExecutionContext* context)
-{
-    LockHolder lock(m_channel->m_mutex);
-    // See if both contexts are run by the same thread (are the same context, or are both documents).
-    if (m_channel->m_remotePort) {
-        // 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_channel->m_remotePort->scriptExecutionContext();
-        if (remoteContext == context || (remoteContext && remoteContext->isDocument() && context->isDocument()))
-            return m_channel->m_remotePort;
-    }
-    return 0;
-}
-
-Ref<PlatformMessagePortChannel> PlatformMessagePortChannel::create(MessagePortQueue* incoming, MessagePortQueue* outgoing)
-{
-    return adoptRef(*new PlatformMessagePortChannel(incoming, outgoing));
-}
-
-PlatformMessagePortChannel::PlatformMessagePortChannel(MessagePortQueue* incoming, MessagePortQueue* outgoing)
-    : m_incomingQueue(incoming)
-    , m_outgoingQueue(outgoing)
-{
-}
-
-PlatformMessagePortChannel::~PlatformMessagePortChannel() = default;
-
-void PlatformMessagePortChannel::setRemotePort(MessagePort* port)
-{
-    LockHolder lock(m_mutex);
-    // Should never set port if it is already set.
-    ASSERT(!port || !m_remotePort);
-    m_remotePort = port;
-}
-
-RefPtr<PlatformMessagePortChannel> PlatformMessagePortChannel::entangledChannel()
-{
-    // FIXME: What guarantees that the result remains the same after we release the lock?
-    // This lock only guarantees that the returned pointer will not be pointing to released memory,
-    // but not that it will still be pointing to this object's entangled port channel.
-    LockHolder lock(m_mutex);
-    return m_entangledChannel;
-}
-
-void PlatformMessagePortChannel::closeInternal()
-{
-    LockHolder lock(m_mutex);
-    // 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_entangledChannel = nullptr;
-    m_outgoingQueue = nullptr;
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/dom/default/PlatformMessagePortChannel.h b/Source/WebCore/dom/default/PlatformMessagePortChannel.h
deleted file mode 100644 (file)
index 15d319b..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2009 Google 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.
- */
-
-#pragma once
-
-#include "MessagePortChannel.h"
-#include <wtf/MessageQueue.h>
-
-namespace WebCore {
-
-    class MessagePort;
-
-    // PlatformMessagePortChannel is a platform-dependent interface to the remote side of a message channel.
-    // This default implementation supports multiple threads running within a single process. Implementations for multi-process platforms should define these public APIs in their own platform-specific PlatformMessagePortChannel file.
-    // The goal of this implementation is to eliminate contention except when cloning or closing the port, so each side of the channel has its own separate mutex.
-    class PlatformMessagePortChannel : public ThreadSafeRefCounted<PlatformMessagePortChannel> {
-    public:
-        // 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()); }
-
-            std::unique_ptr<MessagePortChannel::EventData> takeMessage()
-            {
-                return m_queue.tryGetMessage();
-            }
-
-            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;
-        };
-
-        ~PlatformMessagePortChannel();
-
-        static Ref<PlatformMessagePortChannel> create(MessagePortQueue* incoming, MessagePortQueue* outgoing);
-        PlatformMessagePortChannel(MessagePortQueue* incoming, MessagePortQueue* outgoing);
-
-        RefPtr<PlatformMessagePortChannel> entangledChannel();
-
-        void setRemotePort(MessagePort*);
-        void closeInternal();
-
-        // Lock used to ensure exclusive access to the object internals.
-        Lock m_mutex;
-
-        // Pointer to our entangled pair - cleared when close() is called.
-        RefPtr<PlatformMessagePortChannel> m_entangledChannel;
-
-        // Reference to the message queue for the (local) entangled port.
-        RefPtr<MessagePortQueue> m_incomingQueue;
-        RefPtr<MessagePortQueue> m_outgoingQueue;
-
-        // The port we are connected to (the remote port) - this is the port that is notified when new messages arrive.
-        MessagePort* m_remotePort { nullptr };
-    };
-
-} // namespace WebCore
index b55915f..c35592a 100644 (file)
@@ -44,7 +44,7 @@ struct ServiceWorkerClientData;
 struct ServiceWorkerClientIdentifier;
 struct ServiceWorkerContextData;
 
-using MessagePortChannelArray = Vector<std::unique_ptr<MessagePortChannel>, 1>;
+using MessagePortChannelArray = Vector<RefPtr<MessagePortChannel>, 1>;
 
 class ServiceWorkerThread : public WorkerThread {
 public: