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

Unified Diff: mojo/edk/system/child_broker.cc

Issue 1524333002: Fix race condition with multiplexed message pipes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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
« no previous file with comments | « mojo/edk/system/child_broker.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/edk/system/child_broker.cc
diff --git a/mojo/edk/system/child_broker.cc b/mojo/edk/system/child_broker.cc
index 2964d20e92e23c469466eb1198966eec9ba81280..d686e74229ed765654e29ebea81af63344bf4cdd 100644
--- a/mojo/edk/system/child_broker.cc
+++ b/mojo/edk/system/child_broker.cc
@@ -138,15 +138,9 @@ void ChildBroker::ConnectMessagePipe(uint64_t pipe_id,
base::Bind(&ChildBroker::ChannelDestructed, base::Unretained(this)));
}
- connected_pipes_[pending_connects_[pipe_id]] = in_process_pipes_channel1_;
- connected_pipes_[message_pipe] = in_process_pipes_channel2_;
- in_process_pipes_channel1_->AddRoute(pipe_id, pending_connects_[pipe_id]);
- in_process_pipes_channel2_->AddRoute(pipe_id, message_pipe);
- pending_connects_[pipe_id]->GotNonTransferableChannel(
- in_process_pipes_channel1_->channel());
- message_pipe->GotNonTransferableChannel(
- in_process_pipes_channel2_->channel());
-
+ AttachMessagePipe(pending_connects_[pipe_id], pipe_id,
+ in_process_pipes_channel1_);
+ AttachMessagePipe(message_pipe, pipe_id, in_process_pipes_channel2_);
pending_connects_.erase(pipe_id);
return;
}
@@ -212,17 +206,13 @@ void ChildBroker::OnReadMessage(
pending_connects_.erase(pipe_id);
if (peer_pid == 0) {
// The other side is in the parent process.
- connected_pipes_[pipe] = parent_async_channel_;
- parent_async_channel_->AddRoute(pipe_id, pipe);
- pipe->GotNonTransferableChannel(parent_async_channel_->channel());
+ AttachMessagePipe(pipe, pipe_id, parent_async_channel_);
} else if (channels_.find(peer_pid) == channels_.end()) {
// We saw the peer process die before we got the reply from the parent.
pipe->OnError(ERROR_READ_SHUTDOWN);
} else {
CHECK(connected_pipes_.find(pipe) == connected_pipes_.end());
- connected_pipes_[pipe] = channels_[peer_pid];
- channels_[peer_pid]->AddRoute(pipe_id, pipe);
- pipe->GotNonTransferableChannel(channels_[peer_pid]->channel());
+ AttachMessagePipe(pipe, pipe_id, channels_[peer_pid]);
}
} else {
NOTREACHED();
@@ -273,6 +263,18 @@ void ChildBroker::InitAsyncChannel(
}
}
+void ChildBroker::AttachMessagePipe(MessagePipeDispatcher* message_pipe,
+ uint64_t pipe_id,
+ RoutedRawChannel* raw_channel) {
+ connected_pipes_[message_pipe] = raw_channel;
+ // Note: we must call GotNonTransferableChannel before AddRoute because there
+ // could be race conditions if the pipe got queued messages in |AddRoute| but
+ // then when it's read it returns no messages because it doesn't have the
+ // channel yet.
+ message_pipe->GotNonTransferableChannel(raw_channel->channel());
+ raw_channel->AddRoute(pipe_id, message_pipe);
+}
+
#if defined(OS_WIN)
bool ChildBroker::WriteAndReadResponse(BrokerMessage* message,
« no previous file with comments | « mojo/edk/system/child_broker.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698