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 <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 case MOJO_RESULT_CANCELLED: | 288 case MOJO_RESULT_CANCELLED: |
289 case MOJO_RESULT_FAILED_PRECONDITION: | 289 case MOJO_RESULT_FAILED_PRECONDITION: |
290 DVLOG(1) << "Error: " << handle_results[i] | 290 DVLOG(1) << "Error: " << handle_results[i] |
291 << " handle: " << handle.value(); | 291 << " handle: " << handle.value(); |
292 if (handle.value() == read_handle_.get().value()) { | 292 if (handle.value() == read_handle_.get().value()) { |
293 // The Mojo EDK is shutting down. The ThreadQuitHelper task in | 293 // The Mojo EDK is shutting down. The ThreadQuitHelper task in |
294 // base::Thread won't get run since the control pipe depends on the | 294 // base::Thread won't get run since the control pipe depends on the |
295 // EDK staying alive. So quit manually to avoid this thread hanging. | 295 // EDK staying alive. So quit manually to avoid this thread hanging. |
296 Quit(); | 296 Quit(); |
297 } else { | 297 } else { |
298 RemoveInvalidHandle(handle_results[i], handle); | 298 SignalHandleError(handle, handle_results[i]); |
299 } | 299 } |
300 break; | 300 break; |
301 case MOJO_RESULT_OK: | 301 case MOJO_RESULT_OK: |
302 if (handle.value() == read_handle_.get().value()) { | 302 if (handle.value() == read_handle_.get().value()) { |
303 DVLOG(1) << "Signaled control pipe"; | 303 DVLOG(1) << "Signaled control pipe"; |
304 // Control pipe was written to. | 304 // Control pipe was written to. |
305 ReadMessageRaw(read_handle_.get(), nullptr, nullptr, nullptr, nullptr, | 305 ReadMessageRaw(read_handle_.get(), nullptr, nullptr, nullptr, nullptr, |
306 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); | 306 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); |
307 } else { | 307 } else { |
308 DVLOG(1) << "Handle ready: " << handle.value(); | 308 DVLOG(1) << "Handle ready: " << handle.value(); |
309 SignalHandleReady(handle); | 309 SignalHandleReady(handle); |
310 } | 310 } |
311 break; | 311 break; |
312 default: | 312 default: |
313 base::debug::Alias(&i); | 313 base::debug::Alias(&i); |
314 base::debug::Alias(&handle_results[i]); | 314 base::debug::Alias(&handle_results[i]); |
315 // Unexpected result is likely fatal, crash so we can determine cause. | 315 // Unexpected result is likely fatal, crash so we can determine cause. |
316 CHECK(false); | 316 CHECK(false); |
317 } | 317 } |
318 } | 318 } |
319 return true; | 319 return true; |
320 } | 320 } |
321 | 321 |
322 void MessagePumpMojo::RemoveInvalidHandle(MojoResult result, Handle handle) { | |
323 // TODO(sky): deal with control pipe going bad. | |
324 CHECK(result == MOJO_RESULT_FAILED_PRECONDITION || | |
325 result == MOJO_RESULT_CANCELLED || | |
326 result == MOJO_RESULT_DEADLINE_EXCEEDED); | |
327 // Indicates the control pipe went bad. | |
328 CHECK_NE(handle.value(), read_handle_.get().value()); | |
329 | |
330 auto it = handlers_.find(handle); | |
331 CHECK(it != handlers_.end()); | |
332 MessagePumpMojoHandler* handler = it->second.handler; | |
333 RemoveHandler(handle); | |
334 WillSignalHandler(); | |
335 handler->OnHandleError(handle, result); | |
336 DidSignalHandler(); | |
337 } | |
338 | |
339 bool MessagePumpMojo::RemoveExpiredHandles() { | 322 bool MessagePumpMojo::RemoveExpiredHandles() { |
340 bool removed = false; | 323 bool removed = false; |
341 // Notify and remove any handlers whose time has expired. First, iterate over | 324 // Notify and remove any handlers whose time has expired. First, iterate over |
342 // the set of handles that have a deadline, and add the expired handles to a | 325 // the set of handles that have a deadline, and add the expired handles to a |
343 // map of <Handle, id>. Then, iterate over those expired handles and remove | 326 // map of <Handle, id>. Then, iterate over those expired handles and remove |
344 // them. The two-step process is because a handler can add/remove new | 327 // them. The two-step process is because a handler can add/remove new |
345 // handlers. | 328 // handlers. |
346 std::map<Handle, int> expired_handles; | 329 std::map<Handle, int> expired_handles; |
347 const base::TimeTicks now(internal::NowTicks()); | 330 const base::TimeTicks now(internal::NowTicks()); |
348 for (const Handle handle : deadline_handles_) { | 331 for (const Handle handle : deadline_handles_) { |
349 const auto it = handlers_.find(handle); | 332 const auto it = handlers_.find(handle); |
350 // Expect any handle in |deadline_handles_| to also be in |handlers_| since | 333 // Expect any handle in |deadline_handles_| to also be in |handlers_| since |
351 // the two are modified in lock-step. | 334 // the two are modified in lock-step. |
352 DCHECK(it != handlers_.end()); | 335 DCHECK(it != handlers_.end()); |
353 if (!it->second.deadline.is_null() && it->second.deadline < now) | 336 if (!it->second.deadline.is_null() && it->second.deadline < now) |
354 expired_handles[handle] = it->second.id; | 337 expired_handles[handle] = it->second.id; |
355 } | 338 } |
356 for (const auto& pair : expired_handles) { | 339 for (const auto& pair : expired_handles) { |
357 auto it = handlers_.find(pair.first); | 340 auto it = handlers_.find(pair.first); |
358 // Don't need to check deadline again since it can't change if id hasn't | 341 // Don't need to check deadline again since it can't change if id hasn't |
359 // changed. | 342 // changed. |
360 if (it != handlers_.end() && it->second.id == pair.second) { | 343 if (it != handlers_.end() && it->second.id == pair.second) { |
361 MessagePumpMojoHandler* handler = it->second.handler; | 344 SignalHandleError(pair.first, MOJO_RESULT_DEADLINE_EXCEEDED); |
362 RemoveHandler(pair.first); | |
363 WillSignalHandler(); | |
364 handler->OnHandleError(pair.first, MOJO_RESULT_DEADLINE_EXCEEDED); | |
365 DidSignalHandler(); | |
366 removed = true; | 345 removed = true; |
367 } | 346 } |
368 } | 347 } |
369 return removed; | 348 return removed; |
370 } | 349 } |
371 | 350 |
372 void MessagePumpMojo::SignalControlPipe() { | 351 void MessagePumpMojo::SignalControlPipe() { |
373 const MojoResult result = | 352 const MojoResult result = |
374 WriteMessageRaw(write_handle_.get(), NULL, 0, NULL, 0, | 353 WriteMessageRaw(write_handle_.get(), NULL, 0, NULL, 0, |
375 MOJO_WRITE_MESSAGE_FLAG_NONE); | 354 MOJO_WRITE_MESSAGE_FLAG_NONE); |
(...skipping 15 matching lines...) Expand all Loading... |
391 for (const Handle handle : deadline_handles_) { | 370 for (const Handle handle : deadline_handles_) { |
392 auto it = handlers_.find(handle); | 371 auto it = handlers_.find(handle); |
393 DCHECK(it != handlers_.end()); | 372 DCHECK(it != handlers_.end()); |
394 deadline = std::min( | 373 deadline = std::min( |
395 TimeTicksToMojoDeadline(it->second.deadline, now), deadline); | 374 TimeTicksToMojoDeadline(it->second.deadline, now), deadline); |
396 } | 375 } |
397 return deadline; | 376 return deadline; |
398 } | 377 } |
399 | 378 |
400 void MessagePumpMojo::SignalHandleReady(Handle handle) { | 379 void MessagePumpMojo::SignalHandleReady(Handle handle) { |
401 DCHECK(handlers_.find(handle) != handlers_.end()); | 380 auto it = handlers_.find(handle); |
| 381 DCHECK(it != handlers_.end()); |
| 382 MessagePumpMojoHandler* handler = it->second.handler; |
| 383 |
402 WillSignalHandler(); | 384 WillSignalHandler(); |
403 handlers_[handle].handler->OnHandleReady(handle); | 385 handler->OnHandleReady(handle); |
404 DidSignalHandler(); | 386 DidSignalHandler(); |
405 } | 387 } |
406 | 388 |
| 389 void MessagePumpMojo::SignalHandleError(Handle handle, MojoResult result) { |
| 390 auto it = handlers_.find(handle); |
| 391 DCHECK(it != handlers_.end()); |
| 392 MessagePumpMojoHandler* handler = it->second.handler; |
| 393 |
| 394 RemoveHandler(handle); |
| 395 WillSignalHandler(); |
| 396 handler->OnHandleError(handle, result); |
| 397 DidSignalHandler(); |
| 398 } |
| 399 |
407 void MessagePumpMojo::WillSignalHandler() { | 400 void MessagePumpMojo::WillSignalHandler() { |
408 FOR_EACH_OBSERVER(Observer, observers_, WillSignalHandler()); | 401 FOR_EACH_OBSERVER(Observer, observers_, WillSignalHandler()); |
409 } | 402 } |
410 | 403 |
411 void MessagePumpMojo::DidSignalHandler() { | 404 void MessagePumpMojo::DidSignalHandler() { |
412 FOR_EACH_OBSERVER(Observer, observers_, DidSignalHandler()); | 405 FOR_EACH_OBSERVER(Observer, observers_, DidSignalHandler()); |
413 } | 406 } |
414 | 407 |
415 } // namespace common | 408 } // namespace common |
416 } // namespace mojo | 409 } // namespace mojo |
OLD | NEW |