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: