diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 17d780e06..0830d8d0b 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -3191,9 +3191,9 @@ ZENOHC_API void z_memory_layout_drop(z_moved_memory_layout_t *this_); */ #if (defined(SHARED_MEMORY) && defined(UNSTABLE)) ZENOHC_API -void z_memory_layout_get_data(size_t *out_size, - struct z_alloc_alignment_t *out_alignment, - const z_loaned_memory_layout_t *this_); +void z_memory_layout_get_data(const z_loaned_memory_layout_t *this_, + size_t *out_size, + struct z_alloc_alignment_t *out_alignment); #endif /** * Borrows Memory Layout @@ -3931,10 +3931,19 @@ ZENOHC_API const z_loaned_shm_mut_t *z_shm_mut_loan(const z_owned_shm_mut_t *thi ZENOHC_API z_loaned_shm_mut_t *z_shm_mut_loan_mut(z_owned_shm_mut_t *this_); #endif /** - * Tries to construct ZShmMut slice from ZShm slice + * Tries to obtain mutable SHM buffer instead of immutable one + * @param this: mutable SHM buffer to be initialized upon success + * @param that: immutable SHM buffer + * @param immut: immutable SHM buffer returned back to caller's side + * ONLY in case of Z_EUNAVAILABLE failure + * @return Z_OK in case of success, Z_EUNAVAILABLE in case of unsuccessful write access, + * Z_EINVAL if moved value is incorrect */ #if (defined(SHARED_MEMORY) && defined(UNSTABLE)) -ZENOHC_API void z_shm_mut_try_from_immut(z_owned_shm_mut_t *this_, z_moved_shm_t *that); +ZENOHC_API +z_result_t z_shm_mut_try_from_immut(z_owned_shm_mut_t *this_, + z_moved_shm_t *that, + z_owned_shm_t *immut); #endif #if (defined(SHARED_MEMORY) && defined(UNSTABLE)) ZENOHC_API @@ -4833,9 +4842,9 @@ ZENOHC_API enum zc_reply_keyexpr_t zc_reply_keyexpr_default(void); #endif #if (defined(SHARED_MEMORY) && defined(UNSTABLE)) ZENOHC_API -z_result_t zc_shm_client_list_add_client(z_protocol_id_t id, - z_moved_shm_client_t *client, - zc_loaned_shm_client_list_t *list); +z_result_t zc_shm_client_list_add_client(zc_loaned_shm_client_list_t *this_, + z_protocol_id_t id, + z_moved_shm_client_t *client); #endif /** * Deletes list of SHM Clients diff --git a/src/shm/buffer/zshmmut.rs b/src/shm/buffer/zshmmut.rs index f901ad607..818647d00 100644 --- a/src/shm/buffer/zshmmut.rs +++ b/src/shm/buffer/zshmmut.rs @@ -20,8 +20,9 @@ use std::{ use zenoh::shm::{zshmmut, ZShmMut}; use crate::{ + result, transmute::{LoanedCTypeRef, RustTypeRef, RustTypeRefUninit, TakeRustType}, - z_loaned_shm_mut_t, z_moved_shm_mut_t, z_moved_shm_t, z_owned_shm_mut_t, + z_loaned_shm_mut_t, z_moved_shm_mut_t, z_moved_shm_t, z_owned_shm_mut_t, z_owned_shm_t, }; decl_c_type!( @@ -29,17 +30,32 @@ decl_c_type!( loaned(z_loaned_shm_mut_t, zshmmut), ); -/// Tries to construct ZShmMut slice from ZShm slice +/// Tries to obtain mutable SHM buffer instead of immutable one +/// @param this: mutable SHM buffer to be initialized upon success +/// @param that: immutable SHM buffer +/// @param immut: immutable SHM buffer returned back to caller's side +/// ONLY in case of Z_EUNAVAILABLE failure +/// @return Z_OK in case of success, Z_EUNAVAILABLE in case of unsuccessful write access, +/// Z_EINVAL if moved value is incorrect #[no_mangle] pub extern "C" fn z_shm_mut_try_from_immut( this: &mut MaybeUninit, that: &mut z_moved_shm_t, -) { - let shm: Option = that - .take_rust_type() - .take() - .and_then(|val| val.try_into().ok()); - this.as_rust_type_mut_uninit().write(shm); + immut: &mut MaybeUninit, +) -> result::z_result_t { + if let Some(shm) = that.take_rust_type() { + return match ZShmMut::try_from(shm) { + Ok(val) => { + this.as_rust_type_mut_uninit().write(Some(val)); + result::Z_OK + } + Err(old) => { + immut.as_rust_type_mut_uninit().write(Some(old)); + result::Z_EUNAVAILABLE + } + }; + } + result::Z_EINVAL } /// Constructs ZShmMut slice in its gravestone value. diff --git a/src/shm/client_storage/mod.rs b/src/shm/client_storage/mod.rs index b4efd99bd..16e4e1fa6 100644 --- a/src/shm/client_storage/mod.rs +++ b/src/shm/client_storage/mod.rs @@ -83,14 +83,14 @@ pub unsafe extern "C" fn zc_shm_client_list_loan_mut( #[no_mangle] pub extern "C" fn zc_shm_client_list_add_client( + this: &mut zc_loaned_shm_client_list_t, id: z_protocol_id_t, client: &mut z_moved_shm_client_t, - list: &mut zc_loaned_shm_client_list_t, ) -> z_result_t { let Some(client) = client.take_rust_type() else { return Z_EINVAL; }; - list.as_rust_type_mut().push((id, client)); + this.as_rust_type_mut().push((id, client)); Z_OK } diff --git a/src/shm/provider/types.rs b/src/shm/provider/types.rs index a9c6cb9a5..66610cc9d 100644 --- a/src/shm/provider/types.rs +++ b/src/shm/provider/types.rs @@ -176,9 +176,9 @@ pub extern "C" fn z_memory_layout_drop(this_: &mut z_moved_memory_layout_t) { /// Extract data from Memory Layout #[no_mangle] pub extern "C" fn z_memory_layout_get_data( + this: &z_loaned_memory_layout_t, out_size: &mut MaybeUninit, out_alignment: &mut MaybeUninit, - this: &z_loaned_memory_layout_t, ) { let layout = this.as_rust_type_ref(); out_size.write(layout.size().into()); diff --git a/tests/z_api_shm_test.c b/tests/z_api_shm_test.c index d11b63eac..d91742fa7 100644 --- a/tests/z_api_shm_test.c +++ b/tests/z_api_shm_test.c @@ -77,12 +77,14 @@ int test_shm_buffer(z_moved_shm_mut_t* mbuf) { ASSERT_CHECK(immut2); z_owned_shm_mut_t mut; - z_shm_mut_try_from_immut(&mut, z_move(immut2)); - ASSERT_CHECK_ERR(immut2); - ASSERT_CHECK_ERR(mut); + ASSERT_TRUE(Z_EUNAVAILABLE == z_shm_mut_try_from_immut(&mut, z_move(immut2), &immut2)); + ASSERT_CHECK(immut2); + + z_drop(z_move(immut2)); - z_shm_mut_try_from_immut(&mut, z_move(immut)); + ASSERT_TRUE(Z_OK == z_shm_mut_try_from_immut(&mut, z_move(immut), &immut)); ASSERT_CHECK(mut); + ASSERT_CHECK_ERR(immut); z_drop(z_move(mut)); ASSERT_CHECK_ERR(mut); @@ -189,7 +191,7 @@ void alloc_fn(struct z_owned_chunk_alloc_result_t* result, const struct z_loaned // check size and alignment size_t size = 0; z_alloc_alignment_t alignment; - z_memory_layout_get_data(&size, &alignment, layout); + z_memory_layout_get_data(layout, &size, &alignment); assert(size == 1); assert(alignment.pow == 0); @@ -251,7 +253,7 @@ void layout_for_fn(struct z_owned_memory_layout_t* layout, void* context) { // check size and alignment size_t size = 0; z_alloc_alignment_t alignment; - z_memory_layout_get_data(&size, &alignment, z_loan(*layout)); + z_memory_layout_get_data(z_loan(*layout), &size, &alignment); if (size != 1 || alignment.pow != 0) { z_memory_layout_drop(z_move(*layout)); @@ -377,7 +379,7 @@ int run_client_storage() { ASSERT_CHECK(client); // add client to the list - ASSERT_OK(zc_shm_client_list_add_client(Z_SHM_POSIX_PROTOCOL_ID, z_move(client), z_loan_mut(list))); + ASSERT_OK(zc_shm_client_list_add_client(z_loan_mut(list), Z_SHM_POSIX_PROTOCOL_ID, z_move(client))); ASSERT_CHECK_ERR(client); // create client storage from the list @@ -426,7 +428,7 @@ int run_c_client() { ASSERT_CHECK(client); // add client to the list - ASSERT_OK(zc_shm_client_list_add_client(100500, z_move(client), z_loan_mut(list))); + ASSERT_OK(zc_shm_client_list_add_client(z_loan_mut(list), 100500, z_move(client))); ASSERT_CHECK_ERR(client); // create client storage from the list