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