diff --git a/include/zenoh/api/shm/client/shm_client.hxx b/include/zenoh/api/shm/client/shm_client.hxx index e691f0bf..105d7446 100644 --- a/include/zenoh/api/shm/client/shm_client.hxx +++ b/include/zenoh/api/shm/client/shm_client.hxx @@ -27,6 +27,7 @@ namespace zenoh { class CppShmClient { public: virtual std::unique_ptr attach(SegmentId segment_id) = 0; + virtual ProtocolId id() const = 0; virtual ~CppShmClient() = default; }; @@ -43,6 +44,8 @@ inline bool _z_cpp_shm_client_attach_fn(struct z_shm_segment_t* out_segment, z_s return false; } +inline ProtocolId _z_cpp_shm_client_id_fn(void* context) { return static_cast(context)->id(); } + inline void _z_cpp_shm_client_drop_fn(void* context) { delete static_cast(context); } } } // namespace shm::client::closures @@ -59,7 +62,10 @@ class ShmClient : public Owned<::z_owned_shm_client_t> { ShmClient(std::unique_ptr&& cpp_interface) : Owned(nullptr) { zc_threadsafe_context_t context = {{cpp_interface.release()}, &shm::client::closures::_z_cpp_shm_client_drop_fn}; - zc_shm_client_callbacks_t callbacks = {&shm::client::closures::_z_cpp_shm_client_attach_fn}; + zc_shm_client_callbacks_t callbacks = { + &shm::client::closures::_z_cpp_shm_client_attach_fn, + &shm::client::closures::_z_cpp_shm_client_id_fn, + }; z_shm_client_new(&this->_0, context, callbacks); } }; diff --git a/include/zenoh/api/shm/client_storage/client_storage.hxx b/include/zenoh/api/shm/client_storage/client_storage.hxx index 106ddc31..82d97b75 100644 --- a/include/zenoh/api/shm/client_storage/client_storage.hxx +++ b/include/zenoh/api/shm/client_storage/client_storage.hxx @@ -47,9 +47,9 @@ class ShmClientStorage : public Owned<::z_owned_shm_client_storage_t> { /// clients /// @param err if not null, the result code will be written to this location, otherwise ZException exception will be /// thrown in case of error. - template ::value_type, - std::pair>::value>> + template ::value_type, ShmClient>::value>> ShmClientStorage(Container&& container, bool add_default_client_set, ZResult* err = nullptr) : ShmClientStorage(std::make_move_iterator(container.begin()), std::make_move_iterator(container.end()), add_default_client_set, err) {} @@ -61,8 +61,8 @@ class ShmClientStorage : public Owned<::z_owned_shm_client_storage_t> { /// clients /// @param err if not null, the result code will be written to this location, otherwise ZException exception will be /// thrown in case of error. - template ::value_type, - std::pair>::value>> + template ::value_type, ShmClient>::value>> ShmClientStorage(std::move_iterator begin, std::move_iterator end, bool add_default_client_set, ZResult* err = nullptr) : Owned(nullptr) { @@ -71,9 +71,8 @@ class ShmClientStorage : public Owned<::z_owned_shm_client_storage_t> { // fill list with clients for (std::move_iterator it = begin; it != end; ++it) { - __ZENOH_RESULT_CHECK( - zc_shm_client_list_add_client(interop::as_loaned_c_ptr(list), it->first, z_move(it->second._0)), err, - "Failed to form list of SHM clients"); + __ZENOH_RESULT_CHECK(zc_shm_client_list_add_client(interop::as_loaned_c_ptr(list), z_move(it->_0)), err, + "Failed to form list of SHM clients"); } // create client storage from the list diff --git a/include/zenoh/api/shm/protocol_implementations/posix/posix_shm_provider.hxx b/include/zenoh/api/shm/protocol_implementations/posix/posix_shm_provider.hxx index 2e8401bd..1e6418e2 100644 --- a/include/zenoh/api/shm/protocol_implementations/posix/posix_shm_provider.hxx +++ b/include/zenoh/api/shm/protocol_implementations/posix/posix_shm_provider.hxx @@ -26,12 +26,20 @@ class PosixShmProvider : public ShmProvider { /// @name Constructors + /// @brief Create a new PosixShmProvider. + /// @param size size of POSIX shared memory segment to be allocated and used by the provider + /// @param err if not null, the result code will be written to this location, otherwise ZException exception will be + /// thrown in case of error. + PosixShmProvider(std::size_t size, ZResult* err = nullptr) : ShmProvider(zenoh::detail::null_object) { + __ZENOH_RESULT_CHECK(::z_posix_shm_provider_new(&this->_0, size), err, "Failed to create POSIX SHM provider"); + } + /// @brief Create a new PosixShmProvider. /// @param layout layout for POSIX shared memory segment to be allocated and used by the provider /// @param err if not null, the result code will be written to this location, otherwise ZException exception will be /// thrown in case of error. PosixShmProvider(const MemoryLayout& layout, ZResult* err = nullptr) : ShmProvider(zenoh::detail::null_object) { - __ZENOH_RESULT_CHECK(::z_posix_shm_provider_new(&this->_0, interop::as_loaned_c_ptr(layout)), err, + __ZENOH_RESULT_CHECK(::z_posix_shm_provider_with_layout_new(&this->_0, interop::as_loaned_c_ptr(layout)), err, "Failed to create POSIX SHM provider"); } }; diff --git a/include/zenoh/api/shm/provider/alloc_layout.hxx b/include/zenoh/api/shm/provider/alloc_layout.hxx index 009f17b1..b4d485e5 100644 --- a/include/zenoh/api/shm/provider/alloc_layout.hxx +++ b/include/zenoh/api/shm/provider/alloc_layout.hxx @@ -51,11 +51,18 @@ class AllocLayout : public Owned<::z_owned_alloc_layout_t> { public: /// @name Constructors + /// @brief Create a new Alloc Layout for SHM Provider. + AllocLayout(const ShmProvider& owner_provider, std::size_t size, ZResult* err = nullptr) : Owned(nullptr) { + __ZENOH_RESULT_CHECK(::z_alloc_layout_new(&this->_0, interop::as_loaned_c_ptr(owner_provider), size), err, + "Failed to create SHM Alloc Layout"); + } + /// @brief Create a new Alloc Layout for SHM Provider. AllocLayout(const ShmProvider& owner_provider, std::size_t size, AllocAlignment alignment, ZResult* err = nullptr) : Owned(nullptr) { - __ZENOH_RESULT_CHECK(::z_alloc_layout_new(&this->_0, interop::as_loaned_c_ptr(owner_provider), size, alignment), - err, "Failed to create SHM Alloc Layout"); + __ZENOH_RESULT_CHECK( + ::z_alloc_layout_with_alignment_new(&this->_0, interop::as_loaned_c_ptr(owner_provider), size, alignment), + err, "Failed to create SHM Alloc Layout"); } /// @name Methods diff --git a/include/zenoh/api/shm/provider/shm_provider.hxx b/include/zenoh/api/shm/provider/shm_provider.hxx index 19b73d24..6bdbba52 100644 --- a/include/zenoh/api/shm/provider/shm_provider.hxx +++ b/include/zenoh/api/shm/provider/shm_provider.hxx @@ -50,45 +50,82 @@ class ShmProvider : public Owned<::z_owned_shm_provider_t> { friend class AllocLayout; protected: - ShmProvider(zenoh::detail::null_object_t) : Owned(nullptr){}; + ShmProvider(zenoh::detail::null_object_t) : Owned(nullptr) {} public: + BufLayoutAllocResult alloc(size_t size) const { + z_buf_layout_alloc_result_t result; + ::z_shm_provider_alloc(&result, interop::as_loaned_c_ptr(*this), size); + return Converters::from(result); + } + BufLayoutAllocResult alloc(size_t size, AllocAlignment alignment) const { z_buf_layout_alloc_result_t result; - ::z_shm_provider_alloc(&result, interop::as_loaned_c_ptr(*this), size, alignment); + ::z_shm_provider_alloc_aligned(&result, interop::as_loaned_c_ptr(*this), size, alignment); + return Converters::from(result); + } + + BufLayoutAllocResult alloc_gc(size_t size) const { + z_buf_layout_alloc_result_t result; + ::z_shm_provider_alloc_gc(&result, interop::as_loaned_c_ptr(*this), size); return Converters::from(result); } BufLayoutAllocResult alloc_gc(size_t size, AllocAlignment alignment) const { z_buf_layout_alloc_result_t result; - ::z_shm_provider_alloc_gc(&result, interop::as_loaned_c_ptr(*this), size, alignment); + ::z_shm_provider_alloc_gc_aligned(&result, interop::as_loaned_c_ptr(*this), size, alignment); + return Converters::from(result); + } + + BufLayoutAllocResult alloc_gc_defrag(size_t size) const { + z_buf_layout_alloc_result_t result; + ::z_shm_provider_alloc_gc_defrag(&result, interop::as_loaned_c_ptr(*this), size); return Converters::from(result); } BufLayoutAllocResult alloc_gc_defrag(size_t size, AllocAlignment alignment) const { z_buf_layout_alloc_result_t result; - ::z_shm_provider_alloc_gc_defrag(&result, interop::as_loaned_c_ptr(*this), size, alignment); + ::z_shm_provider_alloc_gc_defrag_aligned(&result, interop::as_loaned_c_ptr(*this), size, alignment); + return Converters::from(result); + } + + BufLayoutAllocResult alloc_gc_defrag_dealloc(size_t size) const { + z_buf_layout_alloc_result_t result; + ::z_shm_provider_alloc_gc_defrag_dealloc(&result, interop::as_loaned_c_ptr(*this), size); return Converters::from(result); } BufLayoutAllocResult alloc_gc_defrag_dealloc(size_t size, AllocAlignment alignment) const { z_buf_layout_alloc_result_t result; - ::z_shm_provider_alloc_gc_defrag_dealloc(&result, interop::as_loaned_c_ptr(*this), size, alignment); + ::z_shm_provider_alloc_gc_defrag_dealloc_aligned(&result, interop::as_loaned_c_ptr(*this), size, alignment); + return Converters::from(result); + } + + BufLayoutAllocResult alloc_gc_defrag_blocking(size_t size) const { + z_buf_layout_alloc_result_t result; + ::z_shm_provider_alloc_gc_defrag_blocking(&result, interop::as_loaned_c_ptr(*this), size); return Converters::from(result); } BufLayoutAllocResult alloc_gc_defrag_blocking(size_t size, AllocAlignment alignment) const { z_buf_layout_alloc_result_t result; - ::z_shm_provider_alloc_gc_defrag_blocking(&result, interop::as_loaned_c_ptr(*this), size, alignment); + ::z_shm_provider_alloc_gc_defrag_blocking_aligned(&result, interop::as_loaned_c_ptr(*this), size, alignment); return Converters::from(result); } + ZResult alloc_gc_defrag_async(size_t size, std::unique_ptr receiver) const { + auto rcv = receiver.release(); + ::zc_threadsafe_context_t context = {{rcv}, &ShmProviderAsyncInterface::drop}; + return ::z_shm_provider_alloc_gc_defrag_async(&rcv->_result, interop::as_loaned_c_ptr(*this), size, context, + ShmProviderAsyncInterface::result); + } + ZResult alloc_gc_defrag_async(size_t size, AllocAlignment alignment, std::unique_ptr receiver) const { auto rcv = receiver.release(); ::zc_threadsafe_context_t context = {{rcv}, &ShmProviderAsyncInterface::drop}; - return ::z_shm_provider_alloc_gc_defrag_async(&rcv->_result, interop::as_loaned_c_ptr(*this), size, alignment, - context, ShmProviderAsyncInterface::result); + return ::z_shm_provider_alloc_gc_defrag_aligned_async(&rcv->_result, interop::as_loaned_c_ptr(*this), size, + alignment, context, ShmProviderAsyncInterface::result); } void defragment() const { ::z_shm_provider_defragment(interop::as_loaned_c_ptr(*this)); } @@ -114,8 +151,7 @@ class CppShmProvider : public ShmProvider { /// @name Constructors /// @brief Create a new CPP-defined ShmProvider. - CppShmProvider(ProtocolId id, std::unique_ptr backend) - : ShmProvider(zenoh::detail::null_object) { + CppShmProvider(std::unique_ptr backend) : ShmProvider(zenoh::detail::null_object) { // init context zc_context_t context = {backend.release(), &shm::provider_backend::closures::_z_cpp_shm_provider_backend_drop_fn}; @@ -126,15 +162,16 @@ class CppShmProvider : public ShmProvider { &shm::provider_backend::closures::_z_cpp_shm_provider_backend_free_fn, &shm::provider_backend::closures::_z_cpp_shm_provider_backend_defragment_fn, &shm::provider_backend::closures::_z_cpp_shm_provider_backend_available_fn, - &shm::provider_backend::closures::_z_cpp_shm_provider_backend_layout_for_fn}; + &shm::provider_backend::closures::_z_cpp_shm_provider_backend_layout_for_fn, + &shm::provider_backend::closures::_z_cpp_shm_provider_backend_id_fn, + }; // create provider - ::z_shm_provider_new(&this->_0, id, context, callbacks); + ::z_shm_provider_new(&this->_0, context, callbacks); } /// @brief Create a new CPP-defined threadsafe ShmProvider. - CppShmProvider(ProtocolId id, std::unique_ptr backend) - : ShmProvider(zenoh::detail::null_object) { + CppShmProvider(std::unique_ptr backend) : ShmProvider(zenoh::detail::null_object) { // init context ::zc_threadsafe_context_t context = {{backend.release()}, &shm::provider_backend::closures::_z_cpp_shm_provider_backend_drop_fn}; @@ -145,10 +182,12 @@ class CppShmProvider : public ShmProvider { &shm::provider_backend::closures::_z_cpp_shm_provider_backend_free_fn, &shm::provider_backend::closures::_z_cpp_shm_provider_backend_defragment_fn, &shm::provider_backend::closures::_z_cpp_shm_provider_backend_available_fn, - &shm::provider_backend::closures::_z_cpp_shm_provider_backend_layout_for_fn}; + &shm::provider_backend::closures::_z_cpp_shm_provider_backend_layout_for_fn, + &shm::provider_backend::closures::_z_cpp_shm_provider_backend_id_fn, + }; // create provider - ::z_shm_provider_threadsafe_new(&this->_0, id, context, callbacks); + ::z_shm_provider_threadsafe_new(&this->_0, context, callbacks); } }; diff --git a/include/zenoh/api/shm/provider/shm_provider_backend.hxx b/include/zenoh/api/shm/provider/shm_provider_backend.hxx index 5bcc9de9..38ad894b 100644 --- a/include/zenoh/api/shm/provider/shm_provider_backend.hxx +++ b/include/zenoh/api/shm/provider/shm_provider_backend.hxx @@ -14,6 +14,8 @@ #pragma once +#include + #include "../../base.hxx" #include "../../interop.hxx" #include "chunk.hxx" @@ -28,6 +30,7 @@ class CppShmProviderBackendIface { virtual size_t defragment() = 0; virtual size_t available() const = 0; virtual void layout_for(MemoryLayout &layout) = 0; + virtual ProtocolId id() const = 0; virtual ~CppShmProviderBackendIface() = default; }; @@ -56,6 +59,9 @@ inline size_t _z_cpp_shm_provider_backend_available_fn(void *context) { inline void _z_cpp_shm_provider_backend_layout_for_fn(struct z_owned_memory_layout_t *layout, void *context) { static_cast(context)->layout_for(interop::as_owned_cpp_ref(layout)); } +inline ProtocolId _z_cpp_shm_provider_backend_id_fn(void *context) { + return static_cast(context)->id(); +} } } // namespace shm::provider_backend::closures diff --git a/tests/zenohc/config.cxx b/tests/zenohc/config.cxx index b3916b1f..e1eb4e3e 100644 --- a/tests/zenohc/config.cxx +++ b/tests/zenohc/config.cxx @@ -32,7 +32,7 @@ void test_config_to_string() { Config config = Config::create_default(); auto s = config.to_string(); assert(s.size() > 0); - assert(s.find("{\"id\":\"") == 0); + assert(s.find("{\"id\":") != std::string::npos); } int main(int argc, char** argv) { diff --git a/tests/zenohc/shm_api.cxx b/tests/zenohc/shm_api.cxx index 5a113036..22ea624e 100644 --- a/tests/zenohc/shm_api.cxx +++ b/tests/zenohc/shm_api.cxx @@ -160,6 +160,9 @@ class TestShmProviderBackend : public CppShmProviderBackend { delete[] busy_flags; } + private: + static void deref_segemnt_fn(void* context) {} + private: virtual ChunkAllocResult alloc(const MemoryLayout& layout) override { assert(interop::detail::check(layout)); @@ -176,12 +179,16 @@ class TestShmProviderBackend : public CppShmProviderBackend { this->busy_flags[i] = true; this->bytes_available--; + z_owned_ptr_in_segment_t ptr; + zc_threadsafe_context_t segment = {{NULL}, &TestShmProviderBackend::deref_segemnt_fn}; + z_ptr_in_segment_new(&ptr, &this->bytes[i], segment); + AllocatedChunk chunk; - chunk.data = &this->bytes[i]; - uint64_t ptr = (uint64_t)(chunk.data); - chunk.descriptpr.chunk = ptr & 0xFFFFFFFF; + chunk.ptr = z_move(ptr); + uint64_t data_ptr = (uint64_t)(&this->bytes[i]); + chunk.descriptpr.chunk = data_ptr & 0xFFFFFFFF; chunk.descriptpr.len = 1; - chunk.descriptpr.segment = (ptr >> 32) & 0xFFFFFFFF; + chunk.descriptpr.segment = (data_ptr >> 32) & 0xFFFFFFFF; return ChunkAllocResult(chunk); } @@ -209,6 +216,8 @@ class TestShmProviderBackend : public CppShmProviderBackend { virtual size_t available() const override { return this->bytes_available; } + virtual ProtocolId id() const override { return 100500; } + virtual void layout_for(MemoryLayout& layout) override { assert(interop::detail::check(layout)); @@ -224,14 +233,13 @@ class TestShmProviderBackend : public CppShmProviderBackend { }; int run_c_provider() { - const ProtocolId id = 100500; const size_t size = 1024; // create test backend auto backend = std::make_unique(size); // create provider - CppShmProvider provider(id, std::move(backend)); + CppShmProvider provider(std::move(backend)); ASSERT_VALID(provider); // test provider @@ -287,7 +295,7 @@ int run_global_client_storage() { } template -int run_client_storage_for_list(std::vector>&& list) { +int run_client_storage_for_list(std::vector&& list) { // create storage auto storage = [list = std::move(list)]() mutable { if constexpr (list_api) { @@ -307,14 +315,14 @@ int run_client_storage_for_list(std::vector>&& template int run_client_storage_impl() { // create client list - std::vector> list; + std::vector list; // create POSIX SHM Client PosixShmClient client; ASSERT_VALID(client); // add client to the list - list.push_back(std::make_pair(Z_SHM_POSIX_PROTOCOL_ID, std::move(client))); + list.push_back(std::move(client)); return run_client_storage_for_list(std::move(list)); } @@ -341,20 +349,20 @@ class TestShmClient : public CppShmClient { virtual std::unique_ptr attach(SegmentId segment_id) override { return std::make_unique(segment_id); } + + virtual ProtocolId id() const override { return 100500; } }; int run_c_client() { - const ProtocolId id = 100500; - // create client list - std::vector> list; + std::vector list; // create C SHM Client auto client = ShmClient(std::make_unique()); ASSERT_VALID(client); // add client to the list - list.push_back(std::make_pair(id, std::move(client))); + list.push_back(std::move(client)); ASSERT_NULL(client); // create client storage from the list diff --git a/zenoh-c b/zenoh-c index 62a780fb..1184c236 160000 --- a/zenoh-c +++ b/zenoh-c @@ -1 +1 @@ -Subproject commit 62a780fb797729b50cadab4c32f6cf14b051a165 +Subproject commit 1184c2364e1e0e73b68ef45a8064ac40a224256e