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

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

Issue 1649633002: Remove files that are no longer used in the Port EDK. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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/child_broker_host.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 <ostream>
12 #include <vector>
13
14 #include "base/memory/aligned_memory.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "mojo/edk/system/dispatcher.h"
17 #include "mojo/edk/system/system_impl_export.h"
18 #include "mojo/public/cpp/system/macros.h"
19
20 namespace mojo {
21 namespace edk {
22
23 class RawChannel;
24 class TransportData;
25
26 // This class is used to represent data in transit. It is thread-unsafe.
27 //
28 // |MessageInTransit| buffers:
29 //
30 // A |MessageInTransit| can be serialized by writing the main buffer and then,
31 // if it has one, the transport data buffer. Both buffers are
32 // |kMessageAlignment|-byte aligned and a multiple of |kMessageAlignment| bytes
33 // in size.
34 //
35 // The main buffer consists of the header (of type |Header|, which is an
36 // internal detail of this class) followed immediately by the message data
37 // (accessed by |bytes()| and of size |num_bytes()|, and also
38 // |kMessageAlignment|-byte aligned), and then any padding needed to make the
39 // main buffer a multiple of |kMessageAlignment| bytes in size.
40 //
41 // See |TransportData| for a description of the (serialized) transport data
42 // buffer.
43 class MOJO_SYSTEM_IMPL_EXPORT MessageInTransit {
44 public:
45 enum class Type : uint16_t {
46 MESSAGE = 0,
47 // Since there's a limit on how many fds can be sent in one sendmsg call, if
48 // a message has more than that the fds are sent in this message type first.
49 RAW_CHANNEL_POSIX_EXTRA_PLATFORM_HANDLES,
50 // When a RawChannel is serialized, there could be pending messages to be
51 // written to the pipe. They are serialized to shared memory. When they're
52 // deserialized on the receiving end, we want to write them to the pipe
53 // without any message headers, because those have already been written.
54 RAW_MESSAGE,
55 // Tells the other side to close its pipe. This is needed because when a
56 // MessagePipeDispatcher is closed, it has to wait to flush any pending
57 // messages or else in-flight message pipes won't be closed.
58 QUIT_MESSAGE,
59 };
60
61 // Messages (the header and data) must always be aligned to a multiple of this
62 // quantity (which must be a power of 2).
63 static const size_t kMessageAlignment = 8;
64
65 // Forward-declare |Header| so that |View| can use it:
66 private:
67 struct Header;
68
69 public:
70 // This represents a view of serialized message data in a raw buffer.
71 class MOJO_SYSTEM_IMPL_EXPORT View {
72 public:
73 // Constructs a view from the given buffer of the given size. (The size must
74 // be as provided by |MessageInTransit::GetNextMessageSize()|.) The buffer
75 // must remain alive/unmodified through the lifetime of this object.
76 // |buffer| should be |kMessageAlignment|-byte aligned.
77 View(size_t message_size, const void* buffer);
78
79 // Checks that the given |View| appears to be for a valid message, within
80 // predetermined limits (e.g., |num_bytes()| and |main_buffer_size()|, that
81 // |transport_data_buffer()|/|transport_data_buffer_size()| is for valid
82 // transport data -- see |TransportData::ValidateBuffer()|).
83 //
84 // It returns true (and leaves |error_message| alone) if this object appears
85 // to be a valid message (according to the above) and false, pointing
86 // |*error_message| to a suitable error message, if not.
87 bool IsValid(size_t serialized_platform_handle_size,
88 const char** error_message) const;
89
90 // API parallel to that for |MessageInTransit| itself (mostly getters for
91 // header data).
92 const void* main_buffer() const { return buffer_; }
93 size_t main_buffer_size() const {
94 return RoundUpMessageAlignment(sizeof(Header) + header()->num_bytes);
95 }
96 const void* transport_data_buffer() const {
97 return (total_size() > main_buffer_size())
98 ? static_cast<const char*>(buffer_) + main_buffer_size()
99 : nullptr;
100 }
101 size_t transport_data_buffer_size() const {
102 return total_size() - main_buffer_size();
103 }
104 size_t total_size() const { return header()->total_size; }
105 uint32_t num_bytes() const { return header()->num_bytes; }
106 const void* bytes() const {
107 return static_cast<const char*>(buffer_) + sizeof(Header);
108 }
109 Type type() const { return header()->type; }
110 uint64_t route_id() const { return header()->route_id; }
111
112 private:
113 const Header* header() const { return static_cast<const Header*>(buffer_); }
114
115 const void* const buffer_;
116
117 // Though this struct is trivial, disallow copy and assign, since it doesn't
118 // own its data. (If you're copying/assigning this, you're probably doing
119 // something wrong.)
120 MOJO_DISALLOW_COPY_AND_ASSIGN(View);
121 };
122
123 // |bytes| is optional; if null, the message data will be zero-initialized.
124 MessageInTransit(Type type,
125 uint32_t num_bytes,
126 const void* bytes);
127 // Constructs a |MessageInTransit| from a |View|.
128 explicit MessageInTransit(const View& message_view);
129
130 ~MessageInTransit();
131
132 // Gets the size of the next message from |buffer|, which has |buffer_size|
133 // bytes currently available, returning true and setting |*next_message_size|
134 // on success. |buffer| should be aligned on a |kMessageAlignment| boundary
135 // (and on success, |*next_message_size| will be a multiple of
136 // |kMessageAlignment|).
137 // TODO(vtl): In |RawChannelPosix|, the alignment requirements are currently
138 // satisified on a faith-based basis.
139 static bool GetNextMessageSize(const void* buffer,
140 size_t buffer_size,
141 size_t* next_message_size);
142
143 // Makes this message "own" the given set of dispatchers. The dispatchers must
144 // not be referenced from anywhere else (in particular, not from the handle
145 // table), i.e., each dispatcher must have a reference count of 1. This
146 // message must not already have dispatchers.
147 void SetDispatchers(scoped_ptr<DispatcherVector> dispatchers);
148
149 // Sets the |TransportData| for this message. This should only be done when
150 // there are no dispatchers and no existing |TransportData|.
151 void SetTransportData(scoped_ptr<TransportData> transport_data);
152
153 // Serializes any dispatchers to the secondary buffer. This message must not
154 // already have a secondary buffer (so this must only be called once). The
155 // caller must ensure (e.g., by holding on to a reference) that |channel|
156 // stays alive through the call.
157 void SerializeAndCloseDispatchers();
158
159 // Gets the main buffer and its size (in number of bytes), respectively.
160 const void* main_buffer() const { return main_buffer_.get(); }
161 size_t main_buffer_size() const { return main_buffer_size_; }
162
163 // Gets the transport data buffer (if any).
164 const TransportData* transport_data() const { return transport_data_.get(); }
165 TransportData* transport_data() { return transport_data_.get(); }
166
167 // Gets the total size of the message (see comment in |Header|, below).
168 size_t total_size() const { return header()->total_size; }
169
170 // Gets the size of the message data.
171 uint32_t num_bytes() const { return header()->num_bytes; }
172
173 // Gets the message data (of size |num_bytes()| bytes).
174 const void* bytes() const { return main_buffer_.get() + sizeof(Header); }
175 void* bytes() { return main_buffer_.get() + sizeof(Header); }
176
177 Type type() const { return header()->type; }
178
179 void set_route_id(uint64_t route_id) { header()->route_id = route_id; }
180 uint64_t route_id() const { return header()->route_id; }
181
182 // Gets the dispatchers attached to this message; this may return null if
183 // there are none. Note that the caller may mutate the set of dispatchers
184 // (e.g., take ownership of all the dispatchers, leaving the vector empty).
185 DispatcherVector* dispatchers() { return dispatchers_.get(); }
186
187 // Returns true if this message has dispatchers attached.
188 bool has_dispatchers() const {
189 return dispatchers_ && !dispatchers_->empty();
190 }
191
192 // Rounds |n| up to a multiple of |kMessageAlignment|.
193 static inline size_t RoundUpMessageAlignment(size_t n) {
194 return (n + kMessageAlignment - 1) & ~(kMessageAlignment - 1);
195 }
196
197 private:
198 // To allow us to make compile-assertions about |Header| in the .cc file.
199 struct PrivateStructForCompileAsserts;
200
201 // Header for the data (main buffer). Must be a multiple of
202 // |kMessageAlignment| bytes in size. Must be POD.
203 struct Header {
204 // Total size of the message, including the header, the message data
205 // ("bytes") including padding (to make it a multiple of |kMessageAlignment|
206 // bytes), and serialized handle information. Note that this may not be the
207 // correct value if dispatchers are attached but
208 // |SerializeAndCloseDispatchers()| has not been called.
209 uint32_t total_size;
210 Type type; // 2 bytes.
211 uint16_t unusedforalignment; // 2 bytes.
212 uint32_t num_bytes;
213 uint32_t unused;
214 uint64_t route_id;
215 };
216
217 const Header* header() const {
218 return reinterpret_cast<const Header*>(main_buffer_.get());
219 }
220 Header* header() { return reinterpret_cast<Header*>(main_buffer_.get()); }
221
222 void ConstructorHelper(Type type, uint32_t num_bytes);
223 void UpdateTotalSize();
224
225 const size_t main_buffer_size_;
226 const scoped_ptr<char, base::AlignedFreeDeleter> main_buffer_; // Never null.
227
228 scoped_ptr<TransportData> transport_data_; // May be null.
229
230 // Any dispatchers that may be attached to this message. These dispatchers
231 // should be "owned" by this message, i.e., have a ref count of exactly 1. (We
232 // allow a dispatcher entry to be null, in case it couldn't be duplicated for
233 // some reason.)
234 scoped_ptr<DispatcherVector> dispatchers_;
235
236 MOJO_DISALLOW_COPY_AND_ASSIGN(MessageInTransit);
237 };
238
239 // So logging macros and |DCHECK_EQ()|, etc. work.
240 MOJO_SYSTEM_IMPL_EXPORT inline std::ostream& operator<<(
241 std::ostream& out,
242 MessageInTransit::Type type) {
243 return out << static_cast<uint16_t>(type);
244 }
245
246 } // namespace edk
247 } // namespace mojo
248
249 #endif // MOJO_EDK_SYSTEM_MESSAGE_IN_TRANSIT_H_
OLDNEW
« no previous file with comments | « mojo/edk/system/child_broker_host.cc ('k') | mojo/edk/system/message_in_transit.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698