Skip to content

Commit c935d47

Browse files
author
jparisu
committed
Refs #15841: Fix failure handle in Monitor creation
Signed-off-by: jparisu <[email protected]>
1 parent 4854568 commit c935d47

File tree

3 files changed

+89
-74
lines changed

3 files changed

+89
-74
lines changed

src/cpp/Monitor.hpp

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,23 @@
2222
#include <map>
2323
#include <string>
2424

25+
#include <fastdds/dds/domain/DomainParticipant.hpp>
26+
#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
27+
#include <fastdds/dds/domain/DomainParticipantListener.hpp>
28+
#include <fastdds/dds/domain/qos/DomainParticipantQos.hpp>
29+
#include <fastdds/dds/subscriber/DataReader.hpp>
30+
#include <fastdds/dds/subscriber/DataReaderListener.hpp>
31+
#include <fastdds/dds/subscriber/qos/DataReaderQos.hpp>
32+
#include <fastdds/dds/subscriber/qos/SubscriberQos.hpp>
33+
#include <fastdds/dds/subscriber/Subscriber.hpp>
34+
#include <fastdds/dds/topic/qos/TopicQos.hpp>
35+
#include <fastdds/dds/topic/Topic.hpp>
36+
2537
#include <fastdds_statistics_backend/listener/DomainListener.hpp>
2638
#include <fastdds_statistics_backend/listener/CallbackMask.hpp>
2739
#include <fastdds_statistics_backend/types/EntityId.hpp>
2840

2941
namespace eprosima {
30-
namespace fastdds {
31-
namespace dds {
32-
33-
class DomainParticipant;
34-
class DomainParticipantListener;
35-
class Subscriber;
36-
class Topic;
37-
class DataReader;
38-
class DataReaderListener;
39-
40-
} // namespace dds
41-
} // namespace fastdds
42-
4342
namespace statistics_backend {
4443
namespace details {
4544

@@ -50,51 +49,95 @@ namespace details {
5049
*/
5150
struct Monitor
5251
{
52+
/**
53+
* @brief Destroy the Monitor object
54+
*
55+
* Destroy every pointer that has been set.
56+
* This method works even if the monitor creation has failed
57+
*
58+
* @warning this may not be the best way to implement the destruction of subentities, as they are not created
59+
* under this class. But it is very convenience so it is reused during Monitor creation in case an error occurs
60+
* and also it is used to normally destroy the Monitor.
61+
*/
62+
~Monitor()
63+
{
64+
// These values are not always set, as could come from an error creating Monitor, or for test sake.
65+
if (participant)
66+
{
67+
if (subscriber)
68+
{
69+
for (auto& reader : readers)
70+
{
71+
subscriber->delete_datareader(reader.second);
72+
}
73+
74+
participant->delete_subscriber(subscriber);
75+
}
76+
77+
for (auto& topic : topics)
78+
{
79+
participant->delete_topic(topic.second);
80+
}
81+
82+
fastdds::dds::DomainParticipantFactory::get_instance()->delete_participant(participant);
83+
}
84+
85+
if (reader_listener)
86+
{
87+
delete reader_listener;
88+
}
89+
90+
if (participant_listener)
91+
{
92+
delete participant_listener;
93+
}
94+
}
95+
5396
//! The EntityId of the monitored domain
54-
EntityId id;
97+
EntityId id{};
5598

5699
//! The user listener for this monitor
57-
DomainListener* domain_listener;
100+
DomainListener* domain_listener = nullptr;
58101

59102
//! The callback mask applied to the \c domain_listener
60-
CallbackMask domain_callback_mask;
103+
CallbackMask domain_callback_mask{};
61104

62105
//! The data mask applied to the \c domain_listener->on_data_available
63-
DataKindMask data_mask;
106+
DataKindMask data_mask{};
64107

65108
//! The participant created to communicate with the statistics reporting endpoints in this monitor
66-
fastdds::dds::DomainParticipant* participant;
109+
fastdds::dds::DomainParticipant* participant = nullptr;
67110

68111
//! The listener linked to the \c participant
69112
//! It will process the entity discoveries
70-
fastdds::dds::DomainParticipantListener* participant_listener;
113+
fastdds::dds::DomainParticipantListener* participant_listener = nullptr;
71114

72115

73116
//! The participant created to communicate with the statistics reporting publishers in this monitor
74-
fastdds::dds::Subscriber* subscriber;
117+
fastdds::dds::Subscriber* subscriber = nullptr;
75118

76119
//! Holds the topic object created for each of the statistics topics
77-
std::map<std::string, fastdds::dds::Topic*> topics;
120+
std::map<std::string, fastdds::dds::Topic*> topics{};
78121

79122
//! Holds the datareader object created for each of the statistics topics
80-
std::map<std::string, fastdds::dds::DataReader*> readers;
123+
std::map<std::string, fastdds::dds::DataReader*> readers{};
81124

82125
//! The listener linked to the \c readers
83126
//! All readers will use the same listener
84127
//! The listener will decide how to process the data according to the topic of the reader
85-
fastdds::dds::DataReaderListener* reader_listener;
128+
fastdds::dds::DataReaderListener* reader_listener = nullptr;
86129

87130
//! Participant discovery status. Used in the participant discovery user callback
88-
DomainListener::Status participant_status_;
131+
DomainListener::Status participant_status_{};
89132

90133
//! Topic discovery status. Used in the topic discovery user callback
91-
DomainListener::Status topic_status_;
134+
DomainListener::Status topic_status_{};
92135

93136
//! Datareader discovery status. Used in the datareader discovery user callback
94-
DomainListener::Status datareader_status_;
137+
DomainListener::Status datareader_status_{};
95138

96139
//! DataWriter discovery status. Used in the datawriter discovery user callback
97-
DomainListener::Status datawriter_status_;
140+
DomainListener::Status datawriter_status_{};
98141
};
99142

100143
} // namespace details

src/cpp/StatisticsBackend.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -184,24 +184,14 @@ EntityId create_and_register_monitor(
184184
{
185185
details::StatisticsBackendData::get_instance()->lock();
186186

187-
/* Create monitor instance and register it in the database */
187+
// Create monitor instance.
188+
// NOTE: register in database at the end, in case any creation fails
188189
std::shared_ptr<details::Monitor> monitor = std::make_shared<details::Monitor>();
189190
std::shared_ptr<database::Domain> domain = std::make_shared<database::Domain>(domain_name);
190-
try
191-
{
192-
domain->id = details::StatisticsBackendData::get_instance()->database_->insert(domain);
193-
}
194-
catch (const std::exception&)
195-
{
196-
details::StatisticsBackendData::get_instance()->unlock();
197-
throw;
198-
}
199191

200-
monitor->id = domain->id;
201192
monitor->domain_listener = domain_listener;
202193
monitor->domain_callback_mask = callback_mask;
203194
monitor->data_mask = data_mask;
204-
details::StatisticsBackendData::get_instance()->monitors_by_entity_[domain->id] = monitor;
205195

206196
monitor->participant_listener = new subscriber::StatisticsParticipantListener(
207197
domain->id,
@@ -263,6 +253,22 @@ EntityId create_and_register_monitor(
263253
}
264254
}
265255

256+
// Insert domain entity in database
257+
try
258+
{
259+
domain->id = details::StatisticsBackendData::get_instance()->database_->insert(domain);
260+
}
261+
catch (const std::exception&)
262+
{
263+
details::StatisticsBackendData::get_instance()->unlock();
264+
throw;
265+
}
266+
267+
// Insert monitor as a new monitor entity.
268+
// NOTE: Monitor Id is only set after insert domain in database
269+
monitor->id = domain->id;
270+
details::StatisticsBackendData::get_instance()->monitors_by_entity_[domain->id] = monitor;
271+
266272
details::StatisticsBackendData::get_instance()->unlock();
267273
return domain->id;
268274
}

src/cpp/StatisticsBackendData.cpp

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -363,41 +363,7 @@ void StatisticsBackendData::stop_monitor(
363363
monitors_by_entity_.erase(it);
364364

365365
// Delete everything created during monitor initialization
366-
for (const auto& reader : monitor->readers)
367-
{
368-
monitor->subscriber->delete_datareader(reader.second);
369-
}
370-
monitor->readers.clear();
371-
372-
for (const auto& topic : monitor->topics)
373-
{
374-
monitor->participant->delete_topic(topic.second);
375-
}
376-
monitor->topics.clear();
377-
378-
// NOTE: for test sake, this is not always set
379-
if (monitor->subscriber)
380-
{
381-
monitor->participant->delete_subscriber(monitor->subscriber);
382-
}
383-
384-
// NOTE: for test sake, this is not always set
385-
if (monitor->participant)
386-
{
387-
eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->delete_participant(monitor->participant);
388-
}
389-
390-
// NOTE: for test sake, this is not always set
391-
if (monitor->reader_listener)
392-
{
393-
delete monitor->reader_listener;
394-
}
395-
396-
// NOTE: for test sake, this is not always set
397-
if (monitor->participant_listener)
398-
{
399-
delete monitor->participant_listener;
400-
}
366+
monitor.reset();
401367

402368
// The monitor is inactive
403369
// NOTE: for test sake, this is not always set

0 commit comments

Comments
 (0)