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

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

Issue 1753723003: Revert of [mojo-edk] Serialise windows handles into an "extra header" section. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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 <string.h> 7 #include <string.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <limits> 10 #include <limits>
11 11
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/memory/aligned_memory.h" 13 #include "base/memory/aligned_memory.h"
14 #include "mojo/edk/embedder/platform_handle.h" 14 #include "mojo/edk/embedder/platform_handle.h"
15 15
16 namespace mojo { 16 namespace mojo {
17 namespace edk { 17 namespace edk {
18 18
19 namespace { 19 namespace {
20 20
21 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0, 21 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0,
22 "Invalid Header size."); 22 "Invalid Header size.");
23 23
24 } // namespace 24 } // namespace
25 25
26 const size_t kReadBufferSize = 4096; 26 const size_t kReadBufferSize = 4096;
27 const size_t kMaxUnusedReadBufferCapacity = 256 * 1024; 27 const size_t kMaxUnusedReadBufferCapacity = 256 * 1024;
28 const size_t kMaxChannelMessageSize = 256 * 1024 * 1024; 28 const size_t kMaxChannelMessageSize = 256 * 1024 * 1024;
29 const size_t kMaxAttachedHandles = 128;
30 29
31 Channel::Message::Message(size_t payload_size, 30 Channel::Message::Message(size_t payload_size,
32 size_t max_handles, 31 size_t num_handles,
33 Header::MessageType message_type) 32 Header::MessageType message_type) {
34 : max_handles_(max_handles) { 33 size_ = payload_size + sizeof(Header);
35 DCHECK_LE(max_handles_, kMaxAttachedHandles); 34 #if defined(OS_WIN)
35 // On Windows we serialize platform handles directly into the message buffer.
36 size_ += num_handles * sizeof(PlatformHandle);
37 #endif
36 38
37 size_t extra_header_size = 0;
38 #if defined(OS_WIN)
39 // On Windows we serialize platform handles into the extra header space.
40 extra_header_size = max_handles_ * sizeof(PlatformHandle);
41 #endif
42 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes.
43 if (extra_header_size % kChannelMessageAlignment) {
44 extra_header_size += kChannelMessageAlignment -
45 (extra_header_size % kChannelMessageAlignment);
46 }
47 DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment);
48
49 size_ = sizeof(Header) + extra_header_size + payload_size;
50 data_ = static_cast<char*>(base::AlignedAlloc(size_, 39 data_ = static_cast<char*>(base::AlignedAlloc(size_,
51 kChannelMessageAlignment)); 40 kChannelMessageAlignment));
52 memset(data_, 0, size_); 41 memset(data_, 0, size_);
53 header_ = reinterpret_cast<Header*>(data_); 42 header_ = reinterpret_cast<Header*>(data_);
54 43
55 DCHECK_LE(size_, std::numeric_limits<uint32_t>::max()); 44 DCHECK_LE(size_, std::numeric_limits<uint32_t>::max());
56 header_->num_bytes = static_cast<uint32_t>(size_); 45 header_->num_bytes = static_cast<uint32_t>(size_);
57 46
58 DCHECK_LE(sizeof(Header) + extra_header_size, 47 DCHECK_LE(num_handles, std::numeric_limits<uint16_t>::max());
59 std::numeric_limits<uint16_t>::max()); 48 header_->num_handles = static_cast<uint16_t>(num_handles);
60 header_->num_header_bytes =
61 static_cast<uint16_t>(sizeof(Header) + extra_header_size);
62 49
63 header_->message_type = message_type; 50 header_->message_type = message_type;
64 51
65 #if defined(OS_WIN) 52 #if defined(OS_WIN)
66 if (max_handles_ > 0) { 53 if (num_handles > 0) {
67 handles_ = reinterpret_cast<PlatformHandle*>(mutable_extra_header()); 54 handles_ = reinterpret_cast<PlatformHandle*>(
55 data_ + sizeof(Header) + payload_size);
68 // Initialize all handles to invalid values. 56 // Initialize all handles to invalid values.
69 for (size_t i = 0; i < max_handles_; ++i) 57 for (size_t i = 0; i < header_->num_handles; ++i)
70 handles()[i] = PlatformHandle(); 58 handles()[i] = PlatformHandle();
71 } 59 }
72 #endif 60 #endif
73 } 61 }
74 62
75 Channel::Message::~Message() { 63 Channel::Message::~Message() {
76 #if defined(OS_WIN) 64 #if defined(OS_WIN)
77 // On POSIX the ScopedPlatformHandleVectorPtr will do this for us. 65 // On POSIX the ScopedPlatformHandleVectorPtr will do this for us.
78 for (size_t i = 0; i < header_->num_handles; ++i) 66 for (size_t i = 0; i < header_->num_handles; ++i)
79 handles()[i].CloseIfNecessary(); 67 handles()[i].CloseIfNecessary();
(...skipping 12 matching lines...) Expand all
92 if (data_num_bytes < sizeof(Header)) 80 if (data_num_bytes < sizeof(Header))
93 return nullptr; 81 return nullptr;
94 82
95 const Header* header = reinterpret_cast<const Header*>(data); 83 const Header* header = reinterpret_cast<const Header*>(data);
96 if (header->num_bytes != data_num_bytes) { 84 if (header->num_bytes != data_num_bytes) {
97 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes 85 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes
98 << " != " << data_num_bytes; 86 << " != " << data_num_bytes;
99 return nullptr; 87 return nullptr;
100 } 88 }
101 89
102 if (header->num_bytes < header->num_header_bytes) { 90 uint32_t handles_size = header->num_handles * sizeof(PlatformHandle);
103 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " 91 if (data_num_bytes < sizeof(Header) + handles_size) {
104 << header->num_header_bytes; 92 DLOG(ERROR) << "Decoding invalid message:" << data_num_bytes
93 << " < " << (sizeof(Header) + handles_size);
105 return nullptr; 94 return nullptr;
106 } 95 }
107 96
108 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header); 97 DCHECK_LE(handles_size, data_num_bytes - sizeof(Header));
109 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle);
110 if (header->num_handles > max_handles) {
111 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles << " > "
112 << max_handles;
113 return nullptr;
114 }
115 98
116 MessagePtr message( 99 MessagePtr message(new Message(data_num_bytes - sizeof(Header) - handles_size,
117 new Message(data_num_bytes - header->num_header_bytes, max_handles)); 100 header->num_handles));
118 101
119 DCHECK_EQ(message->data_num_bytes(), data_num_bytes); 102 DCHECK_EQ(message->data_num_bytes(), data_num_bytes);
120 DCHECK_EQ(message->extra_header_size(), extra_header_size);
121 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes);
122 103
123 // Copy all payload bytes. 104 // Copy all bytes, including the serialized handles.
124 memcpy(message->mutable_payload(), 105 memcpy(message->mutable_payload(),
125 static_cast<const char*>(data) + header->num_header_bytes,
126 data_num_bytes - header->num_header_bytes);
127 // Copy extra header bytes.
128 memcpy(message->mutable_extra_header(),
129 static_cast<const char*>(data) + sizeof(Header), 106 static_cast<const char*>(data) + sizeof(Header),
130 message->extra_header_size()); 107 data_num_bytes - sizeof(Header));
131 message->header_->num_handles = header->num_handles;
132 108
133 return message; 109 return message;
134 } 110 }
135 111
136 size_t Channel::Message::payload_size() const { 112 size_t Channel::Message::payload_size() const {
137 return size_ - header_->num_header_bytes; 113 #if defined(OS_WIN)
114 return size_ - sizeof(Header) -
115 sizeof(PlatformHandle) * header_->num_handles;
116 #else
117 return header_->num_bytes - sizeof(Header);
118 #endif
138 } 119 }
139 120
140 PlatformHandle* Channel::Message::handles() { 121 PlatformHandle* Channel::Message::handles() {
141 if (max_handles_ == 0) 122 if (header_->num_handles == 0)
142 return nullptr; 123 return nullptr;
143 #if defined(OS_WIN) 124 #if defined(OS_WIN)
144 return handles_; 125 return reinterpret_cast<PlatformHandle*>(static_cast<char*>(data_) +
126 sizeof(Header) + payload_size());
145 #else 127 #else
146 CHECK(handle_vector_); 128 CHECK(handle_vector_);
147 return handle_vector_->data(); 129 return handle_vector_->data();
148 #endif 130 #endif
149 } 131 }
150 132
151 #if defined(OS_MACOSX) && !defined(OS_IOS)
152 bool Channel::Message::has_mach_ports() const {
153 if (!has_handles())
154 return false;
155
156 for (const auto& handle : (*handle_vector_)) {
157 if (handle.type == PlatformHandle::Type::MACH)
158 return true;
159 }
160 return false;
161 }
162 #endif
163
164 void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) { 133 void Channel::Message::SetHandles(ScopedPlatformHandleVectorPtr new_handles) {
165 if (max_handles_ == 0) { 134 if (header_->num_handles == 0) {
166 CHECK(!new_handles || new_handles->size() == 0); 135 CHECK(!new_handles || new_handles->size() == 0);
167 return; 136 return;
168 } 137 }
169 138
170 CHECK(new_handles && new_handles->size() <= max_handles_); 139 CHECK(new_handles && new_handles->size() == header_->num_handles);
171 header_->num_handles = static_cast<uint16_t>(new_handles->size());
172 #if defined(OS_WIN) 140 #if defined(OS_WIN)
173 memcpy(handles(), new_handles->data(), 141 memcpy(handles(), new_handles->data(),
174 sizeof(PlatformHandle) * new_handles->size()); 142 sizeof(PlatformHandle) * header_->num_handles);
175 new_handles->clear(); 143 new_handles->clear();
176 #else 144 #else
177 std::swap(handle_vector_, new_handles); 145 std::swap(handle_vector_, new_handles);
178 #endif 146 #endif
179 } 147 }
180 148
181 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { 149 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() {
182 #if defined(OS_WIN) 150 #if defined(OS_WIN)
183 if (header_->num_handles == 0) 151 if (header_->num_handles == 0)
184 return ScopedPlatformHandleVectorPtr(); 152 return ScopedPlatformHandleVectorPtr();
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 } 322 }
355 323
356 if (read_buffer_->num_occupied_bytes() < header->num_bytes) { 324 if (read_buffer_->num_occupied_bytes() < header->num_bytes) {
357 // Not enough data available to read the full message. Hint to the 325 // Not enough data available to read the full message. Hint to the
358 // implementation that it should try reading the full size of the message. 326 // implementation that it should try reading the full size of the message.
359 *next_read_size_hint = 327 *next_read_size_hint =
360 header->num_bytes - read_buffer_->num_occupied_bytes(); 328 header->num_bytes - read_buffer_->num_occupied_bytes();
361 return true; 329 return true;
362 } 330 }
363 331
364 size_t extra_header_size = 332 size_t payload_size = header->num_bytes - sizeof(Message::Header);
365 header->num_header_bytes - sizeof(Message::Header); 333 void* payload = payload_size ? const_cast<Message::Header*>(&header[1])
366 const void* extra_header = header + 1; 334 : nullptr;
367 size_t payload_size = header->num_bytes - header->num_header_bytes;
368 void* payload =
369 payload_size ? reinterpret_cast<Message::Header*>(
370 const_cast<char*>(read_buffer_->occupied_bytes()) +
371 header->num_header_bytes)
372 : nullptr;
373 335
374 ScopedPlatformHandleVectorPtr handles; 336 ScopedPlatformHandleVectorPtr handles;
375 if (header->num_handles > 0) { 337 if (header->num_handles > 0) {
376 handles = GetReadPlatformHandles(header->num_handles, extra_header, 338 handles = GetReadPlatformHandles(header->num_handles,
377 extra_header_size); 339 &payload, &payload_size);
378 if (!handles) { 340 if (!handles) {
379 // Not enough handles available for this message. 341 // Not enough handles available for this message.
380 break; 342 break;
381 } 343 }
382 } 344 }
383 345
384 // We've got a complete message! Dispatch it and try another. 346 // We've got a complete message! Dispatch it and try another.
385 if (header->message_type != Message::Header::MessageType::NORMAL) { 347 if (header->message_type != Message::Header::MessageType::NORMAL) {
386 OnControlMessage(header->message_type, payload, payload_size, 348 OnControlMessage(header->message_type, payload, payload_size,
387 std::move(handles)); 349 std::move(handles));
(...skipping 10 matching lines...) Expand all
398 return true; 360 return true;
399 } 361 }
400 362
401 void Channel::OnError() { 363 void Channel::OnError() {
402 if (delegate_) 364 if (delegate_)
403 delegate_->OnChannelError(); 365 delegate_->OnChannelError();
404 } 366 }
405 367
406 } // namespace edk 368 } // namespace edk
407 } // namespace mojo 369 } // 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