From 500daedc751bb3f76c90029d894e0bf398d80667 Mon Sep 17 00:00:00 2001 From: Miguel Company Date: Tue, 29 Jun 2021 13:21:00 +0200 Subject: [PATCH] StatusCondition implementation (#2029) * Refs 11824. Added attributes to StatusConditionImpl. Signed-off-by: Miguel Company * Refs 11824. Compositing StatusConditionImpl inside StatusCondition. Signed-off-by: Miguel Company * Refs 11824. Fixed link issues. Signed-off-by: Miguel Company * Refs 11824. Adding implementation to StatusConditionImpl. Signed-off-by: Miguel Company * Refs 11824. Fixed Entity::get_statuscondition. Signed-off-by: Miguel Company * Refs 11824. Added StatusCondition::get_trigger_value. Signed-off-by: Miguel Company * Refs 11824. Linters. Signed-off-by: Miguel Company * Refs 11824. Changed EntityTests. Signed-off-by: Miguel Company --- include/fastdds/dds/core/Entity.hpp | 6 +-- .../dds/core/condition/StatusCondition.hpp | 32 +++++++++-- src/cpp/CMakeLists.txt | 1 + .../core/condition/StatusCondition.cpp | 28 +++++++--- .../core/condition/StatusConditionImpl.cpp | 54 ++++++++++++++++--- .../core/condition/StatusConditionImpl.hpp | 9 ++++ test/unittest/dds/core/entity/CMakeLists.txt | 1 + test/unittest/dds/core/entity/EntityTests.cpp | 9 ++-- test/unittest/dds/status/CMakeLists.txt | 1 + test/unittest/statistics/dds/CMakeLists.txt | 1 + 10 files changed, 115 insertions(+), 27 deletions(-) diff --git a/include/fastdds/dds/core/Entity.hpp b/include/fastdds/dds/core/Entity.hpp index 91cfb13d8fe..e39dec67b38 100644 --- a/include/fastdds/dds/core/Entity.hpp +++ b/include/fastdds/dds/core/Entity.hpp @@ -46,6 +46,7 @@ class Entity const StatusMask& mask = StatusMask::all()) : status_mask_(mask) , status_changes_(StatusMask::none()) + , status_condition_(this) , enable_(false) { } @@ -124,10 +125,9 @@ class Entity * @brief Allows access to the StatusCondition associated with the Entity * @return Reference to StatusCondition object */ - RTPS_DllAPI StatusCondition& get_statuscondition() const + RTPS_DllAPI StatusCondition& get_statuscondition() { - logWarning(CONDITION, "get_statuscondition method not implemented"); - return const_cast(status_condition_); + return status_condition_; } protected: diff --git a/include/fastdds/dds/core/condition/StatusCondition.hpp b/include/fastdds/dds/core/condition/StatusCondition.hpp index 25d3e940935..66baed08b6e 100644 --- a/include/fastdds/dds/core/condition/StatusCondition.hpp +++ b/include/fastdds/dds/core/condition/StatusCondition.hpp @@ -47,7 +47,28 @@ class StatusCondition : public Condition { public: - // StatusCondition not implemented. + StatusCondition( + Entity* parent); + + ~StatusCondition() final; + + // Non-copyable + StatusCondition( + const StatusCondition&) = delete; + StatusCondition& operator =( + const StatusCondition&) = delete; + + // Non-movable + StatusCondition( + StatusCondition&&) = delete; + StatusCondition& operator =( + StatusCondition&&) = delete; + + /** + * @brief Retrieves the trigger_value of the Condition + * @return true if trigger_value is set to 'true', 'false' otherwise + */ + RTPS_DllAPI bool get_trigger_value() const override; /** * @brief Defines the list of communication statuses that are taken into account to determine the trigger_value @@ -71,13 +92,16 @@ class StatusCondition : public Condition detail::StatusConditionImpl* get_impl() { - return nullptr; + return impl_.get(); } protected: - //! StatusMask with relevant statuses set to 1 - StatusMask status_mask; + //! DDS Entity for which this condition is monitoring the status + Entity* entity_ = nullptr; + + //! Class implementation + std::unique_ptr impl_; }; diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index fbbc8739a03..5971d79b9f1 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -162,6 +162,7 @@ set(${PROJECT_NAME}_source_files fastdds/core/condition/ConditionNotifier.cpp fastdds/core/condition/GuardCondition.cpp fastdds/core/condition/StatusCondition.cpp + fastdds/core/condition/StatusConditionImpl.cpp fastdds/core/condition/WaitSet.cpp fastdds/core/condition/WaitSetImpl.cpp fastdds/core/policy/ParameterList.cpp diff --git a/src/cpp/fastdds/core/condition/StatusCondition.cpp b/src/cpp/fastdds/core/condition/StatusCondition.cpp index 190fa27fa96..f7615b90aaf 100644 --- a/src/cpp/fastdds/core/condition/StatusCondition.cpp +++ b/src/cpp/fastdds/core/condition/StatusCondition.cpp @@ -20,29 +20,45 @@ #include #include +#include + namespace eprosima { namespace fastdds { namespace dds { using eprosima::fastrtps::types::ReturnCode_t; +StatusCondition::StatusCondition( + Entity* parent) + : Condition() + , entity_(parent) + , impl_(new detail::StatusConditionImpl(notifier_.get())) +{ +} + +StatusCondition::~StatusCondition() +{ +} + +bool StatusCondition::get_trigger_value() const +{ + return impl_->get_trigger_value(); +} + ReturnCode_t StatusCondition::set_enabled_statuses( const StatusMask& mask) { - static_cast(mask); - return ReturnCode_t::RETCODE_UNSUPPORTED; + return impl_->set_enabled_statuses(mask); } const StatusMask& StatusCondition::get_enabled_statuses() const { - logWarning(CONDITION, "get_enabled_statuses public member function not implemented"); - return status_mask; + return impl_->get_enabled_statuses(); } Entity* StatusCondition::get_entity() const { - logWarning(CONDITION, "get_entity public member function not implemented"); - return nullptr; + return entity_; } } // namespace dds diff --git a/src/cpp/fastdds/core/condition/StatusConditionImpl.cpp b/src/cpp/fastdds/core/condition/StatusConditionImpl.cpp index 4ddb029487f..61f0e6cde2f 100644 --- a/src/cpp/fastdds/core/condition/StatusConditionImpl.cpp +++ b/src/cpp/fastdds/core/condition/StatusConditionImpl.cpp @@ -18,6 +18,10 @@ #include "StatusConditionImpl.hpp" +#include + +#include + namespace eprosima { namespace fastdds { namespace dds { @@ -25,8 +29,10 @@ namespace detail { StatusConditionImpl::StatusConditionImpl( ConditionNotifier* notifier) + : mask_(StatusMask::all()) + , status_(StatusMask::none()) + , notifier_(notifier) { - static_cast(notifier); } StatusConditionImpl::~StatusConditionImpl() @@ -35,28 +41,60 @@ StatusConditionImpl::~StatusConditionImpl() bool StatusConditionImpl::get_trigger_value() const { - return false; + std::lock_guard guard(mutex_); + return (mask_ & status_).any(); } ReturnCode_t StatusConditionImpl::set_enabled_statuses( const StatusMask& mask) { - static_cast(mask); - return ReturnCode_t::RETCODE_UNSUPPORTED; + bool notify = false; + { + std::lock_guard guard(mutex_); + bool old_trigger = (mask_ & status_).any(); + mask_ = mask; + bool new_trigger = (mask_ & status_).any(); + notify = !old_trigger && new_trigger; + } + + if (notify) + { + notifier_->notify(); + } + return ReturnCode_t::RETCODE_OK; } const StatusMask& StatusConditionImpl::get_enabled_statuses() const { - static const StatusMask none = StatusMask::none(); - return none; + std::lock_guard guard(mutex_); + return mask_; } void StatusConditionImpl::set_status( const StatusMask& status, bool trigger_value) { - static_cast(status); - static_cast(trigger_value); + if (trigger_value) + { + bool notify = false; + { + std::lock_guard guard(mutex_); + bool old_trigger = (mask_ & status_).any(); + status_ |= status; + bool new_trigger = (mask_ & status_).any(); + notify = !old_trigger && new_trigger; + } + + if (notify) + { + notifier_->notify(); + } + } + else + { + std::lock_guard guard(mutex_); + status_ &= ~status; + } } } // namespace detail diff --git a/src/cpp/fastdds/core/condition/StatusConditionImpl.hpp b/src/cpp/fastdds/core/condition/StatusConditionImpl.hpp index 648c1248321..8cb0d346e36 100644 --- a/src/cpp/fastdds/core/condition/StatusConditionImpl.hpp +++ b/src/cpp/fastdds/core/condition/StatusConditionImpl.hpp @@ -19,6 +19,8 @@ #ifndef _FASTDDS_CORE_CONDITION_STATUSCONDITIONIMPL_HPP_ #define _FASTDDS_CORE_CONDITION_STATUSCONDITIONIMPL_HPP_ +#include + #include #include @@ -82,6 +84,13 @@ struct StatusConditionImpl void set_status( const StatusMask& status, bool trigger_value); + +private: + + mutable std::mutex mutex_; + StatusMask mask_{}; + StatusMask status_{}; + ConditionNotifier* notifier_; }; } // namespace detail diff --git a/test/unittest/dds/core/entity/CMakeLists.txt b/test/unittest/dds/core/entity/CMakeLists.txt index 7dce347d37b..3448996906c 100644 --- a/test/unittest/dds/core/entity/CMakeLists.txt +++ b/test/unittest/dds/core/entity/CMakeLists.txt @@ -26,6 +26,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/Condition.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/ConditionNotifier.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/StatusCondition.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/StatusConditionImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/WaitSetImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/log/Log.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/log/OStreamConsumer.cpp diff --git a/test/unittest/dds/core/entity/EntityTests.cpp b/test/unittest/dds/core/entity/EntityTests.cpp index 6ddd01ed2ee..a708907629d 100644 --- a/test/unittest/dds/core/entity/EntityTests.cpp +++ b/test/unittest/dds/core/entity/EntityTests.cpp @@ -151,15 +151,12 @@ TEST_F(EntityTests, entity_equal_operator) ASSERT_FALSE(entity1 == entity4); } -/* Test unsupported methods behaviour*/ -TEST_F(EntityTests, unsupported_entity_methods) +TEST_F(EntityTests, get_statuscondition) { Entity entity; - // It cannot compare because StatusCondition does not have comparaison methods - entity.get_statuscondition(); - - HELPER_WaitForEntries(1); + StatusCondition& cond = entity.get_statuscondition(); + EXPECT_EQ(&entity, cond.get_entity()); } int main( diff --git a/test/unittest/dds/status/CMakeLists.txt b/test/unittest/dds/status/CMakeLists.txt index 2955c922d72..b5919771e00 100644 --- a/test/unittest/dds/status/CMakeLists.txt +++ b/test/unittest/dds/status/CMakeLists.txt @@ -24,6 +24,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/Condition.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/ConditionNotifier.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/StatusCondition.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/StatusConditionImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/WaitSetImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/policy/QosPolicyUtils.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/domain/DomainParticipant.cpp diff --git a/test/unittest/statistics/dds/CMakeLists.txt b/test/unittest/statistics/dds/CMakeLists.txt index 4922978f53b..59046428dac 100644 --- a/test/unittest/statistics/dds/CMakeLists.txt +++ b/test/unittest/statistics/dds/CMakeLists.txt @@ -113,6 +113,7 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER)) ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/Condition.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/ConditionNotifier.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/StatusCondition.cpp + ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/StatusConditionImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/condition/WaitSetImpl.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/policy/ParameterList.cpp ${PROJECT_SOURCE_DIR}/src/cpp/fastdds/core/policy/QosPolicyUtils.cpp