Coverage Report

Created: 2026-10-28 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Fast-DDS/src/cpp/fastdds/publisher/PublisherImpl.cpp
Line
Count
Source
1
// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/*
16
 * PublisherImpl.cpp
17
 *
18
 */
19
20
#include <fastdds/publisher/PublisherImpl.hpp>
21
22
#include <functional>
23
24
#include <fastdds/dds/domain/DomainParticipantListener.hpp>
25
#include <fastdds/dds/log/Log.hpp>
26
#include <fastdds/dds/publisher/DataWriter.hpp>
27
#include <fastdds/dds/publisher/Publisher.hpp>
28
#include <fastdds/dds/publisher/PublisherListener.hpp>
29
#include <fastdds/dds/publisher/qos/DataWriterQos.hpp>
30
#include <fastdds/dds/topic/TypeSupport.hpp>
31
#include <fastdds/domain/DomainParticipantImpl.hpp>
32
#include <fastdds/publisher/DataWriterImpl.hpp>
33
#include <fastdds/rtps/participant/RTPSParticipant.hpp>
34
#include <fastdds/topic/TopicDescriptionImpl.hpp>
35
#include <fastdds/utils/QosConverters.hpp>
36
37
#include <rtps/network/utils/netmask_filter.hpp>
38
#ifdef FASTDDS_STATISTICS
39
#include <statistics/types/monitorservice_types.hpp>
40
#endif //FASTDDS_STATISTICS
41
#include <xmlparser/attributes/PublisherAttributes.hpp>
42
#include <xmlparser/XMLProfileManager.h>
43
44
namespace eprosima {
45
namespace fastdds {
46
namespace dds {
47
48
using xmlparser::XMLProfileManager;
49
using xmlparser::XMLP_ret;
50
using rtps::InstanceHandle_t;
51
52
PublisherImpl::PublisherImpl(
53
        DomainParticipantImpl* p,
54
        const PublisherQos& qos,
55
        PublisherListener* listen)
56
0
    : participant_(p)
57
0
    , qos_(&qos == &PUBLISHER_QOS_DEFAULT ? participant_->get_default_publisher_qos() : qos)
58
0
    , listener_(listen)
59
0
    , publisher_listener_(this)
60
0
    , user_publisher_(nullptr)
61
0
    , rtps_participant_(p->get_rtps_participant())
62
0
    , default_datawriter_qos_(DATAWRITER_QOS_DEFAULT)
63
0
{
64
0
    xmlparser::PublisherAttributes pub_attr;
65
0
    XMLProfileManager::getDefaultPublisherAttributes(pub_attr);
66
0
    utils::set_qos_from_attributes(default_datawriter_qos_, pub_attr);
67
0
}
68
69
ReturnCode_t PublisherImpl::enable()
70
0
{
71
0
    if (qos_.entity_factory().autoenable_created_entities)
72
0
    {
73
0
        std::lock_guard<std::mutex> lock(mtx_writers_);
74
0
        for (auto topic_writers : writers_)
75
0
        {
76
0
            for (DataWriterImpl* dw : topic_writers.second)
77
0
            {
78
0
                dw->user_datawriter_->enable();
79
0
            }
80
0
        }
81
0
    }
82
83
0
    return RETCODE_OK;
84
0
}
85
86
void PublisherImpl::disable()
87
0
{
88
0
    set_listener(nullptr);
89
0
    user_publisher_->set_listener(nullptr);
90
0
    {
91
0
        std::lock_guard<std::mutex> lock(mtx_writers_);
92
0
        for (auto it = writers_.begin(); it != writers_.end(); ++it)
93
0
        {
94
0
            for (DataWriterImpl* dw : it->second)
95
0
            {
96
0
                dw->disable();
97
0
            }
98
0
        }
99
0
    }
100
0
}
101
102
PublisherImpl::~PublisherImpl()
103
0
{
104
0
    {
105
0
        std::lock_guard<std::mutex> lock(mtx_writers_);
106
0
        for (auto it = writers_.begin(); it != writers_.end(); ++it)
107
0
        {
108
0
            for (DataWriterImpl* dw : it->second)
109
0
            {
110
0
                delete dw;
111
0
            }
112
0
        }
113
0
        writers_.clear();
114
0
    }
115
116
0
    delete user_publisher_;
117
0
}
118
119
const PublisherQos& PublisherImpl::get_qos() const
120
0
{
121
0
    return qos_;
122
0
}
123
124
ReturnCode_t PublisherImpl::set_qos(
125
        const PublisherQos& qos)
126
0
{
127
0
    bool enabled = user_publisher_->is_enabled();
128
129
0
    const PublisherQos& qos_to_set = (&qos == &PUBLISHER_QOS_DEFAULT) ?
130
0
            participant_->get_default_publisher_qos() : qos;
131
132
0
    if (&qos != &PUBLISHER_QOS_DEFAULT)
133
0
    {
134
0
        ReturnCode_t ret_val = check_qos(qos_to_set);
135
0
        if (RETCODE_OK != ret_val)
136
0
        {
137
0
            return ret_val;
138
0
        }
139
0
    }
140
141
0
    if (enabled && !can_qos_be_updated(qos_, qos_to_set))
142
0
    {
143
0
        return RETCODE_IMMUTABLE_POLICY;
144
0
    }
145
0
    set_qos(qos_, qos_to_set, !enabled);
146
147
0
    if (enabled)
148
0
    {
149
0
        std::lock_guard<std::mutex> lock(mtx_writers_);
150
0
        for (auto topic_writers : writers_)
151
0
        {
152
0
            for (auto writer : topic_writers.second)
153
0
            {
154
0
                writer->publisher_qos_updated();
155
0
            }
156
0
        }
157
0
    }
158
159
0
    return RETCODE_OK;
160
0
}
161
162
const PublisherListener* PublisherImpl::get_listener() const
163
0
{
164
0
    return listener_;
165
0
}
166
167
ReturnCode_t PublisherImpl::set_listener(
168
        PublisherListener* listener)
169
0
{
170
0
    listener_ = listener;
171
0
    return RETCODE_OK;
172
0
}
173
174
void PublisherImpl::PublisherWriterListener::on_publication_matched(
175
        DataWriter* writer,
176
        const PublicationMatchedStatus& info)
177
0
{
178
0
    if (publisher_->listener_ != nullptr)
179
0
    {
180
0
        publisher_->listener_->on_publication_matched(writer, info);
181
0
    }
182
0
}
183
184
void PublisherImpl::PublisherWriterListener::on_liveliness_lost(
185
        DataWriter* writer,
186
        const LivelinessLostStatus& status)
187
0
{
188
0
    if (publisher_->listener_ != nullptr)
189
0
    {
190
0
        publisher_->listener_->on_liveliness_lost(writer, status);
191
0
    }
192
0
}
193
194
void PublisherImpl::PublisherWriterListener::on_offered_deadline_missed(
195
        DataWriter* writer,
196
        const OfferedDeadlineMissedStatus& status)
197
0
{
198
0
    if (publisher_->listener_ != nullptr)
199
0
    {
200
0
        publisher_->listener_->on_offered_deadline_missed(writer, status);
201
0
    }
202
0
}
203
204
DataWriterImpl* PublisherImpl::create_datawriter_impl(
205
        const TypeSupport& type,
206
        Topic* topic,
207
        const DataWriterQos& qos,
208
        DataWriterListener* listener,
209
        std::shared_ptr<fastdds::rtps::IPayloadPool> payload_pool)
210
0
{
211
0
    return new DataWriterImpl(this, type, topic, qos, listener, payload_pool);
212
0
}
213
214
DataWriter* PublisherImpl::create_datawriter(
215
        Topic* topic,
216
        const DataWriterQos& qos,
217
        DataWriterListener* listener,
218
        const StatusMask& mask,
219
        std::shared_ptr<fastdds::rtps::IPayloadPool> payload_pool)
220
0
{
221
0
    EPROSIMA_LOG_INFO(PUBLISHER, "CREATING WRITER IN TOPIC: " << topic->get_name());
222
    //Look for the correct type registration
223
0
    TypeSupport type_support = participant_->find_type(topic->get_type_name());
224
225
    /// Preconditions
226
    // Check the type was registered.
227
0
    if (type_support.empty())
228
0
    {
229
0
        EPROSIMA_LOG_ERROR(PUBLISHER, "Type: " << topic->get_type_name() << " Not Registered");
230
0
        return nullptr;
231
0
    }
232
233
0
    if (RETCODE_OK != DataWriterImpl::check_qos_including_resource_limits(qos, type_support))
234
0
    {
235
0
        return nullptr;
236
0
    }
237
238
    // Check netmask filtering preconditions
239
0
    if (nullptr != rtps_participant_)
240
0
    {
241
0
        std::vector<fastdds::rtps::TransportNetmaskFilterInfo> netmask_filter_info =
242
0
                rtps_participant_->get_netmask_filter_info();
243
0
        std::string error_msg;
244
0
        if (!fastdds::rtps::network::netmask_filter::check_preconditions(netmask_filter_info,
245
0
                qos.endpoint().ignore_non_matching_locators,
246
0
                error_msg) ||
247
0
                !fastdds::rtps::network::netmask_filter::check_preconditions(netmask_filter_info,
248
0
                qos.endpoint().external_unicast_locators, error_msg))
249
0
        {
250
0
            EPROSIMA_LOG_ERROR(PUBLISHER,
251
0
                    "Failed to create writer -> " << error_msg);
252
0
            return nullptr;
253
0
        }
254
0
    }
255
256
0
    DataWriterImpl* impl = create_datawriter_impl(type_support, topic, qos, listener, payload_pool);
257
0
    return create_datawriter(topic, impl, mask);
258
0
}
259
260
DataWriter* PublisherImpl::create_datawriter(
261
        Topic* topic,
262
        DataWriterImpl* impl,
263
        const StatusMask& mask)
264
0
{
265
0
    topic->get_impl()->reference();
266
267
0
    DataWriter* writer = new DataWriter(impl, mask);
268
0
    impl->user_datawriter_ = writer;
269
270
0
    {
271
0
        std::lock_guard<std::mutex> lock(mtx_writers_);
272
0
        writers_[topic->get_name()].push_back(impl);
273
0
    }
274
275
0
    if (user_publisher_->is_enabled() && qos_.entity_factory().autoenable_created_entities)
276
0
    {
277
0
        if (RETCODE_OK != writer->enable())
278
0
        {
279
0
            delete_datawriter(writer);
280
0
            return nullptr;
281
0
        }
282
0
    }
283
284
0
    return writer;
285
0
}
286
287
DataWriter* PublisherImpl::create_datawriter_with_profile(
288
        Topic* topic,
289
        const std::string& profile_name,
290
        DataWriterListener* listener,
291
        const StatusMask& mask,
292
        std::shared_ptr<fastdds::rtps::IPayloadPool> payload_pool)
293
0
{
294
    // TODO (ILG): Change when we have full XML support for DDS QoS profiles
295
0
    xmlparser::PublisherAttributes attr;
296
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fillPublisherAttributes(profile_name, attr))
297
0
    {
298
0
        DataWriterQos qos = default_datawriter_qos_;
299
0
        utils::set_qos_from_attributes(qos, attr);
300
0
        return create_datawriter(topic, qos, listener, mask, payload_pool);
301
0
    }
302
303
0
    return nullptr;
304
0
}
305
306
ReturnCode_t PublisherImpl::delete_datawriter(
307
        const DataWriter* writer)
308
0
{
309
0
    if (user_publisher_ != writer->get_publisher())
310
0
    {
311
0
        return RETCODE_PRECONDITION_NOT_MET;
312
0
    }
313
0
    std::unique_lock<std::mutex> lock(mtx_writers_);
314
0
    auto vit = writers_.find(writer->get_topic()->get_name());
315
0
    if (vit != writers_.end())
316
0
    {
317
0
        auto dw_it = std::find(vit->second.begin(), vit->second.end(), writer->impl_);
318
0
        if (dw_it != vit->second.end())
319
0
        {
320
            //First extract the writer from the maps to free the mutex
321
0
            DataWriterImpl* writer_impl = *dw_it;
322
0
            ReturnCode_t ret_code = writer_impl->check_delete_preconditions();
323
0
            if (RETCODE_OK != ret_code)
324
0
            {
325
0
                return ret_code;
326
0
            }
327
0
            writer_impl->set_listener(nullptr);
328
0
            vit->second.erase(dw_it);
329
0
            if (vit->second.empty())
330
0
            {
331
0
                writers_.erase(vit);
332
0
            }
333
0
            lock.unlock();
334
335
            //Now we can delete it
336
0
            writer_impl->get_topic()->get_impl()->dereference();
337
0
            delete (writer_impl);
338
0
            return RETCODE_OK;
339
0
        }
340
0
    }
341
0
    return RETCODE_ERROR;
342
0
}
343
344
DataWriter* PublisherImpl::lookup_datawriter(
345
        const std::string& topic_name) const
346
0
{
347
0
    std::lock_guard<std::mutex> lock(mtx_writers_);
348
0
    auto it = writers_.find(topic_name);
349
0
    if (it != writers_.end() && it->second.size() > 0)
350
0
    {
351
0
        return it->second.front()->user_datawriter_;
352
0
    }
353
0
    return nullptr;
354
0
}
355
356
bool PublisherImpl::get_datawriters(
357
        std::vector<DataWriter*>& writers) const
358
0
{
359
0
    std::lock_guard<std::mutex> lock(mtx_writers_);
360
0
    for (auto vit : writers_)
361
0
    {
362
0
        for (DataWriterImpl* dw : vit.second)
363
0
        {
364
0
            writers.push_back(dw->user_datawriter_);
365
0
        }
366
0
    }
367
0
    return true;
368
0
}
369
370
bool PublisherImpl::has_datawriters() const
371
0
{
372
0
    if (writers_.empty())
373
0
    {
374
0
        return false;
375
0
    }
376
0
    return true;
377
0
}
378
379
bool PublisherImpl::contains_entity(
380
        const fastdds::rtps::InstanceHandle_t& handle) const
381
0
{
382
0
    std::lock_guard<std::mutex> lock(mtx_writers_);
383
0
    for (auto vit : writers_)
384
0
    {
385
0
        for (DataWriterImpl* dw : vit.second)
386
0
        {
387
0
            InstanceHandle_t h(dw->guid());
388
0
            if (h == handle)
389
0
            {
390
0
                return true;
391
0
            }
392
0
        }
393
0
    }
394
0
    return false;
395
0
}
396
397
/* TODO
398
   bool PublisherImpl::suspend_publications()
399
   {
400
    EPROSIMA_LOG_ERROR(PUBLISHER, "Operation not implemented");
401
    return false;
402
   }
403
 */
404
405
/* TODO
406
   bool PublisherImpl::resume_publications()
407
   {
408
    EPROSIMA_LOG_ERROR(PUBLISHER, "Operation not implemented");
409
    return false;
410
   }
411
 */
412
413
/* TODO
414
   bool PublisherImpl::begin_coherent_changes()
415
   {
416
    EPROSIMA_LOG_ERROR(PUBLISHER, "Operation not implemented");
417
    return false;
418
   }
419
 */
420
421
/* TODO
422
   bool PublisherImpl::end_coherent_changes()
423
   {
424
    EPROSIMA_LOG_ERROR(PUBLISHER, "Operation not implemented");
425
    return false;
426
   }
427
 */
428
429
430
ReturnCode_t PublisherImpl::set_default_datawriter_qos(
431
        const DataWriterQos& qos)
432
0
{
433
0
    if (&qos == &DATAWRITER_QOS_DEFAULT)
434
0
    {
435
0
        reset_default_datawriter_qos();
436
0
        return RETCODE_OK;
437
0
    }
438
439
0
    ReturnCode_t ret_val = DataWriterImpl::check_qos(qos);
440
0
    if (RETCODE_OK != ret_val)
441
0
    {
442
0
        return ret_val;
443
0
    }
444
0
    DataWriterImpl::set_qos(default_datawriter_qos_, qos, true);
445
0
    return RETCODE_OK;
446
0
}
447
448
void PublisherImpl::reset_default_datawriter_qos()
449
0
{
450
    // TODO (ILG): Change when we have full XML support for DDS QoS profiles
451
0
    DataWriterImpl::set_qos(default_datawriter_qos_, DATAWRITER_QOS_DEFAULT, true);
452
0
    xmlparser::PublisherAttributes attr;
453
0
    XMLProfileManager::getDefaultPublisherAttributes(attr);
454
0
    utils::set_qos_from_attributes(default_datawriter_qos_, attr);
455
0
}
456
457
const DataWriterQos& PublisherImpl::get_default_datawriter_qos() const
458
0
{
459
0
    return default_datawriter_qos_;
460
0
}
461
462
ReturnCode_t PublisherImpl::get_datawriter_qos_from_profile(
463
        const std::string& profile_name,
464
        DataWriterQos& qos) const
465
0
{
466
0
    std::string _topic_name;
467
0
    return get_datawriter_qos_from_profile(profile_name, qos, _topic_name);
468
0
}
469
470
ReturnCode_t PublisherImpl::get_datawriter_qos_from_profile(
471
        const std::string& profile_name,
472
        DataWriterQos& qos,
473
        std::string& topic_name) const
474
0
{
475
0
    xmlparser::PublisherAttributes attr;
476
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fillPublisherAttributes(profile_name, attr, false))
477
0
    {
478
0
        qos = default_datawriter_qos_;
479
0
        utils::set_qos_from_attributes(qos, attr);
480
0
        topic_name = attr.topic.getTopicName();
481
0
        return RETCODE_OK;
482
0
    }
483
484
0
    return RETCODE_BAD_PARAMETER;
485
0
}
486
487
ReturnCode_t PublisherImpl::get_datawriter_qos_from_xml(
488
        const std::string& xml,
489
        DataWriterQos& qos) const
490
0
{
491
0
    std::string _topic_name;
492
0
    return get_datawriter_qos_from_xml(xml, qos, _topic_name);
493
0
}
494
495
ReturnCode_t PublisherImpl::get_datawriter_qos_from_xml(
496
        const std::string& xml,
497
        DataWriterQos& qos,
498
        std::string& topic_name) const
499
0
{
500
0
    xmlparser::PublisherAttributes attr;
501
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_publisher_attributes_from_xml(xml, attr, false))
502
0
    {
503
0
        qos = default_datawriter_qos_;
504
0
        utils::set_qos_from_attributes(qos, attr);
505
0
        topic_name = attr.topic.getTopicName();
506
0
        return RETCODE_OK;
507
0
    }
508
509
0
    return RETCODE_BAD_PARAMETER;
510
0
}
511
512
ReturnCode_t PublisherImpl::get_datawriter_qos_from_xml(
513
        const std::string& xml,
514
        DataWriterQos& qos,
515
        const std::string& profile_name) const
516
0
{
517
0
    std::string _topic_name;
518
0
    return get_datawriter_qos_from_xml(xml, qos, _topic_name, profile_name);
519
0
}
520
521
ReturnCode_t PublisherImpl::get_datawriter_qos_from_xml(
522
        const std::string& xml,
523
        DataWriterQos& qos,
524
        std::string& topic_name,
525
        const std::string& profile_name) const
526
0
{
527
0
    if (profile_name.empty())
528
0
    {
529
0
        EPROSIMA_LOG_ERROR(PUBLISHER, "Provided profile name must be non-empty");
530
0
        return RETCODE_BAD_PARAMETER;
531
0
    }
532
533
0
    xmlparser::PublisherAttributes attr;
534
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_publisher_attributes_from_xml(xml, attr, true, profile_name))
535
0
    {
536
0
        qos = default_datawriter_qos_;
537
0
        utils::set_qos_from_attributes(qos, attr);
538
0
        topic_name = attr.topic.getTopicName();
539
0
        return RETCODE_OK;
540
0
    }
541
542
0
    return RETCODE_BAD_PARAMETER;
543
0
}
544
545
ReturnCode_t PublisherImpl::get_default_datawriter_qos_from_xml(
546
        const std::string& xml,
547
        DataWriterQos& qos) const
548
0
{
549
0
    std::string _topic_name;
550
0
    return get_default_datawriter_qos_from_xml(xml, qos, _topic_name);
551
0
}
552
553
ReturnCode_t PublisherImpl::get_default_datawriter_qos_from_xml(
554
        const std::string& xml,
555
        DataWriterQos& qos,
556
        std::string& topic_name) const
557
0
{
558
0
    xmlparser::PublisherAttributes attr;
559
0
    if (XMLP_ret::XML_OK == XMLProfileManager::fill_default_publisher_attributes_from_xml(xml, attr, true))
560
0
    {
561
0
        qos = default_datawriter_qos_;
562
0
        utils::set_qos_from_attributes(qos, attr);
563
0
        topic_name = attr.topic.getTopicName();
564
0
        return RETCODE_OK;
565
0
    }
566
567
0
    return RETCODE_BAD_PARAMETER;
568
0
}
569
570
ReturnCode_t PublisherImpl::copy_from_topic_qos(
571
        DataWriterQos& writer_qos,
572
        const TopicQos& topic_qos)
573
0
{
574
0
    writer_qos.durability(topic_qos.durability());
575
0
    writer_qos.durability_service(topic_qos.durability_service());
576
0
    writer_qos.deadline(topic_qos.deadline());
577
0
    writer_qos.latency_budget(topic_qos.latency_budget());
578
0
    writer_qos.liveliness(topic_qos.liveliness());
579
0
    writer_qos.reliability(topic_qos.reliability());
580
0
    writer_qos.destination_order(topic_qos.destination_order());
581
0
    writer_qos.history(topic_qos.history());
582
0
    writer_qos.resource_limits(topic_qos.resource_limits());
583
0
    writer_qos.transport_priority(topic_qos.transport_priority());
584
0
    writer_qos.lifespan(topic_qos.lifespan());
585
0
    writer_qos.ownership(topic_qos.ownership());
586
0
    writer_qos.representation(topic_qos.representation());
587
0
    return RETCODE_OK;
588
0
}
589
590
ReturnCode_t PublisherImpl::wait_for_acknowledgments(
591
        const dds::Duration_t& max_wait)
592
0
{
593
0
    dds::Duration_t current = max_wait;
594
0
    dds::Duration_t begin, end;
595
0
    std::lock_guard<std::mutex> lock(mtx_writers_);
596
0
    for (auto& vit : writers_)
597
0
    {
598
0
        for (DataWriterImpl* dw : vit.second)
599
0
        {
600
0
            participant_->get_current_time(begin);
601
0
            if (RETCODE_OK != dw->wait_for_acknowledgments(current))
602
0
            {
603
0
                return RETCODE_ERROR;
604
0
            }
605
            // Check ellapsed time and decrement
606
0
            participant_->get_current_time(end);
607
0
            current = current - (end - begin);
608
0
            if (current < fastdds::dds::c_TimeZero)
609
0
            {
610
0
                return RETCODE_TIMEOUT;
611
0
            }
612
0
        }
613
0
    }
614
0
    return RETCODE_OK;
615
0
}
616
617
const DomainParticipant* PublisherImpl::get_participant() const
618
0
{
619
0
    return const_cast<const DomainParticipantImpl*>(participant_)->get_participant();
620
0
}
621
622
const Publisher* PublisherImpl::get_publisher() const
623
0
{
624
0
    return user_publisher_;
625
0
}
626
627
ReturnCode_t PublisherImpl::delete_contained_entities()
628
0
{
629
    // Let's be optimistic
630
0
    ReturnCode_t result = RETCODE_OK;
631
632
0
    bool can_be_deleted = true;
633
634
0
    std::lock_guard<std::mutex> lock(mtx_writers_);
635
0
    for (auto writer: writers_)
636
0
    {
637
0
        for (DataWriterImpl* dw: writer.second)
638
0
        {
639
0
            can_be_deleted = dw->check_delete_preconditions() == RETCODE_OK;
640
0
            if (!can_be_deleted)
641
0
            {
642
0
                return RETCODE_PRECONDITION_NOT_MET;
643
0
            }
644
0
        }
645
0
    }
646
647
    // We traverse the map trying to delete all writers;
648
0
    auto writer_iterator = writers_.begin();
649
0
    while (writer_iterator != writers_.end())
650
0
    {
651
        //First extract the writer from the maps to free the mutex
652
0
        auto it = writer_iterator->second.begin();
653
0
        DataWriterImpl* writer_impl = *it;
654
0
        ReturnCode_t ret_code = writer_impl->check_delete_preconditions();
655
0
        if (RETCODE_OK != ret_code)
656
0
        {
657
0
            return RETCODE_ERROR;
658
0
        }
659
0
        writer_impl->set_listener(nullptr);
660
0
        it = writer_iterator->second.erase(it);
661
0
        if (writer_iterator->second.empty())
662
0
        {
663
0
            writer_iterator = writers_.erase(writer_iterator);
664
0
        }
665
666
0
        writer_impl->get_topic()->get_impl()->dereference();
667
0
        delete (writer_impl);
668
0
    }
669
0
    return result;
670
0
}
671
672
bool PublisherImpl::can_be_deleted()
673
0
{
674
0
    bool can_be_deleted = true;
675
676
0
    std::lock_guard<std::mutex> lock(mtx_writers_);
677
0
    for (auto topic_writers : writers_)
678
0
    {
679
0
        for (DataWriterImpl* dw : topic_writers.second)
680
0
        {
681
0
            can_be_deleted = can_be_deleted && (dw->check_delete_preconditions() == RETCODE_OK);
682
0
            if (!can_be_deleted)
683
0
            {
684
0
                return can_be_deleted;
685
0
            }
686
0
        }
687
688
0
    }
689
690
0
    return can_be_deleted;
691
0
}
692
693
bool PublisherImpl::can_be_deleted(
694
        DataWriter* writer) const
695
0
{
696
0
    if (!writer)
697
0
    {
698
0
        EPROSIMA_LOG_ERROR(PUBLISHER, "DataWriter is nullptr.");
699
0
        return false;
700
0
    }
701
702
0
    if (user_publisher_ != writer->get_publisher())
703
0
    {
704
0
        EPROSIMA_LOG_ERROR(PUBLISHER, "DataWriter does not belong to this Publisher.");
705
0
        return false;
706
0
    }
707
708
0
    std::lock_guard<std::mutex> lock(mtx_writers_);
709
0
    auto it = writers_.find(writer->get_topic()->get_name());
710
711
0
    if (it != writers_.end())
712
0
    {
713
0
        auto dw_it = std::find(it->second.begin(), it->second.end(), writer->impl_);
714
715
0
        if (dw_it == it->second.end())
716
0
        {
717
0
            EPROSIMA_LOG_ERROR(PUBLISHER, "DataWriter implementation not found.");
718
0
            return false;
719
0
        }
720
721
0
        return (*dw_it)->check_delete_preconditions() == RETCODE_OK;
722
0
    }
723
724
0
    EPROSIMA_LOG_ERROR(PUBLISHER, "DataWriter not found.");
725
0
    return false;
726
0
}
727
728
const InstanceHandle_t& PublisherImpl::get_instance_handle() const
729
0
{
730
0
    return handle_;
731
0
}
732
733
bool PublisherImpl::type_in_use(
734
        const std::string& type_name) const
735
0
{
736
0
    for (auto it : writers_)
737
0
    {
738
0
        for (DataWriterImpl* writer : it.second)
739
0
        {
740
0
            if (writer->get_topic()->get_type_name() == type_name)
741
0
            {
742
0
                return true; // Is in use
743
0
            }
744
0
        }
745
0
    }
746
0
    return false;
747
0
}
748
749
void PublisherImpl::set_qos(
750
        PublisherQos& to,
751
        const PublisherQos& from,
752
        bool first_time)
753
0
{
754
0
    if (first_time && !(to.presentation() == from.presentation()))
755
0
    {
756
0
        to.presentation(from.presentation());
757
0
    }
758
0
    if (!(to.partition() == from.partition()))
759
0
    {
760
0
        to.partition() = from.partition();
761
0
    }
762
0
    if (!(to.group_data() == from.group_data()))
763
0
    {
764
0
        to.group_data() = from.group_data();
765
0
    }
766
0
    if (!(to.entity_factory() == from.entity_factory()))
767
0
    {
768
0
        to.entity_factory() = from.entity_factory();
769
0
    }
770
0
}
771
772
ReturnCode_t PublisherImpl::check_qos(
773
        const PublisherQos& qos)
774
0
{
775
0
    (void) qos;
776
0
    return RETCODE_OK;
777
0
}
778
779
bool PublisherImpl::can_qos_be_updated(
780
        const PublisherQos& to,
781
        const PublisherQos& from)
782
0
{
783
0
    (void) to;
784
0
    (void) from;
785
0
    return true;
786
0
}
787
788
PublisherListener* PublisherImpl::get_listener_for(
789
        const StatusMask& status)
790
0
{
791
0
    if (listener_ != nullptr &&
792
0
            user_publisher_->get_status_mask().is_active(status))
793
0
    {
794
0
        return listener_;
795
0
    }
796
0
    return participant_->get_listener_for(status);
797
0
}
798
799
#ifdef FASTDDS_STATISTICS
800
bool PublisherImpl::get_monitoring_status(
801
        statistics::MonitorServiceData& status,
802
        const fastdds::rtps::GUID_t& entity_guid)
803
0
{
804
0
    bool ret = false;
805
0
    std::vector<DataWriter*> writers;
806
0
    if (get_datawriters(writers))
807
0
    {
808
0
        for (auto& writer : writers)
809
0
        {
810
0
            if (writer->guid() == entity_guid)
811
0
            {
812
0
                switch (status._d())
813
0
                {
814
0
                    case statistics::StatusKind::INCOMPATIBLE_QOS:
815
0
                    {
816
0
                        OfferedIncompatibleQosStatus incompatible_qos_status;
817
0
                        writer->get_offered_incompatible_qos_status(incompatible_qos_status);
818
0
                        status.incompatible_qos_status().total_count(incompatible_qos_status.total_count);
819
0
                        status.incompatible_qos_status().last_policy_id(incompatible_qos_status.last_policy_id);
820
0
                        for (auto& qos : incompatible_qos_status.policies)
821
0
                        {
822
0
                            statistics::QosPolicyCount_s count;
823
0
                            count.count(qos.count);
824
0
                            count.policy_id(qos.policy_id);
825
0
                            status.incompatible_qos_status().policies().push_back(count);
826
0
                        }
827
0
                        ret = true;
828
0
                        break;
829
0
                    }
830
                    //! TODO
831
                    /*case statistics::StatusKind::INCONSISTENT_TOPIC:
832
                       {
833
                        writer->get_inconsistent_topic_status();
834
                        ret = true;
835
                        break;
836
                       }*/
837
0
                    case statistics::StatusKind::LIVELINESS_LOST:
838
0
                    {
839
0
                        LivelinessLostStatus liveliness_lost_status;
840
0
                        writer->get_liveliness_lost_status(liveliness_lost_status);
841
0
                        status.liveliness_lost_status().total_count(liveliness_lost_status.total_count);
842
0
                        ret = true;
843
0
                        break;
844
0
                    }
845
0
                    case statistics::StatusKind::DEADLINE_MISSED:
846
0
                    {
847
0
                        DeadlineMissedStatus deadline_missed_status;
848
0
                        writer->get_offered_deadline_missed_status(deadline_missed_status);
849
0
                        status.deadline_missed_status().total_count(deadline_missed_status.total_count);
850
0
                        std::memcpy(
851
0
                            status.deadline_missed_status().last_instance_handle().data(),
852
0
                            deadline_missed_status.last_instance_handle.value,
853
0
                            16);
854
0
                        ret = true;
855
0
                        break;
856
0
                    }
857
0
                    default:
858
0
                    {
859
0
                        EPROSIMA_LOG_ERROR(PUBLISHER, "Queried status not available for this entity " << status._d());
860
0
                        break;
861
0
                    }
862
0
                }
863
864
0
                break;
865
0
            }
866
0
        }
867
0
    }
868
0
    else
869
0
    {
870
0
        EPROSIMA_LOG_ERROR(PUBLISHER, "Could not retrieve datawriters");
871
0
    }
872
873
874
0
    return ret;
875
0
}
876
877
#endif //FASTDDS_STATISTICS
878
879
} // dds
880
} // fastdds
881
} // eprosima