diff --git a/examples/C++/DDS/ZeroCopyExample/LoanableHelloWorldSubscriber.cxx b/examples/C++/DDS/ZeroCopyExample/LoanableHelloWorldSubscriber.cxx index 3efcc70a3f5..7035bccde31 100644 --- a/examples/C++/DDS/ZeroCopyExample/LoanableHelloWorldSubscriber.cxx +++ b/examples/C++/DDS/ZeroCopyExample/LoanableHelloWorldSubscriber.cxx @@ -126,7 +126,7 @@ void LoanableHelloWorldSubscriber::SubListener::on_subscription_matched( void LoanableHelloWorldSubscriber::SubListener::on_data_available( DataReader* reader) { - FASTDDS_SEQUENCE(DataSeq, LoanableHelloWorld); + FASTDDS_CONST_SEQUENCE(DataSeq, LoanableHelloWorld); DataSeq data; SampleInfoSeq infos; diff --git a/include/fastdds/dds/core/LoanableSequence.hpp b/include/fastdds/dds/core/LoanableSequence.hpp index 7cf8f480253..1cdab9b845f 100644 --- a/include/fastdds/dds/core/LoanableSequence.hpp +++ b/include/fastdds/dds/core/LoanableSequence.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -57,8 +58,8 @@ namespace dds { * the sequence is loaning the buffer. The sequence should not be destroyed until the loan is returned. * @li A sequence with a zero maximum always has has_ownership == true */ -template -class LoanableSequence : public LoanableTypedCollection +template +class LoanableSequence : public LoanableTypedCollection { public: @@ -226,5 +227,7 @@ class LoanableSequence : public LoanableTypedCollection // Macro to easily declare a LoanableSequence for a data type #define FASTDDS_SEQUENCE(FooSeq, Foo) using FooSeq = eprosima::fastdds::dds::LoanableSequence +#define FASTDDS_CONST_SEQUENCE(FooSeq, Foo) using FooSeq = eprosima::fastdds::dds::LoanableSequence #endif // _FASTDDS_DDS_CORE_LOANABLESEQUENCE_HPP_ diff --git a/include/fastdds/dds/core/LoanableTypedCollection.hpp b/include/fastdds/dds/core/LoanableTypedCollection.hpp index 842b5230900..a35159f6673 100644 --- a/include/fastdds/dds/core/LoanableTypedCollection.hpp +++ b/include/fastdds/dds/core/LoanableTypedCollection.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -34,7 +35,7 @@ namespace dds { * * This is an abstract class. See @ref LoanableSequence for details. */ -template +template class LoanableTypedCollection : public LoanableCollection { public: @@ -54,7 +55,8 @@ class LoanableTypedCollection : public LoanableCollection * * @return a reference to the element at position @c n */ - T& operator []( + template + typename std::enable_if::type& operator []( size_type n) { if (n >= length_) diff --git a/src/cpp/rtps/DataSharing/ReaderPool.hpp b/src/cpp/rtps/DataSharing/ReaderPool.hpp index 2c1ab324bc8..a3a0bdfb115 100644 --- a/src/cpp/rtps/DataSharing/ReaderPool.hpp +++ b/src/cpp/rtps/DataSharing/ReaderPool.hpp @@ -91,8 +91,13 @@ class ReaderPool : public DataSharingPayloadPool // Open the segment try { +<<<<<<< HEAD segment_ = std::unique_ptr( new fastdds::rtps::SharedMemSegment(boost::interprocess::open_only, +======= + local_segment = std::unique_ptr( + new T(boost::interprocess::open_read_only, +>>>>>>> 6505a51ff (Enable memory protection on DataSharing readers (#2405)) segment_name_.c_str())); } catch (const std::exception& e) diff --git a/src/cpp/utils/shared_memory/SharedMemSegment.hpp b/src/cpp/utils/shared_memory/SharedMemSegment.hpp index 14d062906f1..9bd3bca52ed 100644 --- a/src/cpp/utils/shared_memory/SharedMemSegment.hpp +++ b/src/cpp/utils/shared_memory/SharedMemSegment.hpp @@ -356,6 +356,175 @@ class SharedMemSegment std::string name_; }; +<<<<<<< HEAD +======= +template +class SharedSegment : public SharedSegmentBase +{ +public: + + typedef T managed_shared_memory_type; + typedef U managed_shared_object_type; + + SharedSegment( + boost::interprocess::create_only_t, + const std::string& name, + size_t size) + : SharedSegmentBase(name) + { + segment_ = std::unique_ptr( + new managed_shared_memory_type(boost::interprocess::create_only, name.c_str(), + static_cast(size + EXTRA_SEGMENT_SIZE))); + } + + SharedSegment( + boost::interprocess::open_only_t, + const std::string& name) + : SharedSegmentBase(name) + { + segment_ = std::unique_ptr( + new managed_shared_memory_type(boost::interprocess::open_only, name.c_str())); + } + + SharedSegment( + boost::interprocess::open_read_only_t, + const std::string& name) + : SharedSegmentBase(name) + { + segment_ = std::unique_ptr( + new managed_shared_memory_type(boost::interprocess::open_read_only, name.c_str())); + } + + SharedSegment( + boost::interprocess::open_or_create_t, + const std::string& name, + size_t size) + : SharedSegmentBase(name) + { + segment_ = std::unique_ptr( + new managed_shared_memory_type(boost::interprocess::create_only, name.c_str(), static_cast(size))); + } + + ~SharedSegment() + { + // no need of exception handling cause never throws + segment_.reset(); + } + + static void remove( + const std::string& name) + { + managed_shared_object_type::remove(name.c_str()); + } + + void remove() override + { + managed_shared_object_type::remove(name().c_str()); + } + + void* get_address_from_offset( + SharedSegment::Offset offset) const override + { + return segment_->get_address_from_handle(offset); + } + + SharedSegment::Offset get_offset_from_address( + void* address) const override + { + return segment_->get_handle_from_address(address); + } + + managed_shared_memory_type& get() + { + return *segment_; + } + + /** + * Estimates the extra segment space required for an allocation + */ + static uint32_t compute_per_allocation_extra_size( + size_t allocation_alignment, + const std::string& domain_name) + { + Id uuid; + + try + { + static uint32_t extra_size = 0; + + if (extra_size == 0) + { + uuid.generate(); + + auto name = domain_name + "_" + uuid.to_string(); + + SharedMemEnvironment::get().init(); + + { + managed_shared_memory_type + test_segment(boost::interprocess::create_only, name.c_str(), + (std::max)((uint32_t)1024, static_cast(allocation_alignment * 4))); + + auto m1 = test_segment.get_free_memory(); + test_segment.allocate_aligned(1, static_cast(allocation_alignment)); + auto m2 = test_segment.get_free_memory(); + extra_size = static_cast(m1 - m2); + } + + managed_shared_object_type::remove(name.c_str()); + } + + return extra_size; + + } + catch (const std::exception& e) + { + logError(RTPS_TRANSPORT_SHM, "Failed to create segment " << uuid.to_string() + << ": " << e.what()); + + throw; + } + } + + /** + * Check the allocator internal structures + * @return true if structures are ok, false otherwise + */ + bool check_sanity() + { + return segment_->check_sanity(); + } + + /** + * @return The segment's size in bytes, including internal structures overhead. + */ + Offset mem_size() const + { + return segment_->get_size(); + } + +private: + + std::unique_ptr segment_; +}; + +using SharedMemSegment = SharedSegment< + boost::interprocess::basic_managed_shared_memory< + char, + boost::interprocess::rbtree_best_fit>, + boost::interprocess::iset_index>, + boost::interprocess::shared_memory_object>; + +using SharedFileSegment = SharedSegment< + boost::interprocess::basic_managed_mapped_file< + char, + boost::interprocess::rbtree_best_fit>, + boost::interprocess::iset_index>, + boost::interprocess::file_mapping>; + +>>>>>>> 6505a51ff (Enable memory protection on DataSharing readers (#2405)) } // namespace rtps } // namespace fastdds } // namespace eprosima