1/*
2 * Copyright (C) 2018 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "MessagePortChannelProviderImpl.h"
28
29#include "MessagePort.h"
30#include <wtf/CompletionHandler.h>
31#include <wtf/MainThread.h>
32#include <wtf/RunLoop.h>
33
34namespace WebCore {
35
36MessagePortChannelProviderImpl::MessagePortChannelProviderImpl()
37 : m_registry(*this)
38{
39}
40
41MessagePortChannelProviderImpl::~MessagePortChannelProviderImpl()
42{
43 ASSERT_NOT_REACHED();
44}
45
46void MessagePortChannelProviderImpl::performActionOnMainThread(Function<void()>&& action)
47{
48 if (isMainThread())
49 action();
50 else
51 callOnMainThread(WTFMove(action));
52}
53
54void MessagePortChannelProviderImpl::createNewMessagePortChannel(const MessagePortIdentifier& local, const MessagePortIdentifier& remote)
55{
56 performActionOnMainThread([registry = &m_registry, local, remote] {
57 registry->didCreateMessagePortChannel(local, remote);
58 });
59}
60
61void MessagePortChannelProviderImpl::entangleLocalPortInThisProcessToRemote(const MessagePortIdentifier& local, const MessagePortIdentifier& remote)
62{
63 performActionOnMainThread([registry = &m_registry, local, remote] {
64 registry->didEntangleLocalToRemote(local, remote, Process::identifier());
65 });
66}
67
68void MessagePortChannelProviderImpl::messagePortDisentangled(const MessagePortIdentifier& local)
69{
70 performActionOnMainThread([registry = &m_registry, local] {
71 registry->didDisentangleMessagePort(local);
72 });
73}
74
75void MessagePortChannelProviderImpl::messagePortClosed(const MessagePortIdentifier& local)
76{
77 performActionOnMainThread([registry = &m_registry, local] {
78 registry->didCloseMessagePort(local);
79 });
80}
81
82void MessagePortChannelProviderImpl::postMessageToRemote(MessageWithMessagePorts&& message, const MessagePortIdentifier& remoteTarget)
83{
84 performActionOnMainThread([registry = &m_registry, message = WTFMove(message), remoteTarget]() mutable {
85 if (registry->didPostMessageToRemote(WTFMove(message), remoteTarget))
86 MessagePort::notifyMessageAvailable(remoteTarget);
87 });
88}
89
90void MessagePortChannelProviderImpl::takeAllMessagesForPort(const MessagePortIdentifier& port, Function<void(Vector<MessageWithMessagePorts>&&, Function<void()>&&)>&& outerCallback)
91{
92 // It is the responsibility of outerCallback to get itself to the appropriate thread (e.g. WebWorker thread)
93 auto callback = [outerCallback = WTFMove(outerCallback)](Vector<MessageWithMessagePorts>&& messages, Function<void()>&& messageDeliveryCallback) {
94 ASSERT(isMainThread());
95 outerCallback(WTFMove(messages), WTFMove(messageDeliveryCallback));
96 };
97
98 performActionOnMainThread([registry = &m_registry, port, callback = WTFMove(callback)]() mutable {
99 registry->takeAllMessagesForPort(port, WTFMove(callback));
100 });
101}
102
103void MessagePortChannelProviderImpl::checkRemotePortForActivity(const MessagePortIdentifier& remoteTarget, CompletionHandler<void(HasActivity)>&& outerCallback)
104{
105 auto callback = CompletionHandler<void(HasActivity)> { [outerCallback = WTFMove(outerCallback)](HasActivity hasActivity) mutable {
106 ASSERT(isMainThread());
107 outerCallback(hasActivity);
108 } };
109
110 performActionOnMainThread([registry = &m_registry, remoteTarget, callback = WTFMove(callback)]() mutable {
111 registry->checkRemotePortForActivity(remoteTarget, WTFMove(callback));
112 });
113}
114
115void MessagePortChannelProviderImpl::checkProcessLocalPortForActivity(const MessagePortIdentifier& identifier, ProcessIdentifier, CompletionHandler<void(HasActivity)>&& callback)
116{
117 ASSERT(isMainThread());
118
119 callback(MessagePort::isExistingMessagePortLocallyReachable(identifier) ? HasActivity::Yes : HasActivity::No);
120}
121
122
123} // namespace WebCore
124