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. 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 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 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 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 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 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 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