Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Side by Side Diff: mojo/edk/system/message_in_transit.h

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/edk/system/memory_unittest.cc ('k') | mojo/edk/system/message_in_transit.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifndef MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_
6 #define MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <vector>
12
13 #include "base/macros.h"
14 #include "base/memory/aligned_memory.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "mojo/edk/system/channel_endpoint_id.h"
17 #include "mojo/edk/system/dispatcher.h"
18 #include "mojo/edk/system/memory.h"
19 #include "mojo/edk/system/system_impl_export.h"
20
21 namespace mojo {
22 namespace system {
23
24 class Channel;
25 class TransportData;
26
27 // This class is used to represent data in transit. It is thread-unsafe.
28 //
29 // |MessageInTransit| buffers:
30 //
31 // A |MessageInTransit| can be serialized by writing the main buffer and then,
32 // if it has one, the transport data buffer. Both buffers are
33 // |kMessageAlignment|-byte aligned and a multiple of |kMessageAlignment| bytes
34 // in size.
35 //
36 // The main buffer consists of the header (of type |Header|, which is an
37 // internal detail of this class) followed immediately by the message data
38 // (accessed by |bytes()| and of size |num_bytes()|, and also
39 // |kMessageAlignment|-byte aligned), and then any padding needed to make the
40 // main buffer a multiple of |kMessageAlignment| bytes in size.
41 //
42 // See |TransportData| for a description of the (serialized) transport data
43 // buffer.
44 class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit {
45 public:
46 typedef uint16_t Type;
47 // Messages that are forwarded to endpoints.
48 static const Type kTypeEndpoint = 0;
49 // Messages that are consumed by the |Channel|.
50 static const Type kTypeChannel = 1;
51 // Messages that are consumed by the |RawChannel| (implementation).
52 static const Type kTypeRawChannel = 2;
53
54 typedef uint16_t Subtype;
55 // Subtypes for type |kTypeEndpoint|:
56 static const Subtype kSubtypeEndpointData = 0;
57 // Subtypes for type |kTypeChannel|:
58 static const Subtype kSubtypeChannelAttachAndRunEndpoint = 0;
59 static const Subtype kSubtypeChannelRemoveEndpoint = 1;
60 static const Subtype kSubtypeChannelRemoveEndpointAck = 2;
61
62 // Subtypes for type |kTypeRawChannel|:
63 static const Subtype kSubtypeRawChannelPosixExtraPlatformHandles = 0;
64
65 // Messages (the header and data) must always be aligned to a multiple of this
66 // quantity (which must be a power of 2).
67 static const size_t kMessageAlignment = 8;
68
69 // Forward-declare |Header| so that |View| can use it:
70 private:
71 struct Header;
72
73 public:
74 // This represents a view of serialized message data in a raw buffer.
75 class MOJO_SYSTEM_IMPL_EXPORT View {
76 public:
77 // Constructs a view from the given buffer of the given size. (The size must
78 // be as provided by |MessageInTransit::GetNextMessageSize()|.) The buffer
79 // must remain alive/unmodified through the lifetime of this object.
80 // |buffer| should be |kMessageAlignment|-byte aligned.
81 View(size_t message_size, const void* buffer);
82
83 // Checks that the given |View| appears to be for a valid message, within
84 // predetermined limits (e.g., |num_bytes()| and |main_buffer_size()|, that
85 // |transport_data_buffer()|/|transport_data_buffer_size()| is for valid
86 // transport data -- see |TransportData::ValidateBuffer()|).
87 //
88 // It returns true (and leaves |error_message| alone) if this object appears
89 // to be a valid message (according to the above) and false, pointing
90 // |*error_message| to a suitable error message, if not.
91 bool IsValid(size_t serialized_platform_handle_size,
92 const char** error_message) const;
93
94 // API parallel to that for |MessageInTransit| itself (mostly getters for
95 // header data).
96 const void* main_buffer() const { return buffer_; }
97 size_t main_buffer_size() const {
98 return RoundUpMessageAlignment(sizeof(Header) + header()->num_bytes);
99 }
100 const void* transport_data_buffer() const {
101 return (total_size() > main_buffer_size())
102 ? static_cast<const char*>(buffer_) + main_buffer_size()
103 : nullptr;
104 }
105 size_t transport_data_buffer_size() const {
106 return total_size() - main_buffer_size();
107 }
108 size_t total_size() const { return header()->total_size; }
109 uint32_t num_bytes() const { return header()->num_bytes; }
110 const void* bytes() const {
111 return static_cast<const char*>(buffer_) + sizeof(Header);
112 }
113 Type type() const { return header()->type; }
114 Subtype subtype() const { return header()->subtype; }
115 ChannelEndpointId source_id() const { return header()->source_id; }
116 ChannelEndpointId destination_id() const {
117 return header()->destination_id;
118 }
119
120 private:
121 const Header* header() const { return static_cast<const Header*>(buffer_); }
122
123 const void* const buffer_;
124
125 // Though this struct is trivial, disallow copy and assign, since it doesn't
126 // own its data. (If you're copying/assigning this, you're probably doing
127 // something wrong.)
128 DISALLOW_COPY_AND_ASSIGN(View);
129 };
130
131 // |bytes| is optional; if null, the message data will be zero-initialized.
132 MessageInTransit(Type type,
133 Subtype subtype,
134 uint32_t num_bytes,
135 const void* bytes);
136 // |bytes| should be valid (and non-null), unless |num_bytes| is zero.
137 MessageInTransit(Type type,
138 Subtype subtype,
139 uint32_t num_bytes,
140 UserPointer<const void> bytes);
141 // Constructs a |MessageInTransit| from a |View|.
142 explicit MessageInTransit(const View& message_view);
143
144 ~MessageInTransit();
145
146 // Gets the size of the next message from |buffer|, which has |buffer_size|
147 // bytes currently available, returning true and setting |*next_message_size|
148 // on success. |buffer| should be aligned on a |kMessageAlignment| boundary
149 // (and on success, |*next_message_size| will be a multiple of
150 // |kMessageAlignment|).
151 // TODO(vtl): In |RawChannelPosix|, the alignment requirements are currently
152 // satisified on a faith-based basis.
153 static bool GetNextMessageSize(const void* buffer,
154 size_t buffer_size,
155 size_t* next_message_size);
156
157 // Makes this message "own" the given set of dispatchers. The dispatchers must
158 // not be referenced from anywhere else (in particular, not from the handle
159 // table), i.e., each dispatcher must have a reference count of 1. This
160 // message must not already have dispatchers.
161 void SetDispatchers(scoped_ptr<DispatcherVector> dispatchers);
162
163 // Sets the |TransportData| for this message. This should only be done when
164 // there are no dispatchers and no existing |TransportData|.
165 void SetTransportData(scoped_ptr<TransportData> transport_data);
166
167 // Serializes any dispatchers to the secondary buffer. This message must not
168 // already have a secondary buffer (so this must only be called once). The
169 // caller must ensure (e.g., by holding on to a reference) that |channel|
170 // stays alive through the call.
171 void SerializeAndCloseDispatchers(Channel* channel);
172
173 // Gets the main buffer and its size (in number of bytes), respectively.
174 const void* main_buffer() const { return main_buffer_.get(); }
175 size_t main_buffer_size() const { return main_buffer_size_; }
176
177 // Gets the transport data buffer (if any).
178 const TransportData* transport_data() const { return transport_data_.get(); }
179 TransportData* transport_data() { return transport_data_.get(); }
180
181 // Gets the total size of the message (see comment in |Header|, below).
182 size_t total_size() const { return header()->total_size; }
183
184 // Gets the size of the message data.
185 uint32_t num_bytes() const { return header()->num_bytes; }
186
187 // Gets the message data (of size |num_bytes()| bytes).
188 const void* bytes() const { return main_buffer_.get() + sizeof(Header); }
189 void* bytes() { return main_buffer_.get() + sizeof(Header); }
190
191 Type type() const { return header()->type; }
192 Subtype subtype() const { return header()->subtype; }
193 ChannelEndpointId source_id() const { return header()->source_id; }
194 ChannelEndpointId destination_id() const { return header()->destination_id; }
195
196 void set_source_id(ChannelEndpointId source_id) {
197 header()->source_id = source_id;
198 }
199 void set_destination_id(ChannelEndpointId destination_id) {
200 header()->destination_id = destination_id;
201 }
202
203 // Gets the dispatchers attached to this message; this may return null if
204 // there are none. Note that the caller may mutate the set of dispatchers
205 // (e.g., take ownership of all the dispatchers, leaving the vector empty).
206 DispatcherVector* dispatchers() { return dispatchers_.get(); }
207
208 // Returns true if this message has dispatchers attached.
209 bool has_dispatchers() const {
210 return dispatchers_ && !dispatchers_->empty();
211 }
212
213 // Rounds |n| up to a multiple of |kMessageAlignment|.
214 static inline size_t RoundUpMessageAlignment(size_t n) {
215 return (n + kMessageAlignment - 1) & ~(kMessageAlignment - 1);
216 }
217
218 private:
219 // To allow us to make compile-assertions about |Header| in the .cc file.
220 struct PrivateStructForCompileAsserts;
221
222 // Header for the data (main buffer). Must be a multiple of
223 // |kMessageAlignment| bytes in size. Must be POD.
224 struct Header {
225 // Total size of the message, including the header, the message data
226 // ("bytes") including padding (to make it a multiple of |kMessageAlignment|
227 // bytes), and serialized handle information. Note that this may not be the
228 // correct value if dispatchers are attached but
229 // |SerializeAndCloseDispatchers()| has not been called.
230 uint32_t total_size;
231 Type type; // 2 bytes.
232 Subtype subtype; // 2 bytes.
233 ChannelEndpointId source_id; // 4 bytes.
234 ChannelEndpointId destination_id; // 4 bytes.
235 // Size of actual message data.
236 uint32_t num_bytes;
237 uint32_t unused;
238 };
239
240 const Header* header() const {
241 return reinterpret_cast<const Header*>(main_buffer_.get());
242 }
243 Header* header() { return reinterpret_cast<Header*>(main_buffer_.get()); }
244
245 void ConstructorHelper(Type type, Subtype subtype, uint32_t num_bytes);
246 void UpdateTotalSize();
247
248 const size_t main_buffer_size_;
249 const scoped_ptr<char, base::AlignedFreeDeleter> main_buffer_; // Never null.
250
251 scoped_ptr<TransportData> transport_data_; // May be null.
252
253 // Any dispatchers that may be attached to this message. These dispatchers
254 // should be "owned" by this message, i.e., have a ref count of exactly 1. (We
255 // allow a dispatcher entry to be null, in case it couldn't be duplicated for
256 // some reason.)
257 scoped_ptr<DispatcherVector> dispatchers_;
258
259 DISALLOW_COPY_AND_ASSIGN(MessageInTransit);
260 };
261
262 } // namespace system
263 } // namespace mojo
264
265 #endif // MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_
OLDNEW
« no previous file with comments | « mojo/edk/system/memory_unittest.cc ('k') | mojo/edk/system/message_in_transit.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698