OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/message_pump/message_pump_mojo.h" | 5 #include "mojo/message_pump/message_pump_mojo.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 more_work_is_plausible = delegate->DoIdleWork(); | 161 more_work_is_plausible = delegate->DoIdleWork(); |
162 if (run_state->should_quit) | 162 if (run_state->should_quit) |
163 break; | 163 break; |
164 } | 164 } |
165 } | 165 } |
166 | 166 |
167 bool MessagePumpMojo::DoInternalWork(const RunState& run_state, bool block) { | 167 bool MessagePumpMojo::DoInternalWork(const RunState& run_state, bool block) { |
168 const MojoDeadline deadline = block ? GetDeadlineForWait(run_state) : 0; | 168 const MojoDeadline deadline = block ? GetDeadlineForWait(run_state) : 0; |
169 const WaitState wait_state = GetWaitState(); | 169 const WaitState wait_state = GetWaitState(); |
170 | 170 |
| 171 std::vector<MojoHandleSignalsState> states(wait_state.handles.size()); |
171 const WaitManyResult wait_many_result = | 172 const WaitManyResult wait_many_result = |
172 WaitMany(wait_state.handles, wait_state.wait_signals, deadline, nullptr); | 173 WaitMany(wait_state.handles, wait_state.wait_signals, deadline, &states); |
173 const MojoResult result = wait_many_result.result; | 174 const MojoResult result = wait_many_result.result; |
174 bool did_work = true; | 175 bool did_work = true; |
175 if (result == MOJO_RESULT_OK) { | 176 if (result == MOJO_RESULT_OK) { |
176 if (wait_many_result.index == 0) { | 177 if (wait_many_result.index == 0) { |
177 // Control pipe was written to. | 178 if (states[0].satisfied_signals & MOJO_HANDLE_SIGNAL_PEER_CLOSED) { |
178 ReadMessageRaw(read_handle_.get(), NULL, NULL, NULL, NULL, | 179 // The Mojo EDK is shutting down. The ThreadQuitHelper task in |
179 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); | 180 // base::Thread won't get run since the control pipe depends on the EDK |
| 181 // staying alive. So quit manually to avoid this thread hanging. |
| 182 Quit(); |
| 183 } else { |
| 184 // Control pipe was written to. |
| 185 ReadMessageRaw(read_handle_.get(), NULL, NULL, NULL, NULL, |
| 186 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); |
| 187 } |
180 } else { | 188 } else { |
181 DCHECK(handlers_.find(wait_state.handles[wait_many_result.index]) != | 189 DCHECK(handlers_.find(wait_state.handles[wait_many_result.index]) != |
182 handlers_.end()); | 190 handlers_.end()); |
183 WillSignalHandler(); | 191 WillSignalHandler(); |
184 handlers_[wait_state.handles[wait_many_result.index]] | 192 handlers_[wait_state.handles[wait_many_result.index]] |
185 .handler->OnHandleReady(wait_state.handles[wait_many_result.index]); | 193 .handler->OnHandleReady(wait_state.handles[wait_many_result.index]); |
186 DidSignalHandler(); | 194 DidSignalHandler(); |
187 } | 195 } |
188 } else { | 196 } else { |
189 switch (result) { | 197 switch (result) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 handlers_.erase(wait_state.handles[index]); | 246 handlers_.erase(wait_state.handles[index]); |
239 WillSignalHandler(); | 247 WillSignalHandler(); |
240 handler->OnHandleError(wait_state.handles[index], result); | 248 handler->OnHandleError(wait_state.handles[index], result); |
241 DidSignalHandler(); | 249 DidSignalHandler(); |
242 } | 250 } |
243 | 251 |
244 void MessagePumpMojo::SignalControlPipe() { | 252 void MessagePumpMojo::SignalControlPipe() { |
245 const MojoResult result = | 253 const MojoResult result = |
246 WriteMessageRaw(write_handle_.get(), NULL, 0, NULL, 0, | 254 WriteMessageRaw(write_handle_.get(), NULL, 0, NULL, 0, |
247 MOJO_WRITE_MESSAGE_FLAG_NONE); | 255 MOJO_WRITE_MESSAGE_FLAG_NONE); |
| 256 if (result == MOJO_RESULT_FAILED_PRECONDITION) { |
| 257 // Mojo EDK is shutting down. |
| 258 return; |
| 259 } |
| 260 |
248 // If we can't write we likely won't wake up the thread and there is a strong | 261 // If we can't write we likely won't wake up the thread and there is a strong |
249 // chance we'll deadlock. | 262 // chance we'll deadlock. |
250 CHECK_EQ(MOJO_RESULT_OK, result); | 263 CHECK_EQ(MOJO_RESULT_OK, result); |
251 } | 264 } |
252 | 265 |
253 MessagePumpMojo::WaitState MessagePumpMojo::GetWaitState() const { | 266 MessagePumpMojo::WaitState MessagePumpMojo::GetWaitState() const { |
254 WaitState wait_state; | 267 WaitState wait_state; |
255 wait_state.handles.push_back(read_handle_.get()); | 268 wait_state.handles.push_back(read_handle_.get()); |
256 wait_state.wait_signals.push_back(MOJO_HANDLE_SIGNAL_READABLE); | 269 wait_state.wait_signals.push_back( |
| 270 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED); |
257 | 271 |
258 for (HandleToHandler::const_iterator i = handlers_.begin(); | 272 for (HandleToHandler::const_iterator i = handlers_.begin(); |
259 i != handlers_.end(); ++i) { | 273 i != handlers_.end(); ++i) { |
260 wait_state.handles.push_back(i->first); | 274 wait_state.handles.push_back(i->first); |
261 wait_state.wait_signals.push_back(i->second.wait_signals); | 275 wait_state.wait_signals.push_back(i->second.wait_signals); |
262 } | 276 } |
263 return wait_state; | 277 return wait_state; |
264 } | 278 } |
265 | 279 |
266 MojoDeadline MessagePumpMojo::GetDeadlineForWait( | 280 MojoDeadline MessagePumpMojo::GetDeadlineForWait( |
(...skipping 12 matching lines...) Expand all Loading... |
279 void MessagePumpMojo::WillSignalHandler() { | 293 void MessagePumpMojo::WillSignalHandler() { |
280 FOR_EACH_OBSERVER(Observer, observers_, WillSignalHandler()); | 294 FOR_EACH_OBSERVER(Observer, observers_, WillSignalHandler()); |
281 } | 295 } |
282 | 296 |
283 void MessagePumpMojo::DidSignalHandler() { | 297 void MessagePumpMojo::DidSignalHandler() { |
284 FOR_EACH_OBSERVER(Observer, observers_, DidSignalHandler()); | 298 FOR_EACH_OBSERVER(Observer, observers_, DidSignalHandler()); |
285 } | 299 } |
286 | 300 |
287 } // namespace common | 301 } // namespace common |
288 } // namespace mojo | 302 } // namespace mojo |
OLD | NEW |