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

Side by Side Diff: mojo/edk/system/channel_posix.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.cc ('k') | mojo/edk/system/core.h » ('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 <errno.h> 7 #include <errno.h>
8 #include <sys/socket.h> 8 #include <sys/socket.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <deque> 11 #include <deque>
12 #include <limits> 12 #include <limits>
13 #include <memory> 13 #include <memory>
14 14
15 #include "base/bind.h" 15 #include "base/bind.h"
16 #include "base/location.h" 16 #include "base/location.h"
17 #include "base/macros.h" 17 #include "base/macros.h"
18 #include "base/memory/ref_counted.h" 18 #include "base/memory/ref_counted.h"
19 #include "base/message_loop/message_loop.h" 19 #include "base/message_loop/message_loop.h"
20 #include "base/synchronization/lock.h" 20 #include "base/synchronization/lock.h"
21 #include "base/task_runner.h" 21 #include "base/task_runner.h"
22 #include "mojo/edk/embedder/platform_channel_utils_posix.h" 22 #include "mojo/edk/embedder/platform_channel_utils_posix.h"
23 #include "mojo/edk/embedder/platform_handle_vector.h" 23 #include "mojo/edk/embedder/platform_handle_vector.h"
24 24
25 #if !defined(OS_NACL) 25 #if !defined(OS_NACL)
26 #include <sys/uio.h> 26 #include <sys/uio.h>
27 #endif 27 #endif
28 28
29 #if defined(OS_ANDROID)
30 #include "base/android/parcelable_channel_client.h"
31 #include "base/android/scoped_java_ref.h"
32 #endif
33
29 namespace mojo { 34 namespace mojo {
30 namespace edk { 35 namespace edk {
31 36
32 namespace { 37 namespace {
33 38
34 const size_t kMaxBatchReadCapacity = 256 * 1024; 39 const size_t kMaxBatchReadCapacity = 256 * 1024;
35 40
36 // A view over a Channel::Message object. The write queue uses these since 41 // A view over a Channel::Message object. The write queue uses these since
37 // large messages may need to be sent in chunks. 42 // large messages may need to be sent in chunks.
38 class MessageView { 43 class MessageView {
39 public: 44 public:
40 // Owns |message|. |offset| indexes the first unsent byte in the message. 45 // Owns |message|. |offset| indexes the first unsent byte in the message.
41 MessageView(Channel::MessagePtr message, size_t offset) 46 MessageView(Channel::MessagePtr message, size_t offset)
42 : message_(std::move(message)), 47 : message_(std::move(message)), offset_(offset) {
43 offset_(offset),
44 handles_(message_->TakeHandlesForTransport()) {
45 DCHECK_GT(message_->data_num_bytes(), offset_); 48 DCHECK_GT(message_->data_num_bytes(), offset_);
49 #if defined(OS_ANDROID)
50 // Parcelables must be retrieved before Handles.
51 ids_and_parcelables_ = message_->TakeParcelablesForTransport();
52 #endif
53 handles_ = message_->TakeHandlesForTransport();
46 } 54 }
47 55
48 MessageView(MessageView&& other) { *this = std::move(other); } 56 MessageView(MessageView&& other) { *this = std::move(other); }
49 57
50 MessageView& operator=(MessageView&& other) { 58 MessageView& operator=(MessageView&& other) {
51 message_ = std::move(other.message_); 59 message_ = std::move(other.message_);
52 offset_ = other.offset_; 60 offset_ = other.offset_;
53 handles_ = std::move(other.handles_); 61 handles_ = std::move(other.handles_);
54 return *this; 62 return *this;
55 } 63 }
56 64
57 ~MessageView() {} 65 ~MessageView() {}
58 66
59 const void* data() const { 67 const void* data() const {
60 return static_cast<const char*>(message_->data()) + offset_; 68 return static_cast<const char*>(message_->data()) + offset_;
61 } 69 }
62 70
63 size_t data_num_bytes() const { return message_->data_num_bytes() - offset_; } 71 size_t data_num_bytes() const { return message_->data_num_bytes() - offset_; }
64 72
65 size_t data_offset() const { return offset_; } 73 size_t data_offset() const { return offset_; }
66 void advance_data_offset(size_t num_bytes) { 74 void advance_data_offset(size_t num_bytes) {
67 DCHECK_GT(message_->data_num_bytes(), offset_ + num_bytes); 75 DCHECK_GT(message_->data_num_bytes(), offset_ + num_bytes);
68 offset_ += num_bytes; 76 offset_ += num_bytes;
69 } 77 }
70 78
71 ScopedPlatformHandleVectorPtr TakeHandles() { return std::move(handles_); } 79 ScopedPlatformHandleVectorPtr TakeHandles() { return std::move(handles_); }
72 Channel::MessagePtr TakeMessage() { return std::move(message_); } 80 Channel::MessagePtr TakeMessage() { return std::move(message_); }
81 #if defined(OS_ANDROID)
82 Channel::Message::IDAndParcelableVector TakeParcelables() {
83 return std::move(ids_and_parcelables_);
84 }
85
86 #endif
73 87
74 void SetHandles(ScopedPlatformHandleVectorPtr handles) { 88 void SetHandles(ScopedPlatformHandleVectorPtr handles) {
75 handles_ = std::move(handles); 89 handles_ = std::move(handles);
76 } 90 }
77 91
78 private: 92 private:
79 Channel::MessagePtr message_; 93 Channel::MessagePtr message_;
80 size_t offset_; 94 size_t offset_;
81 ScopedPlatformHandleVectorPtr handles_; 95 ScopedPlatformHandleVectorPtr handles_;
96 #if defined(OS_ANDROID)
97 Channel::Message::IDAndParcelableVector ids_and_parcelables_;
98 #endif
82 99
83 DISALLOW_COPY_AND_ASSIGN(MessageView); 100 DISALLOW_COPY_AND_ASSIGN(MessageView);
84 }; 101 };
85 102
86 class ChannelPosix : public Channel, 103 class ChannelPosix : public Channel,
87 public base::MessageLoop::DestructionObserver, 104 public base::MessageLoop::DestructionObserver,
88 public base::MessageLoopForIO::Watcher { 105 public base::MessageLoopForIO::Watcher {
89 public: 106 public:
90 ChannelPosix(Delegate* delegate, 107 ChannelPosix(Delegate* delegate,
91 ScopedPlatformHandle handle, 108 ConnectionParam connection_param,
92 scoped_refptr<base::TaskRunner> io_task_runner) 109 scoped_refptr<base::TaskRunner> io_task_runner)
93 : Channel(delegate), 110 : Channel(delegate),
94 self_(this), 111 self_(this),
95 handle_(std::move(handle)), 112 handle_(connection_param.TakeChannelHandle()),
113 #if defined(OS_ANDROID)
114 parcelable_channel_client_(
115 connection_param.TakeParcelableChannelClient()),
116 parcelable_channel_server_(
117 connection_param.TakeParcelableChannelServer()),
118 #endif
96 io_task_runner_(io_task_runner) 119 io_task_runner_(io_task_runner)
97 #if defined(OS_MACOSX) 120 #if defined(OS_MACOSX)
98 , 121 ,
99 handles_to_close_(new PlatformHandleVector) 122 handles_to_close_(new PlatformHandleVector)
100 #endif 123 #endif
101 { 124 {
125 CHECK(handle_.is_valid());
126 // We can't DCHECK because the BrokerHost has a channel used for sync
127 // messages with not parcelable channels.
128 // CHECK(parcelable_channel_client_.is_valid());
129 // CHECK(parcelable_channel_server_.is_valid());
102 } 130 }
103 131
104 void Start() override { 132 void Start() override {
105 if (io_task_runner_->RunsTasksOnCurrentThread()) { 133 if (io_task_runner_->RunsTasksOnCurrentThread()) {
106 StartOnIOThread(); 134 StartOnIOThread();
107 } else { 135 } else {
108 io_task_runner_->PostTask( 136 io_task_runner_->PostTask(
109 FROM_HERE, base::Bind(&ChannelPosix::StartOnIOThread, this)); 137 FROM_HERE, base::Bind(&ChannelPosix::StartOnIOThread, this));
110 } 138 }
111 } 139 }
(...skipping 30 matching lines...) Expand all
142 leak_handle_ = true; 170 leak_handle_ = true;
143 } 171 }
144 172
145 bool GetReadPlatformHandles( 173 bool GetReadPlatformHandles(
146 size_t num_handles, 174 size_t num_handles,
147 const void* extra_header, 175 const void* extra_header,
148 size_t extra_header_size, 176 size_t extra_header_size,
149 ScopedPlatformHandleVectorPtr* handles) override { 177 ScopedPlatformHandleVectorPtr* handles) override {
150 if (num_handles > std::numeric_limits<uint16_t>::max()) 178 if (num_handles > std::numeric_limits<uint16_t>::max())
151 return false; 179 return false;
180
152 #if defined(OS_MACOSX) && !defined(OS_IOS) 181 #if defined(OS_MACOSX) && !defined(OS_IOS)
153 // On OSX, we can have mach ports which are located in the extra header 182 // On OSX, we can have mach ports which are located in the extra header
154 // section. 183 // section.
155 using MachPortsEntry = Channel::Message::MachPortsEntry; 184 using MachPortsEntry = Channel::Message::MachPortsEntry;
156 using MachPortsExtraHeader = Channel::Message::MachPortsExtraHeader; 185 using MachPortsExtraHeader = Channel::Message::MachPortsExtraHeader;
157 CHECK(extra_header_size >= 186 CHECK(extra_header_size >=
158 sizeof(MachPortsExtraHeader) + num_handles * sizeof(MachPortsEntry)); 187 sizeof(MachPortsExtraHeader) + num_handles * sizeof(MachPortsEntry));
159 const MachPortsExtraHeader* mach_ports_header = 188 const MachPortsExtraHeader* mach_ports_header =
160 reinterpret_cast<const MachPortsExtraHeader*>(extra_header); 189 reinterpret_cast<const MachPortsExtraHeader*>(extra_header);
161 size_t num_mach_ports = mach_ports_header->num_ports; 190 size_t num_mach_ports = mach_ports_header->num_ports;
(...skipping 14 matching lines...) Expand all
176 // These are actually just Mach port names until they're resolved from 205 // These are actually just Mach port names until they're resolved from
177 // the remote process. 206 // the remote process.
178 (*handles)->at(i).type = PlatformHandle::Type::MACH_NAME; 207 (*handles)->at(i).type = PlatformHandle::Type::MACH_NAME;
179 mach_port_index++; 208 mach_port_index++;
180 } else { 209 } else {
181 CHECK(!incoming_platform_handles_.empty()); 210 CHECK(!incoming_platform_handles_.empty());
182 (*handles)->at(i) = incoming_platform_handles_.front(); 211 (*handles)->at(i) = incoming_platform_handles_.front();
183 incoming_platform_handles_.pop_front(); 212 incoming_platform_handles_.pop_front();
184 } 213 }
185 } 214 }
215 #elif defined(OS_ANDROID)
216 using ParcelableEntry = Channel::Message::ParcelableEntry;
217 using ParcelableExtraHeader = Channel::Message::ParcelableExtraHeader;
218 CHECK(extra_header_size >= sizeof(ParcelableExtraHeader) +
219 num_handles * sizeof(ParcelableEntry));
220 const ParcelableExtraHeader* parcelable_header =
221 reinterpret_cast<const ParcelableExtraHeader*>(extra_header);
222 size_t num_parcelables = parcelable_header->num_parcelables;
223 CHECK(num_parcelables <= num_handles);
224 if (incoming_platform_handles_.size() + num_parcelables < num_handles) {
225 handles->reset();
226 return true;
227 }
228
229 handles->reset(new PlatformHandleVector(num_handles));
230 const ParcelableEntry* parcelables = parcelable_header->entries;
231 for (size_t i = 0, parcelable_index = 0; i < num_handles; ++i) {
232 if (parcelable_index < num_parcelables &&
233 parcelables[parcelable_index].index == i) {
234 (*handles)->at(i) =
235 PlatformHandle(parcelable_channel_server_.TakeParcelable(
236 parcelables[parcelable_index].id));
237 parcelable_index++;
238 } else {
239 CHECK(!incoming_platform_handles_.empty());
240 (*handles)->at(i) = incoming_platform_handles_.front();
241 incoming_platform_handles_.pop_front();
242 }
243 }
186 #else 244 #else
187 if (incoming_platform_handles_.size() < num_handles) { 245 if (incoming_platform_handles_.size() < num_handles) {
188 handles->reset(); 246 handles->reset();
189 return true; 247 return true;
190 } 248 }
191 249
192 handles->reset(new PlatformHandleVector(num_handles)); 250 handles->reset(new PlatformHandleVector(num_handles));
193 for (size_t i = 0; i < num_handles; ++i) { 251 for (size_t i = 0; i < num_handles; ++i) {
194 (*handles)->at(i) = incoming_platform_handles_.front(); 252 (*handles)->at(i) = incoming_platform_handles_.front();
195 incoming_platform_handles_.pop_front(); 253 incoming_platform_handles_.pop_front();
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 bool WriteNoLock(MessageView message_view) { 409 bool WriteNoLock(MessageView message_view) {
352 if (handle_.get().needs_connection) { 410 if (handle_.get().needs_connection) {
353 outgoing_messages_.emplace_front(std::move(message_view)); 411 outgoing_messages_.emplace_front(std::move(message_view));
354 return true; 412 return true;
355 } 413 }
356 size_t bytes_written = 0; 414 size_t bytes_written = 0;
357 do { 415 do {
358 message_view.advance_data_offset(bytes_written); 416 message_view.advance_data_offset(bytes_written);
359 417
360 ssize_t result; 418 ssize_t result;
419 #if defined(OS_ANDROID)
420 Channel::Message::IDAndParcelableVector ids_and_parcelables =
421 std::move(message_view.TakeParcelables());
422 if (!ids_and_parcelables.empty()) {
423 for (auto iter = ids_and_parcelables.begin();
424 iter != ids_and_parcelables.end(); ++iter) {
425 DCHECK(!iter->second.is_null());
426 parcelable_channel_client_.SendParcelable(iter->first, iter->second);
427 }
428 }
429 #endif
361 ScopedPlatformHandleVectorPtr handles = message_view.TakeHandles(); 430 ScopedPlatformHandleVectorPtr handles = message_view.TakeHandles();
362 if (handles && handles->size()) { 431 if (handles && handles->size()) {
363 iovec iov = { 432 iovec iov = {
364 const_cast<void*>(message_view.data()), 433 const_cast<void*>(message_view.data()),
365 message_view.data_num_bytes() 434 message_view.data_num_bytes()
366 }; 435 };
367 // TODO: Handle lots of handles. 436 // TODO: Handle lots of handles.
368 result = PlatformChannelSendmsgWithHandles( 437 result = PlatformChannelSendmsgWithHandles(
369 handle_.get(), &iov, 1, handles->data(), handles->size()); 438 handle_.get(), &iov, 1, handles->data(), handles->size());
370 if (result >= 0) { 439 if (result >= 0) {
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 594
526 handles_to_close_->erase(start, it); 595 handles_to_close_->erase(start, it);
527 return true; 596 return true;
528 } 597 }
529 #endif // defined(OS_MACOSX) 598 #endif // defined(OS_MACOSX)
530 599
531 // Keeps the Channel alive at least until explicit shutdown on the IO thread. 600 // Keeps the Channel alive at least until explicit shutdown on the IO thread.
532 scoped_refptr<Channel> self_; 601 scoped_refptr<Channel> self_;
533 602
534 ScopedPlatformHandle handle_; 603 ScopedPlatformHandle handle_;
604 #if defined(OS_ANDROID)
605 base::android::ParcelableChannelClient parcelable_channel_client_;
606 base::android::ParcelableChannelServer parcelable_channel_server_;
607 #endif
535 scoped_refptr<base::TaskRunner> io_task_runner_; 608 scoped_refptr<base::TaskRunner> io_task_runner_;
536 609
537 // These watchers must only be accessed on the IO thread. 610 // These watchers must only be accessed on the IO thread.
538 std::unique_ptr<base::MessageLoopForIO::FileDescriptorWatcher> read_watcher_; 611 std::unique_ptr<base::MessageLoopForIO::FileDescriptorWatcher> read_watcher_;
539 std::unique_ptr<base::MessageLoopForIO::FileDescriptorWatcher> write_watcher_; 612 std::unique_ptr<base::MessageLoopForIO::FileDescriptorWatcher> write_watcher_;
540 613
541 std::deque<PlatformHandle> incoming_platform_handles_; 614 std::deque<PlatformHandle> incoming_platform_handles_;
542 615
543 // Protects |pending_write_| and |outgoing_messages_|. 616 // Protects |pending_write_| and |outgoing_messages_|.
544 base::Lock write_lock_; 617 base::Lock write_lock_;
545 bool pending_write_ = false; 618 bool pending_write_ = false;
546 bool reject_writes_ = false; 619 bool reject_writes_ = false;
547 std::deque<MessageView> outgoing_messages_; 620 std::deque<MessageView> outgoing_messages_;
548 621
549 bool leak_handle_ = false; 622 bool leak_handle_ = false;
550 623
551 #if defined(OS_MACOSX) 624 #if defined(OS_MACOSX)
552 base::Lock handles_to_close_lock_; 625 base::Lock handles_to_close_lock_;
553 ScopedPlatformHandleVectorPtr handles_to_close_; 626 ScopedPlatformHandleVectorPtr handles_to_close_;
554 #endif 627 #endif
555 628
556 DISALLOW_COPY_AND_ASSIGN(ChannelPosix); 629 DISALLOW_COPY_AND_ASSIGN(ChannelPosix);
557 }; 630 };
558 631
559 } // namespace 632 } // namespace
560 633
561 // static 634 // static
562 scoped_refptr<Channel> Channel::Create( 635 scoped_refptr<Channel> Channel::Create(
563 Delegate* delegate, 636 Delegate* delegate,
564 ScopedPlatformHandle platform_handle, 637 ConnectionParam connection_param,
565 scoped_refptr<base::TaskRunner> io_task_runner) { 638 scoped_refptr<base::TaskRunner> io_task_runner) {
566 return new ChannelPosix(delegate, std::move(platform_handle), io_task_runner); 639 return new ChannelPosix(delegate, std::move(connection_param),
640 io_task_runner);
567 } 641 }
568 642
569 } // namespace edk 643 } // namespace edk
570 } // namespace mojo 644 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/channel.cc ('k') | mojo/edk/system/core.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698