From 2896957a3dfd84e3ce418888d8940b1fa37abc03 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 27 Feb 2019 11:05:11 +0100 Subject: [PATCH 01/54] Refs #4693 Refactor of PublisherHistory and SubscriberHistory to use a map instead of current vector of pairs --- include/fastrtps/publisher/PublisherHistory.h | 21 ++++-- .../fastrtps/subscriber/SubscriberHistory.h | 22 ++++-- src/cpp/publisher/PublisherHistory.cpp | 75 ++++++++----------- src/cpp/subscriber/SubscriberHistory.cpp | 73 +++++++----------- 4 files changed, 87 insertions(+), 104 deletions(-) diff --git a/include/fastrtps/publisher/PublisherHistory.h b/include/fastrtps/publisher/PublisherHistory.h index 03e9a1c7408..18a9359d745 100644 --- a/include/fastrtps/publisher/PublisherHistory.h +++ b/include/fastrtps/publisher/PublisherHistory.h @@ -41,8 +41,8 @@ class PublisherImpl; class PublisherHistory:public rtps::WriterHistory { public: - typedef std::pair> t_p_I_Change; - typedef std::vector t_v_Inst_Caches; + typedef std::map> t_m_Inst_Caches; + typedef std::vector t_v_Caches; /** * Constructor of the PublisherHistory. * @param pimpl Pointer to the PublisherImpl. @@ -89,16 +89,15 @@ class PublisherHistory:public rtps::WriterHistory /** * Remove a change by the publisher History. * @param change Pointer to the CacheChange_t. - * @param vit Pointer to the iterator of the Keyed history vector. * @return True if removed. */ - bool remove_change_pub(rtps::CacheChange_t* change,t_v_Inst_Caches::iterator* vit=nullptr); + bool remove_change_pub(rtps::CacheChange_t* change); virtual bool remove_change_g(rtps::CacheChange_t* a_change); private: - //!Vector of pointer to the CacheChange_t divided by key. - t_v_Inst_Caches m_keyedChanges; + //!Map where keys are instance handles and values are vectors of cache changes associated + t_m_Inst_Caches m_keyedChanges; //!HistoryQosPolicy values. HistoryQosPolicy m_historyQos; //!ResourceLimitsQosPolicy values. @@ -106,7 +105,15 @@ class PublisherHistory:public rtps::WriterHistory //!Publisher Pointer PublisherImpl* mp_pubImpl; - bool find_Key(rtps::CacheChange_t* a_change,t_v_Inst_Caches::iterator* vecPairIterrator); + /** + * @brief Method that finds a key in m_keyedChanges or tries to add it if not found + * @param a_change The change to get the key from + * @param map_it A map iterator to the given key + * @return True if the key was found or could be added to the map + */ + bool find_key( + rtps::CacheChange_t* a_change, + t_m_Inst_Caches::iterator* map_it); }; } /* namespace fastrtps */ diff --git a/include/fastrtps/subscriber/SubscriberHistory.h b/include/fastrtps/subscriber/SubscriberHistory.h index a6ad6cc8c75..56430f0fc68 100644 --- a/include/fastrtps/subscriber/SubscriberHistory.h +++ b/include/fastrtps/subscriber/SubscriberHistory.h @@ -46,8 +46,8 @@ class SubscriberHistory: public rtps::ReaderHistory { public: - typedef std::pair> t_p_I_Change; - typedef std::vector t_v_Inst_Caches; + typedef std::map> t_m_Inst_Caches; + typedef std::vector t_v_Caches; /** * Constructor. Requires information about the subscriner @@ -94,10 +94,9 @@ class SubscriberHistory: public rtps::ReaderHistory /** * This method is called to remove a change from the SubscriberHistory. * @param change Pointer to the CacheChange_t. - * @param vit Pointer to the iterator of the key-ordered cacheChange vector. * @return True if removed. */ - bool remove_change_sub(rtps::CacheChange_t* change,t_v_Inst_Caches::iterator* vit=nullptr); + bool remove_change_sub(rtps::CacheChange_t* change); //!Increase the unread count. inline void increaseUnreadCount() @@ -124,8 +123,8 @@ class SubscriberHistory: public rtps::ReaderHistory //!Number of unread CacheChange_t. uint64_t m_unreadCacheCount; - //!Vector of pointer to the CacheChange_t divided by key. - t_v_Inst_Caches m_keyedChanges; + //!Map where keys are instance handles and values vectors of cache changes + t_m_Inst_Caches m_keyedChanges; //!HistoryQosPolicy values. HistoryQosPolicy m_historyQos; //!ResourceLimitsQosPolicy values. @@ -136,8 +135,15 @@ class SubscriberHistory: public rtps::ReaderHistory //!Type object to deserialize Key void * mp_getKeyObject; - - bool find_Key(rtps::CacheChange_t* a_change,t_v_Inst_Caches::iterator* vecPairIterrator); + /** + * @brief Method that finds a key in m_keyedChanges or tries to add it if not found + * @param a_change The change to get the key from + * @param map_it A map iterator to the given key + * @return True if it was found or could be added to the map + */ + bool find_key( + rtps::CacheChange_t* a_change, + t_m_Inst_Caches::iterator* map_it); }; } /* namespace fastrtps */ diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index b58aa030848..11666a988e9 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -105,8 +105,8 @@ bool PublisherHistory::add_pub_change( //HISTORY WITH KEY else if(mp_pubImpl->getAttributes().topic.getTopicKind() == WITH_KEY) { - t_v_Inst_Caches::iterator vit; - if(find_Key(change,&vit)) + t_m_Inst_Caches::iterator vit; + if(find_key(change,&vit)) { logInfo(RTPS_HISTORY,"Found key: "<< vit->first); bool add = false; @@ -123,13 +123,13 @@ bool PublisherHistory::add_pub_change( } else if (m_historyQos.kind == KEEP_LAST_HISTORY_QOS) { - if(vit->second.size()< (size_t)m_historyQos.depth) + if(vit->second.size() < (size_t)m_historyQos.depth) { add = true; } else { - if(remove_change_pub(vit->second.front(),&vit)) + if(remove_change_pub(vit->second.front())) { add = true; } @@ -154,44 +154,35 @@ bool PublisherHistory::add_pub_change( return returnedValue; } -bool PublisherHistory::find_Key(CacheChange_t* a_change,t_v_Inst_Caches::iterator* vit_out) +bool PublisherHistory::find_key( + CacheChange_t* a_change, + t_m_Inst_Caches::iterator* vit_out) { - t_v_Inst_Caches::iterator vit; - bool found = false; - for(vit= m_keyedChanges.begin();vit!=m_keyedChanges.end();++vit) + t_m_Inst_Caches::iterator vit; + vit = m_keyedChanges.find(a_change->instanceHandle); + if (vit != m_keyedChanges.end()) { - if(a_change->instanceHandle == vit->first) - { - *vit_out = vit; - return true; - } + *vit_out = vit; + return true; } - if(!found) + + if ((int)m_keyedChanges.size() < m_resourceLimitsQos.max_instances) { - if((int)m_keyedChanges.size() < m_resourceLimitsQos.max_instances) - { - t_p_I_Change newpair; - newpair.first = a_change->instanceHandle; - m_keyedChanges.push_back(newpair); - *vit_out = m_keyedChanges.end()-1; - return true; - } - else + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, std::vector())).first; + return true; + } + else + { + for (vit = m_keyedChanges.begin(); vit != m_keyedChanges.end(); ++vit) { - for (vit = m_keyedChanges.begin(); vit != m_keyedChanges.end(); ++vit) + if (vit->second.size() == 0) { - if (vit->second.size() == 0) - { - m_keyedChanges.erase(vit); - t_p_I_Change newpair; - newpair.first = a_change->instanceHandle; - m_keyedChanges.push_back(newpair); - *vit_out = m_keyedChanges.end() - 1; - return true; - } + m_keyedChanges.erase(vit); + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, std::vector())).first; + return true; } - logWarning(SUBSCRIBER, "History has reached the maximum number of instances" << endl;) } + logWarning(PUBLISHER, "History has reached the maximum number of instances" << endl;) } return false; } @@ -232,7 +223,7 @@ bool PublisherHistory::removeMinChange() return false; } -bool PublisherHistory::remove_change_pub(CacheChange_t* change,t_v_Inst_Caches::iterator* vit_in) +bool PublisherHistory::remove_change_pub(CacheChange_t* change) { if(mp_writer == nullptr || mp_mutex == nullptr) @@ -254,17 +245,13 @@ bool PublisherHistory::remove_change_pub(CacheChange_t* change,t_v_Inst_Caches:: } else { - t_v_Inst_Caches::iterator vit; - if(vit_in!=nullptr) - vit = *vit_in; - else if(this->find_Key(change,&vit)) + t_m_Inst_Caches::iterator vit; + if(!this->find_key(change,&vit)) { - - } - else return false; - for(auto chit = vit->second.begin(); - chit!= vit->second.end();++chit) + } + + for(auto chit = vit->second.begin(); chit!= vit->second.end(); ++chit) { if( ((*chit)->sequenceNumber == change->sequenceNumber) && ((*chit)->writerGUID == change->writerGUID) ) diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index 3ea30bf9254..fba385af32d 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -180,8 +180,8 @@ bool SubscriberHistory::received_change( << " and no method to obtain it";); return false; } - t_v_Inst_Caches::iterator vit; - if (find_Key(a_change, &vit)) + t_m_Inst_Caches::iterator vit; + if (find_key(a_change, &vit)) { //logInfo(RTPS_EDP,"Trying to add change with KEY: "<< vit->first << endl;); bool add = false; @@ -224,7 +224,7 @@ bool SubscriberHistory::received_change( { bool read = (*older_sample)->isRead; - if (this->remove_change_sub(*older_sample, &vit)) + if (this->remove_change_sub(*older_sample)) { if (!read) { @@ -472,51 +472,41 @@ bool SubscriberHistory::takeNextData(void* data, SampleInfo_t* info) return false; } -bool SubscriberHistory::find_Key(CacheChange_t* a_change, t_v_Inst_Caches::iterator* vit_out) +bool SubscriberHistory::find_key( + CacheChange_t* a_change, + t_m_Inst_Caches::iterator* vit_out) { - t_v_Inst_Caches::iterator vit; - bool found = false; - for (vit = m_keyedChanges.begin(); vit != m_keyedChanges.end(); ++vit) + t_m_Inst_Caches::iterator vit; + vit = m_keyedChanges.find(a_change->instanceHandle); + if (vit != m_keyedChanges.end()) { - if (a_change->instanceHandle == vit->first) - { - *vit_out = vit; - return true; - } + *vit_out = vit; + return true; } - if (!found) + + if ((int)m_keyedChanges.size() < m_resourceLimitsQos.max_instances) { - if ((int)m_keyedChanges.size() < m_resourceLimitsQos.max_instances) - { - t_p_I_Change newpair; - newpair.first = a_change->instanceHandle; - m_keyedChanges.push_back(newpair); - *vit_out = m_keyedChanges.end() - 1; - return true; - } - else + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, t_v_Caches())).first; + return true; + } + else + { + for (vit = m_keyedChanges.begin(); vit!= m_keyedChanges.end(); ++vit) { - for (vit = m_keyedChanges.begin(); vit != m_keyedChanges.end(); ++vit) + if (vit->second.size() == 0) { - if (vit->second.size() == 0) - { - m_keyedChanges.erase(vit); - t_p_I_Change newpair; - newpair.first = a_change->instanceHandle; - m_keyedChanges.push_back(newpair); - *vit_out = m_keyedChanges.end() - 1; - return true; - } + m_keyedChanges.erase(vit); + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, t_v_Caches())).first; + return true; } - logWarning(SUBSCRIBER, "History has reached the maximum number of instances"); } - + logWarning(SUBSCRIBER, "History has reached the maximum number of instances"); } return false; } -bool SubscriberHistory::remove_change_sub(CacheChange_t* change, t_v_Inst_Caches::iterator* vit_in) +bool SubscriberHistory::remove_change_sub(CacheChange_t* change) { if (mp_reader == nullptr || mp_mutex == nullptr) { @@ -536,19 +526,12 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change, t_v_Inst_Caches } else { - t_v_Inst_Caches::iterator vit; - if (vit_in != nullptr) - { - vit = *vit_in; - } - else if (this->find_Key(change, &vit)) - { - - } - else + t_m_Inst_Caches::iterator vit; + if (!this->find_key(change, &vit)) { return false; } + for (auto chit = vit->second.begin(); chit != vit->second.end(); ++chit) { if ((*chit)->sequenceNumber == change->sequenceNumber && (*chit)->writerGUID == change->writerGUID) From 2ad42621f701592a487b5fc4e15e8a7bd8878724 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 27 Feb 2019 12:23:33 +0100 Subject: [PATCH 02/54] Refs #4693 Adding new class DeadlineTimer --- .../fastrtps/rtps/resources/DeadlineTimer.h | 70 +++++++++++++++++++ src/cpp/CMakeLists.txt | 2 + src/cpp/rtps/resources/DeadlineTimer.cpp | 69 ++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 include/fastrtps/rtps/resources/DeadlineTimer.h create mode 100644 src/cpp/rtps/resources/DeadlineTimer.cpp diff --git a/include/fastrtps/rtps/resources/DeadlineTimer.h b/include/fastrtps/rtps/resources/DeadlineTimer.h new file mode 100644 index 00000000000..0302b0438b9 --- /dev/null +++ b/include/fastrtps/rtps/resources/DeadlineTimer.h @@ -0,0 +1,70 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file DeadlineTimer.h + * + */ + +#ifndef DeadlineTimer_H_ +#define DeadlineTimer_H_ +#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC + +#include "TimedEvent.h" + +#include + +namespace eprosima { +namespace fastrtps{ +namespace rtps { + +/** A class that starts a timer and invokes a callback when the timer expires + * @ingroup MANAGEMENT_MODULE + */ +class DeadlineTimer : public TimedEvent +{ +public: + + /** Constructor + * @param callback A callback to invoke when the timer expires + * @param period Interval of the DeadlineTimer in milliseconds + * @param service IO service to run the event + * @param event_thread starting thread for identification. + */ + DeadlineTimer( + std::function callback, + Duration_t period, + asio::io_service &service, + const std::thread& event_thread); + + /** Destructor + */ + virtual ~DeadlineTimer(); + + /** Method invoked when the event occurs + * @param code Code representing the status of the event + * @param msg Message associated to the event. It can be nullptr + */ + virtual void event(EventCode code, const char* msg) override; + +private: + + //! Callback invoked when the timer expires + std::function callback_; +}; +} +} /* namespace rtps */ +} /* namespace eprosima */ +#endif +#endif diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index 500805f8a7d..d94a9b1ed97 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -31,6 +31,8 @@ set(${PROJECT_NAME}_source_files rtps/resources/TimedEventImpl.cpp rtps/resources/AsyncWriterThread.cpp rtps/resources/AsyncInterestTree.cpp + rtps/resources/DeadlineTimer.cpp + rtps/Endpoint.cpp rtps/writer/RTPSWriter.cpp rtps/writer/StatefulWriter.cpp rtps/writer/ReaderProxy.cpp diff --git a/src/cpp/rtps/resources/DeadlineTimer.cpp b/src/cpp/rtps/resources/DeadlineTimer.cpp new file mode 100644 index 00000000000..c027e7a31e9 --- /dev/null +++ b/src/cpp/rtps/resources/DeadlineTimer.cpp @@ -0,0 +1,69 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file DeadlineTimer.cpp + * + */ + +#include +#include + +namespace eprosima { +namespace fastrtps{ +namespace rtps { + +DeadlineTimer::DeadlineTimer( + std::function callback, + Duration_t period, + asio::io_service &service, + const std::thread &event_thread) + : TimedEvent(service, event_thread, period.to_ns() * 1e-6) + , callback_(callback) +{ +} + +DeadlineTimer::~DeadlineTimer() +{ +} + +void DeadlineTimer::event(EventCode code, const char *msg) +{ + // Unused in release mode. + (void)msg; + + if(code == EVENT_SUCCESS) + { + if (callback_ != nullptr) + { + callback_(); + } + else + { + logWarning(DEADLINETIMER, "Event successfull but callback is nullptr"); + } + } + else if(code == EVENT_ABORT) + { + logInfo(DEADLINETIMER, "Aborted"); + } + else + { + logInfo(DEADLINETIMER, "Event message: " << msg); + } +} + +} +} /* namespace rtps */ +} /* namespace eprosima */ From 8f302ac981c8dc2a622d0dfd27a1708d6b35675c Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 27 Feb 2019 12:27:04 +0100 Subject: [PATCH 03/54] Refs #4693 Changes to Participant, ParticipantImpl and RTPSParticipant so that I can later get the resource event from PublisherImpl and SubscriberImpl --- include/fastrtps/participant/Participant.h | 7 +++++++ include/fastrtps/rtps/participant/RTPSParticipant.h | 3 +++ src/cpp/participant/Participant.cpp | 5 +++++ src/cpp/participant/ParticipantImpl.cpp | 5 +++++ src/cpp/participant/ParticipantImpl.h | 2 ++ src/cpp/rtps/participant/RTPSParticipant.cpp | 5 +++++ 6 files changed, 27 insertions(+) diff --git a/include/fastrtps/participant/Participant.h b/include/fastrtps/participant/Participant.h index 93d205837fe..3a779f8b1b2 100644 --- a/include/fastrtps/participant/Participant.h +++ b/include/fastrtps/participant/Participant.h @@ -35,6 +35,7 @@ namespace rtps { class WriterProxyData; class ReaderProxyData; + class ResourceEvent; } /** @@ -86,6 +87,12 @@ class RTPS_DllAPI Participant bool get_remote_writer_info(const rtps::GUID_t& writerGuid, rtps::WriterProxyData& returnedInfo); bool get_remote_reader_info(const rtps::GUID_t& readerGuid, rtps::ReaderProxyData& returnedInfo); + + /** + * Get the resource event for this participant + */ + rtps::ResourceEvent& get_resource_event() const; + }; } diff --git a/include/fastrtps/rtps/participant/RTPSParticipant.h b/include/fastrtps/rtps/participant/RTPSParticipant.h index ad41510fe7e..115731166e4 100644 --- a/include/fastrtps/rtps/participant/RTPSParticipant.h +++ b/include/fastrtps/rtps/participant/RTPSParticipant.h @@ -41,6 +41,7 @@ class RTPSWriter; class RTPSReader; class WriterProxyData; class ReaderProxyData; +class ResourceEvent; /** @@ -141,6 +142,8 @@ class RTPS_DllAPI RTPSParticipant bool get_remote_reader_info(const GUID_t& readerGuid, ReaderProxyData& returnedInfo); + ResourceEvent& get_resource_event() const; + private: //!Pointer to the implementation. diff --git a/src/cpp/participant/Participant.cpp b/src/cpp/participant/Participant.cpp index 5355da002ce..f6584c54321 100644 --- a/src/cpp/participant/Participant.cpp +++ b/src/cpp/participant/Participant.cpp @@ -63,3 +63,8 @@ bool Participant::get_remote_reader_info(const GUID_t& readerGuid, ReaderProxyDa { return mp_impl->get_remote_reader_info(readerGuid, returnedInfo); } + +ResourceEvent& Participant::get_resource_event() const +{ + return mp_impl->get_resource_event(); +} diff --git a/src/cpp/participant/ParticipantImpl.cpp b/src/cpp/participant/ParticipantImpl.cpp index 91a0f199df7..93ac2bd9a9f 100644 --- a/src/cpp/participant/ParticipantImpl.cpp +++ b/src/cpp/participant/ParticipantImpl.cpp @@ -496,3 +496,8 @@ bool ParticipantImpl::get_remote_reader_info( { return mp_rtpsParticipant->get_remote_reader_info(readerGuid, returnedInfo); } + +ResourceEvent& ParticipantImpl::get_resource_event() const +{ + return mp_rtpsParticipant->get_resource_event(); +} diff --git a/src/cpp/participant/ParticipantImpl.h b/src/cpp/participant/ParticipantImpl.h index 8324f5185f6..42b84097341 100644 --- a/src/cpp/participant/ParticipantImpl.h +++ b/src/cpp/participant/ParticipantImpl.h @@ -158,6 +158,8 @@ class ParticipantImpl const rtps::GUID_t& readerGuid, rtps::ReaderProxyData& returnedInfo); + ResourceEvent& get_resource_event() const; + private: //!Participant Attributes ParticipantAttributes m_att; diff --git a/src/cpp/rtps/participant/RTPSParticipant.cpp b/src/cpp/rtps/participant/RTPSParticipant.cpp index d71552ce323..1e9eb520e79 100644 --- a/src/cpp/rtps/participant/RTPSParticipant.cpp +++ b/src/cpp/rtps/participant/RTPSParticipant.cpp @@ -115,6 +115,11 @@ bool RTPSParticipant::get_remote_reader_info(const GUID_t& readerGuid, ReaderPro return mp_impl->get_remote_reader_info(readerGuid, returnedInfo); } +ResourceEvent& RTPSParticipant::get_resource_event() const +{ + return mp_impl->getEventResource(); +} + } /* namespace rtps */ } /* namespace fastrtps */ } /* namespace eprosima */ From 7008458f8796893e136ec68b1f1ec1aea1232d37 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 27 Feb 2019 12:33:14 +0100 Subject: [PATCH 04/54] Refs #4693 Adding callbacks to pub/sub listeners to notify missed deadlines --- include/fastrtps/publisher/PublisherListener.h | 11 +++++++++++ include/fastrtps/subscriber/SubscriberListener.h | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/include/fastrtps/publisher/PublisherListener.h b/include/fastrtps/publisher/PublisherListener.h index 643741334e4..0efa1e164f7 100644 --- a/include/fastrtps/publisher/PublisherListener.h +++ b/include/fastrtps/publisher/PublisherListener.h @@ -27,6 +27,11 @@ namespace fastrtps { class Publisher; +namespace rtps +{ +class InstanceHandle_t; +} + /** * Class PublisherListener, allows the end user to implement callbacks triggered by certain events. * @ingroup FASTRTPS_MODULE @@ -43,6 +48,12 @@ class RTPS_DllAPI PublisherListener * @param info Information regarding the matched subscriber */ virtual void onPublicationMatched(Publisher* pub, rtps::MatchingInfo& info){(void)pub; (void)info;}; + + /** + * A method called when an instance of a topic misses the deadline period + * @param handle The instance handle + */ + virtual void on_offered_deadline_missed(rtps::InstanceHandle_t& /*handle*/) {}; }; } /* namespace rtps */ diff --git a/include/fastrtps/subscriber/SubscriberListener.h b/include/fastrtps/subscriber/SubscriberListener.h index b28964144d9..e2cd7df4980 100644 --- a/include/fastrtps/subscriber/SubscriberListener.h +++ b/include/fastrtps/subscriber/SubscriberListener.h @@ -25,6 +25,7 @@ namespace eprosima { namespace fastrtps { namespace rtps { class MatchingInfo; + class InstanceHandle_t; } /* namespace rtps */ class Subscriber; @@ -54,6 +55,12 @@ class RTPS_DllAPI SubscriberListener * @param info Matching information */ virtual void onSubscriptionMatched(Subscriber* /*sub*/, rtps::MatchingInfo& /*info*/){}; + + /** + * Virtual method to be called when a topic misses the deadline period + * @param handle The instance handle + */ + virtual void on_requested_deadline_missed(rtps::InstanceHandle_t& /*handle*/) {} }; } /* namespace fastrtps */ From b22e7753b4b91c3299ae0e80abd99583eaec6ff8 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 27 Feb 2019 14:18:33 +0100 Subject: [PATCH 05/54] Refs #4693 Adding deadline functionality to publisher and subscriber --- include/fastrtps/publisher/PublisherHistory.h | 6 ++ .../fastrtps/subscriber/SubscriberHistory.h | 6 ++ src/cpp/CMakeLists.txt | 1 - src/cpp/publisher/PublisherHistory.cpp | 27 +++++++++ src/cpp/publisher/PublisherImpl.cpp | 52 +++++++++++++++++ src/cpp/publisher/PublisherImpl.h | 12 +++- src/cpp/rtps/history/WriterHistory.cpp | 1 + src/cpp/subscriber/SubscriberHistory.cpp | 27 +++++++++ src/cpp/subscriber/SubscriberImpl.cpp | 57 ++++++++++++++++++- src/cpp/subscriber/SubscriberImpl.h | 17 ++++++ 10 files changed, 201 insertions(+), 5 deletions(-) diff --git a/include/fastrtps/publisher/PublisherHistory.h b/include/fastrtps/publisher/PublisherHistory.h index 18a9359d745..bce012211f8 100644 --- a/include/fastrtps/publisher/PublisherHistory.h +++ b/include/fastrtps/publisher/PublisherHistory.h @@ -95,6 +95,12 @@ class PublisherHistory:public rtps::WriterHistory virtual bool remove_change_g(rtps::CacheChange_t* a_change); + /** + * Returns the latest sample for each topic key + * @param samples A vector containing the latest samples + */ + void get_latest_samples(std::vector &samples); + private: //!Map where keys are instance handles and values are vectors of cache changes associated t_m_Inst_Caches m_keyedChanges; diff --git a/include/fastrtps/subscriber/SubscriberHistory.h b/include/fastrtps/subscriber/SubscriberHistory.h index 56430f0fc68..23acd85d542 100644 --- a/include/fastrtps/subscriber/SubscriberHistory.h +++ b/include/fastrtps/subscriber/SubscriberHistory.h @@ -119,6 +119,12 @@ class SubscriberHistory: public rtps::ReaderHistory return m_unreadCacheCount; } + /** + * A method that resturns the latest sample for each topic key + * @param samples A vector containing the latest sample for each key + */ + void get_latest_samples(std::vector& samples); + private: //!Number of unread CacheChange_t. diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index d94a9b1ed97..65e893bead2 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -32,7 +32,6 @@ set(${PROJECT_NAME}_source_files rtps/resources/AsyncWriterThread.cpp rtps/resources/AsyncInterestTree.cpp rtps/resources/DeadlineTimer.cpp - rtps/Endpoint.cpp rtps/writer/RTPSWriter.cpp rtps/writer/StatefulWriter.cpp rtps/writer/ReaderProxy.cpp diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index 11666a988e9..1402cd95863 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -273,3 +273,30 @@ bool PublisherHistory::remove_change_g(CacheChange_t* a_change) { return remove_change_pub(a_change); } + +void PublisherHistory::get_latest_samples(std::vector &samples) +{ + samples.clear(); + + if (mp_pubImpl->getAttributes().topic.getTopicKind() == NO_KEY) + { + samples.reserve(1); + auto max = *std::max_element( + m_changes.begin(), + m_changes.end(), + [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); + samples.push_back(max); + } + else if (mp_pubImpl->getAttributes().topic.getTopicKind() == WITH_KEY) + { + samples.reserve(m_keyedChanges.size()); + for (auto it = m_keyedChanges.begin(); it != m_keyedChanges.end(); ++it) + { + auto max = *std::max_element( + it->second.begin(), + it->second.end(), + [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); + samples.push_back(max); + } + } +} diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index 6e18c196648..bff4e1fdaec 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -31,6 +31,10 @@ #include #include +#include +#include + +#include using namespace eprosima::fastrtps; using namespace ::rtps; @@ -58,6 +62,11 @@ PublisherImpl::PublisherImpl( , mp_userPublisher(nullptr) , mp_rtpsParticipant(nullptr) , high_mark_for_frag_(0) + , deadline_timer_(std::bind(&PublisherImpl::check_deadlines, this), + att.qos.m_deadline.period, + mp_participant->get_resource_event().getIOService(), + mp_participant->get_resource_event().getThread()) + , deadline_duration_(att.qos.m_deadline.period) { } @@ -189,6 +198,12 @@ bool PublisherImpl::create_new_change_with_params( return true; } + + if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) + { + deadline_timer_.restart_timer(); + } + return true; } return false; @@ -317,3 +332,40 @@ bool PublisherImpl::wait_for_all_acked(const Time_t& max_wait) { return mp_writer->wait_for_all_acked(max_wait); } + +void PublisherImpl::check_deadlines() +{ + assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); + + auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + + // Get the latest samples from the history + std::vector samples; + m_history.get_latest_samples(samples); + + if (samples.empty()) + { + return; + } + + // Time of the earliest sample among all topic instances + Time_t minTime = samples.front()->sourceTimestamp; + + for (const auto &sample : samples) + { + if (sample->sourceTimestamp < minTime) + { + minTime = sample->sourceTimestamp; + } + + if (now - sample->sourceTimestamp > deadline_duration_ ) + { + mp_listener->on_offered_deadline_missed(sample->instanceHandle); + } + } + + // Now restart the timer + Duration_t interval = deadline_duration_ - now + minTime > 0? deadline_duration_ - now + minTime: deadline_duration_; + deadline_timer_.update_interval(interval); + deadline_timer_.restart_timer(); +} diff --git a/src/cpp/publisher/PublisherImpl.h b/src/cpp/publisher/PublisherImpl.h index 6ceceeaad89..878c2d6f2c8 100644 --- a/src/cpp/publisher/PublisherImpl.h +++ b/src/cpp/publisher/PublisherImpl.h @@ -30,6 +30,7 @@ #include #include +#include namespace eprosima { namespace fastrtps{ @@ -39,8 +40,6 @@ class RTPSWriter; class RTPSParticipant; } - - class TopicDataType; class PublisherListener; class ParticipantImpl; @@ -157,6 +156,15 @@ class PublisherImpl rtps::RTPSParticipant* mp_rtpsParticipant; uint32_t high_mark_for_frag_; + + //! A timer used to check for deadlines + DeadlineTimer deadline_timer_; + //! Deadline duration + Duration_t deadline_duration_; + + /** Method to check for deadlines + */ + void check_deadlines(); }; diff --git a/src/cpp/rtps/history/WriterHistory.cpp b/src/cpp/rtps/history/WriterHistory.cpp index a0299540ec8..27d0d97d1c2 100644 --- a/src/cpp/rtps/history/WriterHistory.cpp +++ b/src/cpp/rtps/history/WriterHistory.cpp @@ -87,6 +87,7 @@ bool WriterHistory::add_change_(CacheChange_t* a_change, WriteParams &wparams, ++m_lastCacheChangeSeqNum; a_change->sequenceNumber = m_lastCacheChangeSeqNum; + a_change->sourceTimestamp = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); a_change->write_params = wparams; // Updated sample identity diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index fba385af32d..14f5199f9ac 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -548,3 +548,30 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change) } return false; } + +void SubscriberHistory::get_latest_samples(std::vector &samples) +{ + samples.clear(); + + if (mp_subImpl->getAttributes().topic.getTopicKind() == NO_KEY) + { + samples.reserve(1); + auto max = *std::max_element( + m_changes.begin(), + m_changes.end(), + [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); + samples.push_back(max); + } + else if (mp_subImpl->getAttributes().topic.getTopicKind() == WITH_KEY) + { + samples.reserve(m_keyedChanges.size()); + for (auto it = m_keyedChanges.begin(); it != m_keyedChanges.end(); ++it) + { + auto max = *std::max_element( + it->second.begin(), + it->second.end(), + [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); + samples.push_back(max); + } + } +} diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index 1ba58e83ccc..168d64af2dd 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -18,6 +18,7 @@ */ #include "SubscriberImpl.h" +#include "../participant/ParticipantImpl.h" #include #include #include @@ -26,6 +27,7 @@ #include #include +#include #include @@ -51,8 +53,12 @@ SubscriberImpl::SubscriberImpl( , m_readerListener(this) , mp_userSubscriber(nullptr) , mp_rtpsParticipant(nullptr) + , deadline_timer_(std::bind(&SubscriberImpl::check_deadlines, this), + att.qos.m_deadline.period, + mp_participant->get_resource_event().getIOService(), + mp_participant->get_resource_event().getThread()) + , deadline_duration_(att.qos.m_deadline.period) { - } @@ -181,9 +187,10 @@ bool SubscriberImpl::updateAttributes(const SubscriberAttributes& att) void SubscriberImpl::SubscriberReaderListener::onNewCacheChangeAdded(RTPSReader* /*reader*/, const CacheChange_t* const /*change*/) { + mp_subscriberImpl->onNewCacheChangeAdded(); + if(mp_subscriberImpl->mp_listener != nullptr) { - //cout << "FIRST BYTE: "<< (int)change->serializedPayload.data[0] << endl; mp_subscriberImpl->mp_listener->onNewDataMessage(mp_subscriberImpl->mp_userSubscriber); } } @@ -196,6 +203,14 @@ void SubscriberImpl::SubscriberReaderListener::onReaderMatched(RTPSReader* /*rea } } +void SubscriberImpl::onNewCacheChangeAdded() +{ + if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) + { + deadline_timer_.restart_timer(); + } +} + /*! * @brief Returns there is a clean state with all Publishers. * It occurs when the Subscriber received all samples sent by Publishers. In other words, @@ -212,5 +227,43 @@ uint64_t SubscriberImpl::getUnreadCount() const return m_history.getUnreadCount(); } +void SubscriberImpl::check_deadlines() +{ + assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); + + auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + + // Get the latest samples from the history + std::vector samples; + m_history.get_latest_samples(samples); + + if (samples.empty()) + { + return; + } + + // Time of the earliest sample among all topic instances + Time_t minTime = samples.front()->sourceTimestamp; + + // Check if any instance missed the dealine + for (const auto &sample : samples) + { + if (sample->sourceTimestamp < minTime) + { + minTime = sample->sourceTimestamp; + } + + if (now - sample->sourceTimestamp > deadline_duration_) + { + mp_listener->on_requested_deadline_missed(sample->instanceHandle); + } + } + + // Restart the timer + Duration_t interval = deadline_duration_ - now + minTime > 0? deadline_duration_ - now + minTime: deadline_duration_; + deadline_timer_.update_interval(interval); + deadline_timer_.restart_timer(); +} + } /* namespace fastrtps */ } /* namespace eprosima */ diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index 6608bb5c739..a599329ebb3 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace eprosima { @@ -120,6 +121,12 @@ class SubscriberImpl { */ uint64_t getUnreadCount() const; + /** + * @brief A method called when a new cache change is added + * @param change The cache change that has been added + */ + void onNewCacheChangeAdded(); + private: //!Participant ParticipantImpl* mp_participant; @@ -147,6 +154,16 @@ class SubscriberImpl { Subscriber* mp_userSubscriber; //!RTPSParticipant rtps::RTPSParticipant* mp_rtpsParticipant; + + //!A timer used to check for deadlines + DeadlineTimer deadline_timer_; + //!Deadline duration + Duration_t deadline_duration_; + + /** A method to check for deadlines + */ + void check_deadlines(); + }; From 535850d8970970dcc729ad2d852070f166b932a7 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 27 Feb 2019 14:31:52 +0100 Subject: [PATCH 06/54] Refs #4693 Adding check for compatibility reader-writer --- include/fastrtps/qos/ReaderQos.h | 2 +- include/fastrtps/qos/WriterQos.h | 2 +- src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp | 12 ++++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/fastrtps/qos/ReaderQos.h b/include/fastrtps/qos/ReaderQos.h index 7445b1592f0..cd4ec1a2b64 100644 --- a/include/fastrtps/qos/ReaderQos.h +++ b/include/fastrtps/qos/ReaderQos.h @@ -58,7 +58,7 @@ class ReaderQos{ //!Durability Qos, implemented in the library. DurabilityQosPolicy m_durability; - //!Deadline Qos, NOT implemented in the library. + //!Deadline Qos, implemented in the library. DeadlineQosPolicy m_deadline; //!Latency Budget Qos, NOT implemented in the library. LatencyBudgetQosPolicy m_latencyBudget; diff --git a/include/fastrtps/qos/WriterQos.h b/include/fastrtps/qos/WriterQos.h index 0afb6476edf..47704f0c6b0 100644 --- a/include/fastrtps/qos/WriterQos.h +++ b/include/fastrtps/qos/WriterQos.h @@ -63,7 +63,7 @@ class WriterQos{ DurabilityQosPolicy m_durability; //!Durability Service Qos, NOT implemented in the library. DurabilityServiceQosPolicy m_durabilityService; - //!Deadline Qos, NOT implemented in the library. + //!Deadline Qos, implemented in the library. DeadlineQosPolicy m_deadline; //!Latency Budget Qos, NOT implemented in the library. LatencyBudgetQosPolicy m_latencyBudget; diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp b/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp index 00ea9e74ae7..d348b7305f9 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp @@ -426,6 +426,12 @@ bool EDP::validMatching(const WriterProxyData* wdata, const ReaderProxyData* rda << rdata->guid() << " has different Ownership Kind"); return false; } + if(wdata->m_qos.m_deadline.period > rdata->m_qos.m_deadline.period) + { + logWarning(RTPS_EDP,"INCOMPATIBLE QOS (topic: "<< rdata->topicName() <<"):Remote reader " + << rdata->guid() << " has smaller DEADLINE period"); + return false; + } #if HAVE_SECURITY // TODO: Check EndpointSecurityInfo @@ -527,6 +533,12 @@ bool EDP::validMatching(const ReaderProxyData* rdata, const WriterProxyData* wda logWarning(RTPS_EDP, "INCOMPATIBLE QOS (topic: " << wdata->topicName() << "):Remote Writer " << wdata->guid() << " has different Ownership Kind" << endl;); return false; } + if(rdata->m_qos.m_deadline.period < wdata->m_qos.m_deadline.period) + { + logWarning(RTPS_EDP, "INCOMPATIBLE QOS (topic: " << wdata->topicName() << "):RemoteWriter " << wdata->guid() << "has smaller DEADLINE period"); + return false; + } + #if HAVE_SECURITY // TODO: Check EndpointSecurityInfo #endif From b565ea7088268aeed8c699fb2db5d6ce11a14fc2 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 27 Feb 2019 15:39:34 +0100 Subject: [PATCH 07/54] Refs #4693 Adding C++ example --- .../deadlinepayloadPubSubMain.cxx | 24 +++++-- .../deadlinepayloadPublisher.cxx | 69 ++++++++++++++----- .../deadlinepayloadPublisher.h | 38 +++++++--- .../deadlinepayloadSubscriber.cxx | 40 ++++++----- .../deadlinepayloadSubscriber.h | 43 +++++++----- 5 files changed, 147 insertions(+), 67 deletions(-) diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx index e917224ff8f..7130bffc6fd 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx @@ -27,15 +27,29 @@ int main(int argc, char** argv) { std::cout << "Starting " << std::endl; int type = 1; + int deadline = 1000; + int sleep = 100; if (argc > 1) { if (strcmp(argv[1], "publisher") == 0) { type = 1; + if (argc > 2) + { + deadline = atoi(argv[2]); + if (argc > 3) + { + sleep = atoi(argv[3]); + } + } } else if (strcmp(argv[1], "subscriber") == 0) { type = 2; + if (argc > 2) + { + deadline = atoi(argv[2]); + } } } else @@ -52,18 +66,16 @@ int main(int argc, char** argv) case 1: { deadlinepayloadPublisher mypub; - if (mypub.init()) + if (mypub.init(deadline)) { - mypub.run(); + mypub.run(sleep); } break; } case 2: { - io_service io; - steady_timer myTimer(io); - deadlinepayloadSubscriber mysub(myTimer,io); - if (mysub.init()) + deadlinepayloadSubscriber mysub; + if (mysub.init(deadline)) { mysub.run(); } diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx index f2ee41f5050..cdc76cc373b 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx @@ -26,11 +26,19 @@ using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; -deadlinepayloadPublisher::deadlinepayloadPublisher() : mp_participant(nullptr), mp_publisher(nullptr), double_time(false) {} +deadlinepayloadPublisher::deadlinepayloadPublisher() + : mp_participant(nullptr) + , mp_publisher(nullptr) + , double_time(false) +{ +} -deadlinepayloadPublisher::~deadlinepayloadPublisher() { Domain::removeParticipant(mp_participant);} +deadlinepayloadPublisher::~deadlinepayloadPublisher() +{ + Domain::removeParticipant(mp_participant); +} -bool deadlinepayloadPublisher::init() +bool deadlinepayloadPublisher::init(double deadline_period_ms) { // Create RTPSParticipant @@ -52,14 +60,18 @@ bool deadlinepayloadPublisher::init() Wparam.topic.topicKind = WITH_KEY; Wparam.topic.topicDataType = myType.getName(); //This type MUST be registered Wparam.topic.topicName = "deadlinepayloadPubSubTopic"; - Wparam.topic.resourceLimitsQos.max_instances=32; - Wparam.topic.resourceLimitsQos.max_samples_per_instance=5; - Wparam.topic.resourceLimitsQos.max_samples = 32*5; + Wparam.topic.historyQos.kind = KEEP_LAST_HISTORY_QOS; Wparam.topic.historyQos.depth = 5; + Wparam.topic.resourceLimitsQos.allocated_samples = 15; + Wparam.topic.resourceLimitsQos.max_instances = 3; + Wparam.topic.resourceLimitsQos.max_samples_per_instance = 5; + Wparam.topic.resourceLimitsQos.max_samples = 3*5; Wparam.qos.m_reliability.kind= RELIABLE_RELIABILITY_QOS; + Wparam.qos.m_deadline.period = deadline_period_ms * 1e-3; mp_publisher = Domain::createPublisher(mp_participant,Wparam,(PublisherListener*)&m_listener); if(mp_publisher == nullptr) return false; + std::cout << "Publisher created, waiting for Subscribers." << std::endl; return true; } @@ -78,7 +90,12 @@ void deadlinepayloadPublisher::PubListener::onPublicationMatched(Publisher* /*pu } } -void deadlinepayloadPublisher::run() +void deadlinepayloadPublisher::PubListener::on_offered_deadline_missed(InstanceHandle_t &handle) +{ + std::cout << "Publisher listener: deadline missed for instance " << handle << std::endl; +} + +void deadlinepayloadPublisher::run(double sleep_ms) { while(m_listener.n_matched == 0) { @@ -93,19 +110,33 @@ void deadlinepayloadPublisher::run() stream << "generic payload"; st.payload(stream.str()); - /* Initialize your structure here */ - - while(true){ - eClock::my_sleep(900); - - //Send messages - for(unsigned short i=0;i<32;i++){ - st.deadlinekey(i); //Set key - if(i==15){ //Force key 15 message to be sent half of the times + while(true) + { + eClock::my_sleep(sleep_ms); + + // Send messages + for(unsigned short i=0;i<3;i++) + { + // Set key + st.deadlinekey(i); + if(i==2) + { + //Force key 2 message to be sent half of the times double_time = !double_time; - if(double_time) mp_publisher->write(&st); - }else{ - mp_publisher->write(&st); + if(double_time) + { + if (mp_publisher->write(&st)) + { + std::cout << "Message with key " << st.deadlinekey() << " sent" << std::endl; + } + } + } + else + { + if (mp_publisher->write(&st)) + { + std::cout << "Message with key " << st.deadlinekey() << " sent" << std::endl; + } } } } diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h index 896b2e1e571..1d6198d971b 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h @@ -20,30 +20,50 @@ #include "deadlinepayloadPubSubTypes.h" - - class deadlinepayloadPublisher { public: + + /** + * @brief Constructor + */ deadlinepayloadPublisher(); + + /** + * @brief Destructor + */ virtual ~deadlinepayloadPublisher(); - bool init(); - void run(); + + /** + * @brief Initialises publisher + * @param deadline_period_ms The deadline period in milliseconds + * @return True if initialised correctly + */ + bool init(double deadline_period_ms); + + /** + * @brief Run the publisher + * @param sleep_ms A time period to sleep for before sending the new sample + */ + void run(double sleep_ms); + private: + eprosima::fastrtps::Participant *mp_participant; eprosima::fastrtps::Publisher *mp_publisher; - - bool double_time; //Used to force a period double on a certain key - + HelloMsgPubSubType myType; class PubListener : public eprosima::fastrtps::PublisherListener { public: PubListener() : n_matched(0){}; ~PubListener(){}; - void onPublicationMatched(eprosima::fastrtps::Publisher* pub, eprosima::fastrtps::rtps::MatchingInfo& info); + void onPublicationMatched(eprosima::fastrtps::Publisher* pub, eprosima::fastrtps::rtps::MatchingInfo& info) override; + void on_offered_deadline_missed(eprosima::fastrtps::rtps::InstanceHandle_t& handle) override; int n_matched; } m_listener; - HelloMsgPubSubType myType; + + //!Boolean used to force a period double on a certain key + bool double_time; }; #endif // _DEADLINEPAYLOAD_PUBLISHER_H_ diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx index d8828e323e4..69ad2835a25 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx @@ -25,11 +25,19 @@ using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; -deadlinepayloadSubscriber::deadlinepayloadSubscriber(asio::steady_timer &timer,asio::io_service &ioserv) : mp_participant(nullptr), mp_subscriber(nullptr), m_listener(timer,ioserv) {} +deadlinepayloadSubscriber::deadlinepayloadSubscriber() + : mp_participant(nullptr) + , mp_subscriber(nullptr) + , m_listener() +{ +} -deadlinepayloadSubscriber::~deadlinepayloadSubscriber() { Domain::removeParticipant(mp_participant);} +deadlinepayloadSubscriber::~deadlinepayloadSubscriber() +{ + Domain::removeParticipant(mp_participant); +} -bool deadlinepayloadSubscriber::init() +bool deadlinepayloadSubscriber::init(double deadline_ms) { // Create RTPSParticipant @@ -51,10 +59,12 @@ bool deadlinepayloadSubscriber::init() Rparam.topic.topicKind = WITH_KEY; Rparam.topic.topicDataType = myType.getName(); //Must be registered before the creation of the subscriber Rparam.topic.topicName = "deadlinepayloadPubSubTopic"; - Rparam.topic.resourceLimitsQos.max_instances=32; + Rparam.topic.resourceLimitsQos.allocated_samples=15; + Rparam.topic.resourceLimitsQos.max_instances=3; Rparam.topic.resourceLimitsQos.max_samples_per_instance=5; - Rparam.topic.resourceLimitsQos.max_samples = 32*5; + Rparam.topic.resourceLimitsQos.max_samples = 3*5; Rparam.qos.m_reliability.kind= RELIABLE_RELIABILITY_QOS; + Rparam.qos.m_deadline.period = deadline_ms * 1e-3; Rparam.topic.historyQos.depth = 5; mp_subscriber = Domain::createSubscriber(mp_participant,Rparam,(SubscriberListener*)&m_listener); if(mp_subscriber == nullptr) @@ -79,28 +89,24 @@ void deadlinepayloadSubscriber::SubListener::onSubscriptionMatched(Subscriber* / void deadlinepayloadSubscriber::SubListener::onNewDataMessage(Subscriber* sub) { - // Take data HelloMsg st; - //InstanceHandle_t myHandle; - mapable_key handle; - if(sub->takeNextData(&st, &m_info)) + if(sub->readNextData(&st, &m_info)) { if(m_info.sampleKind == ALIVE) { - for(int i=0;i<16;i++) handle.value[i] = m_info.iHandle.value[i]; - myDeadline.setFlag(handle); + std::cout << "Message with key " << st.deadlinekey() << " received" << std::endl; } } } -void deadlinepayloadSubscriber::run() +void deadlinepayloadSubscriber::SubListener::on_requested_deadline_missed(InstanceHandle_t &handle) { + std::cout << "Subscriber listener: deadline missed for instance " << handle << std::endl; +} - m_listener.myDeadline.run(); - std::cout << "Waiting for Data, press Enter to stop the Subscriber. "< #include "deadlinepayloadPubSubTypes.h" -#include "deadlineQoS.h" -#include -#include #include "mapableKey.h" - - - class deadlinepayloadSubscriber { public: - deadlinepayloadSubscriber(asio::steady_timer &timer,asio::io_service &io_service); + + /** + * @brief Constructor + */ + deadlinepayloadSubscriber(); + + /** + * @brief Destructor + */ virtual ~deadlinepayloadSubscriber(); - bool init(); + + /** + * @brief Initialises the subscriber + * @param deadline_ms The deadline period in milliseconds + * @return True if initialised correctly + */ + bool init(double deadline_ms); + + /** + * @brief Runs the subscriber + */ void run(); + private: eprosima::fastrtps::Participant *mp_participant; eprosima::fastrtps::Subscriber *mp_subscriber; - //io_service &io; - class SubListener : public eprosima::fastrtps::SubscriberListener + HelloMsgPubSubType myType; + class SubListener : public eprosima::fastrtps::SubscriberListener { public: - SubListener(asio::steady_timer &timer, asio::io_service &ioserv) : n_matched(0),n_msg(0), myDeadline(timer,ioserv){}; + SubListener() : n_matched(0),n_msg(0){}; ~SubListener(){}; - void onSubscriptionMatched(eprosima::fastrtps::Subscriber* sub, eprosima::fastrtps::rtps::MatchingInfo& info); - void onNewDataMessage(eprosima::fastrtps::Subscriber* sub); + void onSubscriptionMatched(eprosima::fastrtps::Subscriber* sub, eprosima::fastrtps::rtps::MatchingInfo& info) override; + void onNewDataMessage(eprosima::fastrtps::Subscriber* sub) override; + void on_requested_deadline_missed(eprosima::fastrtps::rtps::InstanceHandle_t& handle) override; eprosima::fastrtps::SampleInfo_t m_info; int n_matched; int n_msg; - deadlineQoS myDeadline; - } m_listener; - HelloMsgPubSubType myType; }; #endif // _deadlinepayload_SUBSCRIBER_H_ From a42182d7adecf865066b690a0ba2c15d5a6ed452 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Thu, 28 Feb 2019 09:15:40 +0100 Subject: [PATCH 08/54] Refs #4693 Fixing a bug found in SubscriberHistory while testing deadline --- src/cpp/subscriber/SubscriberHistory.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index 14f5199f9ac..5cf5a5d318f 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -205,9 +205,9 @@ bool SubscriberHistory::received_change( } else { - // Try to substitude a older samples. - auto older_sample = m_changes.rend(); - for (auto it = m_changes.rbegin(); it != m_changes.rend(); ++it) + // Try to substitute the oldest sample with the same key + auto older_sample = vit->second.rend(); + for (auto it = vit->second.rbegin(); it != vit->second.rend(); ++it) { if ((*it)->writerGUID == a_change->writerGUID) @@ -220,7 +220,7 @@ bool SubscriberHistory::received_change( } } - if (older_sample != m_changes.rend()) + if (older_sample != vit->second.rend()) { bool read = (*older_sample)->isRead; From 40c40f9135d36a525adb09b15e4722c635873c27 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Thu, 28 Feb 2019 09:20:24 +0100 Subject: [PATCH 09/54] Refs #4693 Changing default parameters in deadline example --- examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx index 7130bffc6fd..e27e3d1efe8 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx @@ -28,7 +28,7 @@ int main(int argc, char** argv) std::cout << "Starting " << std::endl; int type = 1; int deadline = 1000; - int sleep = 100; + int sleep = 1000; if (argc > 1) { if (strcmp(argv[1], "publisher") == 0) From 98363022174c240932c3f5c85e6b12033eec70e2 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Thu, 28 Feb 2019 09:31:16 +0100 Subject: [PATCH 10/54] Refs #4693 Do not start the timer if all instances missed the deadline --- src/cpp/publisher/PublisherImpl.cpp | 15 +++++++++++---- src/cpp/subscriber/SubscriberImpl.cpp | 15 +++++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index bff4e1fdaec..69d7437f8a2 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -351,6 +351,9 @@ void PublisherImpl::check_deadlines() // Time of the earliest sample among all topic instances Time_t minTime = samples.front()->sourceTimestamp; + // Number of instances missing the deadline + int num_instances = 0; + for (const auto &sample : samples) { if (sample->sourceTimestamp < minTime) @@ -361,11 +364,15 @@ void PublisherImpl::check_deadlines() if (now - sample->sourceTimestamp > deadline_duration_ ) { mp_listener->on_offered_deadline_missed(sample->instanceHandle); + num_instances++; } } - // Now restart the timer - Duration_t interval = deadline_duration_ - now + minTime > 0? deadline_duration_ - now + minTime: deadline_duration_; - deadline_timer_.update_interval(interval); - deadline_timer_.restart_timer(); + if ((size_t)num_instances < samples.size()) + { + // Now restart the timer + Duration_t interval = deadline_duration_ - now + minTime > 0? deadline_duration_ - now + minTime: deadline_duration_; + deadline_timer_.update_interval(interval); + deadline_timer_.restart_timer(); + } } diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index 168d64af2dd..3111449f493 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -245,6 +245,9 @@ void SubscriberImpl::check_deadlines() // Time of the earliest sample among all topic instances Time_t minTime = samples.front()->sourceTimestamp; + // Number of instances missing the deadline + int num_instances = 0; + // Check if any instance missed the dealine for (const auto &sample : samples) { @@ -256,13 +259,17 @@ void SubscriberImpl::check_deadlines() if (now - sample->sourceTimestamp > deadline_duration_) { mp_listener->on_requested_deadline_missed(sample->instanceHandle); + num_instances++; } } - // Restart the timer - Duration_t interval = deadline_duration_ - now + minTime > 0? deadline_duration_ - now + minTime: deadline_duration_; - deadline_timer_.update_interval(interval); - deadline_timer_.restart_timer(); + if ((size_t)num_instances < samples.size()) + { + // Restart the timer + Duration_t interval = deadline_duration_ - now + minTime > 0? deadline_duration_ - now + minTime: deadline_duration_; + deadline_timer_.update_interval(interval); + deadline_timer_.restart_timer(); + } } } /* namespace fastrtps */ From 5b8771b94dab9aba842eaa8ad1a86605784d273a Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Thu, 28 Feb 2019 09:32:04 +0100 Subject: [PATCH 11/54] Refs #4693 Adding more options to the example to allow publisher to send only a certain number of samples --- .../deadlinepayloadPubSubMain.cxx | 7 ++++++- .../DeadlineQoSExample/deadlinepayloadPublisher.cxx | 13 ++++++++++++- .../DeadlineQoSExample/deadlinepayloadPublisher.h | 3 ++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx index e27e3d1efe8..ba4fb0eb17d 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx @@ -29,6 +29,7 @@ int main(int argc, char** argv) int type = 1; int deadline = 1000; int sleep = 1000; + int samples = 0; if (argc > 1) { if (strcmp(argv[1], "publisher") == 0) @@ -40,6 +41,10 @@ int main(int argc, char** argv) if (argc > 3) { sleep = atoi(argv[3]); + if (argc > 4) + { + samples = atoi(argv[4]); + } } } } @@ -68,7 +73,7 @@ int main(int argc, char** argv) deadlinepayloadPublisher mypub; if (mypub.init(deadline)) { - mypub.run(sleep); + mypub.run(sleep, samples); } break; } diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx index cdc76cc373b..418e24ac964 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx @@ -95,7 +95,7 @@ void deadlinepayloadPublisher::PubListener::on_offered_deadline_missed(InstanceH std::cout << "Publisher listener: deadline missed for instance " << handle << std::endl; } -void deadlinepayloadPublisher::run(double sleep_ms) +void deadlinepayloadPublisher::run(double sleep_ms, int samples) { while(m_listener.n_matched == 0) { @@ -110,10 +110,21 @@ void deadlinepayloadPublisher::run(double sleep_ms) stream << "generic payload"; st.payload(stream.str()); + int sample = 0; while(true) { eClock::my_sleep(sleep_ms); + if (samples > 0) + { + if (sample == samples) + { + // Stop sending samples but keep the publisher running + continue; + } + sample++; + } + // Send messages for(unsigned short i=0;i<3;i++) { diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h index 1d6198d971b..6f3eeead86d 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h @@ -44,8 +44,9 @@ class deadlinepayloadPublisher /** * @brief Run the publisher * @param sleep_ms A time period to sleep for before sending the new sample + * @param samples The number of samples per instance to send. If set to 0 sends sample indefinitely */ - void run(double sleep_ms); + void run(double sleep_ms, int samples); private: From 26ae8de9831b7fd1d0ac0760490b833daa75e8ee Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Thu, 28 Feb 2019 10:48:24 +0100 Subject: [PATCH 12/54] Refs #4693 Refactoring Publisher(Subscriber)History to avoid reserving memory for vector of latest samples --- include/fastrtps/publisher/PublisherHistory.h | 7 +++-- .../fastrtps/subscriber/SubscriberHistory.h | 7 +++-- src/cpp/publisher/PublisherHistory.cpp | 20 +++++++++----- src/cpp/publisher/PublisherImpl.cpp | 25 +++++++++++------- src/cpp/publisher/PublisherImpl.h | 2 ++ src/cpp/subscriber/SubscriberHistory.cpp | 20 +++++++++----- src/cpp/subscriber/SubscriberImpl.cpp | 26 +++++++++++-------- src/cpp/subscriber/SubscriberImpl.h | 2 ++ 8 files changed, 72 insertions(+), 37 deletions(-) diff --git a/include/fastrtps/publisher/PublisherHistory.h b/include/fastrtps/publisher/PublisherHistory.h index bce012211f8..3102e6a67c2 100644 --- a/include/fastrtps/publisher/PublisherHistory.h +++ b/include/fastrtps/publisher/PublisherHistory.h @@ -97,9 +97,12 @@ class PublisherHistory:public rtps::WriterHistory /** * Returns the latest sample for each topic key - * @param samples A vector containing the latest samples + * @param samples A vector where the the latest sample for each key will be placed. Must be long enough + * @param num_samples The number of samples in the vector */ - void get_latest_samples(std::vector &samples); + void get_latest_samples( + std::vector &samples, + int& num_samples); private: //!Map where keys are instance handles and values are vectors of cache changes associated diff --git a/include/fastrtps/subscriber/SubscriberHistory.h b/include/fastrtps/subscriber/SubscriberHistory.h index 23acd85d542..d249196e27f 100644 --- a/include/fastrtps/subscriber/SubscriberHistory.h +++ b/include/fastrtps/subscriber/SubscriberHistory.h @@ -121,9 +121,12 @@ class SubscriberHistory: public rtps::ReaderHistory /** * A method that resturns the latest sample for each topic key - * @param samples A vector containing the latest sample for each key + * @param samples A vector where the latest sample for each key will be placed. Must be long enough + * @param num_samples The number of samples in the vector */ - void get_latest_samples(std::vector& samples); + void get_latest_samples( + std::vector& samples, + int& num_samples); private: diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index 1402cd95863..97c4cdbcc53 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -274,29 +274,37 @@ bool PublisherHistory::remove_change_g(CacheChange_t* a_change) return remove_change_pub(a_change); } -void PublisherHistory::get_latest_samples(std::vector &samples) +void PublisherHistory::get_latest_samples(std::vector &samples, int& num_samples) { - samples.clear(); + num_samples = 0; if (mp_pubImpl->getAttributes().topic.getTopicKind() == NO_KEY) { - samples.reserve(1); + if (samples.size() < 1) + { + logError(PUBLISHER, "Cannot return latest sample, output vector is not long enough"); + return; + } auto max = *std::max_element( m_changes.begin(), m_changes.end(), [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); - samples.push_back(max); + samples[num_samples++] = max; } else if (mp_pubImpl->getAttributes().topic.getTopicKind() == WITH_KEY) { - samples.reserve(m_keyedChanges.size()); + if (samples.size() < m_keyedChanges.size()) + { + logError(PUBLISHER, "Cannot return latest samples, output vector is not long enough"); + return; + } for (auto it = m_keyedChanges.begin(); it != m_keyedChanges.end(); ++it) { auto max = *std::max_element( it->second.begin(), it->second.end(), [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); - samples.push_back(max); + samples[num_samples++] = max; } } } diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index 69d7437f8a2..99a07b786f2 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -67,7 +67,12 @@ PublisherImpl::PublisherImpl( mp_participant->get_resource_event().getIOService(), mp_participant->get_resource_event().getThread()) , deadline_duration_(att.qos.m_deadline.period) + , deadline_samples_() { + if (att.qos.m_deadline.period != c_TimeInfinite) + { + deadline_samples_.resize(att.topic.getTopicKind() == NO_KEY? 1: att.topic.resourceLimitsQos.max_instances); + } } PublisherImpl::~PublisherImpl() @@ -340,35 +345,35 @@ void PublisherImpl::check_deadlines() auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); // Get the latest samples from the history - std::vector samples; - m_history.get_latest_samples(samples); + int num_samples = 0; + m_history.get_latest_samples(deadline_samples_, num_samples); - if (samples.empty()) + if (num_samples == 0) { return; } // Time of the earliest sample among all topic instances - Time_t minTime = samples.front()->sourceTimestamp; + Time_t minTime = deadline_samples_.front()->sourceTimestamp; // Number of instances missing the deadline int num_instances = 0; - for (const auto &sample : samples) + for (int i = 0; i < num_samples; i++) { - if (sample->sourceTimestamp < minTime) + if (deadline_samples_[i]->sourceTimestamp < minTime) { - minTime = sample->sourceTimestamp; + minTime = deadline_samples_[i]->sourceTimestamp; } - if (now - sample->sourceTimestamp > deadline_duration_ ) + if (now - deadline_samples_[i]->sourceTimestamp > deadline_duration_ ) { - mp_listener->on_offered_deadline_missed(sample->instanceHandle); + mp_listener->on_offered_deadline_missed(deadline_samples_[i]->instanceHandle); num_instances++; } } - if ((size_t)num_instances < samples.size()) + if (num_instances < num_samples) { // Now restart the timer Duration_t interval = deadline_duration_ - now + minTime > 0? deadline_duration_ - now + minTime: deadline_duration_; diff --git a/src/cpp/publisher/PublisherImpl.h b/src/cpp/publisher/PublisherImpl.h index 878c2d6f2c8..fd5d998ed58 100644 --- a/src/cpp/publisher/PublisherImpl.h +++ b/src/cpp/publisher/PublisherImpl.h @@ -161,6 +161,8 @@ class PublisherImpl DeadlineTimer deadline_timer_; //! Deadline duration Duration_t deadline_duration_; + //! A vector to store the latest samples to check for deadlines + std::vector deadline_samples_; /** Method to check for deadlines */ diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index 5cf5a5d318f..628c4227400 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -549,29 +549,37 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change) return false; } -void SubscriberHistory::get_latest_samples(std::vector &samples) +void SubscriberHistory::get_latest_samples(std::vector &samples, int &num_samples) { - samples.clear(); + num_samples = 0; if (mp_subImpl->getAttributes().topic.getTopicKind() == NO_KEY) { - samples.reserve(1); + if (samples.size() < 1) + { + logError(SUBSCRIBER, "Cannot return latest sample, output vector is not long enough"); + return; + } auto max = *std::max_element( m_changes.begin(), m_changes.end(), [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); - samples.push_back(max); + samples[num_samples++] = max; } else if (mp_subImpl->getAttributes().topic.getTopicKind() == WITH_KEY) { - samples.reserve(m_keyedChanges.size()); + if (samples.size() < m_keyedChanges.size()) + { + logError(SUBSCRIBER, "Cannot return latest samples, output vector is not long enough"); + return; + } for (auto it = m_keyedChanges.begin(); it != m_keyedChanges.end(); ++it) { auto max = *std::max_element( it->second.begin(), it->second.end(), [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); - samples.push_back(max); + samples[num_samples++] = max; } } } diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index 3111449f493..abc75ab506d 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -58,9 +58,13 @@ SubscriberImpl::SubscriberImpl( mp_participant->get_resource_event().getIOService(), mp_participant->get_resource_event().getThread()) , deadline_duration_(att.qos.m_deadline.period) + , deadline_samples_(att.topic.resourceLimitsQos.max_instances) +{ + if (att.qos.m_deadline.period != c_TimeInfinite) { + deadline_samples_.resize(att.topic.getTopicKind() == NO_KEY? 1: att.topic.resourceLimitsQos.max_instances); } - +} SubscriberImpl::~SubscriberImpl() { @@ -234,36 +238,36 @@ void SubscriberImpl::check_deadlines() auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); // Get the latest samples from the history - std::vector samples; - m_history.get_latest_samples(samples); + int num_samples = 0; + m_history.get_latest_samples(deadline_samples_, num_samples); - if (samples.empty()) + if (num_samples == 0) { return; } // Time of the earliest sample among all topic instances - Time_t minTime = samples.front()->sourceTimestamp; + Time_t minTime = deadline_samples_.front()->sourceTimestamp; // Number of instances missing the deadline int num_instances = 0; // Check if any instance missed the dealine - for (const auto &sample : samples) + for (int i = 0; i < num_samples; ++i) { - if (sample->sourceTimestamp < minTime) + if (deadline_samples_[i]->sourceTimestamp < minTime) { - minTime = sample->sourceTimestamp; + minTime = deadline_samples_[i]->sourceTimestamp; } - if (now - sample->sourceTimestamp > deadline_duration_) + if (now - deadline_samples_[i]->sourceTimestamp > deadline_duration_) { - mp_listener->on_requested_deadline_missed(sample->instanceHandle); + mp_listener->on_requested_deadline_missed(deadline_samples_[i]->instanceHandle); num_instances++; } } - if ((size_t)num_instances < samples.size()) + if (num_instances < num_samples) { // Restart the timer Duration_t interval = deadline_duration_ - now + minTime > 0? deadline_duration_ - now + minTime: deadline_duration_; diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index a599329ebb3..00267c2de7f 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -159,6 +159,8 @@ class SubscriberImpl { DeadlineTimer deadline_timer_; //!Deadline duration Duration_t deadline_duration_; + //!A vector storing the latest samples to check for deadline + std::vector deadline_samples_; /** A method to check for deadlines */ From 80d0493fe73a714583756f50158fdc2ac18d6b84 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Fri, 1 Mar 2019 11:38:58 +0100 Subject: [PATCH 13/54] Refs #4693 Removing unused class deadlineQoS --- .../C++/DeadlineQoSExample/deadlineQoS.cxx | 92 ------------------- examples/C++/DeadlineQoSExample/deadlineQoS.h | 68 -------------- 2 files changed, 160 deletions(-) delete mode 100644 examples/C++/DeadlineQoSExample/deadlineQoS.cxx delete mode 100644 examples/C++/DeadlineQoSExample/deadlineQoS.h diff --git a/examples/C++/DeadlineQoSExample/deadlineQoS.cxx b/examples/C++/DeadlineQoSExample/deadlineQoS.cxx deleted file mode 100644 index 4199ad721fb..00000000000 --- a/examples/C++/DeadlineQoSExample/deadlineQoS.cxx +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include - -#include "deadlineQoS.h" -#include - -using namespace asio; -using namespace eprosima; -using namespace eprosima::fastrtps; - -void deadlineQoS::callback() -{ - mapmtx.lock(); - std::cout << "Map holds " << deadlineQoSmap.size() << " different keys" << std::endl; - for(auto it = deadlineQoSmap.begin(); it != deadlineQoSmap.end(); it++){ - - if(it->second == false){ - std::cout << "Deadline QoS on key index "; - std::cout << static_cast(it->first.value[1]); - std::cout << " missed." << std::endl; - } - //After checking the value, reset flag to zero - it->second = false; - } - mapmtx.unlock(); - wait(); -} - -void deadlineQoS::wait() -{ - t.expires_from_now(std::chrono::seconds(1)); //repeat rate here - t.async_wait(std::bind(&deadlineQoS::callback, this)); -} - -void deadlineQoS::setFlag(mapable_key target) -{ - mapmtx.lock(); - if(deadlineQoSmap.find(target)!=deadlineQoSmap.end()){ - //Exists - deadlineQoSmap.at(target)=true; - }else{ - //Does not exist - deadlineQoSmap.insert(std::pair(target,true)); - } - //deadlineQoSmap.[target]=true; - mapmtx.unlock(); - //if(index<32){ - // deadlineQoSlist[index].mtx.lock(); - // deadlineQoSlist[index].flag = true; - // deadlineQoSlist[index].mtx.unlock(); - //} -} - -void deadlineQoS::init(){ - //Not really needed now - std::cout << "Deadline QoS Service started" << std::endl; - //for(int i=0;i<32;i++){ - // deadlineQoSlist[i].mtx.lock(); - // deadlineQoSlist[i].flag = false; - // deadlineQoSlist[i].mtx.unlock(); - //} -} - -void deadlineQoS::runner(){ - wait(); - - io.run(); -} - -void deadlineQoS::run(){ - dlqos = new std::thread(std::bind(&deadlineQoS::runner,this)); -} - -void deadlineQoS::stop(){ - t.cancel(); - io.stop(); - dlqos->join(); -} diff --git a/examples/C++/DeadlineQoSExample/deadlineQoS.h b/examples/C++/DeadlineQoSExample/deadlineQoS.h deleted file mode 100644 index 89d1a7f0e96..00000000000 --- a/examples/C++/DeadlineQoSExample/deadlineQoS.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/* DeadlineQoS - - Helper class to implement a way to check if the deadline constrains is being met on each key - of the topic at hand. - -*/ - - -#ifndef _DEADLINEQOS_H_ -#define _DEADLINEQOS_H_ - -#include -#include -#include -#include - -#include - -#include -#include -#include "mapableKey.h" -#include -#include -#include - -class deadlineQoS -{ - public: - deadlineQoS(asio::steady_timer &timer, asio::io_service &ioserv): t(timer),io(ioserv){ - init(); - } - ~deadlineQoS(){ - delete dlqos; - } - void callback(); - void setFlag(mapable_key target); - - void run(); - void stop(); - //deadlineQoS_struct deadlineQoSlist[32]; - std::map deadlineQoSmap; - std::mutex mapmtx; - private: - asio::steady_timer &t; - asio::io_service &io; - std::thread* dlqos; - void runner(); - void init(); - void wait(); -}; - - - -#endif From 3b0069c126b0de734baa8f00e74bebb57e4cb3a3 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Tue, 5 Mar 2019 15:35:28 +0100 Subject: [PATCH 14/54] Refs #4693 History could be empty, fixing get_latest_samples() in Publisher/SubscriberHistory --- src/cpp/publisher/PublisherHistory.cpp | 12 ++++++++++++ src/cpp/subscriber/SubscriberHistory.cpp | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index 97c4cdbcc53..ffa3621a53c 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -285,6 +285,12 @@ void PublisherHistory::get_latest_samples(std::vector &samples, logError(PUBLISHER, "Cannot return latest sample, output vector is not long enough"); return; } + + if (m_changes.empty()) + { + return; + } + auto max = *std::max_element( m_changes.begin(), m_changes.end(), @@ -298,6 +304,12 @@ void PublisherHistory::get_latest_samples(std::vector &samples, logError(PUBLISHER, "Cannot return latest samples, output vector is not long enough"); return; } + + if (m_keyedChanges.empty()) + { + return; + } + for (auto it = m_keyedChanges.begin(); it != m_keyedChanges.end(); ++it) { auto max = *std::max_element( diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index 628c4227400..7323442d487 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -560,6 +560,12 @@ void SubscriberHistory::get_latest_samples(std::vector &samples logError(SUBSCRIBER, "Cannot return latest sample, output vector is not long enough"); return; } + + if (m_changes.empty()) + { + return; + } + auto max = *std::max_element( m_changes.begin(), m_changes.end(), @@ -573,6 +579,12 @@ void SubscriberHistory::get_latest_samples(std::vector &samples logError(SUBSCRIBER, "Cannot return latest samples, output vector is not long enough"); return; } + + if (m_keyedChanges.empty()) + { + return; + } + for (auto it = m_keyedChanges.begin(); it != m_keyedChanges.end(); ++it) { auto max = *std::max_element( From e79416828c15c4b41a80656d120e125db0dfe0bc Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 6 Mar 2019 07:11:05 +0100 Subject: [PATCH 15/54] Refs #4693 Adding blackbox tests --- test/blackbox/BlackboxTests.hpp | 5 + test/blackbox/BlackboxTestsDeadlineQos.cpp | 201 ++++++++++++++++++ test/blackbox/CMakeLists.txt | 2 + test/blackbox/PubSubReader.hpp | 58 ++++- test/blackbox/PubSubWriter.hpp | 54 ++++- test/blackbox/types/KeyedHelloWorld.cpp | 134 ++++++++++++ test/blackbox/types/KeyedHelloWorld.h | 222 ++++++++++++++++++++ test/blackbox/types/KeyedHelloWorldType.cpp | 125 +++++++++++ test/blackbox/types/KeyedHelloWorldType.h | 50 +++++ test/blackbox/utils/data_generators.cpp | 18 ++ test/blackbox/utils/lambda_functions.cpp | 5 + 11 files changed, 865 insertions(+), 9 deletions(-) create mode 100644 test/blackbox/BlackboxTestsDeadlineQos.cpp create mode 100644 test/blackbox/types/KeyedHelloWorld.cpp create mode 100644 test/blackbox/types/KeyedHelloWorld.h create mode 100644 test/blackbox/types/KeyedHelloWorldType.cpp create mode 100644 test/blackbox/types/KeyedHelloWorldType.h diff --git a/test/blackbox/BlackboxTests.hpp b/test/blackbox/BlackboxTests.hpp index a1bca486c8e..46827b3c2c5 100644 --- a/test/blackbox/BlackboxTests.hpp +++ b/test/blackbox/BlackboxTests.hpp @@ -43,6 +43,7 @@ #include "types/HelloWorldType.h" #include "types/FixedSizedType.h" +#include "types/KeyedHelloWorldType.h" #include "types/StringType.h" #include "types/Data64kbType.h" #include "types/Data1mbType.h" @@ -111,6 +112,8 @@ std::list default_helloworld_data_generator(size_t max = 0); std::list default_fixed_sized_data_generator(size_t max = 0); +std::list default_keyedhelloworld_data_generator(size_t max = 0); + std::list default_large_string_data_generator(size_t max = 0); std::list default_data64kb_data_generator(size_t max = 0); @@ -124,6 +127,8 @@ extern const std::function default_helloworld_print; extern const std::function default_fixed_sized_print; +extern const std::function default_keyedhelloworld_print; + extern const std::function default_string_print; extern const std::function default_data64kb_print; diff --git a/test/blackbox/BlackboxTestsDeadlineQos.cpp b/test/blackbox/BlackboxTestsDeadlineQos.cpp new file mode 100644 index 00000000000..a29f18e0940 --- /dev/null +++ b/test/blackbox/BlackboxTestsDeadlineQos.cpp @@ -0,0 +1,201 @@ +// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "BlackboxTests.hpp" + +#include "PubSubReader.hpp" +#include "PubSubWriter.hpp" +#include "ReqRepAsReliableHelloWorldRequester.hpp" +#include "ReqRepAsReliableHelloWorldReplier.hpp" + +#include + +using namespace eprosima::fastrtps; +using namespace eprosima::fastrtps::rtps; + +BLACKBOXTEST(DeadlineQos, NoKeyTopicLongDeadline) +{ + PubSubReader reader(TEST_TOPIC_NAME); + PubSubWriter writer(TEST_TOPIC_NAME); + + // Rate at which writer sends data in ms + uint32_t writer_sleep_ms = 100; + // Number of samples written by writer + uint32_t writer_samples = 3; + // Deadline period in ms (long in comparison to the rate at which samples are written) + eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 2 * 1e-3); + + reader.deadline_period(deadline_s); + writer.deadline_period(deadline_s); + reader.init(); + writer.init(); + + ASSERT_TRUE(reader.isInitialized()); + ASSERT_TRUE(writer.isInitialized()); + + // Wait for discovery. + writer.wait_discovery(); + reader.wait_discovery(); + + auto data = default_helloworld_data_generator(writer_samples); + + reader.startReception(data); + + size_t count = 0; + for (auto data_sample : data) + { + // Send data + writer.send_sample(data_sample); + ++count; + reader.block_for_at_least(count); + std::this_thread::sleep_for(std::chrono::milliseconds(writer_sleep_ms)); + } + + EXPECT_EQ(writer.missed_deadlines(), 0); + EXPECT_EQ(reader.missed_deadlines(), 0); +} + +BLACKBOXTEST(DeadlineQos, NoKeyTopicShortDeadline) +{ + PubSubReader reader(TEST_TOPIC_NAME); + PubSubWriter writer(TEST_TOPIC_NAME); + + // Rate at which writer sends data in ms + uint32_t writer_sleep_ms = 500; + // Number of samples written by writer + uint32_t writer_samples = 3; + // Deadline period in ms (short in comparison to the rate at which samples are written) + eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 0.1 * 1e-3); + + reader.deadline_period(deadline_s); + writer.deadline_period(deadline_s); + reader.init(); + writer.init(); + + ASSERT_TRUE(reader.isInitialized()); + ASSERT_TRUE(writer.isInitialized()); + + // Wait for discovery. + writer.wait_discovery(); + reader.wait_discovery(); + + auto data = default_helloworld_data_generator(writer_samples); + + reader.startReception(data); + + size_t count = 0; + for (auto data_sample : data) + { + // Send data + writer.send_sample(data_sample); + ++count; + reader.block_for_at_least(count); + + std::this_thread::sleep_for(std::chrono::milliseconds(writer_sleep_ms)); + } + + // All samples should have missed the deadline + EXPECT_EQ(writer.missed_deadlines(), writer_samples); + EXPECT_EQ(reader.missed_deadlines(), writer_samples); +} + +BLACKBOXTEST(DeadlineQos, KeyedTopicLongDeadline) +{ + PubSubReader reader(TEST_TOPIC_NAME); + PubSubWriter writer(TEST_TOPIC_NAME); + + // Rate at which writer sends data in ms + uint32_t writer_sleep_ms = 100; + // Number of samples written by writer + uint32_t writer_samples = 4; + // Deadline period in ms (long compared to rate at which samples are written) + eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 2 * 1e-3); + + reader.deadline_period(deadline_s); + writer.deadline_period(deadline_s); + reader.key(true); + writer.key(true); + reader.init(); + writer.init(); + + ASSERT_TRUE(reader.isInitialized()); + ASSERT_TRUE(writer.isInitialized()); + + // Wait for discovery. + writer.wait_discovery(); + reader.wait_discovery(); + + auto data = default_keyedhelloworld_data_generator(writer_samples); + + reader.startReception(data); + + size_t count = 0; + for (auto data_sample : data) + { + // Send data + data_sample.key(count % 2); + writer.send_sample(data_sample); + ++count; + reader.block_for_at_least(count); + std::this_thread::sleep_for(std::chrono::milliseconds(writer_sleep_ms)); + } + + EXPECT_EQ(writer.missed_deadlines(), 0); + EXPECT_EQ(reader.missed_deadlines(), 0); +} + +BLACKBOXTEST(DeadlineQos, KeyedTopicShortDeadline) +{ + PubSubReader reader(TEST_TOPIC_NAME); + PubSubWriter writer(TEST_TOPIC_NAME); + + // Rate at which writer sends data in ms + uint32_t writer_sleep_ms = 1000; + // Number of samples written by writer + uint32_t writer_samples = 4; + // Deadline period in ms (short compared to rate at which samples are written) + eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 0.1 * 1e-3); + + reader.deadline_period(deadline_s); + writer.deadline_period(deadline_s); + reader.key(true); + writer.key(true); + reader.init(); + writer.init(); + + ASSERT_TRUE(reader.isInitialized()); + ASSERT_TRUE(writer.isInitialized()); + + // Wait for discovery. + writer.wait_discovery(); + reader.wait_discovery(); + + auto data = default_keyedhelloworld_data_generator(writer_samples); + + reader.startReception(data); + + size_t count = 0; + for (auto data_sample : data) + { + // Send data + data_sample.key(count % 2); + writer.send_sample(data_sample); + ++count; + reader.block_for_at_least(count); + std::this_thread::sleep_for(std::chrono::milliseconds(writer_sleep_ms)); + } + + EXPECT_EQ(writer.missed_deadlines(), 0); + EXPECT_EQ(reader.missed_deadlines(), 0); +} diff --git a/test/blackbox/CMakeLists.txt b/test/blackbox/CMakeLists.txt index 289f23c7aa7..b5a7a64f2e1 100644 --- a/test/blackbox/CMakeLists.txt +++ b/test/blackbox/CMakeLists.txt @@ -101,6 +101,8 @@ if(NOT ((MSVC OR MSVC_IDE) AND EPROSIMA_INSTALLER) AND fastcdr_FOUND) set(BLACKBOXTESTS_SOURCE ${BLACKBOXTESTS_TEST_SOURCE} types/HelloWorld.cpp types/HelloWorldType.cpp + types/KeyedHelloWorld.cpp + types/KeyedHelloWorldType.cpp types/String.cpp types/StringType.cpp types/Data64kb.cpp diff --git a/test/blackbox/PubSubReader.hpp b/test/blackbox/PubSubReader.hpp index 165d2929304..afe2be9cf6f 100644 --- a/test/blackbox/PubSubReader.hpp +++ b/test/blackbox/PubSubReader.hpp @@ -106,7 +106,10 @@ class PubSubReader class Listener: public eprosima::fastrtps::SubscriberListener { public: - Listener(PubSubReader &reader) : reader_(reader) {} + Listener(PubSubReader &reader) + : reader_(reader) + , times_deadline_missed_(0) + {} ~Listener(){} @@ -138,21 +141,43 @@ class PubSubReader } } + void on_requested_deadline_missed(eprosima::fastrtps::rtps::InstanceHandle_t&) override + { + times_deadline_missed_++; + } + + int missed_deadlines() const + { + return times_deadline_missed_; + } + private: Listener& operator=(const Listener&) = delete; PubSubReader& reader_; + + int times_deadline_missed_; } listener_; friend class Listener; public: - PubSubReader(const std::string& topic_name) : participant_listener_(*this), listener_(*this), - participant_(nullptr), subscriber_(nullptr), topic_name_(topic_name), initialized_(false), - matched_(0), participant_matched_(0), receiving_(false), current_received_count_(0), - number_samples_expected_(0), discovery_result_(false), onDiscovery_(nullptr) + PubSubReader(const std::string& topic_name) + : participant_listener_(*this), + listener_(*this), + participant_(nullptr), + subscriber_(nullptr), + topic_name_(topic_name), + initialized_(false), + matched_(0), + participant_matched_(0), + receiving_(false), + current_received_count_(0), + number_samples_expected_(0), + discovery_result_(false), + onDiscovery_(nullptr) #if HAVE_SECURITY , authorized_(0), unauthorized_(0) #endif @@ -354,6 +379,24 @@ class PubSubReader return *this; } + PubSubReader& deadline_period(const eprosima::fastrtps::rtps::Duration_t deadline_period) + { + subscriber_attr_.qos.m_deadline.period = deadline_period; + return *this; + } + + PubSubReader& key(bool keyed) + { + subscriber_attr_.topic.topicKind = keyed ? eprosima::fastrtps::TopicKind_t::WITH_KEY : eprosima::fastrtps::TopicKind_t::NO_KEY; + return *this; + } + + PubSubReader& topic_kind(const eprosima::fastrtps::rtps::TopicKind_t kind) + { + subscriber_attr_.topic.topicKind = kind; + return *this; + } + PubSubReader& history_kind(const eprosima::fastrtps::HistoryQosPolicyKind kind) { subscriber_attr_.topic.historyQos.kind = kind; @@ -623,6 +666,11 @@ class PubSubReader return matched_ > 0; } + int missed_deadlines() const + { + return listener_.missed_deadlines(); + } + private: void receive_one(eprosima::fastrtps::Subscriber* subscriber, bool& returnedValue) diff --git a/test/blackbox/PubSubWriter.hpp b/test/blackbox/PubSubWriter.hpp index da0ed994499..f49a19be789 100644 --- a/test/blackbox/PubSubWriter.hpp +++ b/test/blackbox/PubSubWriter.hpp @@ -41,6 +41,7 @@ #include #include #include +#include using eprosima::fastrtps::rtps::IPLocator; using eprosima::fastrtps::UDPv4TransportDescriptor; @@ -132,7 +133,10 @@ class PubSubWriter { public: - Listener(PubSubWriter &writer) : writer_(writer){}; + Listener(PubSubWriter &writer) + : writer_(writer) + , times_deadline_missed_(0) + {}; ~Listener(){}; @@ -150,12 +154,24 @@ class PubSubWriter } } + void on_offered_deadline_missed(eprosima::fastrtps::rtps::InstanceHandle_t&) + { + times_deadline_missed_++; + } + + int missed_deadlines() const + { + return times_deadline_missed_; + } + private: Listener& operator=(const Listener&) = delete; PubSubWriter &writer_; + int times_deadline_missed_; + } listener_; public: @@ -163,9 +179,16 @@ class PubSubWriter typedef TypeSupport type_support; typedef typename type_support::type type; - PubSubWriter(const std::string &topic_name) : participant_listener_(*this), listener_(*this), - participant_(nullptr), publisher_(nullptr), initialized_(false), matched_(0), - participant_matched_(0), discovery_result_(false), onDiscovery_(nullptr) + PubSubWriter(const std::string &topic_name) + : participant_listener_(*this) + , listener_(*this) + , participant_(nullptr) + , publisher_(nullptr) + , initialized_(false) + , matched_(0) + , participant_matched_(0) + , discovery_result_(false) + , onDiscovery_(nullptr) #if HAVE_SECURITY , authorized_(0), unauthorized_(0) #endif @@ -366,6 +389,18 @@ class PubSubWriter return *this; } + PubSubWriter& deadline_period(const eprosima::fastrtps::rtps::Duration_t deadline_period) + { + publisher_attr_.qos.m_deadline.period = deadline_period; + return *this; + } + + PubSubWriter& key(bool keyed) + { + publisher_attr_.topic.topicKind = keyed ? eprosima::fastrtps::TopicKind_t::WITH_KEY : eprosima::fastrtps::TopicKind_t::NO_KEY; + return *this; + } + PubSubWriter& max_blocking_time(const eprosima::fastrtps::rtps::Duration_t time) { publisher_attr_.qos.m_reliability.max_blocking_time = time; @@ -398,6 +433,12 @@ class PubSubWriter return *this; } + PubSubWriter& topic_kind(const eprosima::fastrtps::rtps::TopicKind_t kind) + { + publisher_attr_.topic.topicKind = kind; + return *this; + } + PubSubWriter& disable_builtin_transport() { participant_attr_.rtps.useBuiltinTransports = false; @@ -662,6 +703,11 @@ class PubSubWriter return matched_ > 0; } + int missed_deadlines() const + { + return listener_.missed_deadlines(); + } + private: void participant_matched() diff --git a/test/blackbox/types/KeyedHelloWorld.cpp b/test/blackbox/types/KeyedHelloWorld.cpp new file mode 100644 index 00000000000..c0c55a11c23 --- /dev/null +++ b/test/blackbox/types/KeyedHelloWorld.cpp @@ -0,0 +1,134 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file deadlinepayload.cpp + * This source file contains the definition of the described types in the IDL file. + * + * This file was generated by the tool gen. + */ + +#ifdef _WIN32 +// Remove linker warning LNK4221 on Visual Studio +namespace { char dummy; } +#endif + +#include "KeyedHelloWorld.h" + +#include + +#include +using namespace eprosima::fastcdr::exception; + +#include + +KeyedHelloWorld::KeyedHelloWorld() +{ + m_key = 0; + +} + +KeyedHelloWorld::~KeyedHelloWorld() +{ +} + +KeyedHelloWorld::KeyedHelloWorld(const KeyedHelloWorld &x) +{ + m_key = x.m_key; + m_message = x.m_message; +} + +KeyedHelloWorld::KeyedHelloWorld(KeyedHelloWorld &&x) +{ + m_key = x.m_key; + m_message = std::move(x.m_message); +} + +KeyedHelloWorld& KeyedHelloWorld::operator=(const KeyedHelloWorld &x) +{ + m_key = x.m_key; + m_message = x.m_message; + + return *this; +} + +KeyedHelloWorld& KeyedHelloWorld::operator=(KeyedHelloWorld &&x) +{ + m_key = x.m_key; + m_message = std::move(x.m_message); + + return *this; +} + +bool KeyedHelloWorld::operator==(const KeyedHelloWorld &x) const +{ + if(m_message == x.m_message && + m_key == x.m_key) + return true; + + return false; +} + +size_t KeyedHelloWorld::getMaxCdrSerializedSize(size_t current_alignment) +{ + size_t initial_alignment = current_alignment; + current_alignment += 2 + eprosima::fastcdr::Cdr::alignment(current_alignment, 2); + current_alignment += 4 + eprosima::fastcdr::Cdr::alignment(current_alignment, 4) + 256 + 1; + return current_alignment - initial_alignment; +} + +size_t KeyedHelloWorld::getCdrSerializedSize(const KeyedHelloWorld& data, size_t current_alignment) +{ + size_t initial_alignment = current_alignment; + current_alignment += 2 + eprosima::fastcdr::Cdr::alignment(current_alignment, 2); + current_alignment += 4 + eprosima::fastcdr::Cdr::alignment(current_alignment, 4) + data.message().size() + 1; + return current_alignment - initial_alignment; +} + +void KeyedHelloWorld::serialize(eprosima::fastcdr::Cdr &scdr) const +{ + scdr << m_key; + + if(m_message.length() <= 256) + { + scdr << m_message; + } + else + { + throw eprosima::fastcdr::exception::BadParamException("payload field exceeds the maximum length"); + } +} + +void KeyedHelloWorld::deserialize(eprosima::fastcdr::Cdr &dcdr) +{ + dcdr >> m_key; + dcdr >> m_message; +} + +size_t KeyedHelloWorld::getKeyMaxCdrSerializedSize(size_t current_alignment) +{ + size_t current_align = current_alignment; + current_align += 2 + eprosima::fastcdr::Cdr::alignment(current_align, 2); + return current_align; +} + +bool KeyedHelloWorld::isKeyDefined() +{ + return true; +} + +void KeyedHelloWorld::serializeKey(eprosima::fastcdr::Cdr &scdr) const +{ + scdr << m_key; +} diff --git a/test/blackbox/types/KeyedHelloWorld.h b/test/blackbox/types/KeyedHelloWorld.h new file mode 100644 index 00000000000..181731f5501 --- /dev/null +++ b/test/blackbox/types/KeyedHelloWorld.h @@ -0,0 +1,222 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file KeyedHelloWorld.h + * This header file contains the declaration of the described types in the IDL file. + * + */ + +#ifndef _KeyedHelloWorld_H_ +#define _KeyedHelloWorld_H_ + +#include +#include +#include +#include + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#define eProsima_user_DllExport __declspec( dllexport ) +#else +#define eProsima_user_DllExport +#endif +#else +#define eProsima_user_DllExport +#endif + +#if defined(_WIN32) +#if defined(EPROSIMA_USER_DLL_EXPORT) +#if defined(deadlinemessage_SOURCE) +#define deadlinemessage_DllAPI __declspec( dllexport ) +#else +#define deadlinemessage_DllAPI __declspec( dllimport ) +#endif // deadlinemessage_SOURCE +#else +#define deadlinemessage_DllAPI +#endif +#else +#define deadlinemessage_DllAPI +#endif // _WIN32 + +namespace eprosima +{ + namespace fastcdr + { + class Cdr; + } +} + +/*! + * @brief This class represents the structure KeyedHelloWorld defined by the user in the IDL file. + * @ingroup DEADLINEmessage + */ +class KeyedHelloWorld +{ +public: + + /*! + * @brief Default constructor. + */ + eProsima_user_DllExport KeyedHelloWorld(); + + /*! + * @brief Default destructor. + */ + eProsima_user_DllExport ~KeyedHelloWorld(); + + /*! + * @brief Copy constructor. + * @param x Reference to the object KeyedHelloWorld that will be copied. + */ + eProsima_user_DllExport KeyedHelloWorld(const KeyedHelloWorld &x); + + /*! + * @brief Move constructor. + * @param x Reference to the object KeyedHelloWorld that will be copied. + */ + eProsima_user_DllExport KeyedHelloWorld(KeyedHelloWorld &&x); + + /*! + * @brief Copy assignment. + * @param x Reference to the object KeyedHelloWorld that will be copied. + */ + eProsima_user_DllExport KeyedHelloWorld& operator=(const KeyedHelloWorld &x); + + /*! + * @brief Move assignment. + * @param x Reference to the object KeyedHelloWorld that will be copied. + */ + eProsima_user_DllExport KeyedHelloWorld& operator=(KeyedHelloWorld &&x); + + eProsima_user_DllExport bool operator==(const KeyedHelloWorld &x) const; + + /*! + * @brief This function sets a value in member deadlinekey + * @param _deadlinekey New value for member deadlinekey + */ + inline eProsima_user_DllExport void key(uint16_t _deadlinekey) + { + m_key = _deadlinekey; + } + + /*! + * @brief This function returns the value of member deadlinekey + * @return Value of member deadlinekey + */ + inline eProsima_user_DllExport uint16_t key() const + { + return m_key; + } + + /*! + * @brief This function returns a reference to member deadlinekey + * @return Reference to member deadlinekey + */ + inline eProsima_user_DllExport uint16_t& key() + { + return m_key; + } + /*! + * @brief This function copies the value in member message + * @param _message New value to be copied in member message + */ + inline eProsima_user_DllExport void message(const std::string &_message) + { + m_message = _message; + } + + /*! + * @brief This function moves the value in member message + * @param _message New value to be moved in member message + */ + inline eProsima_user_DllExport void message(std::string &&_message) + { + m_message = std::move(_message); + } + + /*! + * @brief This function returns a constant reference to member message + * @return Constant reference to member message + */ + inline eProsima_user_DllExport const std::string& message() const + { + return m_message; + } + + /*! + * @brief This function returns a reference to member message + * @return Reference to member message + */ + inline eProsima_user_DllExport std::string& message() + { + return m_message; + } + + /*! + * @brief This function returns the maximum serialized size of an object + * depending on the buffer alignment. + * @param current_alignment Buffer alignment. + * @return Maximum serialized size. + */ + eProsima_user_DllExport static size_t getMaxCdrSerializedSize(size_t current_alignment = 0); + + /*! + * @brief This function returns the serialized size of a data depending on the buffer alignment. + * @param data Data which is calculated its serialized size. + * @param current_alignment Buffer alignment. + * @return Serialized size. + */ + eProsima_user_DllExport static size_t getCdrSerializedSize(const KeyedHelloWorld& data, size_t current_alignment = 0); + + + /*! + * @brief This function serializes an object using CDR serialization. + * @param cdr CDR serialization object. + */ + eProsima_user_DllExport void serialize(eprosima::fastcdr::Cdr &cdr) const; + + /*! + * @brief This function deserializes an object using CDR serialization. + * @param cdr CDR serialization object. + */ + eProsima_user_DllExport void deserialize(eprosima::fastcdr::Cdr &cdr); + + + + /*! + * @brief This function returns the maximum serialized size of the Key of an object + * depending on the buffer alignment. + * @param current_alignment Buffer alignment. + * @return Maximum serialized size. + */ + eProsima_user_DllExport static size_t getKeyMaxCdrSerializedSize(size_t current_alignment = 0); + + /*! + * @brief This function tells you if the Key has been defined for this type + */ + eProsima_user_DllExport static bool isKeyDefined(); + + /*! + * @brief This function serializes the key members of an object using CDR serialization. + * @param cdr CDR serialization object. + */ + eProsima_user_DllExport void serializeKey(eprosima::fastcdr::Cdr &cdr) const; + +private: + uint16_t m_key; + std::string m_message; +}; + +#endif // _KeyedHelloWorld_H_ diff --git a/test/blackbox/types/KeyedHelloWorldType.cpp b/test/blackbox/types/KeyedHelloWorldType.cpp new file mode 100644 index 00000000000..85b4ff0ea23 --- /dev/null +++ b/test/blackbox/types/KeyedHelloWorldType.cpp @@ -0,0 +1,125 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file deadlinepayloadPubSubTypes.cpp + * This header file contains the implementation of the serialization functions. + * + * This file was generated by the tool fastcdrgen. + */ + + +#include +#include + +#include "KeyedHelloWorldType.h" + +using namespace eprosima::fastrtps; +using namespace eprosima::fastrtps::rtps; + +KeyedHelloWorldType::KeyedHelloWorldType() { + setName("KeyedHelloWorld"); + m_typeSize = (uint32_t)KeyedHelloWorld::getMaxCdrSerializedSize() + 4 /*encapsulation*/; + m_isGetKeyDefined = KeyedHelloWorld::isKeyDefined(); + m_keyBuffer = (unsigned char*)malloc(KeyedHelloWorld::getKeyMaxCdrSerializedSize()>16 ? KeyedHelloWorld::getKeyMaxCdrSerializedSize() : 16); +} + +KeyedHelloWorldType::~KeyedHelloWorldType() { + if(m_keyBuffer!=nullptr) + free(m_keyBuffer); +} + +bool KeyedHelloWorldType::serialize(void *data, SerializedPayload_t *payload) { + KeyedHelloWorld *p_type = (KeyedHelloWorld*) data; + eprosima::fastcdr::FastBuffer fastbuffer((char*) payload->data, payload->max_size); // Object that manages the raw buffer. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + eprosima::fastcdr::Cdr::DDS_CDR); + payload->encapsulation = ser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + // Serialize encapsulation + ser.serialize_encapsulation(); + + try + { + p_type->serialize(ser); // Serialize the object: + } + catch(eprosima::fastcdr::exception::NotEnoughMemoryException& /*exception*/) + { + return false; + } + + payload->length = (uint32_t)ser.getSerializedDataLength(); //Get the serialized length + return true; +} + +bool KeyedHelloWorldType::deserialize(SerializedPayload_t* payload, void* data) { + KeyedHelloWorld* p_type = (KeyedHelloWorld*) data; //Convert DATA to pointer of your type + eprosima::fastcdr::FastBuffer fastbuffer((char*)payload->data, payload->length); // Object that manages the raw buffer. + eprosima::fastcdr::Cdr deser(fastbuffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, + eprosima::fastcdr::Cdr::DDS_CDR); // Object that deserializes the data. + // Deserialize encapsulation. + deser.read_encapsulation(); + payload->encapsulation = deser.endianness() == eprosima::fastcdr::Cdr::BIG_ENDIANNESS ? CDR_BE : CDR_LE; + + try + { + p_type->deserialize(deser); //Deserialize the object: + } + catch(eprosima::fastcdr::exception::NotEnoughMemoryException& /*exception*/) + { + return false; + } + + return true; +} + +std::function KeyedHelloWorldType::getSerializedSizeProvider(void* data) { + return [data]() -> uint32_t { + return (uint32_t)type::getCdrSerializedSize(*static_cast(data)) + 4 /*encapsulation*/; + }; +} + +void* KeyedHelloWorldType::createData() { + return (void*)new KeyedHelloWorld(); +} + +void KeyedHelloWorldType::deleteData(void* data) { + delete((KeyedHelloWorld*)data); +} + +bool KeyedHelloWorldType::getKey(void *data, InstanceHandle_t* handle, bool force_md5) { + if(!m_isGetKeyDefined) + return false; + KeyedHelloWorld* p_type = (KeyedHelloWorld*) data; + eprosima::fastcdr::FastBuffer fastbuffer((char*)m_keyBuffer,KeyedHelloWorld::getKeyMaxCdrSerializedSize()); // Object that manages the raw buffer. + eprosima::fastcdr::Cdr ser(fastbuffer, eprosima::fastcdr::Cdr::BIG_ENDIANNESS); // Object that serializes the data. + p_type->serializeKey(ser); + if(force_md5 || KeyedHelloWorld::getKeyMaxCdrSerializedSize()>16) + { + m_md5.init(); + m_md5.update(m_keyBuffer,(unsigned int)ser.getSerializedDataLength()); + m_md5.finalize(); + for(uint8_t i = 0;i<16;++i) + { + handle->value[i] = m_md5.digest[i]; + } + } + else + { + for(uint8_t i = 0;i<16;++i) + { + handle->value[i] = m_keyBuffer[i]; + } + } + return true; +} diff --git a/test/blackbox/types/KeyedHelloWorldType.h b/test/blackbox/types/KeyedHelloWorldType.h new file mode 100644 index 00000000000..196ffc98978 --- /dev/null +++ b/test/blackbox/types/KeyedHelloWorldType.h @@ -0,0 +1,50 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * @file KeyedHelloWorldType.h + * This header file contains the declaration of the serialization functions. + * + * This file was generated by the tool fastcdrgen. + */ + + +#ifndef _DEADLINEPAYLOAD_PUBSUBTYPES_H_ +#define _DEADLINEPAYLOAD_PUBSUBTYPES_H_ + +#include + +#include "KeyedHelloWorld.h" + +/*! + * @brief This class represents the TopicDataType of the type HelloMsg defined by the user in the IDL file. + * @ingroup DEADLINEPAYLOAD + */ +class KeyedHelloWorldType : public eprosima::fastrtps::TopicDataType { +public: + typedef KeyedHelloWorld type; + + KeyedHelloWorldType(); + virtual ~KeyedHelloWorldType(); + bool serialize(void *data, eprosima::fastrtps::rtps::SerializedPayload_t *payload); + bool deserialize(eprosima::fastrtps::rtps::SerializedPayload_t *payload, void *data); + std::function getSerializedSizeProvider(void* data); + bool getKey(void *data, eprosima::fastrtps::rtps::InstanceHandle_t *ihandle, bool force_md5); + void* createData(); + void deleteData(void * data); + MD5 m_md5; + unsigned char* m_keyBuffer; +}; + +#endif // _deadlinepayload_PUBSUBTYPE_H_ diff --git a/test/blackbox/utils/data_generators.cpp b/test/blackbox/utils/data_generators.cpp index 1ed575f4960..ee6bb701d45 100644 --- a/test/blackbox/utils/data_generators.cpp +++ b/test/blackbox/utils/data_generators.cpp @@ -47,6 +47,24 @@ std::list default_fixed_sized_data_generator(size_t max) ++index; return fs; }); +} + +std::list default_keyedhelloworld_data_generator(size_t max) +{ + uint16_t index = 0; + size_t maximum = max ? max : 10; + std::list returnedValue(maximum); + + std::generate(returnedValue.begin(), returnedValue.end(), [&index] + { + KeyedHelloWorld hello; + hello.key(index % 2); + std::stringstream ss; + ss << "HelloWorld " << index; + hello.message(ss.str()); + ++index; + return hello; + }); return returnedValue; } diff --git a/test/blackbox/utils/lambda_functions.cpp b/test/blackbox/utils/lambda_functions.cpp index 095b2b4658b..6e17034393e 100644 --- a/test/blackbox/utils/lambda_functions.cpp +++ b/test/blackbox/utils/lambda_functions.cpp @@ -24,6 +24,11 @@ const std::function default_fixed_sized_print = [](con std::cout << hello.index() << " "; }; +const std::function default_keyedhelloworld_print = [](const KeyedHelloWorld& hello) +{ + std::cout << hello.message() << " " << hello.key(); +}; + const std::function default_string_print = [](const String& str) { std::cout << str.message()[str.message().size() - 2] From c853f6c1ed158139d4e401e09971ab866a96dd0f Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 6 Mar 2019 08:30:16 +0100 Subject: [PATCH 16/54] Refs #4693 Adding helper CacheChange to Publisher/SubscriberHistory to ensure latest change is always kept in the history, even if changes are removed (for instance if user does takeData or if writers are volatile --- include/fastrtps/publisher/PublisherHistory.h | 2 ++ .../fastrtps/subscriber/SubscriberHistory.h | 2 ++ src/cpp/publisher/PublisherHistory.cpp | 17 +++++++-------- src/cpp/subscriber/SubscriberHistory.cpp | 21 ++++++++++--------- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/include/fastrtps/publisher/PublisherHistory.h b/include/fastrtps/publisher/PublisherHistory.h index 3102e6a67c2..0beac51256f 100644 --- a/include/fastrtps/publisher/PublisherHistory.h +++ b/include/fastrtps/publisher/PublisherHistory.h @@ -113,6 +113,8 @@ class PublisherHistory:public rtps::WriterHistory ResourceLimitsQosPolicy m_resourceLimitsQos; //!Publisher Pointer PublisherImpl* mp_pubImpl; + //!The latest cache change written (only used for topics with no key) + CacheChange_t* mp_latestCacheChange; /** * @brief Method that finds a key in m_keyedChanges or tries to add it if not found diff --git a/include/fastrtps/subscriber/SubscriberHistory.h b/include/fastrtps/subscriber/SubscriberHistory.h index d249196e27f..ac64db4fb86 100644 --- a/include/fastrtps/subscriber/SubscriberHistory.h +++ b/include/fastrtps/subscriber/SubscriberHistory.h @@ -140,6 +140,8 @@ class SubscriberHistory: public rtps::ReaderHistory ResourceLimitsQosPolicy m_resourceLimitsQos; //!Publisher Pointer SubscriberImpl* mp_subImpl; + //!The latest cache change received (only used for topics with no key) + CacheChange_t* mp_latestCacheChange; //!Type object to deserialize Key void * mp_getKeyObject; diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index ffa3621a53c..bb615d8eac6 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -54,13 +54,15 @@ PublisherHistory::PublisherHistory( , m_historyQos(history) , m_resourceLimitsQos(resource) , mp_pubImpl(pimpl) + , mp_latestCacheChange(new CacheChange_t) { // TODO Auto-generated constructor stub } -PublisherHistory::~PublisherHistory() { - // TODO Auto-generated destructor stub +PublisherHistory::~PublisherHistory() +{ + delete mp_latestCacheChange; } @@ -99,6 +101,7 @@ bool PublisherHistory::add_pub_change( { if(this->add_change_(change, wparams, max_blocking_time)) { + mp_latestCacheChange->copy(change); returnedValue = true; } } @@ -286,16 +289,10 @@ void PublisherHistory::get_latest_samples(std::vector &samples, return; } - if (m_changes.empty()) + if (mp_latestCacheChange != mp_invalidCache) { - return; + samples[num_samples++] = mp_latestCacheChange; } - - auto max = *std::max_element( - m_changes.begin(), - m_changes.end(), - [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); - samples[num_samples++] = max; } else if (mp_pubImpl->getAttributes().topic.getTopicKind() == WITH_KEY) { diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index 7323442d487..4c16fb390af 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -57,6 +57,7 @@ SubscriberHistory::SubscriberHistory( , m_historyQos(history) , m_resourceLimitsQos(resource) , mp_subImpl(simpl) + , mp_latestCacheChange(new CacheChange_t) , mp_getKeyObject(nullptr) { if (mp_subImpl->getType()->m_isGetKeyDefined) @@ -71,6 +72,7 @@ SubscriberHistory::~SubscriberHistory() { mp_subImpl->getType()->deleteData(mp_getKeyObject); } + delete mp_latestCacheChange; } bool SubscriberHistory::received_change( @@ -154,7 +156,12 @@ bool SubscriberHistory::received_change( logInfo(SUBSCRIBER, this->mp_subImpl->getGuid().entityId << ": Change " << a_change->sequenceNumber << " added from: " << a_change->writerGUID;); - //print_changes_seqNum(); + + if (mp_latestCacheChange == mp_invalidCache || mp_latestCacheChange->sourceTimestamp < a_change->sourceTimestamp) + { + mp_latestCacheChange->copy(a_change); + } + return true; } } @@ -549,7 +556,7 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change) return false; } -void SubscriberHistory::get_latest_samples(std::vector &samples, int &num_samples) +void SubscriberHistory::get_latest_samples(std::vector &samples, int &num_samples) { num_samples = 0; @@ -561,16 +568,10 @@ void SubscriberHistory::get_latest_samples(std::vector &samples return; } - if (m_changes.empty()) + if(mp_latestCacheChange != mp_invalidCache) { - return; + samples[num_samples++] = mp_latestCacheChange; } - - auto max = *std::max_element( - m_changes.begin(), - m_changes.end(), - [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); - samples[num_samples++] = max; } else if (mp_subImpl->getAttributes().topic.getTopicKind() == WITH_KEY) { From bae2450cfec7cae927545316b47c2e65c450ece6 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 6 Mar 2019 11:04:47 +0100 Subject: [PATCH 17/54] Refs #4693 Adding a struct to Publisher/SubscriberHistory to keep the latest sample for each instance --- include/fastrtps/publisher/PublisherHistory.h | 39 +++++++++++++++- .../fastrtps/subscriber/SubscriberHistory.h | 41 ++++++++++++++--- src/cpp/publisher/PublisherHistory.cpp | 25 +++++------ src/cpp/subscriber/SubscriberHistory.cpp | 45 +++++++++---------- 4 files changed, 105 insertions(+), 45 deletions(-) diff --git a/include/fastrtps/publisher/PublisherHistory.h b/include/fastrtps/publisher/PublisherHistory.h index 0beac51256f..7396d12ca0d 100644 --- a/include/fastrtps/publisher/PublisherHistory.h +++ b/include/fastrtps/publisher/PublisherHistory.h @@ -41,8 +41,6 @@ class PublisherImpl; class PublisherHistory:public rtps::WriterHistory { public: - typedef std::map> t_m_Inst_Caches; - typedef std::vector t_v_Caches; /** * Constructor of the PublisherHistory. * @param pimpl Pointer to the PublisherImpl. @@ -105,6 +103,43 @@ class PublisherHistory:public rtps::WriterHistory int& num_samples); private: + + /** + * @brief A struct storing a vector of cache changes and the latest change in the group + * @ingroup FASTRTPS_MODULE + */ + struct KeyedChanges + { + //! Default constructor + KeyedChanges() + : cache_changes_() + , latest_change_(new CacheChange_t) + { + } + + //! Copy constructor + KeyedChanges(const KeyedChanges& other) + : cache_changes_(other.cache_changes_) + , latest_change_(new CacheChange_t) + { + latest_change_->copy(other.latest_change_); + } + + //! Destructor + ~KeyedChanges() + { + delete latest_change_; + } + + //! A vector of cache changes + std::vector cache_changes_; + //! The latest cache change in the struct + CacheChange_t* latest_change_; + }; + + typedef std::map t_m_Inst_Caches; + typedef std::vector t_v_Caches; + //!Map where keys are instance handles and values are vectors of cache changes associated t_m_Inst_Caches m_keyedChanges; //!HistoryQosPolicy values. diff --git a/include/fastrtps/subscriber/SubscriberHistory.h b/include/fastrtps/subscriber/SubscriberHistory.h index ac64db4fb86..fabfbce3bbf 100644 --- a/include/fastrtps/subscriber/SubscriberHistory.h +++ b/include/fastrtps/subscriber/SubscriberHistory.h @@ -26,8 +26,6 @@ #include "../qos/QosPolicies.h" #include "SampleInfo.h" - - namespace eprosima { namespace fastrtps { @@ -35,7 +33,6 @@ namespace rtps{ class WriterProxy; } - class SubscriberImpl; /** @@ -46,9 +43,6 @@ class SubscriberHistory: public rtps::ReaderHistory { public: - typedef std::map> t_m_Inst_Caches; - typedef std::vector t_v_Caches; - /** * Constructor. Requires information about the subscriner * @param pimpl Pointer to the subscriber implementation @@ -130,6 +124,41 @@ class SubscriberHistory: public rtps::ReaderHistory private: + /** + * @brief A struct storing a vector of cache changes and the latest change in the group + * @ingroup FASTRTPS_MODULE + */ + struct KeyedChanges + { + //! Default constructor + KeyedChanges() + : cache_changes_() + , latest_change_(new CacheChange_t) + {} + + //! Copy constructor + KeyedChanges(const KeyedChanges& other) + : cache_changes_(other.cache_changes_) + , latest_change_(new CacheChange_t) + { + latest_change_->copy(other.latest_change_); + } + + //! Destructor + ~KeyedChanges() + { + delete latest_change_; + } + + //! A vector of cache changes + std::vector cache_changes_; + //! The latest cache change in the struct + CacheChange_t* latest_change_; + }; + + typedef std::map t_m_Inst_Caches; + typedef std::vector t_v_Caches; + //!Number of unread CacheChange_t. uint64_t m_unreadCacheCount; //!Map where keys are instance handles and values vectors of cache changes diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index bb615d8eac6..b20fe887193 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -115,7 +115,7 @@ bool PublisherHistory::add_pub_change( bool add = false; if(m_historyQos.kind == KEEP_ALL_HISTORY_QOS) { - if((int32_t)vit->second.size() < m_resourceLimitsQos.max_samples_per_instance) + if((int32_t)vit->second.cache_changes_.size() < m_resourceLimitsQos.max_samples_per_instance) { add = true; } @@ -126,13 +126,13 @@ bool PublisherHistory::add_pub_change( } else if (m_historyQos.kind == KEEP_LAST_HISTORY_QOS) { - if(vit->second.size() < (size_t)m_historyQos.depth) + if(vit->second.cache_changes_.size() < (size_t)m_historyQos.depth) { add = true; } else { - if(remove_change_pub(vit->second.front())) + if(remove_change_pub(vit->second.cache_changes_.front())) { add = true; } @@ -146,7 +146,8 @@ bool PublisherHistory::add_pub_change( logInfo(RTPS_HISTORY,this->mp_pubImpl->getGuid().entityId <<" Change " << change->sequenceNumber << " added with key: "<instanceHandle << " and "<serializedPayload.length<< " bytes"); - vit->second.push_back(change); + vit->second.cache_changes_.push_back(change); + vit->second.latest_change_->copy(change); returnedValue = true; } } @@ -171,17 +172,17 @@ bool PublisherHistory::find_key( if ((int)m_keyedChanges.size() < m_resourceLimitsQos.max_instances) { - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, std::vector())).first; + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; return true; } else { for (vit = m_keyedChanges.begin(); vit != m_keyedChanges.end(); ++vit) { - if (vit->second.size() == 0) + if (vit->second.cache_changes_.size() == 0) { m_keyedChanges.erase(vit); - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, std::vector())).first; + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; return true; } } @@ -254,14 +255,14 @@ bool PublisherHistory::remove_change_pub(CacheChange_t* change) return false; } - for(auto chit = vit->second.begin(); chit!= vit->second.end(); ++chit) + for(auto chit = vit->second.cache_changes_.begin(); chit!= vit->second.cache_changes_.end(); ++chit) { if( ((*chit)->sequenceNumber == change->sequenceNumber) && ((*chit)->writerGUID == change->writerGUID) ) { if(remove_change(change)) { - vit->second.erase(chit); + vit->second.cache_changes_.erase(chit); m_isHistoryFull = false; return true; } @@ -309,11 +310,7 @@ void PublisherHistory::get_latest_samples(std::vector &samples, for (auto it = m_keyedChanges.begin(); it != m_keyedChanges.end(); ++it) { - auto max = *std::max_element( - it->second.begin(), - it->second.end(), - [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); - samples[num_samples++] = max; + samples[num_samples++] = it->second.latest_change_; } } } diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index 4c16fb390af..149ba9ee35e 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -190,11 +190,10 @@ bool SubscriberHistory::received_change( t_m_Inst_Caches::iterator vit; if (find_key(a_change, &vit)) { - //logInfo(RTPS_EDP,"Trying to add change with KEY: "<< vit->first << endl;); bool add = false; if (m_historyQos.kind == KEEP_ALL_HISTORY_QOS) { - if ((int32_t)vit->second.size() < m_resourceLimitsQos.max_samples_per_instance) + if ((int32_t)vit->second.cache_changes_.size() < m_resourceLimitsQos.max_samples_per_instance) { add = true; } @@ -206,15 +205,15 @@ bool SubscriberHistory::received_change( } else if (m_historyQos.kind == KEEP_LAST_HISTORY_QOS) { - if (vit->second.size() < (size_t)m_historyQos.depth) + if (vit->second.cache_changes_.size() < (size_t)m_historyQos.depth) { add = true; } else { // Try to substitute the oldest sample with the same key - auto older_sample = vit->second.rend(); - for (auto it = vit->second.rbegin(); it != vit->second.rend(); ++it) + auto older_sample = vit->second.cache_changes_.rend(); + for (auto it = vit->second.cache_changes_.rbegin(); it != vit->second.cache_changes_.rend(); ++it) { if ((*it)->writerGUID == a_change->writerGUID) @@ -227,7 +226,7 @@ bool SubscriberHistory::received_change( } } - if (older_sample != vit->second.rend()) + if (older_sample != vit->second.cache_changes_.rend()) { bool read = (*older_sample)->isRead; @@ -258,23 +257,27 @@ bool SubscriberHistory::received_change( if ((int32_t)m_changes.size() == m_resourceLimitsQos.max_samples) m_isHistoryFull = true; //ADD TO KEY VECTOR - if (vit->second.size() == 0) + if (vit->second.cache_changes_.size() == 0) { - vit->second.push_back(a_change); + vit->second.cache_changes_.push_back(a_change); } - else if (vit->second.back()->sequenceNumber < a_change->sequenceNumber) + else if (vit->second.cache_changes_.back()->sequenceNumber < a_change->sequenceNumber) { - vit->second.push_back(a_change); + vit->second.cache_changes_.push_back(a_change); } else { - vit->second.push_back(a_change); - std::sort(vit->second.begin(), vit->second.end(), sort_ReaderHistoryCache); + vit->second.cache_changes_.push_back(a_change); + std::sort(vit->second.cache_changes_.begin(), + vit->second.cache_changes_.end(), + sort_ReaderHistoryCache); } + vit->second.latest_change_->copy(vit->second.cache_changes_.back()); + logInfo(SUBSCRIBER, this->mp_reader->getGuid().entityId << ": Change " << a_change->sequenceNumber << " added from: " << a_change->writerGUID << " with KEY: " << a_change->instanceHandle;); - // print_changes_seqNum(); + return true; } } @@ -493,17 +496,17 @@ bool SubscriberHistory::find_key( if ((int)m_keyedChanges.size() < m_resourceLimitsQos.max_instances) { - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, t_v_Caches())).first; + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; return true; } else { for (vit = m_keyedChanges.begin(); vit!= m_keyedChanges.end(); ++vit) { - if (vit->second.size() == 0) + if (vit->second.cache_changes_.size() == 0) { m_keyedChanges.erase(vit); - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, t_v_Caches())).first; + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; return true; } } @@ -539,13 +542,13 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change) return false; } - for (auto chit = vit->second.begin(); chit != vit->second.end(); ++chit) + for (auto chit = vit->second.cache_changes_.begin(); chit != vit->second.cache_changes_.end(); ++chit) { if ((*chit)->sequenceNumber == change->sequenceNumber && (*chit)->writerGUID == change->writerGUID) { if (remove_change(change)) { - vit->second.erase(chit); + vit->second.cache_changes_.erase(chit); m_isHistoryFull = false; return true; } @@ -588,11 +591,7 @@ void SubscriberHistory::get_latest_samples(std::vector &samples, for (auto it = m_keyedChanges.begin(); it != m_keyedChanges.end(); ++it) { - auto max = *std::max_element( - it->second.begin(), - it->second.end(), - [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); - samples[num_samples++] = max; + samples[num_samples++] = it->second.latest_change_; } } } From b710723192fcc24b3303ee5052c2c0699329713e Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 6 Mar 2019 15:53:53 +0100 Subject: [PATCH 18/54] Refs #4693 Changed a bit the design to fix failure seen when a sample is sent and never updated (sometimes the deadline wasn't detected as missed) --- src/cpp/publisher/PublisherImpl.cpp | 35 +++++++++++----------- src/cpp/subscriber/SubscriberImpl.cpp | 42 +++++++++++++-------------- src/cpp/subscriber/SubscriberImpl.h | 2 +- 3 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index 99a07b786f2..b0906e24a01 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -206,6 +206,18 @@ bool PublisherImpl::create_new_change_with_params( if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { + // Cancel timer + deadline_timer_.cancel_timer(); + + // Calculate the time at which the instance with the oldest change will expire + int num_instances = 0; + m_history.get_latest_samples(deadline_samples_, num_instances); + auto min = *std::min_element(deadline_samples_.begin(), + deadline_samples_.begin() + num_instances, + [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); + deadline_timer_.update_interval(deadline_duration_ - ch->sourceTimestamp + min->sourceTimestamp); + + // Restart the timer deadline_timer_.restart_timer(); } return true; @@ -342,7 +354,7 @@ void PublisherImpl::check_deadlines() { assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); - auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + // If this method is called, one instance (the one with the oldest change) has missed the deadline // Get the latest samples from the history int num_samples = 0; @@ -350,34 +362,23 @@ void PublisherImpl::check_deadlines() if (num_samples == 0) { + logError(PUBLISHER, "Deadline timer expired but no samples available"); return; } // Time of the earliest sample among all topic instances Time_t minTime = deadline_samples_.front()->sourceTimestamp; - - // Number of instances missing the deadline - int num_instances = 0; + // Instance of the earliest sample among all topic instances + InstanceHandle_t handle = deadline_samples_.front()->instanceHandle; for (int i = 0; i < num_samples; i++) { if (deadline_samples_[i]->sourceTimestamp < minTime) { minTime = deadline_samples_[i]->sourceTimestamp; - } - - if (now - deadline_samples_[i]->sourceTimestamp > deadline_duration_ ) - { - mp_listener->on_offered_deadline_missed(deadline_samples_[i]->instanceHandle); - num_instances++; + handle = deadline_samples_[i]->instanceHandle; } } - if (num_instances < num_samples) - { - // Now restart the timer - Duration_t interval = deadline_duration_ - now + minTime > 0? deadline_duration_ - now + minTime: deadline_duration_; - deadline_timer_.update_interval(interval); - deadline_timer_.restart_timer(); - } + mp_listener->on_offered_deadline_missed(handle); } diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index abc75ab506d..01cd6e07107 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -189,9 +189,9 @@ bool SubscriberImpl::updateAttributes(const SubscriberAttributes& att) return updated; } -void SubscriberImpl::SubscriberReaderListener::onNewCacheChangeAdded(RTPSReader* /*reader*/, const CacheChange_t* const /*change*/) +void SubscriberImpl::SubscriberReaderListener::onNewCacheChangeAdded(RTPSReader* /*reader*/, const CacheChange_t* const change) { - mp_subscriberImpl->onNewCacheChangeAdded(); + mp_subscriberImpl->onNewCacheChangeAdded(change); if(mp_subscriberImpl->mp_listener != nullptr) { @@ -207,10 +207,22 @@ void SubscriberImpl::SubscriberReaderListener::onReaderMatched(RTPSReader* /*rea } } -void SubscriberImpl::onNewCacheChangeAdded() +void SubscriberImpl::onNewCacheChangeAdded(const CacheChange_t* const change) { if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { + // Cancel the timer + deadline_timer_.cancel_timer(); + + // Update timer interval + int num_samples = 0; + m_history.get_latest_samples(deadline_samples_, num_samples); + auto min = *std::min_element(deadline_samples_.begin(), + deadline_samples_.begin() + num_samples, + [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); + deadline_timer_.update_interval(deadline_duration_ - change->sourceTimestamp + min->sourceTimestamp); + + // Restart deadline_timer_.restart_timer(); } } @@ -235,7 +247,7 @@ void SubscriberImpl::check_deadlines() { assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); - auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + // If this method is called, one instance (the one with the oldest change) has missed the deadline // Get the latest samples from the history int num_samples = 0; @@ -243,37 +255,25 @@ void SubscriberImpl::check_deadlines() if (num_samples == 0) { + logError(SUBSCRIBER, "Deadline timer expired but no samples available"); return; } // Time of the earliest sample among all topic instances Time_t minTime = deadline_samples_.front()->sourceTimestamp; + // Instance handle of the earlist sample among all topic instances + InstanceHandle_t handle = deadline_samples_.front()->instanceHandle; - // Number of instances missing the deadline - int num_instances = 0; - - // Check if any instance missed the dealine for (int i = 0; i < num_samples; ++i) { if (deadline_samples_[i]->sourceTimestamp < minTime) { minTime = deadline_samples_[i]->sourceTimestamp; - } - - if (now - deadline_samples_[i]->sourceTimestamp > deadline_duration_) - { - mp_listener->on_requested_deadline_missed(deadline_samples_[i]->instanceHandle); - num_instances++; + handle = deadline_samples_[i]->instanceHandle; } } - if (num_instances < num_samples) - { - // Restart the timer - Duration_t interval = deadline_duration_ - now + minTime > 0? deadline_duration_ - now + minTime: deadline_duration_; - deadline_timer_.update_interval(interval); - deadline_timer_.restart_timer(); - } + mp_listener->on_requested_deadline_missed(handle); } } /* namespace fastrtps */ diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index 00267c2de7f..9ff0cc2e8b5 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -125,7 +125,7 @@ class SubscriberImpl { * @brief A method called when a new cache change is added * @param change The cache change that has been added */ - void onNewCacheChangeAdded(); + void onNewCacheChangeAdded(const CacheChange_t* const change); private: //!Participant From f9a28180fce23ca6d923a9bb4ee5f84d0968244b Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 6 Mar 2019 16:00:29 +0100 Subject: [PATCH 19/54] Refs #4693 Adding some comments to tests and changing parameters so that they run faster --- test/blackbox/BlackboxTestsDeadlineQos.cpp | 46 +++++++++++++++------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/test/blackbox/BlackboxTestsDeadlineQos.cpp b/test/blackbox/BlackboxTestsDeadlineQos.cpp index a29f18e0940..1a3004e2f5c 100644 --- a/test/blackbox/BlackboxTestsDeadlineQos.cpp +++ b/test/blackbox/BlackboxTestsDeadlineQos.cpp @@ -26,14 +26,19 @@ using namespace eprosima::fastrtps::rtps; BLACKBOXTEST(DeadlineQos, NoKeyTopicLongDeadline) { + // This test sets a long deadline (long in comparison to the write rate), + // makes the writer send a few samples and checks that the deadline was + // not missed + // Uses a topic with no key + PubSubReader reader(TEST_TOPIC_NAME); PubSubWriter writer(TEST_TOPIC_NAME); - // Rate at which writer sends data in ms + // Write rate in milliseconds uint32_t writer_sleep_ms = 100; // Number of samples written by writer uint32_t writer_samples = 3; - // Deadline period in ms (long in comparison to the rate at which samples are written) + // Deadline period in seconds eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 2 * 1e-3); reader.deadline_period(deadline_s); @@ -68,14 +73,18 @@ BLACKBOXTEST(DeadlineQos, NoKeyTopicLongDeadline) BLACKBOXTEST(DeadlineQos, NoKeyTopicShortDeadline) { + // This test sets a short deadline (short compared to the write rate), + // makes the writer send a few samples and checks that the deadline was missed every time + // Uses a topic with no key + PubSubReader reader(TEST_TOPIC_NAME); PubSubWriter writer(TEST_TOPIC_NAME); - // Rate at which writer sends data in ms - uint32_t writer_sleep_ms = 500; + // Write rate in milliseconds + uint32_t writer_sleep_ms = 100; // Number of samples written by writer uint32_t writer_samples = 3; - // Deadline period in ms (short in comparison to the rate at which samples are written) + // Deadline period in seconds eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 0.1 * 1e-3); reader.deadline_period(deadline_s); @@ -101,7 +110,6 @@ BLACKBOXTEST(DeadlineQos, NoKeyTopicShortDeadline) writer.send_sample(data_sample); ++count; reader.block_for_at_least(count); - std::this_thread::sleep_for(std::chrono::milliseconds(writer_sleep_ms)); } @@ -112,15 +120,19 @@ BLACKBOXTEST(DeadlineQos, NoKeyTopicShortDeadline) BLACKBOXTEST(DeadlineQos, KeyedTopicLongDeadline) { + // This test sets a long deadline (long in comparison to the write rate), + // makes the writer send a few samples and checks that the deadline was met + // Uses a topic with key + PubSubReader reader(TEST_TOPIC_NAME); PubSubWriter writer(TEST_TOPIC_NAME); - // Rate at which writer sends data in ms + // Write rate in milliseconds uint32_t writer_sleep_ms = 100; // Number of samples written by writer uint32_t writer_samples = 4; - // Deadline period in ms (long compared to rate at which samples are written) - eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 2 * 1e-3); + // Deadline period in seconds + eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 4 * 1e-3); reader.deadline_period(deadline_s); writer.deadline_period(deadline_s); @@ -157,14 +169,18 @@ BLACKBOXTEST(DeadlineQos, KeyedTopicLongDeadline) BLACKBOXTEST(DeadlineQos, KeyedTopicShortDeadline) { + // This test sets a short deadline (short compared to the write rate), + // makes the writer send a few samples and checks that the deadline was missed every time + // Uses a topic with key + PubSubReader reader(TEST_TOPIC_NAME); PubSubWriter writer(TEST_TOPIC_NAME); - // Rate at which writer sends data in ms - uint32_t writer_sleep_ms = 1000; - // Number of samples written by writer + // Only one sample sent by the writer uint32_t writer_samples = 4; - // Deadline period in ms (short compared to rate at which samples are written) + // Time to wait before sending the sample + uint32_t writer_sleep_ms = 100; + // Deadline period in ms eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 0.1 * 1e-3); reader.deadline_period(deadline_s); @@ -196,6 +212,6 @@ BLACKBOXTEST(DeadlineQos, KeyedTopicShortDeadline) std::this_thread::sleep_for(std::chrono::milliseconds(writer_sleep_ms)); } - EXPECT_EQ(writer.missed_deadlines(), 0); - EXPECT_EQ(reader.missed_deadlines(), 0); + EXPECT_EQ(writer.missed_deadlines(), writer_samples); + EXPECT_EQ(reader.missed_deadlines(), writer_samples); } From 1d38bffceec11358213b25381e1d5779f0e3462e Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 6 Mar 2019 16:26:07 +0100 Subject: [PATCH 20/54] Refs #4693 Improving precision of current time --- src/cpp/rtps/history/WriterHistory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpp/rtps/history/WriterHistory.cpp b/src/cpp/rtps/history/WriterHistory.cpp index 27d0d97d1c2..5f504eba28c 100644 --- a/src/cpp/rtps/history/WriterHistory.cpp +++ b/src/cpp/rtps/history/WriterHistory.cpp @@ -87,7 +87,7 @@ bool WriterHistory::add_change_(CacheChange_t* a_change, WriteParams &wparams, ++m_lastCacheChangeSeqNum; a_change->sequenceNumber = m_lastCacheChangeSeqNum; - a_change->sourceTimestamp = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + a_change->sourceTimestamp = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); a_change->write_params = wparams; // Updated sample identity From 1f08d35008702d0a513e4ea2be6ddad9210248d2 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 6 Mar 2019 16:43:37 +0100 Subject: [PATCH 21/54] Refs #4693 Locking reader/writer mutex to prevent the history from being changed while we are checking for deadlines or updating the timer --- src/cpp/publisher/PublisherHistory.cpp | 2 ++ src/cpp/publisher/PublisherImpl.cpp | 2 ++ src/cpp/subscriber/SubscriberHistory.cpp | 2 ++ src/cpp/subscriber/SubscriberImpl.cpp | 4 ++++ 4 files changed, 10 insertions(+) diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index b20fe887193..96c795c50bd 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -280,6 +280,8 @@ bool PublisherHistory::remove_change_g(CacheChange_t* a_change) void PublisherHistory::get_latest_samples(std::vector &samples, int& num_samples) { + std::lock_guard guard(*this->mp_mutex); + num_samples = 0; if (mp_pubImpl->getAttributes().topic.getTopicKind() == NO_KEY) diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index b0906e24a01..f4c038abe07 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -354,6 +354,8 @@ void PublisherImpl::check_deadlines() { assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); + std::unique_lock lock(*mp_writer->getMutex()); + // If this method is called, one instance (the one with the oldest change) has missed the deadline // Get the latest samples from the history diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index 149ba9ee35e..d18129af188 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -561,6 +561,8 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change) void SubscriberHistory::get_latest_samples(std::vector &samples, int &num_samples) { + std::lock_guard guard(*mp_mutex); + num_samples = 0; if (mp_subImpl->getAttributes().topic.getTopicKind() == NO_KEY) diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index 01cd6e07107..ad24166e4a2 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -211,6 +211,8 @@ void SubscriberImpl::onNewCacheChangeAdded(const CacheChange_t* const change) { if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { + std::unique_lock lock(*mp_reader->getMutex()); + // Cancel the timer deadline_timer_.cancel_timer(); @@ -247,6 +249,8 @@ void SubscriberImpl::check_deadlines() { assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); + std::unique_lock lock(*mp_reader->getMutex()); + // If this method is called, one instance (the one with the oldest change) has missed the deadline // Get the latest samples from the history From b9af481726cd14d6f5a4cdf761f10f23bb16cd36 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 6 Mar 2019 18:52:13 +0100 Subject: [PATCH 22/54] Refs #4693 Code formatting --- .../deadlinepayloadPublisher.h | 24 +- .../deadlinepayloadSubscriber.h | 24 +- include/fastrtps/qos/ReaderQos.h | 86 +- include/fastrtps/qos/WriterQos.h | 94 +- src/cpp/subscriber/SubscriberImpl.h | 44 +- test/blackbox/PubSubReader.hpp | 1191 +++++++++-------- test/blackbox/types/KeyedHelloWorld.h | 14 - 7 files changed, 733 insertions(+), 744 deletions(-) diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h index 6f3eeead86d..7447c302dee 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h @@ -20,19 +20,19 @@ #include "deadlinepayloadPubSubTypes.h" -class deadlinepayloadPublisher +class deadlinepayloadPublisher { public: /** * @brief Constructor */ - deadlinepayloadPublisher(); + deadlinepayloadPublisher(); /** * @brief Destructor */ - virtual ~deadlinepayloadPublisher(); + virtual ~deadlinepayloadPublisher(); /** * @brief Initialises publisher @@ -50,18 +50,18 @@ class deadlinepayloadPublisher private: - eprosima::fastrtps::Participant *mp_participant; - eprosima::fastrtps::Publisher *mp_publisher; + eprosima::fastrtps::Participant *mp_participant; + eprosima::fastrtps::Publisher *mp_publisher; HelloMsgPubSubType myType; - class PubListener : public eprosima::fastrtps::PublisherListener - { - public: - PubListener() : n_matched(0){}; - ~PubListener(){}; + class PubListener : public eprosima::fastrtps::PublisherListener + { + public: + PubListener() : n_matched(0){}; + ~PubListener(){}; void onPublicationMatched(eprosima::fastrtps::Publisher* pub, eprosima::fastrtps::rtps::MatchingInfo& info) override; void on_offered_deadline_missed(eprosima::fastrtps::rtps::InstanceHandle_t& handle) override; - int n_matched; - } m_listener; + int n_matched; + } m_listener; //!Boolean used to force a period double on a certain key bool double_time; diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.h b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.h index 148b8159703..cc84f7f128f 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.h +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.h @@ -30,7 +30,7 @@ #include "mapableKey.h" -class deadlinepayloadSubscriber +class deadlinepayloadSubscriber { public: @@ -42,7 +42,7 @@ class deadlinepayloadSubscriber /** * @brief Destructor */ - virtual ~deadlinepayloadSubscriber(); + virtual ~deadlinepayloadSubscriber(); /** * @brief Initialises the subscriber @@ -54,24 +54,24 @@ class deadlinepayloadSubscriber /** * @brief Runs the subscriber */ - void run(); + void run(); private: - eprosima::fastrtps::Participant *mp_participant; - eprosima::fastrtps::Subscriber *mp_subscriber; + eprosima::fastrtps::Participant *mp_participant; + eprosima::fastrtps::Subscriber *mp_subscriber; HelloMsgPubSubType myType; class SubListener : public eprosima::fastrtps::SubscriberListener - { - public: + { + public: SubListener() : n_matched(0),n_msg(0){}; - ~SubListener(){}; + ~SubListener(){}; void onSubscriptionMatched(eprosima::fastrtps::Subscriber* sub, eprosima::fastrtps::rtps::MatchingInfo& info) override; void onNewDataMessage(eprosima::fastrtps::Subscriber* sub) override; void on_requested_deadline_missed(eprosima::fastrtps::rtps::InstanceHandle_t& handle) override; - eprosima::fastrtps::SampleInfo_t m_info; - int n_matched; - int n_msg; - } m_listener; + eprosima::fastrtps::SampleInfo_t m_info; + int n_matched; + int n_msg; + } m_listener; }; #endif // _deadlinepayload_SUBSCRIBER_H_ diff --git a/include/fastrtps/qos/ReaderQos.h b/include/fastrtps/qos/ReaderQos.h index cd4ec1a2b64..48bed3415d8 100644 --- a/include/fastrtps/qos/ReaderQos.h +++ b/include/fastrtps/qos/ReaderQos.h @@ -56,34 +56,34 @@ class ReaderQos{ (this->m_lifespan == b.m_lifespan); } - //!Durability Qos, implemented in the library. - DurabilityQosPolicy m_durability; + //!Durability Qos, implemented in the library. + DurabilityQosPolicy m_durability; //!Deadline Qos, implemented in the library. - DeadlineQosPolicy m_deadline; - //!Latency Budget Qos, NOT implemented in the library. - LatencyBudgetQosPolicy m_latencyBudget; - //!Liveliness Qos, implemented in the library. - LivelinessQosPolicy m_liveliness; - //!ReliabilityQos, implemented in the library. - ReliabilityQosPolicy m_reliability; - //!Ownership Qos, NOT implemented in the library. - OwnershipQosPolicy m_ownership; - //!Destinatio Order Qos, NOT implemented in the library. - DestinationOrderQosPolicy m_destinationOrder; - //!UserData Qos, NOT implemented in the library. - UserDataQosPolicy m_userData; - //!Time Based Filter Qos, NOT implemented in the library. - TimeBasedFilterQosPolicy m_timeBasedFilter; - //!Presentation Qos, NOT implemented in the library. - PresentationQosPolicy m_presentation; - //!Partition Qos, implemented in the library. - PartitionQosPolicy m_partition; - //!Topic Data Qos, NOT implemented in the library. - TopicDataQosPolicy m_topicData; - //!GroupData Qos, NOT implemented in the library. - GroupDataQosPolicy m_groupData; - //!Durability Service Qos, NOT implemented in the library. - DurabilityServiceQosPolicy m_durabilityService; + DeadlineQosPolicy m_deadline; + //!Latency Budget Qos, NOT implemented in the library. + LatencyBudgetQosPolicy m_latencyBudget; + //!Liveliness Qos, implemented in the library. + LivelinessQosPolicy m_liveliness; + //!ReliabilityQos, implemented in the library. + ReliabilityQosPolicy m_reliability; + //!Ownership Qos, NOT implemented in the library. + OwnershipQosPolicy m_ownership; + //!Destinatio Order Qos, NOT implemented in the library. + DestinationOrderQosPolicy m_destinationOrder; + //!UserData Qos, NOT implemented in the library. + UserDataQosPolicy m_userData; + //!Time Based Filter Qos, NOT implemented in the library. + TimeBasedFilterQosPolicy m_timeBasedFilter; + //!Presentation Qos, NOT implemented in the library. + PresentationQosPolicy m_presentation; + //!Partition Qos, implemented in the library. + PartitionQosPolicy m_partition; + //!Topic Data Qos, NOT implemented in the library. + TopicDataQosPolicy m_topicData; + //!GroupData Qos, NOT implemented in the library. + GroupDataQosPolicy m_groupData; + //!Durability Service Qos, NOT implemented in the library. + DurabilityServiceQosPolicy m_durabilityService; //!Lifespan Qos, NOT implemented in the library. LifespanQosPolicy m_lifespan; //!Data Representation Qos, NOT implemented in the library. @@ -91,22 +91,22 @@ class ReaderQos{ //!Type consistency enforcement Qos, NOT implemented in the library. TypeConsistencyEnforcementQosPolicy m_typeConsistency; /** - * Set Qos from another class - * @param readerqos Reference from a ReaderQos object. - * @param first_time Boolean indicating whether is the first time (If not some parameters cannot be set). - */ - RTPS_DllAPI void setQos(const ReaderQos& readerqos, bool first_time); - /** - * Check if the Qos values are compatible between each other. - * @return True if correct. - */ - RTPS_DllAPI bool checkQos() const; - /** - * Check if the Qos can be update with the values provided. This method DOES NOT update anything. - * @param qos Reference to the new qos. - * @return True if they can be updated. - */ - RTPS_DllAPI bool canQosBeUpdated(const ReaderQos& qos) const; + * Set Qos from another class + * @param readerqos Reference from a ReaderQos object. + * @param first_time Boolean indicating whether is the first time (If not some parameters cannot be set). + */ + RTPS_DllAPI void setQos(const ReaderQos& readerqos, bool first_time); + /** + * Check if the Qos values are compatible between each other. + * @return True if correct. + */ + RTPS_DllAPI bool checkQos() const; + /** + * Check if the Qos can be update with the values provided. This method DOES NOT update anything. + * @param qos Reference to the new qos. + * @return True if they can be updated. + */ + RTPS_DllAPI bool canQosBeUpdated(const ReaderQos& qos) const; }; diff --git a/include/fastrtps/qos/WriterQos.h b/include/fastrtps/qos/WriterQos.h index 47704f0c6b0..fda5ac27451 100644 --- a/include/fastrtps/qos/WriterQos.h +++ b/include/fastrtps/qos/WriterQos.h @@ -35,8 +35,8 @@ namespace fastrtps { */ class WriterQos{ public: - RTPS_DllAPI WriterQos(); - RTPS_DllAPI virtual ~WriterQos(); + RTPS_DllAPI WriterQos(); + RTPS_DllAPI virtual ~WriterQos(); bool operator==(const WriterQos& b) const { @@ -59,53 +59,53 @@ class WriterQos{ (this->m_publishMode == b.m_publishMode); } - //!Durability Qos, implemented in the library. - DurabilityQosPolicy m_durability; - //!Durability Service Qos, NOT implemented in the library. - DurabilityServiceQosPolicy m_durabilityService; + //!Durability Qos, implemented in the library. + DurabilityQosPolicy m_durability; + //!Durability Service Qos, NOT implemented in the library. + DurabilityServiceQosPolicy m_durabilityService; //!Deadline Qos, implemented in the library. - DeadlineQosPolicy m_deadline; - //!Latency Budget Qos, NOT implemented in the library. - LatencyBudgetQosPolicy m_latencyBudget; - //!Liveliness Qos, implemented in the library. - LivelinessQosPolicy m_liveliness; - //!Reliability Qos, implemented in the library. - ReliabilityQosPolicy m_reliability; - //!Lifespan Qos, NOT implemented in the library. - LifespanQosPolicy m_lifespan; - //!UserData Qos, NOT implemented in the library. - UserDataQosPolicy m_userData; - //!Time Based Filter Qos, NOT implemented in the library. - TimeBasedFilterQosPolicy m_timeBasedFilter; - //!Ownership Qos, NOT implemented in the library. - OwnershipQosPolicy m_ownership; - //!Owenership Strength Qos, NOT implemented in the library. - OwnershipStrengthQosPolicy m_ownershipStrength; - //!Destination Order Qos, NOT implemented in the library. - DestinationOrderQosPolicy m_destinationOrder; - //!Presentation Qos, NOT implemented in the library. - PresentationQosPolicy m_presentation; - //!Partition Qos, implemented in the library. - PartitionQosPolicy m_partition; - //!Topic Data Qos, NOT implemented in the library. - TopicDataQosPolicy m_topicData; - //!Group Data Qos, NOT implemented in the library. - GroupDataQosPolicy m_groupData; - //!Publication Mode Qos, implemented in the library. - PublishModeQosPolicy m_publishMode; - /** - * Set Qos from another class - * @param qos Reference from a WriterQos object. - * @param first_time Boolean indicating whether is the first time (If not some parameters cannot be set). - */ - RTPS_DllAPI void setQos(const WriterQos& qos, bool first_time); - /** - * Check if the Qos values are compatible between each other. - * @return True if correct. - */ - RTPS_DllAPI bool checkQos() const; + DeadlineQosPolicy m_deadline; + //!Latency Budget Qos, NOT implemented in the library. + LatencyBudgetQosPolicy m_latencyBudget; + //!Liveliness Qos, implemented in the library. + LivelinessQosPolicy m_liveliness; + //!Reliability Qos, implemented in the library. + ReliabilityQosPolicy m_reliability; + //!Lifespan Qos, NOT implemented in the library. + LifespanQosPolicy m_lifespan; + //!UserData Qos, NOT implemented in the library. + UserDataQosPolicy m_userData; + //!Time Based Filter Qos, NOT implemented in the library. + TimeBasedFilterQosPolicy m_timeBasedFilter; + //!Ownership Qos, NOT implemented in the library. + OwnershipQosPolicy m_ownership; + //!Owenership Strength Qos, NOT implemented in the library. + OwnershipStrengthQosPolicy m_ownershipStrength; + //!Destination Order Qos, NOT implemented in the library. + DestinationOrderQosPolicy m_destinationOrder; + //!Presentation Qos, NOT implemented in the library. + PresentationQosPolicy m_presentation; + //!Partition Qos, implemented in the library. + PartitionQosPolicy m_partition; + //!Topic Data Qos, NOT implemented in the library. + TopicDataQosPolicy m_topicData; + //!Group Data Qos, NOT implemented in the library. + GroupDataQosPolicy m_groupData; + //!Publication Mode Qos, implemented in the library. + PublishModeQosPolicy m_publishMode; + /** + * Set Qos from another class + * @param qos Reference from a WriterQos object. + * @param first_time Boolean indicating whether is the first time (If not some parameters cannot be set). + */ + RTPS_DllAPI void setQos(const WriterQos& qos, bool first_time); + /** + * Check if the Qos values are compatible between each other. + * @return True if correct. + */ + RTPS_DllAPI bool checkQos() const; - RTPS_DllAPI bool canQosBeUpdated(const WriterQos& qos) const; + RTPS_DllAPI bool canQosBeUpdated(const WriterQos& qos) const; }; diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index 9ff0cc2e8b5..228acf60126 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -128,32 +128,32 @@ class SubscriberImpl { void onNewCacheChangeAdded(const CacheChange_t* const change); private: - //!Participant - ParticipantImpl* mp_participant; - - //!Pointer to associated RTPSReader - rtps::RTPSReader* mp_reader; - //! Pointer to the TopicDataType object. - TopicDataType* mp_type; - //!Attributes of the Subscriber - SubscriberAttributes m_att; - //!History - SubscriberHistory m_history; - //!Listener - SubscriberListener* mp_listener; - class SubscriberReaderListener : public rtps::ReaderListener - { - public: + + //!Participant + ParticipantImpl* mp_participant; + //!Pointer to associated RTPSReader + rtps::RTPSReader* mp_reader; + //! Pointer to the TopicDataType object. + TopicDataType* mp_type; + //!Attributes of the Subscriber + SubscriberAttributes m_att; + //!History + SubscriberHistory m_history; + //!Listener + SubscriberListener* mp_listener; + class SubscriberReaderListener : public rtps::ReaderListener + { + public: SubscriberReaderListener(SubscriberImpl* s): mp_subscriberImpl(s) {} virtual ~SubscriberReaderListener() {} - void onReaderMatched(rtps::RTPSReader* reader, rtps::MatchingInfo& info); - void onNewCacheChangeAdded(rtps::RTPSReader * reader,const rtps::CacheChange_t* const change); - SubscriberImpl* mp_subscriberImpl; + void onReaderMatched(rtps::RTPSReader* reader, rtps::MatchingInfo& info); + void onNewCacheChangeAdded(rtps::RTPSReader * reader,const rtps::CacheChange_t* const change); + SubscriberImpl* mp_subscriberImpl; } m_readerListener; - Subscriber* mp_userSubscriber; - //!RTPSParticipant - rtps::RTPSParticipant* mp_rtpsParticipant; + Subscriber* mp_userSubscriber; + //!RTPSParticipant + rtps::RTPSParticipant* mp_rtpsParticipant; //!A timer used to check for deadlines DeadlineTimer deadline_timer_; diff --git a/test/blackbox/PubSubReader.hpp b/test/blackbox/PubSubReader.hpp index afe2be9cf6f..20b95270471 100644 --- a/test/blackbox/PubSubReader.hpp +++ b/test/blackbox/PubSubReader.hpp @@ -47,736 +47,739 @@ using eprosima::fastrtps::UDPv4TransportDescriptor; template class PubSubReader { - public: - - typedef TypeSupport type_support; - typedef typename type_support::type type; - - private: - - class ParticipantListener : public eprosima::fastrtps::ParticipantListener - { - public: - - ParticipantListener(PubSubReader &reader) : reader_(reader) {} - - ~ParticipantListener() {} - - void onParticipantDiscovery(eprosima::fastrtps::Participant*, eprosima::fastrtps::ParticipantDiscoveryInfo&& info) override - { - if(reader_.onDiscovery_!= nullptr) - { - std::unique_lock lock(reader_.mutexDiscovery_); - reader_.discovery_result_ |= reader_.onDiscovery_(info); - reader_.cvDiscovery_.notify_one(); - } - - if(info.status == eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT) - { - reader_.participant_matched(); - } - else if(info.status == eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::REMOVED_PARTICIPANT || - info.status == eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DROPPED_PARTICIPANT) - { - reader_.participant_unmatched(); - } - } - -#if HAVE_SECURITY - void onParticipantAuthentication(eprosima::fastrtps::Participant*, eprosima::fastrtps::ParticipantAuthenticationInfo&& info) override - { - if(info.status == eprosima::fastrtps::rtps::ParticipantAuthenticationInfo::AUTHORIZED_PARTICIPANT) - { - reader_.authorized(); - } - else if(info.status == eprosima::fastrtps::rtps::ParticipantAuthenticationInfo::UNAUTHORIZED_PARTICIPANT) - { - reader_.unauthorized(); - } - } -#endif - - private: - - ParticipantListener& operator=(const ParticipantListener&) = delete; - - PubSubReader& reader_; - } participant_listener_; +public: - class Listener: public eprosima::fastrtps::SubscriberListener - { - public: - Listener(PubSubReader &reader) - : reader_(reader) - , times_deadline_missed_(0) - {} - - ~Listener(){} + typedef TypeSupport type_support; + typedef typename type_support::type type; - void onNewDataMessage(eprosima::fastrtps::Subscriber *sub) - { - ASSERT_NE(sub, nullptr); - - if(reader_.receiving_.load()) - { - bool ret = false; - do - { - reader_.receive_one(sub, ret); - } while(ret); - } - } - - void onSubscriptionMatched(eprosima::fastrtps::Subscriber* /*sub*/, eprosima::fastrtps::rtps::MatchingInfo& info) - { - if (info.status == eprosima::fastrtps::rtps::MATCHED_MATCHING) - { - std::cout << "Matched publisher " << info.remoteEndpointGuid << std::endl; - reader_.matched(); - } - else - { - std::cout << "Unmatched publisher " << info.remoteEndpointGuid << std::endl; - reader_.unmatched(); - } - } - - void on_requested_deadline_missed(eprosima::fastrtps::rtps::InstanceHandle_t&) override - { - times_deadline_missed_++; - } - - int missed_deadlines() const - { - return times_deadline_missed_; - } - - private: - - Listener& operator=(const Listener&) = delete; - - PubSubReader& reader_; - - int times_deadline_missed_; - } listener_; - - friend class Listener; +private: + class ParticipantListener : public eprosima::fastrtps::ParticipantListener + { public: - PubSubReader(const std::string& topic_name) - : participant_listener_(*this), - listener_(*this), - participant_(nullptr), - subscriber_(nullptr), - topic_name_(topic_name), - initialized_(false), - matched_(0), - participant_matched_(0), - receiving_(false), - current_received_count_(0), - number_samples_expected_(0), - discovery_result_(false), - onDiscovery_(nullptr) -#if HAVE_SECURITY - , authorized_(0), unauthorized_(0) -#endif - { - subscriber_attr_.topic.topicDataType = type_.getName(); - // Generate topic name - std::ostringstream t; - t << topic_name_ << "_" << asio::ip::host_name() << "_" << GET_PID(); - subscriber_attr_.topic.topicName = t.str(); + ParticipantListener(PubSubReader &reader) : reader_(reader) {} -#if defined(PREALLOCATED_WITH_REALLOC_MEMORY_MODE_TEST) - subscriber_attr_.historyMemoryPolicy = eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE; -#elif defined(DYNAMIC_RESERVE_MEMORY_MODE_TEST) - subscriber_attr_.historyMemoryPolicy = eprosima::fastrtps::rtps::DYNAMIC_RESERVE_MEMORY_MODE; -#else - subscriber_attr_.historyMemoryPolicy = eprosima::fastrtps::rtps::PREALLOCATED_MEMORY_MODE; -#endif + ~ParticipantListener() {} - // By default, heartbeat period delay is 100 milliseconds. - subscriber_attr_.times.heartbeatResponseDelay.seconds = 0; - subscriber_attr_.times.heartbeatResponseDelay.fraction = 4294967 * 100; - } - - ~PubSubReader() + void onParticipantDiscovery(eprosima::fastrtps::Participant*, eprosima::fastrtps::ParticipantDiscoveryInfo&& info) override { - if(participant_ != nullptr) - eprosima::fastrtps::Domain::removeParticipant(participant_); - } - - void init() - { - participant_attr_.rtps.builtin.domainId = (uint32_t)GET_PID() % 230; - participant_ = eprosima::fastrtps::Domain::createParticipant(participant_attr_, &participant_listener_); - - ASSERT_NE(participant_, nullptr); - - participant_guid_ = participant_->getGuid(); - - // Register type - ASSERT_EQ(eprosima::fastrtps::Domain::registerType(participant_, &type_), true); - - //Create subscribe r - subscriber_ = eprosima::fastrtps::Domain::createSubscriber(participant_, subscriber_attr_, &listener_); - ASSERT_NE(subscriber_, nullptr); - - std::cout << "Created subscriber " << subscriber_->getGuid() << " for topic " << - subscriber_attr_.topic.topicName << std::endl; - - initialized_ = true; - } - - bool isInitialized() const { return initialized_; } - - void destroy() - { - if(participant_ != nullptr) + if(reader_.onDiscovery_!= nullptr) { - eprosima::fastrtps::Domain::removeParticipant(participant_); - participant_ = nullptr; + std::unique_lock lock(reader_.mutexDiscovery_); + reader_.discovery_result_ |= reader_.onDiscovery_(info); + reader_.cvDiscovery_.notify_one(); } - } - std::list data_not_received() - { - std::unique_lock lock(mutex_); - return total_msgs_; + if(info.status == eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DISCOVERED_PARTICIPANT) + { + reader_.participant_matched(); + } + else if(info.status == eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::REMOVED_PARTICIPANT || + info.status == eprosima::fastrtps::rtps::ParticipantDiscoveryInfo::DROPPED_PARTICIPANT) + { + reader_.participant_unmatched(); + } } - void startReception(std::list& msgs) +#if HAVE_SECURITY + void onParticipantAuthentication(eprosima::fastrtps::Participant*, eprosima::fastrtps::ParticipantAuthenticationInfo&& info) override { - mutex_.lock(); - total_msgs_ = msgs; - number_samples_expected_ = total_msgs_.size(); - current_received_count_ = 0; - mutex_.unlock(); - - bool ret = false; - do + if(info.status == eprosima::fastrtps::rtps::ParticipantAuthenticationInfo::AUTHORIZED_PARTICIPANT) { - receive_one(subscriber_, ret); + reader_.authorized(); + } + else if(info.status == eprosima::fastrtps::rtps::ParticipantAuthenticationInfo::UNAUTHORIZED_PARTICIPANT) + { + reader_.unauthorized(); } - while(ret); - - receiving_.store(true); } +#endif - void stopReception() - { - receiving_.store(false); - } + private: - void block_for_all() - { - block([this]() -> bool { - return number_samples_expected_ == current_received_count_; - }); - } + ParticipantListener& operator=(const ParticipantListener&) = delete; + PubSubReader& reader_; - size_t block_for_at_least(size_t at_least) - { - block([this, at_least]() -> bool { - return current_received_count_ >= at_least; - }); - return current_received_count_; - } + } participant_listener_; - void block(std::function checker) - { - std::unique_lock lock(mutex_); - cv_.wait(lock, checker); - } + class Listener: public eprosima::fastrtps::SubscriberListener + { + public: - template - size_t block_for_all(const std::chrono::duration<_Rep, _Period>& max_wait) - { - std::unique_lock lock(mutex_); - cv_.wait_for(lock, max_wait, [this]() -> bool { - return number_samples_expected_ == current_received_count_; - }); + Listener(PubSubReader &reader) + : reader_(reader) + , times_deadline_missed_(0) + {} - return current_received_count_; - } + ~Listener(){} - void wait_discovery(std::chrono::seconds timeout = std::chrono::seconds::zero()) + void onNewDataMessage(eprosima::fastrtps::Subscriber *sub) { - std::unique_lock lock(mutexDiscovery_); + ASSERT_NE(sub, nullptr); - std::cout << "Reader is waiting discovery..." << std::endl; + if(reader_.receiving_.load()) + { + bool ret = false; + do + { + reader_.receive_one(sub, ret); + } while(ret); + } + } - if(timeout == std::chrono::seconds::zero()) + void onSubscriptionMatched(eprosima::fastrtps::Subscriber* /*sub*/, eprosima::fastrtps::rtps::MatchingInfo& info) + { + if (info.status == eprosima::fastrtps::rtps::MATCHED_MATCHING) { - cvDiscovery_.wait(lock, [&](){return matched_ != 0;}); + std::cout << "Matched publisher " << info.remoteEndpointGuid << std::endl; + reader_.matched(); } else { - cvDiscovery_.wait_for(lock, timeout, [&](){return matched_ != 0;}); + std::cout << "Unmatched publisher " << info.remoteEndpointGuid << std::endl; + reader_.unmatched(); } + } - std::cout << "Reader discovery finished..." << std::endl; + void on_requested_deadline_missed(eprosima::fastrtps::rtps::InstanceHandle_t&) override + { + times_deadline_missed_++; } - void wait_participant_undiscovery() + int missed_deadlines() const { - std::unique_lock lock(mutexDiscovery_); + return times_deadline_missed_; + } - std::cout << "Reader is waiting undiscovery..." << std::endl; + private: - cvDiscovery_.wait(lock, [&](){return participant_matched_ == 0;}); + Listener& operator=(const Listener&) = delete; - std::cout << "Reader undiscovery finished..." << std::endl; - } + PubSubReader& reader_; - void wait_writer_undiscovery() - { - std::unique_lock lock(mutexDiscovery_); + int times_deadline_missed_; - std::cout << "Reader is waiting removal..." << std::endl; + } listener_; - cvDiscovery_.wait(lock, [&](){return matched_ == 0;}); + friend class Listener; - std::cout << "Reader removal finished..." << std::endl; - } +public: + PubSubReader(const std::string& topic_name) + : participant_listener_(*this) + , listener_(*this) + , participant_(nullptr) + , subscriber_(nullptr) + , topic_name_(topic_name) + , initialized_(false) + , matched_(0) + , participant_matched_(0) + , receiving_(false) + , current_received_count_(0) + , number_samples_expected_(0) + , discovery_result_(false) + , onDiscovery_(nullptr) #if HAVE_SECURITY - void waitAuthorized() + , authorized_(0) + , unauthorized_(0) +#endif { - std::unique_lock lock(mutexAuthentication_); - - std::cout << "Reader is waiting authorization..." << std::endl; + subscriber_attr_.topic.topicDataType = type_.getName(); + // Generate topic name + std::ostringstream t; + t << topic_name_ << "_" << asio::ip::host_name() << "_" << GET_PID(); + subscriber_attr_.topic.topicName = t.str(); - cvAuthentication_.wait(lock, [&]() -> bool { return authorized_ > 0; }); +#if defined(PREALLOCATED_WITH_REALLOC_MEMORY_MODE_TEST) + subscriber_attr_.historyMemoryPolicy = eprosima::fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE; +#elif defined(DYNAMIC_RESERVE_MEMORY_MODE_TEST) + subscriber_attr_.historyMemoryPolicy = eprosima::fastrtps::rtps::DYNAMIC_RESERVE_MEMORY_MODE; +#else + subscriber_attr_.historyMemoryPolicy = eprosima::fastrtps::rtps::PREALLOCATED_MEMORY_MODE; +#endif - std::cout << "Reader authorization finished..." << std::endl; + // By default, heartbeat period delay is 100 milliseconds. + subscriber_attr_.times.heartbeatResponseDelay.seconds = 0; + subscriber_attr_.times.heartbeatResponseDelay.fraction = 4294967 * 100; } - void waitUnauthorized() - { - std::unique_lock lock(mutexAuthentication_); + ~PubSubReader() + { + if(participant_ != nullptr) + eprosima::fastrtps::Domain::removeParticipant(participant_); + } - std::cout << "Reader is waiting unauthorization..." << std::endl; + void init() + { + participant_attr_.rtps.builtin.domainId = (uint32_t)GET_PID() % 230; + participant_ = eprosima::fastrtps::Domain::createParticipant(participant_attr_, &participant_listener_); - cvAuthentication_.wait(lock, [&]() -> bool { return unauthorized_ > 0; }); + ASSERT_NE(participant_, nullptr); - std::cout << "Reader unauthorization finished..." << std::endl; - } -#endif + participant_guid_ = participant_->getGuid(); - size_t getReceivedCount() const - { - return current_received_count_; - } + // Register type + ASSERT_EQ(eprosima::fastrtps::Domain::registerType(participant_, &type_), true); - /*** Function to change QoS ***/ - PubSubReader& reliability(const eprosima::fastrtps::ReliabilityQosPolicyKind kind) - { - subscriber_attr_.qos.m_reliability.kind = kind; - return *this; - } + //Create subscribe r + subscriber_ = eprosima::fastrtps::Domain::createSubscriber(participant_, subscriber_attr_, &listener_); + ASSERT_NE(subscriber_, nullptr); - PubSubReader& deadline_period(const eprosima::fastrtps::rtps::Duration_t deadline_period) - { - subscriber_attr_.qos.m_deadline.period = deadline_period; - return *this; - } + std::cout << "Created subscriber " << subscriber_->getGuid() << " for topic " << + subscriber_attr_.topic.topicName << std::endl; - PubSubReader& key(bool keyed) - { - subscriber_attr_.topic.topicKind = keyed ? eprosima::fastrtps::TopicKind_t::WITH_KEY : eprosima::fastrtps::TopicKind_t::NO_KEY; - return *this; - } - - PubSubReader& topic_kind(const eprosima::fastrtps::rtps::TopicKind_t kind) - { - subscriber_attr_.topic.topicKind = kind; - return *this; - } + initialized_ = true; + } - PubSubReader& history_kind(const eprosima::fastrtps::HistoryQosPolicyKind kind) - { - subscriber_attr_.topic.historyQos.kind = kind; - return *this; - } + bool isInitialized() const { return initialized_; } - PubSubReader& history_depth(const int32_t depth) + void destroy() + { + if(participant_ != nullptr) { - subscriber_attr_.topic.historyQos.depth = depth; - return *this; + eprosima::fastrtps::Domain::removeParticipant(participant_); + participant_ = nullptr; } + } - PubSubReader& disable_builtin_transport() - { - participant_attr_.rtps.useBuiltinTransports = false; - return *this; - } + std::list data_not_received() + { + std::unique_lock lock(mutex_); + return total_msgs_; + } - PubSubReader& add_user_transport_to_pparams(std::shared_ptr userTransportDescriptor) - { - participant_attr_.rtps.userTransports.push_back(userTransportDescriptor); - return *this; - } + void startReception(std::list& msgs) + { + mutex_.lock(); + total_msgs_ = msgs; + number_samples_expected_ = total_msgs_.size(); + current_received_count_ = 0; + mutex_.unlock(); - PubSubReader& resource_limits_allocated_samples(const int32_t initial) + bool ret = false; + do { - subscriber_attr_.topic.resourceLimitsQos.allocated_samples = initial; - return *this; + receive_one(subscriber_, ret); } + while(ret); - PubSubReader& resource_limits_max_samples(const int32_t max) - { - subscriber_attr_.topic.resourceLimitsQos.max_samples = max; - return *this; - } + receiving_.store(true); + } - PubSubReader& heartbeatResponseDelay(const int32_t secs, const int32_t frac) - { - subscriber_attr_.times.heartbeatResponseDelay.seconds = secs; - subscriber_attr_.times.heartbeatResponseDelay.fraction = frac; - return *this; - } + void stopReception() + { + receiving_.store(false); + } - PubSubReader& unicastLocatorList(eprosima::fastrtps::rtps::LocatorList_t unicastLocators) - { - subscriber_attr_.unicastLocatorList = unicastLocators; - return *this; - } + void block_for_all() + { + block([this]() -> bool { + return number_samples_expected_ == current_received_count_; + }); + } - PubSubReader& add_to_unicast_locator_list(const std::string& ip, uint32_t port) - { - eprosima::fastrtps::rtps::Locator_t loc; - IPLocator::setIPv4(loc, ip); - loc.port = port; - subscriber_attr_.unicastLocatorList.push_back(loc); + size_t block_for_at_least(size_t at_least) + { + block([this, at_least]() -> bool { + return current_received_count_ >= at_least; + }); + return current_received_count_; + } - return *this; - } + void block(std::function checker) + { + std::unique_lock lock(mutex_); + cv_.wait(lock, checker); + } - PubSubReader& multicastLocatorList(eprosima::fastrtps::rtps::LocatorList_t multicastLocators) - { - subscriber_attr_.multicastLocatorList = multicastLocators; - return *this; - } + template + size_t block_for_all(const std::chrono::duration<_Rep, _Period>& max_wait) + { + std::unique_lock lock(mutex_); + cv_.wait_for(lock, max_wait, [this]() -> bool { + return number_samples_expected_ == current_received_count_; + }); - PubSubReader& add_to_multicast_locator_list(const std::string& ip, uint32_t port) - { - eprosima::fastrtps::rtps::Locator_t loc; - IPLocator::setIPv4(loc, ip); - loc.port = port; - subscriber_attr_.multicastLocatorList.push_back(loc); + return current_received_count_; + } - return *this; - } + void wait_discovery(std::chrono::seconds timeout = std::chrono::seconds::zero()) + { + std::unique_lock lock(mutexDiscovery_); - PubSubReader& metatraffic_unicast_locator_list(eprosima::fastrtps::rtps::LocatorList_t unicastLocators) - { - participant_attr_.rtps.builtin.metatrafficUnicastLocatorList = unicastLocators; - return *this; - } + std::cout << "Reader is waiting discovery..." << std::endl; - PubSubReader& add_to_metatraffic_unicast_locator_list(const std::string& ip, uint32_t port) + if(timeout == std::chrono::seconds::zero()) { - eprosima::fastrtps::rtps::Locator_t loc; - IPLocator::setIPv4(loc, ip); - loc.port = port; - participant_attr_.rtps.builtin.metatrafficUnicastLocatorList.push_back(loc); - - return *this; + cvDiscovery_.wait(lock, [&](){return matched_ != 0;}); } - - PubSubReader& metatraffic_multicast_locator_list(eprosima::fastrtps::rtps::LocatorList_t unicastLocators) + else { - participant_attr_.rtps.builtin.metatrafficMulticastLocatorList = unicastLocators; - return *this; + cvDiscovery_.wait_for(lock, timeout, [&](){return matched_ != 0;}); } - PubSubReader& add_to_metatraffic_multicast_locator_list(const std::string& ip, uint32_t port) - { - eprosima::fastrtps::rtps::Locator_t loc; - IPLocator::setIPv4(loc, ip); - loc.port = port; - participant_attr_.rtps.builtin.metatrafficMulticastLocatorList.push_back(loc); + std::cout << "Reader discovery finished..." << std::endl; + } - return *this; - } + void wait_participant_undiscovery() + { + std::unique_lock lock(mutexDiscovery_); - PubSubReader& initial_peers(eprosima::fastrtps::rtps::LocatorList_t initial_peers) - { - participant_attr_.rtps.builtin.initialPeersList = initial_peers; - return *this; - } + std::cout << "Reader is waiting undiscovery..." << std::endl; - PubSubReader& durability_kind(const eprosima::fastrtps::DurabilityQosPolicyKind kind) - { - subscriber_attr_.qos.m_durability.kind = kind; - return *this; - } + cvDiscovery_.wait(lock, [&](){return participant_matched_ == 0;}); - PubSubReader& static_discovery(const char* filename) - { - participant_attr_.rtps.builtin.use_SIMPLE_EndpointDiscoveryProtocol = false; - participant_attr_.rtps.builtin.use_STATIC_EndpointDiscoveryProtocol = true; - participant_attr_.rtps.builtin.setStaticEndpointXMLFilename(filename); - return *this; - } + std::cout << "Reader undiscovery finished..." << std::endl; + } - PubSubReader& setSubscriberIDs(uint8_t UserID, uint8_t EntityID) - { - subscriber_attr_.setUserDefinedID(UserID); - subscriber_attr_.setEntityID(EntityID); - return *this; + void wait_writer_undiscovery() + { + std::unique_lock lock(mutexDiscovery_); - } + std::cout << "Reader is waiting removal..." << std::endl; - PubSubReader& setManualTopicName(std::string topicName) - { - subscriber_attr_.topic.topicName=topicName; - return *this; - } + cvDiscovery_.wait(lock, [&](){return matched_ == 0;}); - PubSubReader& disable_multicast(int32_t participantId) - { - participant_attr_.rtps.participantID = participantId; + std::cout << "Reader removal finished..." << std::endl; + } - eprosima::fastrtps::rtps::LocatorList_t default_unicast_locators; - eprosima::fastrtps::rtps::Locator_t default_unicast_locator; +#if HAVE_SECURITY + void waitAuthorized() + { + std::unique_lock lock(mutexAuthentication_); - default_unicast_locators.push_back(default_unicast_locator); - participant_attr_.rtps.builtin.metatrafficUnicastLocatorList = default_unicast_locators; + std::cout << "Reader is waiting authorization..." << std::endl; - eprosima::fastrtps::rtps::Locator_t loopback_locator; - IPLocator::setIPv4(loopback_locator, 127, 0, 0, 1); - participant_attr_.rtps.builtin.initialPeersList.push_back(loopback_locator); - return *this; - } + cvAuthentication_.wait(lock, [&]() -> bool { return authorized_ > 0; }); - PubSubReader& property_policy(const eprosima::fastrtps::rtps::PropertyPolicy property_policy) - { - participant_attr_.rtps.properties = property_policy; - return *this; - } + std::cout << "Reader authorization finished..." << std::endl; + } - PubSubReader& entity_property_policy(const eprosima::fastrtps::rtps::PropertyPolicy property_policy) - { - subscriber_attr_.properties = property_policy; - return *this; - } + void waitUnauthorized() + { + std::unique_lock lock(mutexAuthentication_); - PubSubReader& partition(const std::string& partition) - { - subscriber_attr_.qos.m_partition.push_back(partition.c_str()); - return *this; - } + std::cout << "Reader is waiting unauthorization..." << std::endl; - PubSubReader& userData(std::vector user_data) - { - participant_attr_.rtps.userData = user_data; - return *this; - } + cvAuthentication_.wait(lock, [&]() -> bool { return unauthorized_ > 0; }); - PubSubReader& lease_duration(eprosima::fastrtps::rtps::Duration_t lease_duration, eprosima::fastrtps::rtps::Duration_t announce_period) - { - participant_attr_.rtps.builtin.leaseDuration = lease_duration; - participant_attr_.rtps.builtin.leaseDuration_announcementperiod = announce_period; - return *this; - } + std::cout << "Reader unauthorization finished..." << std::endl; + } +#endif - PubSubReader& load_participant_attr(const std::string& xml) - { - std::unique_ptr root; - if (eprosima::fastrtps::xmlparser::XMLParser::loadXML(xml.data(), xml.size(), root) == eprosima::fastrtps::xmlparser::XMLP_ret::XML_OK) + size_t getReceivedCount() const + { + return current_received_count_; + } + + /*** Function to change QoS ***/ + PubSubReader& reliability(const eprosima::fastrtps::ReliabilityQosPolicyKind kind) + { + subscriber_attr_.qos.m_reliability.kind = kind; + return *this; + } + + PubSubReader& deadline_period(const eprosima::fastrtps::rtps::Duration_t deadline_period) + { + subscriber_attr_.qos.m_deadline.period = deadline_period; + return *this; + } + + PubSubReader& key(bool keyed) + { + subscriber_attr_.topic.topicKind = keyed ? eprosima::fastrtps::TopicKind_t::WITH_KEY : eprosima::fastrtps::TopicKind_t::NO_KEY; + return *this; + } + + PubSubReader& topic_kind(const eprosima::fastrtps::rtps::TopicKind_t kind) + { + subscriber_attr_.topic.topicKind = kind; + return *this; + } + + PubSubReader& history_kind(const eprosima::fastrtps::HistoryQosPolicyKind kind) + { + subscriber_attr_.topic.historyQos.kind = kind; + return *this; + } + + PubSubReader& history_depth(const int32_t depth) + { + subscriber_attr_.topic.historyQos.depth = depth; + return *this; + } + + PubSubReader& disable_builtin_transport() + { + participant_attr_.rtps.useBuiltinTransports = false; + return *this; + } + + PubSubReader& add_user_transport_to_pparams(std::shared_ptr userTransportDescriptor) + { + participant_attr_.rtps.userTransports.push_back(userTransportDescriptor); + return *this; + } + + PubSubReader& resource_limits_allocated_samples(const int32_t initial) + { + subscriber_attr_.topic.resourceLimitsQos.allocated_samples = initial; + return *this; + } + + PubSubReader& resource_limits_max_samples(const int32_t max) + { + subscriber_attr_.topic.resourceLimitsQos.max_samples = max; + return *this; + } + + PubSubReader& heartbeatResponseDelay(const int32_t secs, const int32_t frac) + { + subscriber_attr_.times.heartbeatResponseDelay.seconds = secs; + subscriber_attr_.times.heartbeatResponseDelay.fraction = frac; + return *this; + } + + PubSubReader& unicastLocatorList(eprosima::fastrtps::rtps::LocatorList_t unicastLocators) + { + subscriber_attr_.unicastLocatorList = unicastLocators; + return *this; + } + + PubSubReader& add_to_unicast_locator_list(const std::string& ip, uint32_t port) + { + eprosima::fastrtps::rtps::Locator_t loc; + IPLocator::setIPv4(loc, ip); + loc.port = port; + subscriber_attr_.unicastLocatorList.push_back(loc); + + return *this; + } + + PubSubReader& multicastLocatorList(eprosima::fastrtps::rtps::LocatorList_t multicastLocators) + { + subscriber_attr_.multicastLocatorList = multicastLocators; + return *this; + } + + PubSubReader& add_to_multicast_locator_list(const std::string& ip, uint32_t port) + { + eprosima::fastrtps::rtps::Locator_t loc; + IPLocator::setIPv4(loc, ip); + loc.port = port; + subscriber_attr_.multicastLocatorList.push_back(loc); + + return *this; + } + + PubSubReader& metatraffic_unicast_locator_list(eprosima::fastrtps::rtps::LocatorList_t unicastLocators) + { + participant_attr_.rtps.builtin.metatrafficUnicastLocatorList = unicastLocators; + return *this; + } + + PubSubReader& add_to_metatraffic_unicast_locator_list(const std::string& ip, uint32_t port) + { + eprosima::fastrtps::rtps::Locator_t loc; + IPLocator::setIPv4(loc, ip); + loc.port = port; + participant_attr_.rtps.builtin.metatrafficUnicastLocatorList.push_back(loc); + + return *this; + } + + PubSubReader& metatraffic_multicast_locator_list(eprosima::fastrtps::rtps::LocatorList_t unicastLocators) + { + participant_attr_.rtps.builtin.metatrafficMulticastLocatorList = unicastLocators; + return *this; + } + + PubSubReader& add_to_metatraffic_multicast_locator_list(const std::string& ip, uint32_t port) + { + eprosima::fastrtps::rtps::Locator_t loc; + IPLocator::setIPv4(loc, ip); + loc.port = port; + participant_attr_.rtps.builtin.metatrafficMulticastLocatorList.push_back(loc); + + return *this; + } + + PubSubReader& initial_peers(eprosima::fastrtps::rtps::LocatorList_t initial_peers) + { + participant_attr_.rtps.builtin.initialPeersList = initial_peers; + return *this; + } + + PubSubReader& durability_kind(const eprosima::fastrtps::DurabilityQosPolicyKind kind) + { + subscriber_attr_.qos.m_durability.kind = kind; + return *this; + } + + PubSubReader& static_discovery(const char* filename) + { + participant_attr_.rtps.builtin.use_SIMPLE_EndpointDiscoveryProtocol = false; + participant_attr_.rtps.builtin.use_STATIC_EndpointDiscoveryProtocol = true; + participant_attr_.rtps.builtin.setStaticEndpointXMLFilename(filename); + return *this; + } + + PubSubReader& setSubscriberIDs(uint8_t UserID, uint8_t EntityID) + { + subscriber_attr_.setUserDefinedID(UserID); + subscriber_attr_.setEntityID(EntityID); + return *this; + + } + + PubSubReader& setManualTopicName(std::string topicName) + { + subscriber_attr_.topic.topicName=topicName; + return *this; + } + + PubSubReader& disable_multicast(int32_t participantId) + { + participant_attr_.rtps.participantID = participantId; + + eprosima::fastrtps::rtps::LocatorList_t default_unicast_locators; + eprosima::fastrtps::rtps::Locator_t default_unicast_locator; + + default_unicast_locators.push_back(default_unicast_locator); + participant_attr_.rtps.builtin.metatrafficUnicastLocatorList = default_unicast_locators; + + eprosima::fastrtps::rtps::Locator_t loopback_locator; + IPLocator::setIPv4(loopback_locator, 127, 0, 0, 1); + participant_attr_.rtps.builtin.initialPeersList.push_back(loopback_locator); + return *this; + } + + PubSubReader& property_policy(const eprosima::fastrtps::rtps::PropertyPolicy property_policy) + { + participant_attr_.rtps.properties = property_policy; + return *this; + } + + PubSubReader& entity_property_policy(const eprosima::fastrtps::rtps::PropertyPolicy property_policy) + { + subscriber_attr_.properties = property_policy; + return *this; + } + + PubSubReader& partition(const std::string& partition) + { + subscriber_attr_.qos.m_partition.push_back(partition.c_str()); + return *this; + } + + PubSubReader& userData(std::vector user_data) + { + participant_attr_.rtps.userData = user_data; + return *this; + } + + PubSubReader& lease_duration(eprosima::fastrtps::rtps::Duration_t lease_duration, eprosima::fastrtps::rtps::Duration_t announce_period) + { + participant_attr_.rtps.builtin.leaseDuration = lease_duration; + participant_attr_.rtps.builtin.leaseDuration_announcementperiod = announce_period; + return *this; + } + + PubSubReader& load_participant_attr(const std::string& xml) + { + std::unique_ptr root; + if (eprosima::fastrtps::xmlparser::XMLParser::loadXML(xml.data(), xml.size(), root) == eprosima::fastrtps::xmlparser::XMLP_ret::XML_OK) + { + for (const auto& profile : root->getChildren()) { - for (const auto& profile : root->getChildren()) + if (profile->getType() == eprosima::fastrtps::xmlparser::NodeType::PARTICIPANT) { - if (profile->getType() == eprosima::fastrtps::xmlparser::NodeType::PARTICIPANT) - { - participant_attr_ = *(dynamic_cast*>(profile.get())->get()); - } + participant_attr_ = *(dynamic_cast*>(profile.get())->get()); } } - return *this; } + return *this; + } - PubSubReader& load_subscriber_attr(const std::string& xml) + PubSubReader& load_subscriber_attr(const std::string& xml) + { + std::unique_ptr root; + if (eprosima::fastrtps::xmlparser::XMLParser::loadXML(xml.data(), xml.size(), root) == eprosima::fastrtps::xmlparser::XMLP_ret::XML_OK) { - std::unique_ptr root; - if (eprosima::fastrtps::xmlparser::XMLParser::loadXML(xml.data(), xml.size(), root) == eprosima::fastrtps::xmlparser::XMLP_ret::XML_OK) + for (const auto& profile : root->getChildren()) { - for (const auto& profile : root->getChildren()) + if (profile->getType() == eprosima::fastrtps::xmlparser::NodeType::SUBSCRIBER) { - if (profile->getType() == eprosima::fastrtps::xmlparser::NodeType::SUBSCRIBER) - { - subscriber_attr_ = *(dynamic_cast*>(profile.get())->get()); - } + subscriber_attr_ = *(dynamic_cast*>(profile.get())->get()); } } - return *this; - } - - PubSubReader& max_initial_peers_range(uint32_t maxInitialPeerRange) - { - participant_attr_.rtps.useBuiltinTransports = false; - std::shared_ptr descriptor = std::make_shared(); - descriptor->maxInitialPeersRange = maxInitialPeerRange; - participant_attr_.rtps.userTransports.push_back(descriptor); - return *this; - } - - PubSubReader& participant_id(int32_t participantId) - { - participant_attr_.rtps.participantID = participantId; - return *this; } + return *this; + } - bool update_partition(const std::string& partition) - { - subscriber_attr_.qos.m_partition.clear(); - subscriber_attr_.qos.m_partition.push_back(partition.c_str()); - return subscriber_->updateAttributes(subscriber_attr_); - } + PubSubReader& max_initial_peers_range(uint32_t maxInitialPeerRange) + { + participant_attr_.rtps.useBuiltinTransports = false; + std::shared_ptr descriptor = std::make_shared(); + descriptor->maxInitialPeersRange = maxInitialPeerRange; + participant_attr_.rtps.userTransports.push_back(descriptor); + return *this; + } - /*** Function for discovery callback ***/ - - void wait_discovery_result() - { - std::unique_lock lock(mutexDiscovery_); + PubSubReader& participant_id(int32_t participantId) + { + participant_attr_.rtps.participantID = participantId; + return *this; + } - std::cout << "Reader is waiting discovery result..." << std::endl; + bool update_partition(const std::string& partition) + { + subscriber_attr_.qos.m_partition.clear(); + subscriber_attr_.qos.m_partition.push_back(partition.c_str()); + return subscriber_->updateAttributes(subscriber_attr_); + } - cvDiscovery_.wait(lock, [&](){return discovery_result_;}); + /*** Function for discovery callback ***/ - std::cout << "Reader gets discovery result..." << std::endl; - } - - void setOnDiscoveryFunction(std::function f){ - onDiscovery_ = f; - } + void wait_discovery_result() + { + std::unique_lock lock(mutexDiscovery_); - const eprosima::fastrtps::rtps::GUID_t& participant_guid() const - { - return participant_guid_; - } + std::cout << "Reader is waiting discovery result..." << std::endl; - bool is_matched() const - { - return matched_ > 0; - } + cvDiscovery_.wait(lock, [&](){return discovery_result_;}); - int missed_deadlines() const - { - return listener_.missed_deadlines(); - } + std::cout << "Reader gets discovery result..." << std::endl; + } - private: + void setOnDiscoveryFunction(std::function f){ + onDiscovery_ = f; + } - void receive_one(eprosima::fastrtps::Subscriber* subscriber, bool& returnedValue) - { - returnedValue = false; - type data; - eprosima::fastrtps::SampleInfo_t info; + const eprosima::fastrtps::rtps::GUID_t& participant_guid() const + { + return participant_guid_; + } - if(subscriber->takeNextData((void*)&data, &info)) - { - returnedValue = true; + bool is_matched() const + { + return matched_ > 0; + } - std::unique_lock lock(mutex_); + int missed_deadlines() const + { + return listener_.missed_deadlines(); + } - // Check order of changes. - ASSERT_LT(last_seq, info.sample_identity.sequence_number()); - last_seq = info.sample_identity.sequence_number(); +private: - if(info.sampleKind == eprosima::fastrtps::rtps::ALIVE) - { - auto it = std::find(total_msgs_.begin(), total_msgs_.end(), data); - ASSERT_NE(it, total_msgs_.end()); - total_msgs_.erase(it); - ++current_received_count_; - default_receive_print(data); - cv_.notify_one(); - } - } - } + void receive_one(eprosima::fastrtps::Subscriber* subscriber, bool& returnedValue) + { + returnedValue = false; + type data; + eprosima::fastrtps::SampleInfo_t info; - void participant_matched() + if(subscriber->takeNextData((void*)&data, &info)) { - std::unique_lock lock(mutexDiscovery_); - ++participant_matched_; - cvDiscovery_.notify_one(); - } + returnedValue = true; - void participant_unmatched() - { - std::unique_lock lock(mutexDiscovery_); - --participant_matched_; - cvDiscovery_.notify_one(); - } + std::unique_lock lock(mutex_); - void matched() - { - std::unique_lock lock(mutexDiscovery_); - ++matched_; - cvDiscovery_.notify_one(); - } + // Check order of changes. + ASSERT_LT(last_seq, info.sample_identity.sequence_number()); + last_seq = info.sample_identity.sequence_number(); - void unmatched() - { - std::unique_lock lock(mutexDiscovery_); - --matched_; - cvDiscovery_.notify_one(); + if(info.sampleKind == eprosima::fastrtps::rtps::ALIVE) + { + auto it = std::find(total_msgs_.begin(), total_msgs_.end(), data); + ASSERT_NE(it, total_msgs_.end()); + total_msgs_.erase(it); + ++current_received_count_; + default_receive_print(data); + cv_.notify_one(); + } } + } + + void participant_matched() + { + std::unique_lock lock(mutexDiscovery_); + ++participant_matched_; + cvDiscovery_.notify_one(); + } + + void participant_unmatched() + { + std::unique_lock lock(mutexDiscovery_); + --participant_matched_; + cvDiscovery_.notify_one(); + } + + void matched() + { + std::unique_lock lock(mutexDiscovery_); + ++matched_; + cvDiscovery_.notify_one(); + } + + void unmatched() + { + std::unique_lock lock(mutexDiscovery_); + --matched_; + cvDiscovery_.notify_one(); + } #if HAVE_SECURITY - void authorized() - { - mutexAuthentication_.lock(); - ++authorized_; - mutexAuthentication_.unlock(); - cvAuthentication_.notify_all(); - } - - void unauthorized() - { - mutexAuthentication_.lock(); - ++unauthorized_; - mutexAuthentication_.unlock(); - cvAuthentication_.notify_all(); - } + void authorized() + { + mutexAuthentication_.lock(); + ++authorized_; + mutexAuthentication_.unlock(); + cvAuthentication_.notify_all(); + } + + void unauthorized() + { + mutexAuthentication_.lock(); + ++unauthorized_; + mutexAuthentication_.unlock(); + cvAuthentication_.notify_all(); + } #endif - PubSubReader& operator=(const PubSubReader&)= delete; - - eprosima::fastrtps::Participant *participant_; - eprosima::fastrtps::ParticipantAttributes participant_attr_; - eprosima::fastrtps::Subscriber *subscriber_; - eprosima::fastrtps::SubscriberAttributes subscriber_attr_; - std::string topic_name_; - eprosima::fastrtps::rtps::GUID_t participant_guid_; - bool initialized_; - std::list total_msgs_; - std::mutex mutex_; - std::condition_variable cv_; - std::mutex mutexDiscovery_; - std::condition_variable cvDiscovery_; - std::atomic matched_; - unsigned int participant_matched_; - std::atomic receiving_; - type_support type_; - eprosima::fastrtps::rtps::SequenceNumber_t last_seq; - size_t current_received_count_; - size_t number_samples_expected_; - bool discovery_result_; - - std::function onDiscovery_; + PubSubReader& operator=(const PubSubReader&)= delete; + + eprosima::fastrtps::Participant *participant_; + eprosima::fastrtps::ParticipantAttributes participant_attr_; + eprosima::fastrtps::Subscriber *subscriber_; + eprosima::fastrtps::SubscriberAttributes subscriber_attr_; + std::string topic_name_; + eprosima::fastrtps::rtps::GUID_t participant_guid_; + bool initialized_; + std::list total_msgs_; + std::mutex mutex_; + std::condition_variable cv_; + std::mutex mutexDiscovery_; + std::condition_variable cvDiscovery_; + std::atomic matched_; + unsigned int participant_matched_; + std::atomic receiving_; + type_support type_; + eprosima::fastrtps::rtps::SequenceNumber_t last_seq; + size_t current_received_count_; + size_t number_samples_expected_; + bool discovery_result_; + + std::function onDiscovery_; #if HAVE_SECURITY - std::mutex mutexAuthentication_; - std::condition_variable cvAuthentication_; - unsigned int authorized_; - unsigned int unauthorized_; + std::mutex mutexAuthentication_; + std::condition_variable cvAuthentication_; + unsigned int authorized_; + unsigned int unauthorized_; #endif }; diff --git a/test/blackbox/types/KeyedHelloWorld.h b/test/blackbox/types/KeyedHelloWorld.h index 181731f5501..ec2f6f52ef1 100644 --- a/test/blackbox/types/KeyedHelloWorld.h +++ b/test/blackbox/types/KeyedHelloWorld.h @@ -36,20 +36,6 @@ #define eProsima_user_DllExport #endif -#if defined(_WIN32) -#if defined(EPROSIMA_USER_DLL_EXPORT) -#if defined(deadlinemessage_SOURCE) -#define deadlinemessage_DllAPI __declspec( dllexport ) -#else -#define deadlinemessage_DllAPI __declspec( dllimport ) -#endif // deadlinemessage_SOURCE -#else -#define deadlinemessage_DllAPI -#endif -#else -#define deadlinemessage_DllAPI -#endif // _WIN32 - namespace eprosima { namespace fastcdr From 60b7a35a94852d5480115e172f07b0aaf94db2e2 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Fri, 8 Mar 2019 10:49:12 +0100 Subject: [PATCH 23/54] Refs #4693 Added Offered/RequestedDeadlineMissedStatus defined in the DDS standard --- .../deadlinepayloadPublisher.cxx | 6 +- .../deadlinepayloadPublisher.h | 8 ++- .../deadlinepayloadSubscriber.cxx | 6 +- .../deadlinepayloadSubscriber.h | 8 ++- .../fastrtps/publisher/PublisherListener.h | 31 +++++++---- .../qos/OfferedDeadlineMissedStatus.h | 55 +++++++++++++++++++ .../qos/RequestedDeadlineMissedStatus.h | 55 +++++++++++++++++++ .../fastrtps/subscriber/SubscriberListener.h | 21 ++++--- src/cpp/publisher/PublisherImpl.cpp | 7 ++- src/cpp/publisher/PublisherImpl.h | 3 + src/cpp/subscriber/SubscriberImpl.cpp | 6 +- src/cpp/subscriber/SubscriberImpl.h | 10 ++-- test/blackbox/PubSubReader.hpp | 8 ++- 13 files changed, 190 insertions(+), 34 deletions(-) create mode 100644 include/fastrtps/qos/OfferedDeadlineMissedStatus.h create mode 100644 include/fastrtps/qos/RequestedDeadlineMissedStatus.h diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx index 418e24ac964..819911b1495 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx @@ -90,9 +90,11 @@ void deadlinepayloadPublisher::PubListener::onPublicationMatched(Publisher* /*pu } } -void deadlinepayloadPublisher::PubListener::on_offered_deadline_missed(InstanceHandle_t &handle) +void deadlinepayloadPublisher::PubListener::on_offered_deadline_missed( + Publisher* pub, + OfferedDeadlineMissedStatus& status) { - std::cout << "Publisher listener: deadline missed for instance " << handle << std::endl; + std::cout << "Publisher " << pub->getGuid() << " missed the deadline. Last instance: " << status.last_instance_handle << std::endl; } void deadlinepayloadPublisher::run(double sleep_ms, int samples) diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h index 7447c302dee..03acc3397ce 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h @@ -58,8 +58,12 @@ class deadlinepayloadPublisher public: PubListener() : n_matched(0){}; ~PubListener(){}; - void onPublicationMatched(eprosima::fastrtps::Publisher* pub, eprosima::fastrtps::rtps::MatchingInfo& info) override; - void on_offered_deadline_missed(eprosima::fastrtps::rtps::InstanceHandle_t& handle) override; + void onPublicationMatched( + eprosima::fastrtps::Publisher* pub, + eprosima::fastrtps::rtps::MatchingInfo& info) override; + void on_offered_deadline_missed( + eprosima::fastrtps::Publisher* pub, + eprosima::fastrtps::OfferedDeadlineMissedStatus& status) override; int n_matched; } m_listener; diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx index 69ad2835a25..62b25e19512 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx @@ -99,9 +99,11 @@ void deadlinepayloadSubscriber::SubListener::onNewDataMessage(Subscriber* sub) } } -void deadlinepayloadSubscriber::SubListener::on_requested_deadline_missed(InstanceHandle_t &handle) +void deadlinepayloadSubscriber::SubListener::on_requested_deadline_missed( + Subscriber* sub, + RequestedDeadlineMissedStatus& status) { - std::cout << "Subscriber listener: deadline missed for instance " << handle << std::endl; + std::cout << "Subscriber " << sub->getGuid() << " missed the deadline for instance " << status.last_instance_handle << std::endl; } void deadlinepayloadSubscriber::run() diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.h b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.h index cc84f7f128f..f4763ad5205 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.h +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.h @@ -65,9 +65,13 @@ class deadlinepayloadSubscriber public: SubListener() : n_matched(0),n_msg(0){}; ~SubListener(){}; - void onSubscriptionMatched(eprosima::fastrtps::Subscriber* sub, eprosima::fastrtps::rtps::MatchingInfo& info) override; + void onSubscriptionMatched( + eprosima::fastrtps::Subscriber* sub, + eprosima::fastrtps::rtps::MatchingInfo& info) override; void onNewDataMessage(eprosima::fastrtps::Subscriber* sub) override; - void on_requested_deadline_missed(eprosima::fastrtps::rtps::InstanceHandle_t& handle) override; + void on_requested_deadline_missed( + eprosima::fastrtps::Subscriber* sub, + eprosima::fastrtps::RequestedDeadlineMissedStatus& status) override; eprosima::fastrtps::SampleInfo_t m_info; int n_matched; int n_msg; diff --git a/include/fastrtps/publisher/PublisherListener.h b/include/fastrtps/publisher/PublisherListener.h index 0efa1e164f7..f87399c70c3 100644 --- a/include/fastrtps/publisher/PublisherListener.h +++ b/include/fastrtps/publisher/PublisherListener.h @@ -21,17 +21,13 @@ #include "../rtps/common/Types.h" #include "../rtps/common/MatchingInfo.h" +#include "../qos/OfferedDeadlineMissedStatus.h" namespace eprosima { namespace fastrtps { class Publisher; -namespace rtps -{ -class InstanceHandle_t; -} - /** * Class PublisherListener, allows the end user to implement callbacks triggered by certain events. * @ingroup FASTRTPS_MODULE @@ -40,20 +36,33 @@ class InstanceHandle_t; class RTPS_DllAPI PublisherListener { public: - PublisherListener(){}; - virtual ~PublisherListener(){}; + PublisherListener(){} + virtual ~PublisherListener(){} /** * This method is called when the Publisher is matched (or unmatched) against an endpoint. * @param pub Pointer to the associated Publisher * @param info Information regarding the matched subscriber */ - virtual void onPublicationMatched(Publisher* pub, rtps::MatchingInfo& info){(void)pub; (void)info;}; + virtual void onPublicationMatched( + Publisher* pub, + rtps::MatchingInfo& info) + { + (void)pub; + (void)info; + } /** - * A method called when an instance of a topic misses the deadline period - * @param handle The instance handle + * A method called when a deadline is missed + * @param pub Pointer to the associated Publisher + * @param status The deadline missed status */ - virtual void on_offered_deadline_missed(rtps::InstanceHandle_t& /*handle*/) {}; + virtual void on_offered_deadline_missed( + Publisher* pub, + OfferedDeadlineMissedStatus& status) + { + (void)pub; + (void)status; + } }; } /* namespace rtps */ diff --git a/include/fastrtps/qos/OfferedDeadlineMissedStatus.h b/include/fastrtps/qos/OfferedDeadlineMissedStatus.h new file mode 100644 index 00000000000..9a57f695285 --- /dev/null +++ b/include/fastrtps/qos/OfferedDeadlineMissedStatus.h @@ -0,0 +1,55 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file OfferedDeadlineMissedStatus.h +*/ + +#ifndef _OFFERED_DEADLINE_MISSED_STATUS_H_ +#define _OFFERED_DEADLINE_MISSED_STATUS_H_ + +#include + +namespace eprosima { +namespace fastrtps { + +//! @brief A struct storing the status of the offered deadline +//! @ingroup DEADLINE_MODULE +struct OfferedDeadlineMissedStatus +{ + //! @brief Constructor + OfferedDeadlineMissedStatus() + : total_count() + , total_count_change() + , last_instance_handle() + {} + + //! @brief Destructor + ~OfferedDeadlineMissedStatus() + {} + + //! @brief Total cumulative number of offered deadline periods epased during which a writer failed to provide data + //! @details Missed deadlines accumulate, that is, each deadline period the total_count will be incremented by 1 + uint32_t total_count; + + //! @brief The change in total_count since the last time the listener was called or the status was read + uint32_t total_count_change; + + //! @brief Handle to the last instance missing the deadline + rtps::InstanceHandle_t last_instance_handle; +}; +} //end of namespace +} //end of namespace eprosima + +#endif /* _OFFERED_DEADLINE_MISSED_STATUS_H_ */ diff --git a/include/fastrtps/qos/RequestedDeadlineMissedStatus.h b/include/fastrtps/qos/RequestedDeadlineMissedStatus.h new file mode 100644 index 00000000000..daacef471c9 --- /dev/null +++ b/include/fastrtps/qos/RequestedDeadlineMissedStatus.h @@ -0,0 +1,55 @@ +// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file RequestedDeadlineMissedStatus.h +*/ + +#ifndef _REQUESTED_DEADLINE_MISSED_STATUS_H_ +#define _REQUESTED_DEADLINE_MISSED_STATUS_H_ + +#include + +namespace eprosima { +namespace fastrtps { + +//! @brief A struct storing the status of the requested deadline +//! @ingroup DEADLINE_MODULE +struct RequestedDeadlineMissedStatus +{ + //! @brief Constructor + RequestedDeadlineMissedStatus() + : total_count() + , total_count_change() + , last_instance_handle() + {} + + //! @brief Destructor + ~RequestedDeadlineMissedStatus() + {} + + //! @brief Total cumulative number of missed deadlines detected for any instance + //! @details Missed deadlines accumulate, that is, each deadline period the total_count will be incremented by 1 for each instance for which data was not received + uint32_t total_count; + + //! @brief The change in total_count since the last time the listener was called or the status was read + uint32_t total_count_change; + + //! @brief Handle to the last instance missing the deadline + rtps::InstanceHandle_t last_instance_handle; +}; +} //end of namespace +} //end of namespace eprosima + +#endif /* _REQUESTED_DEADLINE_MISSED_STATUS_H_ */ diff --git a/include/fastrtps/subscriber/SubscriberListener.h b/include/fastrtps/subscriber/SubscriberListener.h index e2cd7df4980..c53fe59369a 100644 --- a/include/fastrtps/subscriber/SubscriberListener.h +++ b/include/fastrtps/subscriber/SubscriberListener.h @@ -20,12 +20,12 @@ #define SUBLISTENER_H_ #include "../fastrtps_dll.h" +#include "../qos/RequestedDeadlineMissedStatus.h" namespace eprosima { namespace fastrtps { namespace rtps { class MatchingInfo; - class InstanceHandle_t; } /* namespace rtps */ class Subscriber; @@ -39,28 +39,35 @@ class RTPS_DllAPI SubscriberListener { public: - SubscriberListener(){}; + SubscriberListener(){} - virtual ~SubscriberListener(){}; + virtual ~SubscriberListener(){} /** * Virtual function to be implemented by the user containing the actions to be performed when a new Data Message is received. * @param sub Subscriber */ - virtual void onNewDataMessage(Subscriber* /*sub*/){}; + virtual void onNewDataMessage(Subscriber* /*sub*/){} /** * Virtual method to be called when the subscriber is matched with a new Writer (or unmatched); i.e., when a writer publishing in the same topic is discovered. * @param sub Subscriber * @param info Matching information */ - virtual void onSubscriptionMatched(Subscriber* /*sub*/, rtps::MatchingInfo& /*info*/){}; + virtual void onSubscriptionMatched( + Subscriber* /*sub*/, + rtps::MatchingInfo& /*info*/) + {} /** * Virtual method to be called when a topic misses the deadline period - * @param handle The instance handle + * @param sub Subscriber + * @param status The requested deadline missed status */ - virtual void on_requested_deadline_missed(rtps::InstanceHandle_t& /*handle*/) {} + virtual void on_requested_deadline_missed( + Subscriber* /*sub*/, + RequestedDeadlineMissedStatus& /*status*/) + {} }; } /* namespace fastrtps */ diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index f4c038abe07..f70da161e8a 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -68,6 +68,7 @@ PublisherImpl::PublisherImpl( mp_participant->get_resource_event().getThread()) , deadline_duration_(att.qos.m_deadline.period) , deadline_samples_() + , deadline_missed_status_() { if (att.qos.m_deadline.period != c_TimeInfinite) { @@ -382,5 +383,9 @@ void PublisherImpl::check_deadlines() } } - mp_listener->on_offered_deadline_missed(handle); + deadline_missed_status_.total_count++; + deadline_missed_status_.total_count_change++; + deadline_missed_status_.last_instance_handle = handle; + + mp_listener->on_offered_deadline_missed(mp_userPublisher, deadline_missed_status_); } diff --git a/src/cpp/publisher/PublisherImpl.h b/src/cpp/publisher/PublisherImpl.h index fd5d998ed58..d7af6e2615a 100644 --- a/src/cpp/publisher/PublisherImpl.h +++ b/src/cpp/publisher/PublisherImpl.h @@ -31,6 +31,7 @@ #include #include +#include namespace eprosima { namespace fastrtps{ @@ -163,6 +164,8 @@ class PublisherImpl Duration_t deadline_duration_; //! A vector to store the latest samples to check for deadlines std::vector deadline_samples_; + //! The offered deadline missed status + OfferedDeadlineMissedStatus deadline_missed_status_; /** Method to check for deadlines */ diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index ad24166e4a2..b1879949033 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -59,6 +59,7 @@ SubscriberImpl::SubscriberImpl( mp_participant->get_resource_event().getThread()) , deadline_duration_(att.qos.m_deadline.period) , deadline_samples_(att.topic.resourceLimitsQos.max_instances) + , deadline_missed_status_() { if (att.qos.m_deadline.period != c_TimeInfinite) { @@ -277,7 +278,10 @@ void SubscriberImpl::check_deadlines() } } - mp_listener->on_requested_deadline_missed(handle); + deadline_missed_status_.total_count++; + deadline_missed_status_.total_count_change++; + deadline_missed_status_.last_instance_handle = handle; + mp_listener->on_requested_deadline_missed(mp_userSubscriber, deadline_missed_status_); } } /* namespace fastrtps */ diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index 228acf60126..cf38cbbd379 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -27,7 +27,7 @@ #include #include #include - +#include namespace eprosima { namespace fastrtps { @@ -155,12 +155,14 @@ class SubscriberImpl { //!RTPSParticipant rtps::RTPSParticipant* mp_rtpsParticipant; - //!A timer used to check for deadlines + //! A timer used to check for deadlines DeadlineTimer deadline_timer_; - //!Deadline duration + //! Deadline duration Duration_t deadline_duration_; - //!A vector storing the latest samples to check for deadline + //! A vector storing the latest samples to check for deadline std::vector deadline_samples_; + //! Requested deadline missed status + RequestedDeadlineMissedStatus deadline_missed_status_; /** A method to check for deadlines */ diff --git a/test/blackbox/PubSubReader.hpp b/test/blackbox/PubSubReader.hpp index 20b95270471..5a912a0bc0e 100644 --- a/test/blackbox/PubSubReader.hpp +++ b/test/blackbox/PubSubReader.hpp @@ -142,9 +142,13 @@ class PubSubReader } } - void on_requested_deadline_missed(eprosima::fastrtps::rtps::InstanceHandle_t&) override + void on_requested_deadline_missed( + eprosima::fastrtps::Subscriber* sub, + eprosima::fastrtps::RequestedDeadlineMissedStatus& status) override { - times_deadline_missed_++; + (void)sub; + + times_deadline_missed_ = status.total_count; } int missed_deadlines() const From e09169228d8d136caf1e5d42db40c00f747ab5ee Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Fri, 8 Mar 2019 11:51:47 +0100 Subject: [PATCH 24/54] Refs #4693 Adding getters for offered/requested deadline missed status --- include/fastrtps/publisher/Publisher.h | 9 +++++++-- include/fastrtps/subscriber/Subscriber.h | 9 +++++++-- src/cpp/publisher/Publisher.cpp | 5 +++++ src/cpp/publisher/PublisherImpl.cpp | 5 +++++ src/cpp/publisher/PublisherImpl.h | 6 ++++++ src/cpp/subscriber/Subscriber.cpp | 5 +++++ src/cpp/subscriber/SubscriberImpl.cpp | 6 ++++++ src/cpp/subscriber/SubscriberImpl.h | 6 ++++++ 8 files changed, 47 insertions(+), 4 deletions(-) diff --git a/include/fastrtps/publisher/Publisher.h b/include/fastrtps/publisher/Publisher.h index 011216ee909..432079cff68 100644 --- a/include/fastrtps/publisher/Publisher.h +++ b/include/fastrtps/publisher/Publisher.h @@ -35,9 +35,8 @@ struct GUID_t; class WriteParams; } - - class PublisherImpl; +struct OfferedDeadlineMissedStatus; /** * Class Publisher, used to send data to associated subscribers. @@ -118,6 +117,12 @@ class RTPS_DllAPI Publisher */ bool updateAttributes(const PublisherAttributes& att); + /** + * @brief Returns the offered deadline missed status + * @param Deadline missed status struct + */ + void get_offered_deadline_missed_status(OfferedDeadlineMissedStatus& status); + private: PublisherImpl* mp_impl; diff --git a/include/fastrtps/subscriber/Subscriber.h b/include/fastrtps/subscriber/Subscriber.h index 53c0129f472..598039dfff5 100644 --- a/include/fastrtps/subscriber/Subscriber.h +++ b/include/fastrtps/subscriber/Subscriber.h @@ -23,13 +23,12 @@ #include "../rtps/common/Guid.h" #include "../attributes/SubscriberAttributes.h" - - namespace eprosima { namespace fastrtps { class SubscriberImpl; class SampleInfo_t; +struct RequestedDeadlineMissedStatus; /** * Class Subscriber, contains the public API that allows the user to control the reception of messages. @@ -101,6 +100,12 @@ class RTPS_DllAPI Subscriber */ uint64_t getUnreadCount() const; + /** + * @brief Get the requested deadline missed status + * @return The deadline missed status + */ + void get_requested_deadline_missed_status(RequestedDeadlineMissedStatus& status); + private: SubscriberImpl* mp_impl; }; diff --git a/src/cpp/publisher/Publisher.cpp b/src/cpp/publisher/Publisher.cpp index 6624b1d7173..54978bd1d79 100644 --- a/src/cpp/publisher/Publisher.cpp +++ b/src/cpp/publisher/Publisher.cpp @@ -89,3 +89,8 @@ bool Publisher::updateAttributes(const PublisherAttributes& att) { return mp_impl->updateAttributes(att); } + +void Publisher::get_offered_deadline_missed_status(OfferedDeadlineMissedStatus &status) +{ + mp_impl->get_offered_deadline_missed_status(status); +} diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index f70da161e8a..b8d67773e30 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -389,3 +389,8 @@ void PublisherImpl::check_deadlines() mp_listener->on_offered_deadline_missed(mp_userPublisher, deadline_missed_status_); } + +void PublisherImpl::get_offered_deadline_missed_status(OfferedDeadlineMissedStatus &status) +{ + status = deadline_missed_status_; +} diff --git a/src/cpp/publisher/PublisherImpl.h b/src/cpp/publisher/PublisherImpl.h index d7af6e2615a..c38fea2498f 100644 --- a/src/cpp/publisher/PublisherImpl.h +++ b/src/cpp/publisher/PublisherImpl.h @@ -129,6 +129,12 @@ class PublisherImpl bool wait_for_all_acked(const rtps::Time_t& max_wait); + /** + * @brief Returns the offered deadline missed status + * @param Deadline missed status struct + */ + void get_offered_deadline_missed_status(OfferedDeadlineMissedStatus& status); + private: ParticipantImpl* mp_participant; //! Pointer to the associated Data Writer. diff --git a/src/cpp/subscriber/Subscriber.cpp b/src/cpp/subscriber/Subscriber.cpp index 5325103430b..23e7f1dab73 100644 --- a/src/cpp/subscriber/Subscriber.cpp +++ b/src/cpp/subscriber/Subscriber.cpp @@ -61,3 +61,8 @@ uint64_t Subscriber::getUnreadCount() const { return mp_impl->getUnreadCount(); } + +void Subscriber::get_requested_deadline_missed_status(RequestedDeadlineMissedStatus& status) +{ + mp_impl->get_requested_deadline_missed_status(status); +} diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index b1879949033..555772e6a7f 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -284,5 +284,11 @@ void SubscriberImpl::check_deadlines() mp_listener->on_requested_deadline_missed(mp_userSubscriber, deadline_missed_status_); } + +void SubscriberImpl::get_requested_deadline_missed_status(RequestedDeadlineMissedStatus& status) +{ + status = deadline_missed_status_; +} + } /* namespace fastrtps */ } /* namespace eprosima */ diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index cf38cbbd379..f4c06f287c0 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -127,6 +127,12 @@ class SubscriberImpl { */ void onNewCacheChangeAdded(const CacheChange_t* const change); + /** + * @brief Get the requested deadline missed status + * @return The deadline missed status + */ + void get_requested_deadline_missed_status(RequestedDeadlineMissedStatus& status); + private: //!Participant From de2c466198ca9f0a11c6385cc4ebd739f862af55 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Mon, 11 Mar 2019 08:15:59 +0100 Subject: [PATCH 25/54] Refs #4693 Back to first deadline implementation + update of unit tests --- src/cpp/publisher/PublisherImpl.cpp | 36 +++++++++------------ src/cpp/subscriber/SubscriberImpl.cpp | 37 +++++++++------------- test/blackbox/BlackboxTestsDeadlineQos.cpp | 8 ++--- test/blackbox/PubSubWriter.hpp | 7 ++-- 4 files changed, 39 insertions(+), 49 deletions(-) diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index b8d67773e30..51c1ee5ede3 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -207,18 +207,6 @@ bool PublisherImpl::create_new_change_with_params( if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { - // Cancel timer - deadline_timer_.cancel_timer(); - - // Calculate the time at which the instance with the oldest change will expire - int num_instances = 0; - m_history.get_latest_samples(deadline_samples_, num_instances); - auto min = *std::min_element(deadline_samples_.begin(), - deadline_samples_.begin() + num_instances, - [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); - deadline_timer_.update_interval(deadline_duration_ - ch->sourceTimestamp + min->sourceTimestamp); - - // Restart the timer deadline_timer_.restart_timer(); } return true; @@ -357,7 +345,7 @@ void PublisherImpl::check_deadlines() std::unique_lock lock(*mp_writer->getMutex()); - // If this method is called, one instance (the one with the oldest change) has missed the deadline + auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); // Get the latest samples from the history int num_samples = 0; @@ -371,26 +359,32 @@ void PublisherImpl::check_deadlines() // Time of the earliest sample among all topic instances Time_t minTime = deadline_samples_.front()->sourceTimestamp; - // Instance of the earliest sample among all topic instances - InstanceHandle_t handle = deadline_samples_.front()->instanceHandle; for (int i = 0; i < num_samples; i++) { if (deadline_samples_[i]->sourceTimestamp < minTime) { minTime = deadline_samples_[i]->sourceTimestamp; - handle = deadline_samples_[i]->instanceHandle; } - } - deadline_missed_status_.total_count++; - deadline_missed_status_.total_count_change++; - deadline_missed_status_.last_instance_handle = handle; + if (now_s - deadline_samples_[i]->sourceTimestamp >= deadline_duration_) + { + deadline_missed_status_.total_count++; + deadline_missed_status_.total_count_change++; + deadline_missed_status_.last_instance_handle = deadline_samples_[i]->instanceHandle; + + mp_listener->on_offered_deadline_missed(mp_userPublisher, deadline_missed_status_); + deadline_missed_status_.total_count_change = 0; + } + } - mp_listener->on_offered_deadline_missed(mp_userPublisher, deadline_missed_status_); + Duration_t interval = deadline_duration_ - now_s + minTime > 0? deadline_duration_ - now_s + minTime: deadline_duration_; + deadline_timer_.update_interval(interval); + deadline_timer_.restart_timer(); } void PublisherImpl::get_offered_deadline_missed_status(OfferedDeadlineMissedStatus &status) { status = deadline_missed_status_; + deadline_missed_status_.total_count_change = 0; } diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index 555772e6a7f..24cbf975195 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -213,19 +213,6 @@ void SubscriberImpl::onNewCacheChangeAdded(const CacheChange_t* const change) if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { std::unique_lock lock(*mp_reader->getMutex()); - - // Cancel the timer - deadline_timer_.cancel_timer(); - - // Update timer interval - int num_samples = 0; - m_history.get_latest_samples(deadline_samples_, num_samples); - auto min = *std::min_element(deadline_samples_.begin(), - deadline_samples_.begin() + num_samples, - [](CacheChange_t* c1, CacheChange_t* c2){ return c1->sourceTimestamp < c2->sourceTimestamp; }); - deadline_timer_.update_interval(deadline_duration_ - change->sourceTimestamp + min->sourceTimestamp); - - // Restart deadline_timer_.restart_timer(); } } @@ -252,7 +239,7 @@ void SubscriberImpl::check_deadlines() std::unique_lock lock(*mp_reader->getMutex()); - // If this method is called, one instance (the one with the oldest change) has missed the deadline + auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); // Get the latest samples from the history int num_samples = 0; @@ -266,22 +253,28 @@ void SubscriberImpl::check_deadlines() // Time of the earliest sample among all topic instances Time_t minTime = deadline_samples_.front()->sourceTimestamp; - // Instance handle of the earlist sample among all topic instances - InstanceHandle_t handle = deadline_samples_.front()->instanceHandle; - for (int i = 0; i < num_samples; ++i) + for (int i = 0; i < num_samples; i++) { if (deadline_samples_[i]->sourceTimestamp < minTime) { minTime = deadline_samples_[i]->sourceTimestamp; - handle = deadline_samples_[i]->instanceHandle; + } + + if (now_s - deadline_samples_[i]->sourceTimestamp >= deadline_duration_) + { + deadline_missed_status_.total_count++; + deadline_missed_status_.total_count_change++; + deadline_missed_status_.last_instance_handle = deadline_samples_[i]->instanceHandle; + + mp_listener->on_requested_deadline_missed(mp_userSubscriber, deadline_missed_status_); + deadline_missed_status_.total_count_change = 0; } } - deadline_missed_status_.total_count++; - deadline_missed_status_.total_count_change++; - deadline_missed_status_.last_instance_handle = handle; - mp_listener->on_requested_deadline_missed(mp_userSubscriber, deadline_missed_status_); + Duration_t interval = minTime + deadline_duration_ - now_s > 0? minTime + deadline_duration_ - now_s: deadline_duration_; + deadline_timer_.update_interval(interval); + deadline_timer_.restart_timer(); } diff --git a/test/blackbox/BlackboxTestsDeadlineQos.cpp b/test/blackbox/BlackboxTestsDeadlineQos.cpp index 1a3004e2f5c..48382d19844 100644 --- a/test/blackbox/BlackboxTestsDeadlineQos.cpp +++ b/test/blackbox/BlackboxTestsDeadlineQos.cpp @@ -114,8 +114,8 @@ BLACKBOXTEST(DeadlineQos, NoKeyTopicShortDeadline) } // All samples should have missed the deadline - EXPECT_EQ(writer.missed_deadlines(), writer_samples); - EXPECT_EQ(reader.missed_deadlines(), writer_samples); + EXPECT_GE(writer.missed_deadlines(), writer_samples); + EXPECT_GE(reader.missed_deadlines(), writer_samples); } BLACKBOXTEST(DeadlineQos, KeyedTopicLongDeadline) @@ -212,6 +212,6 @@ BLACKBOXTEST(DeadlineQos, KeyedTopicShortDeadline) std::this_thread::sleep_for(std::chrono::milliseconds(writer_sleep_ms)); } - EXPECT_EQ(writer.missed_deadlines(), writer_samples); - EXPECT_EQ(reader.missed_deadlines(), writer_samples); + EXPECT_GE(writer.missed_deadlines(), writer_samples); + EXPECT_GE(reader.missed_deadlines(), writer_samples); } diff --git a/test/blackbox/PubSubWriter.hpp b/test/blackbox/PubSubWriter.hpp index f49a19be789..272a2e26390 100644 --- a/test/blackbox/PubSubWriter.hpp +++ b/test/blackbox/PubSubWriter.hpp @@ -154,9 +154,12 @@ class PubSubWriter } } - void on_offered_deadline_missed(eprosima::fastrtps::rtps::InstanceHandle_t&) + void on_offered_deadline_missed( + eprosima::fastrtps::Publisher* pub, + eprosima::fastrtps::OfferedDeadlineMissedStatus& status) override { - times_deadline_missed_++; + (void)pub; + times_deadline_missed_ = status.total_count; } int missed_deadlines() const From 4687ac9e341efe1ab9727ca029c8aa59ffc81105 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Mon, 11 Mar 2019 08:30:04 +0100 Subject: [PATCH 26/54] Refs #4693 Minor changes to C++ example + some fixes for compiler warnings --- examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx | 2 +- examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx | 3 ++- examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx | 3 ++- src/cpp/subscriber/SubscriberImpl.cpp | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx index ba4fb0eb17d..ccf99e0bdba 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx @@ -27,7 +27,7 @@ int main(int argc, char** argv) { std::cout << "Starting " << std::endl; int type = 1; - int deadline = 1000; + int deadline = 2000; int sleep = 1000; int samples = 0; if (argc > 1) diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx index 819911b1495..15bcaef97e6 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx @@ -94,7 +94,8 @@ void deadlinepayloadPublisher::PubListener::on_offered_deadline_missed( Publisher* pub, OfferedDeadlineMissedStatus& status) { - std::cout << "Publisher " << pub->getGuid() << " missed the deadline. Last instance: " << status.last_instance_handle << std::endl; + (void)pub; + std::cout << "Deadline missed for instance: " << status.last_instance_handle << std::endl; } void deadlinepayloadPublisher::run(double sleep_ms, int samples) diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx index 62b25e19512..32a90518d26 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx @@ -103,7 +103,8 @@ void deadlinepayloadSubscriber::SubListener::on_requested_deadline_missed( Subscriber* sub, RequestedDeadlineMissedStatus& status) { - std::cout << "Subscriber " << sub->getGuid() << " missed the deadline for instance " << status.last_instance_handle << std::endl; + (void)sub; + std::cout << "Deadline missed for instance: " << status.last_instance_handle << std::endl; } void deadlinepayloadSubscriber::run() diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index 24cbf975195..edcd4ee77c1 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -208,7 +208,7 @@ void SubscriberImpl::SubscriberReaderListener::onReaderMatched(RTPSReader* /*rea } } -void SubscriberImpl::onNewCacheChangeAdded(const CacheChange_t* const change) +void SubscriberImpl::onNewCacheChangeAdded(const CacheChange_t* const /*change*/) { if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { From c4b749aac49e87e46e2ca07fe791300577131b51 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Mon, 11 Mar 2019 08:37:00 +0100 Subject: [PATCH 27/54] Refs #4693 Resetting total_count_change after requesting deadline missed status --- src/cpp/subscriber/SubscriberImpl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index edcd4ee77c1..a95f09f5ad3 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -281,6 +281,7 @@ void SubscriberImpl::check_deadlines() void SubscriberImpl::get_requested_deadline_missed_status(RequestedDeadlineMissedStatus& status) { status = deadline_missed_status_; + deadline_missed_status_ = 0; } } /* namespace fastrtps */ From 496c5ab17b02dff6f7a35651569bc0b527817f47 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Mon, 11 Mar 2019 09:00:37 +0100 Subject: [PATCH 28/54] Refs #4693 Allowing changing deadline QoS --- src/cpp/publisher/PublisherImpl.cpp | 10 +++++----- src/cpp/subscriber/SubscriberImpl.cpp | 11 +++++------ 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index 51c1ee5ede3..cb126434dbd 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -67,13 +67,9 @@ PublisherImpl::PublisherImpl( mp_participant->get_resource_event().getIOService(), mp_participant->get_resource_event().getThread()) , deadline_duration_(att.qos.m_deadline.period) - , deadline_samples_() + , deadline_samples_(att.topic.getTopicKind() == NO_KEY? 1: att.topic.resourceLimitsQos.max_instances) , deadline_missed_status_() { - if (att.qos.m_deadline.period != c_TimeInfinite) - { - deadline_samples_.resize(att.topic.getTopicKind() == NO_KEY? 1: att.topic.resourceLimitsQos.max_instances); - } } PublisherImpl::~PublisherImpl() @@ -306,10 +302,14 @@ bool PublisherImpl::updateAttributes(const PublisherAttributes& att) StatefulWriter* sfw = (StatefulWriter*)mp_writer; sfw->updateTimes(att.times); } + this->m_att.qos.setQos(att.qos,false); this->m_att = att; //Notify the participant that a Writer has changed its QOS mp_rtpsParticipant->updateWriter(this->mp_writer, m_att.topic, m_att.qos); + + // Update deadline period + deadline_duration_ = m_att.qos.m_deadline.period; } diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index a95f09f5ad3..896eb9f8cfc 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -58,13 +58,9 @@ SubscriberImpl::SubscriberImpl( mp_participant->get_resource_event().getIOService(), mp_participant->get_resource_event().getThread()) , deadline_duration_(att.qos.m_deadline.period) - , deadline_samples_(att.topic.resourceLimitsQos.max_instances) + , deadline_samples_(att.topic.getTopicKind() == NO_KEY? 1: att.topic.resourceLimitsQos.max_instances) , deadline_missed_status_() { - if (att.qos.m_deadline.period != c_TimeInfinite) - { - deadline_samples_.resize(att.topic.getTopicKind() == NO_KEY? 1: att.topic.resourceLimitsQos.max_instances); - } } SubscriberImpl::~SubscriberImpl() @@ -186,6 +182,9 @@ bool SubscriberImpl::updateAttributes(const SubscriberAttributes& att) this->m_att.qos.setQos(att.qos,false); //NOTIFY THE BUILTIN PROTOCOLS THAT THE READER HAS CHANGED mp_rtpsParticipant->updateReader(this->mp_reader, m_att.topic, m_att.qos); + + // Update deadline period + deadline_duration_ = m_att.qos.m_deadline.period; } return updated; } @@ -281,7 +280,7 @@ void SubscriberImpl::check_deadlines() void SubscriberImpl::get_requested_deadline_missed_status(RequestedDeadlineMissedStatus& status) { status = deadline_missed_status_; - deadline_missed_status_ = 0; + deadline_missed_status_.total_count_change = 0; } } /* namespace fastrtps */ From a51ba6b044f3fece9f52ce948dcd15b173f7bb44 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Mon, 11 Mar 2019 09:25:50 +0100 Subject: [PATCH 29/54] Refs #4693 Updating C++ example description --- examples/C++/DeadlineQoSExample/README.txt | 87 ++++++++-------------- 1 file changed, 31 insertions(+), 56 deletions(-) diff --git a/examples/C++/DeadlineQoSExample/README.txt b/examples/C++/DeadlineQoSExample/README.txt index c347e38c6ba..7e27047e207 100644 --- a/examples/C++/DeadlineQoSExample/README.txt +++ b/examples/C++/DeadlineQoSExample/README.txt @@ -1,56 +1,31 @@ ------------------------------ -| USER DEADLINE EXAMPLE | ------------------------------ - -------------------- -- Purpose - -------------------- - -This example shows a way to implement a Deadline QoS feature on a FastRTPS Application, -taking an example project as a starting point. - -Deadline is a subscriber-based QoS provides an alarm when the period in which data is received -doesntmeet the configured requirements (i.e: data arrival is slower than expected). -When a topic has a key, each piece of data with different key is treated as a different -data source/sink and therefore a Deadline alarm is set off independently for each -key. - -------------------- --Working principle- -------------------- - -The Deadline QoS is configured with a minimun data arrival frequency. In every period, a -check is performed to determine if new data has arrived for every key since the last update. -In the case a key does not have new data, the alarm for that key goes off. - -This check is run with the same periodicity as the expected maximun period between samples. -Each key has a flag bit assigned to it, that becomes set to '1' every time a piece of data -with that key arrives. The Deadline check verifies the status of these flags and resets them -to '0' upon exit, meaning that, upon the next check, a '1' flag means "data received in this period" -and a '0' means "no new data". The alarm consists on a user-defined callback function that is called -when a '0' flag is found during the check. - --------------------- -- Implementation - --------------------- - -In this example, the Deadline QoS is implemented by the use of a helper class -DeadlineQoS. This class implements: -- A map of flag bits for each key (with mutex to ensure exclusive access). -- A method to be called from onNewDataMessage to set flags on the QoS map based on the keys. -- A predefined callback function that performs the QoS checks periodically. -- A function to activate the process. -- A deadline-missed callback function. - -------------------- -- USAGE - -------------------- - -To make use of the provided DeadlineQoS implementation... -- Create an instance of deadlineQoS inside your subscriber's listener. -- Activate the service by calling deadlineQoS::run() -- Use eadlineQoS::setFlag(key) to update the flag list on deadlineQoS on new data arrival. -- Specify the desired functionality on Deadline miss in deadlineQoS::callback() - -It is important to configure the topic to distinguish between keys, otherwise the @key parameter -specified in the IDL will be ignored. +------------------------ +| DEADLINE EXAMPLE | +------------------------ + +1 - Application description +--------------------------- + +This example illustrates the Deadline QoS feature on a FastRTPS Application. + +To launch this example open two different consoles: + +In the first one launch: ./DeadlineQoSExample publisher +In the second one launch: ./DeadlineQoSExample subscriber + +2 - Application behaviour +------------------------- + +With the default options provided in the example, the application will use a topic with three different keys, +one of which sends a sample only half of the times. + +The deadline period can be set by providing a second argument to the binary. For example: + +./DeadlineQoSExample publisher 1000 +./DeadlineQosExample subscriber 1000 + +will set a deadline period of 1000 ms in both publisher and subscriber. Additionally, the rate at which the +publisher writes can be changed by providing a third argument. For example: + +./DeadlineQoSExample publisher 1000 500 + +will make the publisher write samples every 500 ms. From 99f5b288dbd110499bd6c3faba2e8e692b1a019b Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 13 Mar 2019 16:02:07 +0100 Subject: [PATCH 30/54] Refs #4693 Alternative implementation --- include/fastrtps/publisher/PublisherHistory.h | 46 +---------- .../fastrtps/subscriber/SubscriberHistory.h | 45 +---------- src/cpp/publisher/PublisherHistory.cpp | 62 +++----------- src/cpp/publisher/PublisherImpl.cpp | 67 +++++++-------- src/cpp/publisher/PublisherImpl.h | 14 +++- src/cpp/rtps/history/WriterHistory.cpp | 1 - src/cpp/subscriber/SubscriberHistory.cpp | 81 ++++--------------- src/cpp/subscriber/SubscriberImpl.cpp | 69 ++++++++-------- src/cpp/subscriber/SubscriberImpl.h | 14 +++- 9 files changed, 117 insertions(+), 282 deletions(-) diff --git a/include/fastrtps/publisher/PublisherHistory.h b/include/fastrtps/publisher/PublisherHistory.h index 7396d12ca0d..b40cd587394 100644 --- a/include/fastrtps/publisher/PublisherHistory.h +++ b/include/fastrtps/publisher/PublisherHistory.h @@ -93,51 +93,9 @@ class PublisherHistory:public rtps::WriterHistory virtual bool remove_change_g(rtps::CacheChange_t* a_change); - /** - * Returns the latest sample for each topic key - * @param samples A vector where the the latest sample for each key will be placed. Must be long enough - * @param num_samples The number of samples in the vector - */ - void get_latest_samples( - std::vector &samples, - int& num_samples); - private: - /** - * @brief A struct storing a vector of cache changes and the latest change in the group - * @ingroup FASTRTPS_MODULE - */ - struct KeyedChanges - { - //! Default constructor - KeyedChanges() - : cache_changes_() - , latest_change_(new CacheChange_t) - { - } - - //! Copy constructor - KeyedChanges(const KeyedChanges& other) - : cache_changes_(other.cache_changes_) - , latest_change_(new CacheChange_t) - { - latest_change_->copy(other.latest_change_); - } - - //! Destructor - ~KeyedChanges() - { - delete latest_change_; - } - - //! A vector of cache changes - std::vector cache_changes_; - //! The latest cache change in the struct - CacheChange_t* latest_change_; - }; - - typedef std::map t_m_Inst_Caches; + typedef std::map> t_m_Inst_Caches; typedef std::vector t_v_Caches; //!Map where keys are instance handles and values are vectors of cache changes associated @@ -148,8 +106,6 @@ class PublisherHistory:public rtps::WriterHistory ResourceLimitsQosPolicy m_resourceLimitsQos; //!Publisher Pointer PublisherImpl* mp_pubImpl; - //!The latest cache change written (only used for topics with no key) - CacheChange_t* mp_latestCacheChange; /** * @brief Method that finds a key in m_keyedChanges or tries to add it if not found diff --git a/include/fastrtps/subscriber/SubscriberHistory.h b/include/fastrtps/subscriber/SubscriberHistory.h index fabfbce3bbf..b7de0bf7bb1 100644 --- a/include/fastrtps/subscriber/SubscriberHistory.h +++ b/include/fastrtps/subscriber/SubscriberHistory.h @@ -113,50 +113,9 @@ class SubscriberHistory: public rtps::ReaderHistory return m_unreadCacheCount; } - /** - * A method that resturns the latest sample for each topic key - * @param samples A vector where the latest sample for each key will be placed. Must be long enough - * @param num_samples The number of samples in the vector - */ - void get_latest_samples( - std::vector& samples, - int& num_samples); - private: - /** - * @brief A struct storing a vector of cache changes and the latest change in the group - * @ingroup FASTRTPS_MODULE - */ - struct KeyedChanges - { - //! Default constructor - KeyedChanges() - : cache_changes_() - , latest_change_(new CacheChange_t) - {} - - //! Copy constructor - KeyedChanges(const KeyedChanges& other) - : cache_changes_(other.cache_changes_) - , latest_change_(new CacheChange_t) - { - latest_change_->copy(other.latest_change_); - } - - //! Destructor - ~KeyedChanges() - { - delete latest_change_; - } - - //! A vector of cache changes - std::vector cache_changes_; - //! The latest cache change in the struct - CacheChange_t* latest_change_; - }; - - typedef std::map t_m_Inst_Caches; + typedef std::map> t_m_Inst_Caches; typedef std::vector t_v_Caches; //!Number of unread CacheChange_t. @@ -169,8 +128,6 @@ class SubscriberHistory: public rtps::ReaderHistory ResourceLimitsQosPolicy m_resourceLimitsQos; //!Publisher Pointer SubscriberImpl* mp_subImpl; - //!The latest cache change received (only used for topics with no key) - CacheChange_t* mp_latestCacheChange; //!Type object to deserialize Key void * mp_getKeyObject; diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index 96c795c50bd..397a37153a1 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -54,15 +54,12 @@ PublisherHistory::PublisherHistory( , m_historyQos(history) , m_resourceLimitsQos(resource) , mp_pubImpl(pimpl) - , mp_latestCacheChange(new CacheChange_t) { // TODO Auto-generated constructor stub - } PublisherHistory::~PublisherHistory() { - delete mp_latestCacheChange; } @@ -101,7 +98,6 @@ bool PublisherHistory::add_pub_change( { if(this->add_change_(change, wparams, max_blocking_time)) { - mp_latestCacheChange->copy(change); returnedValue = true; } } @@ -115,7 +111,7 @@ bool PublisherHistory::add_pub_change( bool add = false; if(m_historyQos.kind == KEEP_ALL_HISTORY_QOS) { - if((int32_t)vit->second.cache_changes_.size() < m_resourceLimitsQos.max_samples_per_instance) + if((int32_t)vit->second.size() < m_resourceLimitsQos.max_samples_per_instance) { add = true; } @@ -126,13 +122,13 @@ bool PublisherHistory::add_pub_change( } else if (m_historyQos.kind == KEEP_LAST_HISTORY_QOS) { - if(vit->second.cache_changes_.size() < (size_t)m_historyQos.depth) + if(vit->second.size() < (size_t)m_historyQos.depth) { add = true; } else { - if(remove_change_pub(vit->second.cache_changes_.front())) + if(remove_change_pub(vit->second.front())) { add = true; } @@ -146,8 +142,7 @@ bool PublisherHistory::add_pub_change( logInfo(RTPS_HISTORY,this->mp_pubImpl->getGuid().entityId <<" Change " << change->sequenceNumber << " added with key: "<instanceHandle << " and "<serializedPayload.length<< " bytes"); - vit->second.cache_changes_.push_back(change); - vit->second.latest_change_->copy(change); + vit->second.push_back(change); returnedValue = true; } } @@ -172,17 +167,17 @@ bool PublisherHistory::find_key( if ((int)m_keyedChanges.size() < m_resourceLimitsQos.max_instances) { - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, t_v_Caches())).first; return true; } else { for (vit = m_keyedChanges.begin(); vit != m_keyedChanges.end(); ++vit) { - if (vit->second.cache_changes_.size() == 0) + if (vit->second.size() == 0) { m_keyedChanges.erase(vit); - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, t_v_Caches())).first; return true; } } @@ -255,14 +250,14 @@ bool PublisherHistory::remove_change_pub(CacheChange_t* change) return false; } - for(auto chit = vit->second.cache_changes_.begin(); chit!= vit->second.cache_changes_.end(); ++chit) + for(auto chit = vit->second.begin(); chit!= vit->second.end(); ++chit) { if( ((*chit)->sequenceNumber == change->sequenceNumber) && ((*chit)->writerGUID == change->writerGUID) ) { if(remove_change(change)) { - vit->second.cache_changes_.erase(chit); + vit->second.erase(chit); m_isHistoryFull = false; return true; } @@ -277,42 +272,3 @@ bool PublisherHistory::remove_change_g(CacheChange_t* a_change) { return remove_change_pub(a_change); } - -void PublisherHistory::get_latest_samples(std::vector &samples, int& num_samples) -{ - std::lock_guard guard(*this->mp_mutex); - - num_samples = 0; - - if (mp_pubImpl->getAttributes().topic.getTopicKind() == NO_KEY) - { - if (samples.size() < 1) - { - logError(PUBLISHER, "Cannot return latest sample, output vector is not long enough"); - return; - } - - if (mp_latestCacheChange != mp_invalidCache) - { - samples[num_samples++] = mp_latestCacheChange; - } - } - else if (mp_pubImpl->getAttributes().topic.getTopicKind() == WITH_KEY) - { - if (samples.size() < m_keyedChanges.size()) - { - logError(PUBLISHER, "Cannot return latest samples, output vector is not long enough"); - return; - } - - if (m_keyedChanges.empty()) - { - return; - } - - for (auto it = m_keyedChanges.begin(); it != m_keyedChanges.end(); ++it) - { - samples[num_samples++] = it->second.latest_change_; - } - } -} diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index cb126434dbd..7c2be0e2566 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -62,12 +62,13 @@ PublisherImpl::PublisherImpl( , mp_userPublisher(nullptr) , mp_rtpsParticipant(nullptr) , high_mark_for_frag_(0) - , deadline_timer_(std::bind(&PublisherImpl::check_deadlines, this), + , deadline_timer_(std::bind(&PublisherImpl::deadline_missed, this), att.qos.m_deadline.period, mp_participant->get_resource_event().getIOService(), mp_participant->get_resource_event().getThread()) , deadline_duration_(att.qos.m_deadline.period) - , deadline_samples_(att.topic.getTopicKind() == NO_KEY? 1: att.topic.resourceLimitsQos.max_instances) + , next_deadline_() + , timer_owner_() , deadline_missed_status_() { } @@ -203,7 +204,13 @@ bool PublisherImpl::create_new_change_with_params( if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { - deadline_timer_.restart_timer(); + auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); + next_deadline_[handle] = now_s + deadline_duration_; + + if (timer_owner_ == handle || timer_owner_ == InstanceHandle_t()) + { + timer_reschedule(); + } } return true; } @@ -339,52 +346,46 @@ bool PublisherImpl::wait_for_all_acked(const Time_t& max_wait) return mp_writer->wait_for_all_acked(max_wait); } -void PublisherImpl::check_deadlines() +void PublisherImpl::timer_reschedule() { assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); std::unique_lock lock(*mp_writer->getMutex()); - auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); + timer_owner_ = std::min_element(next_deadline_.begin(), + next_deadline_.end(), + [](const std::pair &lhs, const std::pair &rhs){ return lhs.second < rhs.second;})->first; - // Get the latest samples from the history - int num_samples = 0; - m_history.get_latest_samples(deadline_samples_, num_samples); + auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); + auto interval_s = next_deadline_[timer_owner_] - now_s; - if (num_samples == 0) - { - logError(PUBLISHER, "Deadline timer expired but no samples available"); - return; - } + deadline_timer_.cancel_timer(); + deadline_timer_.update_interval(interval_s); + deadline_timer_.restart_timer(); +} - // Time of the earliest sample among all topic instances - Time_t minTime = deadline_samples_.front()->sourceTimestamp; +void PublisherImpl::deadline_missed() +{ + assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); - for (int i = 0; i < num_samples; i++) - { - if (deadline_samples_[i]->sourceTimestamp < minTime) - { - minTime = deadline_samples_[i]->sourceTimestamp; - } + std::unique_lock lock(*mp_writer->getMutex()); - if (now_s - deadline_samples_[i]->sourceTimestamp >= deadline_duration_) - { - deadline_missed_status_.total_count++; - deadline_missed_status_.total_count_change++; - deadline_missed_status_.last_instance_handle = deadline_samples_[i]->instanceHandle; + deadline_missed_status_.total_count++; + deadline_missed_status_.total_count_change++; + deadline_missed_status_.last_instance_handle = timer_owner_; + mp_listener->on_offered_deadline_missed(mp_userPublisher, deadline_missed_status_); + deadline_missed_status_.total_count_change = 0; - mp_listener->on_offered_deadline_missed(mp_userPublisher, deadline_missed_status_); - deadline_missed_status_.total_count_change = 0; - } - } + auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); + next_deadline_[timer_owner_] = now_s + deadline_duration_; - Duration_t interval = deadline_duration_ - now_s + minTime > 0? deadline_duration_ - now_s + minTime: deadline_duration_; - deadline_timer_.update_interval(interval); - deadline_timer_.restart_timer(); + timer_reschedule(); } void PublisherImpl::get_offered_deadline_missed_status(OfferedDeadlineMissedStatus &status) { + std::unique_lock lock(*mp_writer->getMutex()); + status = deadline_missed_status_; deadline_missed_status_.total_count_change = 0; } diff --git a/src/cpp/publisher/PublisherImpl.h b/src/cpp/publisher/PublisherImpl.h index c38fea2498f..61a873b719a 100644 --- a/src/cpp/publisher/PublisherImpl.h +++ b/src/cpp/publisher/PublisherImpl.h @@ -168,14 +168,20 @@ class PublisherImpl DeadlineTimer deadline_timer_; //! Deadline duration Duration_t deadline_duration_; - //! A vector to store the latest samples to check for deadlines - std::vector deadline_samples_; + //! A map where keys are instance handles and values are times when instances are due to 'expire', i.e. miss the deadline + std::map next_deadline_; + //! The current timer owner, i.e. the instance which started the timer + InstanceHandle_t timer_owner_; //! The offered deadline missed status OfferedDeadlineMissedStatus deadline_missed_status_; - /** Method to check for deadlines + /** Method called when an instance misses the deadline */ - void check_deadlines(); + void deadline_missed(); + + /** A method to reschedule the deadline timer + */ + void timer_reschedule(); }; diff --git a/src/cpp/rtps/history/WriterHistory.cpp b/src/cpp/rtps/history/WriterHistory.cpp index 5f504eba28c..a0299540ec8 100644 --- a/src/cpp/rtps/history/WriterHistory.cpp +++ b/src/cpp/rtps/history/WriterHistory.cpp @@ -87,7 +87,6 @@ bool WriterHistory::add_change_(CacheChange_t* a_change, WriteParams &wparams, ++m_lastCacheChangeSeqNum; a_change->sequenceNumber = m_lastCacheChangeSeqNum; - a_change->sourceTimestamp = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); a_change->write_params = wparams; // Updated sample identity diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index d18129af188..db70cf06d67 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -57,7 +57,6 @@ SubscriberHistory::SubscriberHistory( , m_historyQos(history) , m_resourceLimitsQos(resource) , mp_subImpl(simpl) - , mp_latestCacheChange(new CacheChange_t) , mp_getKeyObject(nullptr) { if (mp_subImpl->getType()->m_isGetKeyDefined) @@ -72,7 +71,6 @@ SubscriberHistory::~SubscriberHistory() { mp_subImpl->getType()->deleteData(mp_getKeyObject); } - delete mp_latestCacheChange; } bool SubscriberHistory::received_change( @@ -157,11 +155,6 @@ bool SubscriberHistory::received_change( << ": Change " << a_change->sequenceNumber << " added from: " << a_change->writerGUID;); - if (mp_latestCacheChange == mp_invalidCache || mp_latestCacheChange->sourceTimestamp < a_change->sourceTimestamp) - { - mp_latestCacheChange->copy(a_change); - } - return true; } } @@ -193,7 +186,7 @@ bool SubscriberHistory::received_change( bool add = false; if (m_historyQos.kind == KEEP_ALL_HISTORY_QOS) { - if ((int32_t)vit->second.cache_changes_.size() < m_resourceLimitsQos.max_samples_per_instance) + if ((int32_t)vit->second.size() < m_resourceLimitsQos.max_samples_per_instance) { add = true; } @@ -205,15 +198,15 @@ bool SubscriberHistory::received_change( } else if (m_historyQos.kind == KEEP_LAST_HISTORY_QOS) { - if (vit->second.cache_changes_.size() < (size_t)m_historyQos.depth) + if (vit->second.size() < (size_t)m_historyQos.depth) { add = true; } else { // Try to substitute the oldest sample with the same key - auto older_sample = vit->second.cache_changes_.rend(); - for (auto it = vit->second.cache_changes_.rbegin(); it != vit->second.cache_changes_.rend(); ++it) + auto older_sample = vit->second.rend(); + for (auto it = vit->second.rbegin(); it != vit->second.rend(); ++it) { if ((*it)->writerGUID == a_change->writerGUID) @@ -226,7 +219,7 @@ bool SubscriberHistory::received_change( } } - if (older_sample != vit->second.cache_changes_.rend()) + if (older_sample != vit->second.rend()) { bool read = (*older_sample)->isRead; @@ -257,22 +250,21 @@ bool SubscriberHistory::received_change( if ((int32_t)m_changes.size() == m_resourceLimitsQos.max_samples) m_isHistoryFull = true; //ADD TO KEY VECTOR - if (vit->second.cache_changes_.size() == 0) + if (vit->second.size() == 0) { - vit->second.cache_changes_.push_back(a_change); + vit->second.push_back(a_change); } - else if (vit->second.cache_changes_.back()->sequenceNumber < a_change->sequenceNumber) + else if (vit->second.back()->sequenceNumber < a_change->sequenceNumber) { - vit->second.cache_changes_.push_back(a_change); + vit->second.push_back(a_change); } else { - vit->second.cache_changes_.push_back(a_change); - std::sort(vit->second.cache_changes_.begin(), - vit->second.cache_changes_.end(), + vit->second.push_back(a_change); + std::sort(vit->second.begin(), + vit->second.end(), sort_ReaderHistoryCache); } - vit->second.latest_change_->copy(vit->second.cache_changes_.back()); logInfo(SUBSCRIBER, this->mp_reader->getGuid().entityId << ": Change " << a_change->sequenceNumber << " added from: " @@ -496,17 +488,17 @@ bool SubscriberHistory::find_key( if ((int)m_keyedChanges.size() < m_resourceLimitsQos.max_instances) { - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, t_v_Caches())).first; return true; } else { for (vit = m_keyedChanges.begin(); vit!= m_keyedChanges.end(); ++vit) { - if (vit->second.cache_changes_.size() == 0) + if (vit->second.size() == 0) { m_keyedChanges.erase(vit); - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, t_v_Caches())).first; return true; } } @@ -542,13 +534,13 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change) return false; } - for (auto chit = vit->second.cache_changes_.begin(); chit != vit->second.cache_changes_.end(); ++chit) + for (auto chit = vit->second.begin(); chit != vit->second.end(); ++chit) { if ((*chit)->sequenceNumber == change->sequenceNumber && (*chit)->writerGUID == change->writerGUID) { if (remove_change(change)) { - vit->second.cache_changes_.erase(chit); + vit->second.erase(chit); m_isHistoryFull = false; return true; } @@ -558,42 +550,3 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change) } return false; } - -void SubscriberHistory::get_latest_samples(std::vector &samples, int &num_samples) -{ - std::lock_guard guard(*mp_mutex); - - num_samples = 0; - - if (mp_subImpl->getAttributes().topic.getTopicKind() == NO_KEY) - { - if (samples.size() < 1) - { - logError(SUBSCRIBER, "Cannot return latest sample, output vector is not long enough"); - return; - } - - if(mp_latestCacheChange != mp_invalidCache) - { - samples[num_samples++] = mp_latestCacheChange; - } - } - else if (mp_subImpl->getAttributes().topic.getTopicKind() == WITH_KEY) - { - if (samples.size() < m_keyedChanges.size()) - { - logError(SUBSCRIBER, "Cannot return latest samples, output vector is not long enough"); - return; - } - - if (m_keyedChanges.empty()) - { - return; - } - - for (auto it = m_keyedChanges.begin(); it != m_keyedChanges.end(); ++it) - { - samples[num_samples++] = it->second.latest_change_; - } - } -} diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index 896eb9f8cfc..237f37f17d4 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -53,12 +53,12 @@ SubscriberImpl::SubscriberImpl( , m_readerListener(this) , mp_userSubscriber(nullptr) , mp_rtpsParticipant(nullptr) - , deadline_timer_(std::bind(&SubscriberImpl::check_deadlines, this), + , deadline_timer_(std::bind(&SubscriberImpl::deadline_missed, this), att.qos.m_deadline.period, mp_participant->get_resource_event().getIOService(), mp_participant->get_resource_event().getThread()) , deadline_duration_(att.qos.m_deadline.period) - , deadline_samples_(att.topic.getTopicKind() == NO_KEY? 1: att.topic.resourceLimitsQos.max_instances) + , next_deadline_() , deadline_missed_status_() { } @@ -207,12 +207,19 @@ void SubscriberImpl::SubscriberReaderListener::onReaderMatched(RTPSReader* /*rea } } -void SubscriberImpl::onNewCacheChangeAdded(const CacheChange_t* const /*change*/) +void SubscriberImpl::onNewCacheChangeAdded(const CacheChange_t* const change) { if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { std::unique_lock lock(*mp_reader->getMutex()); - deadline_timer_.restart_timer(); + + auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); + next_deadline_[change->instanceHandle] = now_s + deadline_duration_; + + if (timer_owner_ == change->instanceHandle || timer_owner_ == InstanceHandle_t()) + { + timer_reschedule(); + } } } @@ -232,53 +239,47 @@ uint64_t SubscriberImpl::getUnreadCount() const return m_history.getUnreadCount(); } -void SubscriberImpl::check_deadlines() +void SubscriberImpl::timer_reschedule() { assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); std::unique_lock lock(*mp_reader->getMutex()); - auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); + timer_owner_ = std::min_element(next_deadline_.begin(), + next_deadline_.end(), + [](const std::pair& lhs, const std::pair& rhs){ return lhs.second < rhs.second; })->first; - // Get the latest samples from the history - int num_samples = 0; - m_history.get_latest_samples(deadline_samples_, num_samples); + auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); + auto interval_s = next_deadline_[timer_owner_] - now_s; - if (num_samples == 0) - { - logError(SUBSCRIBER, "Deadline timer expired but no samples available"); - return; - } + deadline_timer_.cancel_timer(); + deadline_timer_.update_interval(interval_s); + deadline_timer_.restart_timer(); +} - // Time of the earliest sample among all topic instances - Time_t minTime = deadline_samples_.front()->sourceTimestamp; +void SubscriberImpl::deadline_missed() +{ + assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); - for (int i = 0; i < num_samples; i++) - { - if (deadline_samples_[i]->sourceTimestamp < minTime) - { - minTime = deadline_samples_[i]->sourceTimestamp; - } + std::unique_lock lock(*mp_reader->getMutex()); - if (now_s - deadline_samples_[i]->sourceTimestamp >= deadline_duration_) - { - deadline_missed_status_.total_count++; - deadline_missed_status_.total_count_change++; - deadline_missed_status_.last_instance_handle = deadline_samples_[i]->instanceHandle; + deadline_missed_status_.total_count++; + deadline_missed_status_.total_count_change++; + deadline_missed_status_.last_instance_handle = timer_owner_; + mp_listener->on_requested_deadline_missed(mp_userSubscriber, deadline_missed_status_); + deadline_missed_status_.total_count_change = 0; - mp_listener->on_requested_deadline_missed(mp_userSubscriber, deadline_missed_status_); - deadline_missed_status_.total_count_change = 0; - } - } + auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); + next_deadline_[timer_owner_] = now_s + deadline_duration_; - Duration_t interval = minTime + deadline_duration_ - now_s > 0? minTime + deadline_duration_ - now_s: deadline_duration_; - deadline_timer_.update_interval(interval); - deadline_timer_.restart_timer(); + timer_reschedule(); } void SubscriberImpl::get_requested_deadline_missed_status(RequestedDeadlineMissedStatus& status) { + std::unique_lock lock(*mp_reader->getMutex()); + status = deadline_missed_status_; deadline_missed_status_.total_count_change = 0; } diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index f4c06f287c0..bc1d50b0f79 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -165,14 +165,20 @@ class SubscriberImpl { DeadlineTimer deadline_timer_; //! Deadline duration Duration_t deadline_duration_; - //! A vector storing the latest samples to check for deadline - std::vector deadline_samples_; + //! A map where keys are instance handles and values are times when instances are due to 'expire', i.e. miss the deadline + std::map next_deadline_; + //! The current timer owner, i.e. the instance which started the timer + InstanceHandle_t timer_owner_; //! Requested deadline missed status RequestedDeadlineMissedStatus deadline_missed_status_; - /** A method to check for deadlines + /** Method called when an instance misses the deadline */ - void check_deadlines(); + void deadline_missed(); + + /** A method to reschedule the deadline timer + */ + void timer_reschedule(); }; From 121a30ac234f0c38424c6f0fa899e4d2ba231e8e Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 13 Mar 2019 16:08:37 +0100 Subject: [PATCH 31/54] Refs #4693 Removing some attributes from C++ example --- .../C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx | 8 +------- .../C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx | 6 +----- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx index 15bcaef97e6..85a98e06e66 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx @@ -58,14 +58,8 @@ bool deadlinepayloadPublisher::init(double deadline_period_ms) PublisherAttributes Wparam; Wparam.topic.topicKind = WITH_KEY; - Wparam.topic.topicDataType = myType.getName(); //This type MUST be registered + Wparam.topic.topicDataType = myType.getName(); Wparam.topic.topicName = "deadlinepayloadPubSubTopic"; - Wparam.topic.historyQos.kind = KEEP_LAST_HISTORY_QOS; - Wparam.topic.historyQos.depth = 5; - Wparam.topic.resourceLimitsQos.allocated_samples = 15; - Wparam.topic.resourceLimitsQos.max_instances = 3; - Wparam.topic.resourceLimitsQos.max_samples_per_instance = 5; - Wparam.topic.resourceLimitsQos.max_samples = 3*5; Wparam.qos.m_reliability.kind= RELIABLE_RELIABILITY_QOS; Wparam.qos.m_deadline.period = deadline_period_ms * 1e-3; mp_publisher = Domain::createPublisher(mp_participant,Wparam,(PublisherListener*)&m_listener); diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx index 32a90518d26..53b76d0f928 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx @@ -57,12 +57,8 @@ bool deadlinepayloadSubscriber::init(double deadline_ms) SubscriberAttributes Rparam; Rparam.topic.topicKind = WITH_KEY; - Rparam.topic.topicDataType = myType.getName(); //Must be registered before the creation of the subscriber + Rparam.topic.topicDataType = myType.getName(); Rparam.topic.topicName = "deadlinepayloadPubSubTopic"; - Rparam.topic.resourceLimitsQos.allocated_samples=15; - Rparam.topic.resourceLimitsQos.max_instances=3; - Rparam.topic.resourceLimitsQos.max_samples_per_instance=5; - Rparam.topic.resourceLimitsQos.max_samples = 3*5; Rparam.qos.m_reliability.kind= RELIABLE_RELIABILITY_QOS; Rparam.qos.m_deadline.period = deadline_ms * 1e-3; Rparam.topic.historyQos.depth = 5; From 63691fdb1acfdb91dfe309924af7eeda5caefffd Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 13 Mar 2019 16:09:58 +0100 Subject: [PATCH 32/54] Refs #4693 Replacing forward declaration with include + other minor changes --- .../deadlinepayloadPubSubMain.cxx | 16 ++++++++-------- include/fastrtps/publisher/Publisher.h | 2 +- include/fastrtps/subscriber/Subscriber.h | 2 +- src/cpp/rtps/resources/TimedEventImpl.cpp | 15 ++++++++++++--- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx index ccf99e0bdba..ef826eab4f3 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx @@ -27,8 +27,8 @@ int main(int argc, char** argv) { std::cout << "Starting " << std::endl; int type = 1; - int deadline = 2000; - int sleep = 1000; + int deadline_ms = 2000; + int sleep_ms = 1000; int samples = 0; if (argc > 1) { @@ -37,10 +37,10 @@ int main(int argc, char** argv) type = 1; if (argc > 2) { - deadline = atoi(argv[2]); + deadline_ms = atoi(argv[2]); if (argc > 3) { - sleep = atoi(argv[3]); + sleep_ms = atoi(argv[3]); if (argc > 4) { samples = atoi(argv[4]); @@ -53,7 +53,7 @@ int main(int argc, char** argv) type = 2; if (argc > 2) { - deadline = atoi(argv[2]); + deadline_ms = atoi(argv[2]); } } } @@ -71,16 +71,16 @@ int main(int argc, char** argv) case 1: { deadlinepayloadPublisher mypub; - if (mypub.init(deadline)) + if (mypub.init(deadline_ms)) { - mypub.run(sleep, samples); + mypub.run(sleep_ms, samples); } break; } case 2: { deadlinepayloadSubscriber mysub; - if (mysub.init(deadline)) + if (mysub.init(deadline_ms)) { mysub.run(); } diff --git a/include/fastrtps/publisher/Publisher.h b/include/fastrtps/publisher/Publisher.h index 432079cff68..2fede85c9c4 100644 --- a/include/fastrtps/publisher/Publisher.h +++ b/include/fastrtps/publisher/Publisher.h @@ -25,6 +25,7 @@ #include "../rtps/common/Guid.h" #include "../rtps/common/Time_t.h" #include "../attributes/PublisherAttributes.h" +#include "../qos/OfferedDeadlineMissedStatus.h" namespace eprosima { namespace fastrtps { @@ -36,7 +37,6 @@ class WriteParams; } class PublisherImpl; -struct OfferedDeadlineMissedStatus; /** * Class Publisher, used to send data to associated subscribers. diff --git a/include/fastrtps/subscriber/Subscriber.h b/include/fastrtps/subscriber/Subscriber.h index 598039dfff5..d161287a3b4 100644 --- a/include/fastrtps/subscriber/Subscriber.h +++ b/include/fastrtps/subscriber/Subscriber.h @@ -22,13 +22,13 @@ #include "../rtps/common/Guid.h" #include "../attributes/SubscriberAttributes.h" +#include "../qos/RequestedDeadlineMissedStatus.h" namespace eprosima { namespace fastrtps { class SubscriberImpl; class SampleInfo_t; -struct RequestedDeadlineMissedStatus; /** * Class Subscriber, contains the public API that allows the user to control the reception of messages. diff --git a/src/cpp/rtps/resources/TimedEventImpl.cpp b/src/cpp/rtps/resources/TimedEventImpl.cpp index 4bad3a3b251..3940450b897 100644 --- a/src/cpp/rtps/resources/TimedEventImpl.cpp +++ b/src/cpp/rtps/resources/TimedEventImpl.cpp @@ -61,9 +61,18 @@ namespace eprosima using namespace eprosima::fastrtps::rtps; -TimedEventImpl::TimedEventImpl(TimedEvent* event, asio::io_service &service, const std::thread& event_thread, std::chrono::microseconds interval, TimedEvent::AUTODESTRUCTION_MODE autodestruction) : -timer_(service, interval), m_interval_microsec(interval), mp_event(event), -autodestruction_(autodestruction), state_(std::make_shared(autodestruction)), event_thread_id_(event_thread.get_id()) +TimedEventImpl::TimedEventImpl( + TimedEvent* event, + asio::io_service &service, + const std::thread& event_thread, + std::chrono::microseconds interval, + TimedEvent::AUTODESTRUCTION_MODE autodestruction) + : timer_(service, interval) + , m_interval_microsec(interval) + , mp_event(event) + , autodestruction_(autodestruction) + , state_(std::make_shared(autodestruction)) + , event_thread_id_(event_thread.get_id()) { //TIME_INFINITE(m_timeInfinite); } From 9037d9fb1ab165d30e7f41fc05290a3e617bdebb Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Thu, 14 Mar 2019 09:24:19 +0100 Subject: [PATCH 33/54] Refs #4693 Replacing Time_t with chrono --- src/cpp/publisher/PublisherImpl.cpp | 30 ++++++++++++++----------- src/cpp/publisher/PublisherImpl.h | 6 ++--- src/cpp/subscriber/SubscriberImpl.cpp | 32 +++++++++++++++------------ src/cpp/subscriber/SubscriberImpl.h | 6 ++--- 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index 7c2be0e2566..99b71533faf 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -38,6 +38,7 @@ using namespace eprosima::fastrtps; using namespace ::rtps; +using namespace std::chrono; PublisherImpl::PublisherImpl( ParticipantImpl* p, @@ -66,8 +67,8 @@ PublisherImpl::PublisherImpl( att.qos.m_deadline.period, mp_participant->get_resource_event().getIOService(), mp_participant->get_resource_event().getThread()) - , deadline_duration_(att.qos.m_deadline.period) - , next_deadline_() + , deadline_duration_us_(m_att.qos.m_deadline.period.to_ns() * 1e-3) + , next_deadline_us_() , timer_owner_() , deadline_missed_status_() { @@ -204,8 +205,7 @@ bool PublisherImpl::create_new_change_with_params( if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { - auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); - next_deadline_[handle] = now_s + deadline_duration_; + next_deadline_us_[handle] = steady_clock::now() + duration_cast(deadline_duration_us_); if (timer_owner_ == handle || timer_owner_ == InstanceHandle_t()) { @@ -316,7 +316,11 @@ bool PublisherImpl::updateAttributes(const PublisherAttributes& att) mp_rtpsParticipant->updateWriter(this->mp_writer, m_att.topic, m_att.qos); // Update deadline period - deadline_duration_ = m_att.qos.m_deadline.period; + deadline_duration_us_ = duration>(m_att.qos.m_deadline.period.to_ns() * 1e-3); + if (m_att.qos.m_deadline.period == c_TimeInfinite) + { + deadline_timer_.cancel_timer(); + } } @@ -352,15 +356,16 @@ void PublisherImpl::timer_reschedule() std::unique_lock lock(*mp_writer->getMutex()); - timer_owner_ = std::min_element(next_deadline_.begin(), - next_deadline_.end(), - [](const std::pair &lhs, const std::pair &rhs){ return lhs.second < rhs.second;})->first; + timer_owner_ = std::min_element(next_deadline_us_.begin(), + next_deadline_us_.end(), + []( + const std::pair &lhs, + const std::pair &rhs){ return lhs.second < rhs.second;})->first; - auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); - auto interval_s = next_deadline_[timer_owner_] - now_s; + auto interval_ms = duration_cast(next_deadline_us_[timer_owner_] - steady_clock::now()); deadline_timer_.cancel_timer(); - deadline_timer_.update_interval(interval_s); + deadline_timer_.update_interval_millisec(interval_ms.count()); deadline_timer_.restart_timer(); } @@ -376,8 +381,7 @@ void PublisherImpl::deadline_missed() mp_listener->on_offered_deadline_missed(mp_userPublisher, deadline_missed_status_); deadline_missed_status_.total_count_change = 0; - auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); - next_deadline_[timer_owner_] = now_s + deadline_duration_; + next_deadline_us_[timer_owner_] = steady_clock::now() + duration_cast(deadline_duration_us_); timer_reschedule(); } diff --git a/src/cpp/publisher/PublisherImpl.h b/src/cpp/publisher/PublisherImpl.h index 61a873b719a..c8aad87d220 100644 --- a/src/cpp/publisher/PublisherImpl.h +++ b/src/cpp/publisher/PublisherImpl.h @@ -166,10 +166,10 @@ class PublisherImpl //! A timer used to check for deadlines DeadlineTimer deadline_timer_; - //! Deadline duration - Duration_t deadline_duration_; + //! Deadline duration in microseconds + std::chrono::duration> deadline_duration_us_; //! A map where keys are instance handles and values are times when instances are due to 'expire', i.e. miss the deadline - std::map next_deadline_; + std::map next_deadline_us_; //! The current timer owner, i.e. the instance which started the timer InstanceHandle_t timer_owner_; //! The offered deadline missed status diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index 237f37f17d4..be5d8cae14e 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -32,7 +32,7 @@ #include using namespace eprosima::fastrtps::rtps; - +using namespace std::chrono; namespace eprosima { namespace fastrtps { @@ -57,8 +57,8 @@ SubscriberImpl::SubscriberImpl( att.qos.m_deadline.period, mp_participant->get_resource_event().getIOService(), mp_participant->get_resource_event().getThread()) - , deadline_duration_(att.qos.m_deadline.period) - , next_deadline_() + , deadline_duration_us_(m_att.qos.m_deadline.period.to_ns() * 1e-3) + , next_deadline_us_() , deadline_missed_status_() { } @@ -184,7 +184,12 @@ bool SubscriberImpl::updateAttributes(const SubscriberAttributes& att) mp_rtpsParticipant->updateReader(this->mp_reader, m_att.topic, m_att.qos); // Update deadline period - deadline_duration_ = m_att.qos.m_deadline.period; + + deadline_duration_us_ = duration>(m_att.qos.m_deadline.period.to_ns() * 1e-3); + if (m_att.qos.m_deadline.period == c_TimeInfinite) + { + deadline_timer_.cancel_timer(); + } } return updated; } @@ -213,8 +218,7 @@ void SubscriberImpl::onNewCacheChangeAdded(const CacheChange_t* const change) { std::unique_lock lock(*mp_reader->getMutex()); - auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); - next_deadline_[change->instanceHandle] = now_s + deadline_duration_; + next_deadline_us_[change->instanceHandle] = steady_clock::now() + duration_cast(deadline_duration_us_); if (timer_owner_ == change->instanceHandle || timer_owner_ == InstanceHandle_t()) { @@ -245,15 +249,16 @@ void SubscriberImpl::timer_reschedule() std::unique_lock lock(*mp_reader->getMutex()); - timer_owner_ = std::min_element(next_deadline_.begin(), - next_deadline_.end(), - [](const std::pair& lhs, const std::pair& rhs){ return lhs.second < rhs.second; })->first; + timer_owner_ = std::min_element(next_deadline_us_.begin(), + next_deadline_us_.end(), + []( + const std::pair& lhs, + const std::pair& rhs){ return lhs.second < rhs.second; })->first; - auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); - auto interval_s = next_deadline_[timer_owner_] - now_s; + auto interval_ms = duration_cast(next_deadline_us_[timer_owner_] - steady_clock::now()); deadline_timer_.cancel_timer(); - deadline_timer_.update_interval(interval_s); + deadline_timer_.update_interval_millisec(interval_ms.count()); deadline_timer_.restart_timer(); } @@ -269,8 +274,7 @@ void SubscriberImpl::deadline_missed() mp_listener->on_requested_deadline_missed(mp_userSubscriber, deadline_missed_status_); deadline_missed_status_.total_count_change = 0; - auto now_s = Time_t(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() * 1e-3); - next_deadline_[timer_owner_] = now_s + deadline_duration_; + next_deadline_us_[timer_owner_] = steady_clock::now() + duration_cast(deadline_duration_us_); timer_reschedule(); } diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index bc1d50b0f79..cfbdc7d1ff5 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -163,10 +163,10 @@ class SubscriberImpl { //! A timer used to check for deadlines DeadlineTimer deadline_timer_; - //! Deadline duration - Duration_t deadline_duration_; + //! Deadline duration in microseconds + std::chrono::duration> deadline_duration_us_; //! A map where keys are instance handles and values are times when instances are due to 'expire', i.e. miss the deadline - std::map next_deadline_; + std::map next_deadline_us_; //! The current timer owner, i.e. the instance which started the timer InstanceHandle_t timer_owner_; //! Requested deadline missed status From bbc344876d8d47eb41ceee681bc510f3c37f8c5d Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Thu, 14 Mar 2019 12:00:05 +0100 Subject: [PATCH 34/54] Refs #4693 Moving next_deadline map to history --- include/fastrtps/publisher/PublisherHistory.h | 54 ++++++++++- .../fastrtps/subscriber/SubscriberHistory.h | 51 ++++++++++- src/cpp/publisher/PublisherHistory.cpp | 76 ++++++++++++++-- src/cpp/publisher/PublisherImpl.cpp | 40 +++++--- src/cpp/publisher/PublisherImpl.h | 2 - src/cpp/subscriber/SubscriberHistory.cpp | 91 +++++++++++++++---- src/cpp/subscriber/SubscriberImpl.cpp | 33 ++++--- src/cpp/subscriber/SubscriberImpl.h | 2 - 8 files changed, 289 insertions(+), 60 deletions(-) diff --git a/include/fastrtps/publisher/PublisherHistory.h b/include/fastrtps/publisher/PublisherHistory.h index b40cd587394..c52cd9618e7 100644 --- a/include/fastrtps/publisher/PublisherHistory.h +++ b/include/fastrtps/publisher/PublisherHistory.h @@ -93,13 +93,61 @@ class PublisherHistory:public rtps::WriterHistory virtual bool remove_change_g(rtps::CacheChange_t* a_change); - private: + /** + * @brief Sets the next deadline for the given instance + * @param handle The instance handle + * @param next_deadline_us The time point when the deadline will occur + * @return True if deadline was set successfully + */ + bool set_next_deadline(InstanceHandle_t handle, std::chrono::steady_clock::time_point next_deadline_us); + + /** + * @brief Returns the deadline for the instance that is next going to 'expire' + * @param handle The handle for the instance that will next miss the deadline + * @param next_deadline_us The time point when the deadline will occur + * @return True if deadline could be retrieved for the given instance + */ + bool get_next_deadline(InstanceHandle_t& handle, std::chrono::steady_clock::time_point& next_deadline_us); + +private: - typedef std::map> t_m_Inst_Caches; - typedef std::vector t_v_Caches; + /** + * @brief A struct storing a vector of cache changes and the next deadline in the group + * @ingroup FASTRTPS_MODULE + */ + struct KeyedChanges + { + //! Default constructor + KeyedChanges() + : cache_changes_() + , next_deadline_us_() + { + } + + //! Copy constructor + KeyedChanges(const KeyedChanges& other) + : cache_changes_(other.cache_changes_) + , next_deadline_us_(other.next_deadline_us_) + { + } + + //! Destructor + ~KeyedChanges() + { + } + + //! A vector of cache changes + std::vector cache_changes_; + //! The time when the group will miss the deadline + std::chrono::steady_clock::time_point next_deadline_us_; + }; + + typedef std::map t_m_Inst_Caches; //!Map where keys are instance handles and values are vectors of cache changes associated t_m_Inst_Caches m_keyedChanges; + //!Time point when the next deadline will occur (only used for topics with no key) + std::chrono::steady_clock::time_point next_deadline_us_; //!HistoryQosPolicy values. HistoryQosPolicy m_historyQos; //!ResourceLimitsQosPolicy values. diff --git a/include/fastrtps/subscriber/SubscriberHistory.h b/include/fastrtps/subscriber/SubscriberHistory.h index b7de0bf7bb1..91e3c26c02a 100644 --- a/include/fastrtps/subscriber/SubscriberHistory.h +++ b/include/fastrtps/subscriber/SubscriberHistory.h @@ -113,15 +113,62 @@ class SubscriberHistory: public rtps::ReaderHistory return m_unreadCacheCount; } + /** + * @brief A method to set the next deadline for the given instance + * @param handle The handle to the instance + * @param next_deadline_us The time point when the deadline will occur + * @return True if the deadline was set correctly + */ + bool set_next_deadline(InstanceHandle_t handle, std::chrono::steady_clock::time_point next_deadline_us); + + /** + * @brief A method to get the next instance handle that will miss the deadline and the time when the deadline will occur + * @param handle The handle to the instance + * @param next_deadline_us The time point when the instance will miss the deadline + * @return True if the deadline was retrieved successfully + */ + bool get_next_deadline(InstanceHandle_t& handle, std::chrono::steady_clock::time_point& next_deadline_us); + private: - typedef std::map> t_m_Inst_Caches; - typedef std::vector t_v_Caches; + /** + * @brief A struct storing a vector of cache changes and the next deadline that will happen in the group + * @ingroup FASTRTPS_MODULE + */ + struct KeyedChanges + { + //! Default constructor + KeyedChanges() + : cache_changes_() + , next_deadline_us_() + {} + + //! Copy constructor + KeyedChanges(const KeyedChanges& other) + : cache_changes_(other.cache_changes_) + , next_deadline_us_(other.next_deadline_us_) + { + } + + //! Destructor + ~KeyedChanges() + { + } + + //! A vector of cache changes + std::vector cache_changes_; + //! The time point when the next deadline will occur + std::chrono::steady_clock::time_point next_deadline_us_; + }; + + typedef std::map t_m_Inst_Caches; //!Number of unread CacheChange_t. uint64_t m_unreadCacheCount; //!Map where keys are instance handles and values vectors of cache changes t_m_Inst_Caches m_keyedChanges; + //!Time point when the next deadline will occur (only used for topics with no key) + std::chrono::steady_clock::time_point next_deadline_us_; //!HistoryQosPolicy values. HistoryQosPolicy m_historyQos; //!ResourceLimitsQosPolicy values. diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index 397a37153a1..e5d54e4e84f 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -111,7 +111,7 @@ bool PublisherHistory::add_pub_change( bool add = false; if(m_historyQos.kind == KEEP_ALL_HISTORY_QOS) { - if((int32_t)vit->second.size() < m_resourceLimitsQos.max_samples_per_instance) + if((int32_t)vit->second.cache_changes_.size() < m_resourceLimitsQos.max_samples_per_instance) { add = true; } @@ -122,13 +122,13 @@ bool PublisherHistory::add_pub_change( } else if (m_historyQos.kind == KEEP_LAST_HISTORY_QOS) { - if(vit->second.size() < (size_t)m_historyQos.depth) + if(vit->second.cache_changes_.size() < (size_t)m_historyQos.depth) { add = true; } else { - if(remove_change_pub(vit->second.front())) + if(remove_change_pub(vit->second.cache_changes_.front())) { add = true; } @@ -142,7 +142,7 @@ bool PublisherHistory::add_pub_change( logInfo(RTPS_HISTORY,this->mp_pubImpl->getGuid().entityId <<" Change " << change->sequenceNumber << " added with key: "<instanceHandle << " and "<serializedPayload.length<< " bytes"); - vit->second.push_back(change); + vit->second.cache_changes_.push_back(change); returnedValue = true; } } @@ -167,17 +167,17 @@ bool PublisherHistory::find_key( if ((int)m_keyedChanges.size() < m_resourceLimitsQos.max_instances) { - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, t_v_Caches())).first; + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; return true; } else { for (vit = m_keyedChanges.begin(); vit != m_keyedChanges.end(); ++vit) { - if (vit->second.size() == 0) + if (vit->second.cache_changes_.size() == 0) { m_keyedChanges.erase(vit); - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, t_v_Caches())).first; + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; return true; } } @@ -250,14 +250,14 @@ bool PublisherHistory::remove_change_pub(CacheChange_t* change) return false; } - for(auto chit = vit->second.begin(); chit!= vit->second.end(); ++chit) + for(auto chit = vit->second.cache_changes_.begin(); chit!= vit->second.cache_changes_.end(); ++chit) { if( ((*chit)->sequenceNumber == change->sequenceNumber) && ((*chit)->writerGUID == change->writerGUID) ) { if(remove_change(change)) { - vit->second.erase(chit); + vit->second.cache_changes_.erase(chit); m_isHistoryFull = false; return true; } @@ -272,3 +272,61 @@ bool PublisherHistory::remove_change_g(CacheChange_t* a_change) { return remove_change_pub(a_change); } + +bool PublisherHistory::set_next_deadline(InstanceHandle_t handle, std::chrono::steady_clock::time_point next_deadline_us) +{ + if(mp_writer == nullptr || mp_mutex == nullptr) + { + logError(RTPS_HISTORY,"You need to create a Writer with this History before using it"); + return false; + } + std::lock_guard guard(*this->mp_mutex); + + if (mp_pubImpl->getAttributes().topic.getTopicKind() == NO_KEY) + { + next_deadline_us_ = next_deadline_us; + return true; + } + else if(mp_pubImpl->getAttributes().topic.getTopicKind() == WITH_KEY) + { + if (m_keyedChanges.find(handle) == m_keyedChanges.end()) + { + return false; + } + + m_keyedChanges[handle].next_deadline_us_ = next_deadline_us; + return true; + } + + return false; +} + +bool PublisherHistory::get_next_deadline(InstanceHandle_t &handle, std::chrono::steady_clock::time_point &next_deadline_us) +{ + if(mp_writer == nullptr || mp_mutex == nullptr) + { + logError(RTPS_HISTORY,"You need to create a Writer with this History before using it"); + return false; + } + std::lock_guard guard(*this->mp_mutex); + + if(mp_pubImpl->getAttributes().topic.getTopicKind() == WITH_KEY) + { + auto min = std::min_element(m_keyedChanges.begin(), + m_keyedChanges.end(), + []( + const std::pair &lhs, + const std::pair &rhs){ return lhs.second.next_deadline_us_ < rhs.second.next_deadline_us_;}); + + handle = min->first; + next_deadline_us = min->second.next_deadline_us_; + return true; + } + else if (mp_pubImpl->getAttributes().topic.getTopicKind() == NO_KEY) + { + next_deadline_us = next_deadline_us_; + return true; + } + + return false; +} diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index 99b71533faf..ed0ffe5d6c3 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -68,7 +68,6 @@ PublisherImpl::PublisherImpl( mp_participant->get_resource_event().getIOService(), mp_participant->get_resource_event().getThread()) , deadline_duration_us_(m_att.qos.m_deadline.period.to_ns() * 1e-3) - , next_deadline_us_() , timer_owner_() , deadline_missed_status_() { @@ -81,6 +80,11 @@ PublisherImpl::~PublisherImpl() logInfo(PUBLISHER, this->getGuid().entityId << " in topic: " << this->m_att.topic.topicName); } + if (m_att.qos.m_deadline.period != c_TimeInfinite) + { + deadline_timer_.cancel_timer(); + } + RTPSDomain::removeRTPSWriter(mp_writer); delete(this->mp_userPublisher); } @@ -205,11 +209,16 @@ bool PublisherImpl::create_new_change_with_params( if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { - next_deadline_us_[handle] = steady_clock::now() + duration_cast(deadline_duration_us_); - - if (timer_owner_ == handle || timer_owner_ == InstanceHandle_t()) + if (!m_history.set_next_deadline(ch->instanceHandle, steady_clock::now() + duration_cast(deadline_duration_us_))) { - timer_reschedule(); + logError(PUBLISHER, "Could not set the next deadline in the history"); + } + else + { + if (timer_owner_ == handle || timer_owner_ == InstanceHandle_t()) + { + timer_reschedule(); + } } } return true; @@ -356,13 +365,13 @@ void PublisherImpl::timer_reschedule() std::unique_lock lock(*mp_writer->getMutex()); - timer_owner_ = std::min_element(next_deadline_us_.begin(), - next_deadline_us_.end(), - []( - const std::pair &lhs, - const std::pair &rhs){ return lhs.second < rhs.second;})->first; - - auto interval_ms = duration_cast(next_deadline_us_[timer_owner_] - steady_clock::now()); + steady_clock::time_point next_deadline_us; + if (!m_history.get_next_deadline(timer_owner_, next_deadline_us)) + { + logError(PUBLISHER, "Could not get the next deadline from the history"); + return; + } + auto interval_ms = duration_cast(next_deadline_us - steady_clock::now()); deadline_timer_.cancel_timer(); deadline_timer_.update_interval_millisec(interval_ms.count()); @@ -381,8 +390,11 @@ void PublisherImpl::deadline_missed() mp_listener->on_offered_deadline_missed(mp_userPublisher, deadline_missed_status_); deadline_missed_status_.total_count_change = 0; - next_deadline_us_[timer_owner_] = steady_clock::now() + duration_cast(deadline_duration_us_); - + if (!m_history.set_next_deadline(timer_owner_, steady_clock::now() + duration_cast(deadline_duration_us_))) + { + logError(PUBLISHER, "Could not set the next deadline in the history"); + return; + } timer_reschedule(); } diff --git a/src/cpp/publisher/PublisherImpl.h b/src/cpp/publisher/PublisherImpl.h index c8aad87d220..f3431bce302 100644 --- a/src/cpp/publisher/PublisherImpl.h +++ b/src/cpp/publisher/PublisherImpl.h @@ -168,8 +168,6 @@ class PublisherImpl DeadlineTimer deadline_timer_; //! Deadline duration in microseconds std::chrono::duration> deadline_duration_us_; - //! A map where keys are instance handles and values are times when instances are due to 'expire', i.e. miss the deadline - std::map next_deadline_us_; //! The current timer owner, i.e. the instance which started the timer InstanceHandle_t timer_owner_; //! The offered deadline missed status diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index db70cf06d67..30dff440d27 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -186,7 +186,7 @@ bool SubscriberHistory::received_change( bool add = false; if (m_historyQos.kind == KEEP_ALL_HISTORY_QOS) { - if ((int32_t)vit->second.size() < m_resourceLimitsQos.max_samples_per_instance) + if ((int32_t)vit->second.cache_changes_.size() < m_resourceLimitsQos.max_samples_per_instance) { add = true; } @@ -198,15 +198,15 @@ bool SubscriberHistory::received_change( } else if (m_historyQos.kind == KEEP_LAST_HISTORY_QOS) { - if (vit->second.size() < (size_t)m_historyQos.depth) + if (vit->second.cache_changes_.size() < (size_t)m_historyQos.depth) { add = true; } else { // Try to substitute the oldest sample with the same key - auto older_sample = vit->second.rend(); - for (auto it = vit->second.rbegin(); it != vit->second.rend(); ++it) + auto older_sample = vit->second.cache_changes_.rend(); + for (auto it = vit->second.cache_changes_.rbegin(); it != vit->second.cache_changes_.rend(); ++it) { if ((*it)->writerGUID == a_change->writerGUID) @@ -219,7 +219,7 @@ bool SubscriberHistory::received_change( } } - if (older_sample != vit->second.rend()) + if (older_sample != vit->second.cache_changes_.rend()) { bool read = (*older_sample)->isRead; @@ -250,19 +250,19 @@ bool SubscriberHistory::received_change( if ((int32_t)m_changes.size() == m_resourceLimitsQos.max_samples) m_isHistoryFull = true; //ADD TO KEY VECTOR - if (vit->second.size() == 0) + if (vit->second.cache_changes_.size() == 0) { - vit->second.push_back(a_change); + vit->second.cache_changes_.push_back(a_change); } - else if (vit->second.back()->sequenceNumber < a_change->sequenceNumber) + else if (vit->second.cache_changes_.back()->sequenceNumber < a_change->sequenceNumber) { - vit->second.push_back(a_change); + vit->second.cache_changes_.push_back(a_change); } else { - vit->second.push_back(a_change); - std::sort(vit->second.begin(), - vit->second.end(), + vit->second.cache_changes_.push_back(a_change); + std::sort(vit->second.cache_changes_.begin(), + vit->second.cache_changes_.end(), sort_ReaderHistoryCache); } @@ -488,17 +488,17 @@ bool SubscriberHistory::find_key( if ((int)m_keyedChanges.size() < m_resourceLimitsQos.max_instances) { - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, t_v_Caches())).first; + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; return true; } else { for (vit = m_keyedChanges.begin(); vit!= m_keyedChanges.end(); ++vit) { - if (vit->second.size() == 0) + if (vit->second.cache_changes_.size() == 0) { m_keyedChanges.erase(vit); - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, t_v_Caches())).first; + *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; return true; } } @@ -534,13 +534,13 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change) return false; } - for (auto chit = vit->second.begin(); chit != vit->second.end(); ++chit) + for (auto chit = vit->second.cache_changes_.begin(); chit != vit->second.cache_changes_.end(); ++chit) { if ((*chit)->sequenceNumber == change->sequenceNumber && (*chit)->writerGUID == change->writerGUID) { if (remove_change(change)) { - vit->second.erase(chit); + vit->second.cache_changes_.erase(chit); m_isHistoryFull = false; return true; } @@ -550,3 +550,60 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change) } return false; } + +bool SubscriberHistory::set_next_deadline(InstanceHandle_t handle, std::chrono::steady_clock::time_point next_deadline_us) +{ + if (mp_reader == nullptr || mp_mutex == nullptr) + { + logError(RTPS_HISTORY, "You need to create a Reader with this History before using it"); + return false; + } + std::lock_guard guard(*mp_mutex); + + if (mp_subImpl->getAttributes().topic.getTopicKind() == NO_KEY) + { + next_deadline_us_ = next_deadline_us; + return true; + } + else if (mp_subImpl->getAttributes().topic.getTopicKind() == WITH_KEY) + { + if (m_keyedChanges.find(handle) == m_keyedChanges.end()) + { + return false; + } + + m_keyedChanges[handle].next_deadline_us_ = next_deadline_us; + return true; + } + + return false; +} + +bool SubscriberHistory::get_next_deadline(InstanceHandle_t &handle, std::chrono::steady_clock::time_point &next_deadline_us) +{ + if (mp_reader == nullptr || mp_mutex == nullptr) + { + logError(RTPS_HISTORY, "You need to create a Reader with this History before using it"); + return false; + } + std::lock_guard guard(*mp_mutex); + + if (mp_subImpl->getAttributes().topic.getTopicKind() == NO_KEY) + { + next_deadline_us = next_deadline_us_; + return true; + } + else if (mp_subImpl->getAttributes().topic.getTopicKind() == WITH_KEY) + { + auto min = std::min_element(m_keyedChanges.begin(), + m_keyedChanges.end(), + []( + const std::pair &lhs, + const std::pair &rhs){ return lhs.second.next_deadline_us_ < rhs.second.next_deadline_us_;}); + handle = min->first; + next_deadline_us = min->second.next_deadline_us_; + return true; + } + + return false; +} diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index be5d8cae14e..81f3aa0a680 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -58,7 +58,6 @@ SubscriberImpl::SubscriberImpl( mp_participant->get_resource_event().getIOService(), mp_participant->get_resource_event().getThread()) , deadline_duration_us_(m_att.qos.m_deadline.period.to_ns() * 1e-3) - , next_deadline_us_() , deadline_missed_status_() { } @@ -70,6 +69,11 @@ SubscriberImpl::~SubscriberImpl() logInfo(SUBSCRIBER,this->getGuid().entityId << " in topic: "<m_att.topic.topicName); } + if (m_att.qos.m_deadline.period != c_TimeInfinite) + { + deadline_timer_.cancel_timer(); + } + RTPSDomain::removeRTPSReader(mp_reader); delete(this->mp_userSubscriber); } @@ -218,7 +222,11 @@ void SubscriberImpl::onNewCacheChangeAdded(const CacheChange_t* const change) { std::unique_lock lock(*mp_reader->getMutex()); - next_deadline_us_[change->instanceHandle] = steady_clock::now() + duration_cast(deadline_duration_us_); + if (!m_history.set_next_deadline(change->instanceHandle, steady_clock::now() + duration_cast(deadline_duration_us_))) + { + logError(SUBSCRIBER, "Could not set next deadline in the history"); + return; + } if (timer_owner_ == change->instanceHandle || timer_owner_ == InstanceHandle_t()) { @@ -249,13 +257,13 @@ void SubscriberImpl::timer_reschedule() std::unique_lock lock(*mp_reader->getMutex()); - timer_owner_ = std::min_element(next_deadline_us_.begin(), - next_deadline_us_.end(), - []( - const std::pair& lhs, - const std::pair& rhs){ return lhs.second < rhs.second; })->first; - - auto interval_ms = duration_cast(next_deadline_us_[timer_owner_] - steady_clock::now()); + steady_clock::time_point next_deadline_us; + if (!m_history.get_next_deadline(timer_owner_, next_deadline_us)) + { + logError(SUBSCRIBER, "Could not get the next deadline from the history"); + return; + } + auto interval_ms = duration_cast(next_deadline_us - steady_clock::now()); deadline_timer_.cancel_timer(); deadline_timer_.update_interval_millisec(interval_ms.count()); @@ -274,8 +282,11 @@ void SubscriberImpl::deadline_missed() mp_listener->on_requested_deadline_missed(mp_userSubscriber, deadline_missed_status_); deadline_missed_status_.total_count_change = 0; - next_deadline_us_[timer_owner_] = steady_clock::now() + duration_cast(deadline_duration_us_); - + if (!m_history.set_next_deadline(timer_owner_, steady_clock::now() + duration_cast(deadline_duration_us_))) + { + logError(SUBSCRIBER, "Could not set next deadline in the history"); + return; + } timer_reschedule(); } diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index cfbdc7d1ff5..f481fd4bcea 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -165,8 +165,6 @@ class SubscriberImpl { DeadlineTimer deadline_timer_; //! Deadline duration in microseconds std::chrono::duration> deadline_duration_us_; - //! A map where keys are instance handles and values are times when instances are due to 'expire', i.e. miss the deadline - std::map next_deadline_us_; //! The current timer owner, i.e. the instance which started the timer InstanceHandle_t timer_owner_; //! Requested deadline missed status From d5780d089f10f1aeade0551e42dd92003dcf4ae1 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Thu, 14 Mar 2019 12:10:44 +0100 Subject: [PATCH 35/54] Refs #4693 Clarify example description --- examples/C++/DeadlineQoSExample/README.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/C++/DeadlineQoSExample/README.txt b/examples/C++/DeadlineQoSExample/README.txt index 7e27047e207..06089d102b7 100644 --- a/examples/C++/DeadlineQoSExample/README.txt +++ b/examples/C++/DeadlineQoSExample/README.txt @@ -15,8 +15,11 @@ In the second one launch: ./DeadlineQoSExample subscriber 2 - Application behaviour ------------------------- -With the default options provided in the example, the application will use a topic with three different keys, -one of which sends a sample only half of the times. +The application will use a topic with three different keys, +one of which (the third one) sends a sample only half of the times. + +By default the deadline period is set to 2000 ms and the publisher write rate to 1000 ms, so +that the third instance misses the deadline 50% of the times. The deadline period can be set by providing a second argument to the binary. For example: From 33fce99d790a838d762e36ba49d8f2d962f97266 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Tue, 26 Mar 2019 12:47:19 +0100 Subject: [PATCH 36/54] Refs #4993 Addressing review suggestions related to C++ example --- examples/C++/DeadlineQoSExample/README.md | 30 ++++ examples/C++/DeadlineQoSExample/README.txt | 34 ---- .../deadlinepayloadPubSubMain.cxx | 165 +++++++++++++----- 3 files changed, 151 insertions(+), 78 deletions(-) create mode 100644 examples/C++/DeadlineQoSExample/README.md delete mode 100644 examples/C++/DeadlineQoSExample/README.txt diff --git a/examples/C++/DeadlineQoSExample/README.md b/examples/C++/DeadlineQoSExample/README.md new file mode 100644 index 00000000000..0c10c2cedcf --- /dev/null +++ b/examples/C++/DeadlineQoSExample/README.md @@ -0,0 +1,30 @@ +# Deadline QoS example + +## Application description + +This example illustrates the Deadline QoS feature on a FastRTPS Application. + +To launch this example open two different consoles: + +In the first one launch: ./DeadlineQoSExample publisher +In the second one launch: ./DeadlineQoSExample subscriber + +## Application behaviour + +The application will use a topic with three different keys, +one of which (the third one) sends a sample only half of the times. + +By default the deadline period is set to 2000 ms and the publisher write rate to 1000 ms, so +that the third instance misses the deadline 50% of the time. The number of samples that will be written is set to 10. + +The default behaviour can be changed by providing the following command line arguments: + +./DeadlineQoSExample publisher [--deadline <deadline_ms>] [--sleep <writer_sleep_ms>] [--samples <samples>] +./DeadlineQoSExample subscriber [--deadline <deadline_ms>] + +For example: + +./DeadlineQoSExample publisher --deadline 1000 --sleep 500 --samples 5 +./DeadlineQosExample subscriber --deadline 1000 + +will setup the publisher and subscriber to use a deadline period of 1000 ms, the publisher will write a new sample every 500 ms for the first two keys and every 1000 ms for the third one, and a total of 5 samples will be sent. \ No newline at end of file diff --git a/examples/C++/DeadlineQoSExample/README.txt b/examples/C++/DeadlineQoSExample/README.txt deleted file mode 100644 index 06089d102b7..00000000000 --- a/examples/C++/DeadlineQoSExample/README.txt +++ /dev/null @@ -1,34 +0,0 @@ ------------------------- -| DEADLINE EXAMPLE | ------------------------- - -1 - Application description ---------------------------- - -This example illustrates the Deadline QoS feature on a FastRTPS Application. - -To launch this example open two different consoles: - -In the first one launch: ./DeadlineQoSExample publisher -In the second one launch: ./DeadlineQoSExample subscriber - -2 - Application behaviour -------------------------- - -The application will use a topic with three different keys, -one of which (the third one) sends a sample only half of the times. - -By default the deadline period is set to 2000 ms and the publisher write rate to 1000 ms, so -that the third instance misses the deadline 50% of the times. - -The deadline period can be set by providing a second argument to the binary. For example: - -./DeadlineQoSExample publisher 1000 -./DeadlineQosExample subscriber 1000 - -will set a deadline period of 1000 ms in both publisher and subscriber. Additionally, the rate at which the -publisher writes can be changed by providing a third argument. For example: - -./DeadlineQoSExample publisher 1000 500 - -will make the publisher write samples every 500 ms. diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx index ef826eab4f3..e2c636b2c02 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPubSubMain.cxx @@ -23,69 +23,146 @@ using namespace eprosima; using namespace eprosima::fastrtps; using namespace asio; -int main(int argc, char** argv) + +/** + * @brief Parses command line arguments + * @param argc Number of command line arguments + * @param argv Array of command line arguments + * @param type Publisher or subscriber + * @param deadline_ms Deadline value read from command line arguments (populated if specified) + * @param sleep_ms Writer sleep read from command line arguments (populated if specified) + * @param samples Number of samples read from command line arguments (populated if specified) + * @return True if command line arguments were parsed succesfully and execution can continue + */ +bool parse_arguments( + int argc, + char** argv, + int& type, + int& deadline_ms, + int& sleep_ms, + int& samples) { - std::cout << "Starting " << std::endl; - int type = 1; - int deadline_ms = 2000; - int sleep_ms = 1000; - int samples = 0; - if (argc > 1) + if (argc == 1) + { + // No arguments provided + return false; + } + + for (int i=0; i 2) + if (!strcmp(argv[count], "--deadline")) + { + deadline_ms = atoi(argv[count + 1]); + } + else if (!strcmp(argv[count], "--sleep")) + { + sleep_ms = atoi(argv[count + 1]); + } + else if (!strcmp(argv[count], "--samples")) + { + samples = atoi(argv[count + 1]); + } + else { - deadline_ms = atoi(argv[2]); - if (argc > 3) - { - sleep_ms = atoi(argv[3]); - if (argc > 4) - { - samples = atoi(argv[4]); - } - } + std::cout << "Unknown command line option " << argv[count] << " for publisher" << std::endl; + return false; } + count = count + 2; + } + return true; + } + + if (strcmp(argv[1], "subscriber") == 0) + { + type = 2; + + if (argc != 2 && argc != 4) + { + // Incorrect number of command line arguments for subscriber + return false; } - else if (strcmp(argv[1], "subscriber") == 0) + + if (argc > 2) { - type = 2; - if (argc > 2) + if (!strcmp(argv[2], "--deadline")) { - deadline_ms = atoi(argv[2]); + deadline_ms = atoi(argv[3]); + } + else + { + std::cout << "Unknown command line option " << argv[2] << " for publisher" << std::endl; + return false; } } + return true; } - else + + return false; +} + +int main(int argc, char** argv) +{ + int deadline_ms = 2000; + int sleep_ms = 1000; + int samples = 0; + int type = 1; + + if (!parse_arguments(argc, + argv, + type, + deadline_ms, + sleep_ms, + samples)) { - std::cout << "publisher OR subscriber argument needed" << std::endl; + std::cout << "Usage: " << std::endl; + std::cout << argv[0] << " publisher [--deadline ] [--sleep ] [--samples ]" << std::endl; + std::cout << "OR" << std::endl; + std::cout << argv[0] << " subscriber [--deadline ]" << std::endl; return 0; } // Register the type being used - switch(type) { - case 1: - { - deadlinepayloadPublisher mypub; - if (mypub.init(deadline_ms)) - { - mypub.run(sleep_ms, samples); - } - break; - } - case 2: - { - deadlinepayloadSubscriber mysub; - if (mysub.init(deadline_ms)) - { - mysub.run(); - } - break; - } + case 1: + { + deadlinepayloadPublisher mypub; + if (mypub.init(deadline_ms)) + { + mypub.run(sleep_ms, samples); + } + break; + } + case 2: + { + deadlinepayloadSubscriber mysub; + if (mysub.init(deadline_ms)) + { + mysub.run(); + } + break; + } } return 0; From d445ee789dd449bb6b042dceb90f5f3dbe43ba21 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Tue, 26 Mar 2019 15:15:29 +0100 Subject: [PATCH 37/54] Refs #4993 Applying coding style to public member variables --- include/fastrtps/publisher/PublisherHistory.h | 18 +++--- .../fastrtps/subscriber/SubscriberHistory.h | 22 ++++--- src/cpp/publisher/PublisherHistory.cpp | 48 ++++++++------- src/cpp/subscriber/SubscriberHistory.cpp | 60 ++++++++++--------- 4 files changed, 80 insertions(+), 68 deletions(-) diff --git a/include/fastrtps/publisher/PublisherHistory.h b/include/fastrtps/publisher/PublisherHistory.h index c52cd9618e7..9309c2250a6 100644 --- a/include/fastrtps/publisher/PublisherHistory.h +++ b/include/fastrtps/publisher/PublisherHistory.h @@ -99,7 +99,9 @@ class PublisherHistory:public rtps::WriterHistory * @param next_deadline_us The time point when the deadline will occur * @return True if deadline was set successfully */ - bool set_next_deadline(InstanceHandle_t handle, std::chrono::steady_clock::time_point next_deadline_us); + bool set_next_deadline( + const InstanceHandle_t& handle, + const std::chrono::steady_clock::time_point& next_deadline_us); /** * @brief Returns the deadline for the instance that is next going to 'expire' @@ -119,15 +121,15 @@ class PublisherHistory:public rtps::WriterHistory { //! Default constructor KeyedChanges() - : cache_changes_() - , next_deadline_us_() + : cache_changes() + , next_deadline_us() { } //! Copy constructor KeyedChanges(const KeyedChanges& other) - : cache_changes_(other.cache_changes_) - , next_deadline_us_(other.next_deadline_us_) + : cache_changes(other.cache_changes) + , next_deadline_us(other.next_deadline_us) { } @@ -137,15 +139,15 @@ class PublisherHistory:public rtps::WriterHistory } //! A vector of cache changes - std::vector cache_changes_; + std::vector cache_changes; //! The time when the group will miss the deadline - std::chrono::steady_clock::time_point next_deadline_us_; + std::chrono::steady_clock::time_point next_deadline_us; }; typedef std::map t_m_Inst_Caches; //!Map where keys are instance handles and values are vectors of cache changes associated - t_m_Inst_Caches m_keyedChanges; + t_m_Inst_Caches keyed_changes_; //!Time point when the next deadline will occur (only used for topics with no key) std::chrono::steady_clock::time_point next_deadline_us_; //!HistoryQosPolicy values. diff --git a/include/fastrtps/subscriber/SubscriberHistory.h b/include/fastrtps/subscriber/SubscriberHistory.h index 91e3c26c02a..0ecaface293 100644 --- a/include/fastrtps/subscriber/SubscriberHistory.h +++ b/include/fastrtps/subscriber/SubscriberHistory.h @@ -119,7 +119,9 @@ class SubscriberHistory: public rtps::ReaderHistory * @param next_deadline_us The time point when the deadline will occur * @return True if the deadline was set correctly */ - bool set_next_deadline(InstanceHandle_t handle, std::chrono::steady_clock::time_point next_deadline_us); + bool set_next_deadline( + const InstanceHandle_t& handle, + const std::chrono::steady_clock::time_point& next_deadline_us); /** * @brief A method to get the next instance handle that will miss the deadline and the time when the deadline will occur @@ -127,7 +129,9 @@ class SubscriberHistory: public rtps::ReaderHistory * @param next_deadline_us The time point when the instance will miss the deadline * @return True if the deadline was retrieved successfully */ - bool get_next_deadline(InstanceHandle_t& handle, std::chrono::steady_clock::time_point& next_deadline_us); + bool get_next_deadline( + InstanceHandle_t& handle, + std::chrono::steady_clock::time_point& next_deadline_us); private: @@ -139,14 +143,14 @@ class SubscriberHistory: public rtps::ReaderHistory { //! Default constructor KeyedChanges() - : cache_changes_() - , next_deadline_us_() + : cache_changes() + , next_deadline_us() {} //! Copy constructor KeyedChanges(const KeyedChanges& other) - : cache_changes_(other.cache_changes_) - , next_deadline_us_(other.next_deadline_us_) + : cache_changes(other.cache_changes) + , next_deadline_us(other.next_deadline_us) { } @@ -156,9 +160,9 @@ class SubscriberHistory: public rtps::ReaderHistory } //! A vector of cache changes - std::vector cache_changes_; + std::vector cache_changes; //! The time point when the next deadline will occur - std::chrono::steady_clock::time_point next_deadline_us_; + std::chrono::steady_clock::time_point next_deadline_us; }; typedef std::map t_m_Inst_Caches; @@ -166,7 +170,7 @@ class SubscriberHistory: public rtps::ReaderHistory //!Number of unread CacheChange_t. uint64_t m_unreadCacheCount; //!Map where keys are instance handles and values vectors of cache changes - t_m_Inst_Caches m_keyedChanges; + t_m_Inst_Caches keyed_changes_; //!Time point when the next deadline will occur (only used for topics with no key) std::chrono::steady_clock::time_point next_deadline_us_; //!HistoryQosPolicy values. diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index e5d54e4e84f..06b5e7a9a8a 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -111,7 +111,7 @@ bool PublisherHistory::add_pub_change( bool add = false; if(m_historyQos.kind == KEEP_ALL_HISTORY_QOS) { - if((int32_t)vit->second.cache_changes_.size() < m_resourceLimitsQos.max_samples_per_instance) + if((int32_t)vit->second.cache_changes.size() < m_resourceLimitsQos.max_samples_per_instance) { add = true; } @@ -122,13 +122,13 @@ bool PublisherHistory::add_pub_change( } else if (m_historyQos.kind == KEEP_LAST_HISTORY_QOS) { - if(vit->second.cache_changes_.size() < (size_t)m_historyQos.depth) + if(vit->second.cache_changes.size() < (size_t)m_historyQos.depth) { add = true; } else { - if(remove_change_pub(vit->second.cache_changes_.front())) + if(remove_change_pub(vit->second.cache_changes.front())) { add = true; } @@ -142,7 +142,7 @@ bool PublisherHistory::add_pub_change( logInfo(RTPS_HISTORY,this->mp_pubImpl->getGuid().entityId <<" Change " << change->sequenceNumber << " added with key: "<instanceHandle << " and "<serializedPayload.length<< " bytes"); - vit->second.cache_changes_.push_back(change); + vit->second.cache_changes.push_back(change); returnedValue = true; } } @@ -158,26 +158,26 @@ bool PublisherHistory::find_key( t_m_Inst_Caches::iterator* vit_out) { t_m_Inst_Caches::iterator vit; - vit = m_keyedChanges.find(a_change->instanceHandle); - if (vit != m_keyedChanges.end()) + vit = keyed_changes_.find(a_change->instanceHandle); + if (vit != keyed_changes_.end()) { *vit_out = vit; return true; } - if ((int)m_keyedChanges.size() < m_resourceLimitsQos.max_instances) + if ((int)keyed_changes_.size() < m_resourceLimitsQos.max_instances) { - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; + *vit_out = keyed_changes_.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; return true; } else { - for (vit = m_keyedChanges.begin(); vit != m_keyedChanges.end(); ++vit) + for (vit = keyed_changes_.begin(); vit != keyed_changes_.end(); ++vit) { - if (vit->second.cache_changes_.size() == 0) + if (vit->second.cache_changes.size() == 0) { - m_keyedChanges.erase(vit); - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; + keyed_changes_.erase(vit); + *vit_out = keyed_changes_.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; return true; } } @@ -250,14 +250,14 @@ bool PublisherHistory::remove_change_pub(CacheChange_t* change) return false; } - for(auto chit = vit->second.cache_changes_.begin(); chit!= vit->second.cache_changes_.end(); ++chit) + for(auto chit = vit->second.cache_changes.begin(); chit!= vit->second.cache_changes.end(); ++chit) { if( ((*chit)->sequenceNumber == change->sequenceNumber) && ((*chit)->writerGUID == change->writerGUID) ) { if(remove_change(change)) { - vit->second.cache_changes_.erase(chit); + vit->second.cache_changes.erase(chit); m_isHistoryFull = false; return true; } @@ -273,7 +273,9 @@ bool PublisherHistory::remove_change_g(CacheChange_t* a_change) return remove_change_pub(a_change); } -bool PublisherHistory::set_next_deadline(InstanceHandle_t handle, std::chrono::steady_clock::time_point next_deadline_us) +bool PublisherHistory::set_next_deadline( + const InstanceHandle_t& handle, + const std::chrono::steady_clock::time_point& next_deadline_us) { if(mp_writer == nullptr || mp_mutex == nullptr) { @@ -289,19 +291,21 @@ bool PublisherHistory::set_next_deadline(InstanceHandle_t handle, std::chrono::s } else if(mp_pubImpl->getAttributes().topic.getTopicKind() == WITH_KEY) { - if (m_keyedChanges.find(handle) == m_keyedChanges.end()) + if (keyed_changes_.find(handle) == keyed_changes_.end()) { return false; } - m_keyedChanges[handle].next_deadline_us_ = next_deadline_us; + keyed_changes_[handle].next_deadline_us = next_deadline_us; return true; } return false; } -bool PublisherHistory::get_next_deadline(InstanceHandle_t &handle, std::chrono::steady_clock::time_point &next_deadline_us) +bool PublisherHistory::get_next_deadline( + InstanceHandle_t &handle, + std::chrono::steady_clock::time_point &next_deadline_us) { if(mp_writer == nullptr || mp_mutex == nullptr) { @@ -312,14 +316,14 @@ bool PublisherHistory::get_next_deadline(InstanceHandle_t &handle, std::chrono:: if(mp_pubImpl->getAttributes().topic.getTopicKind() == WITH_KEY) { - auto min = std::min_element(m_keyedChanges.begin(), - m_keyedChanges.end(), + auto min = std::min_element(keyed_changes_.begin(), + keyed_changes_.end(), []( const std::pair &lhs, - const std::pair &rhs){ return lhs.second.next_deadline_us_ < rhs.second.next_deadline_us_;}); + const std::pair &rhs){ return lhs.second.next_deadline_us < rhs.second.next_deadline_us;}); handle = min->first; - next_deadline_us = min->second.next_deadline_us_; + next_deadline_us = min->second.next_deadline_us; return true; } else if (mp_pubImpl->getAttributes().topic.getTopicKind() == NO_KEY) diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index 30dff440d27..afa5deca456 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -186,7 +186,7 @@ bool SubscriberHistory::received_change( bool add = false; if (m_historyQos.kind == KEEP_ALL_HISTORY_QOS) { - if ((int32_t)vit->second.cache_changes_.size() < m_resourceLimitsQos.max_samples_per_instance) + if ((int32_t)vit->second.cache_changes.size() < m_resourceLimitsQos.max_samples_per_instance) { add = true; } @@ -198,15 +198,15 @@ bool SubscriberHistory::received_change( } else if (m_historyQos.kind == KEEP_LAST_HISTORY_QOS) { - if (vit->second.cache_changes_.size() < (size_t)m_historyQos.depth) + if (vit->second.cache_changes.size() < (size_t)m_historyQos.depth) { add = true; } else { // Try to substitute the oldest sample with the same key - auto older_sample = vit->second.cache_changes_.rend(); - for (auto it = vit->second.cache_changes_.rbegin(); it != vit->second.cache_changes_.rend(); ++it) + auto older_sample = vit->second.cache_changes.rend(); + for (auto it = vit->second.cache_changes.rbegin(); it != vit->second.cache_changes.rend(); ++it) { if ((*it)->writerGUID == a_change->writerGUID) @@ -219,7 +219,7 @@ bool SubscriberHistory::received_change( } } - if (older_sample != vit->second.cache_changes_.rend()) + if (older_sample != vit->second.cache_changes.rend()) { bool read = (*older_sample)->isRead; @@ -250,19 +250,19 @@ bool SubscriberHistory::received_change( if ((int32_t)m_changes.size() == m_resourceLimitsQos.max_samples) m_isHistoryFull = true; //ADD TO KEY VECTOR - if (vit->second.cache_changes_.size() == 0) + if (vit->second.cache_changes.size() == 0) { - vit->second.cache_changes_.push_back(a_change); + vit->second.cache_changes.push_back(a_change); } - else if (vit->second.cache_changes_.back()->sequenceNumber < a_change->sequenceNumber) + else if (vit->second.cache_changes.back()->sequenceNumber < a_change->sequenceNumber) { - vit->second.cache_changes_.push_back(a_change); + vit->second.cache_changes.push_back(a_change); } else { - vit->second.cache_changes_.push_back(a_change); - std::sort(vit->second.cache_changes_.begin(), - vit->second.cache_changes_.end(), + vit->second.cache_changes.push_back(a_change); + std::sort(vit->second.cache_changes.begin(), + vit->second.cache_changes.end(), sort_ReaderHistoryCache); } @@ -479,26 +479,26 @@ bool SubscriberHistory::find_key( t_m_Inst_Caches::iterator* vit_out) { t_m_Inst_Caches::iterator vit; - vit = m_keyedChanges.find(a_change->instanceHandle); - if (vit != m_keyedChanges.end()) + vit = keyed_changes_.find(a_change->instanceHandle); + if (vit != keyed_changes_.end()) { *vit_out = vit; return true; } - if ((int)m_keyedChanges.size() < m_resourceLimitsQos.max_instances) + if ((int)keyed_changes_.size() < m_resourceLimitsQos.max_instances) { - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; + *vit_out = keyed_changes_.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; return true; } else { - for (vit = m_keyedChanges.begin(); vit!= m_keyedChanges.end(); ++vit) + for (vit = keyed_changes_.begin(); vit!= keyed_changes_.end(); ++vit) { - if (vit->second.cache_changes_.size() == 0) + if (vit->second.cache_changes.size() == 0) { - m_keyedChanges.erase(vit); - *vit_out = m_keyedChanges.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; + keyed_changes_.erase(vit); + *vit_out = keyed_changes_.insert(std::make_pair(a_change->instanceHandle, KeyedChanges())).first; return true; } } @@ -534,13 +534,13 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change) return false; } - for (auto chit = vit->second.cache_changes_.begin(); chit != vit->second.cache_changes_.end(); ++chit) + for (auto chit = vit->second.cache_changes.begin(); chit != vit->second.cache_changes.end(); ++chit) { if ((*chit)->sequenceNumber == change->sequenceNumber && (*chit)->writerGUID == change->writerGUID) { if (remove_change(change)) { - vit->second.cache_changes_.erase(chit); + vit->second.cache_changes.erase(chit); m_isHistoryFull = false; return true; } @@ -551,7 +551,9 @@ bool SubscriberHistory::remove_change_sub(CacheChange_t* change) return false; } -bool SubscriberHistory::set_next_deadline(InstanceHandle_t handle, std::chrono::steady_clock::time_point next_deadline_us) +bool SubscriberHistory::set_next_deadline( + const InstanceHandle_t& handle, + const std::chrono::steady_clock::time_point& next_deadline_us) { if (mp_reader == nullptr || mp_mutex == nullptr) { @@ -567,12 +569,12 @@ bool SubscriberHistory::set_next_deadline(InstanceHandle_t handle, std::chrono:: } else if (mp_subImpl->getAttributes().topic.getTopicKind() == WITH_KEY) { - if (m_keyedChanges.find(handle) == m_keyedChanges.end()) + if (keyed_changes_.find(handle) == keyed_changes_.end()) { return false; } - m_keyedChanges[handle].next_deadline_us_ = next_deadline_us; + keyed_changes_[handle].next_deadline_us = next_deadline_us; return true; } @@ -595,13 +597,13 @@ bool SubscriberHistory::get_next_deadline(InstanceHandle_t &handle, std::chrono: } else if (mp_subImpl->getAttributes().topic.getTopicKind() == WITH_KEY) { - auto min = std::min_element(m_keyedChanges.begin(), - m_keyedChanges.end(), + auto min = std::min_element(keyed_changes_.begin(), + keyed_changes_.end(), []( const std::pair &lhs, - const std::pair &rhs){ return lhs.second.next_deadline_us_ < rhs.second.next_deadline_us_;}); + const std::pair &rhs){ return lhs.second.next_deadline_us < rhs.second.next_deadline_us;}); handle = min->first; - next_deadline_us = min->second.next_deadline_us_; + next_deadline_us = min->second.next_deadline_us; return true; } From aa7764d2f9757263c0c2c2eec27edbc96a433796 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Tue, 26 Mar 2019 15:20:59 +0100 Subject: [PATCH 38/54] Refs #4993 Passing deadline missed status as const and merging OfferedDeadlineMissedStatus and RequestedDeadlineMissed status into a single structure --- .../deadlinepayloadPublisher.cxx | 2 +- .../deadlinepayloadPublisher.h | 2 +- .../deadlinepayloadSubscriber.cxx | 2 +- .../deadlinepayloadSubscriber.h | 2 +- include/fastrtps/publisher/Publisher.h | 2 +- .../fastrtps/publisher/PublisherListener.h | 4 +- ...eMissedStatus.h => DeadlineMissedStatus.h} | 22 +++++--- .../qos/RequestedDeadlineMissedStatus.h | 55 ------------------- include/fastrtps/subscriber/Subscriber.h | 2 +- .../fastrtps/subscriber/SubscriberListener.h | 4 +- src/cpp/publisher/PublisherImpl.h | 2 +- src/cpp/subscriber/SubscriberImpl.h | 2 +- 12 files changed, 25 insertions(+), 76 deletions(-) rename include/fastrtps/qos/{OfferedDeadlineMissedStatus.h => DeadlineMissedStatus.h} (75%) delete mode 100644 include/fastrtps/qos/RequestedDeadlineMissedStatus.h diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx index 85a98e06e66..83bdbe9de03 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx @@ -86,7 +86,7 @@ void deadlinepayloadPublisher::PubListener::onPublicationMatched(Publisher* /*pu void deadlinepayloadPublisher::PubListener::on_offered_deadline_missed( Publisher* pub, - OfferedDeadlineMissedStatus& status) + const OfferedDeadlineMissedStatus &status) { (void)pub; std::cout << "Deadline missed for instance: " << status.last_instance_handle << std::endl; diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h index 03acc3397ce..863639392fa 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h @@ -63,7 +63,7 @@ class deadlinepayloadPublisher eprosima::fastrtps::rtps::MatchingInfo& info) override; void on_offered_deadline_missed( eprosima::fastrtps::Publisher* pub, - eprosima::fastrtps::OfferedDeadlineMissedStatus& status) override; + const eprosima::fastrtps::OfferedDeadlineMissedStatus& status) override; int n_matched; } m_listener; diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx index 53b76d0f928..051919154dc 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.cxx @@ -97,7 +97,7 @@ void deadlinepayloadSubscriber::SubListener::onNewDataMessage(Subscriber* sub) void deadlinepayloadSubscriber::SubListener::on_requested_deadline_missed( Subscriber* sub, - RequestedDeadlineMissedStatus& status) + const RequestedDeadlineMissedStatus &status) { (void)sub; std::cout << "Deadline missed for instance: " << status.last_instance_handle << std::endl; diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.h b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.h index f4763ad5205..fb0a41f3025 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.h +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadSubscriber.h @@ -71,7 +71,7 @@ class deadlinepayloadSubscriber void onNewDataMessage(eprosima::fastrtps::Subscriber* sub) override; void on_requested_deadline_missed( eprosima::fastrtps::Subscriber* sub, - eprosima::fastrtps::RequestedDeadlineMissedStatus& status) override; + const eprosima::fastrtps::RequestedDeadlineMissedStatus& status) override; eprosima::fastrtps::SampleInfo_t m_info; int n_matched; int n_msg; diff --git a/include/fastrtps/publisher/Publisher.h b/include/fastrtps/publisher/Publisher.h index 2fede85c9c4..4317d26cff3 100644 --- a/include/fastrtps/publisher/Publisher.h +++ b/include/fastrtps/publisher/Publisher.h @@ -25,7 +25,7 @@ #include "../rtps/common/Guid.h" #include "../rtps/common/Time_t.h" #include "../attributes/PublisherAttributes.h" -#include "../qos/OfferedDeadlineMissedStatus.h" +#include "../qos/DeadlineMissedStatus.h" namespace eprosima { namespace fastrtps { diff --git a/include/fastrtps/publisher/PublisherListener.h b/include/fastrtps/publisher/PublisherListener.h index f87399c70c3..50d6df190eb 100644 --- a/include/fastrtps/publisher/PublisherListener.h +++ b/include/fastrtps/publisher/PublisherListener.h @@ -21,7 +21,7 @@ #include "../rtps/common/Types.h" #include "../rtps/common/MatchingInfo.h" -#include "../qos/OfferedDeadlineMissedStatus.h" +#include "../qos/DeadlineMissedStatus.h" namespace eprosima { namespace fastrtps { @@ -58,7 +58,7 @@ class RTPS_DllAPI PublisherListener */ virtual void on_offered_deadline_missed( Publisher* pub, - OfferedDeadlineMissedStatus& status) + const OfferedDeadlineMissedStatus& status) { (void)pub; (void)status; diff --git a/include/fastrtps/qos/OfferedDeadlineMissedStatus.h b/include/fastrtps/qos/DeadlineMissedStatus.h similarity index 75% rename from include/fastrtps/qos/OfferedDeadlineMissedStatus.h rename to include/fastrtps/qos/DeadlineMissedStatus.h index 9a57f695285..a17b0ed1eb6 100644 --- a/include/fastrtps/qos/OfferedDeadlineMissedStatus.h +++ b/include/fastrtps/qos/DeadlineMissedStatus.h @@ -1,4 +1,4 @@ -// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima). // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,30 +13,30 @@ // limitations under the License. /** - * @file OfferedDeadlineMissedStatus.h + * @file DeadlineMissedStatus.h */ -#ifndef _OFFERED_DEADLINE_MISSED_STATUS_H_ -#define _OFFERED_DEADLINE_MISSED_STATUS_H_ +#ifndef _DEADLINE_MISSED_STATUS_H_ +#define _DEADLINE_MISSED_STATUS_H_ #include namespace eprosima { namespace fastrtps { -//! @brief A struct storing the status of the offered deadline +//! @brief A struct storing the deadline status //! @ingroup DEADLINE_MODULE -struct OfferedDeadlineMissedStatus +struct DeadlineMissedStatus { //! @brief Constructor - OfferedDeadlineMissedStatus() + DeadlineMissedStatus() : total_count() , total_count_change() , last_instance_handle() {} //! @brief Destructor - ~OfferedDeadlineMissedStatus() + ~DeadlineMissedStatus() {} //! @brief Total cumulative number of offered deadline periods epased during which a writer failed to provide data @@ -49,7 +49,11 @@ struct OfferedDeadlineMissedStatus //! @brief Handle to the last instance missing the deadline rtps::InstanceHandle_t last_instance_handle; }; + +typedef DeadlineMissedStatus OfferedDeadlineMissedStatus; +typedef DeadlineMissedStatus RequestedDeadlineMissedStatus; + } //end of namespace } //end of namespace eprosima -#endif /* _OFFERED_DEADLINE_MISSED_STATUS_H_ */ +#endif /* _DEADLINE_MISSED_STATUS_H_ */ diff --git a/include/fastrtps/qos/RequestedDeadlineMissedStatus.h b/include/fastrtps/qos/RequestedDeadlineMissedStatus.h deleted file mode 100644 index daacef471c9..00000000000 --- a/include/fastrtps/qos/RequestedDeadlineMissedStatus.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @file RequestedDeadlineMissedStatus.h -*/ - -#ifndef _REQUESTED_DEADLINE_MISSED_STATUS_H_ -#define _REQUESTED_DEADLINE_MISSED_STATUS_H_ - -#include - -namespace eprosima { -namespace fastrtps { - -//! @brief A struct storing the status of the requested deadline -//! @ingroup DEADLINE_MODULE -struct RequestedDeadlineMissedStatus -{ - //! @brief Constructor - RequestedDeadlineMissedStatus() - : total_count() - , total_count_change() - , last_instance_handle() - {} - - //! @brief Destructor - ~RequestedDeadlineMissedStatus() - {} - - //! @brief Total cumulative number of missed deadlines detected for any instance - //! @details Missed deadlines accumulate, that is, each deadline period the total_count will be incremented by 1 for each instance for which data was not received - uint32_t total_count; - - //! @brief The change in total_count since the last time the listener was called or the status was read - uint32_t total_count_change; - - //! @brief Handle to the last instance missing the deadline - rtps::InstanceHandle_t last_instance_handle; -}; -} //end of namespace -} //end of namespace eprosima - -#endif /* _REQUESTED_DEADLINE_MISSED_STATUS_H_ */ diff --git a/include/fastrtps/subscriber/Subscriber.h b/include/fastrtps/subscriber/Subscriber.h index d161287a3b4..4545f18c9fa 100644 --- a/include/fastrtps/subscriber/Subscriber.h +++ b/include/fastrtps/subscriber/Subscriber.h @@ -22,7 +22,7 @@ #include "../rtps/common/Guid.h" #include "../attributes/SubscriberAttributes.h" -#include "../qos/RequestedDeadlineMissedStatus.h" +#include "../qos/DeadlineMissedStatus.h" namespace eprosima { namespace fastrtps { diff --git a/include/fastrtps/subscriber/SubscriberListener.h b/include/fastrtps/subscriber/SubscriberListener.h index c53fe59369a..24187049bed 100644 --- a/include/fastrtps/subscriber/SubscriberListener.h +++ b/include/fastrtps/subscriber/SubscriberListener.h @@ -20,7 +20,7 @@ #define SUBLISTENER_H_ #include "../fastrtps_dll.h" -#include "../qos/RequestedDeadlineMissedStatus.h" +#include "../qos/DeadlineMissedStatus.h" namespace eprosima { namespace fastrtps { @@ -66,7 +66,7 @@ class RTPS_DllAPI SubscriberListener */ virtual void on_requested_deadline_missed( Subscriber* /*sub*/, - RequestedDeadlineMissedStatus& /*status*/) + const RequestedDeadlineMissedStatus& /*status*/) {} }; diff --git a/src/cpp/publisher/PublisherImpl.h b/src/cpp/publisher/PublisherImpl.h index f3431bce302..2be3bbe6196 100644 --- a/src/cpp/publisher/PublisherImpl.h +++ b/src/cpp/publisher/PublisherImpl.h @@ -31,7 +31,7 @@ #include #include -#include +#include namespace eprosima { namespace fastrtps{ diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index f481fd4bcea..59168c9fa49 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include namespace eprosima { namespace fastrtps { From 1a957d0cf943fe74aa58bf239f1331ecd53f5612 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Tue, 26 Mar 2019 15:41:43 +0100 Subject: [PATCH 39/54] Refs #4993 Moving KeyedChanges to a separate file so that publisher and subscriber can share it --- include/fastrtps/KeyedChanges.h | 63 +++++++++++++++++++ include/fastrtps/publisher/PublisherHistory.h | 34 +--------- include/fastrtps/rtps/common/Time_t.h | 2 +- .../fastrtps/rtps/resources/DeadlineTimer.h | 4 +- .../fastrtps/subscriber/SubscriberHistory.h | 31 +-------- src/cpp/rtps/resources/DeadlineTimer.cpp | 6 +- 6 files changed, 71 insertions(+), 69 deletions(-) create mode 100644 include/fastrtps/KeyedChanges.h diff --git a/include/fastrtps/KeyedChanges.h b/include/fastrtps/KeyedChanges.h new file mode 100644 index 00000000000..7910ce8ede7 --- /dev/null +++ b/include/fastrtps/KeyedChanges.h @@ -0,0 +1,63 @@ +// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * @file KeyedChanges.h + * + */ + +#ifndef KEYEDCHANGES_H_ +#define KEYEDCHANGES_H_ + +#include "rtps/common/CacheChange.h" +#include + +namespace eprosima{ +namespace fastrtps{ + +/** + * @brief A struct storing a vector of cache changes and the next deadline in the group + * @ingroup FASTRTPS_MODULE + */ +struct KeyedChanges +{ + //! Default constructor + KeyedChanges() + : cache_changes() + , next_deadline_us() + { + } + + //! Copy constructor + KeyedChanges(const KeyedChanges& other) + : cache_changes(other.cache_changes) + , next_deadline_us(other.next_deadline_us) + { + } + + //! Destructor + ~KeyedChanges() + { + } + + //! A vector of cache changes + std::vector cache_changes; + //! The time when the group will miss the deadline + std::chrono::steady_clock::time_point next_deadline_us; +}; + +} /* namespace */ +} /* namespace eprosima */ + +#endif /* KEYEDCHANGES_H_ */ diff --git a/include/fastrtps/publisher/PublisherHistory.h b/include/fastrtps/publisher/PublisherHistory.h index 9309c2250a6..e20ae3d3a6f 100644 --- a/include/fastrtps/publisher/PublisherHistory.h +++ b/include/fastrtps/publisher/PublisherHistory.h @@ -25,8 +25,7 @@ #include "../rtps/history/WriterHistory.h" #include "../qos/QosPolicies.h" - - +#include "../KeyedChanges.h" namespace eprosima { namespace fastrtps { @@ -113,37 +112,6 @@ class PublisherHistory:public rtps::WriterHistory private: - /** - * @brief A struct storing a vector of cache changes and the next deadline in the group - * @ingroup FASTRTPS_MODULE - */ - struct KeyedChanges - { - //! Default constructor - KeyedChanges() - : cache_changes() - , next_deadline_us() - { - } - - //! Copy constructor - KeyedChanges(const KeyedChanges& other) - : cache_changes(other.cache_changes) - , next_deadline_us(other.next_deadline_us) - { - } - - //! Destructor - ~KeyedChanges() - { - } - - //! A vector of cache changes - std::vector cache_changes; - //! The time when the group will miss the deadline - std::chrono::steady_clock::time_point next_deadline_us; - }; - typedef std::map t_m_Inst_Caches; //!Map where keys are instance handles and values are vectors of cache changes associated diff --git a/include/fastrtps/rtps/common/Time_t.h b/include/fastrtps/rtps/common/Time_t.h index 6e56edf058f..187db983208 100644 --- a/include/fastrtps/rtps/common/Time_t.h +++ b/include/fastrtps/rtps/common/Time_t.h @@ -61,7 +61,7 @@ struct RTPS_DllAPI Time_t /** * Returns stored time as nanoseconds */ - inline int64_t to_ns() + inline int64_t to_ns() const { int64_t nano = seconds * 1000000000ULL; nano += (fraction * 1000000000ULL) / 4294967296ULL; // 1 fraction = 1/(2^32) seconds diff --git a/include/fastrtps/rtps/resources/DeadlineTimer.h b/include/fastrtps/rtps/resources/DeadlineTimer.h index 0302b0438b9..aab4da7bfa3 100644 --- a/include/fastrtps/rtps/resources/DeadlineTimer.h +++ b/include/fastrtps/rtps/resources/DeadlineTimer.h @@ -43,8 +43,8 @@ class DeadlineTimer : public TimedEvent * @param event_thread starting thread for identification. */ DeadlineTimer( - std::function callback, - Duration_t period, + const std::function& callback, + const Duration_t& period, asio::io_service &service, const std::thread& event_thread); diff --git a/include/fastrtps/subscriber/SubscriberHistory.h b/include/fastrtps/subscriber/SubscriberHistory.h index 0ecaface293..3f2b2770fa2 100644 --- a/include/fastrtps/subscriber/SubscriberHistory.h +++ b/include/fastrtps/subscriber/SubscriberHistory.h @@ -24,6 +24,7 @@ #include #include "../rtps/history/ReaderHistory.h" #include "../qos/QosPolicies.h" +#include "../KeyedChanges.h" #include "SampleInfo.h" namespace eprosima { @@ -135,36 +136,6 @@ class SubscriberHistory: public rtps::ReaderHistory private: - /** - * @brief A struct storing a vector of cache changes and the next deadline that will happen in the group - * @ingroup FASTRTPS_MODULE - */ - struct KeyedChanges - { - //! Default constructor - KeyedChanges() - : cache_changes() - , next_deadline_us() - {} - - //! Copy constructor - KeyedChanges(const KeyedChanges& other) - : cache_changes(other.cache_changes) - , next_deadline_us(other.next_deadline_us) - { - } - - //! Destructor - ~KeyedChanges() - { - } - - //! A vector of cache changes - std::vector cache_changes; - //! The time point when the next deadline will occur - std::chrono::steady_clock::time_point next_deadline_us; - }; - typedef std::map t_m_Inst_Caches; //!Number of unread CacheChange_t. diff --git a/src/cpp/rtps/resources/DeadlineTimer.cpp b/src/cpp/rtps/resources/DeadlineTimer.cpp index c027e7a31e9..33bfdc37e5f 100644 --- a/src/cpp/rtps/resources/DeadlineTimer.cpp +++ b/src/cpp/rtps/resources/DeadlineTimer.cpp @@ -25,10 +25,10 @@ namespace fastrtps{ namespace rtps { DeadlineTimer::DeadlineTimer( - std::function callback, - Duration_t period, + const std::function& callback, + const Duration_t& period, asio::io_service &service, - const std::thread &event_thread) + const std::thread& event_thread) : TimedEvent(service, event_thread, period.to_ns() * 1e-6) , callback_(callback) { From cd6293866f75859da77a55e68f7a2455699687d1 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Tue, 26 Mar 2019 15:53:43 +0100 Subject: [PATCH 40/54] Refs #4993 Moving DeadlineTimer new directory src/cpp/timedevent --- include/fastrtps/rtps/{resources => timedevent}/DeadlineTimer.h | 2 +- src/cpp/CMakeLists.txt | 2 +- src/cpp/publisher/PublisherImpl.cpp | 2 +- src/cpp/publisher/PublisherImpl.h | 2 +- src/cpp/rtps/{resources => timedevent}/DeadlineTimer.cpp | 2 +- src/cpp/subscriber/SubscriberImpl.h | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename include/fastrtps/rtps/{resources => timedevent}/DeadlineTimer.h (98%) rename src/cpp/rtps/{resources => timedevent}/DeadlineTimer.cpp (96%) diff --git a/include/fastrtps/rtps/resources/DeadlineTimer.h b/include/fastrtps/rtps/timedevent/DeadlineTimer.h similarity index 98% rename from include/fastrtps/rtps/resources/DeadlineTimer.h rename to include/fastrtps/rtps/timedevent/DeadlineTimer.h index aab4da7bfa3..c587e8225d5 100644 --- a/include/fastrtps/rtps/resources/DeadlineTimer.h +++ b/include/fastrtps/rtps/timedevent/DeadlineTimer.h @@ -21,7 +21,7 @@ #define DeadlineTimer_H_ #ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC -#include "TimedEvent.h" +#include "../resources/TimedEvent.h" #include diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index 65e893bead2..5d06281b2eb 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -31,7 +31,7 @@ set(${PROJECT_NAME}_source_files rtps/resources/TimedEventImpl.cpp rtps/resources/AsyncWriterThread.cpp rtps/resources/AsyncInterestTree.cpp - rtps/resources/DeadlineTimer.cpp + rtps/timedevent/DeadlineTimer.cpp rtps/writer/RTPSWriter.cpp rtps/writer/StatefulWriter.cpp rtps/writer/ReaderProxy.cpp diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index ed0ffe5d6c3..f650f95036f 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include diff --git a/src/cpp/publisher/PublisherImpl.h b/src/cpp/publisher/PublisherImpl.h index 2be3bbe6196..38fb3c2c717 100644 --- a/src/cpp/publisher/PublisherImpl.h +++ b/src/cpp/publisher/PublisherImpl.h @@ -30,7 +30,7 @@ #include #include -#include +#include #include namespace eprosima { diff --git a/src/cpp/rtps/resources/DeadlineTimer.cpp b/src/cpp/rtps/timedevent/DeadlineTimer.cpp similarity index 96% rename from src/cpp/rtps/resources/DeadlineTimer.cpp rename to src/cpp/rtps/timedevent/DeadlineTimer.cpp index 33bfdc37e5f..246610a24f0 100644 --- a/src/cpp/rtps/resources/DeadlineTimer.cpp +++ b/src/cpp/rtps/timedevent/DeadlineTimer.cpp @@ -17,7 +17,7 @@ * */ -#include +#include #include namespace eprosima { diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index 59168c9fa49..7c5db0b5155 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include namespace eprosima { From dd337739b93ad9f0b097ba50afef47b352db3bf0 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 27 Mar 2019 07:33:29 +0100 Subject: [PATCH 41/54] Refs #4993 Fixing compiler errors in blackbox tests --- test/blackbox/PubSubReader.hpp | 2 +- test/blackbox/PubSubWriter.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/blackbox/PubSubReader.hpp b/test/blackbox/PubSubReader.hpp index 5a912a0bc0e..c7b6902f945 100644 --- a/test/blackbox/PubSubReader.hpp +++ b/test/blackbox/PubSubReader.hpp @@ -144,7 +144,7 @@ class PubSubReader void on_requested_deadline_missed( eprosima::fastrtps::Subscriber* sub, - eprosima::fastrtps::RequestedDeadlineMissedStatus& status) override + const eprosima::fastrtps::RequestedDeadlineMissedStatus& status) override { (void)sub; diff --git a/test/blackbox/PubSubWriter.hpp b/test/blackbox/PubSubWriter.hpp index 272a2e26390..805b4eef490 100644 --- a/test/blackbox/PubSubWriter.hpp +++ b/test/blackbox/PubSubWriter.hpp @@ -156,7 +156,7 @@ class PubSubWriter void on_offered_deadline_missed( eprosima::fastrtps::Publisher* pub, - eprosima::fastrtps::OfferedDeadlineMissedStatus& status) override + const eprosima::fastrtps::OfferedDeadlineMissedStatus& status) override { (void)pub; times_deadline_missed_ = status.total_count; From 0b39cf1634eb6e0a90bb1335b705e9a95671c082 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 27 Mar 2019 10:06:47 +0100 Subject: [PATCH 42/54] Refs #4993 Removing unnecessary getter in Participant --- include/fastrtps/participant/Participant.h | 5 ---- src/cpp/participant/Participant.cpp | 31 ++++++++++++---------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/include/fastrtps/participant/Participant.h b/include/fastrtps/participant/Participant.h index 3a779f8b1b2..32575997eeb 100644 --- a/include/fastrtps/participant/Participant.h +++ b/include/fastrtps/participant/Participant.h @@ -88,11 +88,6 @@ class RTPS_DllAPI Participant bool get_remote_reader_info(const rtps::GUID_t& readerGuid, rtps::ReaderProxyData& returnedInfo); - /** - * Get the resource event for this participant - */ - rtps::ResourceEvent& get_resource_event() const; - }; } diff --git a/src/cpp/participant/Participant.cpp b/src/cpp/participant/Participant.cpp index f6584c54321..a67cbeb082a 100644 --- a/src/cpp/participant/Participant.cpp +++ b/src/cpp/participant/Participant.cpp @@ -24,13 +24,13 @@ using namespace eprosima::fastrtps; using namespace eprosima::fastrtps::rtps; -Participant::Participant(): - mp_impl(nullptr) - { - - } +Participant::Participant() + : mp_impl(nullptr) +{ +} -Participant::~Participant() { +Participant::~Participant() +{ // TODO Auto-generated destructor stub } @@ -44,27 +44,30 @@ const ParticipantAttributes& Participant::getAttributes() const return mp_impl->getAttributes(); } -bool Participant::newRemoteEndpointDiscovered(const GUID_t& partguid, uint16_t endpointId, +bool Participant::newRemoteEndpointDiscovered( + const GUID_t& partguid, + uint16_t endpointId, EndpointKind_t kind) { return mp_impl->newRemoteEndpointDiscovered(partguid, endpointId, kind); } -std::vector Participant::getParticipantNames() const { +std::vector Participant::getParticipantNames() const +{ return mp_impl->getParticipantNames(); } -bool Participant::get_remote_writer_info(const GUID_t& writerGuid, WriterProxyData& returnedInfo) +bool Participant::get_remote_writer_info( + const GUID_t& writerGuid, + WriterProxyData& returnedInfo) { return mp_impl->get_remote_writer_info(writerGuid, returnedInfo); } -bool Participant::get_remote_reader_info(const GUID_t& readerGuid, ReaderProxyData& returnedInfo) +bool Participant::get_remote_reader_info( + const GUID_t& readerGuid, + ReaderProxyData& returnedInfo) { return mp_impl->get_remote_reader_info(readerGuid, returnedInfo); } -ResourceEvent& Participant::get_resource_event() const -{ - return mp_impl->get_resource_event(); -} From e6f036bc4f5a0789175a246e6cae9e84008049e5 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 27 Mar 2019 15:15:16 +0100 Subject: [PATCH 43/54] Refs #4993 Fixing warnings --- .../DeadlineQoSExample/deadlinepayloadPublisher.cxx | 2 +- .../C++/DeadlineQoSExample/deadlinepayloadPublisher.h | 2 +- src/cpp/publisher/PublisherImpl.cpp | 2 +- src/cpp/subscriber/SubscriberImpl.cpp | 2 +- test/blackbox/BlackboxTestsDeadlineQos.cpp | 8 ++++---- test/blackbox/PubSubReader.hpp | 10 +++++----- test/blackbox/PubSubWriter.hpp | 8 ++++---- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx index 83bdbe9de03..1b93e294851 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.cxx @@ -92,7 +92,7 @@ void deadlinepayloadPublisher::PubListener::on_offered_deadline_missed( std::cout << "Deadline missed for instance: " << status.last_instance_handle << std::endl; } -void deadlinepayloadPublisher::run(double sleep_ms, int samples) +void deadlinepayloadPublisher::run(uint32_t sleep_ms, int samples) { while(m_listener.n_matched == 0) { diff --git a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h index 863639392fa..b4928fbf646 100644 --- a/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h +++ b/examples/C++/DeadlineQoSExample/deadlinepayloadPublisher.h @@ -46,7 +46,7 @@ class deadlinepayloadPublisher * @param sleep_ms A time period to sleep for before sending the new sample * @param samples The number of samples per instance to send. If set to 0 sends sample indefinitely */ - void run(double sleep_ms, int samples); + void run(uint32_t sleep_ms, int samples); private: diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index f650f95036f..44a7a45ea61 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -374,7 +374,7 @@ void PublisherImpl::timer_reschedule() auto interval_ms = duration_cast(next_deadline_us - steady_clock::now()); deadline_timer_.cancel_timer(); - deadline_timer_.update_interval_millisec(interval_ms.count()); + deadline_timer_.update_interval_millisec((double)interval_ms.count()); deadline_timer_.restart_timer(); } diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index 81f3aa0a680..64cacaedc1b 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -266,7 +266,7 @@ void SubscriberImpl::timer_reschedule() auto interval_ms = duration_cast(next_deadline_us - steady_clock::now()); deadline_timer_.cancel_timer(); - deadline_timer_.update_interval_millisec(interval_ms.count()); + deadline_timer_.update_interval_millisec((double)interval_ms.count()); deadline_timer_.restart_timer(); } diff --git a/test/blackbox/BlackboxTestsDeadlineQos.cpp b/test/blackbox/BlackboxTestsDeadlineQos.cpp index 48382d19844..1c6dc462961 100644 --- a/test/blackbox/BlackboxTestsDeadlineQos.cpp +++ b/test/blackbox/BlackboxTestsDeadlineQos.cpp @@ -67,8 +67,8 @@ BLACKBOXTEST(DeadlineQos, NoKeyTopicLongDeadline) std::this_thread::sleep_for(std::chrono::milliseconds(writer_sleep_ms)); } - EXPECT_EQ(writer.missed_deadlines(), 0); - EXPECT_EQ(reader.missed_deadlines(), 0); + EXPECT_EQ(writer.missed_deadlines(), 0u); + EXPECT_EQ(reader.missed_deadlines(), 0u); } BLACKBOXTEST(DeadlineQos, NoKeyTopicShortDeadline) @@ -163,8 +163,8 @@ BLACKBOXTEST(DeadlineQos, KeyedTopicLongDeadline) std::this_thread::sleep_for(std::chrono::milliseconds(writer_sleep_ms)); } - EXPECT_EQ(writer.missed_deadlines(), 0); - EXPECT_EQ(reader.missed_deadlines(), 0); + EXPECT_EQ(writer.missed_deadlines(), 0u); + EXPECT_EQ(reader.missed_deadlines(), 0u); } BLACKBOXTEST(DeadlineQos, KeyedTopicShortDeadline) diff --git a/test/blackbox/PubSubReader.hpp b/test/blackbox/PubSubReader.hpp index c7b6902f945..c07d29e15c5 100644 --- a/test/blackbox/PubSubReader.hpp +++ b/test/blackbox/PubSubReader.hpp @@ -114,7 +114,7 @@ class PubSubReader ~Listener(){} - void onNewDataMessage(eprosima::fastrtps::Subscriber *sub) + void onNewDataMessage(eprosima::fastrtps::Subscriber *sub) override { ASSERT_NE(sub, nullptr); @@ -128,7 +128,7 @@ class PubSubReader } } - void onSubscriptionMatched(eprosima::fastrtps::Subscriber* /*sub*/, eprosima::fastrtps::rtps::MatchingInfo& info) + void onSubscriptionMatched(eprosima::fastrtps::Subscriber* /*sub*/, eprosima::fastrtps::rtps::MatchingInfo& info) override { if (info.status == eprosima::fastrtps::rtps::MATCHED_MATCHING) { @@ -151,7 +151,7 @@ class PubSubReader times_deadline_missed_ = status.total_count; } - int missed_deadlines() const + unsigned int missed_deadlines() const { return times_deadline_missed_; } @@ -162,7 +162,7 @@ class PubSubReader PubSubReader& reader_; - int times_deadline_missed_; + unsigned int times_deadline_missed_; } listener_; @@ -673,7 +673,7 @@ class PubSubReader return matched_ > 0; } - int missed_deadlines() const + unsigned int missed_deadlines() const { return listener_.missed_deadlines(); } diff --git a/test/blackbox/PubSubWriter.hpp b/test/blackbox/PubSubWriter.hpp index 805b4eef490..baf718df8ab 100644 --- a/test/blackbox/PubSubWriter.hpp +++ b/test/blackbox/PubSubWriter.hpp @@ -140,7 +140,7 @@ class PubSubWriter ~Listener(){}; - void onPublicationMatched(eprosima::fastrtps::Publisher* /*pub*/, eprosima::fastrtps::rtps::MatchingInfo &info) + void onPublicationMatched(eprosima::fastrtps::Publisher* /*pub*/, eprosima::fastrtps::rtps::MatchingInfo &info) override { if (info.status == eprosima::fastrtps::rtps::MATCHED_MATCHING) { @@ -162,7 +162,7 @@ class PubSubWriter times_deadline_missed_ = status.total_count; } - int missed_deadlines() const + unsigned int missed_deadlines() const { return times_deadline_missed_; } @@ -173,7 +173,7 @@ class PubSubWriter PubSubWriter &writer_; - int times_deadline_missed_; + unsigned int times_deadline_missed_; } listener_; @@ -706,7 +706,7 @@ class PubSubWriter return matched_ > 0; } - int missed_deadlines() const + unsigned int missed_deadlines() const { return listener_.missed_deadlines(); } From 539996924a0969b133cf4ebc9addbb50e0703d14 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 27 Mar 2019 15:53:48 +0100 Subject: [PATCH 44/54] Refs #4993 Moved KeyedChanges to a common/ subdirectory --- include/fastrtps/{ => common}/KeyedChanges.h | 2 +- include/fastrtps/publisher/PublisherHistory.h | 2 +- include/fastrtps/subscriber/SubscriberHistory.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename include/fastrtps/{ => common}/KeyedChanges.h (97%) diff --git a/include/fastrtps/KeyedChanges.h b/include/fastrtps/common/KeyedChanges.h similarity index 97% rename from include/fastrtps/KeyedChanges.h rename to include/fastrtps/common/KeyedChanges.h index 7910ce8ede7..72489c984d4 100644 --- a/include/fastrtps/KeyedChanges.h +++ b/include/fastrtps/common/KeyedChanges.h @@ -20,7 +20,7 @@ #ifndef KEYEDCHANGES_H_ #define KEYEDCHANGES_H_ -#include "rtps/common/CacheChange.h" +#include "../rtps/common/CacheChange.h" #include namespace eprosima{ diff --git a/include/fastrtps/publisher/PublisherHistory.h b/include/fastrtps/publisher/PublisherHistory.h index e20ae3d3a6f..dd8f6d1976b 100644 --- a/include/fastrtps/publisher/PublisherHistory.h +++ b/include/fastrtps/publisher/PublisherHistory.h @@ -25,7 +25,7 @@ #include "../rtps/history/WriterHistory.h" #include "../qos/QosPolicies.h" -#include "../KeyedChanges.h" +#include "../common/KeyedChanges.h" namespace eprosima { namespace fastrtps { diff --git a/include/fastrtps/subscriber/SubscriberHistory.h b/include/fastrtps/subscriber/SubscriberHistory.h index 3f2b2770fa2..c1f07ea901f 100644 --- a/include/fastrtps/subscriber/SubscriberHistory.h +++ b/include/fastrtps/subscriber/SubscriberHistory.h @@ -24,7 +24,7 @@ #include #include "../rtps/history/ReaderHistory.h" #include "../qos/QosPolicies.h" -#include "../KeyedChanges.h" +#include "../common/KeyedChanges.h" #include "SampleInfo.h" namespace eprosima { From 094354acc43ba9c0f7dc1e81c6d5d52422231f9b Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Thu, 28 Mar 2019 10:26:45 +0100 Subject: [PATCH 45/54] Refs #4993 Removing unnecessary forward declaration --- include/fastrtps/participant/Participant.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/fastrtps/participant/Participant.h b/include/fastrtps/participant/Participant.h index 32575997eeb..c763e309ad9 100644 --- a/include/fastrtps/participant/Participant.h +++ b/include/fastrtps/participant/Participant.h @@ -35,7 +35,6 @@ namespace rtps { class WriterProxyData; class ReaderProxyData; - class ResourceEvent; } /** From b08572d108b44f2e3790a041df7ed814f4a558c5 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 10 Apr 2019 15:58:18 +0200 Subject: [PATCH 46/54] Refs #4993 Changes to XML parser --- src/cpp/xmlparser/XMLElementParser.cpp | 42 +++++++++++++++++--------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/cpp/xmlparser/XMLElementParser.cpp b/src/cpp/xmlparser/XMLElementParser.cpp index fbdf1ef9887..5dfa3e6d5e1 100644 --- a/src/cpp/xmlparser/XMLElementParser.cpp +++ b/src/cpp/xmlparser/XMLElementParser.cpp @@ -681,16 +681,23 @@ XMLP_ret XMLParser::getXMLWriterQosPolicies(tinyxml2::XMLElement *elem, WriterQo if (XMLP_ret::XML_OK != getXMLPublishModeQos(p_aux0, qos.m_publishMode, ident)) return XMLP_ret::XML_ERROR; } - else if (strcmp(name, DURABILITY_SRV) == 0 || strcmp(name, DEADLINE) == 0 || - strcmp(name, LATENCY_BUDGET) == 0 || strcmp(name, LIFESPAN) == 0 || - strcmp(name, USER_DATA) == 0 || strcmp(name, TIME_FILTER) == 0 || - strcmp(name, OWNERSHIP) == 0 || strcmp(name, OWNERSHIP_STRENGTH) == 0 || - strcmp(name, DEST_ORDER) == 0 || strcmp(name, PRESENTATION) == 0 || - strcmp(name, TOPIC_DATA) == 0 || strcmp(name, GROUP_DATA) == 0) + else if (strcmp(name, DEADLINE) == 0) + { + // deadline + if (XMLP_ret::XML_OK != getXMLDeadlineQos(p_aux0, qos.m_deadline, ident)) + { + return XMLP_ret::XML_ERROR; + } + } + else if (strcmp(name, DURABILITY_SRV) == 0 || strcmp(name, LATENCY_BUDGET) == 0 || + strcmp(name, LIFESPAN) == 0 || strcmp(name, USER_DATA) == 0 || + strcmp(name, TIME_FILTER) == 0 || strcmp(name, OWNERSHIP) == 0 || + strcmp(name, OWNERSHIP_STRENGTH) == 0 || strcmp(name, DEST_ORDER) == 0 || + strcmp(name, PRESENTATION) == 0 || strcmp(name, TOPIC_DATA) == 0 || + strcmp(name, GROUP_DATA) == 0) { // TODO: Do not supported for now //if (nullptr != (p_aux = elem->FirstChildElement( DURABILITY_SRV))) getXMLDurabilityServiceQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( DEADLINE))) getXMLDeadlineQos(p_aux, ident); //if (nullptr != (p_aux = elem->FirstChildElement( LATENCY_BUDGET))) getXMLLatencyBudgetQos(p_aux, ident); //if (nullptr != (p_aux = elem->FirstChildElement( LIFESPAN))) getXMLLifespanQos(p_aux, ident); //if (nullptr != (p_aux = elem->FirstChildElement( USER_DATA))) getXMLUserDataQos(p_aux, ident); @@ -765,16 +772,23 @@ XMLP_ret XMLParser::getXMLReaderQosPolicies(tinyxml2::XMLElement *elem, ReaderQo if (XMLP_ret::XML_OK != getXMLPartitionQos(p_aux0, qos.m_partition, ident)) return XMLP_ret::XML_ERROR; } - else if (strcmp(name, DURABILITY_SRV) == 0 || strcmp(name, DEADLINE) == 0 || - strcmp(name, LATENCY_BUDGET) == 0 || strcmp(name, LIFESPAN) == 0 || - strcmp(name, USER_DATA) == 0 || strcmp(name, TIME_FILTER) == 0 || - strcmp(name, OWNERSHIP) == 0 || strcmp(name, OWNERSHIP_STRENGTH) == 0 || - strcmp(name, DEST_ORDER) == 0 || strcmp(name, PRESENTATION) == 0 || - strcmp(name, TOPIC_DATA) == 0 || strcmp(name, GROUP_DATA) == 0) + else if (strcmp(name, DEADLINE) == 0) + { + // deadline + if (XMLP_ret::XML_OK != getXMLDeadlineQos(p_aux0, qos.m_deadline, ident)) + { + return XMLP_ret::XML_ERROR; + } + } + else if (strcmp(name, DURABILITY_SRV) == 0 || strcmp(name, LATENCY_BUDGET) == 0 || + strcmp(name, LIFESPAN) == 0 || strcmp(name, USER_DATA) == 0 || + strcmp(name, TIME_FILTER) == 0 || strcmp(name, OWNERSHIP) == 0 || + strcmp(name, OWNERSHIP_STRENGTH) == 0 || strcmp(name, DEST_ORDER) == 0 || + strcmp(name, PRESENTATION) == 0 || strcmp(name, TOPIC_DATA) == 0 || + strcmp(name, GROUP_DATA) == 0) { // TODO: Do not supported for now //if (nullptr != (p_aux = elem->FirstChildElement( DURABILITY_SRV))) getXMLDurabilityServiceQos(p_aux, ident); - //if (nullptr != (p_aux = elem->FirstChildElement( DEADLINE))) getXMLDeadlineQos(p_aux, ident); //if (nullptr != (p_aux = elem->FirstChildElement( LATENCY_BUDGET))) getXMLLatencyBudgetQos(p_aux, ident); //if (nullptr != (p_aux = elem->FirstChildElement( LIFESPAN))) getXMLLifespanQos(p_aux, ident); //if (nullptr != (p_aux = elem->FirstChildElement( USER_DATA))) getXMLUserDataQos(p_aux, ident); From d4a21eceb9e4b560bf25f8156e78026c247f0510 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Wed, 10 Apr 2019 16:03:15 +0200 Subject: [PATCH 47/54] Refs #4993 Renaming DeadlineTimer -> TimedCallback so that class is shared with LifespanQoS --- .../{DeadlineTimer.h => TimedCallback.h} | 16 ++++++++-------- src/cpp/CMakeLists.txt | 2 +- src/cpp/publisher/PublisherImpl.cpp | 2 +- src/cpp/publisher/PublisherImpl.h | 4 ++-- .../{DeadlineTimer.cpp => TimedCallback.cpp} | 18 +++++++++--------- src/cpp/subscriber/SubscriberImpl.h | 4 ++-- 6 files changed, 23 insertions(+), 23 deletions(-) rename include/fastrtps/rtps/timedevent/{DeadlineTimer.h => TimedCallback.h} (85%) rename src/cpp/rtps/timedevent/{DeadlineTimer.cpp => TimedCallback.cpp} (74%) diff --git a/include/fastrtps/rtps/timedevent/DeadlineTimer.h b/include/fastrtps/rtps/timedevent/TimedCallback.h similarity index 85% rename from include/fastrtps/rtps/timedevent/DeadlineTimer.h rename to include/fastrtps/rtps/timedevent/TimedCallback.h index c587e8225d5..3907b3b68ee 100644 --- a/include/fastrtps/rtps/timedevent/DeadlineTimer.h +++ b/include/fastrtps/rtps/timedevent/TimedCallback.h @@ -1,4 +1,4 @@ -// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima). // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,12 +13,12 @@ // limitations under the License. /** - * @file DeadlineTimer.h + * @file TimedCallback.h * */ -#ifndef DeadlineTimer_H_ -#define DeadlineTimer_H_ +#ifndef TimedCallback_H_ +#define TimedCallback_H_ #ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC #include "../resources/TimedEvent.h" @@ -32,17 +32,17 @@ namespace rtps { /** A class that starts a timer and invokes a callback when the timer expires * @ingroup MANAGEMENT_MODULE */ -class DeadlineTimer : public TimedEvent +class TimedCallback : public TimedEvent { public: /** Constructor * @param callback A callback to invoke when the timer expires - * @param period Interval of the DeadlineTimer in milliseconds + * @param period Interval of the TimedCallback in milliseconds * @param service IO service to run the event * @param event_thread starting thread for identification. */ - DeadlineTimer( + TimedCallback( const std::function& callback, const Duration_t& period, asio::io_service &service, @@ -50,7 +50,7 @@ class DeadlineTimer : public TimedEvent /** Destructor */ - virtual ~DeadlineTimer(); + virtual ~TimedCallback(); /** Method invoked when the event occurs * @param code Code representing the status of the event diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index 5d06281b2eb..0c5c5d509a0 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -31,7 +31,7 @@ set(${PROJECT_NAME}_source_files rtps/resources/TimedEventImpl.cpp rtps/resources/AsyncWriterThread.cpp rtps/resources/AsyncInterestTree.cpp - rtps/timedevent/DeadlineTimer.cpp + rtps/timedevent/TimedCallback.cpp rtps/writer/RTPSWriter.cpp rtps/writer/StatefulWriter.cpp rtps/writer/ReaderProxy.cpp diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index 44a7a45ea61..18a34ff4e93 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -31,7 +31,7 @@ #include #include -#include +#include #include #include diff --git a/src/cpp/publisher/PublisherImpl.h b/src/cpp/publisher/PublisherImpl.h index 38fb3c2c717..6ac10e88497 100644 --- a/src/cpp/publisher/PublisherImpl.h +++ b/src/cpp/publisher/PublisherImpl.h @@ -30,7 +30,7 @@ #include #include -#include +#include #include namespace eprosima { @@ -165,7 +165,7 @@ class PublisherImpl uint32_t high_mark_for_frag_; //! A timer used to check for deadlines - DeadlineTimer deadline_timer_; + TimedCallback deadline_timer_; //! Deadline duration in microseconds std::chrono::duration> deadline_duration_us_; //! The current timer owner, i.e. the instance which started the timer diff --git a/src/cpp/rtps/timedevent/DeadlineTimer.cpp b/src/cpp/rtps/timedevent/TimedCallback.cpp similarity index 74% rename from src/cpp/rtps/timedevent/DeadlineTimer.cpp rename to src/cpp/rtps/timedevent/TimedCallback.cpp index 246610a24f0..362b5cfee8e 100644 --- a/src/cpp/rtps/timedevent/DeadlineTimer.cpp +++ b/src/cpp/rtps/timedevent/TimedCallback.cpp @@ -1,4 +1,4 @@ -// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima). // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,18 +13,18 @@ // limitations under the License. /** - * @file DeadlineTimer.cpp + * @file TimedCallback.cpp * */ -#include +#include #include namespace eprosima { namespace fastrtps{ namespace rtps { -DeadlineTimer::DeadlineTimer( +TimedCallback::TimedCallback( const std::function& callback, const Duration_t& period, asio::io_service &service, @@ -34,11 +34,11 @@ DeadlineTimer::DeadlineTimer( { } -DeadlineTimer::~DeadlineTimer() +TimedCallback::~TimedCallback() { } -void DeadlineTimer::event(EventCode code, const char *msg) +void TimedCallback::event(EventCode code, const char *msg) { // Unused in release mode. (void)msg; @@ -51,16 +51,16 @@ void DeadlineTimer::event(EventCode code, const char *msg) } else { - logWarning(DEADLINETIMER, "Event successfull but callback is nullptr"); + logWarning(TimedCallback, "Event successfull but callback is nullptr"); } } else if(code == EVENT_ABORT) { - logInfo(DEADLINETIMER, "Aborted"); + logInfo(TimedCallback, "Aborted"); } else { - logInfo(DEADLINETIMER, "Event message: " << msg); + logInfo(TimedCallback, "Event message: " << msg); } } diff --git a/src/cpp/subscriber/SubscriberImpl.h b/src/cpp/subscriber/SubscriberImpl.h index 7c5db0b5155..4429d4f3c6c 100644 --- a/src/cpp/subscriber/SubscriberImpl.h +++ b/src/cpp/subscriber/SubscriberImpl.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include namespace eprosima { @@ -162,7 +162,7 @@ class SubscriberImpl { rtps::RTPSParticipant* mp_rtpsParticipant; //! A timer used to check for deadlines - DeadlineTimer deadline_timer_; + TimedCallback deadline_timer_; //! Deadline duration in microseconds std::chrono::duration> deadline_duration_us_; //! The current timer owner, i.e. the instance which started the timer From a4e89c6ffcdab390c3fb687a592ae95843bebbd2 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Thu, 11 Apr 2019 16:40:15 +0200 Subject: [PATCH 48/54] Refs #4993 Fixing build and warnings --- src/cpp/publisher/PublisherHistory.cpp | 4 ++-- src/cpp/publisher/PublisherImpl.cpp | 6 +++--- src/cpp/subscriber/SubscriberHistory.cpp | 4 ++-- src/cpp/subscriber/SubscriberImpl.cpp | 8 ++++---- test/blackbox/utils/data_generators.cpp | 2 ++ 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index 06b5e7a9a8a..efab0fd64f9 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -282,7 +282,7 @@ bool PublisherHistory::set_next_deadline( logError(RTPS_HISTORY,"You need to create a Writer with this History before using it"); return false; } - std::lock_guard guard(*this->mp_mutex); + std::lock_guard guard(*this->mp_mutex); if (mp_pubImpl->getAttributes().topic.getTopicKind() == NO_KEY) { @@ -312,7 +312,7 @@ bool PublisherHistory::get_next_deadline( logError(RTPS_HISTORY,"You need to create a Writer with this History before using it"); return false; } - std::lock_guard guard(*this->mp_mutex); + std::lock_guard guard(*this->mp_mutex); if(mp_pubImpl->getAttributes().topic.getTopicKind() == WITH_KEY) { diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index 18a34ff4e93..f483e346bc5 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -363,7 +363,7 @@ void PublisherImpl::timer_reschedule() { assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); - std::unique_lock lock(*mp_writer->getMutex()); + std::unique_lock lock(mp_writer->getMutex()); steady_clock::time_point next_deadline_us; if (!m_history.get_next_deadline(timer_owner_, next_deadline_us)) @@ -382,7 +382,7 @@ void PublisherImpl::deadline_missed() { assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); - std::unique_lock lock(*mp_writer->getMutex()); + std::unique_lock lock(mp_writer->getMutex()); deadline_missed_status_.total_count++; deadline_missed_status_.total_count_change++; @@ -400,7 +400,7 @@ void PublisherImpl::deadline_missed() void PublisherImpl::get_offered_deadline_missed_status(OfferedDeadlineMissedStatus &status) { - std::unique_lock lock(*mp_writer->getMutex()); + std::unique_lock lock(mp_writer->getMutex()); status = deadline_missed_status_; deadline_missed_status_.total_count_change = 0; diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index afa5deca456..8a99a3eeac2 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -560,7 +560,7 @@ bool SubscriberHistory::set_next_deadline( logError(RTPS_HISTORY, "You need to create a Reader with this History before using it"); return false; } - std::lock_guard guard(*mp_mutex); + std::lock_guard guard(*mp_mutex); if (mp_subImpl->getAttributes().topic.getTopicKind() == NO_KEY) { @@ -588,7 +588,7 @@ bool SubscriberHistory::get_next_deadline(InstanceHandle_t &handle, std::chrono: logError(RTPS_HISTORY, "You need to create a Reader with this History before using it"); return false; } - std::lock_guard guard(*mp_mutex); + std::lock_guard guard(*mp_mutex); if (mp_subImpl->getAttributes().topic.getTopicKind() == NO_KEY) { diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index 64cacaedc1b..08456125abd 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -220,7 +220,7 @@ void SubscriberImpl::onNewCacheChangeAdded(const CacheChange_t* const change) { if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { - std::unique_lock lock(*mp_reader->getMutex()); + std::unique_lock lock(mp_reader->getMutex()); if (!m_history.set_next_deadline(change->instanceHandle, steady_clock::now() + duration_cast(deadline_duration_us_))) { @@ -255,7 +255,7 @@ void SubscriberImpl::timer_reschedule() { assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); - std::unique_lock lock(*mp_reader->getMutex()); + std::unique_lock lock(mp_reader->getMutex()); steady_clock::time_point next_deadline_us; if (!m_history.get_next_deadline(timer_owner_, next_deadline_us)) @@ -274,7 +274,7 @@ void SubscriberImpl::deadline_missed() { assert(m_att.qos.m_deadline.period != rtps::c_TimeInfinite); - std::unique_lock lock(*mp_reader->getMutex()); + std::unique_lock lock(mp_reader->getMutex()); deadline_missed_status_.total_count++; deadline_missed_status_.total_count_change++; @@ -293,7 +293,7 @@ void SubscriberImpl::deadline_missed() void SubscriberImpl::get_requested_deadline_missed_status(RequestedDeadlineMissedStatus& status) { - std::unique_lock lock(*mp_reader->getMutex()); + std::unique_lock lock(mp_reader->getMutex()); status = deadline_missed_status_; deadline_missed_status_.total_count_change = 0; diff --git a/test/blackbox/utils/data_generators.cpp b/test/blackbox/utils/data_generators.cpp index ee6bb701d45..bf099b8597a 100644 --- a/test/blackbox/utils/data_generators.cpp +++ b/test/blackbox/utils/data_generators.cpp @@ -47,6 +47,8 @@ std::list default_fixed_sized_data_generator(size_t max) ++index; return fs; }); + + return returnedValue; } std::list default_keyedhelloworld_data_generator(size_t max) From 9958ddd69947d2b1587677efd7b1af8511b0143e Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Fri, 12 Apr 2019 07:45:39 +0200 Subject: [PATCH 49/54] Refs #4993 Fixing deadline tests due to issue when resolving conflicts --- src/cpp/publisher/PublisherImpl.cpp | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index f483e346bc5..44638b94a26 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -204,24 +204,22 @@ bool PublisherImpl::create_new_change_with_params( return false; } - return true; - } - - if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) - { - if (!m_history.set_next_deadline(ch->instanceHandle, steady_clock::now() + duration_cast(deadline_duration_us_))) - { - logError(PUBLISHER, "Could not set the next deadline in the history"); - } - else + if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { - if (timer_owner_ == handle || timer_owner_ == InstanceHandle_t()) + if (!m_history.set_next_deadline(ch->instanceHandle, steady_clock::now() + duration_cast(deadline_duration_us_))) { - timer_reschedule(); + logError(PUBLISHER, "Could not set the next deadline in the history"); + } + else + { + if (timer_owner_ == handle || timer_owner_ == InstanceHandle_t()) + { + timer_reschedule(); + } } } + return true; } - return true; } return false; From e0be166b5ec9ac3fe39f3b8b776bd6d70076ab90 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Fri, 12 Apr 2019 10:54:25 +0200 Subject: [PATCH 50/54] Refs #4993 Fixing valgrind --- test/blackbox/types/KeyedHelloWorldType.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/blackbox/types/KeyedHelloWorldType.cpp b/test/blackbox/types/KeyedHelloWorldType.cpp index 85b4ff0ea23..e8a0fc613f6 100644 --- a/test/blackbox/types/KeyedHelloWorldType.cpp +++ b/test/blackbox/types/KeyedHelloWorldType.cpp @@ -32,7 +32,7 @@ KeyedHelloWorldType::KeyedHelloWorldType() { setName("KeyedHelloWorld"); m_typeSize = (uint32_t)KeyedHelloWorld::getMaxCdrSerializedSize() + 4 /*encapsulation*/; m_isGetKeyDefined = KeyedHelloWorld::isKeyDefined(); - m_keyBuffer = (unsigned char*)malloc(KeyedHelloWorld::getKeyMaxCdrSerializedSize()>16 ? KeyedHelloWorld::getKeyMaxCdrSerializedSize() : 16); + m_keyBuffer = (unsigned char*)calloc(KeyedHelloWorld::getKeyMaxCdrSerializedSize()>16 ? KeyedHelloWorld::getKeyMaxCdrSerializedSize() : 16, sizeof(unsigned char*)); } KeyedHelloWorldType::~KeyedHelloWorldType() { From 4a77ec1da5aa6e71a10f5dc37da95ef4dc55014a Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Sat, 13 Apr 2019 12:38:57 +0200 Subject: [PATCH 51/54] Refs #4993 Trying to make tests more stable increasing deadline period + removing unnecessary cancel of timer --- src/cpp/publisher/PublisherImpl.cpp | 5 ----- src/cpp/subscriber/SubscriberImpl.cpp | 5 ----- test/blackbox/BlackboxTestsDeadlineQos.cpp | 4 ++-- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index ebf9ba86dbd..58cc5593903 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -87,11 +87,6 @@ PublisherImpl::~PublisherImpl() logInfo(PUBLISHER, this->getGuid().entityId << " in topic: " << this->m_att.topic.topicName); } - if (m_att.qos.m_deadline.period != c_TimeInfinite) - { - deadline_timer_.cancel_timer(); - } - RTPSDomain::removeRTPSWriter(mp_writer); delete(this->mp_userPublisher); } diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index 3ce71e3756a..8b85ce738f8 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -74,11 +74,6 @@ SubscriberImpl::~SubscriberImpl() logInfo(SUBSCRIBER,this->getGuid().entityId << " in topic: "<m_att.topic.topicName); } - if (m_att.qos.m_deadline.period != c_TimeInfinite) - { - deadline_timer_.cancel_timer(); - } - RTPSDomain::removeRTPSReader(mp_reader); delete(this->mp_userSubscriber); } diff --git a/test/blackbox/BlackboxTestsDeadlineQos.cpp b/test/blackbox/BlackboxTestsDeadlineQos.cpp index 1c6dc462961..39c9e6dec7d 100644 --- a/test/blackbox/BlackboxTestsDeadlineQos.cpp +++ b/test/blackbox/BlackboxTestsDeadlineQos.cpp @@ -39,7 +39,7 @@ BLACKBOXTEST(DeadlineQos, NoKeyTopicLongDeadline) // Number of samples written by writer uint32_t writer_samples = 3; // Deadline period in seconds - eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 2 * 1e-3); + eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 10 * 1e-3); reader.deadline_period(deadline_s); writer.deadline_period(deadline_s); @@ -132,7 +132,7 @@ BLACKBOXTEST(DeadlineQos, KeyedTopicLongDeadline) // Number of samples written by writer uint32_t writer_samples = 4; // Deadline period in seconds - eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 4 * 1e-3); + eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 10 * 1e-3); reader.deadline_period(deadline_s); writer.deadline_period(deadline_s); From f9f5f179ede67b4181abab24c7582d7f815f7817 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Sun, 14 Apr 2019 19:17:58 +0200 Subject: [PATCH 52/54] Refs #4993 Increasing duration even more --- test/blackbox/BlackboxTestsDeadlineQos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/blackbox/BlackboxTestsDeadlineQos.cpp b/test/blackbox/BlackboxTestsDeadlineQos.cpp index 39c9e6dec7d..ac5bb88b067 100644 --- a/test/blackbox/BlackboxTestsDeadlineQos.cpp +++ b/test/blackbox/BlackboxTestsDeadlineQos.cpp @@ -39,7 +39,7 @@ BLACKBOXTEST(DeadlineQos, NoKeyTopicLongDeadline) // Number of samples written by writer uint32_t writer_samples = 3; // Deadline period in seconds - eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 10 * 1e-3); + eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 1000 * 1e-3); reader.deadline_period(deadline_s); writer.deadline_period(deadline_s); @@ -132,7 +132,7 @@ BLACKBOXTEST(DeadlineQos, KeyedTopicLongDeadline) // Number of samples written by writer uint32_t writer_samples = 4; // Deadline period in seconds - eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 10 * 1e-3); + eprosima::fastrtps::rtps::Duration_t deadline_s(writer_sleep_ms * 1000 * 1e-3); reader.deadline_period(deadline_s); writer.deadline_period(deadline_s); From c508107932a7adf5c8194afef49b6bd03c3b9141 Mon Sep 17 00:00:00 2001 From: Raquel Alvarez Date: Mon, 15 Apr 2019 11:01:04 +0200 Subject: [PATCH 53/54] Refs #4993 Splitting long lines --- src/cpp/publisher/PublisherHistory.cpp | 3 ++- src/cpp/publisher/PublisherImpl.cpp | 14 ++++++++++---- src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp | 4 +++- src/cpp/subscriber/SubscriberHistory.cpp | 7 +++++-- src/cpp/subscriber/SubscriberImpl.cpp | 14 ++++++++++---- test/blackbox/PubSubWriter.hpp | 9 +++++++-- 6 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/cpp/publisher/PublisherHistory.cpp b/src/cpp/publisher/PublisherHistory.cpp index 2d1c387f9b2..377f4f1b0f8 100644 --- a/src/cpp/publisher/PublisherHistory.cpp +++ b/src/cpp/publisher/PublisherHistory.cpp @@ -324,7 +324,8 @@ bool PublisherHistory::get_next_deadline( keyed_changes_.end(), []( const std::pair &lhs, - const std::pair &rhs){ return lhs.second.next_deadline_us < rhs.second.next_deadline_us;}); + const std::pair &rhs) + { return lhs.second.next_deadline_us < rhs.second.next_deadline_us; }); handle = min->first; next_deadline_us = min->second.next_deadline_us; diff --git a/src/cpp/publisher/PublisherImpl.cpp b/src/cpp/publisher/PublisherImpl.cpp index 58cc5593903..f0f95d25af0 100644 --- a/src/cpp/publisher/PublisherImpl.cpp +++ b/src/cpp/publisher/PublisherImpl.cpp @@ -208,7 +208,9 @@ bool PublisherImpl::create_new_change_with_params( if (m_att.qos.m_deadline.period != rtps::c_TimeInfinite) { - if (!m_history.set_next_deadline(ch->instanceHandle, steady_clock::now() + duration_cast(deadline_duration_us_))) + if (!m_history.set_next_deadline( + ch->instanceHandle, + steady_clock::now() + duration_cast(deadline_duration_us_))) { logError(PUBLISHER, "Could not set the next deadline in the history"); } @@ -334,7 +336,8 @@ bool PublisherImpl::updateAttributes(const PublisherAttributes& att) if (m_att.qos.m_deadline.period != c_TimeInfinite) { - deadline_duration_us_ = duration>(m_att.qos.m_deadline.period.to_ns() * 1e-3); + deadline_duration_us_ = + duration>(m_att.qos.m_deadline.period.to_ns() * 1e-3); deadline_timer_.update_interval_millisec(m_att.qos.m_deadline.period.to_ns() * 1e-6); } else @@ -346,7 +349,8 @@ bool PublisherImpl::updateAttributes(const PublisherAttributes& att) if (m_att.qos.m_lifespan.duration != c_TimeInfinite) { - lifespan_duration_us_ = duration>(m_att.qos.m_lifespan.duration.to_ns() * 1e-3); + lifespan_duration_us_ = + duration>(m_att.qos.m_lifespan.duration.to_ns() * 1e-3); lifespan_timer_.update_interval_millisec(m_att.qos.m_lifespan.duration.to_ns() * 1e-6); } else @@ -414,7 +418,9 @@ void PublisherImpl::deadline_missed() mp_listener->on_offered_deadline_missed(mp_userPublisher, deadline_missed_status_); deadline_missed_status_.total_count_change = 0; - if (!m_history.set_next_deadline(timer_owner_, steady_clock::now() + duration_cast(deadline_duration_us_))) + if (!m_history.set_next_deadline( + timer_owner_, + steady_clock::now() + duration_cast(deadline_duration_us_))) { logError(PUBLISHER, "Could not set the next deadline in the history"); return; diff --git a/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp b/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp index d348b7305f9..4bd2e04af63 100644 --- a/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp +++ b/src/cpp/rtps/builtin/discovery/endpoint/EDP.cpp @@ -535,7 +535,9 @@ bool EDP::validMatching(const ReaderProxyData* rdata, const WriterProxyData* wda } if(rdata->m_qos.m_deadline.period < wdata->m_qos.m_deadline.period) { - logWarning(RTPS_EDP, "INCOMPATIBLE QOS (topic: " << wdata->topicName() << "):RemoteWriter " << wdata->guid() << "has smaller DEADLINE period"); + logWarning(RTPS_EDP, "INCOMPATIBLE QOS (topic: " + << wdata->topicName() << "):RemoteWriter " + << wdata->guid() << "has smaller DEADLINE period"); return false; } diff --git a/src/cpp/subscriber/SubscriberHistory.cpp b/src/cpp/subscriber/SubscriberHistory.cpp index 8a99a3eeac2..3e7c89ac314 100644 --- a/src/cpp/subscriber/SubscriberHistory.cpp +++ b/src/cpp/subscriber/SubscriberHistory.cpp @@ -581,7 +581,9 @@ bool SubscriberHistory::set_next_deadline( return false; } -bool SubscriberHistory::get_next_deadline(InstanceHandle_t &handle, std::chrono::steady_clock::time_point &next_deadline_us) +bool SubscriberHistory::get_next_deadline( + InstanceHandle_t &handle, + std::chrono::steady_clock::time_point &next_deadline_us) { if (mp_reader == nullptr || mp_mutex == nullptr) { @@ -601,7 +603,8 @@ bool SubscriberHistory::get_next_deadline(InstanceHandle_t &handle, std::chrono: keyed_changes_.end(), []( const std::pair &lhs, - const std::pair &rhs){ return lhs.second.next_deadline_us < rhs.second.next_deadline_us;}); + const std::pair &rhs) + { return lhs.second.next_deadline_us < rhs.second.next_deadline_us; }); handle = min->first; next_deadline_us = min->second.next_deadline_us; return true; diff --git a/src/cpp/subscriber/SubscriberImpl.cpp b/src/cpp/subscriber/SubscriberImpl.cpp index 8b85ce738f8..2a52a296489 100644 --- a/src/cpp/subscriber/SubscriberImpl.cpp +++ b/src/cpp/subscriber/SubscriberImpl.cpp @@ -186,7 +186,8 @@ bool SubscriberImpl::updateAttributes(const SubscriberAttributes& att) if (m_att.qos.m_deadline.period != c_TimeInfinite) { - deadline_duration_us_ = duration>(m_att.qos.m_deadline.period.to_ns() * 1e-3); + deadline_duration_us_ = + duration>(m_att.qos.m_deadline.period.to_ns() * 1e-3); deadline_timer_.update_interval_millisec(m_att.qos.m_deadline.period.to_ns() * 1e-6); } else @@ -198,7 +199,8 @@ bool SubscriberImpl::updateAttributes(const SubscriberAttributes& att) if (m_att.qos.m_lifespan.duration != c_TimeInfinite) { - lifespan_duration_us_ = std::chrono::duration>(m_att.qos.m_lifespan.duration.to_ns() * 1e-3); + lifespan_duration_us_ = + std::chrono::duration>(m_att.qos.m_lifespan.duration.to_ns() * 1e-3); lifespan_timer_.update_interval_millisec(m_att.qos.m_lifespan.duration.to_ns() * 1e-6); } else @@ -236,7 +238,9 @@ bool SubscriberImpl::onNewCacheChangeAdded(const CacheChange_t* const change_in) { std::unique_lock lock(mp_reader->getMutex()); - if (!m_history.set_next_deadline(change_in->instanceHandle, steady_clock::now() + duration_cast(deadline_duration_us_))) + if (!m_history.set_next_deadline( + change_in->instanceHandle, + steady_clock::now() + duration_cast(deadline_duration_us_))) { logError(SUBSCRIBER, "Could not set next deadline in the history"); } @@ -336,7 +340,9 @@ void SubscriberImpl::deadline_missed() mp_listener->on_requested_deadline_missed(mp_userSubscriber, deadline_missed_status_); deadline_missed_status_.total_count_change = 0; - if (!m_history.set_next_deadline(timer_owner_, steady_clock::now() + duration_cast(deadline_duration_us_))) + if (!m_history.set_next_deadline( + timer_owner_, + steady_clock::now() + duration_cast(deadline_duration_us_))) { logError(SUBSCRIBER, "Could not set next deadline in the history"); return; diff --git a/test/blackbox/PubSubWriter.hpp b/test/blackbox/PubSubWriter.hpp index 276756253c4..345a938bafb 100644 --- a/test/blackbox/PubSubWriter.hpp +++ b/test/blackbox/PubSubWriter.hpp @@ -140,7 +140,9 @@ class PubSubWriter ~Listener(){}; - void onPublicationMatched(eprosima::fastrtps::Publisher* /*pub*/, eprosima::fastrtps::rtps::MatchingInfo &info) override + void onPublicationMatched( + eprosima::fastrtps::Publisher* /*pub*/, + eprosima::fastrtps::rtps::MatchingInfo &info) override { if (info.status == eprosima::fastrtps::rtps::MATCHED_MATCHING) { @@ -400,7 +402,10 @@ class PubSubWriter PubSubWriter& key(bool keyed) { - publisher_attr_.topic.topicKind = keyed ? eprosima::fastrtps::TopicKind_t::WITH_KEY : eprosima::fastrtps::TopicKind_t::NO_KEY; + publisher_attr_.topic.topicKind = + keyed ? + eprosima::fastrtps::TopicKind_t::WITH_KEY : + eprosima::fastrtps::TopicKind_t::NO_KEY; return *this; } From 79f458425c400af6c73af1bfb1f40ba376ad8f82 Mon Sep 17 00:00:00 2001 From: LuisGasco Date: Mon, 15 Apr 2019 15:21:49 +0200 Subject: [PATCH 54/54] Refs #5133 Fixed LivelinessAssertion test. --- test/communication/Publisher.cpp | 2 +- test/communication/Subscriber.cpp | 2 +- test/communication/liveliness_assertion.py | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/test/communication/Publisher.cpp b/test/communication/Publisher.cpp index bfc60ce97db..6d04cb5ee5a 100644 --- a/test/communication/Publisher.cpp +++ b/test/communication/Publisher.cpp @@ -171,7 +171,7 @@ int main(int argc, char** argv) //CREATE THE PUBLISHER PublisherAttributes publisher_attributes; - Domain::getDefaultPublisherAttributes(publisher_attributes); + //Domain::getDefaultPublisherAttributes(publisher_attributes); publisher_attributes.topic.topicKind = NO_KEY; publisher_attributes.topic.topicDataType = type.getName(); publisher_attributes.topic.topicName = topic.str(); diff --git a/test/communication/Subscriber.cpp b/test/communication/Subscriber.cpp index ccc84286e3b..64efa45d0c9 100644 --- a/test/communication/Subscriber.cpp +++ b/test/communication/Subscriber.cpp @@ -137,7 +137,7 @@ int main(int argc, char** argv) //CREATE THE SUBSCRIBER SubscriberAttributes subscriber_attributes; - Domain::getDefaultSubscriberAttributes(subscriber_attributes); + //Domain::getDefaultSubscriberAttributes(subscriber_attributes); subscriber_attributes.topic.topicKind = NO_KEY; subscriber_attributes.topic.topicDataType = type.getName(); subscriber_attributes.topic.topicName = topic.str(); diff --git a/test/communication/liveliness_assertion.py b/test/communication/liveliness_assertion.py index 8fd306e433c..9fab36bd354 100644 --- a/test/communication/liveliness_assertion.py +++ b/test/communication/liveliness_assertion.py @@ -40,10 +40,16 @@ while True: line = publisher_proc.stdout.readline() if line.strip().decode('utf-8') == 'Subscriber matched': + print("Subscriber matched.") break subscriber_proc.kill() publisher_proc.communicate() retvalue = publisher_proc.returncode +if retvalue != 0: + print("Test failed: " + str(retvalue)) +else: + print("Test successed") + sys.exit(retvalue)