diff --git a/src/cpp/rtps/writer/StatefulWriter.cpp b/src/cpp/rtps/writer/StatefulWriter.cpp index ee679ba8796..60127cb9174 100644 --- a/src/cpp/rtps/writer/StatefulWriter.cpp +++ b/src/cpp/rtps/writer/StatefulWriter.cpp @@ -1387,6 +1387,8 @@ bool StatefulWriter::all_readers_updated() bool StatefulWriter::wait_for_all_acked( const dds::Duration_t& max_wait) { + send_periodic_heartbeat(); + std::unique_lock lock(mp_mutex); std::unique_lock all_acked_lock(all_acked_mutex_); diff --git a/test/blackbox/common/BlackboxTestsReliability.cpp b/test/blackbox/common/BlackboxTestsReliability.cpp index 8db3ec59092..1269a5d2186 100644 --- a/test/blackbox/common/BlackboxTestsReliability.cpp +++ b/test/blackbox/common/BlackboxTestsReliability.cpp @@ -100,3 +100,45 @@ TEST(Reliability, DisableHeartbeatPiggybackTrue) { reliability_disable_heartbeat_piggyback(true); } + +/** + * This test checks that waitForAllAcked() triggers a heartbeat if needed. + */ +TEST(Reliability, wait_for_all_acked_triggers_heartbeat) +{ + PubSubReader reader(TEST_TOPIC_NAME); + PubSubWriter writer(TEST_TOPIC_NAME); + + // Either ensure that the history will not become full, or disable piggyback heartbeats + static constexpr int32_t HISTORY_DEPTH = 10; + static constexpr int32_t NUM_SAMPLES = 1; + static_assert(NUM_SAMPLES < HISTORY_DEPTH, "NUM_SAMPLES must be less than HISTORY_DEPTH"); + + reader.reliability(eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS) + .history_kind(eprosima::fastdds::dds::KEEP_LAST_HISTORY_QOS) + .history_depth(HISTORY_DEPTH) + .init(); + + writer.reliability(eprosima::fastdds::dds::RELIABLE_RELIABILITY_QOS) + .history_kind(eprosima::fastdds::dds::KEEP_LAST_HISTORY_QOS) + .history_depth(HISTORY_DEPTH) + .heartbeat_period_seconds(180000) // Large heartbeat period to avoid interference + .init(); + + ASSERT_TRUE(reader.isInitialized()); + ASSERT_TRUE(writer.isInitialized()); + + // Wait for discovery. + writer.wait_discovery(); + reader.wait_discovery(); + + // Wait for the initial heartbeat/acknack exchange to finish + std::this_thread::sleep_for(std::chrono::seconds(1)); + + auto data = default_helloworld_data_generator(NUM_SAMPLES); + writer.send(data); + ASSERT_TRUE(data.empty()); + + // Wait until all data is acknowledged. This should trigger a heartbeat. + ASSERT_TRUE(writer.waitForAllAcked(std::chrono::seconds(1))); +}