| 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 |