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

Side by Side Diff: mojo/edk/system/broker_state.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 unified diff | Download patch
« no previous file with comments | « mojo/edk/system/broker_state.h ('k') | mojo/edk/system/child_broker.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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/broker_state.h" 5 #include "mojo/edk/system/broker_state.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/rand_util.h" 8 #include "base/rand_util.h"
9 #include "mojo/edk/embedder/embedder_internal.h" 9 #include "mojo/edk/embedder/embedder_internal.h"
10 #include "mojo/edk/embedder/platform_channel_pair.h" 10 #include "mojo/edk/embedder/platform_channel_pair.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 if (!in_process_pipes_channel1_) { 73 if (!in_process_pipes_channel1_) {
74 PlatformChannelPair channel_pair; 74 PlatformChannelPair channel_pair;
75 in_process_pipes_channel1_ = new RoutedRawChannel( 75 in_process_pipes_channel1_ = new RoutedRawChannel(
76 channel_pair.PassServerHandle(), 76 channel_pair.PassServerHandle(),
77 base::Bind(&BrokerState::ChannelDestructed, base::Unretained(this))); 77 base::Bind(&BrokerState::ChannelDestructed, base::Unretained(this)));
78 in_process_pipes_channel2_ = new RoutedRawChannel( 78 in_process_pipes_channel2_ = new RoutedRawChannel(
79 channel_pair.PassClientHandle(), 79 channel_pair.PassClientHandle(),
80 base::Bind(&BrokerState::ChannelDestructed, base::Unretained(this))); 80 base::Bind(&BrokerState::ChannelDestructed, base::Unretained(this)));
81 } 81 }
82 82
83 connected_pipes_[pending_connects_[pipe_id]] = in_process_pipes_channel1_; 83 AttachMessagePipe(pending_connects_[pipe_id], pipe_id,
84 connected_pipes_[message_pipe] = in_process_pipes_channel2_; 84 in_process_pipes_channel1_);
85 in_process_pipes_channel1_->AddRoute(pipe_id, pending_connects_[pipe_id]); 85 AttachMessagePipe(message_pipe, pipe_id, in_process_pipes_channel2_);
86 in_process_pipes_channel2_->AddRoute(pipe_id, message_pipe);
87 pending_connects_[pipe_id]->GotNonTransferableChannel(
88 in_process_pipes_channel1_->channel());
89 message_pipe->GotNonTransferableChannel(
90 in_process_pipes_channel2_->channel());
91
92 pending_connects_.erase(pipe_id); 86 pending_connects_.erase(pipe_id);
93 return; 87 return;
94 } 88 }
95 89
96 if (pending_child_connects_.find(pipe_id) != pending_child_connects_.end()) { 90 if (pending_child_connects_.find(pipe_id) != pending_child_connects_.end()) {
97 // A child process has already tried to connect. 91 // A child process has already tried to connect.
98 ChildBrokerHost* child_host = pending_child_connects_[pipe_id]; 92 ChildBrokerHost* child_host = pending_child_connects_[pipe_id];
99 child_host->channel()->AddRoute(pipe_id, message_pipe); 93 AttachMessagePipe(message_pipe, pipe_id, child_host->channel());
100 child_host->ConnectMessagePipe(pipe_id, 0); 94 child_host->ConnectMessagePipe(pipe_id, 0);
101 pending_child_connects_.erase(pipe_id); 95 pending_child_connects_.erase(pipe_id);
102 connected_pipes_[message_pipe] = child_host->channel();
103 message_pipe->GotNonTransferableChannel(child_host->channel()->channel());
104 return; 96 return;
105 } 97 }
106 98
107 pending_connects_[pipe_id] = message_pipe; 99 pending_connects_[pipe_id] = message_pipe;
108 } 100 }
109 101
110 void BrokerState::CloseMessagePipe(uint64_t pipe_id, 102 void BrokerState::CloseMessagePipe(uint64_t pipe_id,
111 MessagePipeDispatcher* message_pipe) { 103 MessagePipeDispatcher* message_pipe) {
112 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); 104 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread());
113 base::AutoLock auto_lock(lock_); 105 base::AutoLock auto_lock(lock_);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 pipe_id, pipe_process->GetProcessId()); 163 pipe_id, pipe_process->GetProcessId());
172 pipe_process->ConnectMessagePipe( 164 pipe_process->ConnectMessagePipe(
173 pipe_id, pending_pipe_process->GetProcessId()); 165 pipe_id, pending_pipe_process->GetProcessId());
174 pending_child_connects_.erase(pipe_id); 166 pending_child_connects_.erase(pipe_id);
175 return; 167 return;
176 } 168 }
177 169
178 if (pending_connects_.find(pipe_id) != pending_connects_.end()) { 170 if (pending_connects_.find(pipe_id) != pending_connects_.end()) {
179 // This parent process is the other side of the given pipe. 171 // This parent process is the other side of the given pipe.
180 MessagePipeDispatcher* pending_pipe = pending_connects_[pipe_id]; 172 MessagePipeDispatcher* pending_pipe = pending_connects_[pipe_id];
181 connected_pipes_[pending_pipe] = pipe_process->channel(); 173 AttachMessagePipe(pending_pipe, pipe_id, pipe_process->channel());
182 pipe_process->channel()->AddRoute(pipe_id, pending_pipe);
183 pending_pipe->GotNonTransferableChannel(pipe_process->channel()->channel());
184 pipe_process->ConnectMessagePipe(pipe_id, 0); 174 pipe_process->ConnectMessagePipe(pipe_id, 0);
185 pending_connects_.erase(pipe_id); 175 pending_connects_.erase(pipe_id);
186 return; 176 return;
187 } 177 }
188 178
189 // This is the first connection request for pipe_id to reach the parent. 179 // This is the first connection request for pipe_id to reach the parent.
190 pending_child_connects_[pipe_id] = pipe_process; 180 pending_child_connects_[pipe_id] = pipe_process;
191 } 181 }
192 182
193 void BrokerState::HandleCancelConnectMessagePipe(uint64_t pipe_id) { 183 void BrokerState::HandleCancelConnectMessagePipe(uint64_t pipe_id) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 CHECK(child_processes_.find(pid2) != child_processes_.end()); 219 CHECK(child_processes_.find(pid2) != child_processes_.end());
230 child_processes_[pid1]->ConnectToProcess(pid2, 220 child_processes_[pid1]->ConnectToProcess(pid2,
231 channel_pair.PassServerHandle()); 221 channel_pair.PassServerHandle());
232 child_processes_[pid2]->ConnectToProcess(pid1, 222 child_processes_[pid2]->ConnectToProcess(pid1,
233 channel_pair.PassClientHandle()); 223 channel_pair.PassClientHandle());
234 } 224 }
235 225
236 void BrokerState::ChannelDestructed(RoutedRawChannel* channel) { 226 void BrokerState::ChannelDestructed(RoutedRawChannel* channel) {
237 } 227 }
238 228
229 void BrokerState::AttachMessagePipe(MessagePipeDispatcher* message_pipe,
230 uint64_t pipe_id,
231 RoutedRawChannel* raw_channel) {
232 connected_pipes_[message_pipe] = raw_channel;
233 // Note: we must call GotNonTransferableChannel before AddRoute because there
234 // could be race conditions if the pipe got queued messages in |AddRoute| but
235 // then when it's read it returns no messages because it doesn't have the
236 // channel yet.
237 message_pipe->GotNonTransferableChannel(raw_channel->channel());
238 raw_channel->AddRoute(pipe_id, message_pipe);
239 }
240
239 } // namespace edk 241 } // namespace edk
240 } // namespace mojo 242 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/system/broker_state.h ('k') | mojo/edk/system/child_broker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698