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

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

Issue 1712143002: [mojo-edk] Add support for transferring mach ports. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More stuff. 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
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 #include <utility>
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 "mojo/edk/embedder/platform_handle.h" 15 #include "mojo/edk/embedder/platform_handle.h"
15 16
17 #if defined(OS_MACOSX)
erikchen 2016/03/09 19:13:17 it seems you're inconsistent on whether to include
Anand Mistry (off Chromium) 2016/03/11 07:44:17 Oops. I thought I standardised these. I'll take an
18 #include "base/mac/mach_logging.h"
19 #endif
20
16 namespace mojo { 21 namespace mojo {
17 namespace edk { 22 namespace edk {
18 23
19 namespace { 24 namespace {
20 25
21 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0, 26 static_assert(sizeof(Channel::Message::Header) % kChannelMessageAlignment == 0,
22 "Invalid Header size."); 27 "Invalid Header size.");
23 28
24 #if defined(OS_CHROMEOS) 29 #if defined(OS_CHROMEOS)
25 static_assert(sizeof(Channel::Message::Header) == 8, 30 static_assert(sizeof(Channel::Message::Header) == 8,
(...skipping 10 matching lines...) Expand all
36 Channel::Message::Message(size_t payload_size, 41 Channel::Message::Message(size_t payload_size,
37 size_t max_handles, 42 size_t max_handles,
38 Header::MessageType message_type) 43 Header::MessageType message_type)
39 : max_handles_(max_handles) { 44 : max_handles_(max_handles) {
40 DCHECK_LE(max_handles_, kMaxAttachedHandles); 45 DCHECK_LE(max_handles_, kMaxAttachedHandles);
41 46
42 size_t extra_header_size = 0; 47 size_t extra_header_size = 0;
43 #if defined(OS_WIN) 48 #if defined(OS_WIN)
44 // On Windows we serialize platform handles into the extra header space. 49 // On Windows we serialize platform handles into the extra header space.
45 extra_header_size = max_handles_ * sizeof(PlatformHandle); 50 extra_header_size = max_handles_ * sizeof(PlatformHandle);
51 #elif defined(OS_MACOSX)
52 // On OSX, some of the platform handles may be mach ports, which are
53 // serialised into the message buffer. Since there could be a mix of fds and
54 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t),
55 // so that the original ordering of handles can be re-created.
56 extra_header_size = max_handles * sizeof(MachPortsEntry);
46 #endif 57 #endif
47 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes. 58 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes.
48 if (extra_header_size % kChannelMessageAlignment) { 59 if (extra_header_size % kChannelMessageAlignment) {
49 extra_header_size += kChannelMessageAlignment - 60 extra_header_size += kChannelMessageAlignment -
50 (extra_header_size % kChannelMessageAlignment); 61 (extra_header_size % kChannelMessageAlignment);
51 } 62 }
52 DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment); 63 DCHECK_EQ(0u, extra_header_size % kChannelMessageAlignment);
53 #if defined(OS_CHROMEOS) 64 #if defined(OS_CHROMEOS)
54 DCHECK_EQ(0u, extra_header_size); 65 DCHECK_EQ(0u, extra_header_size);
55 #endif 66 #endif
(...skipping 10 matching lines...) Expand all
66 DCHECK_LE(sizeof(Header) + extra_header_size, 77 DCHECK_LE(sizeof(Header) + extra_header_size,
67 std::numeric_limits<uint16_t>::max()); 78 std::numeric_limits<uint16_t>::max());
68 header_->message_type = message_type; 79 header_->message_type = message_type;
69 #if defined(OS_CHROMEOS) 80 #if defined(OS_CHROMEOS)
70 header_->num_handles = static_cast<uint16_t>(max_handles); 81 header_->num_handles = static_cast<uint16_t>(max_handles);
71 #else 82 #else
72 header_->num_header_bytes = 83 header_->num_header_bytes =
73 static_cast<uint16_t>(sizeof(Header) + extra_header_size); 84 static_cast<uint16_t>(sizeof(Header) + extra_header_size);
74 #endif 85 #endif
75 86
87 if (max_handles_ > 0) {
76 #if defined(OS_WIN) 88 #if defined(OS_WIN)
77 if (max_handles_ > 0) {
78 handles_ = reinterpret_cast<PlatformHandle*>(mutable_extra_header()); 89 handles_ = reinterpret_cast<PlatformHandle*>(mutable_extra_header());
79 // Initialize all handles to invalid values. 90 // Initialize all handles to invalid values.
80 for (size_t i = 0; i < max_handles_; ++i) 91 for (size_t i = 0; i < max_handles_; ++i)
81 handles()[i] = PlatformHandle(); 92 handles()[i] = PlatformHandle();
93 #elif defined(OS_MACOSX) && !defined(OS_IOS)
94 mach_ports_ = reinterpret_cast<MachPortsEntry*>(mutable_extra_header());
95 // Initialize all handles to invalid values.
96 for (size_t i = 0; i < max_handles_; ++i)
97 mach_ports_[i] = {0, static_cast<uint32_t>(MACH_PORT_NULL)};
98 #endif
82 } 99 }
83 #endif
84 } 100 }
85 101
86 Channel::Message::~Message() { 102 Channel::Message::~Message() {
87 #if defined(OS_WIN) 103 #if defined(OS_WIN)
88 // On POSIX the ScopedPlatformHandleVectorPtr will do this for us. 104 // On POSIX the ScopedPlatformHandleVectorPtr will do this for us.
89 for (size_t i = 0; i < header_->num_handles; ++i) 105 for (size_t i = 0; i < header_->num_handles; ++i)
90 handles()[i].CloseIfNecessary(); 106 handles()[i].CloseIfNecessary();
91 #endif 107 #endif
92 base::AlignedFree(data_); 108 base::AlignedFree(data_);
93 } 109 }
94 110
95 // static 111 // static
96 Channel::MessagePtr Channel::Message::Deserialize(const void* data, 112 Channel::MessagePtr Channel::Message::Deserialize(const void* data,
97 size_t data_num_bytes) { 113 size_t data_num_bytes) {
98 #if !defined(OS_WIN) 114 #if !defined(OS_WIN) && (!defined(OS_MACOSX) || defined(OS_IOS))
erikchen 2016/03/09 19:13:17 could you rewrite as !(defined(OS_MACOSX) && !defi
Anand Mistry (off Chromium) 2016/03/11 07:44:17 Done.
99 // We only serialize messages into other messages when performing message 115 // We only serialize messages into other messages when performing message
100 // relay on Windows. 116 // relay on Windows and OSX.
101 NOTREACHED(); 117 NOTREACHED();
102 return nullptr; 118 return nullptr;
103 #else 119 #else
104 if (data_num_bytes < sizeof(Header)) 120 if (data_num_bytes < sizeof(Header))
105 return nullptr; 121 return nullptr;
106 122
107 const Header* header = reinterpret_cast<const Header*>(data); 123 const Header* header = reinterpret_cast<const Header*>(data);
108 if (header->num_bytes != data_num_bytes) { 124 if (header->num_bytes != data_num_bytes) {
109 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes 125 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes
110 << " != " << data_num_bytes; 126 << " != " << data_num_bytes;
111 return nullptr; 127 return nullptr;
112 } 128 }
113 129
114 if (header->num_bytes < header->num_header_bytes) { 130 if (header->num_bytes < header->num_header_bytes) {
115 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < " 131 DLOG(ERROR) << "Decoding invalid message: " << header->num_bytes << " < "
116 << header->num_header_bytes; 132 << header->num_header_bytes;
117 return nullptr; 133 return nullptr;
118 } 134 }
119 135
120 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header); 136 uint32_t extra_header_size = header->num_header_bytes - sizeof(Header);
137 #if defined(OS_WIN)
121 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle); 138 uint32_t max_handles = extra_header_size / sizeof(PlatformHandle);
139 #elif defined(OS_MACOSX)
140 uint32_t max_handles = extra_header_size / sizeof(MachPortsEntry);
141 #endif
122 if (header->num_handles > max_handles) { 142 if (header->num_handles > max_handles) {
123 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles << " > " 143 DLOG(ERROR) << "Decoding invalid message:" << header->num_handles
124 << max_handles; 144 << " > " << max_handles;
125 return nullptr; 145 return nullptr;
126 } 146 }
127 147
128 MessagePtr message( 148 MessagePtr message(new Message(data_num_bytes - header->num_header_bytes,
129 new Message(data_num_bytes - header->num_header_bytes, max_handles)); 149 max_handles));
130
131 DCHECK_EQ(message->data_num_bytes(), data_num_bytes); 150 DCHECK_EQ(message->data_num_bytes(), data_num_bytes);
132 DCHECK_EQ(message->extra_header_size(), extra_header_size); 151 DCHECK_EQ(message->extra_header_size(), extra_header_size);
133 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes); 152 DCHECK_EQ(message->header_->num_header_bytes, header->num_header_bytes);
134 153
135 // Copy all payload bytes. 154 // Copy all payload bytes.
136 memcpy(message->mutable_payload(), 155 memcpy(message->mutable_payload(),
137 static_cast<const char*>(data) + header->num_header_bytes, 156 static_cast<const char*>(data) + header->num_header_bytes,
138 data_num_bytes - header->num_header_bytes); 157 data_num_bytes - header->num_header_bytes);
139 // Copy extra header bytes. 158 // Copy extra header bytes.
140 memcpy(message->mutable_extra_header(), 159 memcpy(message->mutable_extra_header(),
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 CHECK(new_handles && new_handles->size() <= max_handles_); 224 CHECK(new_handles && new_handles->size() <= max_handles_);
206 header_->num_handles = static_cast<uint16_t>(new_handles->size()); 225 header_->num_handles = static_cast<uint16_t>(new_handles->size());
207 #if defined(OS_WIN) 226 #if defined(OS_WIN)
208 memcpy(handles(), new_handles->data(), 227 memcpy(handles(), new_handles->data(),
209 sizeof(PlatformHandle) * new_handles->size()); 228 sizeof(PlatformHandle) * new_handles->size());
210 new_handles->clear(); 229 new_handles->clear();
211 #else 230 #else
212 std::swap(handle_vector_, new_handles); 231 std::swap(handle_vector_, new_handles);
213 #endif // defined(OS_WIN) 232 #endif // defined(OS_WIN)
214 #endif // defined(OS_CHROMEOS) 233 #endif // defined(OS_CHROMEOS)
234
235 #if defined(OS_MACOSX) && !defined(OS_IOS)
236 size_t mach_port_index = 0;
237 for (size_t i = 0; i < max_handles_; ++i)
238 mach_ports_[i] = {0, static_cast<uint32_t>(MACH_PORT_NULL)};
239 for (size_t i = 0; i < handle_vector_->size(); i++) {
240 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH) {
241 mach_port_t port = (*handle_vector_)[i].port;
242 mach_ports_[mach_port_index].index = i;
243 mach_ports_[mach_port_index].mach_port = port;
244 mach_port_index++;
245 }
246 }
247 #endif
215 } 248 }
216 249
217 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { 250 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() {
218 #if defined(OS_WIN) 251 #if defined(OS_WIN)
219 if (header_->num_handles == 0) 252 if (header_->num_handles == 0)
220 return ScopedPlatformHandleVectorPtr(); 253 return ScopedPlatformHandleVectorPtr();
221 ScopedPlatformHandleVectorPtr moved_handles( 254 ScopedPlatformHandleVectorPtr moved_handles(
222 new PlatformHandleVector(header_->num_handles)); 255 new PlatformHandleVector(header_->num_handles));
223 for (size_t i = 0; i < header_->num_handles; ++i) 256 for (size_t i = 0; i < header_->num_handles; ++i)
224 std::swap(moved_handles->at(i), handles()[i]); 257 std::swap(moved_handles->at(i), handles()[i]);
258 header_->num_handles = 0;
225 return moved_handles; 259 return moved_handles;
260 #elif defined(OS_MACOSX) && !defined(OS_IOS)
261 for (size_t i = 0; i < max_handles_; ++i)
262 mach_ports_[i] = {0, static_cast<uint32_t>(MACH_PORT_NULL)};
263 header_->num_handles = 0;
264 return std::move(handle_vector_);
265 #else
266 header_->num_handles = 0;
267 return std::move(handle_vector_);
268 #endif
269 }
270
271 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandlesForTransport() {
272 #if defined(OS_WIN)
273 // Not necessary on Windows.
274 NOTREACHED();
275 return nullptr;
276 #elif defined(OS_MACOSX) && !defined(OS_IOS)
277 if (handle_vector_) {
278 for (auto it = handle_vector_->begin(); it != handle_vector_->end(); ) {
279 if (it->type == PlatformHandle::Type::MACH) {
280 it = handle_vector_->erase(it);
281 } else {
282 ++it;
283 }
284 }
285 }
286 return std::move(handle_vector_);
226 #else 287 #else
227 return std::move(handle_vector_); 288 return std::move(handle_vector_);
228 #endif 289 #endif
229 } 290 }
230 291
231 #if defined(OS_WIN) 292 #if defined(OS_WIN)
232 // static 293 // static
233 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process, 294 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process,
234 base::ProcessHandle to_process, 295 base::ProcessHandle to_process,
235 PlatformHandle* handles, 296 PlatformHandle* handles,
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 return true; 503 return true;
443 } 504 }
444 505
445 void Channel::OnError() { 506 void Channel::OnError() {
446 if (delegate_) 507 if (delegate_)
447 delegate_->OnChannelError(); 508 delegate_->OnChannelError();
448 } 509 }
449 510
450 } // namespace edk 511 } // namespace edk
451 } // namespace mojo 512 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698