Skip to content

Updates for recent SHM API changes #537

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion include/zenoh/api/shm/client/shm_client.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace zenoh {
class CppShmClient {
public:
virtual std::unique_ptr<CppShmSegment> attach(SegmentId segment_id) = 0;
virtual ProtocolId id() const = 0;
virtual ~CppShmClient() = default;
};

Expand All @@ -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<CppShmClient*>(context)->id(); }

inline void _z_cpp_shm_client_drop_fn(void* context) { delete static_cast<CppShmClient*>(context); }
}
} // namespace shm::client::closures
Expand All @@ -59,7 +62,10 @@ class ShmClient : public Owned<::z_owned_shm_client_t> {
ShmClient(std::unique_ptr<CppShmClient>&& 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);
}
};
Expand Down
15 changes: 7 additions & 8 deletions include/zenoh/api/shm/client_storage/client_storage.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -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 <class Container, typename _T = std::enable_if<
std::is_same<typename std::iterator_traits<typename Container::iterator>::value_type,
std::pair<ProtocolId, ShmClient>>::value>>
template <class Container,
typename _T = std::enable_if<std::is_same<
typename std::iterator_traits<typename Container::iterator>::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) {}
Expand All @@ -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 <class I, typename _T = std::enable_if<std::is_same<typename std::iterator_traits<I>::value_type,
std::pair<ProtocolId, ShmClient>>::value>>
template <class I, typename _T =
std::enable_if<std::is_same<typename std::iterator_traits<I>::value_type, ShmClient>::value>>
ShmClientStorage(std::move_iterator<I> begin, std::move_iterator<I> end, bool add_default_client_set,
ZResult* err = nullptr)
: Owned(nullptr) {
Expand All @@ -71,9 +71,8 @@ class ShmClientStorage : public Owned<::z_owned_shm_client_storage_t> {

// fill list with clients
for (std::move_iterator<I> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
};
Expand Down
11 changes: 9 additions & 2 deletions include/zenoh/api/shm/provider/alloc_layout.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
71 changes: 55 additions & 16 deletions include/zenoh/api/shm/provider/shm_provider.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -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<ShmProviderAsyncInterface> 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<ShmProviderAsyncInterface> 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)); }
Expand All @@ -114,8 +151,7 @@ class CppShmProvider : public ShmProvider {
/// @name Constructors

/// @brief Create a new CPP-defined ShmProvider.
CppShmProvider(ProtocolId id, std::unique_ptr<CppShmProviderBackend> backend)
: ShmProvider(zenoh::detail::null_object) {
CppShmProvider(std::unique_ptr<CppShmProviderBackend> 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};
Expand All @@ -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<CppShmProviderBackendThreadsafe> backend)
: ShmProvider(zenoh::detail::null_object) {
CppShmProvider(std::unique_ptr<CppShmProviderBackendThreadsafe> 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};
Expand All @@ -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);
}
};

Expand Down
6 changes: 6 additions & 0 deletions include/zenoh/api/shm/provider/shm_provider_backend.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#pragma once

#include <memory>

#include "../../base.hxx"
#include "../../interop.hxx"
#include "chunk.hxx"
Expand All @@ -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;
};

Expand Down Expand Up @@ -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<CppShmProviderBackend *>(context)->layout_for(interop::as_owned_cpp_ref<MemoryLayout>(layout));
}
inline ProtocolId _z_cpp_shm_provider_backend_id_fn(void *context) {
return static_cast<CppShmProviderBackend *>(context)->id();
}
}
} // namespace shm::provider_backend::closures

Expand Down
2 changes: 1 addition & 1 deletion tests/zenohc/config.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
34 changes: 21 additions & 13 deletions tests/zenohc/shm_api.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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);
}
Expand Down Expand Up @@ -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));

Expand All @@ -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<TestShmProviderBackend>(size);

// create provider
CppShmProvider provider(id, std::move(backend));
CppShmProvider provider(std::move(backend));
ASSERT_VALID(provider);

// test provider
Expand Down Expand Up @@ -287,7 +295,7 @@ int run_global_client_storage() {
}

template <bool list_api>
int run_client_storage_for_list(std::vector<std::pair<ProtocolId, ShmClient>>&& list) {
int run_client_storage_for_list(std::vector<ShmClient>&& list) {
// create storage
auto storage = [list = std::move(list)]() mutable {
if constexpr (list_api) {
Expand All @@ -307,14 +315,14 @@ int run_client_storage_for_list(std::vector<std::pair<ProtocolId, ShmClient>>&&
template <bool list_api>
int run_client_storage_impl() {
// create client list
std::vector<std::pair<ProtocolId, ShmClient>> list;
std::vector<ShmClient> 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<list_api>(std::move(list));
}
Expand All @@ -341,20 +349,20 @@ class TestShmClient : public CppShmClient {
virtual std::unique_ptr<CppShmSegment> attach(SegmentId segment_id) override {
return std::make_unique<TestShmSegment>(segment_id);
}

virtual ProtocolId id() const override { return 100500; }
};

int run_c_client() {
const ProtocolId id = 100500;

// create client list
std::vector<std::pair<ProtocolId, ShmClient>> list;
std::vector<ShmClient> list;

// create C SHM Client
auto client = ShmClient(std::make_unique<TestShmClient>());
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
Expand Down
2 changes: 1 addition & 1 deletion zenoh-c
Submodule zenoh-c updated 71 files
+2 −2 .github/workflows/ci.yml
+13 −13 .github/workflows/release.yml
+0 −3 .gitignore
+24 −8 CMakeLists.txt
+78 −65 Cargo.lock
+7 −7 Cargo.toml
+6 −6 Cargo.toml.in
+73 −60 build-resources/opaque-types/Cargo.lock
+3 −3 build-resources/opaque-types/Cargo.toml
+29 −12 build-resources/opaque-types/src/lib.rs
+37 −0 build.rs
+13 −3 buildrs/cbindgen_generator.rs
+35 −15 buildrs/opaque_types_generator.rs
+3 −3 ci/scripts/bump-and-tag.bash
+19 −20 docs/examples.rst
+3 −3 examples/README.md
+1 −1 examples/z_advanced_sub.c
+1 −1 examples/z_get.c
+3 −7 examples/z_get_shm.c
+1 −1 examples/z_liveliness.c
+1 −1 examples/z_non_blocking_get.c
+19 −4 examples/z_ping.c
+19 −10 examples/z_ping_shm.c
+16 −4 examples/z_pong.c
+4 −1 examples/z_pub.c
+6 −8 examples/z_pub_shm.c
+3 −7 examples/z_pub_shm_thr.c
+1 −1 examples/z_pub_thr.c
+4 −1 examples/z_querier.c
+2 −2 examples/z_queryable.c
+4 −9 examples/z_queryable_shm.c
+3 −3 examples/z_storage.c
+2 −2 examples/z_sub.c
+1 −1 examples/z_sub_thr.c
+179 −50 include/zenoh_commons.h
+16 −0 include/zenoh_constants.h
+24 −0 include/zenoh_macros.h
+3 −0 splitguide.yaml
+3 −3 src/advanced_publisher.rs
+5 −3 src/closures/hello_closure.rs
+5 −3 src/closures/log_closure.rs
+5 −3 src/closures/matching_status_closure.rs
+5 −3 src/closures/miss_closure.rs
+5 −3 src/closures/query_closure.rs
+5 −3 src/closures/reply_closure.rs
+3 −1 src/closures/sample_closure.rs
+3 −1 src/closures/zenohid_closure.rs
+32 −24 src/collections.rs
+7 −7 src/commons.rs
+0 −0 src/opaque_types/.gitkeep
+1 −0 src/opaque_types/mod.rs
+1 −1 src/platform/synchronization.rs
+6 −6 src/scouting.rs
+11 −2 src/shm/client/shm_client.rs
+6 −8 src/shm/client/shm_segment.rs
+4 −7 src/shm/client_storage/mod.rs
+0 −1 src/shm/protocol_implementations/posix/mod.rs
+26 −12 src/shm/protocol_implementations/posix/posix_shm_provider.rs
+0 −21 src/shm/protocol_implementations/posix/protocol_id.rs
+16 −8 src/shm/provider/alloc_layout.rs
+48 −14 src/shm/provider/alloc_layout_impl.rs
+79 −11 src/shm/provider/chunk.rs
+126 −28 src/shm/provider/shm_provider.rs
+13 −1 src/shm/provider/shm_provider_backend.rs
+11 −19 src/shm/provider/shm_provider_impl.rs
+9 −9 src/shm/provider/types.rs
+2 −2 src/subscriber.rs
+7 −7 src/zbytes.rs
+23 −15 tests/z_api_encoding_test.c
+29 −15 tests/z_api_shm_test.c
+1 −1 version.txt
Loading