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

Unified Diff: mojo/edk/system/node_controller.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 side-by-side diff with in-line comments
Download patch
Index: mojo/edk/system/node_controller.cc
diff --git a/mojo/edk/system/node_controller.cc b/mojo/edk/system/node_controller.cc
index 5b2fea82cb9738890071ddddef7808eaf8acaa12..1aac2d5423a2ee3af797ba05739e6459fdb78b76 100644
--- a/mojo/edk/system/node_controller.cc
+++ b/mojo/edk/system/node_controller.cc
@@ -22,6 +22,10 @@
#include "mojo/edk/system/core.h"
#include "mojo/edk/system/ports_message.h"
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+#include "mojo/edk/system/mach_port_relay.h"
+#endif
+
namespace mojo {
namespace edk {
@@ -107,6 +111,18 @@ NodeController::NodeController(Core* core)
DVLOG(1) << "Initializing node " << name_;
}
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+void NodeController::CreateMachPortRelayIfNeeded(
+ base::PortProvider* port_provider) {
+ base::AutoLock lock(mach_port_relay_lock_);
+#if DCHECK_IS_ON()
+ DCHECK(!mach_port_relay_ ||
+ mach_port_relay_->port_provider() == port_provider);
+#endif
+ mach_port_relay_.reset(new MachPortRelay(port_provider));
+}
+#endif
+
void NodeController::SetIOTaskRunner(
scoped_refptr<base::TaskRunner> task_runner) {
io_task_runner_ = task_runner;
@@ -265,14 +281,16 @@ void NodeController::ConnectToParentOnIOThread(
ScopedPlatformHandle platform_handle) {
DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
- base::AutoLock lock(parent_lock_);
- DCHECK(parent_name_ == ports::kInvalidNodeName);
+ {
+ base::AutoLock lock(parent_lock_);
+ DCHECK(parent_name_ == ports::kInvalidNodeName);
- // At this point we don't know the parent's name, so we can't yet insert it
- // into our |peers_| map. That will happen as soon as we receive an
- // AcceptChild message from them.
- bootstrap_parent_channel_ =
- NodeChannel::Create(this, std::move(platform_handle), io_task_runner_);
+ // At this point we don't know the parent's name, so we can't yet insert it
+ // into our |peers_| map. That will happen as soon as we receive an
+ // AcceptChild message from them.
+ bootstrap_parent_channel_ =
+ NodeChannel::Create(this, std::move(platform_handle), io_task_runner_);
+ }
bootstrap_parent_channel_->Start();
}
@@ -393,7 +411,28 @@ void NodeController::SendPeerMessage(const ports::NodeName& name,
return;
}
}
-#endif
+#elif defined(OS_MACOSX) && !defined(OS_IOS)
+ if (channel_message->has_mach_ports()) {
+ // Messages containing mach ports are always routed through the broker, even
+ // if the broker process is the intended recipient.
+ bool use_broker = false;
erikchen 2016/03/09 19:13:17 What happens if the message has mach ports but the
Anand Mistry (off Chromium) 2016/03/11 07:44:18 That's covered below. The child startup process is
+ {
+ base::AutoLock lock(parent_lock_);
+ use_broker = (bootstrap_parent_channel_ ||
+ parent_name_ != ports::kInvalidNodeName);
+ }
+ if (use_broker) {
+ scoped_refptr<NodeChannel> broker = GetBrokerChannel();
+ if (broker) {
+ broker->RelayPortsMessage(name, std::move(channel_message));
+ } else {
+ base::AutoLock lock(broker_lock_);
+ pending_relay_messages_[name].emplace(std::move(channel_message));
+ }
+ return;
+ }
+ }
+#endif // defined(OS_WIN)
if (peer) {
peer->PortsMessage(std::move(channel_message));
@@ -643,7 +682,7 @@ void NodeController::OnBrokerClientAdded(const ports::NodeName& from_node,
}
// This should have come from our own broker.
- if(GetBrokerChannel() != GetPeerChannel(from_node)) {
+ if (GetBrokerChannel() != GetPeerChannel(from_node)) {
DLOG(ERROR) << "BrokerClientAdded from non-broker node " << from_node;
return;
}
@@ -711,7 +750,7 @@ void NodeController::OnAcceptBrokerClient(const ports::NodeName& from_node,
pending_broker_clients.pop();
}
-#if defined(OS_WIN)
+#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
// Have the broker relay any messages we have waiting.
for (auto& entry : pending_relay_messages) {
const ports::NodeName& destination = entry.first;
@@ -821,11 +860,13 @@ void NodeController::OnIntroduce(const ports::NodeName& from_node,
AddPeer(name, channel, true /* start_channel */);
}
-#if defined(OS_WIN)
+#if defined(OS_WIN) || (defined(OS_MACOSX) && !defined(OS_IOS))
void NodeController::OnRelayPortsMessage(const ports::NodeName& from_node,
base::ProcessHandle from_process,
const ports::NodeName& destination,
Channel::MessagePtr message) {
+ DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
+
if (GetBrokerChannel()) {
// Only the broker should be asked to relay a message.
LOG(ERROR) << "Non-broker refusing to relay message.";
@@ -836,6 +877,7 @@ void NodeController::OnRelayPortsMessage(const ports::NodeName& from_node,
// The parent should always know which process this came from.
DCHECK(from_process != base::kNullProcessHandle);
+#if defined(OS_WIN)
// Rewrite the handles to this (the parent) process. If the message is
// destined for another child process, the handles will be rewritten to that
// process before going out (see NodeChannel::WriteChannelMessage).
@@ -847,6 +889,22 @@ void NodeController::OnRelayPortsMessage(const ports::NodeName& from_node,
message->num_handles())) {
DLOG(ERROR) << "Failed to relay one or more handles.";
}
+#else
+ MachPortRelay* relay = GetMachPortRelay();
+ if (!relay) {
+ LOG(ERROR) << "Receiving mach ports without a port relay from "
+ << from_node << ". Dropping message.";
+ return;
+ }
+ if (!relay->ExtractPortRights(message.get(), from_process)) {
+ // NodeChannel should ensure that MachPortRelay is ready for the remote
+ // process. At this point, if the port extraction failed, either something
+ // went wrong in the mach stuff, or the remote process died.
+ LOG(ERROR) << "Error on receiving mach ports " << from_node
+ << ". Dropping message.";
+ return;
+ }
+#endif // defined(OS_WIN)
if (destination == name_) {
// Great, we can deliver this message locally.
@@ -873,6 +931,20 @@ void NodeController::OnChannelError(const ports::NodeName& from_node) {
}
}
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+MachPortRelay* NodeController::GetMachPortRelay() {
+ {
+ base::AutoLock lock(parent_lock_);
+ // Return null if we're not the root.
+ if (bootstrap_parent_channel_ || parent_name_ != ports::kInvalidNodeName)
+ return nullptr;
+ }
+
+ base::AutoLock lock(mach_port_relay_lock_);
+ return mach_port_relay_.get();
+}
+#endif
+
void NodeController::DestroyOnIOThreadShutdown() {
destroy_on_io_thread_shutdown_ = true;
}

Powered by Google App Engine
This is Rietveld 408576698