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

Side by Side Diff: mojo/edk/system/channel.cc

Issue 2710193003: Adding a new message type to the Mojo channel. (Closed)
Patch Set: Fixed Mac tests + sync Created 3 years, 9 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/channel.h ('k') | mojo/edk/system/channel_posix.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 #include "mojo/edk/system/channel.h" 5 #include "mojo/edk/system/channel.h"
6 6
7 #include <stddef.h>
7 #include <string.h> 8 #include <string.h>
8 9
9 #include <algorithm> 10 #include <algorithm>
10 #include <limits> 11 #include <limits>
11 #include <utility> 12 #include <utility>
12 13
13 #include "base/macros.h" 14 #include "base/macros.h"
14 #include "base/memory/aligned_memory.h" 15 #include "base/memory/aligned_memory.h"
15 #include "base/process/process_handle.h" 16 #include "base/process/process_handle.h"
16 #include "mojo/edk/embedder/platform_handle.h" 17 #include "mojo/edk/embedder/platform_handle.h"
17 18
18 #if defined(OS_MACOSX) && !defined(OS_IOS) 19 #if defined(OS_MACOSX) && !defined(OS_IOS)
19 #include "base/mac/mach_logging.h" 20 #include "base/mac/mach_logging.h"
20 #elif defined(OS_WIN) 21 #elif defined(OS_WIN)
21 #include "base/win/win_util.h" 22 #include "base/win/win_util.h"
22 #endif 23 #endif
23 24
24 namespace mojo { 25 namespace mojo {
25 namespace edk { 26 namespace edk {
26 27
27 namespace { 28 namespace {
28 29
29 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0, 30 static_assert(
30 "Invalid Header size."); 31 IsAlignedForChannelMessage(sizeof(Channel::Message::LegacyHeader)),
32 "Invalid LegacyHeader size.");
31 33
32 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 34 static_assert(IsAlignedForChannelMessage(sizeof(Channel::Message::Header)),
33 static_assert(sizeof(Channel::Message::Header) == 8, 35 "Invalid Header size.");
34 "Header must be 8 bytes on ChromeOS and Android"); 36
35 #endif 37 static_assert(sizeof(Channel::Message::LegacyHeader) == 8,
38 "LegacyHeader must be 8 bytes on ChromeOS and Android");
39
40 static_assert(offsetof(Channel::Message::LegacyHeader, num_bytes) ==
41 offsetof(Channel::Message::Header, num_bytes),
42 "num_bytes should be at the same offset in both Header structs.");
43 static_assert(offsetof(Channel::Message::LegacyHeader, message_type) ==
44 offsetof(Channel::Message::Header, message_type),
45 "message_type should be at the same offset in both Header "
46 "structs.");
36 47
37 } // namespace 48 } // namespace
38 49
39 const size_t kReadBufferSize = 4096; 50 const size_t kReadBufferSize = 4096;
40 const size_t kMaxUnusedReadBufferCapacity = 4096; 51 const size_t kMaxUnusedReadBufferCapacity = 4096;
41 const size_t kMaxChannelMessageSize = 256 * 1024 * 1024; 52 const size_t kMaxChannelMessageSize = 256 * 1024 * 1024;
42 const size_t kMaxAttachedHandles = 128; 53 const size_t kMaxAttachedHandles = 128;
43 54
55 Channel::Message::Message(size_t payload_size, size_t max_handles)
56 #if defined(MOJO_EDK_LEGACY_PROTOCOL)
57 : Message(payload_size, max_handles, MessageType::NORMAL_LEGACY) {
58 }
59 #else
60 : Message(payload_size, max_handles, MessageType::NORMAL) {
61 }
62 #endif
63
44 Channel::Message::Message(size_t payload_size, 64 Channel::Message::Message(size_t payload_size,
45 size_t max_handles, 65 size_t max_handles,
46 Header::MessageType message_type) 66 MessageType message_type)
47 : max_handles_(max_handles) { 67 : max_handles_(max_handles) {
48 DCHECK_LE(max_handles_, kMaxAttachedHandles); 68 DCHECK_LE(max_handles_, kMaxAttachedHandles);
49 69
70 const bool is_legacy_message = (message_type == MessageType::NORMAL_LEGACY);
50 size_t extra_header_size = 0; 71 size_t extra_header_size = 0;
51 #if defined(OS_WIN) 72 #if defined(OS_WIN)
52 // On Windows we serialize HANDLEs into the extra header space. 73 // On Windows we serialize HANDLEs into the extra header space.
53 extra_header_size = max_handles_ * sizeof(HandleEntry); 74 extra_header_size = max_handles_ * sizeof(HandleEntry);
54 #elif defined(OS_MACOSX) && !defined(OS_IOS) 75 #elif defined(OS_MACOSX) && !defined(OS_IOS)
55 // On OSX, some of the platform handles may be mach ports, which are 76 // On OSX, some of the platform handles may be mach ports, which are
56 // serialised into the message buffer. Since there could be a mix of fds and 77 // serialised into the message buffer. Since there could be a mix of fds and
57 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t), 78 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t),
58 // so that the original ordering of handles can be re-created. 79 // so that the original ordering of handles can be re-created.
59 if (max_handles) { 80 if (max_handles) {
60 extra_header_size = 81 extra_header_size =
61 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry)); 82 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry));
62 } 83 }
63 #endif 84 #endif
64 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes. 85 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes.
65 if (extra_header_size % kChannelMessageAlignment) { 86 if (!IsAlignedForChannelMessage(extra_header_size)) {
66 extra_header_size += kChannelMessageAlignment - 87 extra_header_size += kChannelMessageAlignment -
67 (extra_header_size % kChannelMessageAlignment); 88 (extra_header_size % kChannelMessageAlignment);
68 } 89 }
69 DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment); 90 DCHECK(IsAlignedForChannelMessage(extra_header_size));
70 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 91 const size_t header_size =
71 DCHECK_EQ(0u, extra_header_size); 92 is_legacy_message ? sizeof(LegacyHeader) : sizeof(Header);
72 #endif 93 DCHECK(extra_header_size == 0 || !is_legacy_message);
73 94
74 size_ = sizeof(Header) + extra_header_size + payload_size; 95 size_ = header_size + extra_header_size + payload_size;
75 data_ = static_cast<char*>(base::AlignedAlloc(size_, 96 data_ = static_cast<char*>(base::AlignedAlloc(size_,
76 kChannelMessageAlignment)); 97 kChannelMessageAlignment));
77 // Only zero out the header and not the payload. Since the payload is going to 98 // Only zero out the header and not the payload. Since the payload is going to
78 // be memcpy'd, zeroing the payload is unnecessary work and a significant 99 // be memcpy'd, zeroing the payload is unnecessary work and a significant
79 // performance issue when dealing with large messages. Any sanitizer errors 100 // performance issue when dealing with large messages. Any sanitizer errors
80 // complaining about an uninitialized read in the payload area should be 101 // complaining about an uninitialized read in the payload area should be
81 // treated as an error and fixed. 102 // treated as an error and fixed.
82 memset(data_, 0, sizeof(Header) + extra_header_size); 103 memset(data_, 0, header_size + extra_header_size);
83 header_ = reinterpret_cast<Header*>(data_);
84 104
85 DCHECK_LE(size_, std::numeric_limits<uint32_t>::max()); 105 DCHECK_LE(size_, std::numeric_limits<uint32_t>::max());
86 header_->num_bytes = static_cast<uint32_t>(size_); 106 legacy_header()->num_bytes = static_cast<uint32_t>(size_);
87 107
88 DCHECK_LE(sizeof(Header) + extra_header_size, 108 DCHECK_LE(header_size + extra_header_size,
89 std::numeric_limits<uint16_t>::max()); 109 std::numeric_limits<uint16_t>::max());
90 header_->message_type = message_type; 110 legacy_header()->message_type = message_type;
91 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 111
92 header_->num_handles = static_cast<uint16_t>(max_handles); 112 if (is_legacy_message) {
93 #else 113 legacy_header()->num_handles = static_cast<uint16_t>(max_handles);
94 header_->num_header_bytes = 114 } else {
95 static_cast<uint16_t>(sizeof(Header) + extra_header_size); 115 header()->num_header_bytes =
96 #endif 116 static_cast<uint16_t>(header_size + extra_header_size);
117 }
97 118
98 if (max_handles_ > 0) { 119 if (max_handles_ > 0) {
99 #if defined(OS_WIN) 120 #if defined(OS_WIN)
100 handles_ = reinterpret_cast<HandleEntry*>(mutable_extra_header()); 121 handles_ = reinterpret_cast<HandleEntry*>(mutable_extra_header());
101 // Initialize all handles to invalid values. 122 // Initialize all handles to invalid values.
102 for (size_t i = 0; i < max_handles_; ++i) 123 for (size_t i = 0; i < max_handles_; ++i)
103 handles_[i].handle = base::win::HandleToUint32(INVALID_HANDLE_VALUE); 124 handles_[i].handle = base::win::HandleToUint32(INVALID_HANDLE_VALUE);
104 #elif defined(OS_MACOSX) && !defined(OS_IOS) 125 #elif defined(OS_MACOSX) && !defined(OS_IOS)
105 mach_ports_header_ = 126 mach_ports_header_ =
106 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header()); 127 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header());
107 mach_ports_header_->num_ports = 0; 128 mach_ports_header_->num_ports = 0;
108 // Initialize all handles to invalid values. 129 // Initialize all handles to invalid values.
109 for (size_t i = 0; i < max_handles_; ++i) { 130 for (size_t i = 0; i < max_handles_; ++i) {
110 mach_ports_header_->entries[i] = 131 mach_ports_header_->entries[i] =
111 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 132 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
112 } 133 }
113 #endif 134 #endif
114 } 135 }
115 } 136 }
116 137
117 Channel::Message::~Message() { 138 Channel::Message::~Message() {
118 base::AlignedFree(data_); 139 base::AlignedFree(data_);
119 } 140 }
120 141
121 // static 142 // static
122 Channel::MessagePtr Channel::Message::Deserialize(const void* data, 143 Channel::MessagePtr Channel::Message::Deserialize(const void* data,
123 size_t data_num_bytes) { 144 size_t data_num_bytes) {
124 if (data_num_bytes < sizeof(Header)) 145 if (data_num_bytes < sizeof(LegacyHeader))
125 return nullptr; 146 return nullptr;
126 147
127 const Header* header = reinterpret_cast<const Header*>(data); 148 const LegacyHeader* legacy_header =
128 if (header->num_bytes != data_num_bytes) { 149 reinterpret_cast<const LegacyHeader*>(data);
129 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes 150 if (legacy_header->num_bytes != data_num_bytes) {
151 DLOG(ERROR) << "Decoding invalid message: " << legacy_header->num_bytes
130 << " != " << data_num_bytes; 152 << " != " << data_num_bytes;
131 return nullptr; 153 return nullptr;
132 } 154 }
133 155
134 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 156 const Header* header = nullptr;
135 size_t payload_size = data_num_bytes - sizeof(Header); 157 if (legacy_header->message_type == MessageType::NORMAL)
136 const char* payload = static_cast<const char*>(data) + sizeof(Header); 158 header = reinterpret_cast<const Header*>(data);
137 #else 159
138 if (header->num_bytes < header->num_header_bytes || 160 uint32_t extra_header_size = 0;
139 header->num_header_bytes < sizeof(Header)) { 161 size_t payload_size = 0;
140 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " 162 const char* payload = nullptr;
141 << header->num_header_bytes; 163 if (!header) {
142 return nullptr; 164 payload_size = data_num_bytes - sizeof(LegacyHeader);
165 payload = static_cast<const char*>(data) + sizeof(LegacyHeader);
166 } else {
167 if (header->num_bytes < header->num_header_bytes ||
168 header->num_header_bytes < sizeof(Header)) {
169 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < "
170 << header->num_header_bytes;
171 return nullptr;
172 }
173 extra_header_size = header->num_header_bytes - sizeof(Header);
174 payload_size = data_num_bytes - header->num_header_bytes;
175 payload = static_cast<const char*>(data) + header->num_header_bytes;
143 } 176 }
144 177
145 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header);
146 size_t payload_size = data_num_bytes - header->num_header_bytes;
147 const char* payload =
148 static_cast<const char*>(data) + header->num_header_bytes;
149 #endif // defined(MOJO_EDK_LEGACY_PROTOCOL)
150
151 #if defined(OS_WIN) 178 #if defined(OS_WIN)
152 uint32_t max_handles = extra_header_size / sizeof(HandleEntry); 179 uint32_t max_handles = extra_header_size / sizeof(HandleEntry);
153 #elif defined(OS_MACOSX) && !defined(OS_IOS) 180 #elif defined(OS_MACOSX) && !defined(OS_IOS)
154 if (extra_header_size < sizeof(MachPortsExtraHeader)) { 181 if (extra_header_size > 0 &&
182 extra_header_size < sizeof(MachPortsExtraHeader)) {
155 DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < " 183 DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < "
156 << sizeof(MachPortsExtraHeader); 184 << sizeof(MachPortsExtraHeader);
157 return nullptr; 185 return nullptr;
158 } 186 }
159 uint32_t max_handles = (extra_header_size - sizeof(MachPortsExtraHeader)) / 187 uint32_t max_handles =
160 sizeof(MachPortsEntry); 188 extra_header_size == 0
189 ? 0
190 : (extra_header_size - sizeof(MachPortsExtraHeader)) /
191 sizeof(MachPortsEntry);
161 #else 192 #else
162 const uint32_t max_handles = 0; 193 const uint32_t max_handles = 0;
163 #endif // defined(OS_WIN) 194 #endif // defined(OS_WIN)
164 195
165 if (header->num_handles > max_handles || max_handles > kMaxAttachedHandles) { 196 const uint16_t num_handles =
166 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles 197 header ? header->num_handles : legacy_header->num_handles;
167 << " > " << max_handles; 198 if (num_handles > max_handles || max_handles > kMaxAttachedHandles) {
199 DLOG(ERROR) << "Decoding invalid message: " << num_handles << " > "
200 << max_handles;
168 return nullptr; 201 return nullptr;
169 } 202 }
170 203
171 MessagePtr message(new Message(payload_size, max_handles)); 204 MessagePtr message(
205 new Message(payload_size, max_handles, legacy_header->message_type));
172 DCHECK_EQ(message->data_num_bytes(), data_num_bytes); 206 DCHECK_EQ(message->data_num_bytes(), data_num_bytes);
173 207
174 // Copy all payload bytes. 208 // Copy all payload bytes.
175 if (payload_size) 209 if (payload_size)
176 memcpy(message->mutable_payload(), payload, payload_size); 210 memcpy(message->mutable_payload(), payload, payload_size);
177 211
178 #if !defined(MOJO_EDK_LEGACY_PROTOCOL) 212 if (header) {
179 DCHECK_EQ(message->extra_header_size(), extra_header_size); 213 DCHECK_EQ(message->extra_header_size(), extra_header_size);
180 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes); 214 DCHECK_EQ(message->header()->num_header_bytes, header->num_header_bytes);
181 215
182 if (message->extra_header_size()) { 216 if (message->extra_header_size()) {
183 // Copy extra header bytes. 217 // Copy extra header bytes.
184 memcpy(message->mutable_extra_header(), 218 memcpy(message->mutable_extra_header(),
185 static_cast<const char*>(data) + sizeof(Header), 219 static_cast<const char*>(data) + sizeof(Header),
186 message->extra_header_size()); 220 message->extra_header_size());
221 }
222 message->header()->num_handles = header->num_handles;
223 } else {
224 message->legacy_header()->num_handles = legacy_header->num_handles;
187 } 225 }
188 #endif
189 226
190 message->header_->num_handles = header->num_handles;
191 #if defined(OS_WIN) 227 #if defined(OS_WIN)
192 ScopedPlatformHandleVectorPtr handles( 228 ScopedPlatformHandleVectorPtr handles(new PlatformHandleVector(num_handles));
193 new PlatformHandleVector(header->num_handles)); 229 for (size_t i = 0; i < num_handles; i++) {
194 for (size_t i = 0; i < header->num_handles; i++) {
195 (*handles)[i].handle = 230 (*handles)[i].handle =
196 base::win::Uint32ToHandle(message->handles_[i].handle); 231 base::win::Uint32ToHandle(message->handles_[i].handle);
197 } 232 }
198 message->SetHandles(std::move(handles)); 233 message->SetHandles(std::move(handles));
199 #endif 234 #endif
200 235
201 return message; 236 return message;
202 } 237 }
203 238
239 const void* Channel::Message::extra_header() const {
240 DCHECK(!is_legacy_message());
241 return data_ + sizeof(Header);
242 }
243
244 void* Channel::Message::mutable_extra_header() {
245 DCHECK(!is_legacy_message());
246 return data_ + sizeof(Header);
247 }
248
249 size_t Channel::Message::extra_header_size() const {
250 return header()->num_header_bytes - sizeof(Header);
251 }
252
253 void* Channel::Message::mutable_payload() {
254 if (is_legacy_message())
255 return static_cast<void*>(legacy_header() + 1);
256 return data_ + header()->num_header_bytes;
257 }
258
259 const void* Channel::Message::payload() const {
260 if (is_legacy_message())
261 return static_cast<const void*>(legacy_header() + 1);
262 return data_ + header()->num_header_bytes;
263 }
264
204 size_t Channel::Message::payload_size() const { 265 size_t Channel::Message::payload_size() const {
205 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 266 if (is_legacy_message())
206 return header_->num_bytes - sizeof(Header); 267 return legacy_header()->num_bytes - sizeof(LegacyHeader);
207 #else 268 return size_ - header()->num_header_bytes;
208 return size_ - header_->num_header_bytes; 269 }
209 #endif 270
271 size_t Channel::Message::num_handles() const {
272 return is_legacy_message() ? legacy_header()->num_handles
273 : header()->num_handles;
274 }
275
276 bool Channel::Message::has_handles() const {
277 return (is_legacy_message() ? legacy_header()->num_handles
278 : header()->num_handles) > 0;
210 } 279 }
211 280
212 #if defined(OS_MACOSX) && !defined(OS_IOS) 281 #if defined(OS_MACOSX) && !defined(OS_IOS)
213 bool Channel::Message::has_mach_ports() const { 282 bool Channel::Message::has_mach_ports() const {
214 if (!has_handles()) 283 if (!has_handles())
215 return false; 284 return false;
216 285
217 for (const auto& handle : (*handle_vector_)) { 286 for (const auto& handle : (*handle_vector_)) {
218 if (handle.type == PlatformHandle::Type::MACH || 287 if (handle.type == PlatformHandle::Type::MACH ||
219 handle.type == PlatformHandle::Type::MACH_NAME) { 288 handle.type == PlatformHandle::Type::MACH_NAME) {
220 return true; 289 return true;
221 } 290 }
222 } 291 }
223 return false; 292 return false;
224 } 293 }
225 #endif 294 #endif
226 295
296 bool Channel::Message::is_legacy_message() const {
297 return legacy_header()->message_type == MessageType::NORMAL_LEGACY;
298 }
299
300 Channel::Message::LegacyHeader* Channel::Message::legacy_header() const {
301 return reinterpret_cast<LegacyHeader*>(data_);
302 }
303
304 Channel::Message::Header* Channel::Message::header() const {
305 DCHECK(!is_legacy_message());
306 return reinterpret_cast<Header*>(data_);
307 }
308
227 void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) { 309 void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) {
228 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 310 if (is_legacy_message()) {
229 // Old semantics for ChromeOS and Android 311 // Old semantics for ChromeOS and Android
230 if (header_->num_handles == 0) { 312 if (legacy_header()->num_handles == 0) {
231 CHECK(!new_handles || new_handles->size() == 0); 313 CHECK(!new_handles || new_handles->size() == 0);
314 return;
315 }
316 CHECK(new_handles && new_handles->size() == legacy_header()->num_handles);
317 std::swap(handle_vector_, new_handles);
232 return; 318 return;
233 } 319 }
234 CHECK(new_handles && new_handles->size() == header_->num_handles);
235 std::swap(handle_vector_, new_handles);
236 320
237 #else
238 if (max_handles_ == 0) { 321 if (max_handles_ == 0) {
239 CHECK(!new_handles || new_handles->size() == 0); 322 CHECK(!new_handles || new_handles->size() == 0);
240 return; 323 return;
241 } 324 }
242 325
243 CHECK(new_handles && new_handles->size() <= max_handles_); 326 CHECK(new_handles && new_handles->size() <= max_handles_);
244 header_->num_handles = static_cast<uint16_t>(new_handles->size()); 327 header()->num_handles = static_cast<uint16_t>(new_handles->size());
245 std::swap(handle_vector_, new_handles); 328 std::swap(handle_vector_, new_handles);
246 #if defined(OS_WIN) 329 #if defined(OS_WIN)
247 memset(handles_, 0, extra_header_size()); 330 memset(handles_, 0, extra_header_size());
248 for (size_t i = 0; i < handle_vector_->size(); i++) 331 for (size_t i = 0; i < handle_vector_->size(); i++)
249 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle); 332 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle);
250 #endif // defined(OS_WIN) 333 #endif // defined(OS_WIN)
251 #endif // defined(MOJO_EDK_LEGACY_PROTOCOL)
252 334
253 #if defined(OS_MACOSX) && !defined(OS_IOS) 335 #if defined(OS_MACOSX) && !defined(OS_IOS)
254 size_t mach_port_index = 0; 336 size_t mach_port_index = 0;
255 if (mach_ports_header_) { 337 if (mach_ports_header_) {
256 for (size_t i = 0; i < max_handles_; ++i) { 338 for (size_t i = 0; i < max_handles_; ++i) {
257 mach_ports_header_->entries[i] = 339 mach_ports_header_->entries[i] =
258 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 340 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
259 } 341 }
260 for (size_t i = 0; i < handle_vector_->size(); i++) { 342 for (size_t i = 0; i < handle_vector_->size(); i++) {
261 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH || 343 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH ||
(...skipping 11 matching lines...) Expand all
273 355
274 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { 356 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() {
275 #if defined(OS_MACOSX) && !defined(OS_IOS) 357 #if defined(OS_MACOSX) && !defined(OS_IOS)
276 if (mach_ports_header_) { 358 if (mach_ports_header_) {
277 for (size_t i = 0; i < max_handles_; ++i) { 359 for (size_t i = 0; i < max_handles_; ++i) {
278 mach_ports_header_->entries[i] = 360 mach_ports_header_->entries[i] =
279 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 361 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
280 } 362 }
281 mach_ports_header_->num_ports = 0; 363 mach_ports_header_->num_ports = 0;
282 } 364 }
283 header_->num_handles = 0; 365 #endif
366 if (is_legacy_message())
367 legacy_header()->num_handles = 0;
368 else
369 header()->num_handles = 0;
284 return std::move(handle_vector_); 370 return std::move(handle_vector_);
285 #else
286 header_->num_handles = 0;
287 return std::move(handle_vector_);
288 #endif
289 } 371 }
290 372
291 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandlesForTransport() { 373 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandlesForTransport() {
292 #if defined(OS_WIN) 374 #if defined(OS_WIN)
293 // Not necessary on Windows. 375 // Not necessary on Windows.
294 NOTREACHED(); 376 NOTREACHED();
295 return nullptr; 377 return nullptr;
296 #elif defined(OS_MACOSX) && !defined(OS_IOS) 378 #elif defined(OS_MACOSX) && !defined(OS_IOS)
297 if (handle_vector_) { 379 if (handle_vector_) {
298 for (auto it = handle_vector_->begin(); it != handle_vector_->end(); ) { 380 for (auto it = handle_vector_->begin(); it != handle_vector_->end(); ) {
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 if (!required_capacity) 566 if (!required_capacity)
485 required_capacity = kReadBufferSize; 567 required_capacity = kReadBufferSize;
486 568
487 *buffer_capacity = required_capacity; 569 *buffer_capacity = required_capacity;
488 return read_buffer_->Reserve(required_capacity); 570 return read_buffer_->Reserve(required_capacity);
489 } 571 }
490 572
491 bool Channel::OnReadComplete(size_t bytes_read, size_t *next_read_size_hint) { 573 bool Channel::OnReadComplete(size_t bytes_read, size_t *next_read_size_hint) {
492 bool did_dispatch_message = false; 574 bool did_dispatch_message = false;
493 read_buffer_->Claim(bytes_read); 575 read_buffer_->Claim(bytes_read);
494 while (read_buffer_->num_occupied_bytes() >= sizeof(Message::Header)) { 576 while (read_buffer_->num_occupied_bytes() >= sizeof(Message::LegacyHeader)) {
495 // Ensure the occupied data is properly aligned. If it isn't, a SIGBUS could 577 // Ensure the occupied data is properly aligned. If it isn't, a SIGBUS could
496 // happen on architectures that don't allow misaligned words access (i.e. 578 // happen on architectures that don't allow misaligned words access (i.e.
497 // anything other than x86). Only re-align when necessary to avoid copies. 579 // anything other than x86). Only re-align when necessary to avoid copies.
498 if (reinterpret_cast<uintptr_t>(read_buffer_->occupied_bytes()) % 580 if (!IsAlignedForChannelMessage(
499 kChannelMessageAlignment != 0) 581 reinterpret_cast<uintptr_t>(read_buffer_->occupied_bytes()))) {
500 read_buffer_->Realign(); 582 read_buffer_->Realign();
583 }
501 584
502 // We have at least enough data available for a MessageHeader. 585 // We have at least enough data available for a LegacyHeader.
503 const Message::Header* header = reinterpret_cast<const Message::Header*>( 586 const Message::LegacyHeader* legacy_header =
504 read_buffer_->occupied_bytes()); 587 reinterpret_cast<const Message::LegacyHeader*>(
505 if (header->num_bytes < sizeof(Message::Header) || 588 read_buffer_->occupied_bytes());
506 header->num_bytes > kMaxChannelMessageSize) { 589
507 LOG(ERROR) << "Invalid message size: " << header->num_bytes; 590 if (legacy_header->num_bytes < sizeof(Message::LegacyHeader) ||
591 legacy_header->num_bytes > kMaxChannelMessageSize) {
592 LOG(ERROR) << "Invalid message size: " << legacy_header->num_bytes;
508 return false; 593 return false;
509 } 594 }
510 595
511 if (read_buffer_->num_occupied_bytes() < header->num_bytes) { 596 if (read_buffer_->num_occupied_bytes() < legacy_header->num_bytes) {
512 // Not enough data available to read the full message. Hint to the 597 // Not enough data available to read the full message. Hint to the
513 // implementation that it should try reading the full size of the message. 598 // implementation that it should try reading the full size of the message.
514 *next_read_size_hint = 599 *next_read_size_hint =
515 header->num_bytes - read_buffer_->num_occupied_bytes(); 600 legacy_header->num_bytes - read_buffer_->num_occupied_bytes();
516 return true; 601 return true;
517 } 602 }
518 603
519 #if defined(MOJO_EDK_LEGACY_PROTOCOL) 604 const Message::Header* header = nullptr;
605 if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY) {
606 header = reinterpret_cast<const Message::Header*>(legacy_header);
607 }
608
520 size_t extra_header_size = 0; 609 size_t extra_header_size = 0;
521 const void* extra_header = nullptr; 610 const void* extra_header = nullptr;
522 size_t payload_size = header->num_bytes - sizeof(Message::Header); 611 size_t payload_size = 0;
523 void* payload = payload_size ? const_cast<Message::Header*>(&header[1]) 612 void* payload = nullptr;
524 : nullptr; 613 if (header) {
525 #else 614 if (header->num_header_bytes < sizeof(Message::Header) ||
526 if (header->num_header_bytes < sizeof(Message::Header) || 615 header->num_header_bytes > header->num_bytes) {
527 header->num_header_bytes > header->num_bytes) { 616 LOG(ERROR) << "Invalid message header size: "
528 LOG(ERROR) << "Invalid message header size: " << header->num_header_bytes; 617 << header->num_header_bytes;
529 return false; 618 return false;
619 }
620 extra_header_size = header->num_header_bytes - sizeof(Message::Header);
621 extra_header = extra_header_size ? header + 1 : nullptr;
622 payload_size = header->num_bytes - header->num_header_bytes;
623 payload = payload_size
624 ? reinterpret_cast<Message::Header*>(
625 const_cast<char*>(read_buffer_->occupied_bytes()) +
626 header->num_header_bytes)
627 : nullptr;
628 } else {
629 payload_size = legacy_header->num_bytes - sizeof(Message::LegacyHeader);
630 payload = payload_size
631 ? const_cast<Message::LegacyHeader*>(&legacy_header[1])
632 : nullptr;
530 } 633 }
531 size_t extra_header_size =
532 header->num_header_bytes - sizeof(Message::Header);
533 const void* extra_header = extra_header_size ? header + 1 : nullptr;
534 size_t payload_size = header->num_bytes - header->num_header_bytes;
535 void* payload =
536 payload_size ? reinterpret_cast<Message::Header*>(
537 const_cast<char*>(read_buffer_->occupied_bytes()) +
538 header->num_header_bytes)
539 : nullptr;
540 #endif // defined(MOJO_EDK_LEGACY_PROTOCOL)
541 634
635 const uint16_t num_handles =
636 header ? header->num_handles : legacy_header->num_handles;
542 ScopedPlatformHandleVectorPtr handles; 637 ScopedPlatformHandleVectorPtr handles;
543 if (header->num_handles > 0) { 638 if (num_handles > 0) {
544 if (!GetReadPlatformHandles(header->num_handles, extra_header, 639 if (!GetReadPlatformHandles(num_handles, extra_header, extra_header_size,
545 extra_header_size, &handles)) { 640 &handles)) {
546 return false; 641 return false;
547 } 642 }
548 643
549 if (!handles) { 644 if (!handles) {
550 // Not enough handles available for this message. 645 // Not enough handles available for this message.
551 break; 646 break;
552 } 647 }
553 } 648 }
554 649
555 // We've got a complete message! Dispatch it and try another. 650 // We've got a complete message! Dispatch it and try another.
556 if (header->message_type != Message::Header::MessageType::NORMAL) { 651 if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY &&
557 if (!OnControlMessage(header->message_type, payload, payload_size, 652 legacy_header->message_type != Message::MessageType::NORMAL) {
653 if (!OnControlMessage(legacy_header->message_type, payload, payload_size,
558 std::move(handles))) { 654 std::move(handles))) {
559 return false; 655 return false;
560 } 656 }
561 did_dispatch_message = true; 657 did_dispatch_message = true;
562 } else if (delegate_) { 658 } else if (delegate_) {
563 delegate_->OnChannelMessage(payload, payload_size, std::move(handles)); 659 delegate_->OnChannelMessage(payload, payload_size, std::move(handles));
564 did_dispatch_message = true; 660 did_dispatch_message = true;
565 } 661 }
566 662
567 read_buffer_->Discard(header->num_bytes); 663 read_buffer_->Discard(legacy_header->num_bytes);
568 } 664 }
569 665
570 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize; 666 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize;
571 return true; 667 return true;
572 } 668 }
573 669
574 void Channel::OnError() { 670 void Channel::OnError() {
575 if (delegate_) 671 if (delegate_)
576 delegate_->OnChannelError(); 672 delegate_->OnChannelError();
577 } 673 }
578 674
579 bool Channel::OnControlMessage(Message::Header::MessageType message_type, 675 bool Channel::OnControlMessage(Message::MessageType message_type,
580 const void* payload, 676 const void* payload,
581 size_t payload_size, 677 size_t payload_size,
582 ScopedPlatformHandleVectorPtr handles) { 678 ScopedPlatformHandleVectorPtr handles) {
583 return false; 679 return false;
584 } 680 }
585 681
586 } // namespace edk 682 } // namespace edk
587 } // namespace mojo 683 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/channel.h ('k') | mojo/edk/system/channel_posix.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698