1/*
2 * Copyright (C) 2012 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 "MessageReceiverMap.h"
28
29#include "Decoder.h"
30#include "MessageReceiver.h"
31
32namespace IPC {
33
34MessageReceiverMap::MessageReceiverMap()
35{
36}
37
38MessageReceiverMap::~MessageReceiverMap()
39{
40}
41
42void MessageReceiverMap::addMessageReceiver(StringReference messageReceiverName, MessageReceiver& messageReceiver)
43{
44 ASSERT(!m_globalMessageReceivers.contains(messageReceiverName));
45
46 messageReceiver.willBeAddedToMessageReceiverMap();
47 m_globalMessageReceivers.set(messageReceiverName, &messageReceiver);
48}
49
50void MessageReceiverMap::addMessageReceiver(StringReference messageReceiverName, uint64_t destinationID, MessageReceiver& messageReceiver)
51{
52 ASSERT(destinationID);
53 ASSERT(!m_messageReceivers.contains(std::make_pair(messageReceiverName, destinationID)));
54 ASSERT(!m_globalMessageReceivers.contains(messageReceiverName));
55
56 messageReceiver.willBeAddedToMessageReceiverMap();
57 m_messageReceivers.set(std::make_pair(messageReceiverName, destinationID), &messageReceiver);
58}
59
60void MessageReceiverMap::removeMessageReceiver(StringReference messageReceiverName)
61{
62 ASSERT(m_globalMessageReceivers.contains(messageReceiverName));
63
64 auto it = m_globalMessageReceivers.find(messageReceiverName);
65 it->value->willBeRemovedFromMessageReceiverMap();
66
67 m_globalMessageReceivers.remove(it);
68}
69
70void MessageReceiverMap::removeMessageReceiver(StringReference messageReceiverName, uint64_t destinationID)
71{
72 ASSERT(m_messageReceivers.contains(std::make_pair(messageReceiverName, destinationID)));
73
74 auto it = m_messageReceivers.find(std::make_pair(messageReceiverName, destinationID));
75 it->value->willBeRemovedFromMessageReceiverMap();
76
77 m_messageReceivers.remove(it);
78}
79
80void MessageReceiverMap::removeMessageReceiver(MessageReceiver& messageReceiver)
81{
82 Vector<StringReference> globalReceiversToRemove;
83 for (auto& nameAndReceiver : m_globalMessageReceivers) {
84 if (nameAndReceiver.value == &messageReceiver)
85 globalReceiversToRemove.append(nameAndReceiver.key);
86 }
87
88 for (auto& globalReceiverToRemove : globalReceiversToRemove)
89 removeMessageReceiver(globalReceiverToRemove);
90
91 Vector<std::pair<StringReference, uint64_t>> receiversToRemove;
92 for (auto& nameAndIdAndReceiver : m_messageReceivers) {
93 if (nameAndIdAndReceiver.value == &messageReceiver)
94 receiversToRemove.append(std::make_pair(nameAndIdAndReceiver.key.first, nameAndIdAndReceiver.key.second));
95 }
96
97 for (auto& receiverToRemove : receiversToRemove)
98 removeMessageReceiver(receiverToRemove.first, receiverToRemove.second);
99}
100
101void MessageReceiverMap::invalidate()
102{
103 for (auto& messageReceiver : m_globalMessageReceivers.values())
104 messageReceiver->willBeRemovedFromMessageReceiverMap();
105 m_globalMessageReceivers.clear();
106
107
108 for (auto& messageReceiver : m_messageReceivers.values())
109 messageReceiver->willBeRemovedFromMessageReceiverMap();
110 m_messageReceivers.clear();
111}
112
113bool MessageReceiverMap::dispatchMessage(Connection& connection, Decoder& decoder)
114{
115 if (MessageReceiver* messageReceiver = m_globalMessageReceivers.get(decoder.messageReceiverName())) {
116 ASSERT(!decoder.destinationID());
117
118 messageReceiver->didReceiveMessage(connection, decoder);
119 return true;
120 }
121
122 if (MessageReceiver* messageReceiver = m_messageReceivers.get(std::make_pair(decoder.messageReceiverName(), decoder.destinationID()))) {
123 messageReceiver->didReceiveMessage(connection, decoder);
124 return true;
125 }
126
127 return false;
128}
129
130bool MessageReceiverMap::dispatchSyncMessage(Connection& connection, Decoder& decoder, std::unique_ptr<Encoder>& replyEncoder)
131{
132 if (MessageReceiver* messageReceiver = m_globalMessageReceivers.get(decoder.messageReceiverName())) {
133 ASSERT(!decoder.destinationID());
134
135 messageReceiver->didReceiveSyncMessage(connection, decoder, replyEncoder);
136 return true;
137 }
138
139 if (MessageReceiver* messageReceiver = m_messageReceivers.get(std::make_pair(decoder.messageReceiverName(), decoder.destinationID()))) {
140 messageReceiver->didReceiveSyncMessage(connection, decoder, replyEncoder);
141 return true;
142 }
143
144 return false;
145}
146
147} // namespace IPC
148