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

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

Issue 2735113003: Changing SpawnChild to return a struct.
Patch Set: 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 <stddef.h>
8 #include <string.h> 8 #include <string.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <limits> 11 #include <limits>
12 #include <utility> 12 #include <utility>
13 13
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/memory/aligned_memory.h" 15 #include "base/memory/aligned_memory.h"
16 #include "base/process/process_handle.h" 16 #include "base/process/process_handle.h"
17 #include "mojo/edk/embedder/platform_handle.h" 17 #include "mojo/edk/embedder/platform_handle.h"
18 18
19 #if defined(OS_MACOSX) && !defined(OS_IOS) 19 #if defined(OS_MACOSX) && !defined(OS_IOS)
20 #include "base/mac/mach_logging.h" 20 #include "base/mac/mach_logging.h"
21 #elif defined(OS_ANDROID)
22 #include "base/rand_util.h"
21 #elif defined(OS_WIN) 23 #elif defined(OS_WIN)
22 #include "base/win/win_util.h" 24 #include "base/win/win_util.h"
23 #endif 25 #endif
24 26
25 namespace mojo { 27 namespace mojo {
26 namespace edk { 28 namespace edk {
27 29
28 namespace { 30 namespace {
29 31
30 static_assert( 32 static_assert(
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 extra_header_size = max_handles_ * sizeof(HandleEntry); 76 extra_header_size = max_handles_ * sizeof(HandleEntry);
75 #elif defined(OS_MACOSX) && !defined(OS_IOS) 77 #elif defined(OS_MACOSX) && !defined(OS_IOS)
76 // On OSX, some of the platform handles may be mach ports, which are 78 // On OSX, some of the platform handles may be mach ports, which are
77 // serialised into the message buffer. Since there could be a mix of fds and 79 // serialised into the message buffer. Since there could be a mix of fds and
78 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t), 80 // mach ports, we store the mach ports as an <index, port> pair (of uint32_t),
79 // so that the original ordering of handles can be re-created. 81 // so that the original ordering of handles can be re-created.
80 if (max_handles) { 82 if (max_handles) {
81 extra_header_size = 83 extra_header_size =
82 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry)); 84 sizeof(MachPortsExtraHeader) + (max_handles * sizeof(MachPortsEntry));
83 } 85 }
86 #elif defined(OS_ANDROID)
87 if (max_handles) {
88 extra_header_size =
89 sizeof(ParcelableExtraHeader) + (max_handles * sizeof(ParcelableEntry));
90 }
84 #endif 91 #endif
85 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes. 92 // Pad extra header data to be aliged to |kChannelMessageAlignment| bytes.
86 if (!IsAlignedForChannelMessage(extra_header_size)) { 93 if (!IsAlignedForChannelMessage(extra_header_size)) {
87 extra_header_size += kChannelMessageAlignment - 94 extra_header_size += kChannelMessageAlignment -
88 (extra_header_size % kChannelMessageAlignment); 95 (extra_header_size % kChannelMessageAlignment);
89 } 96 }
90 DCHECK(IsAlignedForChannelMessage(extra_header_size)); 97 DCHECK(IsAlignedForChannelMessage(extra_header_size));
91 const size_t header_size = 98 const size_t header_size =
92 is_legacy_message ? sizeof(LegacyHeader) : sizeof(Header); 99 is_legacy_message ? sizeof(LegacyHeader) : sizeof(Header);
93 DCHECK(extra_header_size == 0 || !is_legacy_message); 100 DCHECK(extra_header_size == 0 || !is_legacy_message);
(...skipping 30 matching lines...) Expand all
124 handles_[i].handle = base::win::HandleToUint32(INVALID_HANDLE_VALUE); 131 handles_[i].handle = base::win::HandleToUint32(INVALID_HANDLE_VALUE);
125 #elif defined(OS_MACOSX) && !defined(OS_IOS) 132 #elif defined(OS_MACOSX) && !defined(OS_IOS)
126 mach_ports_header_ = 133 mach_ports_header_ =
127 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header()); 134 reinterpret_cast<MachPortsExtraHeader*>(mutable_extra_header());
128 mach_ports_header_->num_ports = 0; 135 mach_ports_header_->num_ports = 0;
129 // Initialize all handles to invalid values. 136 // Initialize all handles to invalid values.
130 for (size_t i = 0; i < max_handles_; ++i) { 137 for (size_t i = 0; i < max_handles_; ++i) {
131 mach_ports_header_->entries[i] = 138 mach_ports_header_->entries[i] =
132 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 139 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
133 } 140 }
141 #elif defined(OS_ANDROID)
142 parcelable_header_ =
143 reinterpret_cast<ParcelableExtraHeader*>(mutable_extra_header());
144 parcelable_header_->num_parcelables = 0;
145 memset(parcelable_header_->entries, 0,
146 sizeof(ParcelableEntry) * max_handles_);
134 #endif 147 #endif
135 } 148 }
136 } 149 }
137 150
138 Channel::Message::~Message() { 151 Channel::Message::~Message() {
139 base::AlignedFree(data_); 152 base::AlignedFree(data_);
140 } 153 }
141 154
142 // static 155 // static
143 Channel::MessagePtr Channel::Message::Deserialize(const void* data, 156 Channel::MessagePtr Channel::Message::Deserialize(const void* data,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 extra_header_size < sizeof(MachPortsExtraHeader)) { 195 extra_header_size < sizeof(MachPortsExtraHeader)) {
183 DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < " 196 DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < "
184 << sizeof(MachPortsExtraHeader); 197 << sizeof(MachPortsExtraHeader);
185 return nullptr; 198 return nullptr;
186 } 199 }
187 uint32_t max_handles = 200 uint32_t max_handles =
188 extra_header_size == 0 201 extra_header_size == 0
189 ? 0 202 ? 0
190 : (extra_header_size - sizeof(MachPortsExtraHeader)) / 203 : (extra_header_size - sizeof(MachPortsExtraHeader)) /
191 sizeof(MachPortsEntry); 204 sizeof(MachPortsEntry);
205 #elif defined(OS_ANDROID)
206 if (extra_header_size < sizeof(ParcelableExtraHeader)) {
207 DLOG(ERROR) << "Decoding invalid message: " << extra_header_size << " < "
208 << sizeof(ParcelableExtraHeader);
209 return nullptr;
210 }
211 uint32_t max_handles = (extra_header_size - sizeof(ParcelableExtraHeader)) /
212 sizeof(ParcelableEntry);
192 #else 213 #else
193 const uint32_t max_handles = 0; 214 const uint32_t max_handles = 0;
194 #endif // defined(OS_WIN) 215 #endif // defined(OS_WIN)
195 216
196 const uint16_t num_handles = 217 const uint16_t num_handles =
197 header ? header->num_handles : legacy_header->num_handles; 218 header ? header->num_handles : legacy_header->num_handles;
198 if (num_handles > max_handles || max_handles > kMaxAttachedHandles) { 219 if (num_handles > max_handles || max_handles > kMaxAttachedHandles) {
199 DLOG(ERROR) << "Decoding invalid message: " << num_handles << " > " 220 DLOG(ERROR) << "Decoding invalid message: " << num_handles << " > "
200 << max_handles; 221 << max_handles;
201 return nullptr; 222 return nullptr;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 } 340 }
320 341
321 if (max_handles_ == 0) { 342 if (max_handles_ == 0) {
322 CHECK(!new_handles || new_handles->size() == 0); 343 CHECK(!new_handles || new_handles->size() == 0);
323 return; 344 return;
324 } 345 }
325 346
326 CHECK(new_handles && new_handles->size() <= max_handles_); 347 CHECK(new_handles && new_handles->size() <= max_handles_);
327 header()->num_handles = static_cast<uint16_t>(new_handles->size()); 348 header()->num_handles = static_cast<uint16_t>(new_handles->size());
328 std::swap(handle_vector_, new_handles); 349 std::swap(handle_vector_, new_handles);
350
329 #if defined(OS_WIN) 351 #if defined(OS_WIN)
330 memset(handles_, 0, extra_header_size()); 352 memset(handles_, 0, extra_header_size());
331 for (size_t i = 0; i < handle_vector_->size(); i++) 353 for (size_t i = 0; i < handle_vector_->size(); i++)
332 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle); 354 handles_[i].handle = base::win::HandleToUint32((*handle_vector_)[i].handle);
333 #endif // defined(OS_WIN) 355 #endif // defined(OS_WIN)
334 356
335 #if defined(OS_MACOSX) && !defined(OS_IOS) 357 #if defined(OS_MACOSX) && !defined(OS_IOS)
336 size_t mach_port_index = 0; 358 size_t mach_port_index = 0;
337 if (mach_ports_header_) { 359 if (mach_ports_header_) {
338 for (size_t i = 0; i < max_handles_; ++i) { 360 for (size_t i = 0; i < max_handles_; ++i) {
339 mach_ports_header_->entries[i] = 361 mach_ports_header_->entries[i] =
340 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 362 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
341 } 363 }
342 for (size_t i = 0; i < handle_vector_->size(); i++) { 364 for (size_t i = 0; i < handle_vector_->size(); i++) {
343 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH || 365 if ((*handle_vector_)[i].type == PlatformHandle::Type::MACH ||
344 (*handle_vector_)[i].type == PlatformHandle::Type::MACH_NAME) { 366 (*handle_vector_)[i].type == PlatformHandle::Type::MACH_NAME) {
345 mach_port_t port = (*handle_vector_)[i].port; 367 mach_port_t port = (*handle_vector_)[i].port;
346 mach_ports_header_->entries[mach_port_index].index = i; 368 mach_ports_header_->entries[mach_port_index].index = i;
347 mach_ports_header_->entries[mach_port_index].mach_port = port; 369 mach_ports_header_->entries[mach_port_index].mach_port = port;
348 mach_port_index++; 370 mach_port_index++;
349 } 371 }
350 } 372 }
351 mach_ports_header_->num_ports = static_cast<uint16_t>(mach_port_index); 373 mach_ports_header_->num_ports = static_cast<uint16_t>(mach_port_index);
352 } 374 }
353 #endif 375 #endif
376
377 #if defined(OS_ANDROID)
378 size_t parcelable_index = 0;
379 if (parcelable_header_) {
380 memset(parcelable_header_->entries, 0,
381 sizeof(ParcelableEntry) * max_handles_);
382 for (size_t i = 0; i < handle_vector_->size(); i++) {
383 if ((*handle_vector_)[i].type == PlatformHandle::Type::PARCELABLE) {
384 // jobject parcelable = (*handle_vector_)[i].parcelable;
385 // TODO: WHERE DOES THE PARCELABLE GO?
386 parcelable_header_->entries[parcelable_index].index = i;
387 parcelable_header_->entries[parcelable_index].id = i;
388 parcelable_index++;
389 }
390 }
391 parcelable_header_->num_parcelables =
392 static_cast<uint16_t>(parcelable_index);
393 }
394 #endif
354 } 395 }
355 396
356 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() { 397 ScopedPlatformHandleVectorPtr Channel::Message::TakeHandles() {
357 #if defined(OS_MACOSX) && !defined(OS_IOS) 398 #if defined(OS_MACOSX) && !defined(OS_IOS)
358 if (mach_ports_header_) { 399 if (mach_ports_header_) {
359 for (size_t i = 0; i < max_handles_; ++i) { 400 for (size_t i = 0; i < max_handles_; ++i) {
360 mach_ports_header_->entries[i] = 401 mach_ports_header_->entries[i] =
361 {0, static_cast<uint32_t>(MACH_PORT_NULL)}; 402 {0, static_cast<uint32_t>(MACH_PORT_NULL)};
362 } 403 }
363 mach_ports_header_->num_ports = 0; 404 mach_ports_header_->num_ports = 0;
(...skipping 18 matching lines...) Expand all
382 it->type == PlatformHandle::Type::MACH_NAME) { 423 it->type == PlatformHandle::Type::MACH_NAME) {
383 // For Mach port names, we can can just leak them. They're not real 424 // For Mach port names, we can can just leak them. They're not real
384 // ports anyways. For real ports, they're leaked because this is a child 425 // ports anyways. For real ports, they're leaked because this is a child
385 // process and the remote process will take ownership. 426 // process and the remote process will take ownership.
386 it = handle_vector_->erase(it); 427 it = handle_vector_->erase(it);
387 } else { 428 } else {
388 ++it; 429 ++it;
389 } 430 }
390 } 431 }
391 } 432 }
433 #elif defined(OS_ANDROID)
434 if (handle_vector_) {
435 for (auto it = handle_vector_->begin(); it != handle_vector_->end();) {
436 if (it->type == PlatformHandle::Type::PARCELABLE) {
437 it = handle_vector_->erase(it);
438 } else {
439 ++it;
440 }
441 }
442 }
443 #endif
392 return std::move(handle_vector_); 444 return std::move(handle_vector_);
393 #else 445 }
394 return std::move(handle_vector_); 446
447 #if defined(OS_ANDROID)
448 Channel::Message::IDAndParcelableVector
449 Channel::Message::TakeParcelablesForTransport() {
450 IDAndParcelableVector ids_and_parcelables;
451 if (parcelable_header_) {
452 memset(parcelable_header_->entries, 0,
453 sizeof(ParcelableEntry) * max_handles_);
454 size_t parcelable_index = 0;
455 for (auto iter = handle_vector_->begin(); iter != handle_vector_->end();
456 ++iter) {
457 if (iter->type == PlatformHandle::Type::PARCELABLE) {
458 uint32_t parcelable_id = static_cast<uint32_t>(base::RandUint64());
459 parcelable_header_->entries[parcelable_index].index = parcelable_index;
460 parcelable_header_->entries[parcelable_index].id = parcelable_id;
461 parcelable_index++;
462 ids_and_parcelables.push_back(std::make_pair(
463 parcelable_id,
464 base::android::ScopedJavaLocalRef<jobject>(iter->parcelable)));
465 }
466 }
467 parcelable_header_->num_parcelables =
468 static_cast<uint16_t>(parcelable_index);
469 }
470
471 return std::move(ids_and_parcelables);
472 }
395 #endif 473 #endif
396 }
397 474
398 #if defined(OS_WIN) 475 #if defined(OS_WIN)
399 // static 476 // static
400 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process, 477 bool Channel::Message::RewriteHandles(base::ProcessHandle from_process,
401 base::ProcessHandle to_process, 478 base::ProcessHandle to_process,
402 PlatformHandleVector* handles) { 479 PlatformHandleVector* handles) {
403 bool success = true; 480 bool success = true;
404 for (size_t i = 0; i < handles->size(); ++i) { 481 for (size_t i = 0; i < handles->size(); ++i) {
405 if (!(*handles)[i].is_valid()) { 482 if (!(*handles)[i].is_valid()) {
406 DLOG(ERROR) << "Refusing to duplicate invalid handle."; 483 DLOG(ERROR) << "Refusing to duplicate invalid handle.";
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 } 710 }
634 711
635 const uint16_t num_handles = 712 const uint16_t num_handles =
636 header ? header->num_handles : legacy_header->num_handles; 713 header ? header->num_handles : legacy_header->num_handles;
637 ScopedPlatformHandleVectorPtr handles; 714 ScopedPlatformHandleVectorPtr handles;
638 if (num_handles > 0) { 715 if (num_handles > 0) {
639 if (!GetReadPlatformHandles(num_handles, extra_header, extra_header_size, 716 if (!GetReadPlatformHandles(num_handles, extra_header, extra_header_size,
640 &handles)) { 717 &handles)) {
641 return false; 718 return false;
642 } 719 }
643
644 if (!handles) { 720 if (!handles) {
645 // Not enough handles available for this message. 721 // Not enough handles available for this message.
646 break; 722 break;
647 } 723 }
648 } 724 }
649 725
650 // We've got a complete message! Dispatch it and try another. 726 // We've got a complete message! Dispatch it and try another.
651 if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY && 727 if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY &&
652 legacy_header->message_type != Message::MessageType::NORMAL) { 728 legacy_header->message_type != Message::MessageType::NORMAL) {
653 if (!OnControlMessage(legacy_header->message_type, payload, payload_size, 729 if (!OnControlMessage(legacy_header->message_type, payload, payload_size,
654 std::move(handles))) { 730 std::move(handles))) {
655 return false; 731 return false;
656 } 732 }
657 did_dispatch_message = true; 733 did_dispatch_message = true;
658 } else if (delegate_) { 734 } else if (delegate_) {
735 ((handles) ? handles->size() : 0);
659 delegate_->OnChannelMessage(payload, payload_size, std::move(handles)); 736 delegate_->OnChannelMessage(payload, payload_size, std::move(handles));
660 did_dispatch_message = true; 737 did_dispatch_message = true;
661 } 738 }
662 739
663 read_buffer_->Discard(legacy_header->num_bytes); 740 read_buffer_->Discard(legacy_header->num_bytes);
664 } 741 }
665 742
666 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize; 743 *next_read_size_hint = did_dispatch_message ? 0 : kReadBufferSize;
667 return true; 744 return true;
668 } 745 }
669 746
670 void Channel::OnError() { 747 void Channel::OnError() {
671 if (delegate_) 748 if (delegate_)
672 delegate_->OnChannelError(); 749 delegate_->OnChannelError();
673 } 750 }
674 751
675 bool Channel::OnControlMessage(Message::MessageType message_type, 752 bool Channel::OnControlMessage(Message::MessageType message_type,
676 const void* payload, 753 const void* payload,
677 size_t payload_size, 754 size_t payload_size,
678 ScopedPlatformHandleVectorPtr handles) { 755 ScopedPlatformHandleVectorPtr handles) {
679 return false; 756 return false;
680 } 757 }
681 758
682 } // namespace edk 759 } // namespace edk
683 } // namespace mojo 760 } // 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