Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StatusCondition implementation [11824] #2029

Merged
6 changes: 3 additions & 3 deletions include/fastdds/dds/core/Entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class Entity
const StatusMask& mask = StatusMask::all())
: status_mask_(mask)
, status_changes_(StatusMask::none())
, status_condition_(this)
, enable_(false)
{
}
Expand Down Expand Up @@ -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<StatusCondition&>(status_condition_);
return status_condition_;
}

protected:
Expand Down
32 changes: 28 additions & 4 deletions include/fastdds/dds/core/condition/StatusCondition.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<detail::StatusConditionImpl> impl_;

};

Expand Down
1 change: 1 addition & 0 deletions src/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 22 additions & 6 deletions src/cpp/fastdds/core/condition/StatusCondition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,45 @@
#include <fastdds/dds/core/condition/StatusCondition.hpp>
#include <fastrtps/types/TypesBase.h>

#include <fastdds/core/condition/StatusConditionImpl.hpp>

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<void>(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
Expand Down
54 changes: 46 additions & 8 deletions src/cpp/fastdds/core/condition/StatusConditionImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,21 @@

#include "StatusConditionImpl.hpp"

#include <mutex>

#include <fastdds/core/condition/ConditionNotifier.hpp>

namespace eprosima {
namespace fastdds {
namespace dds {
namespace detail {

StatusConditionImpl::StatusConditionImpl(
ConditionNotifier* notifier)
: mask_(StatusMask::all())
, status_(StatusMask::none())
, notifier_(notifier)
{
static_cast<void>(notifier);
}

StatusConditionImpl::~StatusConditionImpl()
Expand All @@ -35,28 +41,60 @@ StatusConditionImpl::~StatusConditionImpl()

bool StatusConditionImpl::get_trigger_value() const
{
return false;
std::lock_guard<std::mutex> guard(mutex_);
return (mask_ & status_).any();
}

ReturnCode_t StatusConditionImpl::set_enabled_statuses(
const StatusMask& mask)
{
static_cast<void>(mask);
return ReturnCode_t::RETCODE_UNSUPPORTED;
bool notify = false;
{
std::lock_guard<std::mutex> 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<std::mutex> guard(mutex_);
return mask_;
}

void StatusConditionImpl::set_status(
const StatusMask& status,
bool trigger_value)
{
static_cast<void>(status);
static_cast<void>(trigger_value);
if (trigger_value)
{
bool notify = false;
{
std::lock_guard<std::mutex> 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<std::mutex> guard(mutex_);
status_ &= ~status;
}
}

} // namespace detail
Expand Down
9 changes: 9 additions & 0 deletions src/cpp/fastdds/core/condition/StatusConditionImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#ifndef _FASTDDS_CORE_CONDITION_STATUSCONDITIONIMPL_HPP_
#define _FASTDDS_CORE_CONDITION_STATUSCONDITIONIMPL_HPP_

#include <mutex>

#include <fastdds/dds/core/status/StatusMask.hpp>
#include <fastrtps/types/TypesBase.h>

Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions test/unittest/dds/core/entity/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 3 additions & 6 deletions test/unittest/dds/core/entity/EntityTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
1 change: 1 addition & 0 deletions test/unittest/dds/status/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions test/unittest/statistics/dds/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down