From 744524ae73cb3a6ae3af902228787721c56ec785 Mon Sep 17 00:00:00 2001 From: Chen Lihui Date: Mon, 14 Nov 2022 15:43:50 +0800 Subject: [PATCH 01/14] fix notification lost Signed-off-by: Chen Lihui --- src/cpp/fastdds/core/condition/WaitSetImpl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp index 73390e35de6..ecd74b73568 100644 --- a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp +++ b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp @@ -68,7 +68,7 @@ ReturnCode_t WaitSetImpl::attach_condition( // Should wake_up when adding a new triggered condition if (is_waiting_ && condition.get_trigger_value()) { - wake_up(); + cond_.notify_one(); } } } @@ -156,6 +156,7 @@ ReturnCode_t WaitSetImpl::get_conditions( void WaitSetImpl::wake_up() { + std::lock_guard guard(mutex_); cond_.notify_one(); } From db53f1a12a03a27d17316e0a0c7751ce67d44686 Mon Sep 17 00:00:00 2001 From: Chen Lihui Date: Tue, 15 Nov 2022 16:20:05 +0800 Subject: [PATCH 02/14] add a regression test Signed-off-by: Chen Lihui --- .../dds/core/condition/WaitSetImplTests.cpp | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/test/unittest/dds/core/condition/WaitSetImplTests.cpp b/test/unittest/dds/core/condition/WaitSetImplTests.cpp index 2d13a7a3f8d..937173f3c91 100644 --- a/test/unittest/dds/core/condition/WaitSetImplTests.cpp +++ b/test/unittest/dds/core/condition/WaitSetImplTests.cpp @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include @@ -33,7 +34,7 @@ class TestCondition : public Condition { public: - bool trigger_value = false; + volatile bool trigger_value = false; bool get_trigger_value() const override { @@ -197,6 +198,47 @@ TEST(WaitSetImplTests, wait) } } +TEST(WaitSetImplTests, fix_wait_notification_lost) +{ + ConditionSeq conditions; + WaitSetImpl wait_set; + + // Waiting should return the added connection while the condition triggered + { + TestCondition triggered_condition; + + // Expecting calls on the notifier of triggered_condition + auto notifier = triggered_condition.get_notifier(); + EXPECT_CALL(*notifier, attach_to(_)).Times(1); + EXPECT_CALL(*notifier, will_be_deleted(_)).Times(1); + wait_set.attach_condition(triggered_condition); + + std::promise promise; + std::future future = promise.get_future(); + ReturnCode_t ret = ReturnCode_t::RETCODE_ERROR; + std::thread add_triggered_condition([&]() + { + // not to use `WaitSetImpl::wait` with a timeout value, because the + // `condition_variable::wait_for` could call _Predicate function again + // after timeout in the `WaitSetImpl::wait`. + ret = wait_set.wait(conditions, eprosima::fastrtps::c_TimeInfinite); + promise.set_value(); + }); + + triggered_condition.trigger_value = true; + wait_set.wake_up(); + + // expect to get notification after wake_up, otherwise output error within 5 seconds + future.wait_for(std::chrono::seconds(5)); + ASSERT_EQ(ReturnCode_t::RETCODE_OK, ret); + EXPECT_EQ(1u, conditions.size()); + EXPECT_NE(conditions.cend(), std::find(conditions.cbegin(), conditions.cend(), &triggered_condition)); + add_triggered_condition.join(); + + wait_set.will_be_deleted(triggered_condition); + } +} + int main( int argc, char** argv) From f1ce5e2ff0f398410e6b7a2fb871156d3075b520 Mon Sep 17 00:00:00 2001 From: Chen Lihui Date: Tue, 15 Nov 2022 16:52:12 +0800 Subject: [PATCH 03/14] rename a variable name and update comments Signed-off-by: Chen Lihui --- .../dds/core/condition/WaitSetImplTests.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/test/unittest/dds/core/condition/WaitSetImplTests.cpp b/test/unittest/dds/core/condition/WaitSetImplTests.cpp index 937173f3c91..3fd10eab69c 100644 --- a/test/unittest/dds/core/condition/WaitSetImplTests.cpp +++ b/test/unittest/dds/core/condition/WaitSetImplTests.cpp @@ -203,11 +203,11 @@ TEST(WaitSetImplTests, fix_wait_notification_lost) ConditionSeq conditions; WaitSetImpl wait_set; - // Waiting should return the added connection while the condition triggered + // Waiting should return the added connection after the trigger value is updated and the wait_set waken. { TestCondition triggered_condition; - // Expecting calls on the notifier of triggered_condition + // Expecting calls on the notifier of triggered_condition. auto notifier = triggered_condition.get_notifier(); EXPECT_CALL(*notifier, attach_to(_)).Times(1); EXPECT_CALL(*notifier, will_be_deleted(_)).Times(1); @@ -216,11 +216,10 @@ TEST(WaitSetImplTests, fix_wait_notification_lost) std::promise promise; std::future future = promise.get_future(); ReturnCode_t ret = ReturnCode_t::RETCODE_ERROR; - std::thread add_triggered_condition([&]() + std::thread wait_conditions([&]() { - // not to use `WaitSetImpl::wait` with a timeout value, because the - // `condition_variable::wait_for` could call _Predicate function again - // after timeout in the `WaitSetImpl::wait`. + // Not to use `WaitSetImpl::wait` with a timeout value, because the + // `condition_variable::wait_for` could call _Predicate function again. ret = wait_set.wait(conditions, eprosima::fastrtps::c_TimeInfinite); promise.set_value(); }); @@ -228,12 +227,12 @@ TEST(WaitSetImplTests, fix_wait_notification_lost) triggered_condition.trigger_value = true; wait_set.wake_up(); - // expect to get notification after wake_up, otherwise output error within 5 seconds + // Expecting get notification after wake_up, otherwise output error within 5 seconds. future.wait_for(std::chrono::seconds(5)); ASSERT_EQ(ReturnCode_t::RETCODE_OK, ret); EXPECT_EQ(1u, conditions.size()); EXPECT_NE(conditions.cend(), std::find(conditions.cbegin(), conditions.cend(), &triggered_condition)); - add_triggered_condition.join(); + wait_conditions.join(); wait_set.will_be_deleted(triggered_condition); } From a92143efa3b15ed86e642bd4c6142729ccd0ecc2 Mon Sep 17 00:00:00 2001 From: Chen Lihui Date: Tue, 15 Nov 2022 17:46:54 +0800 Subject: [PATCH 04/14] fix uncrustify issue Signed-off-by: Chen Lihui --- test/unittest/dds/core/condition/WaitSetImplTests.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unittest/dds/core/condition/WaitSetImplTests.cpp b/test/unittest/dds/core/condition/WaitSetImplTests.cpp index 3fd10eab69c..6c713c624b9 100644 --- a/test/unittest/dds/core/condition/WaitSetImplTests.cpp +++ b/test/unittest/dds/core/condition/WaitSetImplTests.cpp @@ -218,10 +218,10 @@ TEST(WaitSetImplTests, fix_wait_notification_lost) ReturnCode_t ret = ReturnCode_t::RETCODE_ERROR; std::thread wait_conditions([&]() { - // Not to use `WaitSetImpl::wait` with a timeout value, because the - // `condition_variable::wait_for` could call _Predicate function again. - ret = wait_set.wait(conditions, eprosima::fastrtps::c_TimeInfinite); - promise.set_value(); + // Not to use `WaitSetImpl::wait` with a timeout value, because the + // `condition_variable::wait_for` could call _Predicate function again. + ret = wait_set.wait(conditions, eprosima::fastrtps::c_TimeInfinite); + promise.set_value(); }); triggered_condition.trigger_value = true; From 3e089ffc7c0d11d11f5521814d4168f5b5526df3 Mon Sep 17 00:00:00 2001 From: Chen Lihui Date: Wed, 16 Nov 2022 10:22:47 +0800 Subject: [PATCH 05/14] make the regression test better Signed-off-by: Chen Lihui --- .../dds/core/condition/WaitSetImplTests.cpp | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/test/unittest/dds/core/condition/WaitSetImplTests.cpp b/test/unittest/dds/core/condition/WaitSetImplTests.cpp index 6c713c624b9..fcf653a1968 100644 --- a/test/unittest/dds/core/condition/WaitSetImplTests.cpp +++ b/test/unittest/dds/core/condition/WaitSetImplTests.cpp @@ -14,6 +14,7 @@ #include #include +#include #include @@ -211,7 +212,27 @@ TEST(WaitSetImplTests, fix_wait_notification_lost) auto notifier = triggered_condition.get_notifier(); EXPECT_CALL(*notifier, attach_to(_)).Times(1); EXPECT_CALL(*notifier, will_be_deleted(_)).Times(1); + + class AnotherTestCondition : public Condition + { + public: + + bool get_trigger_value() const override + { + // Time to simulate thread context switch or something else + std::this_thread::sleep_for(std::chrono::seconds(2)); + return false; + } + + } second_simulator_condition; + + // Expecting calls on the notifier of second_simulator_condition. + notifier = second_simulator_condition.get_notifier(); + EXPECT_CALL(*notifier, attach_to(_)).Times(1); + EXPECT_CALL(*notifier, will_be_deleted(_)).Times(1); + wait_set.attach_condition(triggered_condition); + wait_set.attach_condition(second_simulator_condition); std::promise promise; std::future future = promise.get_future(); @@ -224,17 +245,23 @@ TEST(WaitSetImplTests, fix_wait_notification_lost) promise.set_value(); }); + // One second sleep to make the `wait_set.wait` check `triggered_condition` in the above thread + std::this_thread::sleep_for(std::chrono::seconds(1)); triggered_condition.trigger_value = true; wait_set.wake_up(); // Expecting get notification after wake_up, otherwise output error within 5 seconds. future.wait_for(std::chrono::seconds(5)); - ASSERT_EQ(ReturnCode_t::RETCODE_OK, ret); + EXPECT_EQ(ReturnCode_t::RETCODE_OK, ret); EXPECT_EQ(1u, conditions.size()); EXPECT_NE(conditions.cend(), std::find(conditions.cbegin(), conditions.cend(), &triggered_condition)); + + // Wake up the `wait_set` to make sure the thread exit + wait_set.wake_up(); wait_conditions.join(); wait_set.will_be_deleted(triggered_condition); + wait_set.will_be_deleted(second_simulator_condition); } } From 764823af24e63d7318990f20d9adf07d74289c52 Mon Sep 17 00:00:00 2001 From: Chen Lihui Date: Wed, 16 Nov 2022 13:14:49 +0800 Subject: [PATCH 06/14] fix uncrustify Signed-off-by: Chen Lihui --- test/unittest/dds/core/condition/WaitSetImplTests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/unittest/dds/core/condition/WaitSetImplTests.cpp b/test/unittest/dds/core/condition/WaitSetImplTests.cpp index fcf653a1968..798a6355103 100644 --- a/test/unittest/dds/core/condition/WaitSetImplTests.cpp +++ b/test/unittest/dds/core/condition/WaitSetImplTests.cpp @@ -224,7 +224,8 @@ TEST(WaitSetImplTests, fix_wait_notification_lost) return false; } - } second_simulator_condition; + } + second_simulator_condition; // Expecting calls on the notifier of second_simulator_condition. notifier = second_simulator_condition.get_notifier(); From 8c6036436161319128ef005964e4446f52512ad9 Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Wed, 16 Nov 2022 10:13:44 +0100 Subject: [PATCH 07/14] Refs #16192. Fix deadlock on WaitSetImpl. Signed-off-by: Miguel Company --- src/cpp/fastdds/core/condition/WaitSetImpl.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp index ecd74b73568..d74115a1d58 100644 --- a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp +++ b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp @@ -36,8 +36,16 @@ namespace detail { WaitSetImpl::~WaitSetImpl() { - std::lock_guard guard(mutex_); - for (const Condition* c : entries_) + eprosima::utilities::collections::unordered_vector old_entries; + + { + // We only need to protect access to the collection. + std::lock_guard guard(mutex_); + old_entries = entries_; + entries_.clear(); + } + + for (const Condition* c : old_entries) { c->get_notifier()->detach_from(this); } From 3d03c30bc025d4daa1ca642ee8467401f49b5f68 Mon Sep 17 00:00:00 2001 From: Miguel Barro Date: Sat, 19 Nov 2022 16:40:15 +0100 Subject: [PATCH 08/14] Refs 16192. Workaround for deadlock and notify pessimization Signed-off-by: Miguel Barro --- .../fastdds/core/condition/WaitSetImpl.cpp | 40 ++++++++++--------- .../fastdds/core/condition/WaitSetImpl.hpp | 2 + 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp index d74115a1d58..1e235df9ccd 100644 --- a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp +++ b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp @@ -36,16 +36,8 @@ namespace detail { WaitSetImpl::~WaitSetImpl() { - eprosima::utilities::collections::unordered_vector old_entries; - - { - // We only need to protect access to the collection. - std::lock_guard guard(mutex_); - old_entries = entries_; - entries_.clear(); - } - - for (const Condition* c : old_entries) + std::lock_guard guard(mutex_); + for (const Condition* c : entries_) { c->get_notifier()->detach_from(this); } @@ -76,7 +68,7 @@ ReturnCode_t WaitSetImpl::attach_condition( // Should wake_up when adding a new triggered condition if (is_waiting_ && condition.get_trigger_value()) { - cond_.notify_one(); + wake_up(); } } } @@ -119,16 +111,28 @@ ReturnCode_t WaitSetImpl::wait( auto fill_active_conditions = [&]() { - bool ret_val = false; - active_conditions.clear(); - for (const Condition* c : entries_) + bool ret_val; + unsigned int old_counter; + + // Loop if predicate may be outdated + do { - if (c->get_trigger_value()) + ret_val = false; + old_counter = notifications_; + active_conditions.clear(); + + for (const Condition* c : entries_) { - ret_val = true; - active_conditions.push_back(const_cast(c)); + if (c->get_trigger_value()) + { + ret_val = true; + active_conditions.push_back(const_cast(c)); + } } } + while(old_counter != notifications_ + || active_conditions.size() == entries_.size()); + return ret_val; }; @@ -164,7 +168,7 @@ ReturnCode_t WaitSetImpl::get_conditions( void WaitSetImpl::wake_up() { - std::lock_guard guard(mutex_); + ++notifications_; cond_.notify_one(); } diff --git a/src/cpp/fastdds/core/condition/WaitSetImpl.hpp b/src/cpp/fastdds/core/condition/WaitSetImpl.hpp index d3e5fc187b0..8e275e81c44 100644 --- a/src/cpp/fastdds/core/condition/WaitSetImpl.hpp +++ b/src/cpp/fastdds/core/condition/WaitSetImpl.hpp @@ -19,6 +19,7 @@ #ifndef _FASTDDS_CORE_CONDITION_WAITSETIMPL_HPP_ #define _FASTDDS_CORE_CONDITION_WAITSETIMPL_HPP_ +#include #include #include @@ -113,6 +114,7 @@ struct WaitSetImpl std::condition_variable cond_; eprosima::utilities::collections::unordered_vector entries_; bool is_waiting_ = false; + std::atomic_uint notifications_ = {0}; }; } // namespace detail From 068178628b9b00eb8727128ca15b490ab62f45d0 Mon Sep 17 00:00:00 2001 From: Miguel Barro Date: Sat, 19 Nov 2022 18:37:21 +0100 Subject: [PATCH 09/14] Refs 16192. Mandatory logic fix Signed-off-by: Miguel Barro --- src/cpp/fastdds/core/condition/WaitSetImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp index 1e235df9ccd..37fbc283d50 100644 --- a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp +++ b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp @@ -131,7 +131,7 @@ ReturnCode_t WaitSetImpl::wait( } } while(old_counter != notifications_ - || active_conditions.size() == entries_.size()); + && active_conditions.size() != entries_.size()); return ret_val; }; From 34a8f8d57f8e24135c35eeb9965b03f2010c3022 Mon Sep 17 00:00:00 2001 From: Miguel Barro Date: Sat, 19 Nov 2022 18:41:38 +0100 Subject: [PATCH 10/14] Refs 16192. linter Signed-off-by: Miguel Barro --- src/cpp/fastdds/core/condition/WaitSetImpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp index 37fbc283d50..d4f0e76d9b7 100644 --- a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp +++ b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp @@ -130,8 +130,8 @@ ReturnCode_t WaitSetImpl::wait( } } } - while(old_counter != notifications_ - && active_conditions.size() != entries_.size()); + while (old_counter != notifications_ + && active_conditions.size() != entries_.size()); return ret_val; }; From eb389f645eac1c26aececac6f023145ca875b9b0 Mon Sep 17 00:00:00 2001 From: Miguel Barro Date: Mon, 21 Nov 2022 11:46:32 +0100 Subject: [PATCH 11/14] Refs #16192. Catch up any notification lost Signed-off-by: Miguel Barro --- .../fastdds/core/condition/WaitSetImpl.cpp | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp index d4f0e76d9b7..7b3d97d7ce7 100644 --- a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp +++ b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp @@ -103,6 +103,8 @@ ReturnCode_t WaitSetImpl::wait( const fastrtps::Duration_t& timeout) { std::unique_lock lock(mutex_); + // last notification processed + unsigned int old_counter; if (is_waiting_) { @@ -112,7 +114,6 @@ ReturnCode_t WaitSetImpl::wait( auto fill_active_conditions = [&]() { bool ret_val; - unsigned int old_counter; // Loop if predicate may be outdated do @@ -138,16 +139,22 @@ ReturnCode_t WaitSetImpl::wait( bool condition_value = false; is_waiting_ = true; - if (fastrtps::c_TimeInfinite == timeout) - { - cond_.wait(lock, fill_active_conditions); - condition_value = true; - } - else + auto missing_notification_outage = std::chrono::milliseconds(500); + auto now = std::chrono::steady_clock::now(); + auto deadline = fastrtps::c_TimeInfinite == timeout ? + std::chrono::steady_clock::time_point::max() : + now + std::chrono::nanoseconds(timeout.to_ns()); + + do { - auto ns = timeout.to_ns(); - condition_value = cond_.wait_for(lock, std::chrono::nanoseconds(ns), fill_active_conditions); + now = std::chrono::steady_clock::now(); + auto next_outage_timeout = now + missing_notification_outage; + auto ctimeout = std::min(next_outage_timeout, deadline); + + condition_value = cond_.wait_until(lock, ctimeout, fill_active_conditions); } + while (!condition_value && ( old_counter != notifications_ || deadline > now)); + is_waiting_ = false; return condition_value ? ReturnCode_t::RETCODE_OK : ReturnCode_t::RETCODE_TIMEOUT; From 90d02d3d303e9ca79f9c997ebddd2b7e40334920 Mon Sep 17 00:00:00 2001 From: Miguel Barro Date: Mon, 21 Nov 2022 12:05:28 +0100 Subject: [PATCH 12/14] Refs 16192. Avoid predicate evaluation on spurious wakeups. Signed-off-by: Miguel Barro --- src/cpp/fastdds/core/condition/WaitSetImpl.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp index 7b3d97d7ce7..a951c4ea259 100644 --- a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp +++ b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp @@ -115,6 +115,12 @@ ReturnCode_t WaitSetImpl::wait( { bool ret_val; + if ( old_counter == notifications_ ) + { + // spurious wakeup + return false; + } + // Loop if predicate may be outdated do { From b95d811228be676584ecc2b0d6035b77d7827056 Mon Sep 17 00:00:00 2001 From: Miguel Barro Date: Mon, 21 Nov 2022 14:06:10 +0100 Subject: [PATCH 13/14] Refs 16192. Fixing gcc warnings Signed-off-by: Miguel Barro --- src/cpp/fastdds/core/condition/WaitSetImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp index a951c4ea259..2e4cd83e07e 100644 --- a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp +++ b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp @@ -104,7 +104,7 @@ ReturnCode_t WaitSetImpl::wait( { std::unique_lock lock(mutex_); // last notification processed - unsigned int old_counter; + unsigned int old_counter = 0; if (is_waiting_) { From aa260da77dd827dc13841dc9573cc5448cfe14b9 Mon Sep 17 00:00:00 2001 From: Miguel Barro Date: Mon, 21 Nov 2022 17:11:01 +0100 Subject: [PATCH 14/14] Refs 16192. Allowing wait without previous notification Signed-off-by: Miguel Barro --- src/cpp/fastdds/core/condition/WaitSetImpl.cpp | 2 +- src/cpp/fastdds/core/condition/WaitSetImpl.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp index 2e4cd83e07e..013bd383c95 100644 --- a/src/cpp/fastdds/core/condition/WaitSetImpl.cpp +++ b/src/cpp/fastdds/core/condition/WaitSetImpl.cpp @@ -104,7 +104,7 @@ ReturnCode_t WaitSetImpl::wait( { std::unique_lock lock(mutex_); // last notification processed - unsigned int old_counter = 0; + unsigned int old_counter = notifications_ - 1; if (is_waiting_) { diff --git a/src/cpp/fastdds/core/condition/WaitSetImpl.hpp b/src/cpp/fastdds/core/condition/WaitSetImpl.hpp index 8e275e81c44..96c5da5dc11 100644 --- a/src/cpp/fastdds/core/condition/WaitSetImpl.hpp +++ b/src/cpp/fastdds/core/condition/WaitSetImpl.hpp @@ -114,7 +114,7 @@ struct WaitSetImpl std::condition_variable cond_; eprosima::utilities::collections::unordered_vector entries_; bool is_waiting_ = false; - std::atomic_uint notifications_ = {0}; + std::atomic_uint notifications_ = {1}; }; } // namespace detail