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 // Used to request that the conjugate port acknowledges read messages by
61 // sending back a UserMessageReadAck.
62 kUserMessageReadAckRequest,
63
64 // Used to acknowledge read messages to the conjugate.
65 kUserMessageReadAck,
66 };
67
68 #pragma pack(push, 1)
69 struct PortDescriptor {
70 PortDescriptor();
71
72 NodeName peer_node_name;
73 PortName peer_port_name;
74 NodeName referring_node_name;
75 PortName referring_port_name;
76 uint64_t next_sequence_num_to_send;
77 uint64_t next_sequence_num_to_receive;
78 uint64_t last_sequence_num_to_receive;
79 bool peer_closed;
80 char padding[7];
81 };
82 #pragma pack(pop)
83 virtual ~Event();
84
85 static ScopedEvent Deserialize(const void* buffer, size_t num_bytes);
86
87 template <typename T>
88 static std::unique_ptr<T> Cast(ScopedEvent* event) {
89 return base::WrapUnique(static_cast<T*>(event->release()));
90 }
91
92 Type type() const { return type_; }
93 const PortName& port_name() const { return port_name_; }
94 void set_port_name(const PortName& port_name) { port_name_ = port_name; }
95
96 size_t GetSerializedSize() const;
97 void Serialize(void* buffer) const;
98 virtual ScopedEvent Clone() const;
99
100 protected:
101 Event(Type type, const PortName& port_name);
102
103 virtual size_t GetSerializedDataSize() const = 0;
104 virtual void SerializeData(void* buffer) const = 0;
105
106 private:
107 const Type type_;
108 PortName port_name_;
109
110 DISALLOW_COPY_AND_ASSIGN(Event);
111 };
112
COMPONENT_EXPORT(MOJO_CORE_PORTS)113 class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageEvent : public Event {
114 public:
115 explicit UserMessageEvent(size_t num_ports);
116 ~UserMessageEvent() override;
117
118 bool HasMessage() const { return !!message_; }
119 void AttachMessage(std::unique_ptr<UserMessage> message);
120
121 template <typename T>
122 T* GetMessage() {
123 DCHECK(HasMessage());
124 DCHECK_EQ(&T::kUserMessageTypeInfo, message_->type_info());
125 return static_cast<T*>(message_.get());
126 }
127
128 template <typename T>
129 const T* GetMessage() const {
130 DCHECK(HasMessage());
131 DCHECK_EQ(&T::kUserMessageTypeInfo, message_->type_info());
132 return static_cast<const T*>(message_.get());
133 }
134
135 void ReservePorts(size_t num_ports);
136 bool NotifyWillBeRoutedExternally();
137
138 uint64_t sequence_num() const { return sequence_num_; }
139 void set_sequence_num(uint64_t sequence_num) { sequence_num_ = sequence_num; }
140
141 size_t num_ports() const { return ports_.size(); }
142 PortDescriptor* port_descriptors() { return port_descriptors_.data(); }
143 PortName* ports() { return ports_.data(); }
144
145 static ScopedEvent Deserialize(const PortName& port_name,
146 const void* buffer,
147 size_t num_bytes);
148
149 size_t GetSizeIfSerialized() const;
150
151 private:
152 UserMessageEvent(const PortName& port_name, uint64_t sequence_num);
153
154 size_t GetSerializedDataSize() const override;
155 void SerializeData(void* buffer) const override;
156
157 uint64_t sequence_num_ = 0;
158 std::vector<PortDescriptor> port_descriptors_;
159 std::vector<PortName> ports_;
160 std::unique_ptr<UserMessage> message_;
161
162 DISALLOW_COPY_AND_ASSIGN(UserMessageEvent);
163 };
164
COMPONENT_EXPORT(MOJO_CORE_PORTS)165 class COMPONENT_EXPORT(MOJO_CORE_PORTS) PortAcceptedEvent : public Event {
166 public:
167 explicit PortAcceptedEvent(const PortName& port_name);
168 ~PortAcceptedEvent() override;
169
170 static ScopedEvent Deserialize(const PortName& port_name,
171 const void* buffer,
172 size_t num_bytes);
173
174 private:
175 size_t GetSerializedDataSize() const override;
176 void SerializeData(void* buffer) const override;
177
178 DISALLOW_COPY_AND_ASSIGN(PortAcceptedEvent);
179 };
180
COMPONENT_EXPORT(MOJO_CORE_PORTS)181 class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveProxyEvent : public Event {
182 public:
183 ObserveProxyEvent(const PortName& port_name,
184 const NodeName& proxy_node_name,
185 const PortName& proxy_port_name,
186 const NodeName& proxy_target_node_name,
187 const PortName& proxy_target_port_name);
188 ~ObserveProxyEvent() override;
189
190 const NodeName& proxy_node_name() const { return proxy_node_name_; }
191 const PortName& proxy_port_name() const { return proxy_port_name_; }
192 const NodeName& proxy_target_node_name() const {
193 return proxy_target_node_name_;
194 }
195 const PortName& proxy_target_port_name() const {
196 return proxy_target_port_name_;
197 }
198
199 static ScopedEvent Deserialize(const PortName& port_name,
200 const void* buffer,
201 size_t num_bytes);
202
203 private:
204 size_t GetSerializedDataSize() const override;
205 void SerializeData(void* buffer) const override;
206 ScopedEvent Clone() const override;
207
208 const NodeName proxy_node_name_;
209 const PortName proxy_port_name_;
210 const NodeName proxy_target_node_name_;
211 const PortName proxy_target_port_name_;
212
213 DISALLOW_COPY_AND_ASSIGN(ObserveProxyEvent);
214 };
215
COMPONENT_EXPORT(MOJO_CORE_PORTS)216 class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveProxyAckEvent : public Event {
217 public:
218 ObserveProxyAckEvent(const PortName& port_name, uint64_t last_sequence_num);
219 ~ObserveProxyAckEvent() override;
220
221 uint64_t last_sequence_num() const { return last_sequence_num_; }
222
223 static ScopedEvent Deserialize(const PortName& port_name,
224 const void* buffer,
225 size_t num_bytes);
226
227 private:
228 size_t GetSerializedDataSize() const override;
229 void SerializeData(void* buffer) const override;
230 ScopedEvent Clone() const override;
231
232 const uint64_t last_sequence_num_;
233
234 DISALLOW_COPY_AND_ASSIGN(ObserveProxyAckEvent);
235 };
236
COMPONENT_EXPORT(MOJO_CORE_PORTS)237 class COMPONENT_EXPORT(MOJO_CORE_PORTS) ObserveClosureEvent : public Event {
238 public:
239 ObserveClosureEvent(const PortName& port_name, uint64_t last_sequence_num);
240 ~ObserveClosureEvent() override;
241
242 uint64_t last_sequence_num() const { return last_sequence_num_; }
243 void set_last_sequence_num(uint64_t last_sequence_num) {
244 last_sequence_num_ = last_sequence_num;
245 }
246
247 static ScopedEvent Deserialize(const PortName& port_name,
248 const void* buffer,
249 size_t num_bytes);
250
251 private:
252 size_t GetSerializedDataSize() const override;
253 void SerializeData(void* buffer) const override;
254 ScopedEvent Clone() const override;
255
256 uint64_t last_sequence_num_;
257
258 DISALLOW_COPY_AND_ASSIGN(ObserveClosureEvent);
259 };
260
COMPONENT_EXPORT(MOJO_CORE_PORTS)261 class COMPONENT_EXPORT(MOJO_CORE_PORTS) MergePortEvent : public Event {
262 public:
263 MergePortEvent(const PortName& port_name,
264 const PortName& new_port_name,
265 const PortDescriptor& new_port_descriptor);
266 ~MergePortEvent() override;
267
268 const PortName& new_port_name() const { return new_port_name_; }
269 const PortDescriptor& new_port_descriptor() const {
270 return new_port_descriptor_;
271 }
272
273 static ScopedEvent Deserialize(const PortName& port_name,
274 const void* buffer,
275 size_t num_bytes);
276
277 private:
278 size_t GetSerializedDataSize() const override;
279 void SerializeData(void* buffer) const override;
280
281 const PortName new_port_name_;
282 const PortDescriptor new_port_descriptor_;
283
284 DISALLOW_COPY_AND_ASSIGN(MergePortEvent);
285 };
286
COMPONENT_EXPORT(MOJO_CORE_PORTS)287 class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageReadAckRequestEvent
288 : public Event {
289 public:
290 UserMessageReadAckRequestEvent(const PortName& port_name,
291 uint64_t sequence_num_to_acknowledge);
292 ~UserMessageReadAckRequestEvent() override;
293
294 uint64_t sequence_num_to_acknowledge() const {
295 return sequence_num_to_acknowledge_;
296 }
297
298 static ScopedEvent Deserialize(const PortName& port_name,
299 const void* buffer,
300 size_t num_bytes);
301
302 private:
303 size_t GetSerializedDataSize() const override;
304 void SerializeData(void* buffer) const override;
305
306 uint64_t sequence_num_to_acknowledge_;
307 };
308
COMPONENT_EXPORT(MOJO_CORE_PORTS)309 class COMPONENT_EXPORT(MOJO_CORE_PORTS) UserMessageReadAckEvent : public Event {
310 public:
311 UserMessageReadAckEvent(const PortName& port_name,
312 uint64_t sequence_num_acknowledged);
313 ~UserMessageReadAckEvent() override;
314
315 uint64_t sequence_num_acknowledged() const {
316 return sequence_num_acknowledged_;
317 }
318
319 static ScopedEvent Deserialize(const PortName& port_name,
320 const void* buffer,
321 size_t num_bytes);
322
323 private:
324 size_t GetSerializedDataSize() const override;
325 void SerializeData(void* buffer) const override;
326
327 uint64_t sequence_num_acknowledged_;
328 };
329
330 } // namespace ports
331 } // namespace core
332 } // namespace mojo
333
334 #endif // MOJO_CORE_PORTS_EVENT_H_
335