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

Side by Side Diff: mojo/edk/system/node_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: Fix build 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/node_channel.h ('k') | mojo/edk/system/node_controller.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/node_channel.h" 5 #include "mojo/edk/system/node_channel.h"
6 6
7 #include <cstring> 7 #include <cstring>
8 #include <limits> 8 #include <limits>
9 #include <sstream> 9 #include <sstream>
10 10
11 #include "base/bind.h"
12 #include "base/location.h"
11 #include "base/logging.h" 13 #include "base/logging.h"
12 #include "mojo/edk/system/channel.h" 14 #include "mojo/edk/system/channel.h"
13 15
16 #if defined(OS_MACOSX) && !defined(OS_IOS)
17 #include "mojo/edk/system/mach_port_relay.h"
18 #endif
19
14 namespace mojo { 20 namespace mojo {
15 namespace edk { 21 namespace edk {
16 22
17 namespace { 23 namespace {
18 24
19 template <typename T> 25 template <typename T>
20 T Align(T t) { 26 T Align(T t) {
21 const auto k = kChannelMessageAlignment; 27 const auto k = kChannelMessageAlignment;
22 return t + (k - (t % k)) % k; 28 return t + (k - (t % k)) % k;
23 } 29 }
24 30
25 enum class MessageType : uint32_t { 31 enum class MessageType : uint32_t {
26 ACCEPT_CHILD, 32 ACCEPT_CHILD,
27 ACCEPT_PARENT, 33 ACCEPT_PARENT,
28 ADD_BROKER_CLIENT, 34 ADD_BROKER_CLIENT,
29 BROKER_CLIENT_ADDED, 35 BROKER_CLIENT_ADDED,
30 ACCEPT_BROKER_CLIENT, 36 ACCEPT_BROKER_CLIENT,
31 PORTS_MESSAGE, 37 PORTS_MESSAGE,
32 REQUEST_PORT_MERGE, 38 REQUEST_PORT_MERGE,
33 REQUEST_INTRODUCTION, 39 REQUEST_INTRODUCTION,
34 INTRODUCE, 40 INTRODUCE,
35 #if defined(OS_WIN) 41 #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
36 RELAY_PORTS_MESSAGE, 42 RELAY_PORTS_MESSAGE,
37 #endif 43 #endif
38 }; 44 };
39 45
40 struct Header { 46 struct Header {
41 MessageType type; 47 MessageType type;
42 uint32_t padding; 48 uint32_t padding;
43 }; 49 };
44 50
45 static_assert(sizeof(Header) % kChannelMessageAlignment == 0, 51 static_assert(sizeof(Header) % kChannelMessageAlignment == 0,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 // Used for both REQUEST_INTRODUCTION and INTRODUCE. 97 // Used for both REQUEST_INTRODUCTION and INTRODUCE.
92 // 98 //
93 // For INTRODUCE the message also includes a valid platform handle for a channel 99 // For INTRODUCE the message also includes a valid platform handle for a channel
94 // the receiver may use to communicate with the named node directly, or an 100 // the receiver may use to communicate with the named node directly, or an
95 // invalid platform handle if the node is unknown to the sender or otherwise 101 // invalid platform handle if the node is unknown to the sender or otherwise
96 // cannot be introduced. 102 // cannot be introduced.
97 struct IntroductionData { 103 struct IntroductionData {
98 ports::NodeName name; 104 ports::NodeName name;
99 }; 105 };
100 106
101 #if defined(OS_WIN) 107 #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
102 // This struct is followed by the full payload of a message to be relayed. 108 // This struct is followed by the full payload of a message to be relayed.
103 struct RelayPortsMessageData { 109 struct RelayPortsMessageData {
104 ports::NodeName destination; 110 ports::NodeName destination;
105 }; 111 };
106 #endif 112 #endif
107 113
108 template <typename DataType> 114 template <typename DataType>
109 Channel::MessagePtr CreateMessage(MessageType type, 115 Channel::MessagePtr CreateMessage(MessageType type,
110 size_t payload_size, 116 size_t payload_size,
111 size_t num_handles, 117 size_t num_handles,
112 DataType** out_data) { 118 DataType** out_data) {
113 Channel::MessagePtr message( 119 Channel::MessagePtr message(
114 new Channel::Message(sizeof(Header) + payload_size, num_handles)); 120 new Channel::Message(sizeof(Header) + payload_size, num_handles));
115 Header* header = reinterpret_cast<Header*>(message->mutable_payload()); 121 Header* header = reinterpret_cast<Header*>(message->mutable_payload());
116 header->type = type; 122 header->type = type;
117 header->padding = 0; 123 header->padding = 0;
118 *out_data = reinterpret_cast<DataType*>(&header[1]); 124 *out_data = reinterpret_cast<DataType*>(&header[1]);
119 return message; 125 return message;
120 }; 126 }
121 127
122 template <typename DataType> 128 template <typename DataType>
123 void GetMessagePayload(const void* bytes, DataType** out_data) { 129 void GetMessagePayload(const void* bytes, DataType** out_data) {
124 *out_data = reinterpret_cast<const DataType*>( 130 *out_data = reinterpret_cast<const DataType*>(
125 static_cast<const char*>(bytes) + sizeof(Header)); 131 static_cast<const char*>(bytes) + sizeof(Header));
126 } 132 }
127 133
128 } // namespace 134 } // namespace
129 135
130 // static 136 // static
(...skipping 14 matching lines...) Expand all
145 151
146 // static 152 // static
147 void NodeChannel::GetPortsMessageData(Channel::Message* message, 153 void NodeChannel::GetPortsMessageData(Channel::Message* message,
148 void** data, 154 void** data,
149 size_t* num_data_bytes) { 155 size_t* num_data_bytes) {
150 *data = reinterpret_cast<Header*>(message->mutable_payload()) + 1; 156 *data = reinterpret_cast<Header*>(message->mutable_payload()) + 1;
151 *num_data_bytes = message->payload_size() - sizeof(Header); 157 *num_data_bytes = message->payload_size() - sizeof(Header);
152 } 158 }
153 159
154 void NodeChannel::Start() { 160 void NodeChannel::Start() {
161 #if defined(OS_MACOSX) && !defined(OS_IOS)
162 MachPortRelay* relay = delegate_->GetMachPortRelay();
163 if (relay)
164 relay->AddObserver(this);
165 #endif
166
155 base::AutoLock lock(channel_lock_); 167 base::AutoLock lock(channel_lock_);
156 DCHECK(channel_); 168 DCHECK(channel_);
157 channel_->Start(); 169 channel_->Start();
158 } 170 }
159 171
160 void NodeChannel::ShutDown() { 172 void NodeChannel::ShutDown() {
173 #if defined(OS_MACOSX) && !defined(OS_IOS)
174 MachPortRelay* relay = delegate_->GetMachPortRelay();
175 if (relay)
176 relay->RemoveObserver(this);
177 #endif
178
161 base::AutoLock lock(channel_lock_); 179 base::AutoLock lock(channel_lock_);
162 if (channel_) { 180 if (channel_) {
163 channel_->ShutDown(); 181 channel_->ShutDown();
164 channel_ = nullptr; 182 channel_ = nullptr;
165 } 183 }
166 } 184 }
167 185
168 void NodeChannel::SetRemoteProcessHandle(base::ProcessHandle process_handle) { 186 void NodeChannel::SetRemoteProcessHandle(base::ProcessHandle process_handle) {
169 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 187 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
170 base::AutoLock lock(remote_process_handle_lock_); 188 base::AutoLock lock(remote_process_handle_lock_);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 ScopedPlatformHandleVectorPtr handles(new PlatformHandleVector()); 314 ScopedPlatformHandleVectorPtr handles(new PlatformHandleVector());
297 if (channel_handle.is_valid()) 315 if (channel_handle.is_valid())
298 handles->push_back(channel_handle.release()); 316 handles->push_back(channel_handle.release());
299 Channel::MessagePtr message = CreateMessage( 317 Channel::MessagePtr message = CreateMessage(
300 MessageType::INTRODUCE, sizeof(IntroductionData), handles->size(), &data); 318 MessageType::INTRODUCE, sizeof(IntroductionData), handles->size(), &data);
301 message->SetHandles(std::move(handles)); 319 message->SetHandles(std::move(handles));
302 data->name = name; 320 data->name = name;
303 WriteChannelMessage(std::move(message)); 321 WriteChannelMessage(std::move(message));
304 } 322 }
305 323
306 #if defined(OS_WIN) 324 #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
307 void NodeChannel::RelayPortsMessage(const ports::NodeName& destination, 325 void NodeChannel::RelayPortsMessage(const ports::NodeName& destination,
308 Channel::MessagePtr message) { 326 Channel::MessagePtr message) {
327 #if defined(OS_WIN)
309 DCHECK(message->has_handles()); 328 DCHECK(message->has_handles());
310 329
311 // Note that this is only used on Windows, and on Windows all platform 330 // Note that this is only used on Windows, and on Windows all platform
312 // handles are included in the message data. We blindly copy all the data 331 // handles are included in the message data. We blindly copy all the data
313 // here and the relay node (the parent) will duplicate handles as needed. 332 // here and the relay node (the parent) will duplicate handles as needed.
314 size_t num_bytes = sizeof(RelayPortsMessageData) + message->data_num_bytes(); 333 size_t num_bytes = sizeof(RelayPortsMessageData) + message->data_num_bytes();
315 RelayPortsMessageData* data; 334 RelayPortsMessageData* data;
316 Channel::MessagePtr relay_message = CreateMessage( 335 Channel::MessagePtr relay_message = CreateMessage(
317 MessageType::RELAY_PORTS_MESSAGE, num_bytes, 0, &data); 336 MessageType::RELAY_PORTS_MESSAGE, num_bytes, 0, &data);
318 data->destination = destination; 337 data->destination = destination;
319 memcpy(data + 1, message->data(), message->data_num_bytes()); 338 memcpy(data + 1, message->data(), message->data_num_bytes());
320 339
321 // When the handles are duplicated in the parent, the source handles will 340 // When the handles are duplicated in the parent, the source handles will
322 // be closed. If the parent never receives this message then these handles 341 // be closed. If the parent never receives this message then these handles
323 // will leak, but that means something else has probably broken and the 342 // will leak, but that means something else has probably broken and the
324 // sending process won't likely be around much longer. 343 // sending process won't likely be around much longer.
325 ScopedPlatformHandleVectorPtr handles = message->TakeHandles(); 344 ScopedPlatformHandleVectorPtr handles = message->TakeHandles();
326 handles->clear(); 345 handles->clear();
327 346
347 #else
348 DCHECK(message->has_mach_ports());
349
350 // On OSX, the handles are extracted from the relayed message and attached to
351 // the wrapper. The broker then takes the handles attached to the wrapper and
352 // moves them back to the relayed message. This is necessary because the
353 // message may contain fds which need to be attached to the outer message so
354 // that they can be transferred to the broker.
355 ScopedPlatformHandleVectorPtr handles = message->TakeHandles();
356 size_t num_bytes = sizeof(RelayPortsMessageData) + message->data_num_bytes();
357 RelayPortsMessageData* data;
358 Channel::MessagePtr relay_message = CreateMessage(
359 MessageType::RELAY_PORTS_MESSAGE, num_bytes, handles->size(), &data);
360 data->destination = destination;
361 memcpy(data + 1, message->data(), message->data_num_bytes());
362 relay_message->SetHandles(std::move(handles));
363 #endif // defined(OS_WIN)
364
328 WriteChannelMessage(std::move(relay_message)); 365 WriteChannelMessage(std::move(relay_message));
329 } 366 }
330 #endif 367 #endif // defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
331 368
332 NodeChannel::NodeChannel(Delegate* delegate, 369 NodeChannel::NodeChannel(Delegate* delegate,
333 ScopedPlatformHandle platform_handle, 370 ScopedPlatformHandle platform_handle,
334 scoped_refptr<base::TaskRunner> io_task_runner) 371 scoped_refptr<base::TaskRunner> io_task_runner)
335 : delegate_(delegate), 372 : delegate_(delegate),
336 io_task_runner_(io_task_runner), 373 io_task_runner_(io_task_runner),
337 channel_( 374 channel_(
338 Channel::Create(this, std::move(platform_handle), io_task_runner_)) { 375 Channel::Create(this, std::move(platform_handle), io_task_runner_)) {
339 } 376 }
340 377
(...skipping 13 matching lines...) Expand all
354 { 391 {
355 base::AutoLock lock(remote_process_handle_lock_); 392 base::AutoLock lock(remote_process_handle_lock_);
356 if (handles && remote_process_handle_ != base::kNullProcessHandle) { 393 if (handles && remote_process_handle_ != base::kNullProcessHandle) {
357 if (!Channel::Message::RewriteHandles(remote_process_handle_, 394 if (!Channel::Message::RewriteHandles(remote_process_handle_,
358 base::GetCurrentProcessHandle(), 395 base::GetCurrentProcessHandle(),
359 handles->data(), handles->size())) { 396 handles->data(), handles->size())) {
360 DLOG(ERROR) << "Received one or more invalid handles."; 397 DLOG(ERROR) << "Received one or more invalid handles.";
361 } 398 }
362 } 399 }
363 } 400 }
364 #endif 401 #elif defined(OS_MACOSX) && !defined(OS_IOS)
402 // If we're not the root, receive any mach ports from the message. If we're
403 // the root, the only message containing mach ports should be a
404 // RELAY_PORTS_MESSAGE.
405 {
406 MachPortRelay* relay = delegate_->GetMachPortRelay();
407 if (handles && !relay) {
408 if (!MachPortRelay::ReceivePorts(handles.get())) {
409 LOG(ERROR) << "Error receiving mach ports.";
410 }
411 }
412 }
413 #endif // defined(OS_WIN)
365 414
366 const Header* header = static_cast<const Header*>(payload); 415 const Header* header = static_cast<const Header*>(payload);
367 switch (header->type) { 416 switch (header->type) {
368 case MessageType::ACCEPT_CHILD: { 417 case MessageType::ACCEPT_CHILD: {
369 const AcceptChildData* data; 418 const AcceptChildData* data;
370 GetMessagePayload(payload, &data); 419 GetMessagePayload(payload, &data);
371 delegate_->OnAcceptChild(remote_node_name_, data->parent_name, 420 delegate_->OnAcceptChild(remote_node_name_, data->parent_name,
372 data->token); 421 data->token);
373 break; 422 break;
374 } 423 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 ScopedPlatformHandle channel_handle; 526 ScopedPlatformHandle channel_handle;
478 if (handles && handles->size() == 1) { 527 if (handles && handles->size() == 1) {
479 channel_handle = ScopedPlatformHandle(handles->at(0)); 528 channel_handle = ScopedPlatformHandle(handles->at(0));
480 handles->clear(); 529 handles->clear();
481 } 530 }
482 delegate_->OnIntroduce(remote_node_name_, data->name, 531 delegate_->OnIntroduce(remote_node_name_, data->name,
483 std::move(channel_handle)); 532 std::move(channel_handle));
484 break; 533 break;
485 } 534 }
486 535
487 #if defined(OS_WIN) 536 #if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
488 case MessageType::RELAY_PORTS_MESSAGE: { 537 case MessageType::RELAY_PORTS_MESSAGE: {
489 base::ProcessHandle from_process; 538 base::ProcessHandle from_process;
490 { 539 {
491 base::AutoLock lock(remote_process_handle_lock_); 540 base::AutoLock lock(remote_process_handle_lock_);
492 from_process = remote_process_handle_; 541 from_process = remote_process_handle_;
493 } 542 }
494 const RelayPortsMessageData* data; 543 const RelayPortsMessageData* data;
495 GetMessagePayload(payload, &data); 544 GetMessagePayload(payload, &data);
496 const void* message_start = data + 1; 545 const void* message_start = data + 1;
497 Channel::MessagePtr message = Channel::Message::Deserialize( 546 Channel::MessagePtr message = Channel::Message::Deserialize(
498 message_start, payload_size - sizeof(Header) - sizeof(*data)); 547 message_start, payload_size - sizeof(Header) - sizeof(*data));
499 if (!message) { 548 if (!message) {
500 DLOG(ERROR) << "Dropping invalid relay message."; 549 DLOG(ERROR) << "Dropping invalid relay message.";
501 break; 550 break;
502 } 551 }
552 #if defined(OS_MACOSX) && !defined(OS_IOS)
553 message->SetHandles(std::move(handles));
554 MachPortRelay* relay = delegate_->GetMachPortRelay();
555 if (!relay) {
556 LOG(ERROR) << "Receiving mach ports without a port relay from "
557 << remote_node_name_ << ". Dropping message.";
558 break;
559 }
560 {
561 base::AutoLock lock(pending_mach_messages_lock_);
562 if (relay->port_provider()->TaskForPid(from_process) ==
563 MACH_PORT_NULL) {
564 pending_relay_messages_.push(
565 std::make_pair(data->destination, std::move(message)));
566 break;
567 }
568 }
569 #endif
503 delegate_->OnRelayPortsMessage(remote_node_name_, from_process, 570 delegate_->OnRelayPortsMessage(remote_node_name_, from_process,
504 data->destination, std::move(message)); 571 data->destination, std::move(message));
505 break; 572 break;
506 } 573 }
507 #endif 574 #endif
508 575
509 default: 576 default:
510 DLOG(ERROR) << "Received unknown message type " 577 DLOG(ERROR) << "Received unknown message type "
511 << static_cast<uint32_t>(header->type) << " from node " 578 << static_cast<uint32_t>(header->type) << " from node "
512 << remote_node_name_; 579 << remote_node_name_;
513 delegate_->OnChannelError(remote_node_name_); 580 delegate_->OnChannelError(remote_node_name_);
514 break; 581 break;
515 } 582 }
516 } 583 }
517 584
518 void NodeChannel::OnChannelError() { 585 void NodeChannel::OnChannelError() {
519 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); 586 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
520 587
521 ShutDown(); 588 ShutDown();
522 // |OnChannelError()| may cause |this| to be destroyed, but still need access 589 // |OnChannelError()| may cause |this| to be destroyed, but still need access
523 // to the name name after that destruction. So may a copy of 590 // to the name name after that destruction. So may a copy of
524 // |remote_node_name_| so it can be used if |this| becomes destroyed. 591 // |remote_node_name_| so it can be used if |this| becomes destroyed.
525 ports::NodeName node_name = remote_node_name_; 592 ports::NodeName node_name = remote_node_name_;
526 delegate_->OnChannelError(node_name); 593 delegate_->OnChannelError(node_name);
527 } 594 }
528 595
596 #if defined(OS_MACOSX) && !defined(OS_IOS)
597 void NodeChannel::OnProcessReady(base::ProcessHandle process) {
598 io_task_runner_->PostTask(FROM_HERE, base::Bind(
599 &NodeChannel::ProcessPendingMessagesWithMachPorts, this));
600 }
601
602 void NodeChannel::ProcessPendingMessagesWithMachPorts() {
603 MachPortRelay* relay = delegate_->GetMachPortRelay();
604 DCHECK(relay);
605
606 base::ProcessHandle remote_process_handle;
607 {
608 base::AutoLock lock(remote_process_handle_lock_);
609 remote_process_handle = remote_process_handle_;
610 }
611 PendingMessageQueue pending_writes;
612 PendingRelayMessageQueue pending_relays;
613 {
614 base::AutoLock lock(pending_mach_messages_lock_);
615 pending_writes.swap(pending_write_messages_);
616 pending_relays.swap(pending_relay_messages_);
617 }
618 DCHECK(pending_writes.empty() && pending_relays.empty());
619
620 while (!pending_writes.empty()) {
621 Channel::MessagePtr message = std::move(pending_writes.front());
622 pending_writes.pop();
623 if (!relay->SendPortsToProcess(message.get(), remote_process_handle)) {
624 LOG(ERROR) << "Error on sending mach ports. Remote process is likely "
625 << "gone. Dropping message.";
626 return;
627 }
628
629 base::AutoLock lock(channel_lock_);
630 if (!channel_) {
631 DLOG(ERROR) << "Dropping message on closed channel.";
632 break;
633 } else {
634 channel_->Write(std::move(message));
635 }
636 }
637
638 while (!pending_relays.empty()) {
639 ports::NodeName destination = pending_relays.front().first;
640 Channel::MessagePtr message = std::move(pending_relays.front().second);
641 pending_relays.pop();
642 delegate_->OnRelayPortsMessage(remote_node_name_, remote_process_handle,
643 destination, std::move(message));
644 }
645 }
646 #endif
647
529 void NodeChannel::WriteChannelMessage(Channel::MessagePtr message) { 648 void NodeChannel::WriteChannelMessage(Channel::MessagePtr message) {
530 #if defined(OS_WIN) 649 #if defined(OS_WIN)
531 // Map handles to the destination process. Note: only messages from a 650 // Map handles to the destination process. Note: only messages from a
532 // privileged node should contain handles on Windows. If an unprivileged 651 // privileged node should contain handles on Windows. If an unprivileged
533 // node needs to send handles, it should do so via RelayPortsMessage which 652 // node needs to send handles, it should do so via RelayPortsMessage which
534 // stashes the handles in the message in such a way that they go undetected 653 // stashes the handles in the message in such a way that they go undetected
535 // here (they'll be unpacked and duplicated by a privileged parent.) 654 // here (they'll be unpacked and duplicated by a privileged parent.)
536 655
537 if (message->has_handles()) { 656 if (message->has_handles()) {
538 base::ProcessHandle remote_process_handle; 657 base::ProcessHandle remote_process_handle;
539 { 658 {
540 base::AutoLock lock(remote_process_handle_lock_); 659 base::AutoLock lock(remote_process_handle_lock_);
541 remote_process_handle = remote_process_handle_; 660 remote_process_handle = remote_process_handle_;
542 } 661 }
543 662
544 // Rewrite outgoing handles if we have a handle to the destination process. 663 // Rewrite outgoing handles if we have a handle to the destination process.
545 if (remote_process_handle != base::kNullProcessHandle) { 664 if (remote_process_handle != base::kNullProcessHandle) {
546 if (!message->RewriteHandles(base::GetCurrentProcessHandle(), 665 if (!message->RewriteHandles(base::GetCurrentProcessHandle(),
547 remote_process_handle, message->handles(), 666 remote_process_handle, message->handles(),
548 message->num_handles())) { 667 message->num_handles())) {
549 DLOG(ERROR) << "Failed to duplicate one or more outgoing handles."; 668 DLOG(ERROR) << "Failed to duplicate one or more outgoing handles.";
550 } 669 }
551 } 670 }
552 } 671 }
672 #elif defined(OS_MACOSX) && !defined(OS_IOS)
673 // On OSX, we need to transfer mach ports to the destination process before
674 // transferring the message itself.
675 if (message->has_mach_ports()) {
676 MachPortRelay* relay = delegate_->GetMachPortRelay();
677 if (relay) {
678 base::ProcessHandle remote_process_handle;
679 {
680 base::AutoLock lock(remote_process_handle_lock_);
681 // Expect that the receiving node is a child.
682 DCHECK(remote_process_handle_ != base::kNullProcessHandle);
683 remote_process_handle = remote_process_handle_;
684 }
685 {
686 base::AutoLock lock(pending_mach_messages_lock_);
687 if (relay->port_provider()->TaskForPid(remote_process_handle) ==
688 MACH_PORT_NULL) {
689 // It is also possible for TaskForPid() to return MACH_PORT_NULL when
690 // the process has started, then died. In that case, the queued
691 // message will never be processed. But that's fine since we're about
692 // to die anyway.
693 pending_write_messages_.push(std::move(message));
694 return;
695 }
696 }
697
698 if (!relay->SendPortsToProcess(message.get(), remote_process_handle)) {
699 LOG(ERROR) << "Error on sending mach ports. Remote process is likely "
700 << "gone. Dropping message.";
701 return;
702 }
703 }
704 }
553 #endif 705 #endif
554 706
555 base::AutoLock lock(channel_lock_); 707 base::AutoLock lock(channel_lock_);
556 if (!channel_) 708 if (!channel_)
557 DLOG(ERROR) << "Dropping message on closed channel."; 709 DLOG(ERROR) << "Dropping message on closed channel.";
558 else 710 else
559 channel_->Write(std::move(message)); 711 channel_->Write(std::move(message));
560 } 712 }
561 713
562 } // namespace edk 714 } // namespace edk
563 } // namespace mojo 715 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/node_channel.h ('k') | mojo/edk/system/node_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698