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/common/message_pump_mojo.h" | 5 #include "mojo/common/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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 | 166 |
167 more_work_is_plausible = delegate->DoIdleWork(); | 167 more_work_is_plausible = delegate->DoIdleWork(); |
168 if (run_state->should_quit) | 168 if (run_state->should_quit) |
169 break; | 169 break; |
170 } | 170 } |
171 } | 171 } |
172 | 172 |
173 bool MessagePumpMojo::DoInternalWork(const RunState& run_state, bool block) { | 173 bool MessagePumpMojo::DoInternalWork(const RunState& run_state, bool block) { |
174 const MojoDeadline deadline = block ? GetDeadlineForWait(run_state) : 0; | 174 const MojoDeadline deadline = block ? GetDeadlineForWait(run_state) : 0; |
175 const WaitState wait_state = GetWaitState(run_state); | 175 const WaitState wait_state = GetWaitState(run_state); |
176 const MojoResult result = | 176 |
177 WaitMany(wait_state.handles, wait_state.wait_signals, deadline); | 177 const WaitManyResult wait_many_result = |
| 178 WaitMany(wait_state.handles, wait_state.wait_signals, deadline, nullptr); |
| 179 const MojoResult result = wait_many_result.result; |
178 bool did_work = true; | 180 bool did_work = true; |
179 if (result == 0) { | 181 if (result == MOJO_RESULT_OK) { |
180 // Control pipe was written to. | 182 if (wait_many_result.index == 0) { |
181 ReadMessageRaw(run_state.read_handle.get(), NULL, NULL, NULL, NULL, | 183 // Control pipe was written to. |
182 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); | 184 ReadMessageRaw(run_state.read_handle.get(), NULL, NULL, NULL, NULL, |
183 } else if (result > 0) { | 185 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); |
184 const size_t index = static_cast<size_t>(result); | 186 } else { |
185 DCHECK(handlers_.find(wait_state.handles[index]) != handlers_.end()); | 187 DCHECK(handlers_.find(wait_state.handles[wait_many_result.index]) != |
186 WillSignalHandler(); | 188 handlers_.end()); |
187 handlers_[wait_state.handles[index]].handler->OnHandleReady( | 189 WillSignalHandler(); |
188 wait_state.handles[index]); | 190 handlers_[wait_state.handles[wait_many_result.index]] |
189 DidSignalHandler(); | 191 .handler->OnHandleReady(wait_state.handles[wait_many_result.index]); |
| 192 DidSignalHandler(); |
| 193 } |
190 } else { | 194 } else { |
191 switch (result) { | 195 switch (result) { |
192 case MOJO_RESULT_CANCELLED: | 196 case MOJO_RESULT_CANCELLED: |
193 case MOJO_RESULT_FAILED_PRECONDITION: | 197 case MOJO_RESULT_FAILED_PRECONDITION: |
194 RemoveFirstInvalidHandle(wait_state); | 198 RemoveInvalidHandle(wait_state, result, wait_many_result.index); |
195 break; | 199 break; |
196 case MOJO_RESULT_DEADLINE_EXCEEDED: | 200 case MOJO_RESULT_DEADLINE_EXCEEDED: |
197 did_work = false; | 201 did_work = false; |
198 break; | 202 break; |
199 default: | 203 default: |
200 base::debug::Alias(&result); | 204 base::debug::Alias(&result); |
201 // Unexpected result is likely fatal, crash so we can determine cause. | 205 // Unexpected result is likely fatal, crash so we can determine cause. |
202 CHECK(false); | 206 CHECK(false); |
203 } | 207 } |
204 } | 208 } |
(...skipping 12 matching lines...) Expand all Loading... |
217 WillSignalHandler(); | 221 WillSignalHandler(); |
218 i->second.handler->OnHandleError(i->first, MOJO_RESULT_DEADLINE_EXCEEDED); | 222 i->second.handler->OnHandleError(i->first, MOJO_RESULT_DEADLINE_EXCEEDED); |
219 DidSignalHandler(); | 223 DidSignalHandler(); |
220 handlers_.erase(i->first); | 224 handlers_.erase(i->first); |
221 did_work = true; | 225 did_work = true; |
222 } | 226 } |
223 } | 227 } |
224 return did_work; | 228 return did_work; |
225 } | 229 } |
226 | 230 |
227 void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) { | 231 void MessagePumpMojo::RemoveInvalidHandle(const WaitState& wait_state, |
| 232 MojoResult result, |
| 233 uint32_t index) { |
228 // TODO(sky): deal with control pipe going bad. | 234 // TODO(sky): deal with control pipe going bad. |
229 for (size_t i = 0; i < wait_state.handles.size(); ++i) { | 235 CHECK(result == MOJO_RESULT_FAILED_PRECONDITION || |
230 const MojoResult result = | 236 result == MOJO_RESULT_CANCELLED); |
231 Wait(wait_state.handles[i], wait_state.wait_signals[i], 0); | 237 CHECK_NE(index, 0u); // Indicates the control pipe went bad. |
232 if (result == MOJO_RESULT_INVALID_ARGUMENT) { | |
233 // We should never have an invalid argument. If we do it indicates | |
234 // RemoveHandler() was not invoked and is likely to cause problems else | |
235 // where in the stack if we ignore it. | |
236 CHECK(false); | |
237 } else if (result == MOJO_RESULT_FAILED_PRECONDITION || | |
238 result == MOJO_RESULT_CANCELLED) { | |
239 CHECK_NE(i, 0u); // Indicates the control pipe went bad. | |
240 | 238 |
241 // Remove the handle first, this way if OnHandleError() tries to remove | 239 // Remove the handle first, this way if OnHandleError() tries to remove the |
242 // the handle our iterator isn't invalidated. | 240 // handle our iterator isn't invalidated. |
243 CHECK(handlers_.find(wait_state.handles[i]) != handlers_.end()); | 241 CHECK(handlers_.find(wait_state.handles[index]) != handlers_.end()); |
244 MessagePumpMojoHandler* handler = | 242 MessagePumpMojoHandler* handler = |
245 handlers_[wait_state.handles[i]].handler; | 243 handlers_[wait_state.handles[index]].handler; |
246 handlers_.erase(wait_state.handles[i]); | 244 handlers_.erase(wait_state.handles[index]); |
247 WillSignalHandler(); | 245 WillSignalHandler(); |
248 handler->OnHandleError(wait_state.handles[i], result); | 246 handler->OnHandleError(wait_state.handles[index], result); |
249 DidSignalHandler(); | 247 DidSignalHandler(); |
250 return; | |
251 } | |
252 } | |
253 } | 248 } |
254 | 249 |
255 void MessagePumpMojo::SignalControlPipe(const RunState& run_state) { | 250 void MessagePumpMojo::SignalControlPipe(const RunState& run_state) { |
256 const MojoResult result = | 251 const MojoResult result = |
257 WriteMessageRaw(run_state.write_handle.get(), NULL, 0, NULL, 0, | 252 WriteMessageRaw(run_state.write_handle.get(), NULL, 0, NULL, 0, |
258 MOJO_WRITE_MESSAGE_FLAG_NONE); | 253 MOJO_WRITE_MESSAGE_FLAG_NONE); |
259 // If we can't write we likely won't wake up the thread and there is a strong | 254 // If we can't write we likely won't wake up the thread and there is a strong |
260 // chance we'll deadlock. | 255 // chance we'll deadlock. |
261 CHECK_EQ(MOJO_RESULT_OK, result); | 256 CHECK_EQ(MOJO_RESULT_OK, result); |
262 } | 257 } |
(...skipping 28 matching lines...) Expand all Loading... |
291 void MessagePumpMojo::WillSignalHandler() { | 286 void MessagePumpMojo::WillSignalHandler() { |
292 FOR_EACH_OBSERVER(Observer, observers_, WillSignalHandler()); | 287 FOR_EACH_OBSERVER(Observer, observers_, WillSignalHandler()); |
293 } | 288 } |
294 | 289 |
295 void MessagePumpMojo::DidSignalHandler() { | 290 void MessagePumpMojo::DidSignalHandler() { |
296 FOR_EACH_OBSERVER(Observer, observers_, DidSignalHandler()); | 291 FOR_EACH_OBSERVER(Observer, observers_, DidSignalHandler()); |
297 } | 292 } |
298 | 293 |
299 } // namespace common | 294 } // namespace common |
300 } // namespace mojo | 295 } // namespace mojo |
OLD | NEW |