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 MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_ | 5 #ifndef MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_ |
6 #define 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/channel_endpoint_id.h" | |
17 #include "mojo/edk/system/dispatcher.h" | 16 #include "mojo/edk/system/dispatcher.h" |
18 #include "mojo/edk/system/memory.h" | 17 #include "mojo/edk/system/memory.h" |
19 #include "mojo/edk/system/system_impl_export.h" | 18 #include "mojo/edk/system/system_impl_export.h" |
20 #include "mojo/public/cpp/system/macros.h" | 19 #include "mojo/public/cpp/system/macros.h" |
21 | 20 |
22 namespace mojo { | 21 namespace mojo { |
23 namespace system { | 22 namespace system { |
24 | 23 |
25 class Channel; | 24 class RawChannel; |
26 class TransportData; | 25 class TransportData; |
27 | 26 |
28 // This class is used to represent data in transit. It is thread-unsafe. | 27 // This class is used to represent data in transit. It is thread-unsafe. |
29 // | 28 // |
30 // |MessageInTransit| buffers: | 29 // |MessageInTransit| buffers: |
31 // | 30 // |
32 // A |MessageInTransit| can be serialized by writing the main buffer and then, | 31 // A |MessageInTransit| can be serialized by writing the main buffer and then, |
33 // if it has one, the transport data buffer. Both buffers are | 32 // if it has one, the transport data buffer. Both buffers are |
34 // |kMessageAlignment|-byte aligned and a multiple of |kMessageAlignment| bytes | 33 // |kMessageAlignment|-byte aligned and a multiple of |kMessageAlignment| bytes |
35 // in size. | 34 // in size. |
36 // | 35 // |
37 // The main buffer consists of the header (of type |Header|, which is an | 36 // 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 | 37 // internal detail of this class) followed immediately by the message data |
39 // (accessed by |bytes()| and of size |num_bytes()|, and also | 38 // (accessed by |bytes()| and of size |num_bytes()|, and also |
40 // |kMessageAlignment|-byte aligned), and then any padding needed to make the | 39 // |kMessageAlignment|-byte aligned), and then any padding needed to make the |
41 // main buffer a multiple of |kMessageAlignment| bytes in size. | 40 // main buffer a multiple of |kMessageAlignment| bytes in size. |
42 // | 41 // |
43 // See |TransportData| for a description of the (serialized) transport data | 42 // See |TransportData| for a description of the (serialized) transport data |
44 // buffer. | 43 // buffer. |
45 class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit { | 44 class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit { |
46 public: | 45 public: |
47 enum class Type : uint16_t { | 46 enum class Type : uint16_t { |
48 // Messages that are forwarded to endpoint clients. | 47 MESSAGE = 0, |
49 ENDPOINT_CLIENT = 0, | 48 RAW_CHANNEL_POSIX_EXTRA_PLATFORM_HANDLES = 1, |
50 // Messages that are consumed by the |ChannelEndpoint|. | 49 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 }; | 50 }; |
94 | 51 |
95 // Messages (the header and data) must always be aligned to a multiple of this | 52 // Messages (the header and data) must always be aligned to a multiple of this |
96 // quantity (which must be a power of 2). | 53 // quantity (which must be a power of 2). |
97 static const size_t kMessageAlignment = 8; | 54 static const size_t kMessageAlignment = 8; |
98 | 55 |
99 // Forward-declare |Header| so that |View| can use it: | 56 // Forward-declare |Header| so that |View| can use it: |
100 private: | 57 private: |
101 struct Header; | 58 struct Header; |
102 | 59 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 } | 91 } |
135 size_t transport_data_buffer_size() const { | 92 size_t transport_data_buffer_size() const { |
136 return total_size() - main_buffer_size(); | 93 return total_size() - main_buffer_size(); |
137 } | 94 } |
138 size_t total_size() const { return header()->total_size; } | 95 size_t total_size() const { return header()->total_size; } |
139 uint32_t num_bytes() const { return header()->num_bytes; } | 96 uint32_t num_bytes() const { return header()->num_bytes; } |
140 const void* bytes() const { | 97 const void* bytes() const { |
141 return static_cast<const char*>(buffer_) + sizeof(Header); | 98 return static_cast<const char*>(buffer_) + sizeof(Header); |
142 } | 99 } |
143 Type type() const { return header()->type; } | 100 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 | 101 |
150 private: | 102 private: |
151 const Header* header() const { return static_cast<const Header*>(buffer_); } | 103 const Header* header() const { return static_cast<const Header*>(buffer_); } |
152 | 104 |
153 const void* const buffer_; | 105 const void* const buffer_; |
154 | 106 |
155 // Though this struct is trivial, disallow copy and assign, since it doesn't | 107 // 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 | 108 // own its data. (If you're copying/assigning this, you're probably doing |
157 // something wrong.) | 109 // something wrong.) |
158 MOJO_DISALLOW_COPY_AND_ASSIGN(View); | 110 MOJO_DISALLOW_COPY_AND_ASSIGN(View); |
159 }; | 111 }; |
160 | 112 |
161 // |bytes| is optional; if null, the message data will be zero-initialized. | 113 // |bytes| is optional; if null, the message data will be zero-initialized. |
162 MessageInTransit(Type type, | 114 MessageInTransit(Type type, |
163 Subtype subtype, | |
164 uint32_t num_bytes, | 115 uint32_t num_bytes, |
165 const void* bytes); | 116 const void* bytes); |
166 // |bytes| should be valid (and non-null), unless |num_bytes| is zero. | 117 // |bytes| should be valid (and non-null), unless |num_bytes| is zero. |
167 MessageInTransit(Type type, | 118 MessageInTransit(Type type, |
168 Subtype subtype, | |
169 uint32_t num_bytes, | 119 uint32_t num_bytes, |
170 UserPointer<const void> bytes); | 120 UserPointer<const void> bytes); |
171 // Constructs a |MessageInTransit| from a |View|. | 121 // Constructs a |MessageInTransit| from a |View|. |
172 explicit MessageInTransit(const View& message_view); | 122 explicit MessageInTransit(const View& message_view); |
173 | 123 |
174 ~MessageInTransit(); | 124 ~MessageInTransit(); |
175 | 125 |
176 // Gets the size of the next message from |buffer|, which has |buffer_size| | 126 // Gets the size of the next message from |buffer|, which has |buffer_size| |
177 // bytes currently available, returning true and setting |*next_message_size| | 127 // bytes currently available, returning true and setting |*next_message_size| |
178 // on success. |buffer| should be aligned on a |kMessageAlignment| boundary | 128 // on success. |buffer| should be aligned on a |kMessageAlignment| boundary |
(...skipping 12 matching lines...) Expand all Loading... |
191 void SetDispatchers(scoped_ptr<DispatcherVector> dispatchers); | 141 void SetDispatchers(scoped_ptr<DispatcherVector> dispatchers); |
192 | 142 |
193 // Sets the |TransportData| for this message. This should only be done when | 143 // Sets the |TransportData| for this message. This should only be done when |
194 // there are no dispatchers and no existing |TransportData|. | 144 // there are no dispatchers and no existing |TransportData|. |
195 void SetTransportData(scoped_ptr<TransportData> transport_data); | 145 void SetTransportData(scoped_ptr<TransportData> transport_data); |
196 | 146 |
197 // Serializes any dispatchers to the secondary buffer. This message must not | 147 // 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 | 148 // 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| | 149 // caller must ensure (e.g., by holding on to a reference) that |channel| |
200 // stays alive through the call. | 150 // stays alive through the call. |
201 void SerializeAndCloseDispatchers(Channel* channel); | 151 void SerializeAndCloseDispatchers(); |
202 | 152 |
203 // Gets the main buffer and its size (in number of bytes), respectively. | 153 // Gets the main buffer and its size (in number of bytes), respectively. |
204 const void* main_buffer() const { return main_buffer_.get(); } | 154 const void* main_buffer() const { return main_buffer_.get(); } |
205 size_t main_buffer_size() const { return main_buffer_size_; } | 155 size_t main_buffer_size() const { return main_buffer_size_; } |
206 | 156 |
207 // Gets the transport data buffer (if any). | 157 // Gets the transport data buffer (if any). |
208 const TransportData* transport_data() const { return transport_data_.get(); } | 158 const TransportData* transport_data() const { return transport_data_.get(); } |
209 TransportData* transport_data() { return transport_data_.get(); } | 159 TransportData* transport_data() { return transport_data_.get(); } |
210 | 160 |
211 // Gets the total size of the message (see comment in |Header|, below). | 161 // Gets the total size of the message (see comment in |Header|, below). |
212 size_t total_size() const { return header()->total_size; } | 162 size_t total_size() const { return header()->total_size; } |
213 | 163 |
214 // Gets the size of the message data. | 164 // Gets the size of the message data. |
215 uint32_t num_bytes() const { return header()->num_bytes; } | 165 uint32_t num_bytes() const { return header()->num_bytes; } |
216 | 166 |
217 // Gets the message data (of size |num_bytes()| bytes). | 167 // Gets the message data (of size |num_bytes()| bytes). |
218 const void* bytes() const { return main_buffer_.get() + sizeof(Header); } | 168 const void* bytes() const { return main_buffer_.get() + sizeof(Header); } |
219 void* bytes() { return main_buffer_.get() + sizeof(Header); } | 169 void* bytes() { return main_buffer_.get() + sizeof(Header); } |
220 | 170 |
221 Type type() const { return header()->type; } | 171 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 | 172 |
233 // Gets the dispatchers attached to this message; this may return null if | 173 // 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 | 174 // 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). | 175 // (e.g., take ownership of all the dispatchers, leaving the vector empty). |
236 DispatcherVector* dispatchers() { return dispatchers_.get(); } | 176 DispatcherVector* dispatchers() { return dispatchers_.get(); } |
237 | 177 |
238 // Returns true if this message has dispatchers attached. | 178 // Returns true if this message has dispatchers attached. |
239 bool has_dispatchers() const { | 179 bool has_dispatchers() const { |
240 return dispatchers_ && !dispatchers_->empty(); | 180 return dispatchers_ && !dispatchers_->empty(); |
241 } | 181 } |
(...skipping 10 matching lines...) Expand all Loading... |
252 // Header for the data (main buffer). Must be a multiple of | 192 // Header for the data (main buffer). Must be a multiple of |
253 // |kMessageAlignment| bytes in size. Must be POD. | 193 // |kMessageAlignment| bytes in size. Must be POD. |
254 struct Header { | 194 struct Header { |
255 // Total size of the message, including the header, the message data | 195 // Total size of the message, including the header, the message data |
256 // ("bytes") including padding (to make it a multiple of |kMessageAlignment| | 196 // ("bytes") including padding (to make it a multiple of |kMessageAlignment| |
257 // bytes), and serialized handle information. Note that this may not be the | 197 // bytes), and serialized handle information. Note that this may not be the |
258 // correct value if dispatchers are attached but | 198 // correct value if dispatchers are attached but |
259 // |SerializeAndCloseDispatchers()| has not been called. | 199 // |SerializeAndCloseDispatchers()| has not been called. |
260 uint32_t total_size; | 200 uint32_t total_size; |
261 Type type; // 2 bytes. | 201 Type type; // 2 bytes. |
262 Subtype subtype; // 2 bytes. | 202 Type blahblahforalignment; // 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; | 203 uint32_t num_bytes; |
267 uint32_t unused; | 204 uint32_t unused; |
268 }; | 205 }; |
269 | 206 |
270 const Header* header() const { | 207 const Header* header() const { |
271 return reinterpret_cast<const Header*>(main_buffer_.get()); | 208 return reinterpret_cast<const Header*>(main_buffer_.get()); |
272 } | 209 } |
273 Header* header() { return reinterpret_cast<Header*>(main_buffer_.get()); } | 210 Header* header() { return reinterpret_cast<Header*>(main_buffer_.get()); } |
274 | 211 |
275 void ConstructorHelper(Type type, Subtype subtype, uint32_t num_bytes); | 212 void ConstructorHelper(Type type, uint32_t num_bytes); |
276 void UpdateTotalSize(); | 213 void UpdateTotalSize(); |
277 | 214 |
278 const size_t main_buffer_size_; | 215 const size_t main_buffer_size_; |
279 const scoped_ptr<char, base::AlignedFreeDeleter> main_buffer_; // Never null. | 216 const scoped_ptr<char, base::AlignedFreeDeleter> main_buffer_; // Never null. |
280 | 217 |
281 scoped_ptr<TransportData> transport_data_; // May be null. | 218 scoped_ptr<TransportData> transport_data_; // May be null. |
282 | 219 |
283 // Any dispatchers that may be attached to this message. These dispatchers | 220 // 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 | 221 // 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 | 222 // allow a dispatcher entry to be null, in case it couldn't be duplicated for |
286 // some reason.) | 223 // some reason.) |
287 scoped_ptr<DispatcherVector> dispatchers_; | 224 scoped_ptr<DispatcherVector> dispatchers_; |
288 | 225 |
289 MOJO_DISALLOW_COPY_AND_ASSIGN(MessageInTransit); | 226 MOJO_DISALLOW_COPY_AND_ASSIGN(MessageInTransit); |
290 }; | 227 }; |
291 | 228 |
292 // So logging macros and |DCHECK_EQ()|, etc. work. | 229 // So logging macros and |DCHECK_EQ()|, etc. work. |
293 MOJO_SYSTEM_IMPL_EXPORT inline std::ostream& operator<<( | 230 MOJO_SYSTEM_IMPL_EXPORT inline std::ostream& operator<<( |
294 std::ostream& out, | 231 std::ostream& out, |
295 MessageInTransit::Type type) { | 232 MessageInTransit::Type type) { |
296 return out << static_cast<uint16_t>(type); | 233 return out << static_cast<uint16_t>(type); |
297 } | 234 } |
298 | 235 |
299 // So logging macros and |DCHECK_EQ()|, etc. work. | |
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 | 236 } // namespace system |
307 } // namespace mojo | 237 } // namespace mojo |
308 | 238 |
309 #endif // MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_ | 239 #endif // MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_ |
OLD | NEW |