1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef MOJO_CORE_PORTS_EVENT_H_
6 #define MOJO_CORE_PORTS_EVENT_H_
7
8 #include <stdint.h>
9
10 #include <vector>
11
12 #include "base/component_export.h"
13 #include "base/macros.h"
14 #include "base/memory/ptr_util.h"
15 #include "mojo/core/ports/name.h"
16 #include "mojo/core/ports/user_message.h"
17
18 namespace mojo {
19 namespace core {
20 namespace ports {
21
22 class Event;
23
24 using ScopedEvent = std::unique_ptr<Event>;
25
26 // A Event is the fundamental unit of operation and communication within and
27 // between Nodes.
COMPONENT_EXPORT(MOJO_CORE_PORTS)28 class COMPONENT_EXPORT(MOJO_CORE_PORTS) Event {
29 public:
30 enum Type : uint32_t {
31 // A user message event contains arbitrary user-specified payload data
32 // which may include any number of ports and/or system handles (e.g. FDs).
33 kUserMessage,
34
35 // When a Node receives a user message with one or more ports attached, it
36 // sends back an instance of this event for every attached port to indicate
37 // that the port has been accepted by its destination node.
38 kPortAccepted,
39
40 // This event begins circulation any time a port enters a proxying state. It
41 // may be re-circulated in certain edge cases, but the ultimate purpose of
42 // the event is to ensure that every port along a route is (if necessary)
43 // aware that the proxying port is indeed proxying (and to where) so that it
44 // can begin to be bypassed along the route.
45 kObserveProxy,
46
47 // An event used to acknowledge to a proxy that all concerned nodes and
48 // ports are aware of its proxying state and that no more user messages will
49 // be routed to it beyond a given final sequence number.
50 kObserveProxyAck,
51
52 // Indicates that a port has been closed. This event fully circulates a
53 // route to ensure that all ports are aware of closure.
54 kObserveClosure,
55
56 // Used to request the merging of two routes via two sacrificial receiving
57 // ports, one from each route.
58 kMergePort,
59 };
60
61 #pragma pack(push, 1)
62 struct PortDescriptor {
63 PortDescriptor();
64
65 NodeName peer_node_name;
66 PortName peer_port_name;
67 NodeName referring_node_name;
68 PortName referring_port_name;
69 uint64_t next_sequence_num_to_send;
70 uint64_t next_sequence_num_to_receive;
71 uint64_t last_sequence_num_to_receive;
72 bool peer_closed;
73 char padding[7];
74 };
75 #pragma pack(pop)
76 virtual ~Event();
77
78 static ScopedEvent Deserialize(const void* buffer, size_t num_bytes);
79
80 template <typename T>
81 static std::unique_ptr<T> Cast(ScopedEvent* event) {
82 return base::WrapUnique(static_cast<T*>(event->release()));
83 }
84
85 Type type() const { return type_; }
86 const PortName& port_name() const { return port_name_; }
87 void set_port_name(const PortName& port_name) { port_name_ = port_name; }
88
89 size_t GetSerializedSize() const;
90 void Serialize(void* buffer) const;
91 virtual ScopedEvent Clone() const;
92
93 protected:
94 Event(Type type, const PortName& port_name);
95
96 virtual size_t GetSerializedDataSize() const = 0;
97 virtual void SerializeData(void* buffer) const = 0;
98
99 private:
100 const Type type_;
101 PortName port_name_;
102
103 DISALLOW_COPY_AND_ASSIGN(Event);
104 };
105
COMPONENT_EXPORT(MOJO_CORE_PORTS)106 class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageEvent : public Event {
107 public:
108 explicit UserMessageEvent(size_t num_ports);
109 ~UserMessageEvent() override;
110
111 bool HasMessage() const { return !!message_; }
112 void AttachMessage(std::unique_ptr<UserMessage> message);
113
114 template <typename T>
115 T* GetMessage() {
116 DCHECK(HasMessage());
117 DCHECK_EQ(&T::kUserMessageTypeInfo, message_->type_info());
118 return static_cast<T*>(message_.get());
119 }
120
121 template <typename T>
122 const T* GetMessage() const {
123 DCHECK(HasMessage());
124 DCHECK_EQ(&T::kUserMessageTypeInfo, message_->type_info());
125 return static_cast<const T*>(message_.get());
126 }
127
128 void ReservePorts(size_t num_ports);
129 bool NotifyWillBeRoutedExternally();
130
131 uint32_t sequence_num() const { return sequence_num_; }
132 void set_sequence_num(uint32_t sequence_num) { sequence_num_ = sequence_num; }
133
134 size_t num_ports() const { return ports_.size(); }
135 PortDescriptor* port_descriptors() { return port_descriptors_.data(); }
136 PortName* ports() { return ports_.data(); }
137
138 static ScopedEvent Deserialize(const PortName& port_name,
139 const void* buffer,
140 size_t num_bytes);
141
142 size_t GetSizeIfSerialized() const;
143
144 private:
145 UserMessageEvent(const PortName& port_name, uint64_t sequence_num);
146
147 size_t GetSerializedDataSize() const override;
148 void SerializeData(void* buffer) const override;
149
150 uint64_t sequence_num_ = 0;
151 std::vector<PortDescriptor> port_descriptors_;
152 std::vector<PortName> ports_;
153 std::unique_ptr<UserMessage> message_;
154
155 DISALLOW_COPY_AND_ASSIGN(UserMessageEvent);
156 };
157
COMPONENT_EXPORT(MOJO_CORE_PORTS)158 class COMPONENT_EXPORT(MOJO_CORE_PORTS) PortAcceptedEvent : public Event {
159 public:
160 explicit PortAcceptedEvent(const PortName& port_name);
161 ~PortAcceptedEvent() override;
162
163 static ScopedEvent Deserialize(const PortName& port_name,
164 const void* buffer,
165 size_t num_bytes);
166
167 private:
168 size_t GetSerializedDataSize() const override;
169 void SerializeData(void* buffer) const override;
170
171 DISALLOW_COPY_AND_ASSIGN(PortAcceptedEvent);
172 };
173
COMPONENT_EXPORT(MOJO_CORE_PORTS)174 class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveProxyEvent : public Event {
175 public:
176 ObserveProxyEvent(const PortName& port_name,
177 const NodeName& proxy_node_name,
178 const PortName& proxy_port_name,
179 const NodeName& proxy_target_node_name,
180 const PortName& proxy_target_port_name);
181 ~ObserveProxyEvent() override;
182
183 const NodeName& proxy_node_name() const { return proxy_node_name_; }
184 const PortName& proxy_port_name() const { return proxy_port_name_; }
185 const NodeName& proxy_target_node_name() const {
186 return proxy_target_node_name_;
187 }
188 const PortName& proxy_target_port_name() const {
189 return proxy_target_port_name_;
190 }
191
192 static ScopedEvent Deserialize(const PortName& port_name,
193 const void* buffer,
194 size_t num_bytes);
195
196 private:
197 size_t GetSerializedDataSize() const override;
198 void SerializeData(void* buffer) const override;
199 ScopedEvent Clone() const override;
200
201 const NodeName proxy_node_name_;
202 const PortName proxy_port_name_;
203 const NodeName proxy_target_node_name_;
204 const PortName proxy_target_port_name_;
205
206 DISALLOW_COPY_AND_ASSIGN(ObserveProxyEvent);
207 };
208
COMPONENT_EXPORT(MOJO_CORE_PORTS)209 class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveProxyAckEvent : public Event {
210 public:
211 ObserveProxyAckEvent(const PortName& port_name, uint64_t last_sequence_num);
212 ~ObserveProxyAckEvent() override;
213
214 uint64_t last_sequence_num() const { return last_sequence_num_; }
215
216 static ScopedEvent Deserialize(const PortName& port_name,
217 const void* buffer,
218 size_t num_bytes);
219
220 private:
221 size_t GetSerializedDataSize() const override;
222 void SerializeData(void* buffer) const override;
223 ScopedEvent Clone() const override;
224
225 const uint64_t last_sequence_num_;
226
227 DISALLOW_COPY_AND_ASSIGN(ObserveProxyAckEvent);
228 };
229
COMPONENT_EXPORT(MOJO_CORE_PORTS)230 class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveClosureEvent : public Event {
231 public:
232 ObserveClosureEvent(const PortName& port_name, uint64_t last_sequence_num);
233 ~ObserveClosureEvent() override;
234
235 uint64_t last_sequence_num() const { return last_sequence_num_; }
236 void set_last_sequence_num(uint64_t last_sequence_num) {
237 last_sequence_num_ = last_sequence_num;
238 }
239
240 static ScopedEvent Deserialize(const PortName& port_name,
241 const void* buffer,
242 size_t num_bytes);
243
244 private:
245 size_t GetSerializedDataSize() const override;
246 void SerializeData(void* buffer) const override;
247 ScopedEvent Clone() const override;
248
249 uint64_t last_sequence_num_;
250
251 DISALLOW_COPY_AND_ASSIGN(ObserveClosureEvent);
252 };
253
COMPONENT_EXPORT(MOJO_CORE_PORTS)254 class COMPONENT_EXPORT(MOJO_CORE_PORTS) MergePortEvent : public Event {
255 public:
256 MergePortEvent(const PortName& port_name,
257 const PortName& new_port_name,
258 const PortDescriptor& new_port_descriptor);
259 ~MergePortEvent() override;
260
261 const PortName& new_port_name() const { return new_port_name_; }
262 const PortDescriptor& new_port_descriptor() const {
263 return new_port_descriptor_;
264 }
265
266 static ScopedEvent Deserialize(const PortName& port_name,
267 const void* buffer,
268 size_t num_bytes);
269
270 private:
271 size_t GetSerializedDataSize() const override;
272 void SerializeData(void* buffer) const override;
273
274 const PortName new_port_name_;
275 const PortDescriptor new_port_descriptor_;
276
277 DISALLOW_COPY_AND_ASSIGN(MergePortEvent);
278 };
279
280 } // namespace ports
281 } // namespace core
282 } // namespace mojo
283
284 #endif // MOJO_CORE_PORTS_EVENT_H_
285