| 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 // NOTE(vtl): Some of these tests are inherently flaky (e.g., if run on a | 5 // NOTE(vtl): Some of these tests are inherently flaky (e.g., if run on a |
| 6 // heavily-loaded system). Sorry. |test::EpsilonTimeout()| may be increased to | 6 // heavily-loaded system). Sorry. |test::EpsilonTimeout()| may be increased to |
| 7 // increase tolerance and reduce observed flakiness (though doing so reduces the | 7 // increase tolerance and reduce observed flakiness (though doing so reduces the |
| 8 // meaningfulness of the test). | 8 // meaningfulness of the test). |
| 9 | 9 |
| 10 #include "mojo/edk/system/awakable_list.h" | 10 #include "mojo/edk/system/awakable_list.h" |
| 11 | 11 |
| 12 #include "mojo/edk/platform/thread_utils.h" | 12 #include "mojo/edk/platform/thread_utils.h" |
| 13 #include "mojo/edk/system/handle_signals_state.h" | 13 #include "mojo/edk/system/handle_signals_state.h" |
| 14 #include "mojo/edk/system/test/timeouts.h" | 14 #include "mojo/edk/system/test/timeouts.h" |
| 15 #include "mojo/edk/system/waiter.h" | 15 #include "mojo/edk/system/waiter.h" |
| 16 #include "mojo/edk/system/waiter_test_utils.h" | 16 #include "mojo/edk/system/waiter_test_utils.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 18 |
| 19 using mojo::platform::ThreadSleep; | 19 using mojo::platform::ThreadSleep; |
| 20 | 20 |
| 21 namespace mojo { | 21 namespace mojo { |
| 22 namespace system { | 22 namespace system { |
| 23 namespace { | 23 namespace { |
| 24 | 24 |
| 25 TEST(AwakableListTest, BasicCancel) { | 25 TEST(AwakableListTest, BasicCancelAndRemoveAll) { |
| 26 MojoResult result; | 26 MojoResult result; |
| 27 uint64_t context; | 27 uint64_t context; |
| 28 | 28 |
| 29 // Cancel immediately after thread start. | 29 // Cancel immediately after thread start. |
| 30 { | 30 { |
| 31 AwakableList awakable_list; | 31 AwakableList awakable_list; |
| 32 test::SimpleWaiterThread thread(&result, &context); | 32 test::SimpleWaiterThread thread(&result, &context); |
| 33 awakable_list.Add(thread.waiter(), 1, false, MOJO_HANDLE_SIGNAL_READABLE); | 33 awakable_list.Add(thread.waiter(), 1, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 34 thread.Start(); | 34 thread.Start(); |
| 35 awakable_list.CancelAndRemoveAll(); | 35 awakable_list.CancelAndRemoveAll(); |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 EXPECT_EQ(MOJO_RESULT_OK, result1); | 322 EXPECT_EQ(MOJO_RESULT_OK, result1); |
| 323 EXPECT_EQ(7u, context1); | 323 EXPECT_EQ(7u, context1); |
| 324 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); | 324 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result2); |
| 325 EXPECT_EQ(8u, context2); | 325 EXPECT_EQ(8u, context2); |
| 326 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result3); | 326 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result3); |
| 327 EXPECT_EQ(9u, context3); | 327 EXPECT_EQ(9u, context3); |
| 328 EXPECT_EQ(MOJO_RESULT_CANCELLED, result4); | 328 EXPECT_EQ(MOJO_RESULT_CANCELLED, result4); |
| 329 EXPECT_EQ(10u, context4); | 329 EXPECT_EQ(10u, context4); |
| 330 } | 330 } |
| 331 | 331 |
| 332 TEST(AwakableListTest, RemoveMatchContext) { | 332 TEST(AwakableListTest, RemoveMatchContext1) { |
| 333 MojoResult result; | 333 MojoResult result; |
| 334 uint64_t context; | 334 uint64_t context; |
| 335 | 335 |
| 336 { | 336 { |
| 337 AwakableList awakable_list; | 337 AwakableList awakable_list; |
| 338 test::SimpleWaiterThread thread(&result, &context); | 338 test::SimpleWaiterThread thread(&result, &context); |
| 339 awakable_list.Add(thread.waiter(), 1, false, MOJO_HANDLE_SIGNAL_READABLE); | 339 awakable_list.Add(thread.waiter(), 1, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 340 awakable_list.Add(thread.waiter(), 2, false, MOJO_HANDLE_SIGNAL_READABLE); | 340 awakable_list.Add(thread.waiter(), 2, false, MOJO_HANDLE_SIGNAL_READABLE); |
| 341 thread.Start(); | 341 thread.Start(); |
| 342 awakable_list.Remove(true, thread.waiter(), 2); | 342 awakable_list.Remove(true, thread.waiter(), 2); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 372 awakable_list.Remove(true, thread.waiter(), 2); | 372 awakable_list.Remove(true, thread.waiter(), 2); |
| 373 } // Join |thread|. | 373 } // Join |thread|. |
| 374 EXPECT_EQ(MOJO_RESULT_OK, result); | 374 EXPECT_EQ(MOJO_RESULT_OK, result); |
| 375 EXPECT_EQ(2u, context); | 375 EXPECT_EQ(2u, context); |
| 376 } | 376 } |
| 377 | 377 |
| 378 class TestAwakable : public Awakable { | 378 class TestAwakable : public Awakable { |
| 379 public: | 379 public: |
| 380 TestAwakable() {} | 380 TestAwakable() {} |
| 381 | 381 |
| 382 void Awake(uint64_t /*context*/, | 382 void Awake(uint64_t context, |
| 383 AwakeReason /*reason*/, | 383 AwakeReason reason, |
| 384 const HandleSignalsState& /*signals_state*/) override { | 384 const HandleSignalsState& signals_state) override { |
| 385 awake_count++; | 385 awake_count++; |
| 386 last_context = context; |
| 387 last_reason = reason; |
| 388 last_state = signals_state; |
| 386 } | 389 } |
| 387 | 390 |
| 388 unsigned awake_count = 0; | 391 unsigned awake_count = 0; |
| 392 uint64_t last_context = static_cast<uint64_t>(-1); |
| 393 AwakeReason last_reason = AwakeReason::CANCELLED; |
| 394 HandleSignalsState last_state; |
| 389 | 395 |
| 390 MOJO_DISALLOW_COPY_AND_ASSIGN(TestAwakable); | 396 MOJO_DISALLOW_COPY_AND_ASSIGN(TestAwakable); |
| 391 }; | 397 }; |
| 392 | 398 |
| 393 TEST(AwakableListTest, PersistentVsNonPersistent) { | 399 TEST(AwakableListTest, PersistentVsOneShot1) { |
| 400 AwakableList awakable_list; |
| 394 TestAwakable persistent0; | 401 TestAwakable persistent0; |
| 395 TestAwakable persistent1; | 402 TestAwakable persistent1; |
| 396 TestAwakable oneshot0; | 403 TestAwakable oneshot0; |
| 397 TestAwakable oneshot1; | 404 TestAwakable oneshot1; |
| 398 TestAwakable oneshot2; | 405 |
| 399 | 406 awakable_list.Add(&persistent0, 100, true, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 400 AwakableList remove_all; | 407 awakable_list.Add(&persistent1, 101, true, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 401 remove_all.Add(&oneshot0, 0, false, MOJO_HANDLE_SIGNAL_WRITABLE); | 408 awakable_list.Add(&oneshot0, 200, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 402 remove_all.Add(&oneshot1, 0, false, MOJO_HANDLE_SIGNAL_WRITABLE); | 409 awakable_list.Add(&oneshot1, 201, false, MOJO_HANDLE_SIGNAL_WRITABLE); |
| 403 | 410 EXPECT_EQ(persistent0.awake_count, 0u); |
| 404 remove_all.OnStateChange( | 411 EXPECT_EQ(persistent1.awake_count, 0u); |
| 405 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), | 412 EXPECT_EQ(oneshot0.awake_count, 0u); |
| 406 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, | 413 EXPECT_EQ(oneshot1.awake_count, 0u); |
| 407 MOJO_HANDLE_SIGNAL_WRITABLE)); | 414 |
| 408 EXPECT_EQ(oneshot0.awake_count, 1u); | 415 awakable_list.OnStateChange( |
| 409 EXPECT_EQ(oneshot1.awake_count, 1u); | |
| 410 | |
| 411 remove_all.OnStateChange( | |
| 412 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), | |
| 413 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, | |
| 414 MOJO_HANDLE_SIGNAL_WRITABLE)); | |
| 415 EXPECT_EQ(oneshot0.awake_count, 1u); | |
| 416 EXPECT_EQ(oneshot1.awake_count, 1u); | |
| 417 | |
| 418 AwakableList remove_first; | |
| 419 remove_first.Add(&oneshot2, 0, false, MOJO_HANDLE_SIGNAL_WRITABLE); | |
| 420 remove_first.Add(&persistent0, 0, true, MOJO_HANDLE_SIGNAL_WRITABLE); | |
| 421 remove_first.Add(&persistent1, 0, true, MOJO_HANDLE_SIGNAL_WRITABLE); | |
| 422 | |
| 423 remove_first.OnStateChange( | |
| 424 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), | 416 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), |
| 425 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, | 417 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, |
| 426 MOJO_HANDLE_SIGNAL_WRITABLE)); | 418 MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 427 EXPECT_EQ(persistent0.awake_count, 1u); | 419 EXPECT_EQ(persistent0.awake_count, 1u); |
| 428 EXPECT_EQ(persistent1.awake_count, 1u); | 420 EXPECT_EQ(persistent0.last_context, 100u); |
| 429 EXPECT_EQ(oneshot2.awake_count, 1u); | 421 EXPECT_EQ(persistent0.last_reason, Awakable::AwakeReason::CHANGED); |
| 430 | 422 EXPECT_TRUE(persistent0.last_state.equals(HandleSignalsState( |
| 431 remove_first.OnStateChange( | 423 MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_HANDLE_SIGNAL_WRITABLE))); |
| 424 EXPECT_EQ(persistent1.awake_count, 1u); |
| 425 EXPECT_EQ(persistent1.last_context, 101u); |
| 426 EXPECT_EQ(persistent1.last_reason, Awakable::AwakeReason::CHANGED); |
| 427 EXPECT_TRUE(persistent1.last_state.equals(HandleSignalsState( |
| 428 MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_HANDLE_SIGNAL_WRITABLE))); |
| 429 EXPECT_EQ(oneshot0.awake_count, 1u); |
| 430 EXPECT_EQ(oneshot0.last_context, 200u); |
| 431 EXPECT_EQ(oneshot0.last_reason, Awakable::AwakeReason::SATISFIED); |
| 432 EXPECT_TRUE(oneshot0.last_state.equals(HandleSignalsState( |
| 433 MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_HANDLE_SIGNAL_WRITABLE))); |
| 434 EXPECT_EQ(oneshot1.awake_count, 1u); |
| 435 EXPECT_EQ(oneshot1.last_context, 201u); |
| 436 EXPECT_EQ(oneshot1.last_reason, Awakable::AwakeReason::SATISFIED); |
| 437 EXPECT_TRUE(oneshot1.last_state.equals(HandleSignalsState( |
| 438 MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_HANDLE_SIGNAL_WRITABLE))); |
| 439 |
| 440 awakable_list.OnStateChange( |
| 441 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, |
| 442 MOJO_HANDLE_SIGNAL_WRITABLE), |
| 443 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 444 EXPECT_EQ(persistent0.awake_count, 2u); |
| 445 EXPECT_EQ(persistent0.last_context, 100u); |
| 446 EXPECT_EQ(persistent0.last_reason, Awakable::AwakeReason::CHANGED); |
| 447 EXPECT_TRUE(persistent0.last_state.equals(HandleSignalsState( |
| 448 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE))); |
| 449 EXPECT_EQ(persistent1.awake_count, 2u); |
| 450 EXPECT_EQ(persistent1.last_context, 101u); |
| 451 EXPECT_EQ(persistent1.last_reason, Awakable::AwakeReason::CHANGED); |
| 452 EXPECT_TRUE(persistent1.last_state.equals(HandleSignalsState( |
| 453 MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE))); |
| 454 EXPECT_EQ(oneshot0.awake_count, 1u); |
| 455 EXPECT_EQ(oneshot1.awake_count, 1u); |
| 456 |
| 457 awakable_list.OnStateChange( |
| 432 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), | 458 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE), |
| 433 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, | 459 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, |
| 434 MOJO_HANDLE_SIGNAL_WRITABLE)); | 460 MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 435 EXPECT_EQ(persistent0.awake_count, 2u); | 461 EXPECT_EQ(persistent0.awake_count, 3u); |
| 436 EXPECT_EQ(persistent1.awake_count, 2u); | 462 EXPECT_EQ(persistent0.last_context, 100u); |
| 437 EXPECT_EQ(oneshot2.awake_count, 1u); | 463 EXPECT_EQ(persistent0.last_reason, Awakable::AwakeReason::CHANGED); |
| 438 | 464 EXPECT_TRUE(persistent0.last_state.equals(HandleSignalsState( |
| 439 remove_first.Remove(false, &persistent0, 0); | 465 MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_HANDLE_SIGNAL_WRITABLE))); |
| 440 remove_first.Remove(false, &persistent1, 0); | 466 EXPECT_EQ(persistent1.awake_count, 3u); |
| 467 EXPECT_EQ(persistent1.last_context, 101u); |
| 468 EXPECT_EQ(persistent1.last_reason, Awakable::AwakeReason::CHANGED); |
| 469 EXPECT_TRUE(persistent1.last_state.equals(HandleSignalsState( |
| 470 MOJO_HANDLE_SIGNAL_WRITABLE, MOJO_HANDLE_SIGNAL_WRITABLE))); |
| 471 EXPECT_EQ(oneshot0.awake_count, 1u); |
| 472 EXPECT_EQ(oneshot1.awake_count, 1u); |
| 473 |
| 474 awakable_list.Remove(false, &persistent0, 0); |
| 475 awakable_list.Remove(false, &persistent1, 0); |
| 476 EXPECT_EQ(persistent0.awake_count, 3u); |
| 477 EXPECT_EQ(persistent1.awake_count, 3u); |
| 478 EXPECT_EQ(oneshot0.awake_count, 1u); |
| 479 EXPECT_EQ(oneshot1.awake_count, 1u); |
| 480 |
| 481 awakable_list.OnStateChange( |
| 482 HandleSignalsState(MOJO_HANDLE_SIGNAL_WRITABLE, |
| 483 MOJO_HANDLE_SIGNAL_WRITABLE), |
| 484 HandleSignalsState(MOJO_HANDLE_SIGNAL_NONE, MOJO_HANDLE_SIGNAL_WRITABLE)); |
| 485 EXPECT_EQ(persistent0.awake_count, 3u); |
| 486 EXPECT_EQ(persistent1.awake_count, 3u); |
| 487 EXPECT_EQ(oneshot0.awake_count, 1u); |
| 488 EXPECT_EQ(oneshot1.awake_count, 1u); |
| 441 } | 489 } |
| 442 | 490 |
| 491 // Checks carefully that persistent awakables see all changes whereas one-shot |
| 492 // awakables see only "leading edges". |
| 493 TEST(AwakableListTest, PersistentVsOneShot2) { |
| 494 static constexpr MojoHandleSignals kNone = MOJO_HANDLE_SIGNAL_NONE; |
| 495 static constexpr MojoHandleSignals kR = MOJO_HANDLE_SIGNAL_READABLE; |
| 496 static constexpr MojoHandleSignals kW = MOJO_HANDLE_SIGNAL_WRITABLE; |
| 497 static constexpr MojoHandleSignals kPC = MOJO_HANDLE_SIGNAL_PEER_CLOSED; |
| 498 |
| 499 AwakableList awakable_list; |
| 500 TestAwakable persistent; |
| 501 TestAwakable oneshot; |
| 502 |
| 503 // Starting state: Satisfied: None. Satisfiable: R | W | PC. |
| 504 HandleSignalsState old_state(kNone, kR | kW | kPC); |
| 505 HandleSignalsState new_state = old_state; |
| 506 |
| 507 // Watch R and PC; we'll do the same for |oneshot|, but add/remove each time. |
| 508 awakable_list.Add(&persistent, 123, true, kR | kPC); |
| 509 EXPECT_EQ(persistent.awake_count, 0u); |
| 510 |
| 511 // Satisfied: +R. |
| 512 awakable_list.Add(&oneshot, 456, false, kR | kPC); |
| 513 new_state.satisfied_signals |= kR; |
| 514 awakable_list.OnStateChange(old_state, new_state); |
| 515 old_state = new_state; |
| 516 EXPECT_EQ(persistent.awake_count, 1u); |
| 517 EXPECT_EQ(oneshot.awake_count, 1u); |
| 518 EXPECT_EQ(oneshot.last_reason, Awakable::AwakeReason::SATISFIED); |
| 519 awakable_list.Remove(true, &oneshot, 456); |
| 520 |
| 521 // Satisfied: -R. |
| 522 oneshot.awake_count = 0; |
| 523 awakable_list.Add(&oneshot, 456, false, kR | kPC); |
| 524 new_state.satisfied_signals &= ~kR; |
| 525 awakable_list.OnStateChange(old_state, new_state); |
| 526 old_state = new_state; |
| 527 EXPECT_EQ(persistent.awake_count, 2u); |
| 528 EXPECT_EQ(oneshot.awake_count, 0u); |
| 529 awakable_list.Remove(true, &oneshot, 456); |
| 530 |
| 531 // Satisfied: +W. |
| 532 oneshot.awake_count = 0; |
| 533 awakable_list.Add(&oneshot, 456, false, kR | kPC); |
| 534 new_state.satisfied_signals |= kW; |
| 535 awakable_list.OnStateChange(old_state, new_state); |
| 536 old_state = new_state; |
| 537 EXPECT_EQ(persistent.awake_count, 2u); |
| 538 EXPECT_EQ(oneshot.awake_count, 0u); |
| 539 awakable_list.Remove(true, &oneshot, 456); |
| 540 |
| 541 // Satisfied: +PC -W. |
| 542 oneshot.awake_count = 0; |
| 543 awakable_list.Add(&oneshot, 456, false, kR | kPC); |
| 544 new_state.satisfied_signals |= kPC; |
| 545 new_state.satisfied_signals &= ~kW; |
| 546 awakable_list.OnStateChange(old_state, new_state); |
| 547 old_state = new_state; |
| 548 EXPECT_EQ(persistent.awake_count, 3u); |
| 549 EXPECT_EQ(oneshot.awake_count, 1u); |
| 550 EXPECT_EQ(oneshot.last_reason, Awakable::AwakeReason::SATISFIED); |
| 551 awakable_list.Remove(true, &oneshot, 456); |
| 552 |
| 553 // Satisfied: +R -PC. |
| 554 oneshot.awake_count = 0; |
| 555 awakable_list.Add(&oneshot, 456, false, kR | kPC); |
| 556 new_state.satisfied_signals |= kR; |
| 557 new_state.satisfied_signals &= ~kPC; |
| 558 awakable_list.OnStateChange(old_state, new_state); |
| 559 old_state = new_state; |
| 560 EXPECT_EQ(persistent.awake_count, 4u); |
| 561 // It was previously satisfied and remains satisfied (for different reasons), |
| 562 // so the one-shot does not observe this change. |
| 563 EXPECT_EQ(oneshot.awake_count, 0u); |
| 564 awakable_list.Remove(true, &oneshot, 456); |
| 565 |
| 566 // Satisfiable: -PC. |
| 567 oneshot.awake_count = 0; |
| 568 awakable_list.Add(&oneshot, 456, false, kR | kPC); |
| 569 new_state.satisfiable_signals &= ~kPC; |
| 570 awakable_list.OnStateChange(old_state, new_state); |
| 571 old_state = new_state; |
| 572 EXPECT_EQ(persistent.awake_count, 5u); |
| 573 EXPECT_EQ(oneshot.awake_count, 0u); |
| 574 awakable_list.Remove(true, &oneshot, 456); |
| 575 |
| 576 // Satisfiable: -W. |
| 577 oneshot.awake_count = 0; |
| 578 awakable_list.Add(&oneshot, 456, false, kR | kPC); |
| 579 new_state.satisfiable_signals &= ~kW; |
| 580 awakable_list.OnStateChange(old_state, new_state); |
| 581 old_state = new_state; |
| 582 EXPECT_EQ(persistent.awake_count, 5u); |
| 583 EXPECT_EQ(oneshot.awake_count, 0u); |
| 584 awakable_list.Remove(true, &oneshot, 456); |
| 585 |
| 586 // Satisfied: -R. Satisfiable: -R. |
| 587 oneshot.awake_count = 0; |
| 588 awakable_list.Add(&oneshot, 456, false, kR | kPC); |
| 589 new_state.satisfied_signals &= ~kR; |
| 590 new_state.satisfiable_signals &= ~kR; |
| 591 awakable_list.OnStateChange(old_state, new_state); |
| 592 old_state = new_state; |
| 593 EXPECT_EQ(persistent.awake_count, 6u); |
| 594 // "Leading edge" for one-shot is "rising" for (overall) satisfied-ness and |
| 595 // "falling" for (overall) satisfiability, so it's really picking up the -R in |
| 596 // satisfiability here. |
| 597 EXPECT_EQ(oneshot.awake_count, 1u); |
| 598 EXPECT_EQ(oneshot.last_reason, Awakable::AwakeReason::UNSATISFIABLE); |
| 599 awakable_list.Remove(true, &oneshot, 456); |
| 600 |
| 601 // Satisfiable: +R: |
| 602 oneshot.awake_count = 0; |
| 603 awakable_list.Add(&oneshot, 456, false, kR | kPC); |
| 604 new_state.satisfiable_signals |= kR; |
| 605 awakable_list.OnStateChange(old_state, new_state); |
| 606 old_state = new_state; |
| 607 EXPECT_EQ(persistent.awake_count, 7u); |
| 608 // And the one-shot doesn't pick up the +R in satisfiability here. |
| 609 EXPECT_EQ(oneshot.awake_count, 0u); |
| 610 awakable_list.Remove(true, &oneshot, 456); |
| 611 |
| 612 awakable_list.Remove(true, &persistent, 123); |
| 613 EXPECT_EQ(persistent.awake_count, 7u); |
| 614 } |
| 615 |
| 616 TEST(AwakableListTest, RemoveNoMatchContext) { |
| 617 static constexpr MojoHandleSignals kNone = MOJO_HANDLE_SIGNAL_NONE; |
| 618 static constexpr MojoHandleSignals kR = MOJO_HANDLE_SIGNAL_READABLE; |
| 619 |
| 620 AwakableList awakable_list; |
| 621 TestAwakable persistent0; |
| 622 TestAwakable persistent1; |
| 623 |
| 624 // Add |persistent0| twice, with different contexts. |
| 625 awakable_list.Add(&persistent0, 12, true, kR); |
| 626 awakable_list.Add(&persistent0, 34, true, kR); |
| 627 awakable_list.Add(&persistent1, 56, true, kR); |
| 628 EXPECT_EQ(persistent0.awake_count, 0u); |
| 629 EXPECT_EQ(persistent1.awake_count, 0u); |
| 630 |
| 631 awakable_list.OnStateChange(HandleSignalsState(kNone, kR), |
| 632 HandleSignalsState(kR, kR)); |
| 633 EXPECT_EQ(persistent0.awake_count, 2u); |
| 634 EXPECT_EQ(persistent1.awake_count, 1u); |
| 635 |
| 636 awakable_list.OnStateChange(HandleSignalsState(kNone, kR), |
| 637 HandleSignalsState(kNone, kR)); |
| 638 EXPECT_EQ(persistent0.awake_count, 2u); |
| 639 EXPECT_EQ(persistent1.awake_count, 1u); |
| 640 |
| 641 awakable_list.Remove(false, &persistent0, 0); |
| 642 EXPECT_EQ(persistent0.awake_count, 2u); |
| 643 EXPECT_EQ(persistent1.awake_count, 1u); |
| 644 |
| 645 awakable_list.OnStateChange(HandleSignalsState(kNone, kR), |
| 646 HandleSignalsState(kR, kR)); |
| 647 EXPECT_EQ(persistent0.awake_count, 2u); |
| 648 EXPECT_EQ(persistent1.awake_count, 2u); |
| 649 |
| 650 awakable_list.Remove(false, &persistent1, 0); |
| 651 EXPECT_EQ(persistent0.awake_count, 2u); |
| 652 EXPECT_EQ(persistent1.awake_count, 2u); |
| 653 } |
| 654 |
| 655 TEST(AwakableListTest, RemoveMatchContext2) { |
| 656 static constexpr MojoHandleSignals kNone = MOJO_HANDLE_SIGNAL_NONE; |
| 657 static constexpr MojoHandleSignals kR = MOJO_HANDLE_SIGNAL_READABLE; |
| 658 |
| 659 AwakableList awakable_list; |
| 660 TestAwakable persistent0; |
| 661 TestAwakable persistent1; |
| 662 |
| 663 // Add |persistent0| twice, with different contexts. |
| 664 awakable_list.Add(&persistent0, 12, true, kR); |
| 665 awakable_list.Add(&persistent0, 34, true, kR); |
| 666 awakable_list.Add(&persistent1, 56, true, kR); |
| 667 EXPECT_EQ(persistent0.awake_count, 0u); |
| 668 EXPECT_EQ(persistent1.awake_count, 0u); |
| 669 |
| 670 awakable_list.OnStateChange(HandleSignalsState(kNone, kR), |
| 671 HandleSignalsState(kR, kR)); |
| 672 EXPECT_EQ(persistent0.awake_count, 2u); |
| 673 EXPECT_EQ(persistent1.awake_count, 1u); |
| 674 |
| 675 awakable_list.OnStateChange(HandleSignalsState(kNone, kR), |
| 676 HandleSignalsState(kNone, kR)); |
| 677 EXPECT_EQ(persistent0.awake_count, 2u); |
| 678 EXPECT_EQ(persistent1.awake_count, 1u); |
| 679 |
| 680 awakable_list.Remove(true, &persistent0, 34); |
| 681 EXPECT_EQ(persistent0.awake_count, 2u); |
| 682 EXPECT_EQ(persistent1.awake_count, 1u); |
| 683 |
| 684 awakable_list.OnStateChange(HandleSignalsState(kNone, kR), |
| 685 HandleSignalsState(kR, kR)); |
| 686 EXPECT_EQ(persistent0.awake_count, 3u); |
| 687 EXPECT_EQ(persistent0.last_context, 12u); |
| 688 EXPECT_EQ(persistent1.awake_count, 2u); |
| 689 |
| 690 // No-op: non-existent context. |
| 691 awakable_list.Remove(true, &persistent1, 0); |
| 692 EXPECT_EQ(persistent0.awake_count, 3u); |
| 693 EXPECT_EQ(persistent1.awake_count, 2u); |
| 694 |
| 695 awakable_list.OnStateChange(HandleSignalsState(kNone, kR), |
| 696 HandleSignalsState(kNone, kR)); |
| 697 EXPECT_EQ(persistent0.awake_count, 3u); |
| 698 EXPECT_EQ(persistent1.awake_count, 2u); |
| 699 |
| 700 awakable_list.OnStateChange(HandleSignalsState(kNone, kR), |
| 701 HandleSignalsState(kR, kR)); |
| 702 EXPECT_EQ(persistent0.awake_count, 4u); |
| 703 EXPECT_EQ(persistent0.last_context, 12u); |
| 704 EXPECT_EQ(persistent1.awake_count, 3u); |
| 705 |
| 706 awakable_list.Remove(true, &persistent0, 12); |
| 707 awakable_list.Remove(true, &persistent1, 56); |
| 708 |
| 709 awakable_list.OnStateChange(HandleSignalsState(kNone, kR), |
| 710 HandleSignalsState(kNone, kR)); |
| 711 EXPECT_EQ(persistent0.awake_count, 4u); |
| 712 EXPECT_EQ(persistent1.awake_count, 3u); |
| 713 |
| 714 awakable_list.OnStateChange(HandleSignalsState(kNone, kR), |
| 715 HandleSignalsState(kR, kR)); |
| 716 EXPECT_EQ(persistent0.awake_count, 4u); |
| 717 EXPECT_EQ(persistent1.awake_count, 3u); |
| 718 } |
| 719 |
| 443 } // namespace | 720 } // namespace |
| 444 } // namespace system | 721 } // namespace system |
| 445 } // namespace mojo | 722 } // namespace mojo |
| OLD | NEW |