| 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_SYSTEM_MESSAGE_IN_TRANSIT_H_ | 5 #ifndef MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_ |
| 6 #define MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_ | 6 #define MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_ |
| 7 | 7 |
| 8 #include <stddef.h> |
| 8 #include <stdint.h> | 9 #include <stdint.h> |
| 9 | 10 |
| 10 #include <vector> | 11 #include <vector> |
| 11 | 12 |
| 12 #include "base/macros.h" | 13 #include "base/macros.h" |
| 13 #include "base/memory/aligned_memory.h" | 14 #include "base/memory/aligned_memory.h" |
| 14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 15 #include "mojo/embedder/platform_handle.h" | |
| 16 #include "mojo/system/dispatcher.h" | 16 #include "mojo/system/dispatcher.h" |
| 17 #include "mojo/system/system_impl_export.h" | 17 #include "mojo/system/system_impl_export.h" |
| 18 | 18 |
| 19 namespace mojo { | 19 namespace mojo { |
| 20 namespace system { | 20 namespace system { |
| 21 | 21 |
| 22 class Channel; | 22 class Channel; |
| 23 class TransportData; |
| 23 | 24 |
| 24 // This class is used to represent data in transit. It is thread-unsafe. | 25 // This class is used to represent data in transit. It is thread-unsafe. |
| 25 // | 26 // |
| 26 // |MessageInTransit| buffers: | 27 // |MessageInTransit| buffers: |
| 27 // | 28 // |
| 28 // A |MessageInTransit| can be serialized by writing the main buffer and then, | 29 // A |MessageInTransit| can be serialized by writing the main buffer and then, |
| 29 // if it has one, the secondary buffer. Both buffers are | 30 // if it has one, the transport data buffer. Both buffers are |
| 30 // |kMessageAlignment|-byte aligned and a multiple of |kMessageAlignment| bytes | 31 // |kMessageAlignment|-byte aligned and a multiple of |kMessageAlignment| bytes |
| 31 // in size. | 32 // in size. |
| 32 // | 33 // |
| 33 // The main buffer consists of the header (of type |Header|, which is an | 34 // The main buffer consists of the header (of type |Header|, which is an |
| 34 // internal detail of this class) followed immediately by the message data | 35 // internal detail of this class) followed immediately by the message data |
| 35 // (accessed by |bytes()| and of size |num_bytes()|, and also | 36 // (accessed by |bytes()| and of size |num_bytes()|, and also |
| 36 // |kMessageAlignment|-byte aligned), and then any padding needed to make the | 37 // |kMessageAlignment|-byte aligned), and then any padding needed to make the |
| 37 // main buffer a multiple of |kMessageAlignment| bytes in size. | 38 // main buffer a multiple of |kMessageAlignment| bytes in size. |
| 38 // | 39 // |
| 39 // The secondary buffer consists first of a table of |HandleTableEntry|s (each | 40 // See |TransportData| for a description of the (serialized) transport data |
| 40 // of which is already a multiple of |kMessageAlignment| in size), followed by | 41 // buffer. |
| 41 // data needed for the |HandleTableEntry|s: A |HandleTableEntry| consists of an | |
| 42 // offset (in bytes, relative to the start of the secondary buffer; we guarantee | |
| 43 // that it's a multiple of |kMessageAlignment|), and a size (in bytes). | |
| 44 class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit { | 42 class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit { |
| 45 public: | 43 public: |
| 46 typedef uint16_t Type; | 44 typedef uint16_t Type; |
| 47 // Messages that are forwarded to |MessagePipeEndpoint|s. | 45 // Messages that are forwarded to |MessagePipeEndpoint|s. |
| 48 static const Type kTypeMessagePipeEndpoint = 0; | 46 static const Type kTypeMessagePipeEndpoint = 0; |
| 49 // Messages that are forwarded to |MessagePipe|s. | 47 // Messages that are forwarded to |MessagePipe|s. |
| 50 static const Type kTypeMessagePipe = 1; | 48 static const Type kTypeMessagePipe = 1; |
| 51 // Messages that are consumed by the channel. | 49 // Messages that are consumed by the channel. |
| 52 static const Type kTypeChannel = 2; | 50 static const Type kTypeChannel = 2; |
| 53 | 51 |
| 54 typedef uint16_t Subtype; | 52 typedef uint16_t Subtype; |
| 55 // Subtypes for type |kTypeMessagePipeEndpoint|: | 53 // Subtypes for type |kTypeMessagePipeEndpoint|: |
| 56 static const Subtype kSubtypeMessagePipeEndpointData = 0; | 54 static const Subtype kSubtypeMessagePipeEndpointData = 0; |
| 57 // Subtypes for type |kTypeMessagePipe|: | 55 // Subtypes for type |kTypeMessagePipe|: |
| 58 // Nothing currently. | 56 // Nothing currently. |
| 59 // Subtypes for type |kTypeChannel|: | 57 // Subtypes for type |kTypeChannel|: |
| 60 static const Subtype kSubtypeChannelRunMessagePipeEndpoint = 0; | 58 static const Subtype kSubtypeChannelRunMessagePipeEndpoint = 0; |
| 61 static const Subtype kSubtypeChannelRemoveMessagePipeEndpoint = 1; | 59 static const Subtype kSubtypeChannelRemoveMessagePipeEndpoint = 1; |
| 62 static const Subtype kSubtypeChannelRemoveMessagePipeEndpointAck = 2; | 60 static const Subtype kSubtypeChannelRemoveMessagePipeEndpointAck = 2; |
| 63 | 61 |
| 64 typedef uint32_t EndpointId; | 62 typedef uint32_t EndpointId; |
| 65 // Never a valid endpoint ID. | 63 // Never a valid endpoint ID. |
| 66 static const EndpointId kInvalidEndpointId = 0; | 64 static const EndpointId kInvalidEndpointId = 0; |
| 67 | 65 |
| 68 // Messages (the header and data) must always be aligned to a multiple of this | 66 // Messages (the header and data) must always be aligned to a multiple of this |
| 69 // quantity (which must be a power of 2). | 67 // quantity (which must be a power of 2). |
| 70 static const size_t kMessageAlignment = 8; | 68 static const size_t kMessageAlignment = 8; |
| 71 | 69 |
| 72 // The maximum size of a single serialized dispatcher. This must be a multiple | |
| 73 // of |kMessageAlignment|. | |
| 74 static const size_t kMaxSerializedDispatcherSize = 10000; | |
| 75 | |
| 76 // The maximum number of platform handles to attach for a single serialized | |
| 77 // dispatcher. | |
| 78 static const size_t kMaxSerializedDispatcherPlatformHandles = 2; | |
| 79 | |
| 80 // Forward-declare |Header| so that |View| can use it: | 70 // Forward-declare |Header| so that |View| can use it: |
| 81 private: | 71 private: |
| 82 struct Header; | 72 struct Header; |
| 83 public: | 73 public: |
| 84 // This represents a view of serialized message data in a raw buffer. | 74 // This represents a view of serialized message data in a raw buffer. |
| 85 class MOJO_SYSTEM_IMPL_EXPORT View { | 75 class MOJO_SYSTEM_IMPL_EXPORT View { |
| 86 public: | 76 public: |
| 87 // Constructs a view from the given buffer of the given size. (The size must | 77 // Constructs a view from the given buffer of the given size. (The size must |
| 88 // be as provided by |MessageInTransit::GetNextMessageSize()|.) The buffer | 78 // be as provided by |MessageInTransit::GetNextMessageSize()|.) The buffer |
| 89 // must remain alive/unmodified through the lifetime of this object. | 79 // must remain alive/unmodified through the lifetime of this object. |
| 90 // |buffer| should be |kMessageAlignment|-byte aligned. | 80 // |buffer| should be |kMessageAlignment|-byte aligned. |
| 91 View(size_t message_size, const void* buffer); | 81 View(size_t message_size, const void* buffer); |
| 92 | 82 |
| 93 // Checks the following things versus pre-determined limits: | 83 // Checks that the given |View| appears to be for a valid message, within |
| 94 // - |num_bytes()| and |main_buffer_size()|, | 84 // predetermined limits (e.g., |num_bytes()| and |main_buffer_size()|, that |
| 95 // - |num_handles()| and |secondary_buffer_size()|, | 85 // |transport_data_buffer()|/|transport_data_buffer_size()| is for valid |
| 96 // - the entries in the handle entry table (that the sizes and offsets are | 86 // transport data -- see |TransportData::ValidateBuffer()|). |
| 97 // valid). | |
| 98 // Note: It does not check the serialized dispatcher data itself. | |
| 99 // | 87 // |
| 100 // It returns true (and leaves |error_message| alone) if this object appears | 88 // It returns true (and leaves |error_message| alone) if this object appears |
| 101 // to be a valid message (according to the above) and false, pointing | 89 // to be a valid message (according to the above) and false, pointing |
| 102 // |*error_message| to a suitable error message, if not. | 90 // |*error_message| to a suitable error message, if not. |
| 103 bool IsValid(const char** error_message) const; | 91 bool IsValid(const char** error_message) const; |
| 104 | 92 |
| 105 // API parallel to that for |MessageInTransit| itself (mostly getters for | 93 // API parallel to that for |MessageInTransit| itself (mostly getters for |
| 106 // header data). | 94 // header data). |
| 107 const void* main_buffer() const { return buffer_; } | 95 const void* main_buffer() const { return buffer_; } |
| 108 size_t main_buffer_size() const { | 96 size_t main_buffer_size() const { |
| 109 return RoundUpMessageAlignment(sizeof(Header) + header()->num_bytes); | 97 return RoundUpMessageAlignment(sizeof(Header) + header()->num_bytes); |
| 110 } | 98 } |
| 111 const void* secondary_buffer() const { | 99 const void* transport_data_buffer() const { |
| 112 return (total_size() > main_buffer_size()) ? | 100 return (total_size() > main_buffer_size()) ? |
| 113 static_cast<const char*>(buffer_) + main_buffer_size() : NULL; | 101 static_cast<const char*>(buffer_) + main_buffer_size() : NULL; |
| 114 } | 102 } |
| 115 size_t secondary_buffer_size() const { | 103 size_t transport_data_buffer_size() const { |
| 116 return total_size() - main_buffer_size(); | 104 return total_size() - main_buffer_size(); |
| 117 } | 105 } |
| 118 size_t total_size() const { return header()->total_size; } | 106 size_t total_size() const { return header()->total_size; } |
| 119 uint32_t num_bytes() const { return header()->num_bytes; } | 107 uint32_t num_bytes() const { return header()->num_bytes; } |
| 120 const void* bytes() const { | 108 const void* bytes() const { |
| 121 return static_cast<const char*>(buffer_) + sizeof(Header); | 109 return static_cast<const char*>(buffer_) + sizeof(Header); |
| 122 } | 110 } |
| 123 uint32_t num_handles() const { return header()->num_handles; } | |
| 124 Type type() const { return header()->type; } | 111 Type type() const { return header()->type; } |
| 125 Subtype subtype() const { return header()->subtype; } | 112 Subtype subtype() const { return header()->subtype; } |
| 126 EndpointId source_id() const { return header()->source_id; } | 113 EndpointId source_id() const { return header()->source_id; } |
| 127 EndpointId destination_id() const { return header()->destination_id; } | 114 EndpointId destination_id() const { return header()->destination_id; } |
| 128 | 115 |
| 129 private: | 116 private: |
| 130 const Header* header() const { return static_cast<const Header*>(buffer_); } | 117 const Header* header() const { return static_cast<const Header*>(buffer_); } |
| 131 | 118 |
| 132 const void* const buffer_; | 119 const void* const buffer_; |
| 133 | 120 |
| 134 // Though this struct is trivial, disallow copy and assign, since it doesn't | 121 // Though this struct is trivial, disallow copy and assign, since it doesn't |
| 135 // own its data. (If you're copying/assigning this, you're probably doing | 122 // own its data. (If you're copying/assigning this, you're probably doing |
| 136 // something wrong.) | 123 // something wrong.) |
| 137 DISALLOW_COPY_AND_ASSIGN(View); | 124 DISALLOW_COPY_AND_ASSIGN(View); |
| 138 }; | 125 }; |
| 139 | 126 |
| 140 // |bytes| is optional; if null, the message data will be zero-initialized. | 127 // |bytes| is optional; if null, the message data will be zero-initialized. |
| 141 MessageInTransit(Type type, | 128 MessageInTransit(Type type, |
| 142 Subtype subtype, | 129 Subtype subtype, |
| 143 uint32_t num_bytes, | 130 uint32_t num_bytes, |
| 144 uint32_t num_handles, | |
| 145 const void* bytes); | 131 const void* bytes); |
| 146 // Constructs a |MessageInTransit| from a |View|. | 132 // Constructs a |MessageInTransit| from a |View|. |
| 147 explicit MessageInTransit(const View& message_view); | 133 explicit MessageInTransit(const View& message_view); |
| 148 | 134 |
| 149 ~MessageInTransit(); | 135 ~MessageInTransit(); |
| 150 | 136 |
| 151 // Gets the size of the next message from |buffer|, which has |buffer_size| | 137 // Gets the size of the next message from |buffer|, which has |buffer_size| |
| 152 // bytes currently available, returning true and setting |*next_message_size| | 138 // bytes currently available, returning true and setting |*next_message_size| |
| 153 // on success. |buffer| should be aligned on a |kMessageAlignment| boundary | 139 // on success. |buffer| should be aligned on a |kMessageAlignment| boundary |
| 154 // (and on success, |*next_message_size| will be a multiple of | 140 // (and on success, |*next_message_size| will be a multiple of |
| (...skipping 10 matching lines...) Expand all Loading... |
| 165 // message must not already have dispatchers. | 151 // message must not already have dispatchers. |
| 166 void SetDispatchers( | 152 void SetDispatchers( |
| 167 scoped_ptr<std::vector<scoped_refptr<Dispatcher> > > dispatchers); | 153 scoped_ptr<std::vector<scoped_refptr<Dispatcher> > > dispatchers); |
| 168 | 154 |
| 169 // Serializes any dispatchers to the secondary buffer. This message must not | 155 // Serializes any dispatchers to the secondary buffer. This message must not |
| 170 // already have a secondary buffer (so this must only be called once). The | 156 // already have a secondary buffer (so this must only be called once). The |
| 171 // caller must ensure (e.g., by holding on to a reference) that |channel| | 157 // caller must ensure (e.g., by holding on to a reference) that |channel| |
| 172 // stays alive through the call. | 158 // stays alive through the call. |
| 173 void SerializeAndCloseDispatchers(Channel* channel); | 159 void SerializeAndCloseDispatchers(Channel* channel); |
| 174 | 160 |
| 175 // Deserializes any dispatchers from the secondary buffer. This message must | |
| 176 // not have any dispatchers attached. | |
| 177 // TODO(vtl): Having to copy the secondary buffer (in the constructor from a | |
| 178 // |View|) is suboptimal. Maybe this should just be done in the constructor? | |
| 179 void DeserializeDispatchers(Channel* channel); | |
| 180 | |
| 181 // Gets the main buffer and its size (in number of bytes), respectively. | 161 // Gets the main buffer and its size (in number of bytes), respectively. |
| 182 const void* main_buffer() const { return main_buffer_.get(); } | 162 const void* main_buffer() const { return main_buffer_.get(); } |
| 183 size_t main_buffer_size() const { return main_buffer_size_; } | 163 size_t main_buffer_size() const { return main_buffer_size_; } |
| 184 | 164 |
| 185 // Gets the secondary buffer and its size (in number of bytes), respectively. | 165 // Gets the transport data buffer (if any). |
| 186 const void* secondary_buffer() const { return secondary_buffer_.get(); } | 166 const TransportData* transport_data() const { return transport_data_.get(); } |
| 187 size_t secondary_buffer_size() const { return secondary_buffer_size_; } | |
| 188 | 167 |
| 189 // Gets the total size of the message (see comment in |Header|, below). | 168 // Gets the total size of the message (see comment in |Header|, below). |
| 190 size_t total_size() const { return header()->total_size; } | 169 size_t total_size() const { return header()->total_size; } |
| 191 | 170 |
| 192 // Gets the size of the message data. | 171 // Gets the size of the message data. |
| 193 uint32_t num_bytes() const { return header()->num_bytes; } | 172 uint32_t num_bytes() const { return header()->num_bytes; } |
| 194 | 173 |
| 195 // Gets the message data (of size |num_bytes()| bytes). | 174 // Gets the message data (of size |num_bytes()| bytes). |
| 196 const void* bytes() const { return main_buffer_.get() + sizeof(Header); } | 175 const void* bytes() const { return main_buffer_.get() + sizeof(Header); } |
| 197 void* bytes() { return main_buffer_.get() + sizeof(Header); } | 176 void* bytes() { return main_buffer_.get() + sizeof(Header); } |
| 198 | 177 |
| 199 uint32_t num_handles() const { return header()->num_handles; } | |
| 200 | |
| 201 Type type() const { return header()->type; } | 178 Type type() const { return header()->type; } |
| 202 Subtype subtype() const { return header()->subtype; } | 179 Subtype subtype() const { return header()->subtype; } |
| 203 EndpointId source_id() const { return header()->source_id; } | 180 EndpointId source_id() const { return header()->source_id; } |
| 204 EndpointId destination_id() const { return header()->destination_id; } | 181 EndpointId destination_id() const { return header()->destination_id; } |
| 205 | 182 |
| 206 void set_source_id(EndpointId source_id) { header()->source_id = source_id; } | 183 void set_source_id(EndpointId source_id) { header()->source_id = source_id; } |
| 207 void set_destination_id(EndpointId destination_id) { | 184 void set_destination_id(EndpointId destination_id) { |
| 208 header()->destination_id = destination_id; | 185 header()->destination_id = destination_id; |
| 209 } | 186 } |
| 210 | 187 |
| 211 // Gets the dispatchers attached to this message; this may return null if | 188 // Gets the dispatchers attached to this message; this may return null if |
| 212 // there are none. Note that the caller may mutate the set of dispatchers | 189 // there are none. Note that the caller may mutate the set of dispatchers |
| 213 // (e.g., take ownership of all the dispatchers, leaving the vector empty). | 190 // (e.g., take ownership of all the dispatchers, leaving the vector empty). |
| 214 std::vector<scoped_refptr<Dispatcher> >* dispatchers() { | 191 std::vector<scoped_refptr<Dispatcher> >* dispatchers() { |
| 215 return dispatchers_.get(); | 192 return dispatchers_.get(); |
| 216 } | 193 } |
| 217 | 194 |
| 218 // Returns true if this message has dispatchers attached. | 195 // Returns true if this message has dispatchers attached. |
| 219 bool has_dispatchers() const { | 196 bool has_dispatchers() const { |
| 220 return dispatchers_ && !dispatchers_->empty(); | 197 return dispatchers_ && !dispatchers_->empty(); |
| 221 } | 198 } |
| 222 | 199 |
| 223 // Gets the platform-specific handles attached to this message; this may | |
| 224 // return null if there are none. Note that the caller may mutate the set of | |
| 225 // platform-specific handles. | |
| 226 std::vector<embedder::PlatformHandle>* platform_handles() { | |
| 227 return platform_handles_.get(); | |
| 228 } | |
| 229 | |
| 230 // Returns true if this message has platform-specific handles attached. | |
| 231 bool has_platform_handles() const { | |
| 232 return platform_handles_ && !platform_handles_->empty(); | |
| 233 } | |
| 234 | |
| 235 // Rounds |n| up to a multiple of |kMessageAlignment|. | 200 // Rounds |n| up to a multiple of |kMessageAlignment|. |
| 236 static inline size_t RoundUpMessageAlignment(size_t n) { | 201 static inline size_t RoundUpMessageAlignment(size_t n) { |
| 237 return (n + kMessageAlignment - 1) & ~(kMessageAlignment - 1); | 202 return (n + kMessageAlignment - 1) & ~(kMessageAlignment - 1); |
| 238 } | 203 } |
| 239 | 204 |
| 240 private: | 205 private: |
| 241 // To allow us to make assertions about |Header| in the .cc file. | 206 // To allow us to make compile-assertions about |Header| in the .cc file. |
| 242 struct PrivateStructForCompileAsserts; | 207 struct PrivateStructForCompileAsserts; |
| 243 | 208 |
| 244 // Header for the data (main buffer). Must be a multiple of | 209 // Header for the data (main buffer). Must be a multiple of |
| 245 // |kMessageAlignment| bytes in size. Must be POD. | 210 // |kMessageAlignment| bytes in size. Must be POD. |
| 246 struct Header { | 211 struct Header { |
| 247 // Total size of the message, including the header, the message data | 212 // Total size of the message, including the header, the message data |
| 248 // ("bytes") including padding (to make it a multiple of |kMessageAlignment| | 213 // ("bytes") including padding (to make it a multiple of |kMessageAlignment| |
| 249 // bytes), and serialized handle information. Note that this may not be the | 214 // bytes), and serialized handle information. Note that this may not be the |
| 250 // correct value if dispatchers are attached but | 215 // correct value if dispatchers are attached but |
| 251 // |SerializeAndCloseDispatchers()| has not been called. | 216 // |SerializeAndCloseDispatchers()| has not been called. |
| 252 uint32_t total_size; | 217 uint32_t total_size; |
| 253 Type type; // 2 bytes. | 218 Type type; // 2 bytes. |
| 254 Subtype subtype; // 2 bytes. | 219 Subtype subtype; // 2 bytes. |
| 255 EndpointId source_id; // 4 bytes. | 220 EndpointId source_id; // 4 bytes. |
| 256 EndpointId destination_id; // 4 bytes. | 221 EndpointId destination_id; // 4 bytes. |
| 257 // Size of actual message data. | 222 // Size of actual message data. |
| 258 uint32_t num_bytes; | 223 uint32_t num_bytes; |
| 259 // Number of handles "attached". | |
| 260 uint32_t num_handles; | |
| 261 }; | |
| 262 | |
| 263 struct HandleTableEntry { | |
| 264 int32_t type; // From |Dispatcher::Type| (|kTypeUnknown| for "invalid"). | |
| 265 uint32_t offset; // Relative to the start of the secondary buffer. | |
| 266 uint32_t size; // (Not including any padding.) | |
| 267 uint32_t unused; | 224 uint32_t unused; |
| 268 }; | 225 }; |
| 269 | 226 |
| 270 // The maximum possible size of a valid secondary buffer. | |
| 271 static const size_t kMaxSecondaryBufferSize; | |
| 272 | |
| 273 // The maximum total number of platform handles that may be attached. | |
| 274 static const size_t kMaxPlatformHandles; | |
| 275 | |
| 276 // Validates the secondary buffer. Returns null on success, or a | |
| 277 // human-readable error message (meant for logging/debugging) on error. | |
| 278 static const char* ValidateSecondaryBuffer(size_t num_handles, | |
| 279 const void* secondary_buffer, | |
| 280 size_t secondary_buffer_size); | |
| 281 | |
| 282 const Header* header() const { | 227 const Header* header() const { |
| 283 return reinterpret_cast<const Header*>(main_buffer_.get()); | 228 return reinterpret_cast<const Header*>(main_buffer_.get()); |
| 284 } | 229 } |
| 285 Header* header() { return reinterpret_cast<Header*>(main_buffer_.get()); } | 230 Header* header() { return reinterpret_cast<Header*>(main_buffer_.get()); } |
| 286 | 231 |
| 287 void UpdateTotalSize(); | 232 void UpdateTotalSize(); |
| 288 | 233 |
| 289 const size_t main_buffer_size_; | 234 const size_t main_buffer_size_; |
| 290 const scoped_ptr<char, base::AlignedFreeDeleter> main_buffer_; // Never null. | 235 const scoped_ptr<char, base::AlignedFreeDeleter> main_buffer_; // Never null. |
| 291 | 236 |
| 292 size_t secondary_buffer_size_; | 237 scoped_ptr<TransportData> transport_data_; // May be null. |
| 293 scoped_ptr<char, base::AlignedFreeDeleter> secondary_buffer_; // May be null. | |
| 294 | 238 |
| 295 // Any dispatchers that may be attached to this message. These dispatchers | 239 // Any dispatchers that may be attached to this message. These dispatchers |
| 296 // should be "owned" by this message, i.e., have a ref count of exactly 1. (We | 240 // should be "owned" by this message, i.e., have a ref count of exactly 1. (We |
| 297 // allow a dispatcher entry to be null, in case it couldn't be duplicated for | 241 // allow a dispatcher entry to be null, in case it couldn't be duplicated for |
| 298 // some reason.) | 242 // some reason.) |
| 299 scoped_ptr<std::vector<scoped_refptr<Dispatcher> > > dispatchers_; | 243 scoped_ptr<std::vector<scoped_refptr<Dispatcher> > > dispatchers_; |
| 300 | 244 |
| 301 // Any platform-specific handles attached to this message (for inter-process | |
| 302 // transport). The vector (if any) owns the handles that it contains (and is | |
| 303 // responsible for closing them). | |
| 304 // TODO(vtl): With C++11, change it to a vector of |ScopedPlatformHandles|. | |
| 305 scoped_ptr<std::vector<embedder::PlatformHandle> > platform_handles_; | |
| 306 | |
| 307 DISALLOW_COPY_AND_ASSIGN(MessageInTransit); | 245 DISALLOW_COPY_AND_ASSIGN(MessageInTransit); |
| 308 }; | 246 }; |
| 309 | 247 |
| 310 } // namespace system | 248 } // namespace system |
| 311 } // namespace mojo | 249 } // namespace mojo |
| 312 | 250 |
| 313 #endif // MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_ | 251 #endif // MOJO_SYSTEM_MESSAGE_IN_TRANSIT_H_ |
| OLD | NEW |