| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef THIRD_PARTY_MOJO_SRC_MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_ | 5 #ifndef MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_ |
| 6 #define THIRD_PARTY_MOJO_SRC_MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_ | 6 #define MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <stdint.h> | 9 #include <stdint.h> |
| 10 | 10 |
| 11 #include <ostream> | 11 #include <ostream> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "base/memory/aligned_memory.h" | 14 #include "base/memory/aligned_memory.h" |
| 15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 16 #include "mojo/edk/system/dispatcher.h" |
| 17 #include "mojo/edk/system/system_impl_export.h" |
| 16 #include "mojo/public/cpp/system/macros.h" | 18 #include "mojo/public/cpp/system/macros.h" |
| 17 #include "third_party/mojo/src/mojo/edk/system/channel_endpoint_id.h" | |
| 18 #include "third_party/mojo/src/mojo/edk/system/dispatcher.h" | |
| 19 #include "third_party/mojo/src/mojo/edk/system/memory.h" | |
| 20 #include "third_party/mojo/src/mojo/edk/system/system_impl_export.h" | |
| 21 | 19 |
| 22 namespace mojo { | 20 namespace mojo { |
| 23 namespace system { | 21 namespace edk { |
| 24 | 22 |
| 25 class Channel; | 23 class RawChannel; |
| 26 class TransportData; | 24 class TransportData; |
| 27 | 25 |
| 28 // This class is used to represent data in transit. It is thread-unsafe. | 26 // This class is used to represent data in transit. It is thread-unsafe. |
| 29 // | 27 // |
| 30 // |MessageInTransit| buffers: | 28 // |MessageInTransit| buffers: |
| 31 // | 29 // |
| 32 // A |MessageInTransit| can be serialized by writing the main buffer and then, | 30 // A |MessageInTransit| can be serialized by writing the main buffer and then, |
| 33 // if it has one, the transport data buffer. Both buffers are | 31 // if it has one, the transport data buffer. Both buffers are |
| 34 // |kMessageAlignment|-byte aligned and a multiple of |kMessageAlignment| bytes | 32 // |kMessageAlignment|-byte aligned and a multiple of |kMessageAlignment| bytes |
| 35 // in size. | 33 // in size. |
| 36 // | 34 // |
| 37 // The main buffer consists of the header (of type |Header|, which is an | 35 // The main buffer consists of the header (of type |Header|, which is an |
| 38 // internal detail of this class) followed immediately by the message data | 36 // internal detail of this class) followed immediately by the message data |
| 39 // (accessed by |bytes()| and of size |num_bytes()|, and also | 37 // (accessed by |bytes()| and of size |num_bytes()|, and also |
| 40 // |kMessageAlignment|-byte aligned), and then any padding needed to make the | 38 // |kMessageAlignment|-byte aligned), and then any padding needed to make the |
| 41 // main buffer a multiple of |kMessageAlignment| bytes in size. | 39 // main buffer a multiple of |kMessageAlignment| bytes in size. |
| 42 // | 40 // |
| 43 // See |TransportData| for a description of the (serialized) transport data | 41 // See |TransportData| for a description of the (serialized) transport data |
| 44 // buffer. | 42 // buffer. |
| 45 class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit { | 43 class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit { |
| 46 public: | 44 public: |
| 47 enum class Type : uint16_t { | 45 enum class Type : uint16_t { |
| 48 // Messages that are forwarded to endpoint clients. | 46 MESSAGE = 0, |
| 49 ENDPOINT_CLIENT = 0, | 47 RAW_CHANNEL_POSIX_EXTRA_PLATFORM_HANDLES = 1, |
| 50 // Messages that are consumed by the |ChannelEndpoint|. | 48 RAW_CHANNEL_QUIT = 2, |
| 51 ENDPOINT = 1, | |
| 52 // Messages that are consumed by the |Channel|. | |
| 53 CHANNEL = 2, | |
| 54 // Messages that are consumed by the |RawChannel| (implementation). | |
| 55 RAW_CHANNEL = 3, | |
| 56 // |ConnectionManager| implementations also use |RawChannel|s. | |
| 57 // Messages sent to a |MasterConnectionManager|. | |
| 58 CONNECTION_MANAGER = 4, | |
| 59 // Messages sent by a |MasterConnectionManager| (all responses). | |
| 60 CONNECTION_MANAGER_ACK = 5, | |
| 61 }; | |
| 62 | |
| 63 enum class Subtype : uint16_t { | |
| 64 // Subtypes for type |Type::ENDPOINT_CLIENT|: | |
| 65 // Message pipe or data pipe data (etc.). | |
| 66 ENDPOINT_CLIENT_DATA = 0, | |
| 67 // Data pipe: consumer -> producer message that data was consumed. Payload | |
| 68 // is |RemoteDataPipeAck|. | |
| 69 ENDPOINT_CLIENT_DATA_PIPE_ACK = 1, | |
| 70 // Subtypes for type |Type::ENDPOINT|: | |
| 71 // TODO(vtl): Nothing yet. | |
| 72 // Subtypes for type |Type::CHANNEL|: | |
| 73 CHANNEL_ATTACH_AND_RUN_ENDPOINT = 0, | |
| 74 CHANNEL_REMOVE_ENDPOINT = 1, | |
| 75 CHANNEL_REMOVE_ENDPOINT_ACK = 2, | |
| 76 // Subtypes for type |Type::RAW_CHANNEL|: | |
| 77 RAW_CHANNEL_POSIX_EXTRA_PLATFORM_HANDLES = 0, | |
| 78 // Subtypes for type |Type::CONNECTION_MANAGER| (the message data is always | |
| 79 // a buffer containing the connection ID): | |
| 80 CONNECTION_MANAGER_ALLOW_CONNECT = 0, | |
| 81 CONNECTION_MANAGER_CANCEL_CONNECT = 1, | |
| 82 CONNECTION_MANAGER_CONNECT = 2, | |
| 83 // Subtypes for type |Type::CONNECTION_MANAGER_ACK|, corresponding to | |
| 84 // |ConnectionManager::Result| values (failure and non-"connect" acks never | |
| 85 // have any message contents; success acks for "connect" always have a | |
| 86 // |ConnectionManagerAckSuccessConnectData| as data and also a platform | |
| 87 // handle attached for "new connection"): | |
| 88 CONNECTION_MANAGER_ACK_FAILURE = 0, | |
| 89 CONNECTION_MANAGER_ACK_SUCCESS = 1, | |
| 90 CONNECTION_MANAGER_ACK_SUCCESS_CONNECT_SAME_PROCESS = 2, | |
| 91 CONNECTION_MANAGER_ACK_SUCCESS_CONNECT_NEW_CONNECTION = 3, | |
| 92 CONNECTION_MANAGER_ACK_SUCCESS_CONNECT_REUSE_CONNECTION = 4, | |
| 93 }; | 49 }; |
| 94 | 50 |
| 95 // Messages (the header and data) must always be aligned to a multiple of this | 51 // Messages (the header and data) must always be aligned to a multiple of this |
| 96 // quantity (which must be a power of 2). | 52 // quantity (which must be a power of 2). |
| 97 static const size_t kMessageAlignment = 8; | 53 static const size_t kMessageAlignment = 8; |
| 98 | 54 |
| 99 // Forward-declare |Header| so that |View| can use it: | 55 // Forward-declare |Header| so that |View| can use it: |
| 100 private: | 56 private: |
| 101 struct Header; | 57 struct Header; |
| 102 | 58 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 } | 90 } |
| 135 size_t transport_data_buffer_size() const { | 91 size_t transport_data_buffer_size() const { |
| 136 return total_size() - main_buffer_size(); | 92 return total_size() - main_buffer_size(); |
| 137 } | 93 } |
| 138 size_t total_size() const { return header()->total_size; } | 94 size_t total_size() const { return header()->total_size; } |
| 139 uint32_t num_bytes() const { return header()->num_bytes; } | 95 uint32_t num_bytes() const { return header()->num_bytes; } |
| 140 const void* bytes() const { | 96 const void* bytes() const { |
| 141 return static_cast<const char*>(buffer_) + sizeof(Header); | 97 return static_cast<const char*>(buffer_) + sizeof(Header); |
| 142 } | 98 } |
| 143 Type type() const { return header()->type; } | 99 Type type() const { return header()->type; } |
| 144 Subtype subtype() const { return header()->subtype; } | |
| 145 ChannelEndpointId source_id() const { return header()->source_id; } | |
| 146 ChannelEndpointId destination_id() const { | |
| 147 return header()->destination_id; | |
| 148 } | |
| 149 | 100 |
| 150 private: | 101 private: |
| 151 const Header* header() const { return static_cast<const Header*>(buffer_); } | 102 const Header* header() const { return static_cast<const Header*>(buffer_); } |
| 152 | 103 |
| 153 const void* const buffer_; | 104 const void* const buffer_; |
| 154 | 105 |
| 155 // Though this struct is trivial, disallow copy and assign, since it doesn't | 106 // Though this struct is trivial, disallow copy and assign, since it doesn't |
| 156 // own its data. (If you're copying/assigning this, you're probably doing | 107 // own its data. (If you're copying/assigning this, you're probably doing |
| 157 // something wrong.) | 108 // something wrong.) |
| 158 MOJO_DISALLOW_COPY_AND_ASSIGN(View); | 109 MOJO_DISALLOW_COPY_AND_ASSIGN(View); |
| 159 }; | 110 }; |
| 160 | 111 |
| 161 // |bytes| is optional; if null, the message data will be zero-initialized. | 112 // |bytes| is optional; if null, the message data will be zero-initialized. |
| 162 MessageInTransit(Type type, | 113 MessageInTransit(Type type, |
| 163 Subtype subtype, | |
| 164 uint32_t num_bytes, | 114 uint32_t num_bytes, |
| 165 const void* bytes); | 115 const void* bytes); |
| 166 // |bytes| should be valid (and non-null), unless |num_bytes| is zero. | |
| 167 MessageInTransit(Type type, | |
| 168 Subtype subtype, | |
| 169 uint32_t num_bytes, | |
| 170 UserPointer<const void> bytes); | |
| 171 // Constructs a |MessageInTransit| from a |View|. | 116 // Constructs a |MessageInTransit| from a |View|. |
| 172 explicit MessageInTransit(const View& message_view); | 117 explicit MessageInTransit(const View& message_view); |
| 173 | 118 |
| 174 ~MessageInTransit(); | 119 ~MessageInTransit(); |
| 175 | 120 |
| 176 // Gets the size of the next message from |buffer|, which has |buffer_size| | 121 // Gets the size of the next message from |buffer|, which has |buffer_size| |
| 177 // bytes currently available, returning true and setting |*next_message_size| | 122 // bytes currently available, returning true and setting |*next_message_size| |
| 178 // on success. |buffer| should be aligned on a |kMessageAlignment| boundary | 123 // on success. |buffer| should be aligned on a |kMessageAlignment| boundary |
| 179 // (and on success, |*next_message_size| will be a multiple of | 124 // (and on success, |*next_message_size| will be a multiple of |
| 180 // |kMessageAlignment|). | 125 // |kMessageAlignment|). |
| (...skipping 10 matching lines...) Expand all Loading... |
| 191 void SetDispatchers(scoped_ptr<DispatcherVector> dispatchers); | 136 void SetDispatchers(scoped_ptr<DispatcherVector> dispatchers); |
| 192 | 137 |
| 193 // Sets the |TransportData| for this message. This should only be done when | 138 // Sets the |TransportData| for this message. This should only be done when |
| 194 // there are no dispatchers and no existing |TransportData|. | 139 // there are no dispatchers and no existing |TransportData|. |
| 195 void SetTransportData(scoped_ptr<TransportData> transport_data); | 140 void SetTransportData(scoped_ptr<TransportData> transport_data); |
| 196 | 141 |
| 197 // Serializes any dispatchers to the secondary buffer. This message must not | 142 // Serializes any dispatchers to the secondary buffer. This message must not |
| 198 // already have a secondary buffer (so this must only be called once). The | 143 // already have a secondary buffer (so this must only be called once). The |
| 199 // caller must ensure (e.g., by holding on to a reference) that |channel| | 144 // caller must ensure (e.g., by holding on to a reference) that |channel| |
| 200 // stays alive through the call. | 145 // stays alive through the call. |
| 201 void SerializeAndCloseDispatchers(Channel* channel); | 146 void SerializeAndCloseDispatchers(); |
| 202 | 147 |
| 203 // Gets the main buffer and its size (in number of bytes), respectively. | 148 // Gets the main buffer and its size (in number of bytes), respectively. |
| 204 const void* main_buffer() const { return main_buffer_.get(); } | 149 const void* main_buffer() const { return main_buffer_.get(); } |
| 205 size_t main_buffer_size() const { return main_buffer_size_; } | 150 size_t main_buffer_size() const { return main_buffer_size_; } |
| 206 | 151 |
| 207 // Gets the transport data buffer (if any). | 152 // Gets the transport data buffer (if any). |
| 208 const TransportData* transport_data() const { return transport_data_.get(); } | 153 const TransportData* transport_data() const { return transport_data_.get(); } |
| 209 TransportData* transport_data() { return transport_data_.get(); } | 154 TransportData* transport_data() { return transport_data_.get(); } |
| 210 | 155 |
| 211 // Gets the total size of the message (see comment in |Header|, below). | 156 // Gets the total size of the message (see comment in |Header|, below). |
| 212 size_t total_size() const { return header()->total_size; } | 157 size_t total_size() const { return header()->total_size; } |
| 213 | 158 |
| 214 // Gets the size of the message data. | 159 // Gets the size of the message data. |
| 215 uint32_t num_bytes() const { return header()->num_bytes; } | 160 uint32_t num_bytes() const { return header()->num_bytes; } |
| 216 | 161 |
| 217 // Gets the message data (of size |num_bytes()| bytes). | 162 // Gets the message data (of size |num_bytes()| bytes). |
| 218 const void* bytes() const { return main_buffer_.get() + sizeof(Header); } | 163 const void* bytes() const { return main_buffer_.get() + sizeof(Header); } |
| 219 void* bytes() { return main_buffer_.get() + sizeof(Header); } | 164 void* bytes() { return main_buffer_.get() + sizeof(Header); } |
| 220 | 165 |
| 221 Type type() const { return header()->type; } | 166 Type type() const { return header()->type; } |
| 222 Subtype subtype() const { return header()->subtype; } | |
| 223 ChannelEndpointId source_id() const { return header()->source_id; } | |
| 224 ChannelEndpointId destination_id() const { return header()->destination_id; } | |
| 225 | |
| 226 void set_source_id(ChannelEndpointId source_id) { | |
| 227 header()->source_id = source_id; | |
| 228 } | |
| 229 void set_destination_id(ChannelEndpointId destination_id) { | |
| 230 header()->destination_id = destination_id; | |
| 231 } | |
| 232 | 167 |
| 233 // Gets the dispatchers attached to this message; this may return null if | 168 // Gets the dispatchers attached to this message; this may return null if |
| 234 // there are none. Note that the caller may mutate the set of dispatchers | 169 // there are none. Note that the caller may mutate the set of dispatchers |
| 235 // (e.g., take ownership of all the dispatchers, leaving the vector empty). | 170 // (e.g., take ownership of all the dispatchers, leaving the vector empty). |
| 236 DispatcherVector* dispatchers() { return dispatchers_.get(); } | 171 DispatcherVector* dispatchers() { return dispatchers_.get(); } |
| 237 | 172 |
| 238 // Returns true if this message has dispatchers attached. | 173 // Returns true if this message has dispatchers attached. |
| 239 bool has_dispatchers() const { | 174 bool has_dispatchers() const { |
| 240 return dispatchers_ && !dispatchers_->empty(); | 175 return dispatchers_ && !dispatchers_->empty(); |
| 241 } | 176 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 252 // Header for the data (main buffer). Must be a multiple of | 187 // Header for the data (main buffer). Must be a multiple of |
| 253 // |kMessageAlignment| bytes in size. Must be POD. | 188 // |kMessageAlignment| bytes in size. Must be POD. |
| 254 struct Header { | 189 struct Header { |
| 255 // Total size of the message, including the header, the message data | 190 // Total size of the message, including the header, the message data |
| 256 // ("bytes") including padding (to make it a multiple of |kMessageAlignment| | 191 // ("bytes") including padding (to make it a multiple of |kMessageAlignment| |
| 257 // bytes), and serialized handle information. Note that this may not be the | 192 // bytes), and serialized handle information. Note that this may not be the |
| 258 // correct value if dispatchers are attached but | 193 // correct value if dispatchers are attached but |
| 259 // |SerializeAndCloseDispatchers()| has not been called. | 194 // |SerializeAndCloseDispatchers()| has not been called. |
| 260 uint32_t total_size; | 195 uint32_t total_size; |
| 261 Type type; // 2 bytes. | 196 Type type; // 2 bytes. |
| 262 Subtype subtype; // 2 bytes. | 197 Type unusedforalignment; // 2 bytes. |
| 263 ChannelEndpointId source_id; // 4 bytes. | |
| 264 ChannelEndpointId destination_id; // 4 bytes. | |
| 265 // Size of actual message data. | |
| 266 uint32_t num_bytes; | 198 uint32_t num_bytes; |
| 267 uint32_t unused; | 199 uint32_t unused; |
| 268 }; | 200 }; |
| 269 | 201 |
| 270 const Header* header() const { | 202 const Header* header() const { |
| 271 return reinterpret_cast<const Header*>(main_buffer_.get()); | 203 return reinterpret_cast<const Header*>(main_buffer_.get()); |
| 272 } | 204 } |
| 273 Header* header() { return reinterpret_cast<Header*>(main_buffer_.get()); } | 205 Header* header() { return reinterpret_cast<Header*>(main_buffer_.get()); } |
| 274 | 206 |
| 275 void ConstructorHelper(Type type, Subtype subtype, uint32_t num_bytes); | 207 void ConstructorHelper(Type type, uint32_t num_bytes); |
| 276 void UpdateTotalSize(); | 208 void UpdateTotalSize(); |
| 277 | 209 |
| 278 const size_t main_buffer_size_; | 210 const size_t main_buffer_size_; |
| 279 const scoped_ptr<char, base::AlignedFreeDeleter> main_buffer_; // Never null. | 211 const scoped_ptr<char, base::AlignedFreeDeleter> main_buffer_; // Never null. |
| 280 | 212 |
| 281 scoped_ptr<TransportData> transport_data_; // May be null. | 213 scoped_ptr<TransportData> transport_data_; // May be null. |
| 282 | 214 |
| 283 // Any dispatchers that may be attached to this message. These dispatchers | 215 // Any dispatchers that may be attached to this message. These dispatchers |
| 284 // should be "owned" by this message, i.e., have a ref count of exactly 1. (We | 216 // should be "owned" by this message, i.e., have a ref count of exactly 1. (We |
| 285 // allow a dispatcher entry to be null, in case it couldn't be duplicated for | 217 // allow a dispatcher entry to be null, in case it couldn't be duplicated for |
| 286 // some reason.) | 218 // some reason.) |
| 287 scoped_ptr<DispatcherVector> dispatchers_; | 219 scoped_ptr<DispatcherVector> dispatchers_; |
| 288 | 220 |
| 289 MOJO_DISALLOW_COPY_AND_ASSIGN(MessageInTransit); | 221 MOJO_DISALLOW_COPY_AND_ASSIGN(MessageInTransit); |
| 290 }; | 222 }; |
| 291 | 223 |
| 292 // So logging macros and |DCHECK_EQ()|, etc. work. | 224 // So logging macros and |DCHECK_EQ()|, etc. work. |
| 293 MOJO_SYSTEM_IMPL_EXPORT inline std::ostream& operator<<( | 225 MOJO_SYSTEM_IMPL_EXPORT inline std::ostream& operator<<( |
| 294 std::ostream& out, | 226 std::ostream& out, |
| 295 MessageInTransit::Type type) { | 227 MessageInTransit::Type type) { |
| 296 return out << static_cast<uint16_t>(type); | 228 return out << static_cast<uint16_t>(type); |
| 297 } | 229 } |
| 298 | 230 |
| 299 // So logging macros and |DCHECK_EQ()|, etc. work. | 231 } // namespace edk |
| 300 MOJO_SYSTEM_IMPL_EXPORT inline std::ostream& operator<<( | |
| 301 std::ostream& out, | |
| 302 MessageInTransit::Subtype subtype) { | |
| 303 return out << static_cast<uint16_t>(subtype); | |
| 304 } | |
| 305 | |
| 306 } // namespace system | |
| 307 } // namespace mojo | 232 } // namespace mojo |
| 308 | 233 |
| 309 #endif // THIRD_PARTY_MOJO_SRC_MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_ | 234 #endif // MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_ |
| OLD | NEW |