From 86045e737391ccffa0383eaa51c6c2bc858fa0ca Mon Sep 17 00:00:00 2001 From: amistry Date: Thu, 17 Mar 2016 17:48:43 -0700 Subject: [mojo-edk] Shutdown a node's bootstrap parent channel outside its lock. On OSX, NodeChannel::ShutDown() calls into NodeController::GetMachPortRelay() which acquires |parent_lock_| and deadlocks due to a recursuve lock acquisition. BUG=582468 Review URL: https://codereview.chromium.org/1808233003 Cr-Commit-Position: refs/heads/master@{#381852} --- mojo/edk/system/node_controller.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'mojo') diff --git a/mojo/edk/system/node_controller.cc b/mojo/edk/system/node_controller.cc index 3733c6c..30b331f 100644 --- a/mojo/edk/system/node_controller.cc +++ b/mojo/edk/system/node_controller.cc @@ -500,15 +500,20 @@ void NodeController::AcceptIncomingMessages() { void NodeController::DropAllPeers() { DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); + std::vector> all_peers; { base::AutoLock lock(parent_lock_); if (bootstrap_parent_channel_) { - bootstrap_parent_channel_->ShutDown(); - bootstrap_parent_channel_ = nullptr; + // |bootstrap_parent_channel_| isn't null'd here becuase we rely on its + // existence to determine whether or not this is the root node. Once + // bootstrap_parent_channel_->ShutDown() has been called, + // |bootstrap_parent_channel_| is essentially a dead object and it doesn't + // matter if it's deleted now or when |this| is deleted. + // Note: |bootstrap_parent_channel_| is only modified on the IO thread. + all_peers.push_back(bootstrap_parent_channel_); } } - std::vector> all_peers; { base::AutoLock lock(peers_lock_); for (const auto& peer : peers_) -- cgit v1.1