| OLD | NEW |
| 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/child_broker.h" | 5 #include "mojo/edk/system/child_broker.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 client_handle = channel_pair.PassClientHandle(); | 131 client_handle = channel_pair.PassClientHandle(); |
| 132 #endif | 132 #endif |
| 133 in_process_pipes_channel1_ = new RoutedRawChannel( | 133 in_process_pipes_channel1_ = new RoutedRawChannel( |
| 134 server_handle.Pass(), | 134 server_handle.Pass(), |
| 135 base::Bind(&ChildBroker::ChannelDestructed, base::Unretained(this))); | 135 base::Bind(&ChildBroker::ChannelDestructed, base::Unretained(this))); |
| 136 in_process_pipes_channel2_ = new RoutedRawChannel( | 136 in_process_pipes_channel2_ = new RoutedRawChannel( |
| 137 client_handle.Pass(), | 137 client_handle.Pass(), |
| 138 base::Bind(&ChildBroker::ChannelDestructed, base::Unretained(this))); | 138 base::Bind(&ChildBroker::ChannelDestructed, base::Unretained(this))); |
| 139 } | 139 } |
| 140 | 140 |
| 141 connected_pipes_[pending_connects_[pipe_id]] = in_process_pipes_channel1_; | 141 AttachMessagePipe(pending_connects_[pipe_id], pipe_id, |
| 142 connected_pipes_[message_pipe] = in_process_pipes_channel2_; | 142 in_process_pipes_channel1_); |
| 143 in_process_pipes_channel1_->AddRoute(pipe_id, pending_connects_[pipe_id]); | 143 AttachMessagePipe(message_pipe, pipe_id, in_process_pipes_channel2_); |
| 144 in_process_pipes_channel2_->AddRoute(pipe_id, message_pipe); | |
| 145 pending_connects_[pipe_id]->GotNonTransferableChannel( | |
| 146 in_process_pipes_channel1_->channel()); | |
| 147 message_pipe->GotNonTransferableChannel( | |
| 148 in_process_pipes_channel2_->channel()); | |
| 149 | |
| 150 pending_connects_.erase(pipe_id); | 144 pending_connects_.erase(pipe_id); |
| 151 return; | 145 return; |
| 152 } | 146 } |
| 153 | 147 |
| 154 data.type = CONNECT_MESSAGE_PIPE; | 148 data.type = CONNECT_MESSAGE_PIPE; |
| 155 scoped_ptr<MessageInTransit> message(new MessageInTransit( | 149 scoped_ptr<MessageInTransit> message(new MessageInTransit( |
| 156 MessageInTransit::Type::MESSAGE, sizeof(data), &data)); | 150 MessageInTransit::Type::MESSAGE, sizeof(data), &data)); |
| 157 pending_connects_[pipe_id] = message_pipe; | 151 pending_connects_[pipe_id] = message_pipe; |
| 158 WriteAsyncMessage(message.Pass()); | 152 WriteAsyncMessage(message.Pass()); |
| 159 } | 153 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 static_cast<const PeerPipeConnectedMessage*>(message_view.bytes()); | 199 static_cast<const PeerPipeConnectedMessage*>(message_view.bytes()); |
| 206 | 200 |
| 207 uint64_t pipe_id = message->pipe_id; | 201 uint64_t pipe_id = message->pipe_id; |
| 208 uint64_t peer_pid = message->process_id; | 202 uint64_t peer_pid = message->process_id; |
| 209 | 203 |
| 210 CHECK(pending_connects_.find(pipe_id) != pending_connects_.end()); | 204 CHECK(pending_connects_.find(pipe_id) != pending_connects_.end()); |
| 211 MessagePipeDispatcher* pipe = pending_connects_[pipe_id]; | 205 MessagePipeDispatcher* pipe = pending_connects_[pipe_id]; |
| 212 pending_connects_.erase(pipe_id); | 206 pending_connects_.erase(pipe_id); |
| 213 if (peer_pid == 0) { | 207 if (peer_pid == 0) { |
| 214 // The other side is in the parent process. | 208 // The other side is in the parent process. |
| 215 connected_pipes_[pipe] = parent_async_channel_; | 209 AttachMessagePipe(pipe, pipe_id, parent_async_channel_); |
| 216 parent_async_channel_->AddRoute(pipe_id, pipe); | |
| 217 pipe->GotNonTransferableChannel(parent_async_channel_->channel()); | |
| 218 } else if (channels_.find(peer_pid) == channels_.end()) { | 210 } else if (channels_.find(peer_pid) == channels_.end()) { |
| 219 // We saw the peer process die before we got the reply from the parent. | 211 // We saw the peer process die before we got the reply from the parent. |
| 220 pipe->OnError(ERROR_READ_SHUTDOWN); | 212 pipe->OnError(ERROR_READ_SHUTDOWN); |
| 221 } else { | 213 } else { |
| 222 CHECK(connected_pipes_.find(pipe) == connected_pipes_.end()); | 214 CHECK(connected_pipes_.find(pipe) == connected_pipes_.end()); |
| 223 connected_pipes_[pipe] = channels_[peer_pid]; | 215 AttachMessagePipe(pipe, pipe_id, channels_[peer_pid]); |
| 224 channels_[peer_pid]->AddRoute(pipe_id, pipe); | |
| 225 pipe->GotNonTransferableChannel(channels_[peer_pid]->channel()); | |
| 226 } | 216 } |
| 227 } else { | 217 } else { |
| 228 NOTREACHED(); | 218 NOTREACHED(); |
| 229 } | 219 } |
| 230 } | 220 } |
| 231 | 221 |
| 232 void ChildBroker::OnError(Error error) { | 222 void ChildBroker::OnError(Error error) { |
| 233 // The parent process shut down. | 223 // The parent process shut down. |
| 234 } | 224 } |
| 235 | 225 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 266 async_channel_queue_.GetMessage()); | 256 async_channel_queue_.GetMessage()); |
| 267 } | 257 } |
| 268 | 258 |
| 269 while (!pending_inprocess_connects_.empty()) { | 259 while (!pending_inprocess_connects_.empty()) { |
| 270 ConnectMessagePipe(pending_inprocess_connects_.begin()->first, | 260 ConnectMessagePipe(pending_inprocess_connects_.begin()->first, |
| 271 pending_inprocess_connects_.begin()->second); | 261 pending_inprocess_connects_.begin()->second); |
| 272 pending_inprocess_connects_.erase(pending_inprocess_connects_.begin()); | 262 pending_inprocess_connects_.erase(pending_inprocess_connects_.begin()); |
| 273 } | 263 } |
| 274 } | 264 } |
| 275 | 265 |
| 266 void ChildBroker::AttachMessagePipe(MessagePipeDispatcher* message_pipe, |
| 267 uint64_t pipe_id, |
| 268 RoutedRawChannel* raw_channel) { |
| 269 connected_pipes_[message_pipe] = raw_channel; |
| 270 // Note: we must call GotNonTransferableChannel before AddRoute because there |
| 271 // could be race conditions if the pipe got queued messages in |AddRoute| but |
| 272 // then when it's read it returns no messages because it doesn't have the |
| 273 // channel yet. |
| 274 message_pipe->GotNonTransferableChannel(raw_channel->channel()); |
| 275 raw_channel->AddRoute(pipe_id, message_pipe); |
| 276 } |
| 277 |
| 276 #if defined(OS_WIN) | 278 #if defined(OS_WIN) |
| 277 | 279 |
| 278 bool ChildBroker::WriteAndReadResponse(BrokerMessage* message, | 280 bool ChildBroker::WriteAndReadResponse(BrokerMessage* message, |
| 279 void* response, | 281 void* response, |
| 280 uint32_t response_size) { | 282 uint32_t response_size) { |
| 281 CHECK(parent_sync_channel_.is_valid()); | 283 CHECK(parent_sync_channel_.is_valid()); |
| 282 | 284 |
| 283 bool result = true; | 285 bool result = true; |
| 284 DWORD bytes_written = 0; | 286 DWORD bytes_written = 0; |
| 285 // This will always write in one chunk per | 287 // This will always write in one chunk per |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 if (WriteAndReadResponse(&message, handles, response_size)) { | 320 if (WriteAndReadResponse(&message, handles, response_size)) { |
| 319 server->reset(PlatformHandle(handles[0])); | 321 server->reset(PlatformHandle(handles[0])); |
| 320 client->reset(PlatformHandle(handles[1])); | 322 client->reset(PlatformHandle(handles[1])); |
| 321 } | 323 } |
| 322 } | 324 } |
| 323 | 325 |
| 324 #endif | 326 #endif |
| 325 | 327 |
| 326 } // namespace edk | 328 } // namespace edk |
| 327 } // namespace mojo | 329 } // namespace mojo |
| OLD | NEW |