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 |