| 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/broker_state.h" | 5 #include "mojo/edk/system/broker_state.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 AttachMessagePipe(pending_connects_[pipe_id], pipe_id, | 86 AttachMessagePipe(pending_connects_[pipe_id], pipe_id, |
| 87 in_process_pipes_channel1_); | 87 in_process_pipes_channel1_); |
| 88 AttachMessagePipe(message_pipe, pipe_id, in_process_pipes_channel2_); | 88 AttachMessagePipe(message_pipe, pipe_id, in_process_pipes_channel2_); |
| 89 pending_connects_.erase(pipe_id); | 89 pending_connects_.erase(pipe_id); |
| 90 return; | 90 return; |
| 91 } | 91 } |
| 92 | 92 |
| 93 if (pending_child_connects_.find(pipe_id) != pending_child_connects_.end()) { | 93 if (pending_child_connects_.find(pipe_id) != pending_child_connects_.end()) { |
| 94 // A child process has already tried to connect. | 94 // A child process has already tried to connect. |
| 95 ChildBrokerHost* child_host = pending_child_connects_[pipe_id]; | 95 ChildBrokerHost* child_host = pending_child_connects_[pipe_id]; |
| 96 AttachMessagePipe(message_pipe, pipe_id, child_host->channel()); | 96 if (child_host && child_host->channel()) { |
| 97 child_host->ConnectMessagePipe(pipe_id, 0); | 97 AttachMessagePipe(message_pipe, pipe_id, child_host->channel()); |
| 98 child_host->ConnectMessagePipe(pipe_id, 0); |
| 99 } else { |
| 100 message_pipe->OnError(RawChannel::Delegate::ERROR_READ_SHUTDOWN); |
| 101 } |
| 102 |
| 98 pending_child_connects_.erase(pipe_id); | 103 pending_child_connects_.erase(pipe_id); |
| 99 return; | 104 return; |
| 100 } | 105 } |
| 101 | 106 |
| 102 pending_connects_[pipe_id] = message_pipe; | 107 pending_connects_[pipe_id] = message_pipe; |
| 103 } | 108 } |
| 104 | 109 |
| 105 void BrokerState::CloseMessagePipe(uint64_t pipe_id, | 110 void BrokerState::CloseMessagePipe(uint64_t pipe_id, |
| 106 MessagePipeDispatcher* message_pipe) { | 111 MessagePipeDispatcher* message_pipe) { |
| 107 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); | 112 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); |
| 108 | 113 |
| 109 CHECK(connected_pipes_.find(message_pipe) != connected_pipes_.end()); | 114 CHECK(connected_pipes_.find(message_pipe) != connected_pipes_.end()); |
| 110 connected_pipes_[message_pipe]->RemoveRoute(pipe_id); | 115 connected_pipes_[message_pipe]->RemoveRoute(pipe_id); |
| 111 connected_pipes_.erase(message_pipe); | 116 connected_pipes_.erase(message_pipe); |
| 112 } | 117 } |
| 113 | 118 |
| 114 void BrokerState::ChildBrokerHostCreated(ChildBrokerHost* child_broker_host) { | 119 void BrokerState::ChildBrokerHostCreated(ChildBrokerHost* child_broker_host) { |
| 115 base::AutoLock auto_lock(lock_); | 120 base::AutoLock auto_lock(lock_); |
| 116 CHECK(child_processes_.find(child_broker_host->GetProcessId()) == | 121 CHECK(child_processes_.find(child_broker_host->GetProcessId()) == |
| 117 child_processes_.end()); | 122 child_processes_.end()); |
| 118 child_processes_[child_broker_host->GetProcessId()] = child_broker_host; | 123 child_processes_[child_broker_host->GetProcessId()] = child_broker_host; |
| 119 } | 124 } |
| 120 | 125 |
| 121 void BrokerState::ChildBrokerHostDestructed( | 126 void BrokerState::ChildBrokerHostDestructed( |
| 122 ChildBrokerHost* child_broker_host) { | 127 ChildBrokerHost* child_broker_host) { |
| 123 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); | 128 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); |
| 124 base::AutoLock auto_lock(lock_); | 129 base::AutoLock auto_lock(lock_); |
| 125 | 130 |
| 126 for (auto it = pending_child_connects_.begin(); | 131 for (auto it = pending_child_connects_.begin(); |
| 127 it != pending_child_connects_.end();) { | 132 it != pending_child_connects_.end(); ++it) { |
| 128 if (it->second == child_broker_host) { | 133 if (it->second == child_broker_host) { |
| 129 // Since we can't do it = pending_child_connects_.erase(it); until | 134 // Signify that the process has died. When another process tries to |
| 130 // hash_map uses unordered_map on posix. | 135 // connect to the message pipe, we will tell it that the peer has died so |
| 131 auto cur = it++; | 136 // that it can fire a peer closed notification. |
| 132 pending_child_connects_.erase(cur); | 137 it->second = nullptr; |
| 133 } else { | |
| 134 it++; | |
| 135 } | 138 } |
| 136 } | 139 } |
| 137 | 140 |
| 138 base::ProcessId pid = child_broker_host->GetProcessId(); | 141 base::ProcessId pid = child_broker_host->GetProcessId(); |
| 139 for (auto it = connected_processes_.begin(); | 142 for (auto it = connected_processes_.begin(); |
| 140 it != connected_processes_.end();) { | 143 it != connected_processes_.end();) { |
| 141 if ((*it).first == pid || (*it).second == pid) { | 144 if ((*it).first == pid || (*it).second == pid) { |
| 142 // Since we can't do it = pending_child_connects_.erase(it); until | 145 // Since we can't do it = connected_processes_.erase(it); until hash_map |
| 143 // hash_map uses unordered_map on posix. | 146 // uses unordered_map on posix. |
| 144 auto cur = it++; | 147 auto cur = it++; |
| 145 connected_processes_.erase(cur); | 148 connected_processes_.erase(cur); |
| 146 } else { | 149 } else { |
| 147 it++; | 150 it++; |
| 148 } | 151 } |
| 149 } | 152 } |
| 150 | 153 |
| 151 CHECK(child_processes_.find(pid) != child_processes_.end()); | 154 CHECK(child_processes_.find(pid) != child_processes_.end()); |
| 152 child_processes_.erase(pid); | 155 child_processes_.erase(pid); |
| 153 } | 156 } |
| 154 | 157 |
| 155 void BrokerState::HandleConnectMessagePipe(ChildBrokerHost* pipe_process, | 158 void BrokerState::HandleConnectMessagePipe(ChildBrokerHost* pipe_process, |
| 156 uint64_t pipe_id) { | 159 uint64_t pipe_id) { |
| 157 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); | 160 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); |
| 158 base::AutoLock auto_lock(lock_); | 161 base::AutoLock auto_lock(lock_); |
| 159 if (pending_child_connects_.find(pipe_id) != pending_child_connects_.end()) { | 162 if (pending_child_connects_.find(pipe_id) != pending_child_connects_.end()) { |
| 160 // Another child process is waiting to connect to the given pipe. | 163 // Another child process is waiting to connect to the given pipe. |
| 161 ChildBrokerHost* pending_pipe_process = pending_child_connects_[pipe_id]; | 164 ChildBrokerHost* pending_pipe_process = pending_child_connects_[pipe_id]; |
| 162 EnsureProcessesConnected(pipe_process->GetProcessId(), | 165 if (pending_pipe_process && pending_pipe_process->channel()) { |
| 163 pending_pipe_process->GetProcessId()); | 166 EnsureProcessesConnected(pipe_process->GetProcessId(), |
| 164 pending_pipe_process->ConnectMessagePipe( | 167 pending_pipe_process->GetProcessId()); |
| 165 pipe_id, pipe_process->GetProcessId()); | 168 pending_pipe_process->ConnectMessagePipe( |
| 166 pipe_process->ConnectMessagePipe( | 169 pipe_id, pipe_process->GetProcessId()); |
| 167 pipe_id, pending_pipe_process->GetProcessId()); | 170 pipe_process->ConnectMessagePipe( |
| 171 pipe_id, pending_pipe_process->GetProcessId()); |
| 172 } else { |
| 173 pipe_process->PeerDied(pipe_id); |
| 174 } |
| 168 pending_child_connects_.erase(pipe_id); | 175 pending_child_connects_.erase(pipe_id); |
| 169 return; | 176 return; |
| 170 } | 177 } |
| 171 | 178 |
| 172 if (pending_connects_.find(pipe_id) != pending_connects_.end()) { | 179 if (pending_connects_.find(pipe_id) != pending_connects_.end()) { |
| 173 // This parent process is the other side of the given pipe. | 180 // This parent process is the other side of the given pipe. |
| 174 MessagePipeDispatcher* pending_pipe = pending_connects_[pipe_id]; | 181 MessagePipeDispatcher* pending_pipe = pending_connects_[pipe_id]; |
| 175 AttachMessagePipe(pending_pipe, pipe_id, pipe_process->channel()); | 182 AttachMessagePipe(pending_pipe, pipe_id, pipe_process->channel()); |
| 176 pipe_process->ConnectMessagePipe(pipe_id, 0); | 183 pipe_process->ConnectMessagePipe(pipe_id, 0); |
| 177 pending_connects_.erase(pipe_id); | 184 pending_connects_.erase(pipe_id); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 // then when it's read it returns no messages because it doesn't have the | 244 // then when it's read it returns no messages because it doesn't have the |
| 238 // channel yet. | 245 // channel yet. |
| 239 message_pipe->GotNonTransferableChannel(raw_channel->channel()); | 246 message_pipe->GotNonTransferableChannel(raw_channel->channel()); |
| 240 // The above call could have caused |CloseMessagePipe| to be called. | 247 // The above call could have caused |CloseMessagePipe| to be called. |
| 241 if (connected_pipes_.find(message_pipe) != connected_pipes_.end()) | 248 if (connected_pipes_.find(message_pipe) != connected_pipes_.end()) |
| 242 raw_channel->AddRoute(pipe_id, message_pipe); | 249 raw_channel->AddRoute(pipe_id, message_pipe); |
| 243 } | 250 } |
| 244 | 251 |
| 245 } // namespace edk | 252 } // namespace edk |
| 246 } // namespace mojo | 253 } // namespace mojo |
| OLD | NEW |