5454#include " StatisticsBackendData.hpp"
5555#include " detail/data_getters.hpp"
5656#include " detail/data_aggregation.hpp"
57+ #include " detail/ScopeExit.hpp"
5758
5859using namespace eprosima ::fastdds::dds;
5960using namespace eprosima ::fastdds::rtps;
@@ -187,20 +188,15 @@ EntityId create_and_register_monitor(
187188 // What should happen is that all this logic is moved to StatisticsBackendData. You know, some day...
188189
189190 details::StatisticsBackendData::get_instance ()->lock ();
191+ MAKE_UNNAMED_SCOPE_EXIT (details::StatisticsBackendData::get_instance ()->unlock ());
190192
191193 // Create monitor instance.
192194 std::shared_ptr<details::Monitor> monitor = std::make_shared<details::Monitor>();
193195 std::shared_ptr<database::Domain> domain = std::make_shared<database::Domain>(domain_name);
194196
195- try
196- {
197- domain->id = details::StatisticsBackendData::get_instance ()->database_ ->insert (domain);
198- }
199- catch (const std::exception&)
200- {
201- details::StatisticsBackendData::get_instance ()->unlock ();
202- throw ;
203- }
197+ // Throw exception in fail case
198+ domain->id = details::StatisticsBackendData::get_instance ()->database_ ->insert (domain);
199+
204200 // TODO: in case this function fails afterwards, the domain will be kept in the database without associated
205201 // Participant. There must exist a way in database to delete a domain, or to make a rollback.
206202
@@ -209,14 +205,19 @@ EntityId create_and_register_monitor(
209205 monitor->domain_callback_mask = callback_mask;
210206 monitor->data_mask = data_mask;
211207 details::StatisticsBackendData::get_instance ()->monitors_by_entity_ [domain->id ] = monitor;
208+ auto se_erase_monitor_database_ =
209+ MAKE_SCOPE_EXIT (details::StatisticsBackendData::get_instance ()->monitors_by_entity_ .erase (domain->id ));
212210
213211 monitor->participant_listener = new subscriber::StatisticsParticipantListener (
214212 domain->id ,
215213 details::StatisticsBackendData::get_instance ()->database_ .get (),
216214 details::StatisticsBackendData::get_instance ()->entity_queue_ ,
217215 details::StatisticsBackendData::get_instance ()->data_queue_ );
216+ auto se_participant_listener_ = MAKE_SCOPE_EXIT (delete monitor->participant_listener );
217+
218218 monitor->reader_listener = new subscriber::StatisticsReaderListener (
219219 details::StatisticsBackendData::get_instance ()->data_queue_ );
220+ auto se_reader_listener_ = MAKE_SCOPE_EXIT (delete monitor->reader_listener );
220221
221222 /* Create DomainParticipant */
222223 StatusMask participant_mask = StatusMask::all ();
@@ -229,14 +230,9 @@ EntityId create_and_register_monitor(
229230
230231 if (monitor->participant == nullptr )
231232 {
232- // Remove those elements that have been set
233- delete monitor->reader_listener ;
234- delete monitor->participant_listener ;
235- details::StatisticsBackendData::get_instance ()->monitors_by_entity_ .erase (domain->id );
236-
237- details::StatisticsBackendData::get_instance ()->unlock ();
238233 throw Error (" Error initializing monitor. Could not create participant" );
239234 }
235+ auto se_participant_ = MAKE_SCOPE_EXIT (DomainParticipantFactory::get_instance ()->delete_participant (monitor->participant ));
240236
241237 /* Create Subscriber */
242238 monitor->subscriber = monitor->participant ->create_subscriber (
@@ -246,15 +242,29 @@ EntityId create_and_register_monitor(
246242
247243 if (monitor->subscriber == nullptr )
248244 {
249- // Remove those elements that have been set
250- DomainParticipantFactory::get_instance ()->delete_participant (monitor->participant );
251- delete monitor->reader_listener ;
252- delete monitor->participant_listener ;
253- details::StatisticsBackendData::get_instance ()->monitors_by_entity_ .erase (domain->id );
254-
255- details::StatisticsBackendData::get_instance ()->unlock ();
256245 throw Error (" Error initializing monitor. Could not create subscriber" );
257246 }
247+ auto se_subscriber_ = MAKE_SCOPE_EXIT (monitor->participant ->delete_subscriber (monitor->subscriber ));
248+
249+ auto se_topics_datareaders_ =
250+ MAKE_SCOPE_EXIT (
251+ {
252+ for (auto & it : monitor->readers )
253+ {
254+ if (nullptr != it.second )
255+ {
256+ monitor->subscriber ->delete_datareader (it.second );
257+ }
258+ }
259+ for (auto & it : monitor->topics )
260+ {
261+ if (nullptr != it.second )
262+ {
263+ monitor->participant ->delete_topic (it.second );
264+ }
265+ }
266+ }
267+ );
258268
259269 for (const auto & topic : topics)
260270 {
@@ -265,28 +275,6 @@ EntityId create_and_register_monitor(
265275 }
266276 catch (const std::exception& e)
267277 {
268- // Remove those elements that have been set
269- for (auto & it : monitor->readers )
270- {
271- if (nullptr != it.second )
272- {
273- monitor->subscriber ->delete_datareader (it.second );
274- }
275- }
276- for (auto & it : monitor->topics )
277- {
278- if (nullptr != it.second )
279- {
280- monitor->participant ->delete_topic (it.second );
281- }
282- }
283- monitor->participant ->delete_subscriber (monitor->subscriber );
284- DomainParticipantFactory::get_instance ()->delete_participant (monitor->participant );
285- delete monitor->reader_listener ;
286- delete monitor->participant_listener ;
287- details::StatisticsBackendData::get_instance ()->monitors_by_entity_ .erase (domain->id );
288-
289- details::StatisticsBackendData::get_instance ()->unlock ();
290278 throw Error (" Error registering topic " + std::string (topic) + " : " + e.what ());
291279 }
292280
@@ -299,33 +287,17 @@ EntityId create_and_register_monitor(
299287
300288 if (monitor->readers [topic] == nullptr )
301289 {
302- // Remove those elements that have been set
303- for (auto & it : monitor->readers )
304- {
305- if (nullptr != it.second )
306- {
307- monitor->subscriber ->delete_datareader (it.second );
308- }
309- }
310- for (auto & it : monitor->topics )
311- {
312- if (nullptr != it.second )
313- {
314- monitor->participant ->delete_topic (it.second );
315- }
316- }
317- monitor->participant ->delete_subscriber (monitor->subscriber );
318- DomainParticipantFactory::get_instance ()->delete_participant (monitor->participant );
319- delete monitor->reader_listener ;
320- delete monitor->participant_listener ;
321- details::StatisticsBackendData::get_instance ()->monitors_by_entity_ .erase (domain->id );
322-
323- details::StatisticsBackendData::get_instance ()->unlock ();
324290 throw Error (" Error initializing monitor. Could not create reader for topic " + std::string (topic));
325291 }
326292 }
327293
328- details::StatisticsBackendData::get_instance ()->unlock ();
294+ se_erase_monitor_database_.cancel ();
295+ se_participant_listener_.cancel ();
296+ se_reader_listener_.cancel ();
297+ se_participant_.cancel ();
298+ se_subscriber_.cancel ();
299+ se_topics_datareaders_.cancel ();
300+
329301 return domain->id ;
330302}
331303
0 commit comments