diff --git a/doc/website/release-notes/iceoryx-unreleased.md b/doc/website/release-notes/iceoryx-unreleased.md index 1ff673c346..54e96133b8 100644 --- a/doc/website/release-notes/iceoryx-unreleased.md +++ b/doc/website/release-notes/iceoryx-unreleased.md @@ -63,6 +63,7 @@ - Avoid UB when accessing `iox::expected` [\#1750](https://github.com/eclipse-iceoryx/iceoryx/issues/1750) - Fix double move in `vector::emplace` [\#1823](https://github.com/eclipse-iceoryx/iceoryx/issues/1823) - Default roudi_config.toml path is not used [\#1826](https://github.com/eclipse-iceoryx/iceoryx/issues/1826) +- `WaitSet::wait` returns if data was send before `WaitSet::attachState(.., State::HAS_{DATA, REQUEST, RESPONSE})` [\#1855](https://github.com/eclipse-iceoryx/iceoryx/issues/1855) **Refactoring:** diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/wait_set.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/wait_set.inl index 6c58efef01..a8035a2782 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/wait_set.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/wait_set.inl @@ -233,6 +233,12 @@ WaitSet::attachState(T& stateOrigin, stateOrigin, TriggerHandle(*m_conditionVariableDataPtr, {*this, &WaitSet::removeTrigger}, uniqueId), stateType); + + auto& trigger = m_triggerArray[uniqueId]; + if (trigger->isStateConditionSatisfied()) + { + ConditionNotifier(*m_conditionVariableDataPtr, uniqueId).notify(); + } }); } @@ -259,6 +265,12 @@ inline expected WaitSet::attachState( .and_then([&](auto& uniqueId) { NotificationAttorney::enableState( stateOrigin, TriggerHandle(*m_conditionVariableDataPtr, {*this, &WaitSet::removeTrigger}, uniqueId)); + + auto& trigger = m_triggerArray[uniqueId]; + if (trigger->isStateConditionSatisfied()) + { + ConditionNotifier(*m_conditionVariableDataPtr, uniqueId).notify(); + } }); } diff --git a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp index 2853c5f60b..6cf856f90f 100644 --- a/iceoryx_posh/test/moduletests/test_popo_waitset.cpp +++ b/iceoryx_posh/test/moduletests/test_popo_waitset.cpp @@ -1761,4 +1761,67 @@ TEST_F(WaitSet_test, TimedWaitUnblocksAfterMarkForDestructionCall) t.join(); } +TEST_F(WaitSet_test, WaitSetReturnsIfStateTriggeredBeforeAttachingWithEventType) +{ + ::testing::Test::RecordProperty("TEST_ID", "407dc160-a50c-45b3-84bc-92a5f186fc14"); + m_simpleEvents[0U].m_autoResetTrigger = false; + m_simpleEvents[0U].trigger(); + + ASSERT_FALSE(m_sut->attachState(m_simpleEvents[0U], SimpleState1::STATE1).has_error()); + + auto triggerVector = m_sut->timedWait(iox::units::Duration::fromSeconds(1337)); + ASSERT_THAT(triggerVector.size(), Eq(1U)); + EXPECT_TRUE(triggerVector[0U]->doesOriginateFrom(&m_simpleEvents[0U])); +} + +TEST_F(WaitSet_test, WaitSetReturnsIfStateTriggeredBeforeAttachingWithEventId) +{ + ::testing::Test::RecordProperty("TEST_ID", "5753de85-7b34-4024-bd50-938c8885d269"); + m_simpleEvents[0U].m_autoResetTrigger = false; + m_simpleEvents[0U].trigger(); + + ASSERT_FALSE(m_sut->attachState(m_simpleEvents[0U], 0U).has_error()); + + auto triggerVector = m_sut->timedWait(iox::units::Duration::fromSeconds(1337)); + ASSERT_THAT(triggerVector.size(), Eq(1U)); + EXPECT_TRUE(triggerVector[0U]->doesOriginateFrom(&m_simpleEvents[0U])); +} + +TEST_F(WaitSet_test, WaitSetReturnsAgainIfStateTriggeredBeforeAttachingWithEventType) +{ + ::testing::Test::RecordProperty("TEST_ID", "c86d2592-e8e5-4acc-b468-0a82be82fe7c"); + m_simpleEvents[0U].m_autoResetTrigger = false; + m_simpleEvents[0U].trigger(); + + ASSERT_FALSE(m_sut->attachState(m_simpleEvents[0U], SimpleState1::STATE1).has_error()); + + auto triggerVector1 = m_sut->timedWait(iox::units::Duration::fromSeconds(1337)); + ASSERT_THAT(triggerVector1.size(), Eq(1U)); + EXPECT_TRUE(triggerVector1[0U]->doesOriginateFrom(&m_simpleEvents[0U])); + + // Waiting for another time should lead to the same result + auto triggerVector2 = m_sut->timedWait(iox::units::Duration::fromSeconds(1337)); + ASSERT_THAT(triggerVector2.size(), Eq(1U)); + EXPECT_TRUE(triggerVector2[0U]->doesOriginateFrom(&m_simpleEvents[0U])); +} + +TEST_F(WaitSet_test, WaitSetReturnsAgainIfStateTriggeredBeforeAttachingWithEventId) +{ + ::testing::Test::RecordProperty("TEST_ID", "b07c9e09-f497-4bfa-9403-633d15363f5e"); + m_simpleEvents[0U].m_autoResetTrigger = false; + m_simpleEvents[0U].trigger(); + + ASSERT_FALSE(m_sut->attachState(m_simpleEvents[0U], 0U).has_error()); + + auto triggerVector1 = m_sut->timedWait(iox::units::Duration::fromSeconds(1337)); + ASSERT_THAT(triggerVector1.size(), Eq(1U)); + EXPECT_TRUE(triggerVector1[0U]->doesOriginateFrom(&m_simpleEvents[0U])); + + // Waiting for another time should lead to the same result + auto triggerVector2 = m_sut->timedWait(iox::units::Duration::fromSeconds(1337)); + ASSERT_THAT(triggerVector2.size(), Eq(1U)); + EXPECT_TRUE(triggerVector2[0U]->doesOriginateFrom(&m_simpleEvents[0U])); +} + + } // namespace