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 <memory> | 11 #include <memory> |
12 #include <ostream> | 12 #include <ostream> |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include "mojo/edk/platform/aligned_alloc.h" | 15 #include "mojo/edk/platform/aligned_alloc.h" |
16 #include "mojo/edk/system/channel_endpoint_id.h" | 16 #include "mojo/edk/system/channel_endpoint_id.h" |
17 #include "mojo/edk/system/dispatcher.h" | 17 #include "mojo/edk/system/dispatcher.h" |
| 18 #include "mojo/edk/system/handle.h" |
18 #include "mojo/edk/system/memory.h" | 19 #include "mojo/edk/system/memory.h" |
19 #include "mojo/public/cpp/system/macros.h" | 20 #include "mojo/public/cpp/system/macros.h" |
20 | 21 |
21 namespace mojo { | 22 namespace mojo { |
22 namespace system { | 23 namespace system { |
23 | 24 |
24 class Channel; | 25 class Channel; |
25 class TransportData; | 26 class TransportData; |
26 | 27 |
27 // This class is used to represent data in transit. It is thread-unsafe. | 28 // This class is used to represent data in transit. It is thread-unsafe. |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 // bytes currently available, returning true and setting |*next_message_size| | 177 // bytes currently available, returning true and setting |*next_message_size| |
177 // on success. |buffer| should be aligned on a |kMessageAlignment| boundary | 178 // on success. |buffer| should be aligned on a |kMessageAlignment| boundary |
178 // (and on success, |*next_message_size| will be a multiple of | 179 // (and on success, |*next_message_size| will be a multiple of |
179 // |kMessageAlignment|). | 180 // |kMessageAlignment|). |
180 // TODO(vtl): In |RawChannelPosix|, the alignment requirements are currently | 181 // TODO(vtl): In |RawChannelPosix|, the alignment requirements are currently |
181 // satisified on a faith-based basis. | 182 // satisified on a faith-based basis. |
182 static bool GetNextMessageSize(const void* buffer, | 183 static bool GetNextMessageSize(const void* buffer, |
183 size_t buffer_size, | 184 size_t buffer_size, |
184 size_t* next_message_size); | 185 size_t* next_message_size); |
185 | 186 |
186 // Makes this message "own" the given set of dispatchers. The dispatchers must | 187 // Makes this message "own" the given set of handles. Each handle's dispatcher |
187 // not be referenced from anywhere else (in particular, not from the handle | 188 // must not be referenced from anywhere else (in particular, not from any |
188 // table), i.e., each dispatcher must have a reference count of 1. This | 189 // handle in the handle table), i.e., the dispatcher must have a reference |
189 // message must not already have dispatchers. | 190 // count of 1. This message must not already have handles. |
| 191 void SetHandles(std::unique_ptr<HandleVector> handles); |
| 192 // TODO(vtl): Delete this. |
190 void SetDispatchers(std::unique_ptr<DispatcherVector> dispatchers); | 193 void SetDispatchers(std::unique_ptr<DispatcherVector> dispatchers); |
191 | 194 |
192 // Sets the |TransportData| for this message. This should only be done when | 195 // Sets the |TransportData| for this message. This should only be done when |
193 // there are no dispatchers and no existing |TransportData|. | 196 // there are no handles and no existing |TransportData|. |
194 void SetTransportData(std::unique_ptr<TransportData> transport_data); | 197 void SetTransportData(std::unique_ptr<TransportData> transport_data); |
195 | 198 |
196 // Serializes any dispatchers to the secondary buffer. This message must not | 199 // Serializes any handles to the secondary buffer. This message must not |
197 // already have a secondary buffer (so this must only be called once). The | 200 // already have a secondary buffer (so this must only be called once). The |
198 // caller must ensure (e.g., by holding on to a reference) that |channel| | 201 // caller must ensure (e.g., by holding on to a reference) that |channel| |
199 // stays alive through the call. | 202 // stays alive through the call. |
200 void SerializeAndCloseDispatchers(Channel* channel); | 203 void SerializeAndCloseHandles(Channel* channel); |
201 | 204 |
202 // Gets the main buffer and its size (in number of bytes), respectively. | 205 // Gets the main buffer and its size (in number of bytes), respectively. |
203 const void* main_buffer() const { return main_buffer_.get(); } | 206 const void* main_buffer() const { return main_buffer_.get(); } |
204 size_t main_buffer_size() const { return main_buffer_size_; } | 207 size_t main_buffer_size() const { return main_buffer_size_; } |
205 | 208 |
206 // Gets the transport data buffer (if any). | 209 // Gets the transport data buffer (if any). |
207 const TransportData* transport_data() const { return transport_data_.get(); } | 210 const TransportData* transport_data() const { return transport_data_.get(); } |
208 TransportData* transport_data() { return transport_data_.get(); } | 211 TransportData* transport_data() { return transport_data_.get(); } |
209 | 212 |
210 // Gets the total size of the message (see comment in |Header|, below). | 213 // Gets the total size of the message (see comment in |Header|, below). |
(...skipping 11 matching lines...) Expand all Loading... |
222 ChannelEndpointId source_id() const { return header()->source_id; } | 225 ChannelEndpointId source_id() const { return header()->source_id; } |
223 ChannelEndpointId destination_id() const { return header()->destination_id; } | 226 ChannelEndpointId destination_id() const { return header()->destination_id; } |
224 | 227 |
225 void set_source_id(ChannelEndpointId source_id) { | 228 void set_source_id(ChannelEndpointId source_id) { |
226 header()->source_id = source_id; | 229 header()->source_id = source_id; |
227 } | 230 } |
228 void set_destination_id(ChannelEndpointId destination_id) { | 231 void set_destination_id(ChannelEndpointId destination_id) { |
229 header()->destination_id = destination_id; | 232 header()->destination_id = destination_id; |
230 } | 233 } |
231 | 234 |
232 // Gets the dispatchers attached to this message; this may return null if | 235 // Gets the handles attached to this message; this may return null if there |
233 // there are none. Note that the caller may mutate the set of dispatchers | 236 // are none. Note that the caller may mutate the set of handles (e.g., take |
234 // (e.g., take ownership of all the dispatchers, leaving the vector empty). | 237 // ownership of all the handles, leaving the vector empty). |
235 DispatcherVector* dispatchers() { return dispatchers_.get(); } | 238 HandleVector* handles() { return handles_.get(); } |
236 | 239 |
237 // Returns true if this message has dispatchers attached. | 240 // Returns true if this message has handles attached. |
238 bool has_dispatchers() const { | 241 bool has_handles() const { return handles_ && !handles_->empty(); } |
239 return dispatchers_ && !dispatchers_->empty(); | |
240 } | |
241 | 242 |
242 // Rounds |n| up to a multiple of |kMessageAlignment|. | 243 // Rounds |n| up to a multiple of |kMessageAlignment|. |
243 static inline size_t RoundUpMessageAlignment(size_t n) { | 244 static inline size_t RoundUpMessageAlignment(size_t n) { |
244 return (n + kMessageAlignment - 1) & ~(kMessageAlignment - 1); | 245 return (n + kMessageAlignment - 1) & ~(kMessageAlignment - 1); |
245 } | 246 } |
246 | 247 |
247 private: | 248 private: |
248 // To allow us to make compile-assertions about |Header| in the .cc file. | 249 // To allow us to make compile-assertions about |Header| in the .cc file. |
249 struct PrivateStructForCompileAsserts; | 250 struct PrivateStructForCompileAsserts; |
250 | 251 |
251 // Header for the data (main buffer). Must be a multiple of | 252 // Header for the data (main buffer). Must be a multiple of |
252 // |kMessageAlignment| bytes in size. Must be POD. | 253 // |kMessageAlignment| bytes in size. Must be POD. |
253 struct Header { | 254 struct Header { |
254 // Total size of the message, including the header, the message data | 255 // Total size of the message, including the header, the message data |
255 // ("bytes") including padding (to make it a multiple of |kMessageAlignment| | 256 // ("bytes") including padding (to make it a multiple of |kMessageAlignment| |
256 // bytes), and serialized handle information. Note that this may not be the | 257 // bytes), and serialized handle information. Note that this may not be the |
257 // correct value if dispatchers are attached but | 258 // correct value if handles are attached but |SerializeAndCloseHandles()| |
258 // |SerializeAndCloseDispatchers()| has not been called. | 259 // has not been called. |
259 uint32_t total_size; | 260 uint32_t total_size; |
260 Type type; // 2 bytes. | 261 Type type; // 2 bytes. |
261 Subtype subtype; // 2 bytes. | 262 Subtype subtype; // 2 bytes. |
262 ChannelEndpointId source_id; // 4 bytes. | 263 ChannelEndpointId source_id; // 4 bytes. |
263 ChannelEndpointId destination_id; // 4 bytes. | 264 ChannelEndpointId destination_id; // 4 bytes. |
264 // Size of actual message data. | 265 // Size of actual message data. |
265 uint32_t num_bytes; | 266 uint32_t num_bytes; |
266 uint32_t unused; | 267 uint32_t unused; |
267 }; | 268 }; |
268 | 269 |
269 const Header* header() const { | 270 const Header* header() const { |
270 return reinterpret_cast<const Header*>(main_buffer_.get()); | 271 return reinterpret_cast<const Header*>(main_buffer_.get()); |
271 } | 272 } |
272 Header* header() { return reinterpret_cast<Header*>(main_buffer_.get()); } | 273 Header* header() { return reinterpret_cast<Header*>(main_buffer_.get()); } |
273 | 274 |
274 void ConstructorHelper(Type type, Subtype subtype, uint32_t num_bytes); | 275 void ConstructorHelper(Type type, Subtype subtype, uint32_t num_bytes); |
275 void UpdateTotalSize(); | 276 void UpdateTotalSize(); |
276 | 277 |
277 const size_t main_buffer_size_; | 278 const size_t main_buffer_size_; |
278 // Never null. | 279 // Never null. |
279 const platform::AlignedUniquePtr<char> main_buffer_; | 280 const platform::AlignedUniquePtr<char> main_buffer_; |
280 | 281 |
281 std::unique_ptr<TransportData> transport_data_; // May be null. | 282 std::unique_ptr<TransportData> transport_data_; // May be null. |
282 | 283 |
283 // Any dispatchers that may be attached to this message. These dispatchers | 284 // Any handles that may be attached to this message. These handles should be |
284 // should be "owned" by this message, i.e., have a ref count of exactly 1. (We | 285 // "owned" by this message, i.e., their dispatcher have a ref count of exactly |
285 // allow a dispatcher entry to be null, in case it couldn't be duplicated for | 286 // 1. (We allow a handle entry to be "null"/invalid, in case it couldn't be |
286 // some reason.) | 287 // duplicated for some reason.) |
287 std::unique_ptr<DispatcherVector> dispatchers_; | 288 std::unique_ptr<HandleVector> handles_; |
288 | 289 |
289 MOJO_DISALLOW_COPY_AND_ASSIGN(MessageInTransit); | 290 MOJO_DISALLOW_COPY_AND_ASSIGN(MessageInTransit); |
290 }; | 291 }; |
291 | 292 |
292 // So logging macros and |DCHECK_EQ()|, etc. work. | 293 // So logging macros and |DCHECK_EQ()|, etc. work. |
293 inline std::ostream& operator<<(std::ostream& out, | 294 inline std::ostream& operator<<(std::ostream& out, |
294 MessageInTransit::Type type) { | 295 MessageInTransit::Type type) { |
295 return out << static_cast<uint16_t>(type); | 296 return out << static_cast<uint16_t>(type); |
296 } | 297 } |
297 | 298 |
298 // So logging macros and |DCHECK_EQ()|, etc. work. | 299 // So logging macros and |DCHECK_EQ()|, etc. work. |
299 inline std::ostream& operator<<(std::ostream& out, | 300 inline std::ostream& operator<<(std::ostream& out, |
300 MessageInTransit::Subtype subtype) { | 301 MessageInTransit::Subtype subtype) { |
301 return out << static_cast<uint16_t>(subtype); | 302 return out << static_cast<uint16_t>(subtype); |
302 } | 303 } |
303 | 304 |
304 } // namespace system | 305 } // namespace system |
305 } // namespace mojo | 306 } // namespace mojo |
306 | 307 |
307 #endif // MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_ | 308 #endif // MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_ |
OLD | NEW |