From a52ef72f924e88453fae490225f0f4e23ee8724a Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Mon, 26 Feb 2024 10:58:52 +0100 Subject: [PATCH 01/75] introduce owned buffers --- include/zenoh_commons.h | 19 +++++++++-- include/zenoh_macros.h | 10 ++++++ src/attachment.rs | 4 ++- src/collections.rs | 70 ++++++++++++++++++++++++++++++++++++-- src/commons.rs | 21 +++--------- src/config.rs | 7 +--- src/get.rs | 2 +- src/keyexpr.rs | 20 ++--------- src/lib.rs | 22 +++++++++++- src/publication_cache.rs | 25 ++------------ src/publisher.rs | 4 +-- src/pull_subscriber.rs | 15 +------- src/queryable.rs | 21 ++---------- src/querying_subscriber.rs | 26 +++----------- src/session.rs | 22 ++---------- src/subscriber.rs | 23 ++----------- 16 files changed, 144 insertions(+), 167 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 9bf02fe81..c7d46f932 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -155,8 +155,8 @@ typedef enum zcu_reply_keyexpr_t { * and empty slices are represented using a possibly dangling pointer for `start`. */ typedef struct z_bytes_t { - size_t len; const uint8_t *start; + size_t len; } z_bytes_t; /** * The body of a loop over an attachment's key-value pairs. @@ -189,6 +189,15 @@ typedef struct z_attachment_t { const void *data; z_attachment_iter_driver_t iteration_driver; } z_attachment_t; +/** + * A buffer owned by Zenoh. + */ +typedef struct z_owned_buffer_t { + size_t _inner[5]; +} z_owned_buffer_t; +typedef struct z_buffer_t { + size_t _inner; +} z_buffer_t; /** * A map of maybe-owned vector of bytes to owned vector of bytes. * @@ -862,7 +871,7 @@ typedef struct zc_owned_liveliness_get_options_t { */ typedef struct zc_owned_payload_t { struct z_bytes_t payload; - size_t _owner[5]; + struct z_owned_buffer_t _owner; } zc_owned_payload_t; typedef struct zc_owned_shmbuf_t { size_t _0[9]; @@ -1027,6 +1036,12 @@ int8_t z_attachment_iterate(struct z_attachment_t this_, * Returns the gravestone value for `z_attachment_t`. */ ZENOHC_API struct z_attachment_t z_attachment_null(void); +ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); +ZENOHC_API struct z_owned_buffer_t z_buffer_clone(struct z_buffer_t buffer); +ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); +ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); +ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); +ZENOHC_API struct z_bytes_t z_buffer_payload(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index fa6668d48..494d01fb9 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -14,6 +14,7 @@ z_owned_hello_t : z_hello_loan, \ z_owned_str_t : z_str_loan, \ z_owned_query_t : z_query_loan, \ + z_owned_buffer_t: z_buffer_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan \ )(&x) @@ -42,6 +43,7 @@ z_owned_reply_channel_t * : z_reply_channel_drop, \ z_owned_query_channel_t * : z_query_channel_drop, \ z_owned_bytes_map_t * : z_bytes_map_drop, \ + z_owned_buffer_t * : z_buffer_drop, \ zc_owned_payload_t * : zc_payload_drop, \ zc_owned_shmbuf_t * : zc_shmbuf_drop, \ zc_owned_shm_manager_t * : zc_shm_manager_drop, \ @@ -73,6 +75,7 @@ z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ z_owned_reply_channel_t * : z_reply_channel_null, \ z_owned_bytes_map_t * : z_bytes_map_null, \ + z_owned_buffer_t * : z_buffer_null, \ z_attachment_t * : z_attachment_null, \ zc_owned_payload_t * : zc_payload_null, \ zc_owned_shmbuf_t * : zc_shmbuf_null, \ @@ -98,6 +101,7 @@ z_owned_query_t : z_query_check, \ z_owned_str_t : z_str_check, \ z_owned_bytes_map_t : z_bytes_map_check, \ + z_owned_buffer_t : z_buffer_check, \ z_attachment_t : z_attachment_check, \ zc_owned_payload_t : zc_payload_check, \ zc_owned_shmbuf_t : zc_shmbuf_check, \ @@ -141,6 +145,7 @@ template<> struct zenoh_loan_type{ typedef z_pull_sub template<> struct zenoh_loan_type{ typedef z_encoding_t type; }; template<> struct zenoh_loan_type{ typedef z_hello_t type; }; template<> struct zenoh_loan_type{ typedef const char* type; }; +template<> struct zenoh_loan_type{ typedef z_buffer_t type; }; template<> struct zenoh_loan_type{ typedef ze_querying_subscriber_t type; }; template<> inline z_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } @@ -153,6 +158,7 @@ template<> inline z_encoding_t z_loan(const z_owned_encoding_t& x) { return z_en template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } +template<> inline z_buffer_t z_loan(const z_owned_buffer_t& x) { return z_buffer_loan(&x); } template<> inline ze_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } template struct zenoh_drop_type { typedef T type; }; @@ -171,6 +177,7 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -200,6 +207,7 @@ template<> inline void z_drop(z_owned_reply_t* v) { z_reply_drop(v); } template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } template<> inline void z_drop(z_owned_query_t* v) { z_query_drop(v); } template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } +template<> inline void z_drop(z_owned_buffer_t* v) { z_buffer_drop(v); } template<> inline void z_drop(zc_owned_payload_t* v) { zc_payload_drop(v); } template<> inline void z_drop(zc_owned_shmbuf_t* v) { zc_shmbuf_drop(v); } template<> inline void z_drop(zc_owned_shm_manager_t* v) { zc_shm_manager_drop(v); } @@ -229,6 +237,7 @@ inline void z_null(z_owned_reply_t& v) { v = z_reply_null(); } inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } inline void z_null(z_owned_query_t& v) { v = z_query_null(); } inline void z_null(z_owned_str_t& v) { v = z_str_null(); } +inline void z_null(z_owned_buffer_t& v) { v = z_buffer_null(); } inline void z_null(zc_owned_payload_t& v) { v = zc_payload_null(); } inline void z_null(zc_owned_shmbuf_t& v) { v = zc_shmbuf_null(); } inline void z_null(zc_owned_shm_manager_t& v) { v = zc_shm_manager_null(); } @@ -263,6 +272,7 @@ inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } inline bool z_check(const z_owned_query_t& v) { return z_query_check(&v); } inline bool z_check(const z_owned_str_t& v) { return z_str_check(&v); } +inline bool z_check(const z_owned_buffer_t& v) { return z_buffer_check(&v); } inline bool z_check(const z_owned_bytes_map_t& v) { return z_bytes_map_check(&v); } inline bool z_check(const z_attachment_t& v) { return z_attachment_check(&v); } inline bool z_check(const zc_owned_liveliness_token_t& v) { return zc_liveliness_token_check(&v); } diff --git a/src/attachment.rs b/src/attachment.rs index 5dbbfec5c..051edafdc 100644 --- a/src/attachment.rs +++ b/src/attachment.rs @@ -13,6 +13,7 @@ use zenoh::sample::{Attachment, AttachmentBuilder}; /// /// Returning `0` is treated as `continue`. /// Returning any other value is treated as `break`. +#[allow(non_camel_case_types)] pub type z_attachment_iter_body_t = extern "C" fn(key: z_bytes_t, value: z_bytes_t, context: *mut c_void) -> i8; @@ -20,6 +21,7 @@ pub type z_attachment_iter_body_t = /// /// This function is expected to call `loop_body` once for each key-value pair /// within `iterator`, passing `context`, and returning any non-zero value immediately (breaking iteration). +#[allow(non_camel_case_types)] pub type z_attachment_iter_driver_t = Option< extern "C" fn( iterator: *const c_void, @@ -124,7 +126,7 @@ pub struct z_owned_bytes_map_t { _1: [usize; 4], } -impl_guarded_transmute!( +impl_guarded_transmute!(noderefs Option, Cow<'static, [u8]>>>, z_owned_bytes_map_t ); diff --git a/src/collections.rs b/src/collections.rs index 9fd0c3c16..9ac7831c0 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -11,8 +11,14 @@ // Contributors: // ZettaScale Zenoh team, // + use libc::{c_char, size_t}; -use zenoh::prelude::ZenohId; +use zenoh::{ + buffers::{buffer::SplitBuffer, ZBuf}, + prelude::ZenohId, +}; + +use crate::impl_guarded_transmute; /// A contiguous view of bytes owned by some other entity. /// @@ -21,8 +27,8 @@ use zenoh::prelude::ZenohId; #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct z_bytes_t { - pub len: size_t, pub start: *const u8, + pub len: size_t, } impl z_bytes_t { @@ -155,3 +161,63 @@ impl From<&[u8]> for z_bytes_t { } } } + +/// A buffer owned by Zenoh. +#[repr(C)] +pub struct z_owned_buffer_t { + _inner: [usize; 5], +} +impl_guarded_transmute!(Option, z_owned_buffer_t); + +#[no_mangle] +pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { + None.into() +} +#[no_mangle] +pub extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { + core::mem::drop(buffer.take()) +} + +#[no_mangle] +pub extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { + buffer.is_some() +} +#[no_mangle] +pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { + buffer.as_ref().into() +} + +#[repr(C)] +#[derive(Clone, Copy)] +pub struct z_buffer_t { + _inner: usize, +} +impl_guarded_transmute!(noderefs Option<&ZBuf>, z_buffer_t); +impl From for Option<&'static ZBuf> { + fn from(value: z_buffer_t) -> Self { + unsafe { core::mem::transmute(value) } + } +} +impl From> for z_buffer_t { + fn from(value: Option<&ZBuf>) -> Self { + unsafe { core::mem::transmute(value) } + } +} +#[no_mangle] +pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { + unsafe { Some(core::mem::transmute::<_, &ZBuf>(buffer).clone()).into() } +} + +#[no_mangle] +pub extern "C" fn z_buffer_payload(buffer: z_buffer_t) -> z_bytes_t { + let Some(buffer): Option<&ZBuf> = buffer.into() else { + return z_bytes_null(); + }; + match buffer.contiguous() { + std::borrow::Cow::Borrowed(buffer) => buffer.into(), + std::borrow::Cow::Owned(_) => { + log::error!("A non-contiguous buffer reached user code, this is definitely a bug, please inform us at https://github.com/eclipse-zenoh/zenoh-c/issues/new"); + z_bytes_null() + } + } +} diff --git a/src/commons.rs b/src/commons.rs index 8ac21cb11..f96b9b09b 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -104,7 +104,7 @@ impl From> for z_timestamp_t { #[repr(C)] pub struct zc_owned_payload_t { pub payload: z_bytes_t, - pub _owner: [usize; 5], + pub _owner: z_owned_buffer_t, } impl Default for zc_owned_payload_t { fn default() -> Self { @@ -130,7 +130,9 @@ impl zc_owned_payload_t { } let start = std::mem::replace(&mut self.payload.start, std::ptr::null()); let len = std::mem::replace(&mut self.payload.len, 0); - let mut buf: ZBuf = unsafe { std::mem::transmute(self._owner) }; + let Some(mut buf) = self._owner.take() else { + return None; + }; { let mut slices = buf.zslices_mut(); let slice = slices.next().unwrap(); @@ -153,7 +155,7 @@ impl zc_owned_payload_t { if !z_bytes_check(&self.payload) { return None; } - unsafe { std::mem::transmute(&self._owner) } + self._owner.as_ref() } } impl Drop for zc_owned_payload_t { @@ -198,19 +200,6 @@ pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { pub struct z_qos_t(u8); impl_guarded_transmute!(QoS, z_qos_t); -impl_guarded_transmute!(z_qos_t, QoS); - -impl From for z_qos_t { - fn from(qos: QoS) -> Self { - qos.transmute() - } -} - -impl From for QoS { - fn from(qos: z_qos_t) -> QoS { - qos.transmute() - } -} /// Returns message priority. #[no_mangle] diff --git a/src/config.rs b/src/config.rs index 6e259f3b5..80e3a38f1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -15,7 +15,7 @@ use libc::{c_char, c_uint}; use std::ffi::CStr; use zenoh::config::{Config, ValidatedMap, WhatAmI}; -use crate::{impl_guarded_transmute, z_owned_str_t, z_str_null, GuardedTransmute}; +use crate::{impl_guarded_transmute, z_owned_str_t, z_str_null}; #[no_mangle] pub static Z_ROUTER: c_uint = WhatAmI::Router as c_uint; @@ -76,11 +76,6 @@ pub struct z_config_t(*const z_owned_config_t); pub struct z_owned_config_t(*mut ()); impl_guarded_transmute!(Option>, z_owned_config_t); -impl From>> for z_owned_config_t { - fn from(v: Option>) -> Self { - v.transmute() - } -} /// Returns a :c:type:`z_config_t` loaned from `s`. #[no_mangle] pub extern "C" fn z_config_loan(s: &z_owned_config_t) -> z_config_t { diff --git a/src/get.rs b/src/get.rs index 07bf0de65..41e3cf204 100644 --- a/src/get.rs +++ b/src/get.rs @@ -60,7 +60,7 @@ pub struct z_owned_reply_t([u64; 30]); #[repr(C, align(8))] pub struct z_owned_reply_t([u64; 19]); -impl_guarded_transmute!(ReplyInner, z_owned_reply_t); +impl_guarded_transmute!(noderefs ReplyInner, z_owned_reply_t); impl From for z_owned_reply_t { fn from(mut val: ReplyInner) -> Self { diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 04efe0c99..06784a8dc 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -62,27 +62,11 @@ pub struct z_owned_keyexpr_t([u32; 5]); impl_guarded_transmute!(Option>, z_owned_keyexpr_t); -impl From>> for z_owned_keyexpr_t { - fn from(val: Option>) -> Self { - val.transmute() - } -} impl From> for z_owned_keyexpr_t { fn from(val: KeyExpr<'static>) -> Self { Some(val).into() } } -impl Deref for z_owned_keyexpr_t { - type Target = Option>; - fn deref(&self) -> &Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl DerefMut for z_owned_keyexpr_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { std::mem::transmute(self) } - } -} impl z_owned_keyexpr_t { pub fn null() -> Self { None::.into() @@ -156,8 +140,8 @@ pub struct z_keyexpr_t([u64; 4]); #[repr(C, align(4))] pub struct z_keyexpr_t([u32; 5]); -impl_guarded_transmute!(Option>, z_keyexpr_t); -impl_guarded_transmute!(z_keyexpr_t, z_owned_keyexpr_t); +impl_guarded_transmute!(noderefs Option>, z_keyexpr_t); +impl_guarded_transmute!(noderefs z_keyexpr_t, z_owned_keyexpr_t); impl<'a> From> for z_keyexpr_t { fn from(val: KeyExpr<'a>) -> Self { diff --git a/src/lib.rs b/src/lib.rs index 718475444..19c22fa2e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -61,6 +61,26 @@ trait GuardedTransmute { #[macro_export] macro_rules! impl_guarded_transmute { ($src_type:ty, $dst_type:ty) => { + impl_guarded_transmute!(noderefs $src_type, $dst_type); + impl From<$src_type> for $dst_type { + fn from(value: $src_type) -> $dst_type { + unsafe { core::mem::transmute(value) } + } + } + impl core::ops::Deref for $dst_type { + type Target = $src_type; + fn deref(&self) -> &$src_type { + unsafe { core::mem::transmute(self) } + } + } + impl core::ops::DerefMut for $dst_type { + fn deref_mut(&mut self) -> &mut $src_type { + unsafe { core::mem::transmute(self) } + } + } + + }; + (noderefs $src_type:ty, $dst_type:ty) => { const _: () = { let src = std::mem::align_of::<$src_type>(); let dst = std::mem::align_of::<$dst_type>(); @@ -77,7 +97,7 @@ macro_rules! impl_guarded_transmute { }); } }; - impl $crate::GuardedTransmute<$dst_type> for $src_type { + impl $crate::GuardedTransmute<$dst_type> for $src_type { fn transmute(self) -> $dst_type { unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } } diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 5b96a904c..ee4c85959 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -20,7 +20,7 @@ use zenoh_util::core::SyncResolve; use crate::{ impl_guarded_transmute, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t, - GuardedTransmute, UninitializedKeyExprError, + UninitializedKeyExprError, }; /// Options passed to the :c:func:`ze_declare_publication_cache` function. @@ -53,8 +53,6 @@ pub extern "C" fn ze_publication_cache_options_default() -> ze_publication_cache } } -type PublicationCache = Option>>; - /// An owned zenoh publication_cache. /// /// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. @@ -68,26 +66,9 @@ type PublicationCache = Option>>; #[repr(C)] pub struct ze_owned_publication_cache_t([usize; 1]); +type PublicationCache = Option>>; impl_guarded_transmute!(PublicationCache, ze_owned_publication_cache_t); -impl From for ze_owned_publication_cache_t { - fn from(val: PublicationCache) -> Self { - val.transmute() - } -} - -impl AsRef for ze_owned_publication_cache_t { - fn as_ref(&self) -> &PublicationCache { - unsafe { std::mem::transmute(self) } - } -} - -impl AsMut for ze_owned_publication_cache_t { - fn as_mut(&mut self) -> &mut PublicationCache { - unsafe { std::mem::transmute(self) } - } -} - impl ze_owned_publication_cache_t { pub fn new(pub_cache: zenoh_ext::PublicationCache<'static>) -> Self { Some(Box::new(pub_cache)).into() @@ -187,7 +168,7 @@ pub extern "C" fn ze_publication_cache_check(pub_cache: &ze_owned_publication_ca pub extern "C" fn ze_undeclare_publication_cache( pub_cache: &mut ze_owned_publication_cache_t, ) -> i8 { - if let Some(p) = pub_cache.as_mut().take() { + if let Some(p) = pub_cache.take() { if let Err(e) = p.close().res_sync() { log::error!("{}", e); return e.errno().get(); diff --git a/src/publisher.rs b/src/publisher.rs index 42681093f..f49d8cd31 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -75,7 +75,7 @@ pub struct z_owned_publisher_t([u64; 7]); #[repr(C, align(4))] pub struct z_owned_publisher_t([u32; 8]); -impl_guarded_transmute!(Option>, z_owned_publisher_t); +impl_guarded_transmute!(noderefs Option>, z_owned_publisher_t); impl<'a> From>> for z_owned_publisher_t { fn from(val: Option) -> Self { @@ -387,7 +387,7 @@ pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_owned_keyex #[repr(C, align(8))] pub struct zcu_owned_matching_listener_t([u64; 4]); -impl_guarded_transmute!( +impl_guarded_transmute!(noderefs Option>, zcu_owned_matching_listener_t ); diff --git a/src/pull_subscriber.rs b/src/pull_subscriber.rs index 931b48d84..0eee4bc94 100644 --- a/src/pull_subscriber.rs +++ b/src/pull_subscriber.rs @@ -1,4 +1,3 @@ -use crate::GuardedTransmute; // // Copyright (c) 2017, 2022 ZettaScale Technology. // @@ -56,21 +55,9 @@ impl_guarded_transmute!(PullSubscriber, z_owned_pull_subscriber_t); #[allow(non_camel_case_types)] pub struct z_pull_subscriber_t<'a>(&'a z_owned_pull_subscriber_t); -impl From for z_owned_pull_subscriber_t { - fn from(val: PullSubscriber) -> Self { - val.transmute() - } -} - -impl AsRef for z_owned_pull_subscriber_t { - fn as_ref(&self) -> &PullSubscriber { - unsafe { std::mem::transmute(self) } - } -} - impl<'a> AsRef for z_pull_subscriber_t<'a> { fn as_ref(&self) -> &PullSubscriber { - self.0.as_ref() + self.0 } } diff --git a/src/queryable.rs b/src/queryable.rs index 5a7112afc..1906dc735 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -17,8 +17,7 @@ use crate::attachment::{ }; use crate::{ impl_guarded_transmute, z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, - z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, GuardedTransmute, - LOG_INVALID_SESSION, + z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, LOG_INVALID_SESSION, }; use libc::c_void; use std::ops::{Deref, DerefMut}; @@ -52,22 +51,6 @@ pub struct z_owned_queryable_t([u32; 4]); impl_guarded_transmute!(Queryable, z_owned_queryable_t); -impl From for z_owned_queryable_t { - fn from(val: Queryable) -> Self { - val.transmute() - } -} -impl AsRef for z_owned_queryable_t { - fn as_ref(&self) -> &Queryable { - unsafe { std::mem::transmute(self) } - } -} -impl AsMut for z_owned_queryable_t { - fn as_mut(&mut self) -> &mut Queryable { - unsafe { std::mem::transmute(self) } - } -} - impl z_owned_queryable_t { pub fn null() -> Self { None.into() @@ -263,7 +246,7 @@ pub extern "C" fn z_declare_queryable( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_undeclare_queryable(qable: &mut z_owned_queryable_t) -> i8 { - if let Some(qable) = qable.as_mut().take() { + if let Some(qable) = qable.take() { if let Err(e) = qable.undeclare().res_sync() { log::error!("{}", e); return e.errno().get(); diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index d407f9646..cdec44f0f 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -25,10 +25,10 @@ use crate::{ z_owned_closure_sample_t, z_query_consolidation_none, z_query_consolidation_t, z_query_target_default, z_query_target_t, z_reliability_t, z_sample_t, z_session_t, zcu_locality_default, zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, - GuardedTransmute, LOG_INVALID_SESSION, + LOG_INVALID_SESSION, }; -struct FetchingSubscriberWrapper { +pub struct FetchingSubscriberWrapper { fetching_subscriber: zenoh_ext::FetchingSubscriber<'static, ()>, session: z_session_t, } @@ -54,27 +54,9 @@ impl_guarded_transmute!(FetchingSubscriber, ze_owned_querying_subscriber_t); #[allow(non_camel_case_types)] pub struct ze_querying_subscriber_t<'a>(&'a ze_owned_querying_subscriber_t); -impl From for ze_owned_querying_subscriber_t { - fn from(val: FetchingSubscriber) -> Self { - val.transmute() - } -} - -impl AsRef for ze_owned_querying_subscriber_t { - fn as_ref(&self) -> &FetchingSubscriber { - unsafe { std::mem::transmute(self) } - } -} - impl<'a> AsRef for ze_querying_subscriber_t<'a> { fn as_ref(&self) -> &FetchingSubscriber { - self.0.as_ref() - } -} - -impl AsMut for ze_owned_querying_subscriber_t { - fn as_mut(&mut self) -> &mut FetchingSubscriber { - unsafe { std::mem::transmute(self) } + self.0 } } @@ -276,7 +258,7 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn ze_undeclare_querying_subscriber(sub: &mut ze_owned_querying_subscriber_t) -> i8 { - if let Some(s) = sub.as_mut().take() { + if let Some(s) = sub.take() { if let Err(e) = s.fetching_subscriber.close().res_sync() { log::warn!("{}", e); return e.errno().get(); diff --git a/src/session.rs b/src/session.rs index a4329fbf6..2caab85ea 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh team, // -use crate::{config::*, impl_guarded_transmute, zc_init_logger, GuardedTransmute}; +use crate::{config::*, impl_guarded_transmute, zc_init_logger}; use std::sync::{Arc, Weak}; use zenoh::prelude::sync::SyncResolve; use zenoh::Session; @@ -33,24 +33,6 @@ pub struct z_owned_session_t(usize); impl_guarded_transmute!(Option>, z_owned_session_t); -impl From>> for z_owned_session_t { - fn from(val: Option>) -> Self { - val.transmute() - } -} - -impl AsRef>> for z_owned_session_t { - fn as_ref(&self) -> &Option> { - unsafe { std::mem::transmute(self) } - } -} - -impl AsMut>> for z_owned_session_t { - fn as_mut(&mut self) -> &mut Option> { - unsafe { std::mem::transmute(self) } - } -} - impl AsRef>> for z_session_t { fn as_ref(&self) -> &Option> { unsafe { std::mem::transmute(self) } @@ -150,7 +132,7 @@ pub extern "C" fn z_session_check(session: &z_owned_session_t) -> bool { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_close(session: &mut z_owned_session_t) -> i8 { - let Some(s) = session.as_mut().take() else { + let Some(s) = session.take() else { return 0; }; let s = match Arc::try_unwrap(s) { diff --git a/src/subscriber.rs b/src/subscriber.rs index 910ec424b..b9488960a 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -18,7 +18,6 @@ use crate::keyexpr::*; use crate::session::*; use crate::z_closure_sample_call; use crate::z_owned_closure_sample_t; -use crate::GuardedTransmute; use crate::LOG_INVALID_SESSION; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; @@ -84,24 +83,6 @@ pub struct z_owned_subscriber_t([u32; 1]); impl_guarded_transmute!(Subscriber, z_owned_subscriber_t); -impl From for z_owned_subscriber_t { - fn from(sub: Subscriber) -> Self { - sub.transmute() - } -} - -impl AsRef for z_owned_subscriber_t { - fn as_ref(&self) -> &Subscriber { - unsafe { std::mem::transmute(self) } - } -} - -impl AsMut for z_owned_subscriber_t { - fn as_mut(&mut self) -> &mut Subscriber { - unsafe { std::mem::transmute(self) } - } -} - impl z_owned_subscriber_t { pub fn new(sub: zenoh::subscriber::Subscriber<'static, ()>) -> Self { Some(Box::new(sub)).into() @@ -125,7 +106,7 @@ pub struct z_subscriber_t(*const z_owned_subscriber_t); impl AsRef for z_subscriber_t { fn as_ref(&self) -> &Subscriber { - unsafe { (*self.0).as_ref() } + unsafe { &(*self.0) } } } @@ -240,7 +221,7 @@ pub extern "C" fn z_subscriber_keyexpr(subscriber: z_subscriber_t) -> z_owned_ke #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_undeclare_subscriber(sub: &mut z_owned_subscriber_t) -> i8 { - if let Some(s) = sub.as_mut().take() { + if let Some(s) = sub.take() { if let Err(e) = s.undeclare().res_sync() { log::warn!("{}", e); return e.errno().get(); From 8dbbf37dc2d8848d23ea0efcc572d656fd586168 Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Mon, 26 Feb 2024 15:02:36 +0100 Subject: [PATCH 02/75] privatize sample --- examples/z_get.c | 5 +- examples/z_get_liveliness.c | 2 +- examples/z_non_blocking_get.c | 5 +- examples/z_pong.c | 10 +- examples/z_pull.c | 7 +- examples/z_query_sub.c | 7 +- examples/z_sub.c | 7 +- examples/z_sub_attachment.c | 14 +- examples/z_sub_liveliness.c | 4 +- include/zenoh_commons.h | 163 +++++++++++--------- include/zenoh_macros.h | 3 - src/collections.rs | 54 +++++-- src/commons.rs | 194 ++++++++++-------------- src/get.rs | 2 +- src/lib.rs | 24 +++ src/liveliness.rs | 12 +- src/pull_subscriber.rs | 12 +- src/querying_subscriber.rs | 12 +- src/subscriber.rs | 12 +- tests/z_api_alignment_test.c | 4 +- tests/z_int_pub_cache_query_sub_test.c | 4 +- tests/z_int_pub_sub_attachment_test.c | 9 +- tests/z_int_pub_sub_test.c | 10 +- tests/z_int_queryable_attachment_test.c | 6 +- tests/z_int_queryable_test.c | 4 +- 25 files changed, 311 insertions(+), 275 deletions(-) diff --git a/examples/z_get.c b/examples/z_get.c index 272bef89a..853366210 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -65,8 +65,9 @@ int main(int argc, char **argv) { for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); - printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, sample.payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_bytes_t payload = z_sample_payload(&sample); + printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)payload.len, payload.start); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_get_liveliness.c b/examples/z_get_liveliness.c index c667cb03a..9a00f3ca3 100644 --- a/examples/z_get_liveliness.c +++ b/examples/z_get_liveliness.c @@ -53,7 +53,7 @@ int main(int argc, char **argv) { for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); printf(">> Alive token ('%s')\n", z_loan(keystr)); z_drop(z_move(keystr)); } else { diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index c0b02a274..a741d6071 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -58,8 +58,9 @@ int main(int argc, char **argv) { } if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); - printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, sample.payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_bytes_t payload = z_sample_payload(&sample); + printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)payload.len, payload.start); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_pong.c b/examples/z_pong.c index 8dbb2631e..4047ff3d2 100644 --- a/examples/z_pong.c +++ b/examples/z_pong.c @@ -6,7 +6,7 @@ void callback(const z_sample_t* sample, void* context) { z_publisher_t pub = z_loan(*(z_owned_publisher_t*)context); #ifdef ZENOH_C // The zc_owned_payload_t API is exclusive to zenoh-c, but allows avoiding some copies. - zc_owned_payload_t payload = zc_sample_payload_rcinc(sample); + z_owned_buffer_t payload = z_sample_owned_payload(sample); zc_publisher_put_owned(pub, z_move(payload), NULL); #else z_publisher_put(pub, sample->payload.start, sample->payload.len, NULL); @@ -21,15 +21,17 @@ void drop(void* context) { // valid. } struct args_t { - char* config_path; // -c - uint8_t help_requested; // -h + char* config_path; // -c + uint8_t help_requested; // -h }; struct args_t parse_args(int argc, char** argv); int main(int argc, char** argv) { struct args_t args = parse_args(argc, argv); if (args.help_requested) { - printf("-c (optional, string): the path to a configuration file for the session. If this option isn't passed, the default configuration will be used.\n"); + printf( + "-c (optional, string): the path to a configuration file for the session. If this option isn't passed, the " + "default configuration will be used.\n"); return 1; } z_owned_config_t config = args.config_path ? zc_config_from_file(args.config_path) : z_config_default(); diff --git a/examples/z_pull.c b/examples/z_pull.c index d7039e902..badbd6f44 100644 --- a/examples/z_pull.c +++ b/examples/z_pull.c @@ -23,9 +23,10 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(sample->kind), z_loan(keystr), - (int)sample->payload.len, sample->payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_bytes_t payload = z_sample_payload(sample); + printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + (int)payload.len, payload.start); z_drop(z_move(keystr)); } diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index 680cfd973..7653a6c77 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -23,9 +23,10 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(sample->kind), z_loan(keystr), - (int)sample->payload.len, sample->payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_bytes_t payload = z_sample_payload(sample); + printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + (int)payload.len, payload.start); z_drop(z_move(keystr)); } diff --git a/examples/z_sub.c b/examples/z_sub.c index ccfb32825..b52db8850 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -23,9 +23,10 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(sample->kind), z_loan(keystr), - (int)sample->payload.len, sample->payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_bytes_t payload = z_sample_payload(sample); + printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + (int)payload.len, payload.start); z_drop(z_move(keystr)); } diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index 26cc95ed8..c3d22e39f 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -29,17 +29,19 @@ int8_t attachment_reader(z_bytes_t key, z_bytes_t val, void *ctx) { } void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(sample->kind), z_loan(keystr), - (int)sample->payload.len, sample->payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_bytes_t payload = z_sample_payload(sample); + printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + (int)payload.len, payload.start); + z_attachment_t attachment = z_sample_attachment(sample); // checks if attachment exists - if (z_check(sample->attachment)) { + if (z_check(attachment)) { // reads full attachment - z_attachment_iterate(sample->attachment, attachment_reader, NULL); + z_attachment_iterate(attachment, attachment_reader, NULL); // reads particular attachment item - z_bytes_t index = z_attachment_get(sample->attachment, z_bytes_from_str("index")); + z_bytes_t index = z_attachment_get(attachment, z_bytes_from_str("index")); if (z_check(index)) { printf(" message number: %.*s\n", (int)index.len, index.start); } diff --git a/examples/z_sub_liveliness.c b/examples/z_sub_liveliness.c index f67ac5a68..67c87001a 100644 --- a/examples/z_sub_liveliness.c +++ b/examples/z_sub_liveliness.c @@ -21,8 +21,8 @@ #include "zenoh.h" void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - switch (sample->kind) { + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + switch (z_sample_kind(sample)) { case Z_SAMPLE_KIND_PUT: printf(">> [LivelinessSubscriber] New alive token ('%s')\n", z_loan(keystr)); break; diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index c7d46f932..1d56fe95f 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -196,7 +196,7 @@ typedef struct z_owned_buffer_t { size_t _inner[5]; } z_owned_buffer_t; typedef struct z_buffer_t { - size_t _inner; + const void *_inner; } z_buffer_t; /** * A map of maybe-owned vector of bytes to owned vector of bytes. @@ -368,52 +368,6 @@ typedef struct z_owned_closure_reply_t { void (*call)(struct z_owned_reply_t*, void*); void (*drop)(void*); } z_owned_closure_reply_t; -/** - * A loaned key expression. - * - * Key expressions can identify a single key or a set of keys. - * - * Examples : - * - ``"key/expression"``. - * - ``"key/ex*"``. - * - * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, - * both for local processing and network-wise. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_keyexpr_t { - uint64_t _0[4]; -} z_keyexpr_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_keyexpr_t { - uint32_t _0[5]; -} z_keyexpr_t; -#endif -/** - * The encoding of a payload, in a MIME-like format. - * - * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. - * - * Members: - * z_encoding_prefix_t prefix: The integer prefix of this encoding. - * z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. - */ -typedef struct z_encoding_t { - enum z_encoding_prefix_t prefix; - struct z_bytes_t suffix; -} z_encoding_t; -typedef struct z_timestamp_t { - uint64_t time; - struct z_id_t id; -} z_timestamp_t; -/** - * QoS settings of zenoh message. - * - */ -typedef struct z_qos_t { - uint8_t _0; -} z_qos_t; /** * A data sample. * @@ -428,14 +382,7 @@ typedef struct z_qos_t { * z_attachment_t attachment: The attachment of this data sample. */ typedef struct z_sample_t { - struct z_keyexpr_t keyexpr; - struct z_bytes_t payload; - struct z_encoding_t encoding; - const void *_zc_buf; - enum z_sample_kind_t kind; - struct z_timestamp_t timestamp; - struct z_qos_t qos; - struct z_attachment_t attachment; + const void *_inner; } z_sample_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. @@ -550,6 +497,28 @@ typedef struct ALIGN(4) z_owned_keyexpr_t { uint32_t _0[5]; } z_owned_keyexpr_t; #endif +/** + * A loaned key expression. + * + * Key expressions can identify a single key or a set of keys. + * + * Examples : + * - ``"key/expression"``. + * - ``"key/ex*"``. + * + * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, + * both for local processing and network-wise. + */ +#if !defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_keyexpr_t { + uint64_t _0[4]; +} z_keyexpr_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(4) z_keyexpr_t { + uint32_t _0[5]; +} z_keyexpr_t; +#endif /** * An owned zenoh publisher. * @@ -618,6 +587,19 @@ typedef struct z_delete_options_t { enum z_congestion_control_t congestion_control; enum z_priority_t priority; } z_delete_options_t; +/** + * The encoding of a payload, in a MIME-like format. + * + * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. + * + * Members: + * z_encoding_prefix_t prefix: The integer prefix of this encoding. + * z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. + */ +typedef struct z_encoding_t { + uint64_t prefix; + struct z_bytes_t suffix; +} z_encoding_t; /** * An owned payload encoding. * @@ -632,7 +614,7 @@ typedef struct z_delete_options_t { * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. */ typedef struct z_owned_encoding_t { - enum z_encoding_prefix_t prefix; + uint64_t prefix; struct z_bytes_t suffix; bool _dropped; } z_owned_encoding_t; @@ -746,6 +728,13 @@ typedef struct z_put_options_t { enum z_priority_t priority; struct z_attachment_t attachment; } z_put_options_t; +/** + * QoS settings of zenoh message. + * + */ +typedef struct z_qos_t { + uint8_t _0; +} z_qos_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -808,6 +797,10 @@ typedef struct z_owned_reply_channel_t { struct z_owned_closure_reply_t send; struct z_owned_reply_channel_closure_t recv; } z_owned_reply_channel_t; +typedef struct z_timestamp_t { + uint64_t time; + struct z_id_t id; +} z_timestamp_t; typedef struct z_owned_scouting_config_t { struct z_owned_config_t _config; unsigned long zc_timeout_ms; @@ -869,10 +862,7 @@ typedef struct zc_owned_liveliness_get_options_t { * Should this invariant be broken when the payload is passed to one of zenoh's `put_owned` * functions, then the operation will fail (but the passed value will still be consumed). */ -typedef struct zc_owned_payload_t { - struct z_bytes_t payload; - struct z_owned_buffer_t _owner; -} zc_owned_payload_t; +typedef struct z_owned_buffer_t zc_owned_payload_t; typedef struct zc_owned_shmbuf_t { size_t _0[9]; } zc_owned_shmbuf_t; @@ -1982,6 +1972,41 @@ ZENOHC_API struct z_owned_reply_t z_reply_null(void); */ ZENOHC_API struct z_sample_t z_reply_ok(const struct z_owned_reply_t *reply); +/** + * The sample's attachment. + * + * `sample` is aliased by the return value. + */ +ZENOHC_API struct z_attachment_t z_sample_attachment(const struct z_sample_t *sample); +/** + * The encoding of the payload. + */ +ZENOHC_API struct z_encoding_t z_sample_encoding(const struct z_sample_t *sample); +/** + * The Key Expression of the sample. + * + * `sample` is aliased by its return value. + */ +ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); +/** + * The sample's kind (put or delete). + */ +ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); +/** + * Returns the sample's payload after incrementing its internal reference count. + * + * Note that other samples may have received the same buffer, meaning that mutating this buffer may + * affect the samples received by other subscribers. + */ +ZENOHC_API struct z_owned_buffer_t z_sample_owned_payload(const struct z_sample_t *sample); +/** + * The sample's data, the return value aliases the sample. + * + * If you need ownership of the buffer, you may use `z_sample_owned_payload`. + */ +ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); +ZENOHC_API struct z_qos_t z_sample_qos(const struct z_sample_t *sample); +ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); /** * Scout for routers and/or peers. * @@ -2277,19 +2302,19 @@ ZENOHC_API void zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t /** * Returns `false` if `payload` is the gravestone value. */ -ZENOHC_API bool zc_payload_check(const struct zc_owned_payload_t *payload); +ZENOHC_API bool zc_payload_check(const zc_owned_payload_t *payload); /** * Decrements `payload`'s backing refcount, releasing the memory if appropriate. */ -ZENOHC_API void zc_payload_drop(struct zc_owned_payload_t *payload); +ZENOHC_API void zc_payload_drop(zc_owned_payload_t *payload); /** * Constructs `zc_owned_payload_t`'s gravestone value. */ -ZENOHC_API struct zc_owned_payload_t zc_payload_null(void); +ZENOHC_API zc_owned_payload_t zc_payload_null(void); /** * Clones the `payload` by incrementing its reference counter. */ -ZENOHC_API struct zc_owned_payload_t zc_payload_rcinc(const struct zc_owned_payload_t *payload); +ZENOHC_API zc_owned_payload_t zc_payload_rcinc(const zc_owned_payload_t *payload); /** * Sends a `PUT` message onto the publisher's key expression, transfering the buffer ownership. * @@ -2309,7 +2334,7 @@ ZENOHC_API struct zc_owned_payload_t zc_payload_rcinc(const struct zc_owned_payl */ ZENOHC_API int8_t zc_publisher_put_owned(struct z_publisher_t publisher, - struct zc_owned_payload_t *payload, + zc_owned_payload_t *payload, const struct z_publisher_put_options_t *options); /** * Put data, transfering the buffer ownership. @@ -2331,7 +2356,7 @@ int8_t zc_publisher_put_owned(struct z_publisher_t publisher, ZENOHC_API int8_t zc_put_owned(struct z_session_t session, struct z_keyexpr_t keyexpr, - struct zc_owned_payload_t *payload, + zc_owned_payload_t *payload, const struct z_put_options_t *opts); /** * Creates a new blocking fifo channel, returned as a pair of closures. @@ -2385,10 +2410,6 @@ struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); */ ZENOHC_API struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); -/** - * Clones the sample's payload by incrementing its backing refcount (this doesn't imply any copies). - */ -ZENOHC_API struct zc_owned_payload_t zc_sample_payload_rcinc(const struct z_sample_t *sample); /** * Increments the session's reference count, returning a new owning handle. */ @@ -2443,7 +2464,7 @@ ZENOHC_API void zc_shmbuf_drop(struct zc_owned_shmbuf_t *buf); /** * Constructs an owned payload from an owned SHM buffer. */ -ZENOHC_API struct zc_owned_payload_t zc_shmbuf_into_payload(struct zc_owned_shmbuf_t *buf); +ZENOHC_API zc_owned_payload_t zc_shmbuf_into_payload(struct zc_owned_shmbuf_t *buf); /** * Returns the length of the SHM buffer. * diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 494d01fb9..dba68f29a 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -44,7 +44,6 @@ z_owned_query_channel_t * : z_query_channel_drop, \ z_owned_bytes_map_t * : z_bytes_map_drop, \ z_owned_buffer_t * : z_buffer_drop, \ - zc_owned_payload_t * : zc_payload_drop, \ zc_owned_shmbuf_t * : zc_shmbuf_drop, \ zc_owned_shm_manager_t * : zc_shm_manager_drop, \ zc_owned_liveliness_token_t * : zc_liveliness_undeclare_token, \ @@ -77,7 +76,6 @@ z_owned_bytes_map_t * : z_bytes_map_null, \ z_owned_buffer_t * : z_buffer_null, \ z_attachment_t * : z_attachment_null, \ - zc_owned_payload_t * : zc_payload_null, \ zc_owned_shmbuf_t * : zc_shmbuf_null, \ zc_owned_shm_manager_t * : zc_shm_manager_null, \ ze_owned_publication_cache_t * : ze_publication_cache_null, \ @@ -103,7 +101,6 @@ z_owned_bytes_map_t : z_bytes_map_check, \ z_owned_buffer_t : z_buffer_check, \ z_attachment_t : z_attachment_check, \ - zc_owned_payload_t : zc_payload_check, \ zc_owned_shmbuf_t : zc_shmbuf_check, \ zc_owned_shm_manager_t : zc_shm_manager_check, \ zc_owned_liveliness_token_t : zc_liveliness_token_check, \ diff --git a/src/collections.rs b/src/collections.rs index 9ac7831c0..7f34a8fdd 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -60,7 +60,7 @@ pub extern "C" fn z_bytes_check(b: &z_bytes_t) -> bool { /// Returns the gravestone value for `z_bytes_t` #[no_mangle] -pub extern "C" fn z_bytes_null() -> z_bytes_t { +pub const extern "C" fn z_bytes_null() -> z_bytes_t { z_bytes_t { len: 0, start: core::ptr::null(), @@ -167,11 +167,45 @@ impl From<&[u8]> for z_bytes_t { pub struct z_owned_buffer_t { _inner: [usize; 5], } -impl_guarded_transmute!(Option, z_owned_buffer_t); +impl_guarded_transmute!(noderefs Option, z_owned_buffer_t); +impl Default for z_owned_buffer_t { + fn default() -> Self { + z_buffer_null() + } +} +impl From for z_owned_buffer_t { + fn from(value: ZBuf) -> Self { + let value = match value.contiguous() { + std::borrow::Cow::Borrowed(_) => value, + std::borrow::Cow::Owned(value) => value.into(), + }; + unsafe { core::mem::transmute(Some(value)) } + } +} +impl From> for z_owned_buffer_t { + fn from(value: Option) -> Self { + match value { + Some(value) => value.into(), + None => z_buffer_null(), + } + } +} +impl core::ops::Deref for z_owned_buffer_t { + type Target = Option; + + fn deref(&self) -> &Self::Target { + unsafe { core::mem::transmute(self) } + } +} +impl core::ops::DerefMut for z_owned_buffer_t { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { core::mem::transmute(self) } + } +} #[no_mangle] pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { - None.into() + unsafe { core::mem::transmute(None::) } } #[no_mangle] pub extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { @@ -189,20 +223,16 @@ pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { #[repr(C)] #[derive(Clone, Copy)] -pub struct z_buffer_t { - _inner: usize, +pub struct z_buffer_t<'a> { + _inner: &'a (), } -impl_guarded_transmute!(noderefs Option<&ZBuf>, z_buffer_t); -impl From for Option<&'static ZBuf> { +impl_guarded_transmute!(Option<&'a ZBuf>, z_buffer_t<'a>, 'a); +impl<'a> From> for Option<&'a ZBuf> { fn from(value: z_buffer_t) -> Self { unsafe { core::mem::transmute(value) } } } -impl From> for z_buffer_t { - fn from(value: Option<&ZBuf>) -> Self { - unsafe { core::mem::transmute(value) } - } -} + #[no_mangle] pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { unsafe { Some(core::mem::transmute::<_, &ZBuf>(buffer).clone()).into() } diff --git a/src/commons.rs b/src/commons.rs index f96b9b09b..6ca6e19b4 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -20,7 +20,6 @@ use crate::z_priority_t; use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; -use zenoh::buffers::ZBuf; use zenoh::prelude::SampleKind; use zenoh::prelude::SplitBuffer; use zenoh::query::ReplyKeyExpr; @@ -101,97 +100,27 @@ impl From> for z_timestamp_t { /// Should this invariant be broken when the payload is passed to one of zenoh's `put_owned` /// functions, then the operation will fail (but the passed value will still be consumed). #[allow(non_camel_case_types)] -#[repr(C)] -pub struct zc_owned_payload_t { - pub payload: z_bytes_t, - pub _owner: z_owned_buffer_t, -} -impl Default for zc_owned_payload_t { - fn default() -> Self { - zc_payload_null() - } -} -impl TryFrom for zc_owned_payload_t { - type Error = (); - fn try_from(buf: ZBuf) -> Result { - let std::borrow::Cow::Borrowed(payload) = buf.contiguous() else { - return Err(()); - }; - Ok(Self { - payload: payload.into(), - _owner: unsafe { std::mem::transmute(buf) }, - }) - } -} -impl zc_owned_payload_t { - pub fn take(&mut self) -> Option { - if !z_bytes_check(&self.payload) { - return None; - } - let start = std::mem::replace(&mut self.payload.start, std::ptr::null()); - let len = std::mem::replace(&mut self.payload.len, 0); - let Some(mut buf) = self._owner.take() else { - return None; - }; - { - let mut slices = buf.zslices_mut(); - let slice = slices.next().unwrap(); - assert!( - slices.next().is_none(), - "A multi-slice buffer reached zenoh-c, which is definitely a bug, please report it." - ); - let start_offset = unsafe { start.offset_from(slice.as_slice().as_ptr()) }; - let Ok(start_offset) = start_offset.try_into() else { - return None; - }; - *slice = match slice.subslice(start_offset, start_offset + len) { - Some(s) => s, - None => return None, - }; - } - Some(buf) - } - fn owner(&self) -> Option<&ZBuf> { - if !z_bytes_check(&self.payload) { - return None; - } - self._owner.as_ref() - } -} -impl Drop for zc_owned_payload_t { - fn drop(&mut self) { - self.take(); - } -} +pub type zc_owned_payload_t = z_owned_buffer_t; /// Clones the `payload` by incrementing its reference counter. #[no_mangle] pub extern "C" fn zc_payload_rcinc(payload: &zc_owned_payload_t) -> zc_owned_payload_t { - match payload.owner() { - None => Default::default(), - Some(payload) => payload.clone().try_into().unwrap_or_default(), - } + z_buffer_clone(z_buffer_loan(payload)) } /// Returns `false` if `payload` is the gravestone value. #[no_mangle] pub extern "C" fn zc_payload_check(payload: &zc_owned_payload_t) -> bool { - !payload.payload.start.is_null() + z_buffer_check(payload) } /// Decrements `payload`'s backing refcount, releasing the memory if appropriate. #[no_mangle] pub extern "C" fn zc_payload_drop(payload: &mut zc_owned_payload_t) { - unsafe { std::ptr::replace(payload, zc_payload_null()) }; + z_buffer_drop(payload) } /// Constructs `zc_owned_payload_t`'s gravestone value. #[no_mangle] pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { - zc_owned_payload_t { - payload: z_bytes_t { - len: 0, - start: std::ptr::null(), - }, - _owner: unsafe { core::mem::MaybeUninit::zeroed().assume_init() }, - } + z_buffer_null() } /// QoS settings of zenoh message. @@ -235,50 +164,77 @@ pub extern "C" fn z_qos_default() -> z_qos_t { /// z_attachment_t attachment: The attachment of this data sample. #[repr(C)] pub struct z_sample_t<'a> { - pub keyexpr: z_keyexpr_t, - pub payload: z_bytes_t, - pub encoding: z_encoding_t, - pub _zc_buf: &'a c_void, - pub kind: z_sample_kind_t, - pub timestamp: z_timestamp_t, - pub qos: z_qos_t, - pub attachment: z_attachment_t, + _inner: &'a (), +} +impl<'a> core::ops::Deref for z_sample_t<'a> { + type Target = Sample; + fn deref(&self) -> &Self::Target { + unsafe { core::mem::transmute::<&(), &Sample>(self._inner) } + } } impl<'a> z_sample_t<'a> { - pub fn new(sample: &'a Sample, owner: &'a ZBuf) -> Self { - let std::borrow::Cow::Borrowed(payload) = owner.contiguous() else { + pub fn new(sample: &'a Sample) -> Self { + if !sample.value.payload.zslices().count() <= 1 { panic!("Attempted to construct z_sample_t from discontiguous buffer, this is definitely a bug in zenoh-c, please report it.") }; z_sample_t { - keyexpr: (&sample.key_expr).into(), - payload: z_bytes_t::from(payload), - encoding: (&sample.encoding).into(), - _zc_buf: unsafe { std::mem::transmute(owner) }, - kind: sample.kind.into(), - timestamp: sample.timestamp.as_ref().into(), - qos: sample.qos.into(), - attachment: match &sample.attachment { - Some(attachment) => z_attachment_t { - data: attachment as *const _ as *mut c_void, - iteration_driver: Some(attachment_iteration_driver), - }, - None => z_attachment_null(), - }, + _inner: unsafe { core::mem::transmute(sample) }, } } } -/// Clones the sample's payload by incrementing its backing refcount (this doesn't imply any copies). +/// The Key Expression of the sample. +/// +/// `sample` is aliased by its return value. #[no_mangle] -pub extern "C" fn zc_sample_payload_rcinc(sample: Option<&z_sample_t>) -> zc_owned_payload_t { - let Some(sample) = sample else { - return zc_payload_null(); - }; - let buf = unsafe { std::mem::transmute::<_, &ZBuf>(sample._zc_buf).clone() }; - zc_owned_payload_t { - payload: sample.payload, - _owner: unsafe { std::mem::transmute(buf) }, +pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { + (&sample.key_expr).into() +} +/// The encoding of the payload. +#[no_mangle] +pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { + (&sample.encoding).into() +} +/// The sample's data, the return value aliases the sample. +/// +/// If you need ownership of the buffer, you may use `z_sample_owned_payload`. +#[no_mangle] +pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_bytes_t { + sample.payload.slices().next().unwrap_or(b"").into() +} +/// Returns the sample's payload after incrementing its internal reference count. +/// +/// Note that other samples may have received the same buffer, meaning that mutating this buffer may +/// affect the samples received by other subscribers. +#[no_mangle] +pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> z_owned_buffer_t { + sample.payload.clone().into() +} +/// The sample's kind (put or delete). +#[no_mangle] +pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { + sample.kind.into() +} +#[no_mangle] +pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { + sample.timestamp.as_ref().into() +} +#[no_mangle] +pub extern "C" fn z_sample_qos(sample: &z_sample_t) -> z_qos_t { + sample.qos.into() +} +/// The sample's attachment. +/// +/// `sample` is aliased by the return value. +#[no_mangle] +pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { + match &sample.attachment { + Some(attachment) => z_attachment_t { + data: attachment as *const _ as *mut c_void, + iteration_driver: Some(attachment_iteration_driver), + }, + None => z_attachment_null(), } } @@ -425,21 +381,24 @@ impl From for z_encoding_prefix_t { #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct z_encoding_t { - pub prefix: z_encoding_prefix_t, + pub prefix: u64, pub suffix: z_bytes_t, } impl From for zenoh_protocol::core::Encoding { fn from(enc: z_encoding_t) -> Self { if enc.suffix.len == 0 { - zenoh_protocol::core::Encoding::Exact(enc.prefix.into()) + zenoh_protocol::core::Encoding::Exact((enc.prefix as u8).try_into().unwrap()) } else { let suffix = unsafe { let slice: &'static [u8] = std::slice::from_raw_parts(enc.suffix.start, enc.suffix.len); std::str::from_utf8_unchecked(slice) }; - zenoh_protocol::core::Encoding::WithSuffix(enc.prefix.into(), suffix.into()) + zenoh_protocol::core::Encoding::WithSuffix( + (enc.prefix as u8).try_into().unwrap(), + suffix.into(), + ) } } } @@ -448,7 +407,7 @@ impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { fn from(val: &zenoh_protocol::core::Encoding) -> Self { let suffix = val.suffix(); z_encoding_t { - prefix: (*val.prefix()).into(), + prefix: u8::from(*val.prefix()) as u64, suffix: z_bytes_t { start: suffix.as_ptr(), len: suffix.len(), @@ -470,7 +429,7 @@ impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. #[repr(C)] pub struct z_owned_encoding_t { - pub prefix: z_encoding_prefix_t, + pub prefix: u64, pub suffix: z_bytes_t, pub _dropped: bool, } @@ -478,7 +437,7 @@ pub struct z_owned_encoding_t { impl z_owned_encoding_t { pub fn null() -> Self { z_owned_encoding_t { - prefix: z_encoding_prefix_t::Empty, + prefix: 0, suffix: z_bytes_t::default(), _dropped: true, } @@ -506,7 +465,10 @@ pub unsafe extern "C" fn z_encoding( len: libc::strlen(suffix), } }; - z_encoding_t { prefix, suffix } + z_encoding_t { + prefix: prefix as u64, + suffix, + } } /// Constructs a default :c:type:`z_encoding_t`. diff --git a/src/get.rs b/src/get.rs index 41e3cf204..423810a4f 100644 --- a/src/get.rs +++ b/src/get.rs @@ -108,7 +108,7 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { if let Cow::Owned(_) = sample.payload.contiguous() { unreachable!("z_reply_ok found a payload that wasn't contiguous by the time it was reached, which breaks some crate assertions. This is definitely a bug with zenoh, please contact us.") } - z_sample_t::new(sample, &sample.payload) + z_sample_t::new(sample) } else { panic!("Assertion failed: tried to treat `z_owned_reply_t` as Ok despite that not being the case") } diff --git a/src/lib.rs b/src/lib.rs index 19c22fa2e..9c01e4aa2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,6 +103,30 @@ macro_rules! impl_guarded_transmute { } } }; + ($src_type:ty, $dst_type:ty, $($gen: tt)*) => { + impl<$($gen)*> $crate::GuardedTransmute<$dst_type> for $src_type { + fn transmute(self) -> $dst_type { + unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } + } + } + impl<$($gen)*> From<$src_type> for $dst_type { + fn from(value: $src_type) -> $dst_type { + unsafe { core::mem::transmute(value) } + } + } + impl<$($gen)*> core::ops::Deref for $dst_type { + type Target = $src_type; + fn deref(&self) -> &$src_type { + unsafe { core::mem::transmute(self) } + } + } + impl<$($gen)*> core::ops::DerefMut for $dst_type { + fn deref_mut(&mut self) -> &mut $src_type { + unsafe { core::mem::transmute(self) } + } + } + + }; } pub(crate) const LOG_INVALID_SESSION: &str = "Invalid session"; diff --git a/src/liveliness.rs b/src/liveliness.rs index 040205892..69ee2d2e2 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -176,13 +176,11 @@ pub extern "C" fn zc_liveliness_declare_subscriber( match session .liveliness() .declare_subscriber(key) - .callback(move |sample| { - let payload = sample.payload.contiguous(); - let owner = match payload { - std::borrow::Cow::Owned(v) => zenoh::buffers::ZBuf::from(v), - _ => sample.payload.clone(), - }; - let sample = z_sample_t::new(&sample, &owner); + .callback(move |mut sample| { + if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { + sample.payload = v.into(); + } + let sample = z_sample_t::new(&sample); z_closure_sample_call(&callback, &sample) }) .res() diff --git a/src/pull_subscriber.rs b/src/pull_subscriber.rs index 0eee4bc94..247484cb1 100644 --- a/src/pull_subscriber.rs +++ b/src/pull_subscriber.rs @@ -149,13 +149,11 @@ pub extern "C" fn z_declare_pull_subscriber( Some(s) => { let mut res = s .declare_subscriber(keyexpr) - .callback(move |sample| { - let payload = sample.payload.contiguous(); - let owner = match payload { - std::borrow::Cow::Owned(v) => zenoh::buffers::ZBuf::from(v), - _ => sample.payload.clone(), - }; - let sample = z_sample_t::new(&sample, &owner); + .callback(move |mut sample| { + if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { + sample.payload = v.into(); + } + let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }) .pull_mode(); diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index cdec44f0f..a4681b4e9 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -185,13 +185,11 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( } } match sub - .callback(move |sample| { - let payload = sample.payload.contiguous(); - let owner = match payload { - std::borrow::Cow::Owned(v) => zenoh::buffers::ZBuf::from(v), - _ => sample.payload.clone(), - }; - let sample = z_sample_t::new(&sample, &owner); + .callback(move |mut sample| { + if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { + sample.payload = v.into(); + } + let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }) .res() diff --git a/src/subscriber.rs b/src/subscriber.rs index b9488960a..7d15e740a 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -179,13 +179,11 @@ pub extern "C" fn z_declare_subscriber( match session.upgrade() { Some(s) => { - let mut res = s.declare_subscriber(keyexpr).callback(move |sample| { - let payload = sample.payload.contiguous(); - let owner = match payload { - std::borrow::Cow::Owned(v) => zenoh::buffers::ZBuf::from(v), - _ => sample.payload.clone(), - }; - let sample = z_sample_t::new(&sample, &owner); + let mut res = s.declare_subscriber(keyexpr).callback(move |mut sample| { + if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { + sample.payload = v.into(); + } + let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }); if let Some(opts) = opts { diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index ee63017c2..8dcff3317 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -76,7 +76,7 @@ void reply_handler(z_owned_reply_t *reply, void *arg) { if (z_reply_is_ok(reply)) { z_sample_t sample = z_reply_ok(reply); - z_owned_str_t k_str = z_keyexpr_to_string(sample.keyexpr); + z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); #ifdef ZENOH_PICO if (k_str == NULL) { k_str = zp_keyexpr_resolve(*(z_session_t *)arg, sample.keyexpr); @@ -95,7 +95,7 @@ volatile unsigned int datas = 0; void data_handler(const z_sample_t *sample, void *arg) { datas++; - z_owned_str_t k_str = z_keyexpr_to_string(sample->keyexpr); + z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(sample)); #ifdef ZENOH_PICO if (k_str == NULL) { k_str = zp_keyexpr_resolve(*(z_session_t *)arg, sample->keyexpr); diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index 6674aec55..7495939f2 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -85,14 +85,14 @@ int run_publisher() { void data_handler(const z_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); } z_drop(z_move(keystr)); - ASSERT_STR_BYTES_EQUAL(values[val_num], sample->payload); + ASSERT_STR_BYTES_EQUAL(values[val_num], z_sample_payload(sample)); printf("data_handler: %i\n", val_num); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index 75ae88547..554d1fd57 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -66,22 +66,23 @@ int run_publisher() { void data_handler(const z_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); } z_drop(z_move(keystr)); - if (strncmp(values[val_num], (const char *)sample->payload.start, (int)sample->payload.len)) { + z_bytes_t payload = z_sample_payload(sample); + if (strncmp(values[val_num], (const char *)payload.start, (int)payload.len)) { perror("Unexpected value received"); exit(-1); } - z_bytes_t v_const = z_attachment_get(sample->attachment, z_bytes_from_str(K_CONST)); + z_bytes_t v_const = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); - z_bytes_t v_var = z_attachment_get(sample->attachment, z_bytes_from_str(K_VAR)); + z_bytes_t v_var = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_VAR)); ASSERT_STR_BYTES_EQUAL(values[val_num], v_var); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index cf005a80f..6e48fef5a 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -59,21 +59,21 @@ int run_publisher() { void data_handler(const z_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); } z_drop(z_move(keystr)); - if (strncmp(values[val_num], (const char *)sample->payload.start, (int)sample->payload.len)) { + z_bytes_t payload = z_sample_payload(sample); + if (strncmp(values[val_num], (const char *)payload.start, (int)payload.len)) { perror("Unexpected value received"); exit(-1); } - if (z_qos_get_congestion_control(sample->qos) != Z_CONGESTION_CONTROL_BLOCK - || z_qos_get_priority(sample->qos) != Z_PRIORITY_DATA - ) { + if (z_qos_get_congestion_control(z_sample_qos(sample)) != Z_CONGESTION_CONTROL_BLOCK || + z_qos_get_priority(z_sample_qos(sample)) != Z_PRIORITY_DATA) { perror("Unexpected QoS values"); exit(-1); } diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index b2f2a7ab8..836f8d988 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -109,11 +109,11 @@ int run_get() { assert(z_reply_is_ok(&reply)); z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - ASSERT_STR_BYTES_EQUAL(values[val_num], sample.payload); + ASSERT_STR_BYTES_EQUAL(values[val_num], z_sample_payload(&sample)); - z_bytes_t v_const = z_attachment_get(sample.attachment, z_bytes_from_str(K_CONST)); + z_bytes_t v_const = z_attachment_get(z_sample_attachment(&sample), z_bytes_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); z_drop(z_move(keystr)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index 4244af2c7..67c690f8e 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -85,9 +85,9 @@ int run_get() { assert(z_reply_is_ok(&reply)); z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); + z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - ASSERT_STR_BYTES_EQUAL(values[val_num], sample.payload); + ASSERT_STR_BYTES_EQUAL(values[val_num], z_sample_payload(&sample)); z_drop(z_move(keystr)); } From 3551d3843f2980556e9edc54db17cf4b3fa03013 Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Thu, 29 Feb 2024 11:40:39 +0100 Subject: [PATCH 03/75] add support for owned samples --- Cargo.toml | 2 +- include/zenoh_commons.h | 34 ++++++++++++++++++++++++++++++++ src/commons.rs | 43 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 52deaa71c..638c6422d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ serde_yaml = "0.9.19" [lib] path="src/lib.rs" -name = "zenohc" +name = "zenohcd" crate-type = ["cdylib", "staticlib"] doctest = false diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 1d56fe95f..3fa477cd3 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -863,6 +863,12 @@ typedef struct zc_owned_liveliness_get_options_t { * functions, then the operation will fail (but the passed value will still be consumed). */ typedef struct z_owned_buffer_t zc_owned_payload_t; +typedef struct zc_owned_sample_t { + struct z_owned_keyexpr_t _0; + struct z_owned_buffer_t _1; + struct z_owned_buffer_t _2; + size_t _3[12]; +} zc_owned_sample_t; typedef struct zc_owned_shmbuf_t { size_t _0[9]; } zc_owned_shmbuf_t; @@ -2005,7 +2011,13 @@ ZENOHC_API struct z_owned_buffer_t z_sample_owned_payload(const struct z_sample_ * If you need ownership of the buffer, you may use `z_sample_owned_payload`. */ ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); +/** + * The qos with which the sample was received. + */ ZENOHC_API struct z_qos_t z_sample_qos(const struct z_sample_t *sample); +/** + * The samples timestamp + */ ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); /** * Scout for routers and/or peers. @@ -2410,6 +2422,28 @@ struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); */ ZENOHC_API struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); +/** + * Returns `true` if `sample` is valid. + * + * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed + * unless the value has been dropped already. + */ +ZENOHC_API +bool zc_sample_check(const struct zc_owned_sample_t *sample); +/** + * Clone a sample in the cheapest way available. + */ +ZENOHC_API struct zc_owned_sample_t zc_sample_clone(const struct z_sample_t *sample); +/** + * Destroy the sample. + */ +ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); +/** + * Borrow the sample, allowing calling its accessor methods. + * + * Calling this function using a dropped sample is undefined behaviour. + */ +ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); /** * Increments the session's reference count, returning a new owning handle. */ diff --git a/src/commons.rs b/src/commons.rs index 6ca6e19b4..085a0df5a 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -12,6 +12,8 @@ // ZettaScale Zenoh team, // +use std::ops::Deref; + use crate::collections::*; use crate::keyexpr::*; use crate::z_congestion_control_t; @@ -216,10 +218,12 @@ pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> z_owned_buffer_ pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { sample.kind.into() } +/// The samples timestamp #[no_mangle] pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { sample.timestamp.as_ref().into() } +/// The qos with which the sample was received. #[no_mangle] pub extern "C" fn z_sample_qos(sample: &z_sample_t) -> z_qos_t { sample.qos.into() @@ -238,6 +242,45 @@ pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { } } +#[repr(C)] +pub struct zc_owned_sample_t { + _0: z_owned_keyexpr_t, + _1: z_owned_buffer_t, + _2: z_owned_buffer_t, + _3: [usize; 12], +} + +impl_guarded_transmute!(Option, zc_owned_sample_t); + +/// Clone a sample in the cheapest way available. +#[no_mangle] +pub extern "C" fn zc_sample_clone(sample: &z_sample_t) -> zc_owned_sample_t { + Some(sample.deref().clone()).into() +} + +/// Returns `true` if `sample` is valid. +/// +/// Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed +/// unless the value has been dropped already. +#[no_mangle] +pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { + sample.is_some() +} + +/// Borrow the sample, allowing calling its accessor methods. +/// +/// Calling this function using a dropped sample is undefined behaviour. +#[no_mangle] +pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> z_sample_t { + z_sample_t::new(unsafe { sample.as_ref().unwrap_unchecked() }) +} + +/// Destroy the sample. +#[no_mangle] +pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { + core::mem::drop(sample.take()); +} + /// A :c:type:`z_encoding_t` integer `prefix`. /// /// - **Z_ENCODING_PREFIX_EMPTY** From 7148d5b57ab81907621c1c4c0202735fb36c12b5 Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Thu, 29 Feb 2024 14:18:57 +0100 Subject: [PATCH 04/75] document the owned sample type itself --- include/zenoh_commons.h | 6 ++++++ src/commons.rs | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 3fa477cd3..53c80c75c 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -863,6 +863,12 @@ typedef struct zc_owned_liveliness_get_options_t { * functions, then the operation will fail (but the passed value will still be consumed). */ typedef struct z_owned_buffer_t zc_owned_payload_t; +/** + * An owned sample. + * + * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + */ typedef struct zc_owned_sample_t { struct z_owned_keyexpr_t _0; struct z_owned_buffer_t _1; diff --git a/src/commons.rs b/src/commons.rs index 085a0df5a..555a380be 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -242,6 +242,10 @@ pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { } } +/// An owned sample. +/// +/// This is a read only type that can only be constructed by cloning a `z_sample_t`. +/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. #[repr(C)] pub struct zc_owned_sample_t { _0: z_owned_keyexpr_t, From 9c9f1ac5ad6eaa0b9939e70d473031fa210afe63 Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Thu, 29 Feb 2024 14:53:08 +0100 Subject: [PATCH 05/75] fix macro usages --- src/platform/synchronization.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index dbd9d94b8..a16664352 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -22,8 +22,8 @@ pub struct ZMutexPtr { #[derive(Clone, Copy)] pub struct z_mutex_t(usize); -impl_guarded_transmute!(z_mutex_t, ZMutexPtr); -impl_guarded_transmute!(ZMutexPtr, z_mutex_t); +impl_guarded_transmute!(noderefs z_mutex_t, ZMutexPtr); +impl_guarded_transmute!(noderefs ZMutexPtr, z_mutex_t); // using the same error codes as in GNU pthreads, but with negative sign // due to convention to return negative values on error @@ -141,8 +141,8 @@ struct ZCondvarPtr { #[derive(Clone, Copy)] pub struct z_condvar_t(usize); -impl_guarded_transmute!(z_condvar_t, ZCondvarPtr); -impl_guarded_transmute!(ZCondvarPtr, z_condvar_t); +impl_guarded_transmute!(noderefs z_condvar_t, ZCondvarPtr); +impl_guarded_transmute!(noderefs ZCondvarPtr, z_condvar_t); #[no_mangle] #[allow(clippy::missing_safety_doc)] @@ -233,8 +233,8 @@ pub struct z_task_t(usize); #[derive(Clone, Copy)] pub struct z_task_attr_t(usize); -impl_guarded_transmute!(z_task_t, ZTaskPtr); -impl_guarded_transmute!(ZTaskPtr, z_task_t); +impl_guarded_transmute!(noderefs z_task_t, ZTaskPtr); +impl_guarded_transmute!(noderefs ZTaskPtr, z_task_t); struct FunArgPair { fun: unsafe extern "C" fn(arg: *mut c_void), From 3eb72362b564c04734d46c2bc05227a80e55f2d7 Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Fri, 1 Mar 2024 16:07:56 +0100 Subject: [PATCH 06/75] fix auto-generated zenohcd --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 638c6422d..52deaa71c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ serde_yaml = "0.9.19" [lib] path="src/lib.rs" -name = "zenohcd" +name = "zenohc" crate-type = ["cdylib", "staticlib"] doctest = false From 769d824adf227f013f2f6f1f0b666f152a5aeeb4 Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Tue, 5 Mar 2024 17:09:53 +0100 Subject: [PATCH 07/75] introduce split buffers in zenoh-c --- include/zenoh_commons.h | 55 +++++++++++++++++++++++++++++++++- src/collections.rs | 66 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 115 insertions(+), 6 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 53c80c75c..5e3af4644 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -190,11 +190,22 @@ typedef struct z_attachment_t { z_attachment_iter_driver_t iteration_driver; } z_attachment_t; /** - * A buffer owned by Zenoh. + * A split buffer that owns all of its data. + * + * To minimize copies and reallocations, Zenoh may provide you data in split buffers. + * + * You can use `z_buffer_contiguous` to obtain a contiguous version of a buffer. + * If the buffer was already contiguous, the reference count will simply be increased. + * Otherwise, the split buffer's entire content will be copied in a newly allocated buffer. */ typedef struct z_owned_buffer_t { size_t _inner[5]; } z_owned_buffer_t; +/** + * A loan of a `z_owned_buffer_t`. + * + * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. + */ typedef struct z_buffer_t { const void *_inner; } z_buffer_t; @@ -1038,12 +1049,54 @@ int8_t z_attachment_iterate(struct z_attachment_t this_, * Returns the gravestone value for `z_attachment_t`. */ ZENOHC_API struct z_attachment_t z_attachment_null(void); +/** + * Returns `true` if the buffer is in a valid state. + */ ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); +/** + * Increments the buffer's reference count, returning an owned version of the buffer. + */ ZENOHC_API struct z_owned_buffer_t z_buffer_clone(struct z_buffer_t buffer); +/** + * Returns an owned version of this buffer whose data is guaranteed to be contiguous in memory. + * + * This is achieved by increasing the reference count if the buffer is already contiguous, and by copying its data in a new contiguous buffer if it wasn't. + */ +ZENOHC_API +struct z_owned_buffer_t z_buffer_contiguous(struct z_buffer_t buffer); +/** + * Decrements the buffer's reference counter, destroying it if applicable. + * + * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. + */ ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); +/** + * Loans the buffer, allowing you to call functions that only need a loan of it. + */ ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); +/** + * The gravestone value for `z_owned_buffer_t`. + */ ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); +/** + * Returns the payload of the buffer if it is contiguous, aliasling it. + * + * If the payload was not contiguous in memory, `z_bytes_null` will be returned instead. + */ ZENOHC_API struct z_bytes_t z_buffer_payload(struct z_buffer_t buffer); +/** + * Returns the `index`th slice of the buffer, aliasing it. + * + * Out of bounds accesses will return `z_bytes_null`. + */ +ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); +/** + * Returns the number of slices in the buffer. + * + * If the return value is 0 or 1, then the buffer's data is contiguous in memory and `z_buffer_contiguous` will succeed. + */ +ZENOHC_API +size_t z_buffer_slice_count(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. */ diff --git a/src/collections.rs b/src/collections.rs index 7f34a8fdd..89c0e0438 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -162,7 +162,13 @@ impl From<&[u8]> for z_bytes_t { } } -/// A buffer owned by Zenoh. +/// A split buffer that owns all of its data. +/// +/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. +/// +/// You can use `z_buffer_contiguous` to obtain a contiguous version of a buffer. +/// If the buffer was already contiguous, the reference count will simply be increased. +/// Otherwise, the split buffer's entire content will be copied in a newly allocated buffer. #[repr(C)] pub struct z_owned_buffer_t { _inner: [usize; 5], @@ -203,24 +209,35 @@ impl core::ops::DerefMut for z_owned_buffer_t { } } +/// The gravestone value for `z_owned_buffer_t`. #[no_mangle] pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { unsafe { core::mem::transmute(None::) } } + +/// Decrements the buffer's reference counter, destroying it if applicable. +/// +/// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. #[no_mangle] pub extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { core::mem::drop(buffer.take()) } +/// Returns `true` if the buffer is in a valid state. #[no_mangle] pub extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { buffer.is_some() } + +/// Loans the buffer, allowing you to call functions that only need a loan of it. #[no_mangle] pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { buffer.as_ref().into() } +/// A loan of a `z_owned_buffer_t`. +/// +/// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. #[repr(C)] #[derive(Clone, Copy)] pub struct z_buffer_t<'a> { @@ -233,11 +250,15 @@ impl<'a> From> for Option<&'a ZBuf> { } } +/// Increments the buffer's reference count, returning an owned version of the buffer. #[no_mangle] pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { unsafe { Some(core::mem::transmute::<_, &ZBuf>(buffer).clone()).into() } } +/// Returns the payload of the buffer if it is contiguous, aliasling it. +/// +/// If the payload was not contiguous in memory, `z_bytes_null` will be returned instead. #[no_mangle] pub extern "C" fn z_buffer_payload(buffer: z_buffer_t) -> z_bytes_t { let Some(buffer): Option<&ZBuf> = buffer.into() else { @@ -245,9 +266,44 @@ pub extern "C" fn z_buffer_payload(buffer: z_buffer_t) -> z_bytes_t { }; match buffer.contiguous() { std::borrow::Cow::Borrowed(buffer) => buffer.into(), - std::borrow::Cow::Owned(_) => { - log::error!("A non-contiguous buffer reached user code, this is definitely a bug, please inform us at https://github.com/eclipse-zenoh/zenoh-c/issues/new"); - z_bytes_null() - } + std::borrow::Cow::Owned(_) => z_bytes_null(), + } +} + +/// Returns an owned version of this buffer whose data is guaranteed to be contiguous in memory. +/// +/// This is achieved by increasing the reference count if the buffer is already contiguous, and by copying its data in a new contiguous buffer if it wasn't. +#[no_mangle] +pub extern "C" fn z_buffer_contiguous(buffer: z_buffer_t) -> z_owned_buffer_t { + let Some(buf): Option<&ZBuf> = buffer.into() else { + return z_buffer_null(); + }; + match buf.contiguous() { + std::borrow::Cow::Borrowed(_) => buf.clone().into(), + std::borrow::Cow::Owned(buf) => ZBuf::from(buf).into(), + } +} + +/// Returns the number of slices in the buffer. +/// +/// If the return value is 0 or 1, then the buffer's data is contiguous in memory and `z_buffer_contiguous` will succeed. +#[no_mangle] +pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { + match buffer.into() { + None => 0, + Some(buf) => ZBuf::slices(buf).len(), + } +} + +/// Returns the `index`th slice of the buffer, aliasing it. +/// +/// Out of bounds accesses will return `z_bytes_null`. +#[no_mangle] +pub extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { + match buffer.into() { + None => z_bytes_null(), + Some(buf) => ZBuf::slices(buf) + .nth(index) + .map_or(z_bytes_null(), |slice| slice.into()), } } From 1b09b308accafcbb4c9e54675bf6e878072d18de Mon Sep 17 00:00:00 2001 From: Pierre Avital Date: Fri, 8 Mar 2024 11:16:02 +0100 Subject: [PATCH 08/75] address pr comments --- include/zenoh_commons.h | 9 +-------- src/commons.rs | 16 +++++----------- src/lib.rs | 8 ++++++++ 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 5e3af4644..e0b405014 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -383,14 +383,6 @@ typedef struct z_owned_closure_reply_t { * A data sample. * * A sample is the value associated to a given resource at a given point in time. - * - * Members: - * z_keyexpr_t keyexpr: The resource key of this data sample. - * z_bytes_t payload: The value of this data sample. - * z_encoding_t encoding: The encoding of the value of this data sample. - * z_sample_kind_t kind: The kind of this data sample (PUT or DELETE). - * z_timestamp_t timestamp: The timestamp of this data sample. - * z_attachment_t attachment: The attachment of this data sample. */ typedef struct z_sample_t { const void *_inner; @@ -2503,6 +2495,7 @@ ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); * Calling this function using a dropped sample is undefined behaviour. */ ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); +ZENOHC_API struct zc_owned_sample_t zc_sample_null(void); /** * Increments the session's reference count, returning a new owning handle. */ diff --git a/src/commons.rs b/src/commons.rs index 555a380be..d23618846 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -156,14 +156,6 @@ pub extern "C" fn z_qos_default() -> z_qos_t { /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. -/// -/// Members: -/// z_keyexpr_t keyexpr: The resource key of this data sample. -/// z_bytes_t payload: The value of this data sample. -/// z_encoding_t encoding: The encoding of the value of this data sample. -/// z_sample_kind_t kind: The kind of this data sample (PUT or DELETE). -/// z_timestamp_t timestamp: The timestamp of this data sample. -/// z_attachment_t attachment: The attachment of this data sample. #[repr(C)] pub struct z_sample_t<'a> { _inner: &'a (), @@ -177,9 +169,6 @@ impl<'a> core::ops::Deref for z_sample_t<'a> { impl<'a> z_sample_t<'a> { pub fn new(sample: &'a Sample) -> Self { - if !sample.value.payload.zslices().count() <= 1 { - panic!("Attempted to construct z_sample_t from discontiguous buffer, this is definitely a bug in zenoh-c, please report it.") - }; z_sample_t { _inner: unsafe { core::mem::transmute(sample) }, } @@ -285,6 +274,11 @@ pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { core::mem::drop(sample.take()); } +#[no_mangle] +pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { + None.into() +} + /// A :c:type:`z_encoding_t` integer `prefix`. /// /// - **Z_ENCODING_PREFIX_EMPTY** diff --git a/src/lib.rs b/src/lib.rs index 9c01e4aa2..2ff9259c6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,6 +58,14 @@ trait GuardedTransmute { fn transmute(self) -> D; } +/// For internal use only. +/// +/// This macro is used to establish the equivalence between a Rust type (first parameter) and a C layout (second parameter). +/// +/// It automatically implements `From`, `Deref` and `DerefMut` to make writing code around these equivalent types. +/// +/// Because carrying around the proper semantics of lifetimes is hard, this macro fails to produce working code when lifetimes are +/// present in either parameter. You may then call it with the `noderefs` prefix to avoid the offending implementations being defined. #[macro_export] macro_rules! impl_guarded_transmute { ($src_type:ty, $dst_type:ty) => { From 4d1816b6b0ee1ae1a290a6d11131afa9993ae90c Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 28 Mar 2024 12:25:27 +0100 Subject: [PATCH 09/75] merge --- Cargo.lock | 548 ++++++++++++------------ Cargo.toml | 2 + Cargo.toml.in | 2 + docs/api.rst | 8 +- docs/requirements.txt | 8 +- examples/z_liveliness.c | 8 +- examples/z_ping.c | 19 +- examples/z_pub.c | 12 +- examples/z_pub_attachment.c | 8 +- examples/z_pub_cache.c | 8 +- examples/z_pub_shm.c | 8 +- examples/z_pull.c | 8 +- examples/z_query_sub.c | 8 +- examples/z_queryable.c | 8 +- examples/z_queryable_with_channels.c | 6 - examples/z_scout.c | 20 +- examples/z_sub.c | 8 +- examples/z_sub_attachment.c | 8 +- examples/z_sub_liveliness.c | 8 +- examples/z_sub_thr.c | 25 +- include/zenoh_commons.h | 132 +++++- src/attachment.rs | 66 +++ src/get.rs | 6 +- src/keyexpr.rs | 97 +++++ src/lib.rs | 27 ++ src/liveliness.rs | 22 +- src/platform/clock.rs | 127 ++++++ src/platform/mod.rs | 9 +- src/platform/random.rs | 34 ++ src/platform/sleep.rs | 19 + src/scouting.rs | 31 +- tests/z_api_alignment_test.c | 48 +-- tests/z_api_attachment_test.c | 14 + tests/z_api_keyexpr_test.c | 30 ++ tests/z_int_pub_cache_query_sub_test.c | 2 +- tests/z_int_pub_sub_attachment_test.c | 2 +- tests/z_int_queryable_attachment_test.c | 2 +- tests/z_int_queryable_test.c | 2 +- 38 files changed, 922 insertions(+), 478 deletions(-) create mode 100644 src/platform/clock.rs create mode 100644 src/platform/random.rs create mode 100644 src/platform/sleep.rs diff --git a/Cargo.lock b/Cargo.lock index 6d2575fae..1c62eb1df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,11 +55,26 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" dependencies = [ "anstyle", "anstyle-parse", @@ -71,9 +86,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" @@ -115,16 +130,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" -[[package]] -name = "async-attributes" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" -dependencies = [ - "quote", - "syn 1.0.109", -] - [[package]] name = "async-channel" version = "1.9.0" @@ -213,23 +218,12 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "async-rustls" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29479d362e242e320fa8f5c831940a5b83c1679af014068196cd20d4bf497b6b" -dependencies = [ - "futures-io", - "rustls", -] - [[package]] name = "async-std" version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" dependencies = [ - "async-attributes", "async-channel", "async-global-executor", "async-io", @@ -393,7 +387,7 @@ version = "0.24.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b922faaf31122819ec80c4047cc684c6979a087366c069611e33649bf98e18d" dependencies = [ - "clap 3.2.25", + "clap", "heck", "indexmap 1.9.3", "log", @@ -421,6 +415,20 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.0", +] + [[package]] name = "cipher" version = "0.4.4" @@ -439,47 +447,13 @@ checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", "bitflags 1.3.2", - "clap_lex 0.2.4", + "clap_lex", "indexmap 1.9.3", "strsim", "termcolor", "textwrap", ] -[[package]] -name = "clap" -version = "4.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" -dependencies = [ - "anstream", - "anstyle", - "clap_lex 0.6.0", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.33", -] - [[package]] name = "clap_lex" version = "0.2.4" @@ -489,12 +463,6 @@ dependencies = [ "os_str_bytes", ] -[[package]] -name = "clap_lex" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" - [[package]] name = "colorchoice" version = "1.0.0" @@ -636,11 +604,21 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -649,6 +627,19 @@ dependencies = [ "termcolor", ] +[[package]] +name = "env_logger" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -657,23 +648,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -704,9 +684,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "fixedbitset" @@ -906,12 +886,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - [[package]] name = "gloo-timers" version = "0.2.6" @@ -970,12 +944,6 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - [[package]] name = "hmac" version = "0.12.1" @@ -996,9 +964,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" dependencies = [ "bytes", "fnv", @@ -1017,6 +985,29 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "iana-time-zone" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows 0.48.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "idna" version = "0.4.0" @@ -1092,7 +1083,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.2", - "rustix 0.38.21", + "rustix 0.38.32", "windows-sys 0.48.0", ] @@ -1160,9 +1151,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.148" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libloading" @@ -1246,9 +1237,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi", @@ -1509,20 +1500,6 @@ dependencies = [ "spki", ] -[[package]] -name = "pnet" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "130c5b738eeda2dc5796fe2671e49027e6935e817ab51b930a36ec9e6a206a64" -dependencies = [ - "ipnetwork", - "pnet_base", - "pnet_datalink", - "pnet_packet", - "pnet_sys", - "pnet_transport", -] - [[package]] name = "pnet_base" version = "0.34.0" @@ -1545,39 +1522,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "pnet_macros" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688b17499eee04a0408aca0aa5cba5fc86401d7216de8a63fdf7a4c227871804" -dependencies = [ - "proc-macro2", - "quote", - "regex", - "syn 2.0.33", -] - -[[package]] -name = "pnet_macros_support" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea925b72f4bd37f8eab0f221bbe4c78b63498350c983ffa9dd4bcde7e030f56" -dependencies = [ - "pnet_base", -] - -[[package]] -name = "pnet_packet" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a005825396b7fe7a38a8e288dbc342d5034dac80c15212436424fef8ea90ba" -dependencies = [ - "glob", - "pnet_base", - "pnet_macros", - "pnet_macros_support", -] - [[package]] name = "pnet_sys" version = "0.34.0" @@ -1588,18 +1532,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "pnet_transport" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2637e14d7de974ee2f74393afccbc8704f3e54e6eb31488715e72481d1662cc3" -dependencies = [ - "libc", - "pnet_base", - "pnet_packet", - "pnet_sys", -] - [[package]] name = "polling" version = "2.8.0" @@ -1648,7 +1580,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls", + "rustls 0.21.7", "thiserror", "tokio", "tracing", @@ -1664,7 +1596,7 @@ dependencies = [ "rand", "ring 0.16.20", "rustc-hash", - "rustls", + "rustls 0.21.7", "rustls-native-certs 0.6.3", "slab", "thiserror", @@ -1680,7 +1612,7 @@ checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" dependencies = [ "bytes", "libc", - "socket2 0.5.4", + "socket2 0.5.6", "tracing", "windows-sys 0.48.0", ] @@ -1733,15 +1665,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_users" version = "0.4.3" @@ -1749,7 +1672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "redox_syscall", "thiserror", ] @@ -1880,15 +1803,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ "bitflags 2.4.0", "errno", "libc", "linux-raw-sys 0.4.13", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1903,6 +1826,20 @@ dependencies = [ "sct", ] +[[package]] +name = "rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +dependencies = [ + "log", + "ring 0.17.6", + "rustls-pki-types", + "rustls-webpki 0.102.2", + "subtle", + "zeroize", +] + [[package]] name = "rustls-native-certs" version = "0.6.3" @@ -1949,9 +1886,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.0.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb0a1f9b9efec70d32e6d6aa3e58ebd88c3754ec98dfe9145c63cf54cc829b83" +checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" [[package]] name = "rustls-webpki" @@ -1965,9 +1902,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.0" +version = "0.102.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de2635c8bc2b88d367767c5de8ea1d8db9af3f6219eba28442242d9ab81d1b89" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" dependencies = [ "ring 0.17.6", "rustls-pki-types", @@ -2233,12 +2170,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2320,22 +2257,21 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.1", - "redox_syscall 0.4.1", - "rustix 0.38.21", - "windows-sys 0.48.0", + "fastrand 2.0.2", + "rustix 0.38.32", + "windows-sys 0.52.0", ] [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -2392,9 +2328,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.32.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -2402,27 +2338,48 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", - "socket2 0.5.4", + "socket2 0.5.6", "tokio-macros", "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", "syn 2.0.33", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.7", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.2", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-tungstenite" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log", @@ -2430,6 +2387,21 @@ dependencies = [ "tungstenite", ] +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "futures-util", + "hashbrown 0.14.0", + "pin-project-lite", + "tokio", +] + [[package]] name = "toml" version = "0.5.11" @@ -2474,9 +2446,9 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" dependencies = [ "byteorder", "bytes", @@ -2515,9 +2487,9 @@ checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "uhlc" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1eadef1fa26cbbae1276c46781e8f4d888bdda434779c18ae6c2a0e69991885" +checksum = "99b6df3f3e948b40e20c38a6d1fd6d8f91b3573922fc164e068ad3331560487e" dependencies = [ "humantime", "lazy_static", @@ -2760,7 +2732,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b7b128a98c1cfa201b09eb49ba285887deb3cbe7466a98850eb1adabb452be5" dependencies = [ - "windows", + "windows 0.34.0", ] [[package]] @@ -2807,6 +2779,15 @@ dependencies = [ "windows_x86_64_msvc 0.34.0", ] +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -2972,20 +2953,17 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-global-executor", - "async-std", "async-trait", "base64", "const_format", - "env_logger", + "env_logger 0.11.2", "event-listener 4.0.0", "flume", "form_urlencoded", "futures", "git-version", - "hex", "lazy_static", "log", "ordered-float", @@ -2996,8 +2974,10 @@ dependencies = [ "rustc_version", "serde", "serde_json", - "socket2 0.5.4", + "socket2 0.5.6", "stop-token", + "tokio", + "tokio-util", "uhlc", "uuid", "vec_map", @@ -3013,6 +2993,7 @@ dependencies = [ "zenoh-plugin-trait", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-shm", "zenoh-sync", "zenoh-transport", @@ -3022,7 +3003,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "zenoh-collections", ] @@ -3034,10 +3015,12 @@ dependencies = [ "async-std", "async-trait", "cbindgen", - "env_logger", + "chrono", + "env_logger 0.10.2", "fs2", "futures", "json5", + "lazy_static", "libc", "log", "rand", @@ -3052,7 +3035,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "log", "serde", @@ -3065,15 +3048,16 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "flume", "json5", + "log", "num_cpus", "secrecy", "serde", @@ -3089,17 +3073,19 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", + "async-global-executor", "lazy_static", + "tokio", "zenoh-result", + "zenoh-runtime", ] [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "aes", "hmac", @@ -3112,19 +3098,20 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "bincode", - "env_logger", + "env_logger 0.11.2", "flume", "futures", "log", "serde", + "tokio", "zenoh", "zenoh-core", "zenoh-macros", "zenoh-result", + "zenoh-runtime", "zenoh-sync", "zenoh-util", ] @@ -3132,7 +3119,7 @@ dependencies = [ [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "hashbrown 0.14.0", "keyed-set", @@ -3146,9 +3133,8 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "async-trait", "zenoh-config", "zenoh-link-commons", @@ -3165,46 +3151,50 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "async-trait", "flume", + "futures", "log", - "lz4_flex", + "rustls 0.22.2", + "rustls-webpki 0.102.2", "serde", - "typenum", + "tokio", + "tokio-util", "zenoh-buffers", "zenoh-codec", "zenoh-core", "zenoh-protocol", "zenoh-result", - "zenoh-sync", + "zenoh-runtime", "zenoh-util", ] [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-rustls", - "async-std", "async-trait", "base64", "futures", "log", "quinn", - "rustls", + "rustls 0.21.7", "rustls-native-certs 0.7.0", "rustls-pemfile 2.0.0", - "rustls-webpki 0.102.0", + "rustls-webpki 0.102.2", "secrecy", + "tokio", + "tokio-rustls 0.24.1", + "tokio-util", "zenoh-config", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-sync", "zenoh-util", ] @@ -3212,15 +3202,17 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "async-trait", "log", + "tokio", + "tokio-util", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-sync", "zenoh-util", ] @@ -3228,24 +3220,27 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-rustls", - "async-std", "async-trait", "base64", "futures", "log", - "rustls", + "rustls 0.22.2", "rustls-pemfile 2.0.0", - "rustls-webpki 0.102.0", + "rustls-pki-types", + "rustls-webpki 0.102.2", "secrecy", + "tokio", + "tokio-rustls 0.25.0", + "tokio-util", "webpki-roots", "zenoh-config", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-sync", "zenoh-util", ] @@ -3253,18 +3248,20 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "async-trait", "log", - "socket2 0.5.4", + "socket2 0.5.6", + "tokio", + "tokio-util", "zenoh-buffers", "zenoh-collections", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-sync", "zenoh-util", ] @@ -3272,37 +3269,40 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "async-trait", "futures", "log", "nix 0.27.1", + "tokio", + "tokio-util", "uuid", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-sync", ] [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "async-trait", "futures-util", "log", "tokio", "tokio-tungstenite", + "tokio-util", "url", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-sync", "zenoh-util", ] @@ -3310,20 +3310,18 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "proc-macro2", "quote", - "rustc_version", "syn 2.0.33", - "unzip-n", "zenoh-keyexpr", ] [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "const_format", "libloading", @@ -3339,14 +3337,12 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "const_format", - "hex", "rand", "serde", "uhlc", - "uuid", "zenoh-buffers", "zenoh-keyexpr", "zenoh-result", @@ -3355,17 +3351,27 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "anyhow", ] +[[package]] +name = "zenoh-runtime" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "lazy_static", + "tokio", + "zenoh-collections", + "zenoh-result", +] + [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "bincode", "log", "serde", "shared_memory", @@ -3376,26 +3382,22 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-std", "event-listener 4.0.0", - "flume", "futures", "tokio", "zenoh-buffers", "zenoh-collections", "zenoh-core", + "zenoh-runtime", ] [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ - "async-executor", - "async-global-executor", - "async-std", "async-trait", "flume", "log", @@ -3406,6 +3408,8 @@ dependencies = [ "rsa", "serde", "sha3", + "tokio", + "tokio-util", "zenoh-buffers", "zenoh-codec", "zenoh-collections", @@ -3415,6 +3419,7 @@ dependencies = [ "zenoh-link", "zenoh-protocol", "zenoh-result", + "zenoh-runtime", "zenoh-shm", "zenoh-sync", "zenoh-util", @@ -3423,27 +3428,22 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#7d9d684cf953f9f813eb320812eaf95f767ef200" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-std", "async-trait", - "clap 4.4.11", - "const_format", "flume", - "futures", - "hex", "home", "humantime", "lazy_static", "libc", "libloading", "log", - "pnet", "pnet_datalink", "shellexpand", + "tokio", "winapi", "zenoh-core", - "zenoh-protocol", "zenoh-result", ] diff --git a/Cargo.toml b/Cargo.toml index 52deaa71c..95867f95f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,9 +41,11 @@ maintenance = { status = "actively-developed" } [dependencies] async-std = "=1.12.0" async-trait = "0.1.66" +chrono = "0.4.34" env_logger = "0.10.0" futures = "0.3.26" json5 = "0.4.1" +lazy_static = "1.4.0" libc = "0.2.139" log = "0.4.17" rand = "0.8.5" diff --git a/Cargo.toml.in b/Cargo.toml.in index d1eec11bd..f434df3a1 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -41,9 +41,11 @@ maintenance = { status = "actively-developed" } [dependencies] async-std = "=1.12.0" async-trait = "0.1.66" +chrono = "0.4.34" env_logger = "0.10.0" futures = "0.3.26" json5 = "0.4.1" +lazy_static = "1.4.0" libc = "0.2.139" log = "0.4.17" rand = "0.8.5" diff --git a/docs/api.rst b/docs/api.rst index 6694af4a5..758c405b5 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -38,6 +38,8 @@ Bytes map .. autocfunction:: zenoh_commons.h::z_bytes_map_null .. autocfunction:: zenoh_commons.h::z_bytes_map_drop .. autocfunction:: zenoh_commons.h::z_bytes_map_get +.. autocfunction:: zenoh_commons.h::z_bytes_map_len +.. autocfunction:: zenoh_commons.h::z_bytes_map_is_empty .. autocfunction:: zenoh_commons.h::z_bytes_map_insert_by_alias .. autocfunction:: zenoh_commons.h::z_bytes_map_insert_by_copy .. autocfunction:: zenoh_commons.h::z_bytes_map_iter @@ -106,6 +108,7 @@ Key expression .. autocstruct:: zenoh_commons.h::z_owned_keyexpr_t .. autocfunction:: zenoh_commons.h::z_keyexpr +.. autocfunction:: zenoh_commons.h::z_keyexpr_autocanonize .. autocfunction:: zenoh_commons.h::z_keyexpr_unchecked .. autocfunction:: zenoh_commons.h::z_keyexpr_to_string .. autocfunction:: zenoh_commons.h::z_keyexpr_as_bytes @@ -120,6 +123,7 @@ Key expression .. autocfunction:: zenoh_commons.h::z_keyexpr_intersects .. autocfunction:: zenoh_commons.h::z_keyexpr_new +.. autocfunction:: zenoh_commons.h::z_keyexpr_new_autocanonize .. autocfunction:: zenoh_commons.h::z_keyexpr_loan .. autocfunction:: zenoh_commons.h::z_keyexpr_check .. autocfunction:: zenoh_commons.h::z_keyexpr_drop @@ -157,6 +161,8 @@ Attachment .. autocfunction:: zenoh_commons.h::z_attachment_null .. autocfunction:: zenoh_commons.h::z_attachment_get +.. autocfunction:: zenoh_commons.h::z_attachment_len +.. autocfunction:: zenoh_commons.h::z_attachment_is_empty .. autocfunction:: zenoh_commons.h::z_attachment_check .. autocfunction:: zenoh_commons.h::z_attachment_iterate @@ -299,7 +305,7 @@ Types .. autocstruct:: zenoh_commons.h::zc_owned_liveliness_token_t .. autocstruct:: zenoh_commons.h::zc_owned_liveliness_declaration_options_t -.. autocstruct:: zenoh_commons.h::zc_owned_liveliness_get_options_t +.. autocstruct:: zenoh_commons.h::zc_liveliness_get_options_t .. autocstruct:: zenoh_commons.h::zc_owned_liveliness_declare_subscriber_options_t Functions diff --git a/docs/requirements.txt b/docs/requirements.txt index 670562c3e..a5a4b5f60 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ -sphinx==4.5.0 -sphinx_c_autodoc -sphinx_rtd_theme -clang==14 +sphinx==7.2.6 +sphinx_c_autodoc==1.3.0 +sphinx_rtd_theme==2.0.0 +clang==14.0 diff --git a/examples/z_liveliness.c b/examples/z_liveliness.c index b21cc40bc..4191b0496 100644 --- a/examples/z_liveliness.c +++ b/examples/z_liveliness.c @@ -13,12 +13,6 @@ #include #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" int main(int argc, char **argv) { @@ -63,7 +57,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } else if (c == 'd') { printf("Undeclaring liveliness token...\n"); z_drop(z_move(token)); diff --git a/examples/z_ping.c b/examples/z_ping.c index bb061baee..fdc08f71d 100644 --- a/examples/z_ping.c +++ b/examples/z_ping.c @@ -2,7 +2,6 @@ #include #include #include -#include #include "zenoh.h" @@ -58,35 +57,27 @@ int main(int argc, char** argv) { z_mutex_lock(&mutex); if (args.warmup_ms) { printf("Warming up for %dms...\n", args.warmup_ms); - struct timespec wmup_start, wmup_stop, wmup_timeout; - clock_gettime(CLOCK_MONOTONIC, &wmup_start); + z_clock_t warmup_start = z_clock_now(); + unsigned long elapsed_us = 0; while (elapsed_us < args.warmup_ms * 1000) { - clock_gettime(CLOCK_REALTIME, &wmup_timeout); - wmup_timeout.tv_sec += PING_TIMEOUT_SEC; z_publisher_put(z_loan(pub), data, args.size, NULL); int s = z_condvar_wait(&cond, &mutex); if (s != 0) { handle_error_en(s, "z_condvar_wait"); } - clock_gettime(CLOCK_MONOTONIC, &wmup_stop); - elapsed_us = - (1000000 * (wmup_stop.tv_sec - wmup_start.tv_sec) + (wmup_stop.tv_nsec - wmup_start.tv_nsec) / 1000); + elapsed_us = z_clock_elapsed_us(&warmup_start); } } - struct timespec t_start, t_stop, t_timeout; unsigned long* results = z_malloc(sizeof(unsigned long) * args.number_of_pings); for (int i = 0; i < args.number_of_pings; i++) { - clock_gettime(CLOCK_REALTIME, &t_timeout); - t_timeout.tv_sec += PING_TIMEOUT_SEC; - clock_gettime(CLOCK_MONOTONIC, &t_start); + z_clock_t measure_start = z_clock_now(); z_publisher_put(z_loan(pub), data, args.size, NULL); int s = z_condvar_wait(&cond, &mutex); if (s != 0) { handle_error_en(s, "z_condvar_wait"); } - clock_gettime(CLOCK_MONOTONIC, &t_stop); - results[i] = (1000000 * (t_stop.tv_sec - t_start.tv_sec) + (t_stop.tv_nsec - t_start.tv_nsec) / 1000); + results[i] = z_clock_elapsed_us(&measure_start); } for (int i = 0; i < args.number_of_pings; i++) { printf("%d bytes: seq=%d rtt=%luµs, lat=%luµs\n", args.size, i, results[i], results[i] / 2); diff --git a/examples/z_pub.c b/examples/z_pub.c index 73fd02287..ecc95e42d 100644 --- a/examples/z_pub.c +++ b/examples/z_pub.c @@ -15,12 +15,6 @@ #include #include "zenoh.h" -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif void matching_status_handler(const zcu_matching_status_t *matching_status, void *arg) { if (matching_status->matching) { @@ -41,11 +35,11 @@ int main(int argc, char **argv) { z_owned_config_t config = z_config_default(); if (argc > 4) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { + if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[4]) < 0) { printf( "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " "JSON-serialized list of strings\n", - argv[3], Z_CONFIG_CONNECT_KEY, Z_CONFIG_CONNECT_KEY); + argv[4], Z_CONFIG_CONNECT_KEY, Z_CONFIG_CONNECT_KEY); exit(-1); } } @@ -72,7 +66,7 @@ int main(int argc, char **argv) { char buf[256]; for (int idx = 0; 1; ++idx) { - sleep(1); + z_sleep_s(1); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_publisher_put_options_t options = z_publisher_put_options_default(); diff --git a/examples/z_pub_attachment.c b/examples/z_pub_attachment.c index b75f245c3..a24133e91 100644 --- a/examples/z_pub_attachment.c +++ b/examples/z_pub_attachment.c @@ -15,12 +15,6 @@ #include #include "zenoh.h" -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif int main(int argc, char **argv) { char *keyexpr = "demo/example/zenoh-c-pub"; @@ -69,7 +63,7 @@ int main(int argc, char **argv) { char buf[256]; char buf_ind[16]; for (int idx = 0; 1; ++idx) { - sleep(1); + z_sleep_s(1); // add some other attachment value sprintf(buf_ind, "%d", idx); diff --git a/examples/z_pub_cache.c b/examples/z_pub_cache.c index 8c1d36221..770bf9d93 100644 --- a/examples/z_pub_cache.c +++ b/examples/z_pub_cache.c @@ -15,12 +15,6 @@ #include #include "zenoh.h" -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif int main(int argc, char **argv) { char *keyexpr = "demo/example/zenoh-c-pub"; @@ -66,7 +60,7 @@ int main(int argc, char **argv) { char buf[256]; for (int idx = 0; 1; ++idx) { - sleep(1); + z_sleep_s(1); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)buf, strlen(buf), NULL); diff --git a/examples/z_pub_shm.c b/examples/z_pub_shm.c index f26c65c08..10970bf62 100644 --- a/examples/z_pub_shm.c +++ b/examples/z_pub_shm.c @@ -17,12 +17,6 @@ #include #include "zenoh.h" -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #define N 10 @@ -85,7 +79,7 @@ int main(int argc, char **argv) { snprintf(buf, 255, "[%4d] %s", idx, value); size_t len = strlen(buf); zc_shmbuf_set_length(&shmbuf, len); - sleep(1); + z_sleep_s(1); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); diff --git a/examples/z_pull.c b/examples/z_pull.c index badbd6f44..4f2de7945 100644 --- a/examples/z_pull.c +++ b/examples/z_pull.c @@ -12,12 +12,6 @@ // ZettaScale Zenoh Team, // #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" const char *kind_to_str(z_sample_kind_t kind); @@ -67,7 +61,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } else { z_subscriber_pull(z_loan(sub)); } diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index 7653a6c77..d60bc2bf1 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -12,12 +12,6 @@ // ZettaScale Zenoh Team, // #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" const char *kind_to_str(z_sample_kind_t kind); @@ -69,7 +63,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } } diff --git a/examples/z_queryable.c b/examples/z_queryable.c index f74f5d355..9d6ec7702 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -13,12 +13,6 @@ #include #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" const char *expr = "demo/example/zenoh-c-queryable"; @@ -81,7 +75,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } } diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index 80c98d689..672ddd607 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -14,12 +14,6 @@ #include #include #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" const char *expr = "demo/example/zenoh-c-queryable"; diff --git a/examples/z_scout.c b/examples/z_scout.c index 3b882f547..1b7b3c21d 100644 --- a/examples/z_scout.c +++ b/examples/z_scout.c @@ -12,14 +12,6 @@ // ZettaScale Zenoh Team, #include - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif - #include "zenoh.h" void fprintpid(FILE *stream, z_id_t pid) { @@ -41,13 +33,9 @@ void fprintpid(FILE *stream, z_id_t pid) { } void fprintwhatami(FILE *stream, unsigned int whatami) { - if (whatami == Z_ROUTER) { - fprintf(stream, "\"Router\""); - } else if (whatami == Z_PEER) { - fprintf(stream, "\"Peer\""); - } else { - fprintf(stream, "\"Other\""); - } + char buf[64]; + z_whatami_to_str(whatami, buf, sizeof(buf)); + fprintf(stream, "%s", buf); } void fprintlocators(FILE *stream, const z_str_array_t *locs) { @@ -96,6 +84,6 @@ int main(int argc, char **argv) { z_owned_closure_hello_t closure = z_closure(callback, drop, context); printf("Scouting...\n"); z_scout(z_move(config), z_move(closure)); - sleep(1); + z_sleep_s(1); return 0; } \ No newline at end of file diff --git a/examples/z_sub.c b/examples/z_sub.c index b52db8850..378a717e6 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -12,12 +12,6 @@ // ZettaScale Zenoh Team, // #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" const char *kind_to_str(z_sample_kind_t kind); @@ -74,7 +68,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } } diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index c3d22e39f..2031d1155 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -13,12 +13,6 @@ // #include #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" const char *kind_to_str(z_sample_kind_t kind); @@ -86,7 +80,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } } diff --git a/examples/z_sub_liveliness.c b/examples/z_sub_liveliness.c index 67c87001a..5916200b2 100644 --- a/examples/z_sub_liveliness.c +++ b/examples/z_sub_liveliness.c @@ -12,12 +12,6 @@ // ZettaScale Zenoh Team, // #include -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif #include "zenoh.h" void data_handler(const z_sample_t *sample, void *arg) { @@ -76,7 +70,7 @@ int main(int argc, char **argv) { while (c != 'q') { c = getchar(); if (c == -1) { - sleep(1); + z_sleep_s(1); } } diff --git a/examples/z_sub_thr.c b/examples/z_sub_thr.c index d32480174..05ee709d3 100644 --- a/examples/z_sub_thr.c +++ b/examples/z_sub_thr.c @@ -12,7 +12,6 @@ // ZettaScale Zenoh Team, // #include -#include #include "zenoh.h" @@ -21,46 +20,40 @@ typedef struct { volatile unsigned long count; volatile unsigned long finished_rounds; - struct timespec start; - struct timespec first_start; + z_clock_t start; + z_clock_t first_start; + bool started; } z_stats_t; z_stats_t *z_stats_make() { z_stats_t *stats = z_malloc(sizeof(z_stats_t)); stats->count = 0; stats->finished_rounds = 0; - stats->first_start.tv_nsec = 0; + stats->started = false; return stats; } -static inline double get_elapsed_s(const struct timespec *start, const struct timespec *end) { - return (double)(end->tv_sec - start->tv_sec) + (double)(end->tv_nsec - start->tv_nsec) / 1.0E9; -} - void on_sample(const z_sample_t *sample, void *context) { z_stats_t *stats = (z_stats_t *)context; if (stats->count == 0) { - clock_gettime(CLOCK_MONOTONIC, &stats->start); - if (stats->first_start.tv_nsec == 0) { + stats->start = z_clock_now(); + if (!stats->started) { stats->first_start = stats->start; + stats->started = true; } stats->count++; } else if (stats->count < N) { stats->count++; } else { - struct timespec end; - clock_gettime(CLOCK_MONOTONIC, &end); stats->finished_rounds++; - printf("%f msg/s\n", (double)N / get_elapsed_s(&stats->start, &end)); + printf("%f msg/s\n", 1000.0 * N / z_clock_elapsed_ms(&stats->start)); stats->count = 0; } } void drop_stats(void *context) { const z_stats_t *stats = (z_stats_t *)context; const unsigned long sent_messages = N * stats->finished_rounds + stats->count; - struct timespec end; - clock_gettime(CLOCK_MONOTONIC, &end); - double elapsed_s = get_elapsed_s(&stats->first_start, &end); + double elapsed_s = z_clock_elapsed_s(&stats->first_start); printf("Stats being dropped after unsubscribing: sent %ld messages over %f seconds (%f msg/s)\n", sent_messages, elapsed_s, (double)sent_messages / elapsed_s); z_free(context); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index e0b405014..55a52f82d 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -93,6 +93,20 @@ typedef enum z_encoding_prefix_t { Z_ENCODING_PREFIX_IMAGE_PNG = 19, Z_ENCODING_PREFIX_IMAGE_GIF = 20, } z_encoding_prefix_t; +/** + * A :c:type:`z_keyexpr_intersection_level_t`. + * + * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** + */ +typedef enum z_keyexpr_intersection_level_t { + Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT = 0, + Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS = 1, + Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES = 2, + Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS = 3, +} z_keyexpr_intersection_level_t; /** * The priority of zenoh messages. * @@ -218,6 +232,14 @@ typedef struct z_owned_bytes_map_t { uint64_t _0[2]; size_t _1[4]; } z_owned_bytes_map_t; +/** + * Clock + * Uses monotonic clock + */ +typedef struct z_clock_t { + uint64_t t; + const void *t_base; +} z_clock_t; /** * Represents a Zenoh ID. * @@ -343,13 +365,8 @@ typedef struct z_owned_closure_query_t { * * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. */ -#if defined(TARGET_ARCH_X86_64) +#if !defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_owned_reply_t { - uint64_t _0[28]; -} z_owned_reply_t; -#endif -#if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(16) z_owned_reply_t { uint64_t _0[30]; } z_owned_reply_t; #endif @@ -825,6 +842,13 @@ typedef struct z_task_t { typedef struct z_task_attr_t { size_t _0; } z_task_attr_t; +/** + * Time + * Uses system clock + */ +typedef struct z_time_t { + uint64_t t; +} z_time_t; /** * The options for `zc_liveliness_declare_token` */ @@ -850,9 +874,9 @@ typedef struct zc_owned_liveliness_token_t { /** * The options for :c:func:`zc_liveliness_declare_subscriber` */ -typedef struct zc_owned_liveliness_get_options_t { +typedef struct zc_liveliness_get_options_t { uint32_t timeout_ms; -} zc_owned_liveliness_get_options_t; +} zc_liveliness_get_options_t; /** * An owned payload, backed by a reference counted owner. * @@ -1025,6 +1049,10 @@ ZENOHC_API bool z_attachment_check(const struct z_attachment_t *this_); * Returns the value associated with the key. */ ZENOHC_API struct z_bytes_t z_attachment_get(struct z_attachment_t this_, struct z_bytes_t key); +/** + * Returns true if `z_attachment_t` contains no key-value pairs, false otherwise. + */ +ZENOHC_API bool z_attachment_is_empty(struct z_attachment_t this_); /** * Iterate over `this`'s key-value pairs, breaking if `body` returns a non-zero * value for a key-value pair, and returning the latest return value. @@ -1037,6 +1065,12 @@ ZENOHC_API int8_t z_attachment_iterate(struct z_attachment_t this_, z_attachment_iter_body_t body, void *context); +/** + * Returns number of key-value pairs for `z_attachment_t`. + * + * Does so by iterating over all existing key-value pairs. + */ +ZENOHC_API size_t z_attachment_len(struct z_attachment_t this_); /** * Returns the gravestone value for `z_attachment_t`. */ @@ -1154,6 +1188,10 @@ ZENOHC_API void z_bytes_map_insert_by_copy(const struct z_owned_bytes_map_t *this_, struct z_bytes_t key, struct z_bytes_t value); +/** + * Returns true if the map is empty, false otherwise. + */ +ZENOHC_API bool z_bytes_map_is_empty(struct z_owned_bytes_map_t *this_); /** * Iterates over the key-value pairs in the map. * @@ -1170,6 +1208,10 @@ ZENOHC_API int8_t z_bytes_map_iter(const struct z_owned_bytes_map_t *this_, z_attachment_iter_body_t body, void *ctx); +/** + * Returns number of key-value pairs in the map. + */ +ZENOHC_API size_t z_bytes_map_len(struct z_owned_bytes_map_t *this_); /** * Constructs a new map. */ @@ -1193,6 +1235,10 @@ ZENOHC_API struct z_bytes_t z_bytes_null(void); * Constructs a `len` bytes long view starting at `start`. */ ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); +ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); +ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); +ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); +ZENOHC_API struct z_clock_t z_clock_now(void); /** * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. * @@ -1594,6 +1640,14 @@ ZENOHC_API struct z_keyexpr_t z_keyexpr(const char *name); * Currently exclusive to zenoh-c */ ZENOHC_API struct z_bytes_t z_keyexpr_as_bytes(struct z_keyexpr_t keyexpr); +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + * The string is canonized in-place before being passed to keyexpr. + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +struct z_keyexpr_t z_keyexpr_autocanonize(char *name); /** * Canonizes the passed string in place, possibly shortening it by modifying `len`. * @@ -1682,10 +1736,23 @@ ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *key * Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. */ ZENOHC_API struct z_owned_keyexpr_t z_keyexpr_new(const char *name); +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. + */ +ZENOHC_API +struct z_owned_keyexpr_t z_keyexpr_new_autocanonize(const char *name); /** * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type */ ZENOHC_API struct z_owned_keyexpr_t z_keyexpr_null(void); +/** + * Returns the relation between `left` and `right` from `left`'s point of view. + * + * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. + */ +ZENOHC_API +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, + struct z_keyexpr_t right); /** * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. * The user is responsible of droping the returned string using `z_drop` @@ -1971,6 +2038,11 @@ ZENOHC_API struct z_owned_queryable_t z_queryable_null(void); * Constructs the default value for :c:type:`z_query_reply_options_t`. */ ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); +ZENOHC_API void z_random_fill(void *buf, size_t len); +ZENOHC_API uint16_t z_random_u16(void); +ZENOHC_API uint32_t z_random_u32(void); +ZENOHC_API uint64_t z_random_u64(void); +ZENOHC_API uint8_t z_random_u8(void); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -2108,6 +2180,9 @@ struct z_session_t z_session_loan(const struct z_owned_session_t *s); * Constructs a null safe-to-drop value of 'z_owned_session_t' type */ ZENOHC_API struct z_owned_session_t z_session_null(void); +ZENOHC_API int8_t z_sleep_ms(size_t time); +ZENOHC_API int8_t z_sleep_s(size_t time); +ZENOHC_API int8_t z_sleep_us(size_t time); /** * Returns ``true`` if `strs` is valid. */ @@ -2170,6 +2245,11 @@ int8_t z_task_init(struct z_task_t *task, void (*fun)(void *arg), void *arg); ZENOHC_API int8_t z_task_join(struct z_task_t *task); +ZENOHC_API uint64_t z_time_elapsed_ms(const struct z_time_t *time); +ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); +ZENOHC_API uint64_t z_time_elapsed_us(const struct z_time_t *time); +ZENOHC_API struct z_time_t z_time_now(void); +ZENOHC_API const char *z_time_now_as_str(const char *buf, size_t len); /** * Returns ``true`` if `ts` is a valid timestamp */ @@ -2200,6 +2280,18 @@ ZENOHC_API int8_t z_undeclare_queryable(struct z_owned_queryable_t *qable); */ ZENOHC_API int8_t z_undeclare_subscriber(struct z_owned_subscriber_t *sub); +/** + * Converts the kind of zenoh entity into a string. + * + * Parameters: + * whatami: A whatami bitmask of zenoh entity kind. + * buf: Buffer to write a null-terminated string to. + * len: Maximum number of bytes that can be written to the `buf`. + * + * Returns 0 if successful, negative values if whatami contains an invalid bitmask or `buf` is null, + * or number of remaining bytes, if the null-terminated string size exceeds `len`. + */ +ZENOHC_API int8_t z_whatami_to_str(uint8_t whatami, char *buf, size_t len); /** * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. */ @@ -2245,6 +2337,15 @@ ZENOHC_API void zc_init_logger(void); * It is a loaned key expression that aliases `name`. */ ZENOHC_API struct z_keyexpr_t zc_keyexpr_from_slice(const char *name, size_t len); +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + * The string is canonized in-place before being passed to keyexpr. + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +struct z_keyexpr_t zc_keyexpr_from_slice_autocanonize(char *name, + size_t *len); /** * Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions: * - `name` MUST be valid UTF8. @@ -2317,24 +2418,23 @@ ZENOHC_API int8_t zc_liveliness_get(struct z_session_t session, struct z_keyexpr_t key, struct z_owned_closure_reply_t *callback, - const struct zc_owned_liveliness_get_options_t *options); + const struct zc_liveliness_get_options_t *options); /** * Returns `true` if the options are valid. */ -ZENOHC_API -bool zc_liveliness_get_options_check(const struct zc_owned_liveliness_get_options_t *_opts); +ZENOHC_API bool zc_liveliness_get_options_check(const struct zc_liveliness_get_options_t *_opts); /** - * The gravestone value for `zc_owned_liveliness_get_options_t` + * The gravestone value for `zc_liveliness_get_options_t` */ -ZENOHC_API struct zc_owned_liveliness_get_options_t zc_liveliness_get_options_default(void); +ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_default(void); /** * Destroys the options. */ -ZENOHC_API void zc_liveliness_get_options_drop(struct zc_owned_liveliness_get_options_t *opts); +ZENOHC_API void zc_liveliness_get_options_drop(struct zc_liveliness_get_options_t *opts); /** - * The gravestone value for `zc_owned_liveliness_get_options_t` + * The gravestone value for `zc_liveliness_get_options_t` */ -ZENOHC_API struct zc_owned_liveliness_get_options_t zc_liveliness_get_options_null(void); +ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_null(void); /** * Returns `true` if the options are valid. */ diff --git a/src/attachment.rs b/src/attachment.rs index 051edafdc..7b456a9c1 100644 --- a/src/attachment.rs +++ b/src/attachment.rs @@ -117,6 +117,58 @@ pub extern "C" fn z_attachment_get(this: z_attachment_t, key: z_bytes_t) -> z_by } } +fn _z_attachment_len(this: z_attachment_t, check_if_non_empty: bool) -> usize { + match this.iteration_driver.as_ref() { + None => 0, + Some(iteration_driver) => { + struct count_context_t { + count: usize, + stop_if_not_empty: bool, + } + + extern "C" fn attachment_count_iterator( + _key: z_bytes_t, + _value: z_bytes_t, + context: *mut c_void, + ) -> i8 { + unsafe { + let context = &mut *(context as *mut count_context_t); + context.count += 1; + if context.stop_if_not_empty { + 1 + } else { + 0 + } + } + } + let mut count_context = count_context_t { + count: 0, + stop_if_not_empty: check_if_non_empty, + }; + (iteration_driver)( + this.data, + attachment_count_iterator, + &mut count_context as *mut _ as *mut c_void, + ); + count_context.count + } + } +} + +/// Returns number of key-value pairs for `z_attachment_t`. +/// +/// Does so by iterating over all existing key-value pairs. +#[no_mangle] +pub extern "C" fn z_attachment_len(this: z_attachment_t) -> usize { + _z_attachment_len(this, false) +} + +/// Returns true if `z_attachment_t` contains no key-value pairs, false otherwise. +#[no_mangle] +pub extern "C" fn z_attachment_is_empty(this: z_attachment_t) -> bool { + _z_attachment_len(this, true) == 0 +} + /// A map of maybe-owned vector of bytes to owned vector of bytes. /// /// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher @@ -164,6 +216,20 @@ pub extern "C" fn z_bytes_map_drop(this: &mut z_owned_bytes_map_t) { this.take(); } +/// Returns number of key-value pairs in the map. +#[no_mangle] +pub extern "C" fn z_bytes_map_len(this: &mut z_owned_bytes_map_t) -> usize { + let this = unsafe { &*this.get() }; + this.as_ref().map(|m| m.len()).unwrap_or(0) +} + +/// Returns true if the map is empty, false otherwise. +#[no_mangle] +pub extern "C" fn z_bytes_map_is_empty(this: &mut z_owned_bytes_map_t) -> bool { + let this = unsafe { &*this.get() }; + this.as_ref().map(|m| m.is_empty()).unwrap_or(true) +} + /// Returns the value associated with `key`, returning a gravestone value if: /// - `this` or `key` is in gravestone state. /// - `this` has no value associated to `key` diff --git a/src/get.rs b/src/get.rs index 423810a4f..bc37d7039 100644 --- a/src/get.rs +++ b/src/get.rs @@ -48,12 +48,8 @@ type ReplyInner = Option; /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -#[cfg(target_arch = "x86_64")] +#[cfg(not(target_arch = "arm"))] #[repr(C, align(8))] -pub struct z_owned_reply_t([u64; 28]); - -#[cfg(target_arch = "aarch64")] -#[repr(C, align(16))] pub struct z_owned_reply_t([u64; 30]); #[cfg(target_arch = "arm")] diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 06784a8dc..7742b3948 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -24,6 +24,7 @@ use crate::z_str_null; use crate::GuardedTransmute; use crate::LOG_INVALID_SESSION; use libc::c_char; +use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; @@ -103,6 +104,32 @@ pub unsafe extern "C" fn z_keyexpr_new(name: *const c_char) -> z_owned_keyexpr_t } } +/// Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. +#[allow(clippy::missing_safety_doc)] +#[no_mangle] +pub unsafe extern "C" fn z_keyexpr_new_autocanonize(name: *const c_char) -> z_owned_keyexpr_t { + if name.is_null() { + return z_owned_keyexpr_t::null(); + } + let name = std::slice::from_raw_parts(name as _, libc::strlen(name)); + match std::str::from_utf8(name) { + Ok(name) => { + let name_owned = name.to_owned(); + match KeyExpr::autocanonize(name_owned) { + Ok(v) => v.into_owned().into(), + Err(e) => { + log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); + z_owned_keyexpr_t::null() + } + } + } + Err(e) => { + log::error!("{}", e); + z_owned_keyexpr_t::null() + } + } +} + /// Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. #[no_mangle] pub extern "C" fn z_keyexpr_loan(keyexpr: &z_owned_keyexpr_t) -> z_keyexpr_t { @@ -293,6 +320,22 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice(name: *const c_char, len: usize) } } +/// Constructs a :c:type:`z_keyexpr_t` departing from a string. +/// It is a loaned key expression that aliases `name`. +/// The string is canonized in-place before being passed to keyexpr. +/// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). +#[allow(clippy::missing_safety_doc)] +#[no_mangle] +pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( + name: *mut c_char, + len: &mut usize, +) -> z_keyexpr_t { + if z_keyexpr_canonize(name, len) < 0 { + return z_keyexpr_t::null(); + } + zc_keyexpr_from_slice(name, *len) +} + /// Constructs a :c:type:`z_keyexpr_t` departing from a string. /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] @@ -305,6 +348,20 @@ pub unsafe extern "C" fn z_keyexpr(name: *const c_char) -> z_keyexpr_t { } } +/// Constructs a :c:type:`z_keyexpr_t` departing from a string. +/// It is a loaned key expression that aliases `name`. +/// The string is canonized in-place before being passed to keyexpr. +/// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). +#[allow(clippy::missing_safety_doc)] +#[no_mangle] +pub unsafe extern "C" fn z_keyexpr_autocanonize(name: *mut c_char) -> z_keyexpr_t { + if name.is_null() || z_keyexpr_canonize_null_terminated(name) < 0 { + z_keyexpr_t::null() + } else { + z_keyexpr(name) + } +} + /// Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions: /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: @@ -552,3 +609,43 @@ pub extern "C" fn z_keyexpr_join(left: z_keyexpr_t, right: z_keyexpr_t) -> z_own } } } + +/// A :c:type:`z_keyexpr_intersection_level_t`. +/// +/// - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** +/// - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** +/// - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** +/// - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(C)] +pub enum z_keyexpr_intersection_level_t { + DISJOINT = 0, + INTERSECTS = 1, + INCLUDES = 2, + EQUALS = 3, +} + +impl From for z_keyexpr_intersection_level_t { + fn from(val: SetIntersectionLevel) -> Self { + match val { + SetIntersectionLevel::Disjoint => z_keyexpr_intersection_level_t::DISJOINT, + SetIntersectionLevel::Intersects => z_keyexpr_intersection_level_t::INTERSECTS, + SetIntersectionLevel::Includes => z_keyexpr_intersection_level_t::INCLUDES, + SetIntersectionLevel::Equals => z_keyexpr_intersection_level_t::EQUALS, + } + } +} + +#[no_mangle] +/// Returns the relation between `left` and `right` from `left`'s point of view. +/// +/// Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. +pub extern "C" fn z_keyexpr_relation_to( + left: z_keyexpr_t, + right: z_keyexpr_t, +) -> z_keyexpr_intersection_level_t { + match (&*left, &*right) { + (Some(l), Some(r)) => l.relation_to(r).into(), + _ => z_keyexpr_intersection_level_t::DISJOINT, + } +} diff --git a/src/lib.rs b/src/lib.rs index 2ff9259c6..5019a0713 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,9 @@ #![allow(non_camel_case_types)] mod collections; +use std::cmp::min; +use std::slice; + pub use crate::collections::*; mod config; pub use crate::config::*; @@ -43,6 +46,7 @@ pub use crate::publisher::*; mod closures; pub use closures::*; mod liveliness; +use libc::c_void; pub use liveliness::*; mod publication_cache; pub use publication_cache::*; @@ -174,3 +178,26 @@ fn test_no_default_features() { ) ); } + +trait CopyableToCArray { + fn copy_to_c_array(&self, buf: *mut c_void, len: usize) -> usize; +} + +impl CopyableToCArray for &[u8] { + fn copy_to_c_array(&self, buf: *mut c_void, len: usize) -> usize { + if buf.is_null() || (len == 0 && !self.is_empty()) { + return 0; + } + + let max_len = min(len, self.len()); + let b = unsafe { slice::from_raw_parts_mut(buf as *mut u8, max_len) }; + b[0..max_len].copy_from_slice(&self[0..max_len]); + max_len + } +} + +impl CopyableToCArray for &str { + fn copy_to_c_array(&self, buf: *mut c_void, len: usize) -> usize { + self.as_bytes().copy_to_c_array(buf, len) + } +} diff --git a/src/liveliness.rs b/src/liveliness.rs index 69ee2d2e2..d66508cd5 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -195,29 +195,27 @@ pub extern "C" fn zc_liveliness_declare_subscriber( /// The options for :c:func:`zc_liveliness_declare_subscriber` #[repr(C)] -pub struct zc_owned_liveliness_get_options_t { +pub struct zc_liveliness_get_options_t { timeout_ms: u32, } -/// The gravestone value for `zc_owned_liveliness_get_options_t` +/// The gravestone value for `zc_liveliness_get_options_t` #[no_mangle] -pub extern "C" fn zc_liveliness_get_options_null() -> zc_owned_liveliness_get_options_t { - zc_owned_liveliness_get_options_t { timeout_ms: 0 } +pub extern "C" fn zc_liveliness_get_options_null() -> zc_liveliness_get_options_t { + zc_liveliness_get_options_t { timeout_ms: 0 } } -/// The gravestone value for `zc_owned_liveliness_get_options_t` +/// The gravestone value for `zc_liveliness_get_options_t` #[no_mangle] -pub extern "C" fn zc_liveliness_get_options_default() -> zc_owned_liveliness_get_options_t { - zc_owned_liveliness_get_options_t { timeout_ms: 10000 } +pub extern "C" fn zc_liveliness_get_options_default() -> zc_liveliness_get_options_t { + zc_liveliness_get_options_t { timeout_ms: 10000 } } /// Returns `true` if the options are valid. #[no_mangle] -pub extern "C" fn zc_liveliness_get_options_check( - _opts: &zc_owned_liveliness_get_options_t, -) -> bool { +pub extern "C" fn zc_liveliness_get_options_check(_opts: &zc_liveliness_get_options_t) -> bool { true } /// Destroys the options. #[no_mangle] -pub extern "C" fn zc_liveliness_get_options_drop(opts: &mut zc_owned_liveliness_get_options_t) { +pub extern "C" fn zc_liveliness_get_options_drop(opts: &mut zc_liveliness_get_options_t) { *opts = zc_liveliness_get_options_null() } @@ -231,7 +229,7 @@ pub extern "C" fn zc_liveliness_get( session: z_session_t, key: z_keyexpr_t, callback: &mut z_owned_closure_reply_t, - options: Option<&zc_owned_liveliness_get_options_t>, + options: Option<&zc_liveliness_get_options_t>, ) -> i8 { let Some(session) = session.upgrade() else { log::error!("Failed to declare liveliness token: provided session was invalid"); diff --git a/src/platform/clock.rs b/src/platform/clock.rs new file mode 100644 index 000000000..196d697cb --- /dev/null +++ b/src/platform/clock.rs @@ -0,0 +1,127 @@ +use chrono::{DateTime, Local}; +use libc::c_char; +use std::{ + os::raw::c_void, + time::{Duration, Instant, SystemTime, UNIX_EPOCH}, +}; + +use crate::CopyableToCArray; +use lazy_static::lazy_static; + +// Use initial time stored in static variable as a reference time, +// to be able to return number of ns passed since. +// This is to avoid wrapping Instant into a c type and not +// have to account for its platform-dependent size and alignment. +lazy_static! { + static ref CLOCK_BASE: Instant = Instant::now(); +} + +/// Clock +/// Uses monotonic clock +#[repr(C)] +#[derive(Clone, Copy)] +pub struct z_clock_t { + t: u64, + t_base: *const c_void, +} + +#[no_mangle] +pub extern "C" fn z_clock_now() -> z_clock_t { + z_clock_t { + t: CLOCK_BASE.elapsed().as_nanos() as u64, + t_base: &CLOCK_BASE as *const CLOCK_BASE as *const c_void, + } +} +#[allow(clippy::missing_safety_doc)] +unsafe fn get_elapsed_nanos(time: *const z_clock_t) -> u64 { + if time.is_null() { + return 0; + } + let now_t = (*((*time).t_base as *const CLOCK_BASE)) + .elapsed() + .as_nanos() as u64; + if now_t > (*time).t { + now_t - (*time).t + } else { + 0 + } +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_clock_elapsed_s(time: *const z_clock_t) -> u64 { + get_elapsed_nanos(time) / 1_000_000_000 +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_clock_elapsed_ms(time: *const z_clock_t) -> u64 { + get_elapsed_nanos(time) / 1_000_000 +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_clock_elapsed_us(time: *const z_clock_t) -> u64 { + get_elapsed_nanos(time) / 1_000 +} + +/// Time +/// Uses system clock +#[repr(C)] +#[derive(Clone, Copy)] +pub struct z_time_t { + t: u64, +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_time_now_as_str(buf: *const c_char, len: usize) -> *const c_char { + if len == 0 || buf.is_null() { + return buf; + } + let datetime: DateTime = SystemTime::now().into(); + let s = datetime.format("%Y-%m-%dT%H:%M:%SZ").to_string(); + let res = s.as_str().copy_to_c_array(buf as *mut c_void, len - 1); + *((buf as usize + res) as *mut c_char) = 0; + buf +} + +#[no_mangle] +pub extern "C" fn z_time_now() -> z_time_t { + z_time_t { + t: SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or(Duration::new(0, 0)) + .as_nanos() as u64, + } +} +#[allow(clippy::missing_safety_doc)] +unsafe fn get_elapsed_nanos_system_clock(time: *const z_time_t) -> u64 { + if time.is_null() { + return 0; + } + let now_t = z_time_now().t; + if now_t > (*time).t { + now_t - (*time).t + } else { + 0 + } +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_time_elapsed_s(time: *const z_time_t) -> u64 { + get_elapsed_nanos_system_clock(time) / 1_000_000_000 +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_time_elapsed_ms(time: *const z_time_t) -> u64 { + get_elapsed_nanos_system_clock(time) / 1_000_000 +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_time_elapsed_us(time: *const z_time_t) -> u64 { + get_elapsed_nanos_system_clock(time) / 1_000 +} diff --git a/src/platform/mod.rs b/src/platform/mod.rs index c9f87a9c7..438763afe 100644 --- a/src/platform/mod.rs +++ b/src/platform/mod.rs @@ -1,5 +1,5 @@ // -// Copyright (c) 2017, 2023 ZettaScale Technology. +// Copyright (c) 2017, 2024 ZettaScale Technology. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License 2.0 which is available at @@ -12,5 +12,12 @@ // ZettaScale Zenoh team, // +pub use clock::*; +mod clock; +pub use sleep::*; +mod sleep; pub use synchronization::*; mod synchronization; + +pub use random::*; +mod random; diff --git a/src/platform/random.rs b/src/platform/random.rs new file mode 100644 index 000000000..d466e7b77 --- /dev/null +++ b/src/platform/random.rs @@ -0,0 +1,34 @@ +use std::slice::from_raw_parts_mut; + +use libc::c_void; +use rand::{random, thread_rng, RngCore}; + +#[no_mangle] +pub extern "C" fn z_random_u8() -> u8 { + random::() +} + +#[no_mangle] +pub extern "C" fn z_random_u16() -> u16 { + random::() +} + +#[no_mangle] +pub extern "C" fn z_random_u32() -> u32 { + random::() +} + +#[no_mangle] +pub extern "C" fn z_random_u64() -> u64 { + random::() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_random_fill(buf: *mut c_void, len: usize) { + if buf.is_null() || len == 0 { + return; + } + let b: &mut [u8] = from_raw_parts_mut(buf as *mut u8, len); + thread_rng().fill_bytes(b); +} diff --git a/src/platform/sleep.rs b/src/platform/sleep.rs new file mode 100644 index 000000000..b2f3e4dd7 --- /dev/null +++ b/src/platform/sleep.rs @@ -0,0 +1,19 @@ +use std::{thread, time}; + +#[no_mangle] +pub extern "C" fn z_sleep_s(time: usize) -> i8 { + thread::sleep(time::Duration::from_secs(time as u64)); + 0 +} + +#[no_mangle] +pub extern "C" fn z_sleep_ms(time: usize) -> i8 { + thread::sleep(time::Duration::from_millis(time as u64)); + 0 +} + +#[no_mangle] +pub extern "C" fn z_sleep_us(time: usize) -> i8 { + thread::sleep(time::Duration::from_micros(time as u64)); + 0 +} diff --git a/src/scouting.rs b/src/scouting.rs index 6df207840..c7dd80be7 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -13,11 +13,11 @@ // use crate::{ z_closure_hello_call, z_config_check, z_config_default, z_config_null, z_config_t, z_id_t, - z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, + z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, CopyableToCArray, }; use async_std::task; use libc::{c_char, c_uint, c_ulong, size_t}; -use std::ffi::CString; +use std::{ffi::CString, os::raw::c_void}; use zenoh::scouting::Hello; use zenoh_protocol::core::{whatami::WhatAmIMatcher, WhatAmI}; use zenoh_util::core::AsyncResolve; @@ -268,3 +268,30 @@ pub extern "C" fn z_scout( }); 0 } + +/// Converts the kind of zenoh entity into a string. +/// +/// Parameters: +/// whatami: A whatami bitmask of zenoh entity kind. +/// buf: Buffer to write a null-terminated string to. +/// len: Maximum number of bytes that can be written to the `buf`. +/// +/// Returns 0 if successful, negative values if whatami contains an invalid bitmask or `buf` is null, +/// or number of remaining bytes, if the null-terminated string size exceeds `len`. +#[no_mangle] +pub extern "C" fn z_whatami_to_str(whatami: u8, buf: *mut c_char, len: usize) -> i8 { + if buf.is_null() || len == 0 { + return -1; + } + match WhatAmIMatcher::try_from(whatami) { + Err(_) => -1, + Ok(w) => { + let s = w.to_str(); + let res = s.copy_to_c_array(buf as *mut c_void, len - 1); + unsafe { + *((buf as usize + res) as *mut c_char) = 0; + } + (s.len() - res) as i8 + } + } +} diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 8dcff3317..9ade440f3 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -17,14 +17,6 @@ #undef NDEBUG #include - -#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) -#include -#define sleep(x) Sleep(x * 1000) -#else -#include -#endif - #include "zenoh.h" #define SLEEP 1 @@ -135,7 +127,7 @@ int main(int argc, char **argv) { assert(_ret_int == -1); #endif - sleep(SLEEP); + z_sleep_s(SLEEP); size_t keyexpr_len = strlen(URI); char *keyexpr_str = (char *)z_malloc(keyexpr_len + 1); @@ -157,7 +149,7 @@ int main(int argc, char **argv) { assert(strlen(URI) == keyexpr_len); #endif - sleep(SLEEP); + z_sleep_s(SLEEP); z_owned_config_t _ret_config = z_config_new(); assert(z_check(_ret_config)); @@ -184,7 +176,7 @@ int main(int argc, char **argv) { #endif z_drop(z_move(_ret_sconfig)); - sleep(SLEEP); + z_sleep_s(SLEEP); _ret_sconfig = z_scouting_config_from(z_loan(_ret_config)); z_owned_closure_hello_t _ret_closure_hello = z_closure(hello_handler, NULL, NULL); @@ -192,8 +184,8 @@ int main(int argc, char **argv) { assert(_ret_int8 == 0); assert(hellos == 1); - sleep(atoi(SCOUTING_TIMEOUT) / 1000); - sleep(SLEEP); + z_sleep_s(atoi(SCOUTING_TIMEOUT) / 1000); + z_sleep_s(SLEEP); z_owned_session_t s1 = z_open(z_move(_ret_config)); assert(z_check(s1)); @@ -207,13 +199,13 @@ int main(int argc, char **argv) { z_owned_closure_zid_t _ret_closure_zid = z_closure(zid_handler, NULL, NULL); _ret_int8 = z_info_peers_zid(z_loan(s1), z_move(_ret_closure_zid)); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(zids == 0); _ret_int8 = z_info_routers_zid(z_loan(s1), z_move(_ret_closure_zid)); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(zids == 1); #ifdef ZENOH_PICO @@ -223,7 +215,7 @@ int main(int argc, char **argv) { zp_start_lease_task(z_loan(s1), &_ret_lease_opt); #endif - sleep(SLEEP); + z_sleep_s(SLEEP); _ret_config = z_config_default(); #ifdef ZENOH_PICO @@ -248,7 +240,7 @@ int main(int argc, char **argv) { zp_start_lease_task(z_loan(s2), NULL); #endif - sleep(SLEEP); + z_sleep_s(SLEEP); z_session_t ls1 = z_loan(s1); z_owned_closure_sample_t _ret_closure_sample = z_closure(data_handler, NULL, &ls1); @@ -257,7 +249,7 @@ int main(int argc, char **argv) { z_declare_subscriber(z_loan(s2), z_keyexpr(keyexpr_str), z_move(_ret_closure_sample), &_ret_sub_opt); assert(z_check(_ret_sub)); - sleep(SLEEP); + z_sleep_s(SLEEP); char s1_res[64]; sprintf(s1_res, "%s/chunk/%d", keyexpr_str, 1); @@ -271,14 +263,14 @@ int main(int argc, char **argv) { _ret_int8 = z_put(z_loan(s1), z_loan(_ret_expr), (const uint8_t *)value, strlen(value), &_ret_put_opt); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(datas == 1); z_delete_options_t _ret_delete_opt = z_delete_options_default(); _ret_int8 = z_delete(z_loan(s1), z_loan(_ret_expr), &_ret_delete_opt); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(datas == 2); _ret_int8 = z_undeclare_keyexpr(z_loan(s1), z_move(_ret_expr)); @@ -303,23 +295,23 @@ int main(int argc, char **argv) { _ret_int8 = z_publisher_put(z_loan(_ret_pub), (const uint8_t *)value, strlen(value), &_ret_pput_opt); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); _ret_int8 = z_subscriber_pull(z_loan(_ret_psub)); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(datas == 3); z_publisher_delete_options_t _ret_pdelete_opt = z_publisher_delete_options_default(); _ret_int8 = z_publisher_delete(z_loan(_ret_pub), &_ret_pdelete_opt); - sleep(SLEEP); + z_sleep_s(SLEEP); _ret_int8 = z_subscriber_pull(z_loan(_ret_psub)); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(datas == 4); _ret_int8 = z_undeclare_publisher(z_move(_ret_pub)); @@ -328,7 +320,7 @@ int main(int argc, char **argv) { _ret_int8 = z_undeclare_pull_subscriber(z_move(_ret_psub)); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); z_owned_closure_query_t _ret_closure_query = z_closure(query_handler, NULL, &ls1); z_queryable_options_t _ret_qle_opt = z_queryable_options_default(); @@ -336,7 +328,7 @@ int main(int argc, char **argv) { z_declare_queryable(z_loan(s1), z_keyexpr(s1_res), z_move(_ret_closure_query), &_ret_qle_opt); assert(z_check(qle)); - sleep(SLEEP); + z_sleep_s(SLEEP); z_session_t ls2 = z_loan(s2); z_owned_closure_reply_t _ret_closure_reply = z_closure(reply_handler, NULL, &ls2); @@ -350,7 +342,7 @@ int main(int argc, char **argv) { _ret_int8 = z_get(z_loan(s2), z_keyexpr(s1_res), "", z_move(_ret_closure_reply), &_ret_get_opt); assert(_ret_int8 == 0); - sleep(SLEEP); + z_sleep_s(SLEEP); assert(queries == 1); assert(replies == 1); @@ -372,7 +364,7 @@ int main(int argc, char **argv) { _ret_int8 = z_close(z_move(s2)); assert(_ret_int8 == 0); - sleep(SLEEP * 5); + z_sleep_s(SLEEP * 5); z_free(keyexpr_str); diff --git a/tests/z_api_attachment_test.c b/tests/z_api_attachment_test.c index c11abcbfe..737048e9b 100644 --- a/tests/z_api_attachment_test.c +++ b/tests/z_api_attachment_test.c @@ -29,6 +29,11 @@ void writting_through_map_by_alias_read_by_get() { z_attachment_t attachment = z_bytes_map_as_attachment(&map); // Elements check + + assert(z_bytes_map_len(&map) == 2); + assert(z_attachment_len(attachment) == 2); + assert(!z_attachment_is_empty(attachment)); + z_bytes_t a1 = z_attachment_get(attachment, z_bytes_from_str("k1")); ASSERT_STR_BYTES_EQUAL("v1", a1); @@ -61,6 +66,10 @@ void writting_through_map_by_copy_read_by_iter() { z_attachment_t attachment = z_bytes_map_as_attachment(&map); // Elements check + assert(z_bytes_map_len(&map) == 2); + assert(z_attachment_len(attachment) == 2); + assert(!z_attachment_is_empty(attachment)); + int res = z_attachment_iterate(attachment, _attachment_reader, (void*)42); assert(res == 24); @@ -81,6 +90,9 @@ void writting_no_map_read_by_get() { z_attachment_t attachment = {.data = NULL, .iteration_driver = &_iteration_driver}; // Elements check + assert(z_attachment_len(attachment) == 2); + assert(!z_attachment_is_empty(attachment)); + z_bytes_t a1 = z_attachment_get(attachment, z_bytes_from_str("k1")); ASSERT_STR_BYTES_EQUAL("v1", a1); @@ -94,6 +106,8 @@ void writting_no_map_read_by_get() { void invalid_attachment_safety() { z_attachment_t attachment = z_attachment_null(); + assert(z_attachment_is_empty(attachment)); + assert(z_attachment_len(attachment) == 0); z_bytes_t a_non = z_attachment_get(attachment, z_bytes_from_str("k_non")); assert(a_non.start == NULL); diff --git a/tests/z_api_keyexpr_test.c b/tests/z_api_keyexpr_test.c index b5cdeaad1..cb3c234b3 100644 --- a/tests/z_api_keyexpr_test.c +++ b/tests/z_api_keyexpr_test.c @@ -41,6 +41,22 @@ void canonize() { printf("'%s', err = %d\n", keyexpr, err); assert(err == 0); assert(strcmp(keyexpr, "a/**/c") == 0); + + strcpy(keyexpr, "a/**/**/c"); + z_keyexpr_t key_expr_canonized = z_keyexpr_autocanonize(keyexpr); + assert(z_keyexpr_check(keyexpr) == true); + assert(strcmp(keyexpr, "a/**/c") == 0); + assert(z_keyexpr_as_bytes(key_expr_canonized).len == len_new); + assert(strncmp(z_keyexpr_as_bytes(key_expr_canonized).start, "a/**/c", len_new) == 0); + + strcpy(keyexpr, "a/**/**/c"); + len_new = len_old; + key_expr_canonized = zc_keyexpr_from_slice_autocanonize(keyexpr, &len_new); + assert(z_keyexpr_check(keyexpr) == true); + assert(len_new == len_old - 3); + assert(strncmp(keyexpr, "a/**/c", len_new) == 0); + assert(z_keyexpr_as_bytes(key_expr_canonized).len == len_new); + assert(strncmp(z_keyexpr_as_bytes(key_expr_canonized).start, "a/**/c", len_new) == 0); } void includes() { @@ -73,9 +89,23 @@ void undeclare() { assert(!z_keyexpr_check(&ke)); } +void relation_to() { + z_keyexpr_t nul = z_keyexpr(NULL); + z_keyexpr_t foobar = z_keyexpr("foo/bar"); + z_keyexpr_t foostar = z_keyexpr("foo/*"); + z_keyexpr_t barstar = z_keyexpr("bar/*"); + assert(z_keyexpr_relation_to(foostar, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES); + assert(z_keyexpr_relation_to(foobar, foostar) == Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS); + assert(z_keyexpr_relation_to(foostar, foostar) == Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS); + assert(z_keyexpr_relation_to(barstar, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); + assert(z_keyexpr_relation_to(nul, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); + assert(z_keyexpr_relation_to(foobar, nul) == Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT); +} + int main(int argc, char **argv) { canonize(); includes(); intersects(); undeclare(); + relation_to(); } diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index 7495939f2..868b3878e 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -122,7 +122,7 @@ int run_subscriber() { } SEM_POST(sem_sub); - sleep(10); + z_sleep_s(10); z_drop(z_move(sub)); z_close(z_move(s)); diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index 554d1fd57..bafdd87ca 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -107,7 +107,7 @@ int run_subscriber() { } SEM_POST(sem); - sleep(10); + z_sleep_s(10); z_undeclare_subscriber(z_move(sub)); z_close(z_move(s)); diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 836f8d988..1de9de788 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -76,7 +76,7 @@ int run_queryable() { } SEM_POST(sem); - sleep(10); + z_sleep_s(10); z_drop(z_move(qable)); z_close(z_move(s)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index 67c690f8e..9bcc16cc1 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -59,7 +59,7 @@ int run_queryable() { } SEM_POST(sem); - sleep(10); + z_sleep_s(10); z_drop(z_move(qable)); z_close(z_move(s)); From a2cfa7ff963b62792cd4d50577ffbc5010c76f46 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 28 Mar 2024 12:32:31 +0100 Subject: [PATCH 10/75] merge --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c62eb1df..d29080bad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -417,9 +417,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" dependencies = [ "android-tzdata", "iana-time-zone", From 8499281a3da9849f5f8d1e385198f9e44deec49d Mon Sep 17 00:00:00 2001 From: yellowhatter Date: Fri, 29 Mar 2024 11:39:12 +0300 Subject: [PATCH 11/75] WIP on SHM API --- Cargo.lock | 1155 ++++++++++------- Cargo.toml | 12 +- Cargo.toml.in | 10 +- include/zenoh_commons.h | 440 +++++-- rust-toolchain.toml | 2 +- src/lib.rs | 34 +- src/shm.rs | 226 ---- src/shm/client/mod.rs | 16 + src/shm/client/shared_memory_client.rs | 114 ++ src/shm/client/shared_memory_segment.rs | 69 + src/shm/client_storage/mod.rs | 136 ++ src/shm/common/mod.rs | 15 + src/shm/common/types.rs | 27 + src/shm/mod.rs | 19 + src/shm/protocol_implementations/mod.rs | 15 + src/shm/protocol_implementations/posix/mod.rs | 17 + .../posix/posix_shared_memory_client.rs | 27 + .../posix/posix_shared_memory_provider.rs | 81 ++ .../posix/protocol_id.rs | 17 + src/shm/provider/chunk.rs | 102 ++ src/shm/provider/mod.rs | 19 + src/shm/provider/shared_memory_provider.rs | 206 +++ .../shared_memory_provider_backend.rs | 124 ++ src/shm/provider/types.rs | 200 +++ src/shm/provider/zsliceshm.rs | 35 + 25 files changed, 2356 insertions(+), 762 deletions(-) delete mode 100644 src/shm.rs create mode 100644 src/shm/client/mod.rs create mode 100644 src/shm/client/shared_memory_client.rs create mode 100644 src/shm/client/shared_memory_segment.rs create mode 100644 src/shm/client_storage/mod.rs create mode 100644 src/shm/common/mod.rs create mode 100644 src/shm/common/types.rs create mode 100644 src/shm/mod.rs create mode 100644 src/shm/protocol_implementations/mod.rs create mode 100644 src/shm/protocol_implementations/posix/mod.rs create mode 100644 src/shm/protocol_implementations/posix/posix_shared_memory_client.rs create mode 100644 src/shm/protocol_implementations/posix/posix_shared_memory_provider.rs create mode 100644 src/shm/protocol_implementations/posix/protocol_id.rs create mode 100644 src/shm/provider/chunk.rs create mode 100644 src/shm/provider/mod.rs create mode 100644 src/shm/provider/shared_memory_provider.rs create mode 100644 src/shm/provider/shared_memory_provider_backend.rs create mode 100644 src/shm/provider/types.rs create mode 100644 src/shm/provider/zsliceshm.rs diff --git a/Cargo.lock b/Cargo.lock index f41125887..0dae7374a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", @@ -42,9 +42,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -72,9 +72,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.12" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -92,20 +92,20 @@ checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -120,9 +120,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "array-init" @@ -141,32 +141,45 @@ dependencies = [ "futures-core", ] +[[package]] +name = "async-channel" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +dependencies = [ + "concurrent-queue", + "event-listener 5.2.0", + "event-listener-strategy 0.5.0", + "futures-core", + "pin-project-lite", +] + [[package]] name = "async-executor" -version = "1.5.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" dependencies = [ - "async-lock", + "async-lock 3.3.0", "async-task", "concurrent-queue", - "fastrand 1.9.0", - "futures-lite", + "fastrand 2.0.2", + "futures-lite 2.3.0", "slab", ] [[package]] name = "async-global-executor" -version = "2.3.1" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel", + "async-channel 2.2.0", "async-executor", - "async-io", - "async-lock", + "async-io 2.3.2", + "async-lock 3.3.0", "blocking", - "futures-lite", + "futures-lite 2.3.0", "once_cell", "tokio", ] @@ -177,20 +190,39 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ - "async-lock", + "async-lock 2.8.0", "autocfg", "cfg-if", "concurrent-queue", - "futures-lite", + "futures-lite 1.13.0", "log", "parking", - "polling", - "rustix 0.37.25", + "polling 2.8.0", + "rustix 0.37.27", "slab", - "socket2 0.4.9", + "socket2 0.4.10", "waker-fn", ] +[[package]] +name = "async-io" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +dependencies = [ + "async-lock 3.3.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.3.0", + "parking", + "polling 3.6.0", + "rustix 0.38.32", + "slab", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "async-lock" version = "2.8.0" @@ -200,21 +232,49 @@ dependencies = [ "event-listener 2.5.3", ] +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.3", + "event-listener-strategy 0.4.0", + "pin-project-lite", +] + [[package]] name = "async-process" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" dependencies = [ - "async-io", - "async-lock", - "autocfg", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", "blocking", "cfg-if", - "event-listener 2.5.3", - "futures-lite", - "rustix 0.37.25", - "signal-hook", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.32", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-signal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +dependencies = [ + "async-io 2.3.2", + "async-lock 2.8.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.32", + "signal-hook-registry", + "slab", "windows-sys 0.48.0", ] @@ -224,16 +284,16 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" dependencies = [ - "async-channel", + "async-channel 1.9.0", "async-global-executor", - "async-io", - "async-lock", + "async-io 1.13.0", + "async-lock 2.8.0", "async-process", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite", + "futures-lite 1.13.0", "gloo-timers", "kv-log-macro", "log", @@ -247,26 +307,26 @@ dependencies = [ [[package]] name = "async-task" -version = "4.4.0" +version = "4.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" +checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.55", ] [[package]] name = "atomic-waker" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atty" @@ -281,15 +341,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -302,9 +362,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.4" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -329,9 +389,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "block-buffer" @@ -344,36 +404,37 @@ dependencies = [ [[package]] name = "blocking" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ - "async-channel", - "async-lock", + "async-channel 2.2.0", + "async-lock 3.3.0", "async-task", - "atomic-waker", - "fastrand 1.9.0", - "futures-lite", - "log", + "fastrand 2.0.2", + "futures-io", + "futures-lite 2.3.0", + "piper", + "tracing", ] [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cache-padded" @@ -383,9 +444,9 @@ checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" [[package]] name = "cbindgen" -version = "0.24.5" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b922faaf31122819ec80c4047cc684c6979a087366c069611e33649bf98e18d" +checksum = "da6bc11b07529f16944307272d5bd9b22530bc7d05751717c9d416586cedab49" dependencies = [ "clap", "heck", @@ -402,12 +463,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" [[package]] name = "cfg-if" @@ -417,16 +475,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -471,33 +529,33 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "concurrent-queue" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" dependencies = [ "crossbeam-utils", ] [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_format" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c990efc7a285731f9a4378d81aff2f0e85a2c8781a05ef0f8baa8dac54d0ff48" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e026b6ce194a874cb9cf32cd5772d1ef9767cc8fcb5765948d74f37a9d8b2bf6" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" dependencies = [ "proc-macro2", "quote", @@ -506,9 +564,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -516,28 +574,40 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] -name = "crossbeam-utils" -version = "0.8.16" +name = "crc" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" dependencies = [ - "cfg-if", + "crc-catalog", ] +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + [[package]] name = "crypto-common" version = "0.1.6" @@ -550,9 +620,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "der" @@ -600,9 +670,9 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.13" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "env_filter" @@ -629,9 +699,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" dependencies = [ "anstream", "anstyle", @@ -664,15 +734,57 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "4.0.0" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770d968249b5d99410d61f5bf89057f3199a077a04d087092f58e7d10692baae" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" dependencies = [ "concurrent-queue", "parking", "pin-project-lite", ] +[[package]] +name = "event-listener" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b5fb89194fa3cad959b833185b3063ba881dbfc7030680b314250779fb4cc91" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +dependencies = [ + "event-listener 5.2.0", + "pin-project-lite", +] + [[package]] name = "fastrand" version = "1.9.0" @@ -684,9 +796,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "fixedbitset" @@ -714,9 +826,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -733,9 +845,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -748,9 +860,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -758,15 +870,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -775,9 +887,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -794,34 +906,47 @@ dependencies = [ "waker-fn", ] +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand 2.0.2", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.55", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -847,9 +972,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "js-sys", @@ -860,30 +985,28 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "git-version" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6b0decc02f4636b9ccad390dcbe77b722a77efedfa393caf8379a51d5c61899" +checksum = "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19" dependencies = [ "git-version-macro", - "proc-macro-hack", ] [[package]] name = "git-version-macro" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe69f1cbdb6e28af2bac214e943b99ce8a0a06b447d15d3e61161b0423139f3f" +checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ - "proc-macro-hack", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.55", ] [[package]] @@ -915,9 +1038,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", "allocator-api2", @@ -940,9 +1063,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hmac" @@ -955,18 +1078,18 @@ dependencies = [ [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -987,16 +1110,16 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows 0.48.0", + "windows-core", ] [[package]] @@ -1010,9 +1133,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1030,12 +1153,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.3", ] [[package]] @@ -1062,7 +1185,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi 0.3.9", "libc", "windows-sys 0.48.0", ] @@ -1078,26 +1201,26 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.9" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.3.2", - "rustix 0.38.32", - "windows-sys 0.48.0", + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.52.0", ] [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -1115,9 +1238,9 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] @@ -1157,19 +1280,30 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libloading" -version = "0.8.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d580318f95776505201b28cf98eb1fa5e4be3b689633ba6a3e6cd880ff22d8cb" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-targets 0.52.4", ] [[package]] name = "libm" -version = "0.2.7" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.5.0", + "libc", + "redox_syscall", +] [[package]] name = "linux-raw-sys" @@ -1185,37 +1319,46 @@ checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", ] +[[package]] +name = "lockfree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ee94b5ad113c7cb98c5a040f783d0952ee4fe100993881d1673c2cb002dd23" +dependencies = [ + "owned-alloc", +] + [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" dependencies = [ "value-bag", ] [[package]] name = "lz4_flex" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea9b256699eda7b0387ffbc776dd625e28bde3918446381781245b7a50349d8" +checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" dependencies = [ "twox-hash", ] [[package]] name = "memchr" -version = "2.6.3" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "memoffset" @@ -1228,9 +1371,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] @@ -1274,7 +1417,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.5.0", "cfg-if", "libc", ] @@ -1304,19 +1447,18 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" dependencies = [ "autocfg", "num-integer", @@ -1325,9 +1467,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -1339,24 +1481,24 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl-probe" @@ -1372,9 +1514,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-float" -version = "4.1.1" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "536900a8093134cf9ccf00a27deb3532421099e958d9dd431135d0c7543ca1e8" +checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" dependencies = [ "num-traits", ] @@ -1385,11 +1527,17 @@ version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +[[package]] +name = "owned-alloc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30fceb411f9a12ff9222c5f824026be368ff15dc2f13468d850c7d3f502205d6" + [[package]] name = "parking" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "paste" @@ -1408,15 +1556,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.3" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" +checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" dependencies = [ "memchr", "thiserror", @@ -1425,9 +1573,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.3" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" +checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" dependencies = [ "pest", "pest_generator", @@ -1435,22 +1583,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.3" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" +checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.55", ] [[package]] name = "pest_meta" -version = "2.7.3" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" +checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" dependencies = [ "once_cell", "pest", @@ -1464,7 +1612,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.0.0", + "indexmap 2.2.6", ] [[package]] @@ -1479,6 +1627,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.2", + "futures-io", +] + [[package]] name = "pkcs1" version = "0.7.5" @@ -1548,6 +1707,21 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "polling" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0c976a60b2d7e99d6f229e414670a9b85d13ac305cc6d1e9c134de58c5aaaf6" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.3.9", + "pin-project-lite", + "rustix 0.38.32", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1555,16 +1729,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" +name = "proc-macro-crate" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -1580,7 +1758,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.21.7", + "rustls 0.21.10", "thiserror", "tokio", "tracing", @@ -1588,15 +1766,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.10.4" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13f81c9a9d574310b8351f8666f5a93ac3b0069c45c28ad52c10291389a7cf9" +checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" dependencies = [ "bytes", "rand", "ring 0.16.20", "rustc-hash", - "rustls 0.21.7", + "rustls 0.21.10", "rustls-native-certs 0.6.3", "slab", "thiserror", @@ -1619,9 +1797,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1658,29 +1836,29 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ "getrandom", - "redox_syscall", + "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.9.5" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", @@ -1690,9 +1868,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -1701,9 +1879,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "ring" @@ -1722,16 +1900,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.6" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684d5e6e18f669ccebf64a92236bb7db9a34f07be010e3627368182027180866" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1746,16 +1925,14 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.2" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" dependencies = [ - "byteorder", "const-oid", "digest", "num-bigint-dig", "num-integer", - "num-iter", "num-traits", "pkcs1", "pkcs8", @@ -1789,9 +1966,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.25" +version = "0.37.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4eb579851244c2c03e7c24f501c3432bed80b8f720af1d6e5b0e0f01555a035" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" dependencies = [ "bitflags 1.3.2", "errno", @@ -1807,7 +1984,7 @@ version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys 0.4.13", @@ -1816,24 +1993,24 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.16.20", - "rustls-webpki 0.101.5", + "ring 0.17.8", + "rustls-webpki 0.101.7", "sct", ] [[package]] name = "rustls" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" dependencies = [ "log", - "ring 0.17.6", + "ring 0.17.8", "rustls-pki-types", "rustls-webpki 0.102.2", "subtle", @@ -1847,7 +2024,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile 1.0.3", + "rustls-pemfile 1.0.4", "schannel", "security-framework", ] @@ -1859,7 +2036,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", - "rustls-pemfile 2.0.0", + "rustls-pemfile 2.1.1", "rustls-pki-types", "schannel", "security-framework", @@ -1867,18 +2044,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ "base64", ] [[package]] name = "rustls-pemfile" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4" +checksum = "f48172685e6ff52a556baa527774f61fcaa884f59daf3375c62a3f1cd2549dab" dependencies = [ "base64", "rustls-pki-types", @@ -1886,18 +2063,18 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.3.1" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" [[package]] name = "rustls-webpki" -version = "0.101.5" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] @@ -1906,31 +2083,37 @@ version = "0.102.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" dependencies = [ - "ring 0.17.6", + "ring 0.17.8", "rustls-pki-types", "untrusted 0.9.0", ] +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "schemars" -version = "0.8.13" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763f8cd0d4c71ed8389c90cb8100cba87e763bd01a8e614d4f0af97bcd50a161" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "schemars_derive", @@ -1940,9 +2123,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.13" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0f696e21e10fa546b7ffb1c9672c6de8fbc7a81acf59524386d8639bf12737" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -1958,12 +2141,12 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] @@ -2001,28 +2184,28 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.55", ] [[package]] @@ -2038,9 +2221,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", @@ -2049,11 +2232,11 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.25" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.2.6", "itoa", "ryu", "serde", @@ -2062,9 +2245,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", @@ -2073,15 +2256,21 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", "digest", ] +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + [[package]] name = "sha3" version = "0.10.8" @@ -2114,16 +2303,6 @@ dependencies = [ "dirs", ] -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -2135,9 +2314,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", "rand_core", @@ -2154,15 +2333,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -2195,14 +2374,50 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", ] +[[package]] +name = "stabby" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad55eaa7e95bd8f952922221460336fd352bc6680fecabaf7d692205f2b56750" +dependencies = [ + "lazy_static", + "rustversion", + "stabby-abi", +] + +[[package]] +name = "stabby-abi" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a36348288e2ef8ba107386fdebee3238f54b3e709ecadd43ed5556137b456a7" +dependencies = [ + "libc", + "rustversion", + "sha2-const-stable", + "stabby-macros", +] + +[[package]] +name = "stabby-macros" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6aa9f59e8bf047add442a0615d880a333d67eac517b1db9401bbc57983f82b0" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "rand", + "syn 1.0.109", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -2215,7 +2430,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" dependencies = [ - "async-channel", + "async-channel 1.9.0", "cfg-if", "futures-core", "pin-project-lite", @@ -2246,9 +2461,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.33" +version = "2.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" dependencies = [ "proc-macro2", "quote", @@ -2262,7 +2477,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.1", + "fastrand 2.0.2", "rustix 0.38.32", "windows-sys 0.52.0", ] @@ -2284,22 +2499,36 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.55", +] + +[[package]] +name = "thread-priority" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72cb4958060ee2d9540cef68bb3871fd1e547037772c7fe7650d5d1cbec53b3" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "log", + "rustversion", + "winapi", ] [[package]] @@ -2328,9 +2557,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -2351,7 +2580,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.55", ] [[package]] @@ -2360,7 +2589,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.7", + "rustls 0.21.10", "tokio", ] @@ -2370,7 +2599,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.22.2", + "rustls 0.22.3", "rustls-pki-types", "tokio", ] @@ -2397,7 +2626,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "hashbrown 0.14.0", + "hashbrown 0.14.3", "pin-project-lite", "tokio", ] @@ -2411,13 +2640,29 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -2426,20 +2671,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.55", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] @@ -2475,9 +2720,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" @@ -2501,9 +2746,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -2513,9 +2758,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] @@ -2528,9 +2773,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "unsafe-libyaml" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "untrusted" @@ -2557,9 +2802,9 @@ dependencies = [ [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -2580,9 +2825,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.4.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ "getrandom", ] @@ -2613,9 +2858,9 @@ dependencies = [ [[package]] name = "value-bag" -version = "1.4.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" +checksum = "74797339c3b98616c009c7c3eb53a0ce41e85c8ec66bd3db96ed132d20cfdee8" [[package]] name = "vec_map" @@ -2631,9 +2876,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "waker-fn" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" [[package]] name = "wasi" @@ -2643,9 +2888,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2653,24 +2898,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.55", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -2680,9 +2925,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2690,28 +2935,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.55", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -2719,9 +2964,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de2cfda980f21be5a7ed2eadb3e6fe074d56022bea2cdeb1a62eb220fc04188" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" dependencies = [ "rustls-pki-types", ] @@ -2732,7 +2977,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b7b128a98c1cfa201b09eb49ba285887deb3cbe7466a98850eb1adabb452be5" dependencies = [ - "windows 0.34.0", + "windows", ] [[package]] @@ -2753,9 +2998,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -2780,12 +3025,12 @@ dependencies = [ ] [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.52.4", ] [[package]] @@ -2803,7 +3048,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -2823,17 +3068,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -2844,9 +3089,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -2862,9 +3107,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -2880,9 +3125,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -2898,9 +3143,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -2916,9 +3161,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -2928,9 +3173,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -2946,20 +3191,29 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "async-trait", "base64", "const_format", - "env_logger 0.11.2", - "event-listener 4.0.0", + "env_logger 0.11.3", + "event-listener 4.0.3", "flume", "form_urlencoded", "futures", @@ -3003,9 +3257,10 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "zenoh-collections", + "zenoh-shm", ] [[package]] @@ -3035,7 +3290,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "log", "serde", @@ -3048,16 +3303,15 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "flume", "json5", - "log", "num_cpus", "secrecy", "serde", @@ -3073,7 +3327,7 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "async-global-executor", "lazy_static", @@ -3085,7 +3339,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "aes", "hmac", @@ -3098,10 +3352,10 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "bincode", - "env_logger 0.11.2", + "env_logger 0.11.3", "flume", "futures", "log", @@ -3119,9 +3373,9 @@ dependencies = [ [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ - "hashbrown 0.14.0", + "hashbrown 0.14.3", "keyed-set", "rand", "schemars", @@ -3133,7 +3387,7 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "async-trait", "zenoh-config", @@ -3151,13 +3405,13 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "async-trait", "flume", "futures", "log", - "rustls 0.22.2", + "rustls 0.22.3", "rustls-webpki 0.102.2", "serde", "tokio", @@ -3174,16 +3428,16 @@ dependencies = [ [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "async-trait", "base64", "futures", "log", "quinn", - "rustls 0.21.7", + "rustls 0.21.10", "rustls-native-certs 0.7.0", - "rustls-pemfile 2.0.0", + "rustls-pemfile 2.1.1", "rustls-webpki 0.102.2", "secrecy", "tokio", @@ -3202,7 +3456,7 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "async-trait", "log", @@ -3220,14 +3474,14 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "async-trait", "base64", "futures", "log", - "rustls 0.22.2", - "rustls-pemfile 2.0.0", + "rustls 0.22.3", + "rustls-pemfile 2.1.1", "rustls-pki-types", "rustls-webpki 0.102.2", "secrecy", @@ -3248,7 +3502,7 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "async-trait", "log", @@ -3269,7 +3523,7 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "async-trait", "futures", @@ -3289,7 +3543,7 @@ dependencies = [ [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "async-trait", "futures-util", @@ -3310,18 +3564,18 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.55", "zenoh-keyexpr", ] [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "const_format", "libloading", @@ -3337,7 +3591,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "const_format", "rand", @@ -3351,7 +3605,7 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "anyhow", ] @@ -3359,7 +3613,7 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "lazy_static", "tokio", @@ -3370,21 +3624,32 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ + "async-trait", + "bincode", + "crc", + "lazy_static", + "lockfree", "log", + "num-traits", + "rand", "serde", "shared_memory", - "zenoh-buffers", + "stabby", + "thread-priority", + "tokio", + "zenoh-core", + "zenoh-macros", "zenoh-result", ] [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ - "event-listener 4.0.0", + "event-listener 4.0.3", "futures", "tokio", "zenoh-buffers", @@ -3396,7 +3661,7 @@ dependencies = [ [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "async-trait", "flume", @@ -3428,7 +3693,7 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#1d1df0eeec3b897079a9aa5f8441c7fddb83d196" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" dependencies = [ "async-std", "async-trait", @@ -3464,11 +3729,11 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.55", ] [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml index 95867f95f..03f7b6925 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,19 +51,19 @@ log = "0.4.17" rand = "0.8.5" spin = "0.9.5" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["unstable"] } [build-dependencies] -cbindgen = "0.24.3" +cbindgen = "0.26.0" fs2 = "0.4.3" serde_yaml = "0.9.19" [lib] path="src/lib.rs" -name = "zenohc" +name = "zenohcd" crate-type = ["cdylib", "staticlib"] doctest = false diff --git a/Cargo.toml.in b/Cargo.toml.in index f434df3a1..8918983d2 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -51,13 +51,13 @@ log = "0.4.17" rand = "0.8.5" spin = "0.9.5" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["unstable"] } [build-dependencies] -cbindgen = "0.24.3" +cbindgen = "0.26.0" fs2 = "0.4.3" serde_yaml = "0.9.19" diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 6e45ed3d1..e3c58e384 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -15,6 +15,18 @@ #define ALIGN(n) #define ZENOHC_API #endif +/** + * Allocation errors + * + * - **NEED_DEFRAGMENT**: defragmentation needed + * - **OUT_OF_MEMORY**: the provider is out of memory + * - **OTHER**: other error + */ +typedef enum z_alloc_error_t { + Z_ALLOC_ERROR_NEED_DEFRAGMENT, + Z_ALLOC_ERROR_OUT_OF_MEMORY, + Z_ALLOC_ERROR_OTHER, +} z_alloc_error_t; /** * The kind of congestion control. * @@ -162,6 +174,43 @@ typedef enum zcu_reply_keyexpr_t { ZCU_REPLY_KEYEXPR_ANY = 0, ZCU_REPLY_KEYEXPR_MATCHING_QUERY = 1, } zcu_reply_keyexpr_t; +/** + * An AllocatedChunk. + */ +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_allocated_chunk_t { + uint64_t _0[3]; +} z_allocated_chunk_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_allocated_chunk_t { + uint64_t _0[4]; +} z_allocated_chunk_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_allocated_chunk_t { + uint64_t _0[3]; +} z_allocated_chunk_t; +#endif +/** + * Unique segment identifier + */ +typedef uint32_t z_segment_id_t; +/** + * Chunk id within it's segment + */ +typedef uint32_t z_chunk_id_t; +typedef struct zc_chunk_descriptor_data_t { + z_segment_id_t segment; + z_chunk_id_t chunk; + size_t len; +} zc_chunk_descriptor_data_t; +/** + * A ChunkDescriptor + */ +typedef struct z_chunk_descriptor_t { + struct zc_chunk_descriptor_data_t _0; +} z_chunk_descriptor_t; /** * A contiguous view of bytes owned by some other entity. * @@ -203,6 +252,36 @@ typedef struct z_attachment_t { const void *data; z_attachment_iter_driver_t iteration_driver; } z_attachment_t; +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_buf_alloc_result_t { + uint64_t _0[10]; +} z_buf_alloc_result_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_buf_alloc_result_t { + uint64_t _0[10]; +} z_buf_alloc_result_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_buf_alloc_result_t { + uint64_t _0[10]; +} z_buf_alloc_result_t; +#endif +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_slice_shm_t { + uint64_t _0[10]; +} z_slice_shm_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_slice_shm_t { + uint64_t _0[10]; +} z_slice_shm_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_slice_shm_t { + uint64_t _0[10]; +} z_slice_shm_t; +#endif /** * A map of maybe-owned vector of bytes to owned vector of bytes. * @@ -212,6 +291,29 @@ typedef struct z_owned_bytes_map_t { uint64_t _0[2]; size_t _1[4]; } z_owned_bytes_map_t; +/** + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_chunk_alloc_result_t { + uint64_t _0[4]; +} z_chunk_alloc_result_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_chunk_alloc_result_t { + uint64_t _0[4]; +} z_chunk_alloc_result_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_chunk_alloc_result_t { + uint64_t _0[4]; +} z_chunk_alloc_result_t; +#endif /** * Clock * Uses monotonic clock @@ -717,6 +819,71 @@ typedef struct z_hello_t { typedef struct z_owned_str_t { char *_cstr; } z_owned_str_t; +/** + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_memory_layout_t { + uint64_t _0[2]; +} z_memory_layout_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_memory_layout_t { + uint64_t _0[2]; +} z_memory_layout_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_memory_layout_t { + uint64_t _0[2]; +} z_memory_layout_t; +#endif +/** + * A SharedMemoryClient + */ +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_shared_memory_client_t { + uint64_t _0[2]; +} z_shared_memory_client_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_shared_memory_client_t { + uint64_t _0[2]; +} z_shared_memory_client_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_shared_memory_client_t { + uint64_t _0[2]; +} z_shared_memory_client_t; +#endif +/** + * An owned SharedMemoryProvider with POSIX backend + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_posix_shared_memory_provider_t { + uint64_t _0[26]; +} z_posix_shared_memory_provider_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_posix_shared_memory_provider_t { + uint64_t _0[26]; +} z_posix_shared_memory_provider_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_posix_shared_memory_provider_t { + uint64_t _0[26]; +} z_posix_shared_memory_provider_t; +#endif /** * A loaned zenoh publisher. */ @@ -826,6 +993,112 @@ typedef struct z_owned_scouting_config_t { unsigned long zc_timeout_ms; uint8_t zc_what; } z_owned_scouting_config_t; +/** + * A droppable context + */ +typedef struct zc_context_t { + void *context; + void (*drop_fn)(void*); +} zc_context_t; +/** + * A callbacks for SharedMemorySegment + */ +typedef struct zc_shared_memory_segment_callbacks_t { + void (*map_fn)(void*, z_chunk_id_t); +} zc_shared_memory_segment_callbacks_t; +/** + * A SharedMemorySegment + */ +typedef struct z_shared_memory_segment_t { + struct zc_context_t context; + struct zc_shared_memory_segment_callbacks_t callbacks; +} z_shared_memory_segment_t; +/** + * A callbacks for SharedMemoryClient + */ +typedef struct zc_shared_memory_client_callbacks_t { + bool (*attach_fn)(void*, z_segment_id_t, struct z_shared_memory_segment_t*); +} zc_shared_memory_client_callbacks_t; +/** + * A SharedMemoryClientStorage. + */ +typedef struct z_shared_memory_client_storage_t { + size_t _0; +} z_shared_memory_client_storage_t; +/** + * A list of SharedMemoryClients. + */ +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) zc_shared_memory_client_list_t { + uint64_t _0[3]; +} zc_shared_memory_client_list_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) zc_shared_memory_client_list_t { + uint64_t _0[4]; +} zc_shared_memory_client_list_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) zc_shared_memory_client_list_t { + uint64_t _0[3]; +} zc_shared_memory_client_list_t; +#endif +/** + * An owned SharedMemoryProvider + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_shared_memory_provider_t { + uint64_t _0[14]; +} z_shared_memory_provider_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_shared_memory_provider_t { + uint64_t _0[14]; +} z_shared_memory_provider_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_shared_memory_provider_t { + uint64_t _0[14]; +} z_shared_memory_provider_t; +#endif +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(4) z_alloc_alignment_t { + uint32_t _0[1]; +} z_alloc_alignment_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(4) z_alloc_alignment_t { + uint32_t _0[1]; +} z_alloc_alignment_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(4) z_alloc_alignment_t { + uint32_t _0[1]; +} z_alloc_alignment_t; +#endif +/** + * Unique protocol identifier. + * Here is a contract: it is up to user to make sure that incompatible SharedMemoryClient + * and SharedMemoryProviderBackend implementations will never use the same ProtocolID + */ +typedef uint32_t z_protocol_id_t; +/** + * A callbacks for SharedMemoryProviderBackend + */ +typedef struct zc_shared_memory_provider_backend_callbacks_t { + void (*alloc_fn)(void*, const struct z_memory_layout_t*, struct z_chunk_alloc_result_t*); + void (*free_fn)(void*, const struct z_chunk_descriptor_t*); + size_t (*defragment_fn)(void*); + size_t (*available_fn)(void*); + bool (*layout_for_fn)(void*, const struct z_memory_layout_t*, struct z_memory_layout_t*); + void (*drop_fn)(void*); +} zc_shared_memory_provider_backend_callbacks_t; /** * A loaned zenoh subscriber. */ @@ -893,12 +1166,6 @@ typedef struct zc_owned_payload_t { struct z_bytes_t payload; size_t _owner[5]; } zc_owned_payload_t; -typedef struct zc_owned_shmbuf_t { - size_t _0[9]; -} zc_owned_shmbuf_t; -typedef struct zc_owned_shm_manager_t { - size_t _0; -} zc_owned_shm_manager_t; /** * A struct that indicates if there exist Subscribers matching the Publisher's key expression. * @@ -1032,6 +1299,11 @@ ZENOHC_API extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; ZENOHC_API extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; ZENOHC_API extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; ZENOHC_API extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; +ZENOHC_API void z_allocated_chunk_delete(struct z_allocated_chunk_t val); +ZENOHC_API +void z_allocated_chunk_new(struct z_chunk_descriptor_t descriptor, + uint8_t *data, + struct z_allocated_chunk_t *out_val); /** * Returns the gravestone value for `z_attachment_t`. */ @@ -1066,6 +1338,11 @@ ZENOHC_API size_t z_attachment_len(struct z_attachment_t this_); * Returns the gravestone value for `z_attachment_t`. */ ZENOHC_API struct z_attachment_t z_attachment_null(void); +ZENOHC_API void z_buf_alloc_result_delete(struct z_buf_alloc_result_t result); +ZENOHC_API +bool z_buf_alloc_result_unwrap(struct z_buf_alloc_result_t alloc_result, + struct z_slice_shm_t *out_buf, + enum z_alloc_error_t *out_error); /** * Returns ``true`` if `b` is initialized. */ @@ -1178,6 +1455,19 @@ ZENOHC_API struct z_bytes_t z_bytes_null(void); * Constructs a `len` bytes long view starting at `start`. */ ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); +ZENOHC_API void z_chunk_alloc_result_delete(struct z_chunk_alloc_result_t result); +ZENOHC_API +void z_chunk_alloc_result_new_error(enum z_alloc_error_t alloc_error, + struct z_chunk_alloc_result_t *out_result); +ZENOHC_API +void z_chunk_alloc_result_new_ok(struct z_allocated_chunk_t allocated_chunk, + struct z_chunk_alloc_result_t *out_result); +ZENOHC_API void z_chunk_descriptor_delete(struct z_chunk_descriptor_t val); +ZENOHC_API +void z_chunk_descriptor_new(struct zc_chunk_descriptor_data_t data, + struct z_chunk_descriptor_t *out_val); +ZENOHC_API +struct zc_chunk_descriptor_data_t z_chunk_descriptor_unwrap(struct z_chunk_descriptor_t descriptor); ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); @@ -1715,6 +2005,7 @@ ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t keyexpr); */ ZENOHC_API struct z_keyexpr_t z_keyexpr_unchecked(const char *name); +ZENOHC_API void z_memory_layout_delete(struct z_memory_layout_t layout); ZENOHC_API int8_t z_mutex_free(struct z_mutex_t *m); ZENOHC_API int8_t z_mutex_init(struct z_mutex_t *m); ZENOHC_API int8_t z_mutex_lock(struct z_mutex_t *m); @@ -1725,6 +2016,10 @@ ZENOHC_API int8_t z_mutex_unlock(struct z_mutex_t *m); */ ZENOHC_API struct z_owned_session_t z_open(struct z_owned_config_t *config); +ZENOHC_API struct z_shared_memory_client_t z_posix_shared_memory_client_new(void); +ZENOHC_API +bool z_posix_shared_memory_provider_new(const struct z_memory_layout_t *layout, + struct z_posix_shared_memory_provider_t *out_provider); /** * Returns ``true`` if `pub` is valid. */ @@ -2082,6 +2377,62 @@ struct z_session_t z_session_loan(const struct z_owned_session_t *s); * Constructs a null safe-to-drop value of 'z_owned_session_t' type */ ZENOHC_API struct z_owned_session_t z_session_null(void); +ZENOHC_API void z_shared_memory_client_delete(struct z_shared_memory_client_t client); +ZENOHC_API +void z_shared_memory_client_new(struct zc_context_t context, + struct zc_shared_memory_client_callbacks_t callbacks, + struct z_shared_memory_client_t *out_client); +ZENOHC_API +void z_shared_memory_client_storage_deref(struct z_shared_memory_client_storage_t storage); +ZENOHC_API struct z_shared_memory_client_storage_t z_shared_memory_client_storage_global(void); +ZENOHC_API +bool z_shared_memory_client_storage_new(struct zc_shared_memory_client_list_t clients, + struct z_shared_memory_client_storage_t *out_storage); +ZENOHC_API +bool z_shared_memory_client_storage_new_with_default_client_set(struct zc_shared_memory_client_list_t clients, + struct z_shared_memory_client_storage_t *out_storage); +ZENOHC_API +bool z_shared_memory_provider_alloc(const struct z_shared_memory_provider_t *provider, + size_t size, + struct z_alloc_alignment_t alignment, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +bool z_shared_memory_provider_alloc_gc(const struct z_shared_memory_provider_t *provider, + size_t size, + struct z_alloc_alignment_t alignment, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +bool z_shared_memory_provider_alloc_gc_defrag(const struct z_shared_memory_provider_t *provider, + size_t size, + struct z_alloc_alignment_t alignment, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +bool z_shared_memory_provider_alloc_gc_defrag_blocking(const struct z_shared_memory_provider_t *provider, + size_t size, + struct z_alloc_alignment_t alignment, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +bool z_shared_memory_provider_alloc_gc_defrag_dealloc(const struct z_shared_memory_provider_t *provider, + size_t size, + struct z_alloc_alignment_t alignment, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +size_t z_shared_memory_provider_available(const struct z_shared_memory_provider_t *provider); +ZENOHC_API +size_t z_shared_memory_provider_defragment(const struct z_shared_memory_provider_t *provider); +ZENOHC_API void z_shared_memory_provider_delete(struct z_shared_memory_provider_t provider); +ZENOHC_API +size_t z_shared_memory_provider_garbage_collect(const struct z_shared_memory_provider_t *provider); +ZENOHC_API +bool z_shared_memory_provider_map(const struct z_shared_memory_provider_t *provider, + struct z_allocated_chunk_t allocated_chunk, + size_t len, + struct z_slice_shm_t *out_buffer); +ZENOHC_API +void z_shared_memory_provider_new(z_protocol_id_t id, + struct zc_context_t context, + struct zc_shared_memory_provider_backend_callbacks_t callbacks, + struct z_shared_memory_provider_t *out_provider); ZENOHC_API int8_t z_sleep_ms(size_t time); ZENOHC_API int8_t z_sleep_s(size_t time); ZENOHC_API int8_t z_sleep_us(size_t time); @@ -2483,79 +2834,12 @@ ZENOHC_API struct zc_owned_payload_t zc_sample_payload_rcinc(const struct z_samp * Increments the session's reference count, returning a new owning handle. */ ZENOHC_API struct z_owned_session_t zc_session_rcinc(struct z_session_t session); -/** - * Allocates a buffer of size `capacity` in the manager's memory. - * - * # Safety - * Calling this function concurrently with other shm functions on the same manager is UB. - */ -ZENOHC_API -struct zc_owned_shmbuf_t zc_shm_alloc(const struct zc_owned_shm_manager_t *manager, - size_t capacity); -/** - * Runs a defragmentation pass on the SHM manager. - * - * Note that this doesn't trigger a garbage collection pass, nor does it move currently allocated data. - * - * # Safety - * Calling this function concurrently with other shm functions on the same manager is UB. - */ -ZENOHC_API -size_t zc_shm_defrag(const struct zc_owned_shm_manager_t *manager); -/** - * Runs a garbage collection pass on the SHM manager. - * - * Returns the number of bytes that have been freed by the pass. - * - * # Safety - * Calling this function concurrently with other shm functions on the same manager is UB. - */ -ZENOHC_API size_t zc_shm_gc(const struct zc_owned_shm_manager_t *manager); -ZENOHC_API bool zc_shm_manager_check(const struct zc_owned_shm_manager_t *manager); -ZENOHC_API void zc_shm_manager_drop(struct zc_owned_shm_manager_t *manager); -ZENOHC_API -struct zc_owned_shm_manager_t zc_shm_manager_new(struct z_session_t session, - const char *id, - size_t size); -ZENOHC_API struct zc_owned_shm_manager_t zc_shm_manager_null(void); -/** - * Returns the capacity of the SHM buffer. - */ -ZENOHC_API size_t zc_shmbuf_capacity(const struct zc_owned_shmbuf_t *buf); -/** - * Returns `false` if `buf` is in its gravestone state. - */ -ZENOHC_API bool zc_shmbuf_check(const struct zc_owned_shmbuf_t *buf); -/** - * Drops the SHM buffer, decrementing its backing reference counter. - */ -ZENOHC_API void zc_shmbuf_drop(struct zc_owned_shmbuf_t *buf); -/** - * Constructs an owned payload from an owned SHM buffer. - */ -ZENOHC_API struct zc_owned_payload_t zc_shmbuf_into_payload(struct zc_owned_shmbuf_t *buf); -/** - * Returns the length of the SHM buffer. - * - * Note that when constructing an SHM buffer, length is defaulted to its capacity. - */ -ZENOHC_API size_t zc_shmbuf_length(const struct zc_owned_shmbuf_t *buf); -/** - * Constructs a null safe-to-drop value of type `zc_owned_shmbuf_t` - */ -ZENOHC_API struct zc_owned_shmbuf_t zc_shmbuf_null(void); -/** - * Returns the start of the SHM buffer. - */ -ZENOHC_API uint8_t *zc_shmbuf_ptr(const struct zc_owned_shmbuf_t *buf); -/** - * Sets the length of the SHM buffer. - * - * This lets Zenoh know how much of the data to write over the network when sending the value to non-SHM-compatible neighboors. - */ ZENOHC_API -void zc_shmbuf_set_length(const struct zc_owned_shmbuf_t *buf, - size_t len); +void zc_shared_memory_client_list_add(z_protocol_id_t id, + struct z_shared_memory_client_t client, + struct zc_shared_memory_client_list_t *list); +ZENOHC_API void zc_shared_memory_client_list_delete(struct zc_shared_memory_client_list_t list); +ZENOHC_API struct zc_shared_memory_client_list_t zc_shared_memory_client_list_new(void); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 743f7cd99..8142c3012 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.72.0" +channel = "1.73.0" diff --git a/src/lib.rs b/src/lib.rs index de6584885..08c1c1e60 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,10 +56,33 @@ pub mod attachment; pub use platform::*; pub mod platform; #[cfg(feature = "shared-memory")] -mod shm; +pub mod shm; +#[cfg(feature = "shared-memory")] +pub use crate::shm::*; trait GuardedTransmute { fn transmute(self) -> D; + fn transmute_ref(&self) -> &D; + fn transmute_mut(&mut self) -> &mut D; +} + +#[macro_export] +macro_rules! decl_rust_copy_type { + (zenoh:($zenoh_type:ty), c:($c_type:ty)) => { + impl_guarded_transmute!($zenoh_type, $c_type); + impl_guarded_transmute!($c_type, $zenoh_type); + + impl From<$zenoh_type> for $c_type { + fn from(value: $zenoh_type) -> Self { + value.transmute() + } + } + impl From<$c_type> for $zenoh_type { + fn from(value: $c_type) -> Self { + value.transmute() + } + } + }; } #[macro_export] @@ -81,10 +104,19 @@ macro_rules! impl_guarded_transmute { }); } }; + impl $crate::GuardedTransmute<$dst_type> for $src_type { fn transmute(self) -> $dst_type { unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } } + + fn transmute_ref(&self) -> &$dst_type { + unsafe { std::mem::transmute::<&$src_type, &$dst_type>(self) } + } + + fn transmute_mut(&mut self) -> &mut $dst_type { + unsafe { std::mem::transmute::<&mut $src_type, &mut $dst_type>(self) } + } } }; } diff --git a/src/shm.rs b/src/shm.rs deleted file mode 100644 index 50f8b7236..000000000 --- a/src/shm.rs +++ /dev/null @@ -1,226 +0,0 @@ -// -// Copyright (c) 2017, 2022 ZettaScale Technology. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh team, -// - -use std::{ - cell::UnsafeCell, - ops::{Deref, DerefMut}, -}; - -use libc::c_char; -use zenoh::{ - buffers::ZBuf, - shm::{SharedMemoryBuf, SharedMemoryManager}, -}; - -use crate::{z_session_t, zc_owned_payload_t, zc_payload_null}; - -#[repr(C)] -pub struct zc_owned_shm_manager_t(usize); -impl From>>> for zc_owned_shm_manager_t { - fn from(value: Option>>) -> Self { - unsafe { std::mem::transmute(value) } - } -} -impl Deref for zc_owned_shm_manager_t { - type Target = Option>>; - fn deref(&self) -> &Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl DerefMut for zc_owned_shm_manager_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl zc_owned_shm_manager_t { - pub fn null() -> Self { - None::<_>.into() - } -} - -#[no_mangle] -pub extern "C" fn zc_shm_manager_new( - session: z_session_t, - id: *const c_char, - size: usize, -) -> zc_owned_shm_manager_t { - let _ = session; // This function will likely need the session in the future, so we start doing the association now - (move || { - let len = unsafe { libc::strlen(id) }; - let id = unsafe { std::str::from_utf8(std::slice::from_raw_parts(id as *const u8, len)) } - .ok()? - .to_owned(); - Some(Box::new(UnsafeCell::new( - SharedMemoryManager::make(id, size).ok()?, - ))) - })() - .into() -} - -#[no_mangle] -pub extern "C" fn zc_shm_manager_drop(manager: &mut zc_owned_shm_manager_t) { - manager.take(); -} - -#[no_mangle] -pub extern "C" fn zc_shm_manager_check(manager: &zc_owned_shm_manager_t) -> bool { - manager.is_some() -} - -#[no_mangle] -pub extern "C" fn zc_shm_manager_null() -> zc_owned_shm_manager_t { - zc_owned_shm_manager_t::null() -} - -/// Runs a garbage collection pass on the SHM manager. -/// -/// Returns the number of bytes that have been freed by the pass. -/// -/// # Safety -/// Calling this function concurrently with other shm functions on the same manager is UB. -#[no_mangle] -pub unsafe extern "C" fn zc_shm_gc(manager: &zc_owned_shm_manager_t) -> usize { - if let Some(shm) = manager.as_ref() { - unsafe { (*shm.get()).garbage_collect() } - } else { - 0 - } -} - -/// Runs a defragmentation pass on the SHM manager. -/// -/// Note that this doesn't trigger a garbage collection pass, nor does it move currently allocated data. -/// -/// # Safety -/// Calling this function concurrently with other shm functions on the same manager is UB. -#[no_mangle] -pub unsafe extern "C" fn zc_shm_defrag(manager: &zc_owned_shm_manager_t) -> usize { - if let Some(shm) = manager.as_ref() { - unsafe { (*shm.get()).defragment() } - } else { - 0 - } -} - -#[repr(C)] -#[derive(Default)] -pub struct zc_owned_shmbuf_t([usize; 9]); -impl From>> for zc_owned_shmbuf_t { - fn from(value: UnsafeCell>) -> Self { - unsafe { std::mem::transmute(value) } - } -} -impl Deref for zc_owned_shmbuf_t { - type Target = UnsafeCell>; - fn deref(&self) -> &Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl DerefMut for zc_owned_shmbuf_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { std::mem::transmute(self) } - } -} - -impl zc_owned_shmbuf_t { - pub fn null() -> Self { - UnsafeCell::new(None).into() - } -} - -/// Allocates a buffer of size `capacity` in the manager's memory. -/// -/// # Safety -/// Calling this function concurrently with other shm functions on the same manager is UB. -#[no_mangle] -pub unsafe extern "C" fn zc_shm_alloc( - manager: &zc_owned_shm_manager_t, - capacity: usize, -) -> zc_owned_shmbuf_t { - manager - .as_ref() - .map(|shm| unsafe { - match (*shm.get()).alloc(capacity) { - Ok(buf) => std::mem::transmute(buf), - Err(_) => Default::default(), - } - }) - .unwrap_or_default() -} - -/// Drops the SHM buffer, decrementing its backing reference counter. -#[no_mangle] -pub extern "C" fn zc_shmbuf_drop(buf: &mut zc_owned_shmbuf_t) { - buf.get_mut().take(); -} - -/// Returns `false` if `buf` is in its gravestone state. -#[no_mangle] -pub extern "C" fn zc_shmbuf_check(buf: &zc_owned_shmbuf_t) -> bool { - unsafe { (*buf.get()).is_some() } -} - -/// Constructs a null safe-to-drop value of type `zc_owned_shmbuf_t` -#[no_mangle] -pub extern "C" fn zc_shmbuf_null() -> zc_owned_shmbuf_t { - zc_owned_shmbuf_t::null() -} - -/// Constructs an owned payload from an owned SHM buffer. -#[no_mangle] -pub extern "C" fn zc_shmbuf_into_payload(buf: &mut zc_owned_shmbuf_t) -> zc_owned_payload_t { - match buf.get_mut().take() { - Some(buf) => ZBuf::from(buf).try_into().unwrap_or_default(), - None => zc_payload_null(), - } -} - -/// Returns the start of the SHM buffer. -#[no_mangle] -pub unsafe extern "C" fn zc_shmbuf_ptr(buf: &zc_owned_shmbuf_t) -> *mut u8 { - match &*buf.get() { - None => std::ptr::null_mut(), - Some(buf) => buf.as_slice().as_ptr().cast_mut(), - } -} - -/// Returns the capacity of the SHM buffer. -#[no_mangle] -pub unsafe extern "C" fn zc_shmbuf_capacity(buf: &zc_owned_shmbuf_t) -> usize { - match &*buf.get() { - None => 0, - Some(buf) => buf.info.length, - } -} - -/// Returns the length of the SHM buffer. -/// -/// Note that when constructing an SHM buffer, length is defaulted to its capacity. -#[no_mangle] -pub unsafe extern "C" fn zc_shmbuf_length(buf: &zc_owned_shmbuf_t) -> usize { - match &*buf.get() { - None => 0, - Some(buf) => buf.len, - } -} - -/// Sets the length of the SHM buffer. -/// -/// This lets Zenoh know how much of the data to write over the network when sending the value to non-SHM-compatible neighboors. -#[no_mangle] -pub unsafe extern "C" fn zc_shmbuf_set_length(buf: &zc_owned_shmbuf_t, len: usize) { - if let Some(buf) = &mut *buf.get() { - buf.len = len - } -} diff --git a/src/shm/client/mod.rs b/src/shm/client/mod.rs new file mode 100644 index 000000000..eab20733e --- /dev/null +++ b/src/shm/client/mod.rs @@ -0,0 +1,16 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +pub mod shared_memory_client; +pub mod shared_memory_segment; diff --git a/src/shm/client/shared_memory_client.rs b/src/shm/client/shared_memory_client.rs new file mode 100644 index 000000000..bd011b7e7 --- /dev/null +++ b/src/shm/client/shared_memory_client.rs @@ -0,0 +1,114 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use std::{mem::MaybeUninit, sync::Arc}; + +use libc::c_void; +use zenoh::{ + shm::{ + client::{ + shared_memory_client::SharedMemoryClient, shared_memory_segment::SharedMemorySegment, + }, + common::types::SegmentID, + }, + Result, +}; +use zenoh_util::core::bail; + +use crate::{ + common::types::z_segment_id_t, + decl_rust_copy_type, impl_guarded_transmute, + provider::shared_memory_provider_backend::{zc_context_t, Context}, + GuardedTransmute, +}; + +use super::shared_memory_segment::{z_shared_memory_segment_t, DynamicSharedMemorySegment}; + +/// A callbacks for SharedMemoryClient +#[derive(Debug)] +#[repr(C)] +pub struct zc_shared_memory_client_callbacks_t { + attach_fn: unsafe extern "C" fn( + *mut c_void, + z_segment_id_t, + &mut MaybeUninit, + ) -> bool, +} + +/// A SharedMemoryClient +#[cfg(target_arch = "x86_64")] +#[repr(C, align(8))] +pub struct z_shared_memory_client_t([u64; 2]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(16))] +pub struct z_shared_memory_client_t([u64; 2]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(8))] +pub struct z_shared_memory_client_t([u64; 2]); + +decl_rust_copy_type!( + zenoh:(Box), + c:(z_shared_memory_client_t) +); + +#[derive(Debug)] +pub struct DynamicSharedMemoryClient { + context: Context, + callbacks: zc_shared_memory_client_callbacks_t, +} + +impl DynamicSharedMemoryClient { + pub fn new(context: Context, callbacks: zc_shared_memory_client_callbacks_t) -> Self { + Self { context, callbacks } + } +} + +unsafe impl Send for DynamicSharedMemoryClient {} +unsafe impl Sync for DynamicSharedMemoryClient {} + +impl SharedMemoryClient for DynamicSharedMemoryClient { + fn attach(&self, segment: SegmentID) -> Result> { + let mut segment_data = MaybeUninit::uninit(); + unsafe { + match (self.callbacks.attach_fn)(self.context.get(), segment, &mut segment_data) { + true => Ok(Arc::new(DynamicSharedMemorySegment::new( + segment_data.assume_init(), + ))), + false => bail!("C Callback returned error"), + } + } + } +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_client_new( + context: zc_context_t, + callbacks: zc_shared_memory_client_callbacks_t, + out_client: &mut MaybeUninit, +) { + let client = Box::new(DynamicSharedMemoryClient::new( + context.transmute(), + callbacks, + )) as Box; + + out_client.write(client.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_client_delete(client: z_shared_memory_client_t) { + let _ = client.transmute(); +} diff --git a/src/shm/client/shared_memory_segment.rs b/src/shm/client/shared_memory_segment.rs new file mode 100644 index 000000000..e9c86d611 --- /dev/null +++ b/src/shm/client/shared_memory_segment.rs @@ -0,0 +1,69 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use std::sync::atomic::AtomicPtr; + +use libc::c_void; +use zenoh::{ + shm::{client::shared_memory_segment::SharedMemorySegment, common::types::ChunkID}, + Result, +}; + +use crate::{ + common::types::z_chunk_id_t, + provider::shared_memory_provider_backend::{zc_context_t, Context}, + GuardedTransmute, +}; + +/// A callbacks for SharedMemorySegment +#[derive(Debug)] +#[repr(C)] +pub struct zc_shared_memory_segment_callbacks_t { + map_fn: unsafe extern "C" fn(*mut c_void, z_chunk_id_t), +} + +/// A SharedMemorySegment +#[derive(Debug)] +#[repr(C)] +pub struct z_shared_memory_segment_t { + context: zc_context_t, + callbacks: zc_shared_memory_segment_callbacks_t, +} + +#[derive(Debug)] +pub struct DynamicSharedMemorySegment { + context: Context, + callbacks: zc_shared_memory_segment_callbacks_t, +} + +impl DynamicSharedMemorySegment { + pub fn new(data: z_shared_memory_segment_t) -> Self { + Self { + context: data.context.transmute(), + callbacks: data.callbacks, + } + } +} + +unsafe impl Send for DynamicSharedMemorySegment {} +unsafe impl Sync for DynamicSharedMemorySegment {} + +impl SharedMemorySegment for DynamicSharedMemorySegment { + fn map(&self, chunk: ChunkID) -> Result> { + unsafe { + (self.callbacks.map_fn)(self.context.get(), chunk); + } + todo!() + } +} diff --git a/src/shm/client_storage/mod.rs b/src/shm/client_storage/mod.rs new file mode 100644 index 000000000..f9b7736ba --- /dev/null +++ b/src/shm/client_storage/mod.rs @@ -0,0 +1,136 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use zenoh::{ + shm::{ + client::shared_memory_client::SharedMemoryClient, client_storage::GLOBAL_CLIENT_STORAGE, + common::types::ProtocolID, + }, + SharedMemoryClientStorage, +}; + +use crate::{ + client::shared_memory_client::z_shared_memory_client_t, common::types::z_protocol_id_t, + decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute, +}; +use std::{mem::MaybeUninit, sync::Arc}; + +/// A list of SharedMemoryClients. +#[cfg(target_arch = "x86_64")] +#[repr(C, align(8))] +pub struct zc_shared_memory_client_list_t([u64; 3]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(16))] +pub struct zc_shared_memory_client_list_t([u64; 4]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(8))] +pub struct zc_shared_memory_client_list_t([u64; 3]); + +decl_rust_copy_type!( + zenoh:(Vec<(ProtocolID, Box)>), + c:(zc_shared_memory_client_list_t) +); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_shared_memory_client_list_new() -> zc_shared_memory_client_list_t { + let result = Vec::default(); + result.transmute() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_shared_memory_client_list_add( + id: z_protocol_id_t, + client: z_shared_memory_client_t, + list: &mut zc_shared_memory_client_list_t, +) { + list.transmute_mut().push((id, client.transmute())); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_shared_memory_client_list_delete(list: zc_shared_memory_client_list_t) { + let _ = list.transmute(); +} + +/// A SharedMemoryClientStorage. +#[repr(C)] +pub struct z_shared_memory_client_storage_t(usize); + +decl_rust_copy_type!( + zenoh:(Arc), + c:(z_shared_memory_client_storage_t) +); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_client_storage_global() -> z_shared_memory_client_storage_t +{ + let result = GLOBAL_CLIENT_STORAGE.clone(); + result.transmute() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_client_storage_deref( + storage: z_shared_memory_client_storage_t, +) { + let _ = storage.transmute(); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_client_storage_new( + clients: zc_shared_memory_client_list_t, + out_storage: &mut MaybeUninit, +) -> bool { + let mut clients = clients.transmute(); + + if let Some((id, client)) = clients.pop() { + let mut builder = SharedMemoryClientStorage::builder().with_client(id, client); + + for (id, client) in clients.drain(0..) { + match builder.with_client(id, client) { + Ok(b) => builder = b, + Err(_) => return false, + } + } + out_storage.write(Arc::new(builder.build()).transmute()); + return true; + } + false +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_client_storage_new_with_default_client_set( + clients: zc_shared_memory_client_list_t, + out_storage: &mut MaybeUninit, +) -> bool { + let mut builder = SharedMemoryClientStorage::builder().with_default_client_set(); + + let mut clients = clients.transmute(); + + for (id, client) in clients.drain(0..) { + match builder.with_client(id, client) { + Ok(b) => builder = b, + Err(_) => return false, + } + } + out_storage.write(Arc::new(builder.build()).transmute()); + true +} diff --git a/src/shm/common/mod.rs b/src/shm/common/mod.rs new file mode 100644 index 000000000..222c7286b --- /dev/null +++ b/src/shm/common/mod.rs @@ -0,0 +1,15 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +pub mod types; diff --git a/src/shm/common/types.rs b/src/shm/common/types.rs new file mode 100644 index 000000000..4b4d7518f --- /dev/null +++ b/src/shm/common/types.rs @@ -0,0 +1,27 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +/// Unique protocol identifier. +/// Here is a contract: it is up to user to make sure that incompatible SharedMemoryClient +/// and SharedMemoryProviderBackend implementations will never use the same ProtocolID +#[allow(non_camel_case_types)] +pub type z_protocol_id_t = u32; + +/// Unique segment identifier +#[allow(non_camel_case_types)] +pub type z_segment_id_t = u32; + +/// Chunk id within it's segment +#[allow(non_camel_case_types)] +pub type z_chunk_id_t = u32; diff --git a/src/shm/mod.rs b/src/shm/mod.rs new file mode 100644 index 000000000..6eeb0122a --- /dev/null +++ b/src/shm/mod.rs @@ -0,0 +1,19 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +pub mod client; +pub mod client_storage; +pub mod common; +pub mod protocol_implementations; +pub mod provider; diff --git a/src/shm/protocol_implementations/mod.rs b/src/shm/protocol_implementations/mod.rs new file mode 100644 index 000000000..df92f6353 --- /dev/null +++ b/src/shm/protocol_implementations/mod.rs @@ -0,0 +1,15 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +pub mod posix; diff --git a/src/shm/protocol_implementations/posix/mod.rs b/src/shm/protocol_implementations/posix/mod.rs new file mode 100644 index 000000000..9f984d20b --- /dev/null +++ b/src/shm/protocol_implementations/posix/mod.rs @@ -0,0 +1,17 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +pub mod posix_shared_memory_client; +pub mod posix_shared_memory_provider; +pub mod protocol_id; diff --git a/src/shm/protocol_implementations/posix/posix_shared_memory_client.rs b/src/shm/protocol_implementations/posix/posix_shared_memory_client.rs new file mode 100644 index 000000000..2818c1742 --- /dev/null +++ b/src/shm/protocol_implementations/posix/posix_shared_memory_client.rs @@ -0,0 +1,27 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use zenoh::shm::{ + client::shared_memory_client::SharedMemoryClient, + protocol_implementations::posix::posix_shared_memory_client::PosixSharedMemoryClient, +}; + +use crate::{client::shared_memory_client::z_shared_memory_client_t, GuardedTransmute}; + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_posix_shared_memory_client_new() -> z_shared_memory_client_t { + let client = Box::new(PosixSharedMemoryClient) as Box; + client.transmute() +} diff --git a/src/shm/protocol_implementations/posix/posix_shared_memory_provider.rs b/src/shm/protocol_implementations/posix/posix_shared_memory_provider.rs new file mode 100644 index 000000000..f8fc1df2d --- /dev/null +++ b/src/shm/protocol_implementations/posix/posix_shared_memory_provider.rs @@ -0,0 +1,81 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use std::mem::MaybeUninit; + +use zenoh::shm::{ + protocol_implementations::posix::{ + posix_shared_memory_provider_backend::PosixSharedMemoryProviderBackend, + protocol_id::POSIX_PROTOCOL_ID, + }, + provider::shared_memory_provider::{ + SharedMemoryProvider, SharedMemoryProviderBuilder, StaticProtocolID, + }, +}; + +use crate::{ + decl_rust_copy_type, impl_guarded_transmute, provider::types::z_memory_layout_t, + GuardedTransmute, +}; + +/// An owned SharedMemoryProvider with POSIX backend +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. +#[cfg(target_arch = "x86_64")] +#[repr(C, align(8))] +pub struct z_posix_shared_memory_provider_t([u64; 26]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(16))] +pub struct z_posix_shared_memory_provider_t([u64; 26]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(8))] +pub struct z_posix_shared_memory_provider_t([u64; 26]); + +type PosixSharedMemoryProvider = + SharedMemoryProvider, PosixSharedMemoryProviderBackend>; + +decl_rust_copy_type!( + zenoh:(PosixSharedMemoryProvider), + c:(z_posix_shared_memory_provider_t)); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_posix_shared_memory_provider_new( + layout: &z_memory_layout_t, + out_provider: &mut MaybeUninit, +) -> bool { + match PosixSharedMemoryProviderBackend::builder() + .with_layout(layout.transmute_ref()) + .res() + { + Ok(backend) => { + let provider = SharedMemoryProviderBuilder::builder() + .protocol_id::() + .backend(backend) + .res(); + out_provider.write(provider.transmute()); + true + } + Err(e) => { + log::error!("{}", e); + false + } + } +} diff --git a/src/shm/protocol_implementations/posix/protocol_id.rs b/src/shm/protocol_implementations/posix/protocol_id.rs new file mode 100644 index 000000000..f893138f7 --- /dev/null +++ b/src/shm/protocol_implementations/posix/protocol_id.rs @@ -0,0 +1,17 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +// Protocol identifier to use when creating SharedMemoryProvider +//#[repr(C)] +//pub const POSIX_PROTOCOL_ID: ProtocolID = 0; diff --git a/src/shm/provider/chunk.rs b/src/shm/provider/chunk.rs new file mode 100644 index 000000000..d9ca0fdb3 --- /dev/null +++ b/src/shm/provider/chunk.rs @@ -0,0 +1,102 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use std::mem::MaybeUninit; + +use zenoh::shm::provider::chunk::{AllocatedChunk, ChunkDescriptor}; + +use crate::{ + common::types::{z_chunk_id_t, z_segment_id_t}, + decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute, +}; + +#[repr(C)] +pub struct zc_chunk_descriptor_data_t { + segment: z_segment_id_t, + chunk: z_chunk_id_t, + len: usize, +} + +/// A ChunkDescriptor +#[repr(C)] +pub struct z_chunk_descriptor_t(zc_chunk_descriptor_data_t); + +decl_rust_copy_type!( + zenoh:(ChunkDescriptor), + c:(z_chunk_descriptor_t) +); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_chunk_descriptor_new( + data: zc_chunk_descriptor_data_t, + out_val: &mut MaybeUninit, +) { + let descriptor = ChunkDescriptor::new(data.segment, data.chunk, data.len); + out_val.write(descriptor.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_chunk_descriptor_unwrap( + descriptor: z_chunk_descriptor_t, +) -> zc_chunk_descriptor_data_t { + let descriptor = descriptor.transmute(); + zc_chunk_descriptor_data_t { + segment: descriptor.segment, + chunk: descriptor.chunk, + len: descriptor.len, + } +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_chunk_descriptor_delete(val: z_chunk_descriptor_t) { + let _ = val.transmute(); +} + +/// An AllocatedChunk. +#[cfg(target_arch = "x86_64")] +#[repr(C, align(8))] +pub struct z_allocated_chunk_t([u64; 3]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(16))] +pub struct z_allocated_chunk_t([u64; 4]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(8))] +pub struct z_allocated_chunk_t([u64; 3]); + +decl_rust_copy_type!( + zenoh:(AllocatedChunk), + c:(z_allocated_chunk_t) +); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_allocated_chunk_new( + descriptor: z_chunk_descriptor_t, + data: *mut u8, + out_val: &mut MaybeUninit, +) { + let chunk = AllocatedChunk::new(descriptor.transmute(), data.into()); + out_val.write(chunk.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_allocated_chunk_delete(val: z_allocated_chunk_t) { + let _ = val.transmute(); +} diff --git a/src/shm/provider/mod.rs b/src/shm/provider/mod.rs new file mode 100644 index 000000000..a38e328d9 --- /dev/null +++ b/src/shm/provider/mod.rs @@ -0,0 +1,19 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +pub mod chunk; +pub mod shared_memory_provider; +pub mod shared_memory_provider_backend; +pub mod types; +pub mod zsliceshm; diff --git a/src/shm/provider/shared_memory_provider.rs b/src/shm/provider/shared_memory_provider.rs new file mode 100644 index 000000000..7f25d6041 --- /dev/null +++ b/src/shm/provider/shared_memory_provider.rs @@ -0,0 +1,206 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use std::mem::MaybeUninit; + +use zenoh::shm::provider::shared_memory_provider::{ + AllocPolicy, BlockOn, Deallocate, Defragment, DynamicProtocolID, GarbageCollect, JustAlloc, + SharedMemoryProvider, SharedMemoryProviderBuilder, +}; + +use crate::{ + common::types::z_protocol_id_t, decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute, +}; + +use super::{ + chunk::z_allocated_chunk_t, + shared_memory_provider_backend::{ + zc_context_t, zc_shared_memory_provider_backend_callbacks_t, + DynamicSharedMemoryProviderBackend, + }, + types::{z_alloc_alignment_t, z_buf_alloc_result_t}, + zsliceshm::z_slice_shm_t, +}; + +/// An owned SharedMemoryProvider +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. +#[cfg(target_arch = "x86_64")] +#[repr(C, align(8))] +pub struct z_shared_memory_provider_t([u64; 14]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(16))] +pub struct z_shared_memory_provider_t([u64; 14]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(8))] +pub struct z_shared_memory_provider_t([u64; 14]); + +decl_rust_copy_type!( + zenoh:(SharedMemoryProvider), + c:(z_shared_memory_provider_t) +); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_new( + id: z_protocol_id_t, + context: zc_context_t, + callbacks: zc_shared_memory_provider_backend_callbacks_t, + out_provider: &mut MaybeUninit, +) { + let backend = DynamicSharedMemoryProviderBackend::new(context.transmute(), callbacks); + let provider = SharedMemoryProviderBuilder::builder() + .dynamic_protocol_id(id) + .backend(backend) + .res(); + out_provider.write(provider.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_delete(provider: z_shared_memory_provider_t) { + let _ = provider.transmute(); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_alloc( + provider: &z_shared_memory_provider_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool { + alloc::(provider, size, alignment, out_buffer) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc( + provider: &z_shared_memory_provider_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool { + alloc::(provider, size, alignment, out_buffer) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc_defrag( + provider: &z_shared_memory_provider_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool { + alloc::>(provider, size, alignment, out_buffer) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc_defrag_dealloc( + provider: &z_shared_memory_provider_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool { + alloc::>>(provider, size, alignment, out_buffer) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc_defrag_blocking( + provider: &z_shared_memory_provider_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool { + alloc::>>(provider, size, alignment, out_buffer) +} + +#[allow(clippy::missing_safety_doc)] +unsafe fn alloc( + provider: &z_shared_memory_provider_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool { + let provider = provider.transmute_ref(); + match provider + .alloc_layout() + .size(size) + .alignment(alignment.transmute()) + .res() + { + Ok(layout) => { + let result = layout.alloc().with_policy::().res().transmute(); + out_buffer.write(result); + return true; + } + Err(e) => { + log::error!("{e}"); + } + }; + false +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_defragment( + provider: &z_shared_memory_provider_t, +) -> usize { + provider.transmute_ref().defragment() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_garbage_collect( + provider: &z_shared_memory_provider_t, +) -> usize { + provider.transmute_ref().garbage_collect() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_available( + provider: &z_shared_memory_provider_t, +) -> usize { + provider.transmute_ref().available() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_map( + provider: &z_shared_memory_provider_t, + allocated_chunk: z_allocated_chunk_t, + len: usize, + out_buffer: &mut MaybeUninit, +) -> bool { + let provider = provider.transmute_ref(); + match provider.map(allocated_chunk.transmute(), len) { + Ok(buffer) => { + out_buffer.write(buffer.transmute()); + true + } + Err(e) => { + log::error!("{e}"); + false + } + } +} diff --git a/src/shm/provider/shared_memory_provider_backend.rs b/src/shm/provider/shared_memory_provider_backend.rs new file mode 100644 index 000000000..6ff4adca3 --- /dev/null +++ b/src/shm/provider/shared_memory_provider_backend.rs @@ -0,0 +1,124 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use libc::c_void; +use zenoh::shm::provider::{ + chunk::ChunkDescriptor, + shared_memory_provider_backend::SharedMemoryProviderBackend, + types::{ChunkAllocResult, MemoryLayout}, +}; +use zenoh::Result; +use zenoh_util::core::bail; + +use crate::{decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute}; + +use super::{ + chunk::z_chunk_descriptor_t, + types::{z_chunk_alloc_result_t, z_memory_layout_t}, +}; + +/// A droppable context +#[derive(Debug)] +#[repr(C)] +pub struct zc_context_t { + context: *mut c_void, + drop_fn: unsafe extern "C" fn(*mut c_void), +} + +decl_rust_copy_type!( + zenoh:(Context), + c:(zc_context_t) +); + +#[derive(Debug)] +pub struct Context(zc_context_t); + +impl Context { + pub fn get(&self) -> *mut c_void { + self.0.context + } +} +impl Drop for Context { + fn drop(&mut self) { + unsafe { + (self.0.drop_fn)(self.0.context); + } + } +} + +/// A callbacks for SharedMemoryProviderBackend +#[derive(Debug)] +#[repr(C)] +pub struct zc_shared_memory_provider_backend_callbacks_t { + alloc_fn: + unsafe extern "C" fn(*mut c_void, *const z_memory_layout_t, *mut z_chunk_alloc_result_t), + free_fn: unsafe extern "C" fn(*mut c_void, *const z_chunk_descriptor_t), + defragment_fn: unsafe extern "C" fn(*mut c_void) -> usize, + available_fn: unsafe extern "C" fn(*mut c_void) -> usize, + layout_for_fn: + unsafe extern "C" fn(*mut c_void, *const z_memory_layout_t, *mut z_memory_layout_t) -> bool, + drop_fn: unsafe extern "C" fn(*mut c_void), +} + +#[derive(Debug)] +pub struct DynamicSharedMemoryProviderBackend { + context: Context, + callbacks: zc_shared_memory_provider_backend_callbacks_t, +} + +impl DynamicSharedMemoryProviderBackend { + pub fn new(context: Context, callbacks: zc_shared_memory_provider_backend_callbacks_t) -> Self { + Self { context, callbacks } + } +} + +impl SharedMemoryProviderBackend for DynamicSharedMemoryProviderBackend { + fn alloc(&self, layout: &MemoryLayout) -> ChunkAllocResult { + let mut result = std::mem::MaybeUninit::uninit(); + unsafe { + (self.callbacks.alloc_fn)( + self.context.get(), + layout.transmute_ref(), + result.as_mut_ptr(), + ); + result.assume_init().transmute() + } + } + + fn free(&self, chunk: &ChunkDescriptor) { + unsafe { (self.callbacks.free_fn)(self.context.get(), chunk.transmute_ref()) }; + } + + fn defragment(&self) -> usize { + unsafe { (self.callbacks.defragment_fn)(self.context.get()) } + } + + fn available(&self) -> usize { + unsafe { (self.callbacks.available_fn)(self.context.get()) } + } + + fn layout_for(&self, layout: MemoryLayout) -> Result { + let mut result = std::mem::MaybeUninit::uninit(); + unsafe { + match (self.callbacks.layout_for_fn)( + self.context.get(), + layout.transmute_ref(), + result.as_mut_ptr(), + ) { + true => Ok(result.assume_init().transmute()), + false => bail!("{:?}: unsupported layout: {:?}", self, layout), + } + } + } +} diff --git a/src/shm/provider/types.rs b/src/shm/provider/types.rs new file mode 100644 index 000000000..477cdf142 --- /dev/null +++ b/src/shm/provider/types.rs @@ -0,0 +1,200 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use std::mem::MaybeUninit; + +use zenoh::shm::provider::types::{ + AllocAlignment, BufAllocResult, ChunkAllocResult, MemoryLayout, ZAllocError, +}; +use zenoh_util::core::zerror; + +use crate::{decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute}; + +use super::{chunk::z_allocated_chunk_t, zsliceshm::z_slice_shm_t}; + +/// Allocation errors +/// +/// - **NEED_DEFRAGMENT**: defragmentation needed +/// - **OUT_OF_MEMORY**: the provider is out of memory +/// - **OTHER**: other error +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Clone, Copy)] +pub enum z_alloc_error_t { + NEED_DEFRAGMENT, + OUT_OF_MEMORY, + OTHER, +} + +impl From for z_alloc_error_t { + #[inline] + fn from(value: ZAllocError) -> Self { + match value { + ZAllocError::NeedDefragment => z_alloc_error_t::NEED_DEFRAGMENT, + ZAllocError::OutOfMemory => z_alloc_error_t::OUT_OF_MEMORY, + ZAllocError::Other(_) => z_alloc_error_t::OTHER, + } + } +} + +impl From for ZAllocError { + #[inline] + fn from(value: z_alloc_error_t) -> Self { + match value { + z_alloc_error_t::NEED_DEFRAGMENT => ZAllocError::NeedDefragment, + z_alloc_error_t::OUT_OF_MEMORY => ZAllocError::OutOfMemory, + z_alloc_error_t::OTHER => ZAllocError::Other(zerror!("other error").into()), + } + } +} + +// An AllocAlignment. +#[cfg(target_arch = "x86_64")] +#[repr(C, align(4))] +pub struct z_alloc_alignment_t([u32; 1]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(4))] +pub struct z_alloc_alignment_t([u32; 1]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(4))] +pub struct z_alloc_alignment_t([u32; 1]); + +decl_rust_copy_type!( + zenoh:(AllocAlignment), + c:(z_alloc_alignment_t) +); + +// An owned MemoryLayout. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. +#[cfg(target_arch = "x86_64")] +#[repr(C, align(8))] +pub struct z_memory_layout_t([u64; 2]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(16))] +pub struct z_memory_layout_t([u64; 2]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(8))] +pub struct z_memory_layout_t([u64; 2]); +decl_rust_copy_type!( + zenoh:(MemoryLayout), + c:(z_memory_layout_t) +); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_memory_layout_delete(layout: z_memory_layout_t) { + let _ = layout.transmute(); +} + +// An owned ChunkAllocResult +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. +#[cfg(target_arch = "x86_64")] +#[repr(C, align(8))] +pub struct z_chunk_alloc_result_t([u64; 4]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(16))] +pub struct z_chunk_alloc_result_t([u64; 4]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(8))] +pub struct z_chunk_alloc_result_t([u64; 4]); +decl_rust_copy_type!( + zenoh:(ChunkAllocResult), + c:(z_chunk_alloc_result_t) +); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_chunk_alloc_result_new_ok( + allocated_chunk: z_allocated_chunk_t, + out_result: &mut MaybeUninit, +) { + let allocated_chunk = allocated_chunk.transmute(); + let result = Ok(allocated_chunk); + out_result.write(result.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_chunk_alloc_result_new_error( + alloc_error: z_alloc_error_t, + out_result: &mut MaybeUninit, +) { + let alloc_error = alloc_error.into(); + let result = Err(alloc_error); + out_result.write(result.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_chunk_alloc_result_delete(result: z_chunk_alloc_result_t) { + let _ = result.transmute(); +} + +// A BufAllocResult +#[cfg(target_arch = "x86_64")] +#[repr(C, align(8))] +pub struct z_buf_alloc_result_t([u64; 10]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(16))] +pub struct z_buf_alloc_result_t([u64; 10]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(8))] +pub struct z_buf_alloc_result_t([u64; 10]); +decl_rust_copy_type!( + zenoh:(BufAllocResult), + c:(z_buf_alloc_result_t) +); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_buf_alloc_result_unwrap( + alloc_result: z_buf_alloc_result_t, + out_buf: &mut MaybeUninit, + out_error: &mut MaybeUninit, +) -> bool { + match alloc_result.transmute() { + Ok(val) => { + out_buf.write(val.transmute()); + true + } + Err(e) => { + out_error.write(e.into()); + false + } + } +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_buf_alloc_result_delete(result: z_buf_alloc_result_t) { + let _ = result.transmute(); +} diff --git a/src/shm/provider/zsliceshm.rs b/src/shm/provider/zsliceshm.rs new file mode 100644 index 000000000..3a6efdc24 --- /dev/null +++ b/src/shm/provider/zsliceshm.rs @@ -0,0 +1,35 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use zenoh::shm::provider::zsliceshm::ZSliceShm; + +use crate::{decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute}; + +// A ZSliceSHM +#[cfg(target_arch = "x86_64")] +#[repr(C, align(8))] +pub struct z_slice_shm_t([u64; 10]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(16))] +pub struct z_slice_shm_t([u64; 10]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(8))] +pub struct z_slice_shm_t([u64; 10]); + +decl_rust_copy_type!( + zenoh:(ZSliceShm), + c:(z_slice_shm_t) +); From aa44b8930c4b60b702c8806ebb6403e04f78132e Mon Sep 17 00:00:00 2001 From: yellowhatter Date: Fri, 29 Mar 2024 13:47:32 +0300 Subject: [PATCH 12/75] Fix CI --- src/lib.rs | 15 ++------------- src/shm/provider/zsliceshm.rs | 2 +- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index cd1936ac5..93c4d219a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,19 +69,8 @@ trait GuardedTransmute { #[macro_export] macro_rules! decl_rust_copy_type { (zenoh:($zenoh_type:ty), c:($c_type:ty)) => { - impl_guarded_transmute!($zenoh_type, $c_type); - impl_guarded_transmute!($c_type, $zenoh_type); - - impl From<$zenoh_type> for $c_type { - fn from(value: $zenoh_type) -> Self { - value.transmute() - } - } - impl From<$c_type> for $zenoh_type { - fn from(value: $c_type) -> Self { - value.transmute() - } - } + impl_guarded_transmute!(noderefs $zenoh_type, $c_type); + impl_guarded_transmute!(noderefs $c_type, $zenoh_type); }; } diff --git a/src/shm/provider/zsliceshm.rs b/src/shm/provider/zsliceshm.rs index 3a6efdc24..ceb39dac1 100644 --- a/src/shm/provider/zsliceshm.rs +++ b/src/shm/provider/zsliceshm.rs @@ -14,7 +14,7 @@ use zenoh::shm::provider::zsliceshm::ZSliceShm; -use crate::{decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute}; +use crate::{decl_rust_copy_type, impl_guarded_transmute}; // A ZSliceSHM #[cfg(target_arch = "x86_64")] From fcffae8a524614dbe334d0fe2fbfae64ea78190e Mon Sep 17 00:00:00 2001 From: yellowhatter Date: Mon, 1 Apr 2024 18:57:32 +0300 Subject: [PATCH 13/75] [skip ci] - small build fixes - common z_context_t and z_threadsafe_context_t types for callback interfaces mechanics - separate interfaces for thread-safe and non-thread-safe SharedMemoryProvider specializations - AllocLayout interface - async allocation support --- Cargo.lock | 131 +++++----- include/zenoh_commons.h | 217 +++++++++++++--- src/context.rs | 107 ++++++++ src/get.rs | 4 +- src/lib.rs | 6 +- src/shm/client/shared_memory_client.rs | 15 +- src/shm/client/shared_memory_segment.rs | 22 +- src/shm/client_storage/mod.rs | 5 +- src/shm/provider/alloc_layout_threadsafe.rs | 140 ++++++++++ src/shm/provider/mod.rs | 3 + src/shm/provider/shared_memory_provider.rs | 49 ++-- .../shared_memory_provider_backend.rs | 55 ++-- .../provider/shared_memory_provider_impl.rs | 97 +++++++ .../shared_memory_provider_threadsafe.rs | 245 ++++++++++++++++++ 14 files changed, 893 insertions(+), 203 deletions(-) create mode 100644 src/context.rs create mode 100644 src/shm/provider/alloc_layout_threadsafe.rs create mode 100644 src/shm/provider/shared_memory_provider_impl.rs create mode 100644 src/shm/provider/shared_memory_provider_threadsafe.rs diff --git a/Cargo.lock b/Cargo.lock index 0dae7374a..59351f9ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -149,16 +149,16 @@ checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" dependencies = [ "concurrent-queue", "event-listener 5.2.0", - "event-listener-strategy 0.5.0", + "event-listener-strategy 0.5.1", "futures-core", "pin-project-lite", ] [[package]] name = "async-executor" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +checksum = "10b3e585719c2358d2660232671ca8ca4ddb4be4ce8a1842d6c2dc8685303316" dependencies = [ "async-lock 3.3.0", "async-task", @@ -319,7 +319,7 @@ checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.57", ] [[package]] @@ -777,9 +777,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +checksum = "332f51cb23d20b0de8458b86580878211da09bcd4503cb579c225b3d124cabb3" dependencies = [ "event-listener 5.2.0", "pin-project-lite", @@ -927,7 +927,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.57", ] [[package]] @@ -1006,7 +1006,7 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.57", ] [[package]] @@ -1296,13 +1296,12 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.5.0", "libc", - "redox_syscall", ] [[package]] @@ -1347,9 +1346,9 @@ dependencies = [ [[package]] name = "lz4_flex" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" +checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" dependencies = [ "twox-hash", ] @@ -1591,7 +1590,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.57", ] [[package]] @@ -1617,9 +1616,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1834,20 +1833,11 @@ dependencies = [ "getrandom", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_users" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", "libredox", @@ -2161,9 +2151,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -2174,9 +2164,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" dependencies = [ "core-foundation-sys", "libc", @@ -2205,7 +2195,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.57", ] [[package]] @@ -2461,9 +2451,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.55" +version = "2.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35" dependencies = [ "proc-macro2", "quote", @@ -2514,7 +2504,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.57", ] [[package]] @@ -2580,7 +2570,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.57", ] [[package]] @@ -2677,7 +2667,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.57", ] [[package]] @@ -2732,9 +2722,9 @@ checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "uhlc" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1eadef1fa26cbbae1276c46781e8f4d888bdda434779c18ae6c2a0e69991885" +checksum = "99b6df3f3e948b40e20c38a6d1fd6d8f91b3573922fc164e068ad3331560487e" dependencies = [ "humantime", "lazy_static", @@ -2907,7 +2897,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.57", "wasm-bindgen-shared", ] @@ -2941,7 +2931,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.57", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3207,7 +3197,7 @@ dependencies = [ [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-trait", "base64", @@ -3257,10 +3247,9 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "zenoh-collections", - "zenoh-shm", ] [[package]] @@ -3290,7 +3279,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "log", "serde", @@ -3303,15 +3292,16 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "flume", "json5", + "log", "num_cpus", "secrecy", "serde", @@ -3327,7 +3317,7 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-global-executor", "lazy_static", @@ -3339,7 +3329,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "aes", "hmac", @@ -3352,7 +3342,7 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "bincode", "env_logger 0.11.3", @@ -3373,7 +3363,7 @@ dependencies = [ [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "hashbrown 0.14.3", "keyed-set", @@ -3387,7 +3377,7 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-trait", "zenoh-config", @@ -3405,7 +3395,7 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-trait", "flume", @@ -3428,7 +3418,7 @@ dependencies = [ [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-trait", "base64", @@ -3456,7 +3446,7 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-trait", "log", @@ -3474,7 +3464,7 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-trait", "base64", @@ -3502,7 +3492,7 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-trait", "log", @@ -3523,7 +3513,7 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-trait", "futures", @@ -3543,7 +3533,7 @@ dependencies = [ [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-trait", "futures-util", @@ -3564,18 +3554,18 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.57", "zenoh-keyexpr", ] [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "const_format", "libloading", @@ -3591,7 +3581,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "const_format", "rand", @@ -3605,7 +3595,7 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "anyhow", ] @@ -3613,7 +3603,7 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "lazy_static", "tokio", @@ -3624,7 +3614,7 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-trait", "bincode", @@ -3639,6 +3629,7 @@ dependencies = [ "stabby", "thread-priority", "tokio", + "zenoh-buffers", "zenoh-core", "zenoh-macros", "zenoh-result", @@ -3647,7 +3638,7 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "event-listener 4.0.3", "futures", @@ -3661,7 +3652,7 @@ dependencies = [ [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-trait", "flume", @@ -3693,7 +3684,7 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#8dfb1fafeda145f05b30e271dcedef2700b08862" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" dependencies = [ "async-std", "async-trait", @@ -3729,7 +3720,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.57", ] [[package]] diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 133739176..336e22b54 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -174,6 +174,57 @@ typedef enum zcu_reply_keyexpr_t { ZCU_REPLY_KEYEXPR_ANY = 0, ZCU_REPLY_KEYEXPR_MATCHING_QUERY = 1, } zcu_reply_keyexpr_t; +/** + * A thread-safe SharedMemoryProvider's AllocLayout + */ +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_alloc_layout_threadsafe_t { + uint64_t _0[4]; +} z_alloc_layout_threadsafe_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_alloc_layout_threadsafe_t { + uint64_t _0[14]; +} z_alloc_layout_threadsafe_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_alloc_layout_threadsafe_t { + uint64_t _0[14]; +} z_alloc_layout_threadsafe_t; +#endif +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_buf_alloc_result_t { + uint64_t _0[10]; +} z_buf_alloc_result_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_buf_alloc_result_t { + uint64_t _0[10]; +} z_buf_alloc_result_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_buf_alloc_result_t { + uint64_t _0[10]; +} z_buf_alloc_result_t; +#endif +/** + * A tread-safe droppable context. + * Contexts are idiomatically used in C together with callback interfaces to deliver associated state + * information to each callback. + * + * This is a thread-safe context - the associated callbacks may be executed concurrently with the same + * zc_context_t instance. In other words, the context data MUST be thread-safe. + * + * Once moved to zenoh-c ownership, this context is guaranteed to execute delete_fn when deleted.The + * delete_fn is guaranteed to be executed only once at some point of time after the last associated + * callback call returns. + * NOTE: if user doesn't pass the instance of this context to zenoh-c, the delete_fn callback won't + * be executed. + */ +typedef struct zc_threadsafe_context_t { + AtomicPtr context; + void (*delete_fn)(void*); +} zc_threadsafe_context_t; /** * An AllocatedChunk. */ @@ -253,21 +304,6 @@ typedef struct z_attachment_t { z_attachment_iter_driver_t iteration_driver; } z_attachment_t; #if defined(TARGET_ARCH_X86_64) -typedef struct ALIGN(8) z_buf_alloc_result_t { - uint64_t _0[10]; -} z_buf_alloc_result_t; -#endif -#if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(16) z_buf_alloc_result_t { - uint64_t _0[10]; -} z_buf_alloc_result_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_buf_alloc_result_t { - uint64_t _0[10]; -} z_buf_alloc_result_t; -#endif -#if defined(TARGET_ARCH_X86_64) typedef struct ALIGN(8) z_slice_shm_t { uint64_t _0[10]; } z_slice_shm_t; @@ -449,12 +485,12 @@ typedef struct z_owned_closure_query_t { */ #if !defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_owned_reply_t { - uint64_t _0[28]; + uint64_t _0[30]; } z_owned_reply_t; #endif #if defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_owned_reply_t { - uint64_t _0[19]; + uint64_t _0[21]; } z_owned_reply_t; #endif /** @@ -988,24 +1024,17 @@ typedef struct z_owned_scouting_config_t { unsigned long zc_timeout_ms; uint8_t zc_what; } z_owned_scouting_config_t; -/** - * A droppable context - */ -typedef struct zc_context_t { - void *context; - void (*drop_fn)(void*); -} zc_context_t; /** * A callbacks for SharedMemorySegment */ typedef struct zc_shared_memory_segment_callbacks_t { - void (*map_fn)(void*, z_chunk_id_t); + uint8_t *(*map_fn)(void*, z_chunk_id_t); } zc_shared_memory_segment_callbacks_t; /** * A SharedMemorySegment */ typedef struct z_shared_memory_segment_t { - struct zc_context_t context; + struct zc_threadsafe_context_t context; struct zc_shared_memory_segment_callbacks_t callbacks; } z_shared_memory_segment_t; /** @@ -1039,13 +1068,7 @@ typedef struct ALIGN(8) zc_shared_memory_client_list_t { } zc_shared_memory_client_list_t; #endif /** - * An owned SharedMemoryProvider - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + * A non-thread-safe SharedMemoryProvider specialization */ #if defined(TARGET_ARCH_X86_64) typedef struct ALIGN(8) z_shared_memory_provider_t { @@ -1083,6 +1106,29 @@ typedef struct ALIGN(4) z_alloc_alignment_t { * and SharedMemoryProviderBackend implementations will never use the same ProtocolID */ typedef uint32_t z_protocol_id_t; +/** + * A non-tread-safe droppable context. + * Contexts are idiomatically used in C together with callback interfaces to deliver associated state + * information to each callback. + * + * This is a non-thread-safe context - zenoh-c guarantees that associated callbacks that share the same + * zc_context_t instance will never be executed concurrently. In other words, the context data is not + * required to be thread-safe. + * NOTE: Remember that the same callback interfaces associated with different zc_context_t instances can + * still be executed concurrently. The exact behavior depends on user's application, but we strongly + * discourage our users from pinning to some specific behavior unless they _really_ understand what they + * are doing. + * + * Once moved to zenoh-c ownership, this context is guaranteed to execute delete_fn when deleted. The + * delete_fn is guaranteed to be executed only once at some point of time after the last associated + * callback call returns. + * NOTE: if user doesn't pass the instance of this context to zenoh-c, the delete_fn callback won't + * be executed. + */ +typedef struct zc_context_t { + void *context; + void (*delete_fn)(void*); +} zc_context_t; /** * A callbacks for SharedMemoryProviderBackend */ @@ -1094,6 +1140,24 @@ typedef struct zc_shared_memory_provider_backend_callbacks_t { bool (*layout_for_fn)(void*, const struct z_memory_layout_t*, struct z_memory_layout_t*); void (*drop_fn)(void*); } zc_shared_memory_provider_backend_callbacks_t; +/** + * A thread-safe SharedMemoryProvider specialization + */ +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_shared_memory_provider_threadsafe_t { + uint64_t _0[14]; +} z_shared_memory_provider_threadsafe_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_shared_memory_provider_threadsafe_t { + uint64_t _0[14]; +} z_shared_memory_provider_threadsafe_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_shared_memory_provider_threadsafe_t { + uint64_t _0[14]; +} z_shared_memory_provider_threadsafe_t; +#endif /** * A loaned zenoh subscriber. */ @@ -1294,6 +1358,28 @@ ZENOHC_API extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; ZENOHC_API extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; ZENOHC_API extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; ZENOHC_API extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; +ZENOHC_API +void z_alloc_layout_threadsafe_alloc(const struct z_alloc_layout_threadsafe_t *layout, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +void z_alloc_layout_threadsafe_alloc_gc(const struct z_alloc_layout_threadsafe_t *layout, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +void z_alloc_layout_threadsafe_alloc_gc_defrag(const struct z_alloc_layout_threadsafe_t *layout, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +void z_alloc_layout_threadsafe_alloc_gc_defrag_async(const struct z_alloc_layout_threadsafe_t *layout, + struct z_buf_alloc_result_t *out_buffer, + struct zc_threadsafe_context_t result_context, + void (*result_callback)(void*, + struct z_buf_alloc_result_t*)); +ZENOHC_API +void z_alloc_layout_threadsafe_alloc_gc_defrag_blocking(const struct z_alloc_layout_threadsafe_t *layout, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +void z_alloc_layout_threadsafe_alloc_gc_defrag_dealloc(const struct z_alloc_layout_threadsafe_t *layout, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API void z_alloc_layout_threadsafe_delete(struct z_alloc_layout_threadsafe_t layout); ZENOHC_API void z_allocated_chunk_delete(struct z_allocated_chunk_t val); ZENOHC_API void z_allocated_chunk_new(struct z_chunk_descriptor_t descriptor, @@ -2374,7 +2460,7 @@ struct z_session_t z_session_loan(const struct z_owned_session_t *s); ZENOHC_API struct z_owned_session_t z_session_null(void); ZENOHC_API void z_shared_memory_client_delete(struct z_shared_memory_client_t client); ZENOHC_API -void z_shared_memory_client_new(struct zc_context_t context, +void z_shared_memory_client_new(struct zc_threadsafe_context_t context, struct zc_shared_memory_client_callbacks_t callbacks, struct z_shared_memory_client_t *out_client); ZENOHC_API @@ -2428,6 +2514,63 @@ void z_shared_memory_provider_new(z_protocol_id_t id, struct zc_context_t context, struct zc_shared_memory_provider_backend_callbacks_t callbacks, struct z_shared_memory_provider_t *out_provider); +ZENOHC_API +bool z_shared_memory_provider_threadsafe_alloc(const struct z_shared_memory_provider_threadsafe_t *provider, + size_t size, + struct z_alloc_alignment_t alignment, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +bool z_shared_memory_provider_threadsafe_alloc_gc(const struct z_shared_memory_provider_threadsafe_t *provider, + size_t size, + struct z_alloc_alignment_t alignment, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +bool z_shared_memory_provider_threadsafe_alloc_gc_defrag(const struct z_shared_memory_provider_threadsafe_t *provider, + size_t size, + struct z_alloc_alignment_t alignment, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +void z_shared_memory_provider_threadsafe_alloc_gc_defrag_async(const struct z_shared_memory_provider_threadsafe_t *provider, + size_t size, + struct z_alloc_alignment_t alignment, + struct z_buf_alloc_result_t *out_buffer, + struct zc_threadsafe_context_t result_context, + void (*result_callback)(void*, + bool, + struct z_buf_alloc_result_t*)); +ZENOHC_API +bool z_shared_memory_provider_threadsafe_alloc_gc_defrag_blocking(const struct z_shared_memory_provider_threadsafe_t *provider, + size_t size, + struct z_alloc_alignment_t alignment, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +bool z_shared_memory_provider_threadsafe_alloc_gc_defrag_dealloc(const struct z_shared_memory_provider_threadsafe_t *provider, + size_t size, + struct z_alloc_alignment_t alignment, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +bool z_shared_memory_provider_threadsafe_alloc_layout(const struct z_shared_memory_provider_threadsafe_t *provider, + size_t size, + struct z_alloc_alignment_t alignment, + struct z_alloc_layout_threadsafe_t *out_layout); +ZENOHC_API +size_t z_shared_memory_provider_threadsafe_available(const struct z_shared_memory_provider_threadsafe_t *provider); +ZENOHC_API +size_t z_shared_memory_provider_threadsafe_defragment(const struct z_shared_memory_provider_threadsafe_t *provider); +ZENOHC_API +void z_shared_memory_provider_threadsafe_delete(struct z_shared_memory_provider_threadsafe_t provider); +ZENOHC_API +size_t z_shared_memory_provider_threadsafe_garbage_collect(const struct z_shared_memory_provider_threadsafe_t *provider); +ZENOHC_API +bool z_shared_memory_provider_threadsafe_map(const struct z_shared_memory_provider_threadsafe_t *provider, + struct z_allocated_chunk_t allocated_chunk, + size_t len, + struct z_slice_shm_t *out_buffer); +ZENOHC_API +void z_shared_memory_provider_threadsafe_new(z_protocol_id_t id, + struct zc_threadsafe_context_t context, + struct zc_shared_memory_provider_backend_callbacks_t callbacks, + struct z_shared_memory_provider_threadsafe_t *out_provider); ZENOHC_API int8_t z_sleep_ms(size_t time); ZENOHC_API int8_t z_sleep_s(size_t time); ZENOHC_API int8_t z_sleep_us(size_t time); @@ -2830,9 +2973,9 @@ ZENOHC_API struct zc_owned_payload_t zc_sample_payload_rcinc(const struct z_samp */ ZENOHC_API struct z_owned_session_t zc_session_rcinc(struct z_session_t session); ZENOHC_API -void zc_shared_memory_client_list_add(z_protocol_id_t id, - struct z_shared_memory_client_t client, - struct zc_shared_memory_client_list_t *list); +void zc_shared_memory_client_list_add_client(z_protocol_id_t id, + struct z_shared_memory_client_t client, + struct zc_shared_memory_client_list_t *list); ZENOHC_API void zc_shared_memory_client_list_delete(struct zc_shared_memory_client_list_t list); ZENOHC_API struct zc_shared_memory_client_list_t zc_shared_memory_client_list_new(void); /** diff --git a/src/context.rs b/src/context.rs new file mode 100644 index 000000000..fb5e7b4a2 --- /dev/null +++ b/src/context.rs @@ -0,0 +1,107 @@ +// +// Copyright (c) 2017, 2022 ZettaScale Technology. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh team, +// + +use std::{fmt::Debug, sync::atomic::AtomicPtr}; + +use libc::c_void; + +use crate::{decl_rust_copy_type, impl_guarded_transmute}; + +/// A trait for implementing droppable contexts +pub trait DroppableContext: Debug { + fn get(&self) -> *mut c_void; +} + +/// A non-tread-safe droppable context. +/// Contexts are idiomatically used in C together with callback interfaces to deliver associated state +/// information to each callback. +/// +/// This is a non-thread-safe context - zenoh-c guarantees that associated callbacks that share the same +/// zc_context_t instance will never be executed concurrently. In other words, the context data is not +/// required to be thread-safe. +/// NOTE: Remember that the same callback interfaces associated with different zc_context_t instances can +/// still be executed concurrently. The exact behavior depends on user's application, but we strongly +/// discourage our users from pinning to some specific behavior unless they _really_ understand what they +/// are doing. +/// +/// Once moved to zenoh-c ownership, this context is guaranteed to execute delete_fn when deleted. The +/// delete_fn is guaranteed to be executed only once at some point of time after the last associated +/// callback call returns. +/// NOTE: if user doesn't pass the instance of this context to zenoh-c, the delete_fn callback won't +/// be executed. +#[derive(Debug)] +#[repr(C)] +pub struct zc_context_t { + context: *mut c_void, + delete_fn: unsafe extern "C" fn(*mut c_void), +} + +decl_rust_copy_type!( + zenoh:(Context), + c:(zc_context_t) +); + +#[derive(Debug)] +pub struct Context(zc_context_t); +impl DroppableContext for Context { + fn get(&self) -> *mut c_void { + self.0.context + } +} +impl Drop for Context { + fn drop(&mut self) { + unsafe { + (self.0.delete_fn)(self.0.context); + } + } +} + +/// A tread-safe droppable context. +/// Contexts are idiomatically used in C together with callback interfaces to deliver associated state +/// information to each callback. +/// +/// This is a thread-safe context - the associated callbacks may be executed concurrently with the same +/// zc_context_t instance. In other words, the context data MUST be thread-safe. +/// +/// Once moved to zenoh-c ownership, this context is guaranteed to execute delete_fn when deleted.The +/// delete_fn is guaranteed to be executed only once at some point of time after the last associated +/// callback call returns. +/// NOTE: if user doesn't pass the instance of this context to zenoh-c, the delete_fn callback won't +/// be executed. +#[derive(Debug)] +#[repr(C)] +pub struct zc_threadsafe_context_t { + context: AtomicPtr, + delete_fn: unsafe extern "C" fn(*mut c_void), +} + +decl_rust_copy_type!( + zenoh:(ThreadsafeContext), + c:(zc_threadsafe_context_t) +); + +#[derive(Debug)] +pub struct ThreadsafeContext(zc_threadsafe_context_t); +impl DroppableContext for ThreadsafeContext { + fn get(&self) -> *mut c_void { + self.0.context.load(std::sync::atomic::Ordering::Relaxed) + } +} +impl Drop for ThreadsafeContext { + fn drop(&mut self) { + unsafe { + (self.0.delete_fn)(self.0.context.load(std::sync::atomic::Ordering::Relaxed)); + } + } +} diff --git a/src/get.rs b/src/get.rs index 056e0f152..8e985d99f 100644 --- a/src/get.rs +++ b/src/get.rs @@ -50,11 +50,11 @@ type ReplyInner = Option; /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. #[cfg(not(target_arch = "arm"))] #[repr(C, align(8))] -pub struct z_owned_reply_t([u64; 28]); +pub struct z_owned_reply_t([u64; 30]); #[cfg(target_arch = "arm")] #[repr(C, align(8))] -pub struct z_owned_reply_t([u64; 19]); +pub struct z_owned_reply_t([u64; 21]); impl_guarded_transmute!(noderefs ReplyInner, z_owned_reply_t); diff --git a/src/lib.rs b/src/lib.rs index 93c4d219a..4d846550a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,10 +14,14 @@ #![allow(non_camel_case_types)] -mod collections; use std::cmp::min; use std::slice; +#[cfg(feature = "shared-memory")] +mod context; +#[cfg(feature = "shared-memory")] +pub use crate::context::*; +mod collections; pub use crate::collections::*; mod config; pub use crate::config::*; diff --git a/src/shm/client/shared_memory_client.rs b/src/shm/client/shared_memory_client.rs index bd011b7e7..da8456ceb 100644 --- a/src/shm/client/shared_memory_client.rs +++ b/src/shm/client/shared_memory_client.rs @@ -26,10 +26,8 @@ use zenoh::{ use zenoh_util::core::bail; use crate::{ - common::types::z_segment_id_t, - decl_rust_copy_type, impl_guarded_transmute, - provider::shared_memory_provider_backend::{zc_context_t, Context}, - GuardedTransmute, + common::types::z_segment_id_t, decl_rust_copy_type, impl_guarded_transmute, + zc_threadsafe_context_t, DroppableContext, GuardedTransmute, ThreadsafeContext, }; use super::shared_memory_segment::{z_shared_memory_segment_t, DynamicSharedMemorySegment}; @@ -65,19 +63,16 @@ decl_rust_copy_type!( #[derive(Debug)] pub struct DynamicSharedMemoryClient { - context: Context, + context: ThreadsafeContext, callbacks: zc_shared_memory_client_callbacks_t, } impl DynamicSharedMemoryClient { - pub fn new(context: Context, callbacks: zc_shared_memory_client_callbacks_t) -> Self { + pub fn new(context: ThreadsafeContext, callbacks: zc_shared_memory_client_callbacks_t) -> Self { Self { context, callbacks } } } -unsafe impl Send for DynamicSharedMemoryClient {} -unsafe impl Sync for DynamicSharedMemoryClient {} - impl SharedMemoryClient for DynamicSharedMemoryClient { fn attach(&self, segment: SegmentID) -> Result> { let mut segment_data = MaybeUninit::uninit(); @@ -95,7 +90,7 @@ impl SharedMemoryClient for DynamicSharedMemoryClient { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_shared_memory_client_new( - context: zc_context_t, + context: zc_threadsafe_context_t, callbacks: zc_shared_memory_client_callbacks_t, out_client: &mut MaybeUninit, ) { diff --git a/src/shm/client/shared_memory_segment.rs b/src/shm/client/shared_memory_segment.rs index e9c86d611..3dc51bdbc 100644 --- a/src/shm/client/shared_memory_segment.rs +++ b/src/shm/client/shared_memory_segment.rs @@ -19,31 +19,31 @@ use zenoh::{ shm::{client::shared_memory_segment::SharedMemorySegment, common::types::ChunkID}, Result, }; +use zenoh_util::core::zerror; use crate::{ - common::types::z_chunk_id_t, - provider::shared_memory_provider_backend::{zc_context_t, Context}, - GuardedTransmute, + common::types::z_chunk_id_t, zc_threadsafe_context_t, DroppableContext, GuardedTransmute, + ThreadsafeContext, }; /// A callbacks for SharedMemorySegment #[derive(Debug)] #[repr(C)] pub struct zc_shared_memory_segment_callbacks_t { - map_fn: unsafe extern "C" fn(*mut c_void, z_chunk_id_t), + map_fn: unsafe extern "C" fn(*mut c_void, z_chunk_id_t) -> *mut u8, } /// A SharedMemorySegment #[derive(Debug)] #[repr(C)] pub struct z_shared_memory_segment_t { - context: zc_context_t, + context: zc_threadsafe_context_t, callbacks: zc_shared_memory_segment_callbacks_t, } #[derive(Debug)] pub struct DynamicSharedMemorySegment { - context: Context, + context: ThreadsafeContext, callbacks: zc_shared_memory_segment_callbacks_t, } @@ -56,14 +56,14 @@ impl DynamicSharedMemorySegment { } } -unsafe impl Send for DynamicSharedMemorySegment {} -unsafe impl Sync for DynamicSharedMemorySegment {} - impl SharedMemorySegment for DynamicSharedMemorySegment { fn map(&self, chunk: ChunkID) -> Result> { unsafe { - (self.callbacks.map_fn)(self.context.get(), chunk); + let cb_result = (self.callbacks.map_fn)(self.context.get(), chunk); + cb_result + .as_mut() + .map(|p| AtomicPtr::new(p)) + .ok_or_else(|| zerror!("C callback returned null pointer!").into()) } - todo!() } } diff --git a/src/shm/client_storage/mod.rs b/src/shm/client_storage/mod.rs index f9b7736ba..7fb5dc382 100644 --- a/src/shm/client_storage/mod.rs +++ b/src/shm/client_storage/mod.rs @@ -53,7 +53,7 @@ pub unsafe extern "C" fn zc_shared_memory_client_list_new() -> zc_shared_memory_ #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_shared_memory_client_list_add( +pub unsafe extern "C" fn zc_shared_memory_client_list_add_client( id: z_protocol_id_t, client: z_shared_memory_client_t, list: &mut zc_shared_memory_client_list_t, @@ -121,9 +121,8 @@ pub unsafe extern "C" fn z_shared_memory_client_storage_new_with_default_client_ clients: zc_shared_memory_client_list_t, out_storage: &mut MaybeUninit, ) -> bool { - let mut builder = SharedMemoryClientStorage::builder().with_default_client_set(); - let mut clients = clients.transmute(); + let mut builder = SharedMemoryClientStorage::builder().with_default_client_set(); for (id, client) in clients.drain(0..) { match builder.with_client(id, client) { diff --git a/src/shm/provider/alloc_layout_threadsafe.rs b/src/shm/provider/alloc_layout_threadsafe.rs new file mode 100644 index 000000000..3b1d42c02 --- /dev/null +++ b/src/shm/provider/alloc_layout_threadsafe.rs @@ -0,0 +1,140 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use std::mem::MaybeUninit; + +use libc::c_void; +use zenoh::shm::provider::shared_memory_provider::{ + AllocLayout, BlockOn, Deallocate, Defragment, DynamicProtocolID, GarbageCollect, JustAlloc, +}; + +use crate::{ + decl_rust_copy_type, impl_guarded_transmute, zc_threadsafe_context_t, DroppableContext, + GuardedTransmute, ThreadsafeContext, +}; + +use super::{ + shared_memory_provider_backend::DynamicSharedMemoryProviderBackend, types::z_buf_alloc_result_t, +}; + +/// A thread-safe SharedMemoryProvider's AllocLayout +#[cfg(target_arch = "x86_64")] +#[repr(C, align(8))] +pub struct z_alloc_layout_threadsafe_t([u64; 4]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(16))] +pub struct z_alloc_layout_threadsafe_t([u64; 14]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(8))] +pub struct z_alloc_layout_threadsafe_t([u64; 14]); + +decl_rust_copy_type!( + zenoh:(AllocLayout<'static, DynamicProtocolID, DynamicSharedMemoryProviderBackend>), + c:(z_alloc_layout_threadsafe_t) +); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_threadsafe_delete(layout: z_alloc_layout_threadsafe_t) { + let _ = layout.transmute(); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc( + layout: &z_alloc_layout_threadsafe_t, + out_buffer: &mut MaybeUninit, +) { + let layout = layout.transmute_ref(); + let buffer = layout.alloc().with_policy::().res(); + out_buffer.write(buffer.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc_gc( + layout: &z_alloc_layout_threadsafe_t, + out_buffer: &mut MaybeUninit, +) { + let layout = layout.transmute_ref(); + let buffer = layout.alloc().with_policy::().res(); + out_buffer.write(buffer.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc_gc_defrag( + layout: &z_alloc_layout_threadsafe_t, + out_buffer: &mut MaybeUninit, +) { + let layout = layout.transmute_ref(); + let buffer = layout + .alloc() + .with_policy::>() + .res(); + out_buffer.write(buffer.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc_gc_defrag_dealloc( + layout: &z_alloc_layout_threadsafe_t, + out_buffer: &mut MaybeUninit, +) { + let layout = layout.transmute_ref(); + let buffer = layout + .alloc() + .with_policy::>>() + .res(); + out_buffer.write(buffer.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc_gc_defrag_blocking( + layout: &z_alloc_layout_threadsafe_t, + out_buffer: &mut MaybeUninit, +) { + let layout = layout.transmute_ref(); + let buffer = layout + .alloc() + .with_policy::>>() + .res(); + out_buffer.write(buffer.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc_gc_defrag_async( + layout: &'static z_alloc_layout_threadsafe_t, + out_buffer: &'static mut MaybeUninit, + result_context: zc_threadsafe_context_t, + result_callback: unsafe extern "C" fn(*mut c_void, &mut MaybeUninit), +) { + let result_context = result_context.transmute(); + //todo: this should be ported to tokio with executor argument support + async_std::task::block_on(async move { + let layout = layout.transmute_ref(); + let buffer = layout + .alloc() + .with_policy::>>() + .res_async() + .await; + out_buffer.write(buffer.transmute()); + + (result_callback)(result_context.get(), out_buffer); + }); +} diff --git a/src/shm/provider/mod.rs b/src/shm/provider/mod.rs index a38e328d9..0439233e6 100644 --- a/src/shm/provider/mod.rs +++ b/src/shm/provider/mod.rs @@ -12,8 +12,11 @@ // ZettaScale Zenoh Team, // +pub mod alloc_layout_threadsafe; pub mod chunk; pub mod shared_memory_provider; pub mod shared_memory_provider_backend; +pub mod shared_memory_provider_impl; +pub mod shared_memory_provider_threadsafe; pub mod types; pub mod zsliceshm; diff --git a/src/shm/provider/shared_memory_provider.rs b/src/shm/provider/shared_memory_provider.rs index 7f25d6041..ae630f3e7 100644 --- a/src/shm/provider/shared_memory_provider.rs +++ b/src/shm/provider/shared_memory_provider.rs @@ -20,26 +20,21 @@ use zenoh::shm::provider::shared_memory_provider::{ }; use crate::{ - common::types::z_protocol_id_t, decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute, + common::types::z_protocol_id_t, decl_rust_copy_type, impl_guarded_transmute, zc_context_t, + Context, GuardedTransmute, }; use super::{ chunk::z_allocated_chunk_t, shared_memory_provider_backend::{ - zc_context_t, zc_shared_memory_provider_backend_callbacks_t, - DynamicSharedMemoryProviderBackend, + zc_shared_memory_provider_backend_callbacks_t, DynamicSharedMemoryProviderBackend, }, + shared_memory_provider_impl::alloc, types::{z_alloc_alignment_t, z_buf_alloc_result_t}, zsliceshm::z_slice_shm_t, }; -/// An owned SharedMemoryProvider -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. +/// A non-thread-safe SharedMemoryProvider specialization #[cfg(target_arch = "x86_64")] #[repr(C, align(8))] pub struct z_shared_memory_provider_t([u64; 14]); @@ -53,7 +48,7 @@ pub struct z_shared_memory_provider_t([u64; 14]); pub struct z_shared_memory_provider_t([u64; 14]); decl_rust_copy_type!( - zenoh:(SharedMemoryProvider), + zenoh:(SharedMemoryProvider>), c:(z_shared_memory_provider_t) ); @@ -87,7 +82,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_alloc( alignment: z_alloc_alignment_t, out_buffer: &mut MaybeUninit, ) -> bool { - alloc::(provider, size, alignment, out_buffer) + alloc_inner::(provider, size, alignment, out_buffer) } #[no_mangle] @@ -98,7 +93,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc( alignment: z_alloc_alignment_t, out_buffer: &mut MaybeUninit, ) -> bool { - alloc::(provider, size, alignment, out_buffer) + alloc_inner::(provider, size, alignment, out_buffer) } #[no_mangle] @@ -109,7 +104,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc_defrag( alignment: z_alloc_alignment_t, out_buffer: &mut MaybeUninit, ) -> bool { - alloc::>(provider, size, alignment, out_buffer) + alloc_inner::>(provider, size, alignment, out_buffer) } #[no_mangle] @@ -120,7 +115,9 @@ pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc_defrag_dealloc( alignment: z_alloc_alignment_t, out_buffer: &mut MaybeUninit, ) -> bool { - alloc::>>(provider, size, alignment, out_buffer) + alloc_inner::>>( + provider, size, alignment, out_buffer, + ) } #[no_mangle] @@ -131,33 +128,17 @@ pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc_defrag_blocking( alignment: z_alloc_alignment_t, out_buffer: &mut MaybeUninit, ) -> bool { - alloc::>>(provider, size, alignment, out_buffer) + alloc_inner::>>(provider, size, alignment, out_buffer) } #[allow(clippy::missing_safety_doc)] -unsafe fn alloc( +unsafe fn alloc_inner( provider: &z_shared_memory_provider_t, size: usize, alignment: z_alloc_alignment_t, out_buffer: &mut MaybeUninit, ) -> bool { - let provider = provider.transmute_ref(); - match provider - .alloc_layout() - .size(size) - .alignment(alignment.transmute()) - .res() - { - Ok(layout) => { - let result = layout.alloc().with_policy::().res().transmute(); - out_buffer.write(result); - return true; - } - Err(e) => { - log::error!("{e}"); - } - }; - false + alloc::(provider, size, alignment, out_buffer) } #[no_mangle] diff --git a/src/shm/provider/shared_memory_provider_backend.rs b/src/shm/provider/shared_memory_provider_backend.rs index 6ff4adca3..7e4b28b14 100644 --- a/src/shm/provider/shared_memory_provider_backend.rs +++ b/src/shm/provider/shared_memory_provider_backend.rs @@ -12,6 +12,8 @@ // ZettaScale Zenoh Team, // +use std::fmt::Debug; + use libc::c_void; use zenoh::shm::provider::{ chunk::ChunkDescriptor, @@ -21,42 +23,13 @@ use zenoh::shm::provider::{ use zenoh::Result; use zenoh_util::core::bail; -use crate::{decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute}; +use crate::{DroppableContext, GuardedTransmute}; use super::{ chunk::z_chunk_descriptor_t, types::{z_chunk_alloc_result_t, z_memory_layout_t}, }; -/// A droppable context -#[derive(Debug)] -#[repr(C)] -pub struct zc_context_t { - context: *mut c_void, - drop_fn: unsafe extern "C" fn(*mut c_void), -} - -decl_rust_copy_type!( - zenoh:(Context), - c:(zc_context_t) -); - -#[derive(Debug)] -pub struct Context(zc_context_t); - -impl Context { - pub fn get(&self) -> *mut c_void { - self.0.context - } -} -impl Drop for Context { - fn drop(&mut self) { - unsafe { - (self.0.drop_fn)(self.0.context); - } - } -} - /// A callbacks for SharedMemoryProviderBackend #[derive(Debug)] #[repr(C)] @@ -72,18 +45,30 @@ pub struct zc_shared_memory_provider_backend_callbacks_t { } #[derive(Debug)] -pub struct DynamicSharedMemoryProviderBackend { - context: Context, +pub struct DynamicSharedMemoryProviderBackend +where + TContext: DroppableContext, +{ + context: TContext, callbacks: zc_shared_memory_provider_backend_callbacks_t, } -impl DynamicSharedMemoryProviderBackend { - pub fn new(context: Context, callbacks: zc_shared_memory_provider_backend_callbacks_t) -> Self { +impl DynamicSharedMemoryProviderBackend +where + TContext: DroppableContext, +{ + pub fn new( + context: TContext, + callbacks: zc_shared_memory_provider_backend_callbacks_t, + ) -> Self { Self { context, callbacks } } } -impl SharedMemoryProviderBackend for DynamicSharedMemoryProviderBackend { +impl SharedMemoryProviderBackend for DynamicSharedMemoryProviderBackend +where + TContext: DroppableContext, +{ fn alloc(&self, layout: &MemoryLayout) -> ChunkAllocResult { let mut result = std::mem::MaybeUninit::uninit(); unsafe { diff --git a/src/shm/provider/shared_memory_provider_impl.rs b/src/shm/provider/shared_memory_provider_impl.rs new file mode 100644 index 000000000..39d217036 --- /dev/null +++ b/src/shm/provider/shared_memory_provider_impl.rs @@ -0,0 +1,97 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use std::mem::MaybeUninit; + +use zenoh::shm::provider::shared_memory_provider::{ + AllocPolicy, AsyncAllocPolicy, DynamicProtocolID, SharedMemoryProvider, +}; + +use crate::{DroppableContext, GuardedTransmute, ThreadsafeContext}; + +use super::{ + shared_memory_provider_backend::DynamicSharedMemoryProviderBackend, + types::{z_alloc_alignment_t, z_buf_alloc_result_t}, +}; + +#[allow(clippy::missing_safety_doc)] +pub(crate) unsafe fn alloc( + provider: &TAnyProvider, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool +where + TAnyContext: DroppableContext, + TAnyProvider: GuardedTransmute< + SharedMemoryProvider>, + >, +{ + let provider = provider.transmute_ref(); + match provider + .alloc_layout() + .size(size) + .alignment(alignment.transmute()) + .res() + { + Ok(layout) => { + let result = layout.alloc().with_policy::().res().transmute(); + out_buffer.write(result); + return true; + } + Err(e) => { + log::error!("{e}"); + } + }; + false +} + +#[allow(clippy::missing_safety_doc)] +pub(crate) async fn alloc_async( + provider: &TThreadsafeProvider, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool +where + TThreadsafeProvider: GuardedTransmute< + SharedMemoryProvider< + DynamicProtocolID, + DynamicSharedMemoryProviderBackend, + >, + >, +{ + let provider = provider.transmute_ref(); + match provider + .alloc_layout() + .size(size) + .alignment(alignment.transmute()) + .res() + { + Ok(layout) => { + let result = layout + .alloc() + .with_policy::() + .res_async() + .await + .transmute(); + out_buffer.write(result); + return true; + } + Err(e) => { + log::error!("{e}"); + } + }; + false +} diff --git a/src/shm/provider/shared_memory_provider_threadsafe.rs b/src/shm/provider/shared_memory_provider_threadsafe.rs new file mode 100644 index 000000000..ffd22010b --- /dev/null +++ b/src/shm/provider/shared_memory_provider_threadsafe.rs @@ -0,0 +1,245 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use std::mem::MaybeUninit; + +use libc::c_void; +use zenoh::shm::provider::shared_memory_provider::{ + AllocPolicy, BlockOn, Deallocate, Defragment, DynamicProtocolID, GarbageCollect, JustAlloc, + SharedMemoryProvider, SharedMemoryProviderBuilder, +}; + +use crate::{ + common::types::z_protocol_id_t, decl_rust_copy_type, impl_guarded_transmute, + zc_threadsafe_context_t, DroppableContext, GuardedTransmute, ThreadsafeContext, +}; + +use super::{ + alloc_layout_threadsafe::z_alloc_layout_threadsafe_t, + chunk::z_allocated_chunk_t, + shared_memory_provider_backend::{ + zc_shared_memory_provider_backend_callbacks_t, DynamicSharedMemoryProviderBackend, + }, + shared_memory_provider_impl::{alloc, alloc_async}, + types::{z_alloc_alignment_t, z_buf_alloc_result_t}, + zsliceshm::z_slice_shm_t, +}; + +/// A thread-safe SharedMemoryProvider specialization +#[cfg(target_arch = "x86_64")] +#[repr(C, align(8))] +pub struct z_shared_memory_provider_threadsafe_t([u64; 14]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(16))] +pub struct z_shared_memory_provider_threadsafe_t([u64; 14]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(8))] +pub struct z_shared_memory_provider_threadsafe_t([u64; 14]); + +decl_rust_copy_type!( + zenoh:(SharedMemoryProvider>), + c:(z_shared_memory_provider_threadsafe_t) +); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_new( + id: z_protocol_id_t, + context: zc_threadsafe_context_t, + callbacks: zc_shared_memory_provider_backend_callbacks_t, + out_provider: &mut MaybeUninit, +) { + let backend = DynamicSharedMemoryProviderBackend::new(context.transmute(), callbacks); + let provider = SharedMemoryProviderBuilder::builder() + .dynamic_protocol_id(id) + .backend(backend) + .res(); + out_provider.write(provider.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_delete( + provider: z_shared_memory_provider_threadsafe_t, +) { + let _ = provider.transmute(); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_layout( + provider: &'static z_shared_memory_provider_threadsafe_t, + size: usize, + alignment: z_alloc_alignment_t, + out_layout: &mut MaybeUninit, +) -> bool { + let provider = provider.transmute_ref(); + match provider + .alloc_layout() + .size(size) + .alignment(alignment.transmute()) + .res() + { + Ok(layout) => { + out_layout.write(layout.transmute()); + return true; + } + Err(e) => { + log::error!("{e}"); + } + }; + false +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc( + provider: &z_shared_memory_provider_threadsafe_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool { + alloc_inner::(provider, size, alignment, out_buffer) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc( + provider: &z_shared_memory_provider_threadsafe_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool { + alloc_inner::(provider, size, alignment, out_buffer) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag( + provider: &z_shared_memory_provider_threadsafe_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool { + alloc_inner::>(provider, size, alignment, out_buffer) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag_dealloc( + provider: &z_shared_memory_provider_threadsafe_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool { + alloc_inner::>>( + provider, size, alignment, out_buffer, + ) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag_blocking( + provider: &z_shared_memory_provider_threadsafe_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool { + alloc_inner::>>(provider, size, alignment, out_buffer) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag_async( + provider: &z_shared_memory_provider_threadsafe_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, + result_context: zc_threadsafe_context_t, + result_callback: unsafe extern "C" fn( + *mut c_void, + bool, + &mut MaybeUninit, + ), +) { + let result_context = result_context.transmute(); + //todo: this should be ported to tokio with executor argument support + async_std::task::block_on(async move { + let result = alloc_async::< + BlockOn>, + z_shared_memory_provider_threadsafe_t, + >(provider, size, alignment, out_buffer) + .await; + (result_callback)(result_context.get(), result, out_buffer); + }); +} + +#[allow(clippy::missing_safety_doc)] +unsafe fn alloc_inner( + provider: &z_shared_memory_provider_threadsafe_t, + size: usize, + alignment: z_alloc_alignment_t, + out_buffer: &mut MaybeUninit, +) -> bool { + alloc::( + provider, size, alignment, out_buffer, + ) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_defragment( + provider: &z_shared_memory_provider_threadsafe_t, +) -> usize { + provider.transmute_ref().defragment() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_garbage_collect( + provider: &z_shared_memory_provider_threadsafe_t, +) -> usize { + provider.transmute_ref().garbage_collect() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_available( + provider: &z_shared_memory_provider_threadsafe_t, +) -> usize { + provider.transmute_ref().available() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_map( + provider: &z_shared_memory_provider_threadsafe_t, + allocated_chunk: z_allocated_chunk_t, + len: usize, + out_buffer: &mut MaybeUninit, +) -> bool { + let provider = provider.transmute_ref(); + match provider.map(allocated_chunk.transmute(), len) { + Ok(buffer) => { + out_buffer.write(buffer.transmute()); + true + } + Err(e) => { + log::error!("{e}"); + false + } + } +} From b496c431bd7895215ddf1d0265a677830ca16b1e Mon Sep 17 00:00:00 2001 From: yellowhatter Date: Tue, 2 Apr 2024 09:06:54 +0300 Subject: [PATCH 14/75] [skip ci] add non-thread-safe AllocLayout API --- include/zenoh_commons.h | 46 +++++++++++-- src/shm/provider/alloc_layout.rs | 113 +++++++++++++++++++++++++++++++ src/shm/provider/mod.rs | 1 + 3 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 src/shm/provider/alloc_layout.rs diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 336e22b54..b4b66b2ad 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -178,19 +178,19 @@ typedef enum zcu_reply_keyexpr_t { * A thread-safe SharedMemoryProvider's AllocLayout */ #if defined(TARGET_ARCH_X86_64) -typedef struct ALIGN(8) z_alloc_layout_threadsafe_t { +typedef struct ALIGN(8) z_alloc_layout_t { uint64_t _0[4]; -} z_alloc_layout_threadsafe_t; +} z_alloc_layout_t; #endif #if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(16) z_alloc_layout_threadsafe_t { +typedef struct ALIGN(16) z_alloc_layout_t { uint64_t _0[14]; -} z_alloc_layout_threadsafe_t; +} z_alloc_layout_t; #endif #if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_alloc_layout_threadsafe_t { +typedef struct ALIGN(8) z_alloc_layout_t { uint64_t _0[14]; -} z_alloc_layout_threadsafe_t; +} z_alloc_layout_t; #endif #if defined(TARGET_ARCH_X86_64) typedef struct ALIGN(8) z_buf_alloc_result_t { @@ -207,6 +207,24 @@ typedef struct ALIGN(8) z_buf_alloc_result_t { uint64_t _0[10]; } z_buf_alloc_result_t; #endif +/** + * A thread-safe SharedMemoryProvider's AllocLayout + */ +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_alloc_layout_threadsafe_t { + uint64_t _0[4]; +} z_alloc_layout_threadsafe_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_alloc_layout_threadsafe_t { + uint64_t _0[14]; +} z_alloc_layout_threadsafe_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_alloc_layout_threadsafe_t { + uint64_t _0[14]; +} z_alloc_layout_threadsafe_t; +#endif /** * A tread-safe droppable context. * Contexts are idiomatically used in C together with callback interfaces to deliver associated state @@ -1359,6 +1377,22 @@ ZENOHC_API extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; ZENOHC_API extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; ZENOHC_API extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; ZENOHC_API +void z_alloc_layout_alloc(const struct z_alloc_layout_t *layout, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +void z_alloc_layout_alloc_gc(const struct z_alloc_layout_t *layout, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +void z_alloc_layout_alloc_gc_defrag(const struct z_alloc_layout_t *layout, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +void z_alloc_layout_alloc_gc_defrag_blocking(const struct z_alloc_layout_t *layout, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API +void z_alloc_layout_alloc_gc_defrag_dealloc(const struct z_alloc_layout_t *layout, + struct z_buf_alloc_result_t *out_buffer); +ZENOHC_API void z_alloc_layout_delete(struct z_alloc_layout_t layout); +ZENOHC_API void z_alloc_layout_threadsafe_alloc(const struct z_alloc_layout_threadsafe_t *layout, struct z_buf_alloc_result_t *out_buffer); ZENOHC_API diff --git a/src/shm/provider/alloc_layout.rs b/src/shm/provider/alloc_layout.rs new file mode 100644 index 000000000..cf1843d09 --- /dev/null +++ b/src/shm/provider/alloc_layout.rs @@ -0,0 +1,113 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use std::mem::MaybeUninit; + +use zenoh::shm::provider::shared_memory_provider::{ + AllocLayout, BlockOn, Deallocate, Defragment, DynamicProtocolID, GarbageCollect, JustAlloc, +}; + +use crate::{decl_rust_copy_type, impl_guarded_transmute, Context, GuardedTransmute}; + +use super::{ + shared_memory_provider_backend::DynamicSharedMemoryProviderBackend, types::z_buf_alloc_result_t, +}; + +/// A thread-safe SharedMemoryProvider's AllocLayout +#[cfg(target_arch = "x86_64")] +#[repr(C, align(8))] +pub struct z_alloc_layout_t([u64; 4]); + +#[cfg(target_arch = "aarch64")] +#[repr(C, align(16))] +pub struct z_alloc_layout_t([u64; 14]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(8))] +pub struct z_alloc_layout_t([u64; 14]); + +decl_rust_copy_type!( + zenoh:(AllocLayout<'static, DynamicProtocolID, DynamicSharedMemoryProviderBackend>), + c:(z_alloc_layout_t) +); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_delete(layout: z_alloc_layout_t) { + let _ = layout.transmute(); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_alloc( + layout: &z_alloc_layout_t, + out_buffer: &mut MaybeUninit, +) { + let layout = layout.transmute_ref(); + let buffer = layout.alloc().with_policy::().res(); + out_buffer.write(buffer.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_alloc_gc( + layout: &z_alloc_layout_t, + out_buffer: &mut MaybeUninit, +) { + let layout = layout.transmute_ref(); + let buffer = layout.alloc().with_policy::().res(); + out_buffer.write(buffer.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_alloc_gc_defrag( + layout: &z_alloc_layout_t, + out_buffer: &mut MaybeUninit, +) { + let layout = layout.transmute_ref(); + let buffer = layout + .alloc() + .with_policy::>() + .res(); + out_buffer.write(buffer.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_alloc_gc_defrag_dealloc( + layout: &z_alloc_layout_t, + out_buffer: &mut MaybeUninit, +) { + let layout = layout.transmute_ref(); + let buffer = layout + .alloc() + .with_policy::>>() + .res(); + out_buffer.write(buffer.transmute()); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_alloc_gc_defrag_blocking( + layout: &z_alloc_layout_t, + out_buffer: &mut MaybeUninit, +) { + let layout = layout.transmute_ref(); + let buffer = layout + .alloc() + .with_policy::>>() + .res(); + out_buffer.write(buffer.transmute()); +} diff --git a/src/shm/provider/mod.rs b/src/shm/provider/mod.rs index 0439233e6..c8d0abdff 100644 --- a/src/shm/provider/mod.rs +++ b/src/shm/provider/mod.rs @@ -12,6 +12,7 @@ // ZettaScale Zenoh Team, // +pub mod alloc_layout; pub mod alloc_layout_threadsafe; pub mod chunk; pub mod shared_memory_provider; From 0fb31f78710da2a0b30be53063e87f37623b76b7 Mon Sep 17 00:00:00 2001 From: yellowhatter Date: Tue, 2 Apr 2024 13:20:08 +0300 Subject: [PATCH 15/75] [skip ci] - eliminate old SHM API types - fix ThreadsafeContext compilation - add custom SHM clients API for Session open - add necessary deleters --- include/zenoh_commons.h | 54 ++++++++++++++++++-------------- include/zenoh_macros.h | 33 ++++++++++--------- src/context.rs | 10 +++--- src/session.rs | 35 +++++++++++++++++++++ src/shm/provider/alloc_layout.rs | 2 +- src/shm/provider/types.rs | 6 ++++ src/shm/provider/zsliceshm.rs | 8 ++++- tests/z_api_null_drop_test.c | 24 +++----------- 8 files changed, 110 insertions(+), 62 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index b4b66b2ad..f3c22880d 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -174,8 +174,23 @@ typedef enum zcu_reply_keyexpr_t { ZCU_REPLY_KEYEXPR_ANY = 0, ZCU_REPLY_KEYEXPR_MATCHING_QUERY = 1, } zcu_reply_keyexpr_t; +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(4) z_alloc_alignment_t { + uint32_t _0[1]; +} z_alloc_alignment_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(4) z_alloc_alignment_t { + uint32_t _0[1]; +} z_alloc_alignment_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(4) z_alloc_alignment_t { + uint32_t _0[1]; +} z_alloc_alignment_t; +#endif /** - * A thread-safe SharedMemoryProvider's AllocLayout + * A non-thread-safe SharedMemoryProvider's AllocLayout */ #if defined(TARGET_ARCH_X86_64) typedef struct ALIGN(8) z_alloc_layout_t { @@ -240,7 +255,7 @@ typedef struct ALIGN(8) z_alloc_layout_threadsafe_t { * be executed. */ typedef struct zc_threadsafe_context_t { - AtomicPtr context; + void *context; void (*delete_fn)(void*); } zc_threadsafe_context_t; /** @@ -891,6 +906,12 @@ typedef struct ALIGN(8) z_memory_layout_t { uint64_t _0[2]; } z_memory_layout_t; #endif +/** + * A SharedMemoryClientStorage. + */ +typedef struct z_shared_memory_client_storage_t { + size_t _0; +} z_shared_memory_client_storage_t; /** * A SharedMemoryClient */ @@ -1061,12 +1082,6 @@ typedef struct z_shared_memory_segment_t { typedef struct zc_shared_memory_client_callbacks_t { bool (*attach_fn)(void*, z_segment_id_t, struct z_shared_memory_segment_t*); } zc_shared_memory_client_callbacks_t; -/** - * A SharedMemoryClientStorage. - */ -typedef struct z_shared_memory_client_storage_t { - size_t _0; -} z_shared_memory_client_storage_t; /** * A list of SharedMemoryClients. */ @@ -1103,21 +1118,6 @@ typedef struct ALIGN(8) z_shared_memory_provider_t { uint64_t _0[14]; } z_shared_memory_provider_t; #endif -#if defined(TARGET_ARCH_X86_64) -typedef struct ALIGN(4) z_alloc_alignment_t { - uint32_t _0[1]; -} z_alloc_alignment_t; -#endif -#if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(4) z_alloc_alignment_t { - uint32_t _0[1]; -} z_alloc_alignment_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_alloc_alignment_t { - uint32_t _0[1]; -} z_alloc_alignment_t; -#endif /** * Unique protocol identifier. * Here is a contract: it is up to user to make sure that incompatible SharedMemoryClient @@ -1376,6 +1376,7 @@ ZENOHC_API extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; ZENOHC_API extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; ZENOHC_API extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; ZENOHC_API extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; +ZENOHC_API void z_alloc_alignment_delete(struct z_alloc_alignment_t alignment); ZENOHC_API void z_alloc_layout_alloc(const struct z_alloc_layout_t *layout, struct z_buf_alloc_result_t *out_buffer); @@ -2131,6 +2132,12 @@ ZENOHC_API int8_t z_mutex_unlock(struct z_mutex_t *m); */ ZENOHC_API struct z_owned_session_t z_open(struct z_owned_config_t *config); +/** + * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + */ +ZENOHC_API +struct z_owned_session_t z_open_with_shm_clients(struct z_owned_config_t *config, + const struct z_shared_memory_client_storage_t *shm_clients); ZENOHC_API struct z_shared_memory_client_t z_posix_shared_memory_client_new(void); ZENOHC_API bool z_posix_shared_memory_provider_new(const struct z_memory_layout_t *layout, @@ -2608,6 +2615,7 @@ void z_shared_memory_provider_threadsafe_new(z_protocol_id_t id, ZENOHC_API int8_t z_sleep_ms(size_t time); ZENOHC_API int8_t z_sleep_s(size_t time); ZENOHC_API int8_t z_sleep_us(size_t time); +ZENOHC_API void z_slice_shm_delete(struct z_slice_shm_t slice); /** * Returns ``true`` if `strs` is valid. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index fa6668d48..726abef13 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -43,11 +43,25 @@ z_owned_query_channel_t * : z_query_channel_drop, \ z_owned_bytes_map_t * : z_bytes_map_drop, \ zc_owned_payload_t * : zc_payload_drop, \ - zc_owned_shmbuf_t * : zc_shmbuf_drop, \ - zc_owned_shm_manager_t * : zc_shm_manager_drop, \ zc_owned_liveliness_token_t * : zc_liveliness_undeclare_token, \ ze_owned_publication_cache_t * : ze_undeclare_publication_cache, \ ze_owned_querying_subscriber_t * : ze_undeclare_querying_subscriber \ + /* + z_shared_memory_client_t : z_shared_memory_client_delete, + z_shared_memory_client_storage_t : z_shared_memory_client_storage_deref, + zc_shared_memory_client_list_t : zc_shared_memory_client_list_delete, + z_alloc_layout_threadsafe_t : z_alloc_layout_threadsafe_delete, \ + z_alloc_layout_t : z_alloc_layout_delete, \ + z_chunk_descriptor_t : z_chunk_descriptor_delete, \ + z_allocated_chunk_t : z_allocated_chunk_delete, \ + z_shared_memory_provider_threadsafe_t : z_shared_memory_provider_threadsafe_delete, \ + z_shared_memory_provider_t : z_shared_memory_provider_delete, \ + z_alloc_alignment_t : z_alloc_alignment_delete, \ + z_memory_layout_t : z_memory_layout_delete, \ + z_chunk_alloc_result_t : z_chunk_alloc_result_delete, \ + z_buf_alloc_result_t : z_buf_alloc_result_delete, \ + z_slice_shm_t : z_slice_shm_delete \ + */ \ )(x) #define z_null(x) (*x = \ @@ -75,8 +89,6 @@ z_owned_bytes_map_t * : z_bytes_map_null, \ z_attachment_t * : z_attachment_null, \ zc_owned_payload_t * : zc_payload_null, \ - zc_owned_shmbuf_t * : zc_shmbuf_null, \ - zc_owned_shm_manager_t * : zc_shm_manager_null, \ ze_owned_publication_cache_t * : ze_publication_cache_null, \ zc_owned_liveliness_token_t * : zc_liveliness_token_null \ )()) @@ -100,8 +112,6 @@ z_owned_bytes_map_t : z_bytes_map_check, \ z_attachment_t : z_attachment_check, \ zc_owned_payload_t : zc_payload_check, \ - zc_owned_shmbuf_t : zc_shmbuf_check, \ - zc_owned_shm_manager_t : zc_shm_manager_check, \ zc_owned_liveliness_token_t : zc_liveliness_token_check, \ ze_owned_publication_cache_t : ze_publication_cache_check, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_check \ @@ -125,6 +135,9 @@ #define z_closure(...) _z_closure_overloader(__VA_ARGS__, NULL, NULL) #define z_move(x) (&x) +#define z_alt_move(x) (x) +#define z_alt_loan(x) (&x) + #else // #ifndef __cplusplus // clang-format off @@ -172,8 +185,6 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -201,8 +212,6 @@ template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } template<> inline void z_drop(z_owned_query_t* v) { z_query_drop(v); } template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } template<> inline void z_drop(zc_owned_payload_t* v) { zc_payload_drop(v); } -template<> inline void z_drop(zc_owned_shmbuf_t* v) { zc_shmbuf_drop(v); } -template<> inline void z_drop(zc_owned_shm_manager_t* v) { zc_shm_manager_drop(v); } template<> inline void z_drop(z_owned_closure_sample_t* v) { z_closure_sample_drop(v); } template<> inline void z_drop(z_owned_closure_query_t* v) { z_closure_query_drop(v); } template<> inline void z_drop(z_owned_closure_reply_t* v) { z_closure_reply_drop(v); } @@ -230,8 +239,6 @@ inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } inline void z_null(z_owned_query_t& v) { v = z_query_null(); } inline void z_null(z_owned_str_t& v) { v = z_str_null(); } inline void z_null(zc_owned_payload_t& v) { v = zc_payload_null(); } -inline void z_null(zc_owned_shmbuf_t& v) { v = zc_shmbuf_null(); } -inline void z_null(zc_owned_shm_manager_t& v) { v = zc_shm_manager_null(); } inline void z_null(z_owned_closure_sample_t& v) { v = z_closure_sample_null(); } inline void z_null(z_owned_closure_query_t& v) { v = z_closure_query_null(); } inline void z_null(z_owned_closure_reply_t& v) { v = z_closure_reply_null(); } @@ -253,8 +260,6 @@ inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } inline bool z_check(const z_bytes_t& v) { return z_bytes_check(&v); } inline bool z_check(const zc_owned_payload_t& v) { return zc_payload_check(&v); } -inline bool z_check(const zc_owned_shmbuf_t& v) { return zc_shmbuf_check(&v); } -inline bool z_check(const zc_owned_shm_manager_t& v) { return zc_shm_manager_check(&v); } inline bool z_check(const z_owned_subscriber_t& v) { return z_subscriber_check(&v); } inline bool z_check(const z_owned_pull_subscriber_t& v) { return z_pull_subscriber_check(&v); } inline bool z_check(const z_owned_queryable_t& v) { return z_queryable_check(&v); } diff --git a/src/context.rs b/src/context.rs index fb5e7b4a2..cb30a2eac 100644 --- a/src/context.rs +++ b/src/context.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh team, // -use std::{fmt::Debug, sync::atomic::AtomicPtr}; +use std::fmt::Debug; use libc::c_void; @@ -82,7 +82,7 @@ impl Drop for Context { #[derive(Debug)] #[repr(C)] pub struct zc_threadsafe_context_t { - context: AtomicPtr, + context: *mut c_void, delete_fn: unsafe extern "C" fn(*mut c_void), } @@ -95,13 +95,15 @@ decl_rust_copy_type!( pub struct ThreadsafeContext(zc_threadsafe_context_t); impl DroppableContext for ThreadsafeContext { fn get(&self) -> *mut c_void { - self.0.context.load(std::sync::atomic::Ordering::Relaxed) + self.0.context } } impl Drop for ThreadsafeContext { fn drop(&mut self) { unsafe { - (self.0.delete_fn)(self.0.context.load(std::sync::atomic::Ordering::Relaxed)); + (self.0.delete_fn)(self.0.context); } } } +unsafe impl Send for ThreadsafeContext {} +unsafe impl Sync for ThreadsafeContext {} diff --git a/src/session.rs b/src/session.rs index 2caab85ea..3caf63ea1 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,6 +12,8 @@ // ZettaScale Zenoh team, // +#[cfg(feature = "shared-memory")] +use crate::client_storage::z_shared_memory_client_storage_t; use crate::{config::*, impl_guarded_transmute, zc_init_logger}; use std::sync::{Arc, Weak}; use zenoh::prelude::sync::SyncResolve; @@ -118,6 +120,39 @@ pub extern "C" fn z_open(config: &mut z_owned_config_t) -> z_owned_session_t { } } +/// Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. +#[allow(clippy::missing_safety_doc)] +#[no_mangle] +#[cfg(feature = "shared-memory")] +pub extern "C" fn z_open_with_shm_clients( + config: &mut z_owned_config_t, + shm_clients: &z_shared_memory_client_storage_t, +) -> z_owned_session_t { + use crate::GuardedTransmute; + + if cfg!(feature = "logger-autoinit") { + zc_init_logger(); + } + + let config = match config.as_mut().take() { + Some(c) => c, + None => { + log::error!("Config not provided"); + return z_owned_session_t::null(); + } + }; + match zenoh::open(*config) + .with_shm_clients(shm_clients.transmute_ref().clone()) + .res() + { + Ok(s) => z_owned_session_t::new(Arc::new(s)), + Err(e) => { + log::error!("Error opening session: {}", e); + z_owned_session_t::null() + } + } +} + /// Returns ``true`` if `session` is valid. #[allow(clippy::missing_safety_doc)] #[no_mangle] diff --git a/src/shm/provider/alloc_layout.rs b/src/shm/provider/alloc_layout.rs index cf1843d09..68ffbc0a4 100644 --- a/src/shm/provider/alloc_layout.rs +++ b/src/shm/provider/alloc_layout.rs @@ -24,7 +24,7 @@ use super::{ shared_memory_provider_backend::DynamicSharedMemoryProviderBackend, types::z_buf_alloc_result_t, }; -/// A thread-safe SharedMemoryProvider's AllocLayout +/// A non-thread-safe SharedMemoryProvider's AllocLayout #[cfg(target_arch = "x86_64")] #[repr(C, align(8))] pub struct z_alloc_layout_t([u64; 4]); diff --git a/src/shm/provider/types.rs b/src/shm/provider/types.rs index 477cdf142..278449714 100644 --- a/src/shm/provider/types.rs +++ b/src/shm/provider/types.rs @@ -77,6 +77,12 @@ decl_rust_copy_type!( c:(z_alloc_alignment_t) ); +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_alignment_delete(alignment: z_alloc_alignment_t) { + let _ = alignment.transmute(); +} + // An owned MemoryLayout. /// /// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. diff --git a/src/shm/provider/zsliceshm.rs b/src/shm/provider/zsliceshm.rs index ceb39dac1..376f87e59 100644 --- a/src/shm/provider/zsliceshm.rs +++ b/src/shm/provider/zsliceshm.rs @@ -14,7 +14,7 @@ use zenoh::shm::provider::zsliceshm::ZSliceShm; -use crate::{decl_rust_copy_type, impl_guarded_transmute}; +use crate::{decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute}; // A ZSliceSHM #[cfg(target_arch = "x86_64")] @@ -33,3 +33,9 @@ decl_rust_copy_type!( zenoh:(ZSliceShm), c:(z_slice_shm_t) ); + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_slice_shm_delete(slice: z_slice_shm_t) { + let _ = slice.transmute(); +} diff --git a/tests/z_api_null_drop_test.c b/tests/z_api_null_drop_test.c index 814d80e7c..300dac200 100644 --- a/tests/z_api_null_drop_test.c +++ b/tests/z_api_null_drop_test.c @@ -44,8 +44,6 @@ int main(int argc, char **argv) { z_owned_reply_channel_t reply_channel_null_1 = z_reply_channel_null(); z_owned_str_t str_null_1 = z_str_null(); zc_owned_payload_t payload_null_1 = zc_payload_null(); - zc_owned_shmbuf_t shmbuf_null_1 = zc_shmbuf_null(); - zc_owned_shm_manager_t shm_manager_null_1 = zc_shm_manager_null(); // // Test that they actually make invalid value (where applicable) @@ -63,9 +61,7 @@ int main(int argc, char **argv) { assert(!z_check(hello_null_1)); assert(!z_check(str_null_1)); assert(!z_check(payload_null_1)); - assert(!z_check(shmbuf_null_1)); - assert(!z_check(shm_manager_null_1)); - + // // Test that z_null macro defined for all types // @@ -89,9 +85,7 @@ int main(int argc, char **argv) { z_owned_reply_channel_t reply_channel_null_2; z_owned_str_t str_null_2; zc_owned_payload_t payload_null_2; - zc_owned_shmbuf_t shmbuf_null_2; - zc_owned_shm_manager_t shm_manager_null_2; - + z_null(&session_null_2); z_null(&publisher_null_2); z_null(&keyexpr_null_2); @@ -112,9 +106,7 @@ int main(int argc, char **argv) { z_null(&reply_channel_null_2); z_null(&str_null_2); z_null(&payload_null_2); - z_null(&shmbuf_null_2); - z_null(&shm_manager_null_2); - + // // Test that null macro works the same as direct call // @@ -131,9 +123,7 @@ int main(int argc, char **argv) { assert(!z_check(hello_null_2)); assert(!z_check(str_null_2)); assert(!z_check(payload_null_2)); - assert(!z_check(shmbuf_null_2)); - assert(!z_check(shm_manager_null_2)); - + // // Test drop null and double drop it // @@ -158,9 +148,7 @@ int main(int argc, char **argv) { z_drop(z_move(reply_channel_null_1)); z_drop(z_move(str_null_1)); z_drop(z_move(payload_null_1)); - z_drop(z_move(shmbuf_null_1)); - z_drop(z_move(shm_manager_null_1)); - + z_drop(z_move(session_null_2)); z_drop(z_move(publisher_null_2)); z_drop(z_move(keyexpr_null_2)); @@ -181,8 +169,6 @@ int main(int argc, char **argv) { z_drop(z_move(reply_channel_null_2)); z_drop(z_move(str_null_2)); z_drop(z_move(payload_null_2)); - z_drop(z_move(shmbuf_null_2)); - z_drop(z_move(shm_manager_null_2)); } return 0; From 206983ecb23142bda6dc43e00aaec1e89c2d80c9 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Wed, 3 Apr 2024 22:34:30 +0200 Subject: [PATCH 16/75] put and get with owned payload --- .gitignore | 5 +- CMakeLists.txt | 5 + Cargo.lock | 1 + Cargo.toml | 1 + Cargo.toml.in | 1 + build-resources/opaque-types/Cargo.lock | 2624 +++++++++++++++++++++++ build-resources/opaque-types/Cargo.toml | 10 + build-resources/opaque-types/src/lib.rs | 38 + build.rs | 57 +- examples/z_get.c | 9 +- examples/z_non_blocking_get.c | 7 +- examples/z_ping.c | 5 +- examples/z_pong.c | 6 +- examples/z_pub.c | 3 +- examples/z_pub_attachment.c | 3 +- examples/z_pub_cache.c | 3 +- examples/z_pub_shm.c | 2 +- examples/z_pub_thr.c | 3 +- examples/z_pull.c | 7 +- examples/z_put.c | 3 +- examples/z_query_sub.c | 7 +- examples/z_queryable.c | 10 +- examples/z_queryable_with_channels.c | 10 +- examples/z_sub.c | 7 +- examples/z_sub_attachment.c | 6 +- include/zenoh_commons.h | 185 +- src/collections.rs | 79 +- src/commons.rs | 152 +- src/get.rs | 136 +- src/lib.rs | 2 + src/liveliness.rs | 7 +- src/opaque_types/mod.rs | 15 + src/publisher.rs | 59 +- src/pull_subscriber.rs | 6 +- src/put.rs | 68 +- src/queryable.rs | 19 +- src/querying_subscriber.rs | 6 +- src/subscriber.rs | 6 +- tests/z_api_alignment_test.c | 6 +- tests/z_int_pub_cache_query_sub_test.c | 15 +- tests/z_int_pub_sub_attachment_test.c | 9 +- tests/z_int_pub_sub_test.c | 9 +- tests/z_int_queryable_attachment_test.c | 9 +- tests/z_int_queryable_test.c | 9 +- 44 files changed, 3200 insertions(+), 430 deletions(-) create mode 100644 build-resources/opaque-types/Cargo.lock create mode 100644 build-resources/opaque-types/Cargo.toml create mode 100644 build-resources/opaque-types/src/lib.rs create mode 100644 src/opaque_types/mod.rs diff --git a/.gitignore b/.gitignore index d7a6cf967..8aaf37e32 100644 --- a/.gitignore +++ b/.gitignore @@ -70,4 +70,7 @@ dkms.conf .cache # Platform dependent generated files -include/zenoh_configure.h \ No newline at end of file +include/zenoh_configure.h + +# Build resources +.build_resources* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 00aa5cac2..aac66278b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,6 +179,10 @@ set_genexpr_condition(cargo_flags DEBUG $ "--manifest-path=${cargo_toml_dir_debug}/Cargo.toml" "--release;--manifest-path=${cargo_toml_dir_release}/Cargo.toml") set(cargo_flags ${cargo_flags} ${ZENOHC_CARGO_FLAGS}) +set_genexpr_condition(cargo_dep_flags DEBUG $ + "--manifest-path=${CMAKE_CURRENT_SOURCE_DIR}/build-resources/opaque-types/Cargo.toml" + "--release;--manifest-path=${CMAKE_CURRENT_SOURCE_DIR}/build-resources/opaque-types/Cargo.toml") +set(cargo_dep_flags ${cargo_dep_flags} ${ZENOHC_CARGO_FLAGS}) if(ZENOHC_BUILD_WITH_LOGGER_AUTOINIT) set(cargo_flags ${cargo_flags} --features=logger-autoinit) @@ -199,6 +203,7 @@ add_custom_command( OUTPUT ${libs} COMMAND ${CMAKE_COMMAND} -E echo \"RUSTFLAGS = $$RUSTFLAGS\" COMMAND ${CMAKE_COMMAND} -E echo \"cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_flags}\" + COMMAND cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_dep_flags} &> ${CMAKE_CURRENT_SOURCE_DIR}/.build_resources_opaque_types.txt || echo "" COMMAND cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_flags} VERBATIM COMMAND_EXPAND_LISTS diff --git a/Cargo.lock b/Cargo.lock index d29080bad..7bf87ae6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3024,6 +3024,7 @@ dependencies = [ "libc", "log", "rand", + "regex", "serde_yaml", "spin 0.9.8", "zenoh", diff --git a/Cargo.toml b/Cargo.toml index 95867f95f..8e0541888 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,6 +59,7 @@ zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/ze [build-dependencies] cbindgen = "0.24.3" fs2 = "0.4.3" +regex = "1.7.1" serde_yaml = "0.9.19" [lib] diff --git a/Cargo.toml.in b/Cargo.toml.in index f434df3a1..a8123bcd5 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -59,6 +59,7 @@ zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/ze [build-dependencies] cbindgen = "0.24.3" fs2 = "0.4.3" +regex = "1.7.1" serde_yaml = "0.9.19" [lib] diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock new file mode 100644 index 000000000..a6f37dab3 --- /dev/null +++ b/build-resources/opaque-types/Cargo.lock @@ -0,0 +1,2624 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" + +[[package]] +name = "array-init" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d62b7694a562cdf5a74227903507c56ab2cc8bdd1f781ed5cb4cf9c9f810bfc" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28243a43d821d11341ab73c80bed182dc015c514b951616cf79bd4af39af0c3" +dependencies = [ + "concurrent-queue", + "event-listener 5.2.0", + "event-listener-strategy 0.5.0", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +dependencies = [ + "async-lock 3.3.0", + "async-task", + "concurrent-queue", + "fastrand 2.0.2", + "futures-lite 2.3.0", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.2.0", + "async-executor", + "async-io 2.3.2", + "async-lock 3.3.0", + "blocking", + "futures-lite 2.3.0", + "once_cell", + "tokio", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", +] + +[[package]] +name = "async-io" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +dependencies = [ + "async-lock 3.3.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.3.0", + "parking", + "polling 3.6.0", + "rustix 0.38.32", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.3", + "event-listener-strategy 0.4.0", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +dependencies = [ + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", + "blocking", + "cfg-if", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.32", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-signal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +dependencies = [ + "async-io 2.3.2", + "async-lock 2.8.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.32", + "signal-hook-registry", + "slab", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite 1.13.0", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" + +[[package]] +name = "async-trait" +version = "0.1.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +dependencies = [ + "async-channel 2.2.0", + "async-lock 3.3.0", + "async-task", + "fastrand 2.0.2", + "futures-io", + "futures-lite 2.3.0", + "piper", + "tracing", +] + +[[package]] +name = "bumpalo" +version = "3.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "cache-padded" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" + +[[package]] +name = "cc" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "concurrent-queue" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b5fb89194fa3cad959b833185b3063ba881dbfc7030680b314250779fb4cc91" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feedafcaa9b749175d5ac357452a9d41ea2911da598fde46ce1fe02c37751291" +dependencies = [ + "event-listener 5.2.0", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "spin", +] + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand 2.0.2", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "git-version" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad568aa3db0fcbc81f2f116137f263d7304f512a1209b35b85150d3ef88ad19" +dependencies = [ + "git-version-macro", +] + +[[package]] +name = "git-version-macro" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ipnetwork" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e" +dependencies = [ + "serde", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keyed-set" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79e110283e09081809ca488cf3a9709270c6d4d4c4a32674c39cc438366615a" +dependencies = [ + "hashbrown 0.13.2", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if", + "windows-targets 0.52.4", +] + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.5.0", + "libc", + "redox_syscall", +] + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +dependencies = [ + "value-bag", +] + +[[package]] +name = "lz4_flex" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[package]] +name = "nix" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "no-std-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "opaque-types" +version = "0.1.0" +dependencies = [ + "zenoh", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-float" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "pest_meta" +version = "2.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.2", + "futures-io", +] + +[[package]] +name = "pnet_base" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cf6fb3ab38b68d01ab2aea03ed3d1132b4868fa4e06285f29f16da01c5f4c" +dependencies = [ + "no-std-net", +] + +[[package]] +name = "pnet_datalink" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad5854abf0067ebbd3967f7d45ebc8976ff577ff0c7bd101c4973ae3c70f98fe" +dependencies = [ + "ipnetwork", + "libc", + "pnet_base", + "pnet_sys", + "winapi", +] + +[[package]] +name = "pnet_sys" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "417c0becd1b573f6d544f73671070b039051e5ad819cc64aa96377b536128d00" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0c976a60b2d7e99d6f229e414670a9b85d13ac305cc6d1e9c134de58c5aaaf6" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 0.38.32", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "ringbuffer-spsc" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1938faa63a2362ee1747afb2d10567d0fb1413b9cbd6198a8541485c4f773" +dependencies = [ + "array-init", + "cache-padded", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys 0.4.13", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" + +[[package]] +name = "rustls-webpki" +version = "0.102.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "serde", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "shared_memory" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba8593196da75d9dc4f69349682bd4c2099f8cde114257d1ef7ef1b33d1aba54" +dependencies = [ + "cfg-if", + "libc", + "nix", + "rand", + "win-sys", +] + +[[package]] +name = "shellexpand" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" +dependencies = [ + "dirs", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stop-token" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" +dependencies = [ + "async-channel 1.9.0", + "cfg-if", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "token-cell" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a2b964fdb303b08a4eab04d7c1bad2bca33f8eee334ccd28802f1041c6eb87" +dependencies = [ + "paste", +] + +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2 0.5.6", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "futures-util", + "hashbrown 0.14.3", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uhlc" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b6df3f3e948b40e20c38a6d1fd6d8f91b3573922fc164e068ad3331560487e" +dependencies = [ + "humantime", + "lazy_static", + "log", + "rand", + "serde", + "spin", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "unzip-n" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e7e85a0596447f0f2ac090e16bc4c516c6fe91771fb0c0ccf7fa3dae896b9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "getrandom", +] + +[[package]] +name = "validated_struct" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feef04c049b4beae3037a2a31b8da40d8cebec0b97456f24c7de0ede4ed9efed" +dependencies = [ + "json5", + "serde", + "serde_json", + "validated_struct_macros", +] + +[[package]] +name = "validated_struct_macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d4444a980afa9ef0d29c2a3f4d952ec0495a7a996a9c78b52698b71bc21edb4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", + "unzip-n", +] + +[[package]] +name = "value-bag" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74797339c3b98616c009c7c3eb53a0ce41e85c8ec66bd3db96ed132d20cfdee8" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.55", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "win-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b7b128a98c1cfa201b09eb49ba285887deb3cbe7466a98850eb1adabb452be5" +dependencies = [ + "windows", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45296b64204227616fdbf2614cefa4c236b98ee64dfaaaa435207ed99fe7829f" +dependencies = [ + "windows_aarch64_msvc 0.34.0", + "windows_i686_gnu 0.34.0", + "windows_i686_msvc 0.34.0", + "windows_x86_64_gnu 0.34.0", + "windows_x86_64_msvc 0.34.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + +[[package]] +name = "zenoh" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-trait", + "base64", + "const_format", + "env_logger", + "event-listener 4.0.3", + "flume", + "form_urlencoded", + "futures", + "git-version", + "lazy_static", + "log", + "ordered-float", + "paste", + "petgraph", + "rand", + "regex", + "rustc_version", + "serde", + "serde_json", + "socket2 0.5.6", + "stop-token", + "tokio", + "tokio-util", + "uhlc", + "uuid", + "vec_map", + "zenoh-buffers", + "zenoh-codec", + "zenoh-collections", + "zenoh-config", + "zenoh-core", + "zenoh-crypto", + "zenoh-keyexpr", + "zenoh-link", + "zenoh-macros", + "zenoh-plugin-trait", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-shm", + "zenoh-sync", + "zenoh-transport", + "zenoh-util", +] + +[[package]] +name = "zenoh-buffers" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "zenoh-collections", +] + +[[package]] +name = "zenoh-codec" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "log", + "serde", + "uhlc", + "zenoh-buffers", + "zenoh-protocol", + "zenoh-shm", +] + +[[package]] +name = "zenoh-collections" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" + +[[package]] +name = "zenoh-config" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "flume", + "json5", + "log", + "num_cpus", + "secrecy", + "serde", + "serde_json", + "serde_yaml", + "validated_struct", + "zenoh-core", + "zenoh-protocol", + "zenoh-result", + "zenoh-util", +] + +[[package]] +name = "zenoh-core" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-global-executor", + "lazy_static", + "tokio", + "zenoh-result", + "zenoh-runtime", +] + +[[package]] +name = "zenoh-crypto" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "aes", + "hmac", + "rand", + "rand_chacha", + "sha3", + "zenoh-result", +] + +[[package]] +name = "zenoh-keyexpr" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "hashbrown 0.14.3", + "keyed-set", + "rand", + "schemars", + "serde", + "token-cell", + "zenoh-result", +] + +[[package]] +name = "zenoh-link" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-trait", + "zenoh-config", + "zenoh-link-commons", + "zenoh-protocol", + "zenoh-result", +] + +[[package]] +name = "zenoh-link-commons" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-trait", + "flume", + "futures", + "log", + "rustls", + "rustls-webpki", + "serde", + "tokio", + "tokio-util", + "zenoh-buffers", + "zenoh-codec", + "zenoh-core", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-util", +] + +[[package]] +name = "zenoh-macros" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", + "zenoh-keyexpr", +] + +[[package]] +name = "zenoh-plugin-trait" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "const_format", + "libloading", + "log", + "serde", + "serde_json", + "zenoh-keyexpr", + "zenoh-macros", + "zenoh-result", + "zenoh-util", +] + +[[package]] +name = "zenoh-protocol" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "const_format", + "rand", + "serde", + "uhlc", + "zenoh-buffers", + "zenoh-keyexpr", + "zenoh-result", +] + +[[package]] +name = "zenoh-result" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "anyhow", +] + +[[package]] +name = "zenoh-runtime" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "lazy_static", + "tokio", + "zenoh-collections", + "zenoh-result", +] + +[[package]] +name = "zenoh-shm" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "log", + "serde", + "shared_memory", + "zenoh-buffers", + "zenoh-result", +] + +[[package]] +name = "zenoh-sync" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "event-listener 4.0.3", + "futures", + "tokio", + "zenoh-buffers", + "zenoh-collections", + "zenoh-core", + "zenoh-runtime", +] + +[[package]] +name = "zenoh-transport" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-trait", + "flume", + "log", + "lz4_flex", + "paste", + "rand", + "ringbuffer-spsc", + "serde", + "sha3", + "tokio", + "tokio-util", + "zenoh-buffers", + "zenoh-codec", + "zenoh-collections", + "zenoh-config", + "zenoh-core", + "zenoh-crypto", + "zenoh-link", + "zenoh-protocol", + "zenoh-result", + "zenoh-runtime", + "zenoh-shm", + "zenoh-sync", + "zenoh-util", +] + +[[package]] +name = "zenoh-util" +version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" +dependencies = [ + "async-std", + "async-trait", + "flume", + "home", + "humantime", + "lazy_static", + "libc", + "libloading", + "log", + "pnet_datalink", + "shellexpand", + "tokio", + "winapi", + "zenoh-core", + "zenoh-result", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/build-resources/opaque-types/Cargo.toml b/build-resources/opaque-types/Cargo.toml new file mode 100644 index 000000000..6e8319bb0 --- /dev/null +++ b/build-resources/opaque-types/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "opaque-types" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } \ No newline at end of file diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs new file mode 100644 index 000000000..8ef08035c --- /dev/null +++ b/build-resources/opaque-types/src/lib.rs @@ -0,0 +1,38 @@ +use zenoh::sample::Sample; +use zenoh::buffers::ZBuf; + +#[macro_export] +macro_rules! get_opaque_type_data { +($src_type:ty, $expr:expr) => { + const _: () = { + let align = std::mem::align_of::<$src_type>(); + let size = std::mem::size_of::<$src_type>(); + let mut msg: [u8; 61] = *b"type: , align: , size: "; + let mut i = 0; + while i < 4 { + msg[i as usize + 46] = b'0' + ((align / 10u32.pow(3 - i) as usize) % 10) as u8; + msg[i as usize + 57] = b'0' + ((size / 10u32.pow(3 - i) as usize) % 10) as u8; + i += 1; + } + let mut i: usize = 0; + while i < $expr.len() { + msg[i as usize + 5] = $expr.as_bytes()[i]; + i += 1; + } + panic!("{}", unsafe { + std::str::from_utf8_unchecked(msg.as_slice()) + }); + }; + } +} + +/// A split buffer that owns all of its data. +/// +/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. +get_opaque_type_data!(Option, "z_owned_buffer_t"); + +/// An owned sample. +/// +/// This is a read only type that can only be constructed by cloning a `z_sample_t`. +/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. +get_opaque_type_data!(Option, "zc_owned_sample_t"); \ No newline at end of file diff --git a/build.rs b/build.rs index 17dde1894..03a271817 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,5 @@ use fs2::FileExt; +use regex::Regex; use std::io::{Read, Write}; use std::{borrow::Cow, collections::HashMap, io::BufWriter, path::Path}; @@ -24,6 +25,7 @@ const HEADER: &str = r"// "; fn main() { + generate_opaque_types(); cbindgen::generate(std::env::var("CARGO_MANIFEST_DIR").unwrap()) .expect("Unable to generate bindings") .write_to_file(GENERATION_PATH); @@ -36,7 +38,60 @@ fn main() { println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=src"); println!("cargo:rerun-if-changed=splitguide.yaml"); - println!("cargo:rerun-if-changed=cbindgen.toml") + println!("cargo:rerun-if-changed=cbindgen.toml"); + println!("cargo:rerun-if-changed=build-resources") +} + +fn generate_opaque_types() { + let current_folder = std::env::current_dir().unwrap(); + let path_in = current_folder.join("./.build_resources_opaque_types.txt"); + let path_out = current_folder.join("./src/opaque_types/mod.rs"); + + let data_in = std::fs::read_to_string(path_in).unwrap(); + let mut data_out = String::new(); + let docs = get_opaque_type_docs(); + + let re = Regex::new(r"type:(\w+) *, align:0*(\d+), size:0*(\d+)").unwrap(); + for (_, [type_name, align, size]) in re.captures_iter(&data_in).map(|c| c.extract()) { + let s = format!( + "#[repr(C, align({align}))] +pub struct {type_name} {{ + _0: [u8; {size}] +}} +" + ); + if let Some(doc) = docs.get(type_name) { + for d in doc { + data_out += d; + data_out += "\r\n"; + } + } + data_out += &s; + } + std::fs::write(path_out, data_out).unwrap(); +} + +fn get_opaque_type_docs() -> HashMap> { + let current_folder = std::env::current_dir().unwrap(); + let path_in = current_folder.join("./build-resources/opaque-types/src/lib.rs"); + let re = Regex::new(r#"get_opaque_type_data!\(.*, "(\w+)"\)"#).unwrap(); + let mut comments = std::vec::Vec::::new(); + let mut res = HashMap::>::new(); + + for line in std::fs::read_to_string(path_in).unwrap().lines() { + if line.starts_with("///") { + comments.push(line.to_string()); + continue; + } + if comments.is_empty() { + continue; + } + if let Some(c) = re.captures(line) { + res.insert(c[1].to_string(), comments.clone()); + } + comments.clear(); + } + res } fn configure() { diff --git a/examples/z_get.c b/examples/z_get.c index 853366210..e5a1de104 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -57,17 +57,18 @@ int main(int argc, char **argv) { z_owned_reply_channel_t channel = zc_reply_fifo_new(16); z_get_options_t opts = z_get_options_default(); if (value != NULL) { - opts.value.payload = z_bytes_from_str(value); + opts.value.payload = zc_payload_encode_from_string(value); } z_get(z_loan(s), keyexpr, "", z_move(channel.send), - &opts); // here, the send is moved and will be dropped by zenoh when adequate + z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate z_owned_reply_t reply = z_reply_null(); for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_bytes_t payload = z_sample_payload(&sample); - printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)payload.len, payload.start); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); + printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload)); + z_drop(z_move(payload)); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index a741d6071..21437199c 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -49,7 +49,7 @@ int main(int argc, char **argv) { opts.target = Z_QUERY_TARGET_ALL; z_owned_reply_channel_t channel = zc_reply_non_blocking_fifo_new(16); z_get(z_loan(s), keyexpr, "", z_move(channel.send), - &opts); // here, the send is moved and will be dropped by zenoh when adequate + z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate z_owned_reply_t reply = z_reply_null(); for (bool call_success = z_call(channel.recv, &reply); !call_success || z_check(reply); call_success = z_call(channel.recv, &reply)) { @@ -59,8 +59,9 @@ int main(int argc, char **argv) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_bytes_t payload = z_sample_payload(&sample); - printf(">> Received ('%s': '%.*s')\n", z_loan(keystr), (int)payload.len, payload.start); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); + printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload)); + z_drop(z_move(payload)); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_ping.c b/examples/z_ping.c index fdc08f71d..a5c0954d0 100644 --- a/examples/z_ping.c +++ b/examples/z_ping.c @@ -54,6 +54,7 @@ int main(int argc, char** argv) { for (int i = 0; i < args.size; i++) { data[i] = i % 10; } + zc_owned_payload_t payload = zc_payload_encode_from_bytes((z_bytes_t){.start = data, .len = args.size}); z_mutex_lock(&mutex); if (args.warmup_ms) { printf("Warming up for %dms...\n", args.warmup_ms); @@ -61,7 +62,7 @@ int main(int argc, char** argv) { unsigned long elapsed_us = 0; while (elapsed_us < args.warmup_ms * 1000) { - z_publisher_put(z_loan(pub), data, args.size, NULL); + z_publisher_put(z_loan(pub), z_move(payload), NULL); int s = z_condvar_wait(&cond, &mutex); if (s != 0) { handle_error_en(s, "z_condvar_wait"); @@ -72,7 +73,7 @@ int main(int argc, char** argv) { unsigned long* results = z_malloc(sizeof(unsigned long) * args.number_of_pings); for (int i = 0; i < args.number_of_pings; i++) { z_clock_t measure_start = z_clock_now(); - z_publisher_put(z_loan(pub), data, args.size, NULL); + z_publisher_put(z_loan(pub), z_move(payload), NULL); int s = z_condvar_wait(&cond, &mutex); if (s != 0) { handle_error_en(s, "z_condvar_wait"); diff --git a/examples/z_pong.c b/examples/z_pong.c index 4047ff3d2..772280696 100644 --- a/examples/z_pong.c +++ b/examples/z_pong.c @@ -6,10 +6,8 @@ void callback(const z_sample_t* sample, void* context) { z_publisher_t pub = z_loan(*(z_owned_publisher_t*)context); #ifdef ZENOH_C // The zc_owned_payload_t API is exclusive to zenoh-c, but allows avoiding some copies. - z_owned_buffer_t payload = z_sample_owned_payload(sample); - zc_publisher_put_owned(pub, z_move(payload), NULL); -#else - z_publisher_put(pub, sample->payload.start, sample->payload.len, NULL); + zc_owned_payload_t payload = z_sample_owned_payload(sample); + z_publisher_put(pub, z_move(payload), NULL); #endif } void drop(void* context) { diff --git a/examples/z_pub.c b/examples/z_pub.c index ecc95e42d..9dd496153 100644 --- a/examples/z_pub.c +++ b/examples/z_pub.c @@ -71,7 +71,8 @@ int main(int argc, char **argv) { printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_publisher_put(z_loan(pub), (const uint8_t *)buf, strlen(buf), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); diff --git a/examples/z_pub_attachment.c b/examples/z_pub_attachment.c index a24133e91..530d9dc29 100644 --- a/examples/z_pub_attachment.c +++ b/examples/z_pub_attachment.c @@ -71,7 +71,8 @@ int main(int argc, char **argv) { sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - z_publisher_put(z_loan(pub), (const uint8_t *)buf, strlen(buf), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); diff --git a/examples/z_pub_cache.c b/examples/z_pub_cache.c index 770bf9d93..622896948 100644 --- a/examples/z_pub_cache.c +++ b/examples/z_pub_cache.c @@ -63,7 +63,8 @@ int main(int argc, char **argv) { z_sleep_s(1); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)buf, strlen(buf), NULL); + zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } z_drop(z_move(pub_cache)); diff --git a/examples/z_pub_shm.c b/examples/z_pub_shm.c index 10970bf62..3c032e02f 100644 --- a/examples/z_pub_shm.c +++ b/examples/z_pub_shm.c @@ -84,7 +84,7 @@ int main(int argc, char **argv) { z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); zc_owned_payload_t payload = zc_shmbuf_into_payload(z_move(shmbuf)); - zc_publisher_put_owned(z_loan(pub), z_move(payload), &options); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); diff --git a/examples/z_pub_thr.c b/examples/z_pub_thr.c index 8686c33eb..e0568973c 100644 --- a/examples/z_pub_thr.c +++ b/examples/z_pub_thr.c @@ -54,7 +54,8 @@ int main(int argc, char **argv) { } while (1) { - z_publisher_put(z_loan(pub), (const uint8_t *)value, len, NULL); + zc_owned_payload_t payload = zc_payload_encode_from_bytes((z_bytes_t){.start = value, .len = len}); + z_publisher_put(z_loan(pub), z_move(payload), NULL); } z_undeclare_publisher(z_move(pub)); diff --git a/examples/z_pull.c b/examples/z_pull.c index 4f2de7945..c7daf1172 100644 --- a/examples/z_pull.c +++ b/examples/z_pull.c @@ -18,9 +18,10 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_bytes_t payload = z_sample_payload(sample); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - (int)payload.len, payload.start); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + z_loan(payload)); + z_drop(z_move(payload)); z_drop(z_move(keystr)); } diff --git a/examples/z_put.c b/examples/z_put.c index 498d1e958..503fb5c36 100644 --- a/examples/z_put.c +++ b/examples/z_put.c @@ -48,7 +48,8 @@ int main(int argc, char **argv) { z_put_options_t options = z_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); options.attachment = z_bytes_map_as_attachment(&attachment); - int res = z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)value, strlen(value), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(value); + int res = z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), &options); if (res < 0) { printf("Put failed...\n"); } diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index d60bc2bf1..a5b2ec1f9 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -18,9 +18,10 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_bytes_t payload = z_sample_payload(sample); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - (int)payload.len, payload.start); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + z_loan(payload)); + z_drop(z_move(payload)); z_drop(z_move(keystr)); } diff --git a/examples/z_queryable.c b/examples/z_queryable.c index 9d6ec7702..25d8a959d 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -22,10 +22,12 @@ z_keyexpr_t keyexpr; void query_handler(const z_query_t *query, void *context) { z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); z_bytes_t pred = z_query_parameters(query); - z_value_t payload_value = z_query_value(query); - if (payload_value.payload.len > 0) { - printf(">> [Queryable ] Received Query '%s?%.*s' with value '%.*s'\n", z_loan(keystr), (int)pred.len, - pred.start, (int)payload_value.payload.len, payload_value.payload.start); + zc_payload_t payload = z_query_value(query).payload; + if (zc_payload_len(payload) > 0) { + z_owned_str_t payload_string = zc_payload_decode_into_string(payload); + printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, + pred.start, z_loan(payload_string)); + z_drop(z_move(payload_string)); } else { printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); } diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index 672ddd607..dfef42532 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -68,10 +68,12 @@ int main(int argc, char **argv) { z_query_t query = z_loan(oquery); z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(&query)); z_bytes_t pred = z_query_parameters(&query); - z_value_t payload_value = z_query_value(&query); - if (payload_value.payload.len > 0) { - printf(">> [Queryable ] Received Query '%s?%.*s' with value '%.*s'\n", z_loan(keystr), (int)pred.len, - pred.start, (int)payload_value.payload.len, payload_value.payload.start); + zc_payload_t payload = z_query_value(&query).payload; + if (zc_payload_len(payload) > 0) { + z_owned_str_t payload_string = zc_payload_decode_into_string(payload); + printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, + pred.start, z_loan(payload_string)); + z_drop(z_move(payload_string)); } else { printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); } diff --git a/examples/z_sub.c b/examples/z_sub.c index 378a717e6..c7ea05c9a 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -18,9 +18,10 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_bytes_t payload = z_sample_payload(sample); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - (int)payload.len, payload.start); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + z_loan(payload)); + z_drop(z_move(payload)); z_drop(z_move(keystr)); } diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index 2031d1155..b3be1f672 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -24,9 +24,8 @@ int8_t attachment_reader(z_bytes_t key, z_bytes_t val, void *ctx) { void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_bytes_t payload = z_sample_payload(sample); - printf(">> [Subscriber] Received %s ('%s': '%.*s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - (int)payload.len, payload.start); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload)); z_attachment_t attachment = z_sample_attachment(sample); // checks if attachment exists @@ -40,6 +39,7 @@ void data_handler(const z_sample_t *sample, void *arg) { printf(" message number: %.*s\n", (int)index.len, index.start); } } + z_drop(z_move(payload)); z_drop(z_move(keystr)); } diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 55a52f82d..26c428c29 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -207,13 +207,9 @@ typedef struct z_attachment_t { * A split buffer that owns all of its data. * * To minimize copies and reallocations, Zenoh may provide you data in split buffers. - * - * You can use `z_buffer_contiguous` to obtain a contiguous version of a buffer. - * If the buffer was already contiguous, the reference count will simply be increased. - * Otherwise, the split buffer's entire content will be copied in a newly allocated buffer. */ -typedef struct z_owned_buffer_t { - size_t _inner[5]; +typedef struct ALIGN(8) z_owned_buffer_t { + uint8_t _0[40]; } z_owned_buffer_t; /** * A loan of a `z_owned_buffer_t`. @@ -221,7 +217,7 @@ typedef struct z_owned_buffer_t { * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. */ typedef struct z_buffer_t { - const void *_inner; + struct z_owned_buffer_t *_inner; } z_buffer_t; /** * A map of maybe-owned vector of bytes to owned vector of bytes. @@ -617,7 +613,7 @@ typedef struct z_delete_options_t { * z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. */ typedef struct z_encoding_t { - uint64_t prefix; + enum z_encoding_prefix_t prefix; struct z_bytes_t suffix; } z_encoding_t; /** @@ -634,7 +630,7 @@ typedef struct z_encoding_t { * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. */ typedef struct z_owned_encoding_t { - uint64_t prefix; + enum z_encoding_prefix_t prefix; struct z_bytes_t suffix; bool _dropped; } z_owned_encoding_t; @@ -645,16 +641,22 @@ typedef struct z_query_consolidation_t { enum z_consolidation_mode_t mode; } z_query_consolidation_t; /** - * A zenoh value. + * An owned payload, backed by a reference counted owner. + * + * The `payload` field may be modified, and Zenoh will take the new values into account. + */ +typedef struct z_owned_buffer_t zc_owned_payload_t; +/** + * An owned zenoh value. * * Members: - * z_bytes_t payload: The payload of this zenoh value. - * z_encoding_t encoding: The encoding of this zenoh value `payload`. + * zc_owned_payload_t payload: The payload of this zenoh value. + * z_owned_encoding_t encoding: The encoding of this zenoh value `payload`. */ -typedef struct z_value_t { - struct z_bytes_t payload; - struct z_encoding_t encoding; -} z_value_t; +typedef struct z_owned_value_t { + zc_owned_payload_t payload; + struct z_owned_encoding_t encoding; +} z_owned_value_t; /** * Options passed to the :c:func:`z_get` function. * @@ -668,7 +670,7 @@ typedef struct z_value_t { typedef struct z_get_options_t { enum z_query_target_t target; struct z_query_consolidation_t consolidation; - struct z_value_t value; + struct z_owned_value_t value; struct z_attachment_t attachment; uint64_t timeout_ms; } z_get_options_t; @@ -792,6 +794,18 @@ typedef struct z_query_reply_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_query_reply_options_t; +typedef struct z_buffer_t zc_payload_t; +/** + * A zenoh value. + * + * Members: + * zc_payload_t payload: The payload of this zenoh value. + * z_encoding_t encoding: The encoding of this zenoh value `payload`. + */ +typedef struct z_value_t { + zc_payload_t payload; + struct z_encoding_t encoding; +} z_value_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -877,30 +891,14 @@ typedef struct zc_owned_liveliness_token_t { typedef struct zc_liveliness_get_options_t { uint32_t timeout_ms; } zc_liveliness_get_options_t; -/** - * An owned payload, backed by a reference counted owner. - * - * The `payload` field may be modified, and Zenoh will take the new values into account, - * however, assuming `ostart` and `olen` are the respective values of `payload.start` and - * `payload.len` when constructing the `zc_owned_payload_t payload` value was created, - * then `payload.start` MUST remain within the `[ostart, ostart + olen[` interval, and - * `payload.len` must remain within `[0, olen -(payload.start - ostart)]`. - * - * Should this invariant be broken when the payload is passed to one of zenoh's `put_owned` - * functions, then the operation will fail (but the passed value will still be consumed). - */ -typedef struct z_owned_buffer_t zc_owned_payload_t; /** * An owned sample. * * This is a read only type that can only be constructed by cloning a `z_sample_t`. * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. */ -typedef struct zc_owned_sample_t { - struct z_owned_keyexpr_t _0; - struct z_owned_buffer_t _1; - struct z_owned_buffer_t _2; - size_t _3[12]; +typedef struct ALIGN(8) zc_owned_sample_t { + uint8_t _0[224]; } zc_owned_sample_t; typedef struct zc_owned_shmbuf_t { size_t _0[9]; @@ -1083,19 +1081,16 @@ ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); * Increments the buffer's reference count, returning an owned version of the buffer. */ ZENOHC_API struct z_owned_buffer_t z_buffer_clone(struct z_buffer_t buffer); -/** - * Returns an owned version of this buffer whose data is guaranteed to be contiguous in memory. - * - * This is achieved by increasing the reference count if the buffer is already contiguous, and by copying its data in a new contiguous buffer if it wasn't. - */ -ZENOHC_API -struct z_owned_buffer_t z_buffer_contiguous(struct z_buffer_t buffer); /** * Decrements the buffer's reference counter, destroying it if applicable. * * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. */ ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); +/** + * Returns total number bytes in the buffer. + */ +ZENOHC_API size_t z_buffer_len(struct z_buffer_t buffer); /** * Loans the buffer, allowing you to call functions that only need a loan of it. */ @@ -1104,12 +1099,6 @@ ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer * The gravestone value for `z_owned_buffer_t`. */ ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); -/** - * Returns the payload of the buffer if it is contiguous, aliasling it. - * - * If the payload was not contiguous in memory, `z_bytes_null` will be returned instead. - */ -ZENOHC_API struct z_bytes_t z_buffer_payload(struct z_buffer_t buffer); /** * Returns the `index`th slice of the buffer, aliasing it. * @@ -1119,10 +1108,9 @@ ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t i /** * Returns the number of slices in the buffer. * - * If the return value is 0 or 1, then the buffer's data is contiguous in memory and `z_buffer_contiguous` will succeed. + * If the return value is 0 or 1, then the buffer's data is contiguous in memory. */ -ZENOHC_API -size_t z_buffer_slice_count(struct z_buffer_t buffer); +ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. */ @@ -1581,7 +1569,7 @@ int8_t z_get(struct z_session_t session, struct z_keyexpr_t keyexpr, const char *parameters, struct z_owned_closure_reply_t *callback, - const struct z_get_options_t *options); + struct z_get_options_t *options); ZENOHC_API struct z_get_options_t z_get_options_default(void); /** * Returns ``true`` if `hello` is valid. @@ -1819,22 +1807,24 @@ ZENOHC_API struct z_owned_publisher_t z_publisher_null(void); */ ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); /** - * Sends a `PUT` message onto the publisher's key expression. + * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. + * + * This is avoids copies when transfering data that was either: + * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher + * - constructed from a `zc_owned_shmbuf_t` * * The payload's encoding can be sepcified through the options. * * Parameters: * session: The zenoh session. * payload: The value to put. - * len: The length of the value to put. * options: The publisher put options. * Returns: * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API int8_t z_publisher_put(struct z_publisher_t publisher, - const uint8_t *payload, - size_t len, + zc_owned_payload_t *payload, const struct z_publisher_put_options_t *options); /** * Constructs the default value for :c:type:`z_publisher_put_options_t`. @@ -1858,7 +1848,11 @@ ZENOHC_API struct z_owned_pull_subscriber_t z_pull_subscriber_null(void); */ ZENOHC_API struct z_pull_subscriber_options_t z_pull_subscriber_options_default(void); /** - * Put data. + * Put data, transfering the buffer ownership. + * + * This is avoids copies when transfering data that was either: + * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher + * - constructed from a `zc_owned_shmbuf_t` * * The payload's encoding can be sepcified through the options. * @@ -1866,7 +1860,6 @@ ZENOHC_API struct z_pull_subscriber_options_t z_pull_subscriber_options_default( * session: The zenoh session. * keyexpr: The key expression to put. * payload: The value to put. - * len: The length of the value to put. * options: The put options. * Returns: * ``0`` in case of success, negative values in case of failure. @@ -1874,8 +1867,7 @@ ZENOHC_API struct z_pull_subscriber_options_t z_pull_subscriber_options_default( ZENOHC_API int8_t z_put(struct z_session_t session, struct z_keyexpr_t keyexpr, - const uint8_t *payload, - size_t len, + zc_owned_payload_t *payload, const struct z_put_options_t *opts); /** * Constructs the default value for :c:type:`z_put_options_t`. @@ -2133,7 +2125,7 @@ ZENOHC_API struct z_owned_buffer_t z_sample_owned_payload(const struct z_sample_ * * If you need ownership of the buffer, you may use `z_sample_owned_payload`. */ -ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); +ZENOHC_API struct z_buffer_t z_sample_payload(const struct z_sample_t *sample); /** * The qos with which the sample was received. */ @@ -2280,6 +2272,10 @@ ZENOHC_API int8_t z_undeclare_queryable(struct z_owned_queryable_t *qable); */ ZENOHC_API int8_t z_undeclare_subscriber(struct z_owned_subscriber_t *sub); +ZENOHC_API bool z_value_check(const struct z_owned_value_t *value); +ZENOHC_API void z_value_drop(struct z_owned_value_t *value); +ZENOHC_API struct z_value_t z_value_loan(const struct z_owned_value_t *value); +ZENOHC_API struct z_owned_value_t z_value_null(void); /** * Converts the kind of zenoh entity into a string. * @@ -2466,61 +2462,42 @@ ZENOHC_API void zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t * Returns `false` if `payload` is the gravestone value. */ ZENOHC_API bool zc_payload_check(const zc_owned_payload_t *payload); +/** + * Increments internal payload reference count, returning owned payload. + */ +ZENOHC_API zc_owned_payload_t zc_payload_clone(zc_payload_t payload); +/** + * Decodes payload into null-terminated string + */ +ZENOHC_API struct z_owned_str_t zc_payload_decode_into_string(zc_payload_t payload); /** * Decrements `payload`'s backing refcount, releasing the memory if appropriate. */ ZENOHC_API void zc_payload_drop(zc_owned_payload_t *payload); /** - * Constructs `zc_owned_payload_t`'s gravestone value. + * Encodes byte sequence by aliasing. */ -ZENOHC_API zc_owned_payload_t zc_payload_null(void); +ZENOHC_API zc_owned_payload_t zc_payload_encode_from_bytes(struct z_bytes_t bytes); /** - * Clones the `payload` by incrementing its reference counter. + * Encodes a null-terminated string by aliasing. */ -ZENOHC_API zc_owned_payload_t zc_payload_rcinc(const zc_owned_payload_t *payload); +ZENOHC_API zc_owned_payload_t zc_payload_encode_from_string(const char *cstr); /** - * Sends a `PUT` message onto the publisher's key expression, transfering the buffer ownership. - * - * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher - * - constructed from a `zc_owned_shmbuf_t` - * - * The payload's encoding can be sepcified through the options. - * - * Parameters: - * session: The zenoh session. - * payload: The value to put. - * len: The length of the value to put. - * options: The publisher put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. + * Returns total number bytes in the payload. */ -ZENOHC_API -int8_t zc_publisher_put_owned(struct z_publisher_t publisher, - zc_owned_payload_t *payload, - const struct z_publisher_put_options_t *options); +ZENOHC_API size_t zc_payload_len(zc_payload_t payload); /** - * Put data, transfering the buffer ownership. - * - * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher - * - constructed from a `zc_owned_shmbuf_t` - * - * The payload's encoding can be sepcified through the options. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to put. - * payload: The value to put. - * options: The put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. + * Returns a :c:type:`zc_payload_t` loaned from `payload`. */ -ZENOHC_API -int8_t zc_put_owned(struct z_session_t session, - struct z_keyexpr_t keyexpr, - zc_owned_payload_t *payload, - const struct z_put_options_t *opts); +ZENOHC_API zc_payload_t zc_payload_loan(const zc_owned_payload_t *payload); +/** + * Constructs `zc_owned_payload_t`'s gravestone value. + */ +ZENOHC_API zc_owned_payload_t zc_payload_null(void); +/** + * Clones the `payload` by incrementing its reference counter. + */ +ZENOHC_API zc_owned_payload_t zc_payload_rcinc(const zc_owned_payload_t *payload); /** * Creates a new blocking fifo channel, returned as a pair of closures. * diff --git a/src/collections.rs b/src/collections.rs index 89c0e0438..e0f2e7afe 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -13,12 +13,14 @@ // use libc::{c_char, size_t}; +use std::ops::Deref; +use std::ptr::NonNull; use zenoh::{ buffers::{buffer::SplitBuffer, ZBuf}, prelude::ZenohId, }; -use crate::impl_guarded_transmute; +use crate::{impl_guarded_transmute, GuardedTransmute}; /// A contiguous view of bytes owned by some other entity. /// @@ -162,17 +164,7 @@ impl From<&[u8]> for z_bytes_t { } } -/// A split buffer that owns all of its data. -/// -/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. -/// -/// You can use `z_buffer_contiguous` to obtain a contiguous version of a buffer. -/// If the buffer was already contiguous, the reference count will simply be increased. -/// Otherwise, the split buffer's entire content will be copied in a newly allocated buffer. -#[repr(C)] -pub struct z_owned_buffer_t { - _inner: [usize; 5], -} +pub use crate::z_owned_buffer_t; impl_guarded_transmute!(noderefs Option, z_owned_buffer_t); impl Default for z_owned_buffer_t { fn default() -> Self { @@ -181,13 +173,10 @@ impl Default for z_owned_buffer_t { } impl From for z_owned_buffer_t { fn from(value: ZBuf) -> Self { - let value = match value.contiguous() { - std::borrow::Cow::Borrowed(_) => value, - std::borrow::Cow::Owned(value) => value.into(), - }; - unsafe { core::mem::transmute(Some(value)) } + Some(value).transmute() } } + impl From> for z_owned_buffer_t { fn from(value: Option) -> Self { match value { @@ -239,12 +228,18 @@ pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { /// /// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. #[repr(C)] -#[derive(Clone, Copy)] -pub struct z_buffer_t<'a> { - _inner: &'a (), +#[derive(Clone, Copy, Default)] +pub struct z_buffer_t { + _inner: Option>, } -impl_guarded_transmute!(Option<&'a ZBuf>, z_buffer_t<'a>, 'a); -impl<'a> From> for Option<&'a ZBuf> { + +impl From> for z_buffer_t { + fn from(value: Option<&ZBuf>) -> Self { + unsafe { core::mem::transmute(value) } + } +} + +impl From for Option<&'static ZBuf> { fn from(value: z_buffer_t) -> Self { unsafe { core::mem::transmute(value) } } @@ -253,45 +248,29 @@ impl<'a> From> for Option<&'a ZBuf> { /// Increments the buffer's reference count, returning an owned version of the buffer. #[no_mangle] pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { - unsafe { Some(core::mem::transmute::<_, &ZBuf>(buffer).clone()).into() } -} - -/// Returns the payload of the buffer if it is contiguous, aliasling it. -/// -/// If the payload was not contiguous in memory, `z_bytes_null` will be returned instead. -#[no_mangle] -pub extern "C" fn z_buffer_payload(buffer: z_buffer_t) -> z_bytes_t { - let Some(buffer): Option<&ZBuf> = buffer.into() else { - return z_bytes_null(); - }; - match buffer.contiguous() { - std::borrow::Cow::Borrowed(buffer) => buffer.into(), - std::borrow::Cow::Owned(_) => z_bytes_null(), + match buffer._inner { + Some(b) => unsafe { b.as_ref().deref().clone().transmute() }, + None => ZBuf::empty().into(), } } -/// Returns an owned version of this buffer whose data is guaranteed to be contiguous in memory. +/// Returns the number of slices in the buffer. /// -/// This is achieved by increasing the reference count if the buffer is already contiguous, and by copying its data in a new contiguous buffer if it wasn't. +/// If the return value is 0 or 1, then the buffer's data is contiguous in memory. #[no_mangle] -pub extern "C" fn z_buffer_contiguous(buffer: z_buffer_t) -> z_owned_buffer_t { - let Some(buf): Option<&ZBuf> = buffer.into() else { - return z_buffer_null(); - }; - match buf.contiguous() { - std::borrow::Cow::Borrowed(_) => buf.clone().into(), - std::borrow::Cow::Owned(buf) => ZBuf::from(buf).into(), +pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { + match buffer.into() { + None => 0, + Some(buf) => ZBuf::slices(buf).len(), } } -/// Returns the number of slices in the buffer. -/// -/// If the return value is 0 or 1, then the buffer's data is contiguous in memory and `z_buffer_contiguous` will succeed. +/// Returns total number bytes in the buffer. #[no_mangle] -pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { +pub extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { match buffer.into() { None => 0, - Some(buf) => ZBuf::slices(buf).len(), + Some(buf) => ZBuf::slices(buf).fold(0, |acc, s| acc + s.len()), } } diff --git a/src/commons.rs b/src/commons.rs index d23618846..249333d66 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -12,7 +12,9 @@ // ZettaScale Zenoh team, // +use std::any::Any; use std::ops::Deref; +use std::slice; use crate::collections::*; use crate::keyexpr::*; @@ -22,8 +24,10 @@ use crate::z_priority_t; use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; +use zenoh::buffers::buffer::SplitBuffer; +use zenoh::buffers::ZBuf; +use zenoh::buffers::ZSliceBuffer; use zenoh::prelude::SampleKind; -use zenoh::prelude::SplitBuffer; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; use zenoh::sample::QoS; @@ -93,14 +97,7 @@ impl From> for z_timestamp_t { /// An owned payload, backed by a reference counted owner. /// -/// The `payload` field may be modified, and Zenoh will take the new values into account, -/// however, assuming `ostart` and `olen` are the respective values of `payload.start` and -/// `payload.len` when constructing the `zc_owned_payload_t payload` value was created, -/// then `payload.start` MUST remain within the `[ostart, ostart + olen[` interval, and -/// `payload.len` must remain within `[0, olen -(payload.start - ostart)]`. -/// -/// Should this invariant be broken when the payload is passed to one of zenoh's `put_owned` -/// functions, then the operation will fail (but the passed value will still be consumed). +/// The `payload` field may be modified, and Zenoh will take the new values into account. #[allow(non_camel_case_types)] pub type zc_owned_payload_t = z_owned_buffer_t; @@ -125,6 +122,81 @@ pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { z_buffer_null() } +/// Returns a :c:type:`zc_payload_t` loaned from `payload`. +#[no_mangle] +pub extern "C" fn zc_payload_loan(payload: &zc_owned_payload_t) -> zc_payload_t { + z_buffer_loan(payload) +} + +#[allow(non_camel_case_types)] +pub type zc_payload_t = z_buffer_t; + +/// Increments internal payload reference count, returning owned payload. +#[no_mangle] +pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t { + z_buffer_clone(payload) +} + +/// Decodes payload into null-terminated string +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_decode_into_string(payload: zc_payload_t) -> z_owned_str_t { + let payload: Option<&ZBuf> = payload.into(); + if payload.is_none() { + return z_str_null(); + } + let mut cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); + let payload = payload.unwrap(); + + let mut pos = 0; + for s in payload.slices() { + cstr.insert_unchecked(pos, s); + pos += s.len(); + } + cstr +} + +unsafe impl Send for z_bytes_t {} +unsafe impl Sync for z_bytes_t {} + +impl ZSliceBuffer for z_bytes_t { + fn as_slice(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.start, self.len) } + } + fn as_mut_slice(&mut self) -> &mut [u8] { + unsafe { slice::from_raw_parts_mut(self.start as *mut u8, self.len) } + } + fn as_any(&self) -> &dyn Any { + self + } +} + +/// Encodes byte sequence by aliasing. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_encode_from_bytes(bytes: z_bytes_t) -> zc_owned_payload_t { + ZBuf::from(bytes).into() +} + +/// Encodes a null-terminated string by aliasing. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_encode_from_string( + cstr: *const libc::c_char, +) -> zc_owned_payload_t { + let bytes = z_bytes_t { + start: cstr as *const u8, + len: libc::strlen(cstr), + }; + zc_payload_encode_from_bytes(bytes) +} + +/// Returns total number bytes in the payload. +#[no_mangle] +pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { + z_buffer_len(payload) +} + /// QoS settings of zenoh message. /// #[repr(C)] @@ -191,8 +263,8 @@ pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { /// /// If you need ownership of the buffer, you may use `z_sample_owned_payload`. #[no_mangle] -pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_bytes_t { - sample.payload.slices().next().unwrap_or(b"").into() +pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_buffer_t { + Some(&sample.payload).into() } /// Returns the sample's payload after incrementing its internal reference count. /// @@ -231,18 +303,7 @@ pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { } } -/// An owned sample. -/// -/// This is a read only type that can only be constructed by cloning a `z_sample_t`. -/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. -#[repr(C)] -pub struct zc_owned_sample_t { - _0: z_owned_keyexpr_t, - _1: z_owned_buffer_t, - _2: z_owned_buffer_t, - _3: [usize; 12], -} - +pub use crate::zc_owned_sample_t; impl_guarded_transmute!(Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. @@ -422,24 +483,21 @@ impl From for z_encoding_prefix_t { #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct z_encoding_t { - pub prefix: u64, + pub prefix: z_encoding_prefix_t, pub suffix: z_bytes_t, } impl From for zenoh_protocol::core::Encoding { fn from(enc: z_encoding_t) -> Self { if enc.suffix.len == 0 { - zenoh_protocol::core::Encoding::Exact((enc.prefix as u8).try_into().unwrap()) + zenoh_protocol::core::Encoding::Exact(enc.prefix.into()) } else { let suffix = unsafe { let slice: &'static [u8] = std::slice::from_raw_parts(enc.suffix.start, enc.suffix.len); std::str::from_utf8_unchecked(slice) }; - zenoh_protocol::core::Encoding::WithSuffix( - (enc.prefix as u8).try_into().unwrap(), - suffix.into(), - ) + zenoh_protocol::core::Encoding::WithSuffix(enc.prefix.into(), suffix.into()) } } } @@ -448,7 +506,7 @@ impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { fn from(val: &zenoh_protocol::core::Encoding) -> Self { let suffix = val.suffix(); z_encoding_t { - prefix: u8::from(*val.prefix()) as u64, + prefix: (*val.prefix()).into(), suffix: z_bytes_t { start: suffix.as_ptr(), len: suffix.len(), @@ -470,7 +528,7 @@ impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. #[repr(C)] pub struct z_owned_encoding_t { - pub prefix: u64, + pub prefix: z_encoding_prefix_t, pub suffix: z_bytes_t, pub _dropped: bool, } @@ -478,7 +536,7 @@ pub struct z_owned_encoding_t { impl z_owned_encoding_t { pub fn null() -> Self { z_owned_encoding_t { - prefix: 0, + prefix: z_encoding_prefix_t::Empty, suffix: z_bytes_t::default(), _dropped: true, } @@ -506,10 +564,7 @@ pub unsafe extern "C" fn z_encoding( len: libc::strlen(suffix), } }; - z_encoding_t { - prefix: prefix as u64, - suffix, - } + z_encoding_t { prefix, suffix } } /// Constructs a default :c:type:`z_encoding_t`. @@ -562,13 +617,30 @@ pub struct z_owned_str_t { pub _cstr: *mut libc::c_char, } +impl z_owned_str_t { + #[allow(clippy::missing_safety_doc)] + pub unsafe fn preallocate(len: usize) -> z_owned_str_t { + let cstr = libc::malloc(len + 1) as *mut libc::c_char; + *cstr.add(len) = 0; + z_owned_str_t { _cstr: cstr } + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { + std::ptr::copy_nonoverlapping( + value.as_ptr(), + (self._cstr as *mut u8).add(start), + value.len(), + ); + } +} + impl From<&[u8]> for z_owned_str_t { fn from(value: &[u8]) -> Self { unsafe { - let cstr = libc::malloc(value.len() + 1) as *mut libc::c_char; - std::ptr::copy_nonoverlapping(value.as_ptr(), cstr as _, value.len()); - *cstr.add(value.len()) = 0; - z_owned_str_t { _cstr: cstr } + let mut cstr = Self::preallocate(value.len()); + cstr.insert_unchecked(0, value); + cstr } } } diff --git a/src/get.rs b/src/get.rs index bc37d7039..17ed9ccbe 100644 --- a/src/get.rs +++ b/src/get.rs @@ -15,14 +15,14 @@ use libc::c_char; use libc::c_void; use std::{ - borrow::Cow, convert::TryFrom, ffi::CStr, ops::{Deref, DerefMut}, }; +use zenoh::buffers::ZBuf; use zenoh::{ - prelude::{ConsolidationMode, KeyExpr, QueryTarget, SplitBuffer}, + prelude::{ConsolidationMode, KeyExpr, QueryTarget}, query::{Mode, QueryConsolidation, Reply}, sample::AttachmentBuilder, value::Value, @@ -33,10 +33,20 @@ use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, z_attachment_t, }; +use crate::z_encoding_check; +use crate::z_encoding_drop; +use crate::z_encoding_loan; +use crate::z_encoding_null; +use crate::z_owned_encoding_t; +use crate::zc_owned_payload_t; +use crate::zc_payload_check; +use crate::zc_payload_drop; +use crate::zc_payload_loan; +use crate::zc_payload_null; +use crate::zc_payload_t; use crate::{ - impl_guarded_transmute, z_bytes_t, z_closure_reply_call, z_encoding_default, z_encoding_t, - z_keyexpr_t, z_owned_closure_reply_t, z_sample_t, z_session_t, GuardedTransmute, - LOG_INVALID_SESSION, + impl_guarded_transmute, z_closure_reply_call, z_encoding_t, z_keyexpr_t, + z_owned_closure_reply_t, z_sample_t, z_session_t, GuardedTransmute, LOG_INVALID_SESSION, }; type ReplyInner = Option; @@ -59,13 +69,7 @@ pub struct z_owned_reply_t([u64; 19]); impl_guarded_transmute!(noderefs ReplyInner, z_owned_reply_t); impl From for z_owned_reply_t { - fn from(mut val: ReplyInner) -> Self { - if let Some(val) = &mut val { - match &mut val.sample { - Ok(inner) => inner.payload = inner.payload.contiguous().into_owned().into(), - Err(inner) => inner.payload = inner.payload.contiguous().into_owned().into(), - }; - } + fn from(val: ReplyInner) -> Self { val.transmute() } } @@ -101,9 +105,6 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: &z_owned_reply_t) -> bool { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { if let Some(sample) = reply.as_ref().and_then(|s| s.sample.as_ref().ok()) { - if let Cow::Owned(_) = sample.payload.contiguous() { - unreachable!("z_reply_ok found a payload that wasn't contiguous by the time it was reached, which breaks some crate assertions. This is definitely a bug with zenoh, please contact us.") - } z_sample_t::new(sample) } else { panic!("Assertion failed: tried to treat `z_owned_reply_t` as Ok despite that not being the case") @@ -113,14 +114,53 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { /// A zenoh value. /// /// Members: -/// z_bytes_t payload: The payload of this zenoh value. +/// zc_payload_t payload: The payload of this zenoh value. /// z_encoding_t encoding: The encoding of this zenoh value `payload`. #[repr(C)] pub struct z_value_t { - pub payload: z_bytes_t, + pub payload: zc_payload_t, pub encoding: z_encoding_t, } +/// An owned zenoh value. +/// +/// Members: +/// zc_owned_payload_t payload: The payload of this zenoh value. +/// z_owned_encoding_t encoding: The encoding of this zenoh value `payload`. +#[repr(C)] +pub struct z_owned_value_t { + pub payload: zc_owned_payload_t, + pub encoding: z_owned_encoding_t, +} + +#[no_mangle] +pub extern "C" fn z_value_null() -> z_owned_value_t { + z_owned_value_t { + payload: zc_payload_null(), + encoding: z_encoding_null(), + } +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_value_drop(value: &mut z_owned_value_t) { + z_encoding_drop(&mut value.encoding); + zc_payload_drop(&mut value.payload); +} + +#[no_mangle] +pub extern "C" fn z_value_loan(value: &z_owned_value_t) -> z_value_t { + z_value_t { + payload: zc_payload_loan(&value.payload), + encoding: z_encoding_loan(&value.encoding), + } +} + +#[no_mangle] +pub extern "C" fn z_value_check(value: &z_owned_value_t) -> bool { + zc_payload_check(&value.payload) && z_encoding_check(&value.encoding) +} + /// Yields the contents of the reply by asserting it indicates a failure. /// /// You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. @@ -129,10 +169,7 @@ pub struct z_value_t { pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { if let Some(inner) = reply.as_ref().and_then(|s| s.sample.as_ref().err()) { z_value_t { - payload: match &inner.payload.contiguous() { - Cow::Borrowed(payload) => crate::z_bytes_t { start: payload.as_ptr(), len: payload.len() }, - Cow::Owned(_) => unreachable!("z_reply_err found a payload that wasn't contiguous by the time it was reached, which breaks some crate assertions."), - }, + payload: Some(&inner.payload).into(), encoding: (&inner.encoding).into(), } } else { @@ -165,7 +202,7 @@ pub extern "C" fn z_reply_null() -> z_owned_reply_t { pub struct z_get_options_t { pub target: z_query_target_t, pub consolidation: z_query_consolidation_t, - pub value: z_value_t, + pub value: z_owned_value_t, pub attachment: z_attachment_t, pub timeout_ms: u64, } @@ -175,12 +212,7 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { target: QueryTarget::default().into(), consolidation: QueryConsolidation::default().into(), timeout_ms: 0, - value: { - z_value_t { - payload: z_bytes_t::empty(), - encoding: z_encoding_default(), - } - }, + value: z_value_null(), attachment: z_attachment_null(), } } @@ -206,7 +238,7 @@ pub unsafe extern "C" fn z_get( keyexpr: z_keyexpr_t, parameters: *const c_char, callback: &mut z_owned_closure_reply_t, - options: Option<&z_get_options_t>, + options: Option<&mut z_get_options_t>, ) -> i8 { let mut closure = z_owned_closure_reply_t::empty(); std::mem::swap(callback, &mut closure); @@ -223,8 +255,25 @@ pub unsafe extern "C" fn z_get( if let Some(options) = options { q = q .consolidation(options.consolidation) - .target(options.target.into()) - .with_value(&options.value); + .target(options.target.into()); + + if let Some(payload) = options.value.payload.take() { + let mut value = Value::new(payload); + if z_encoding_check(&options.value.encoding) { + value = value.encoding(z_encoding_loan(&options.value.encoding).into()); + } + q = q.with_value(value); + } + z_encoding_drop(&mut options.value.encoding); + if zc_payload_check(&options.value.payload) { + let buf: ZBuf = options.value.payload.as_ref().unwrap().clone(); + let mut value = Value::new(buf); + if z_encoding_check(&options.value.encoding) { + value = value.encoding(z_encoding_loan(&options.value.encoding).into()); + } + q = q.with_value(value); + z_value_drop(&mut options.value); + } if options.timeout_ms != 0 { q = q.timeout(std::time::Duration::from_millis(options.timeout_ms)); } @@ -302,30 +351,29 @@ impl From for QueryTarget { impl From<&z_value_t> for Value { #[inline] fn from(val: &z_value_t) -> Value { - unsafe { - let value: Value = - std::slice::from_raw_parts(val.payload.start, val.payload.len).into(); - let encoding = std::str::from_utf8(std::slice::from_raw_parts( + let payload: Option<&ZBuf> = val.payload.into(); + let payload = match payload { + Some(b) => b.clone(), + None => ZBuf::empty(), + }; + let encoding = unsafe { + std::str::from_utf8(std::slice::from_raw_parts( val.encoding.suffix.start, val.encoding.suffix.len, )) - .expect("encodings must be UTF8"); - value.encoding( - zenoh::prelude::Encoding::new(val.encoding.prefix as u8, encoding).unwrap(), - ) - } + .expect("encodings must be UTF8") + }; + let v = Value::new(payload); + v.encoding(zenoh::prelude::Encoding::new(val.encoding.prefix as u8, encoding).unwrap()) } } impl From<&Value> for z_value_t { #[inline] fn from(val: &Value) -> z_value_t { - let std::borrow::Cow::Borrowed(payload) = val.payload.contiguous() else { - panic!("Would have returned a reference to a temporary, make sure you the Value's payload is contiguous BEFORE calling this constructor.") - }; z_value_t { encoding: (&val.encoding).into(), - payload: payload.into(), + payload: Some(&val.payload).into(), } } } diff --git a/src/lib.rs b/src/lib.rs index 5019a0713..96cc4bd76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,6 +55,8 @@ pub use querying_subscriber::*; pub mod attachment; pub use platform::*; pub mod platform; +pub use opaque_types::*; +pub mod opaque_types; #[cfg(feature = "shared-memory")] mod shm; diff --git a/src/liveliness.rs b/src/liveliness.rs index d66508cd5..b3c61a7de 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -14,7 +14,7 @@ use zenoh::{ liveliness::{Liveliness, LivelinessToken}, - prelude::{SessionDeclarations, SplitBuffer}, + prelude::SessionDeclarations, }; use zenoh_util::core::{zresult::ErrNo, SyncResolve}; @@ -176,10 +176,7 @@ pub extern "C" fn zc_liveliness_declare_subscriber( match session .liveliness() .declare_subscriber(key) - .callback(move |mut sample| { - if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { - sample.payload = v.into(); - } + .callback(move |sample| { let sample = z_sample_t::new(&sample); z_closure_sample_call(&callback, &sample) }) diff --git a/src/opaque_types/mod.rs b/src/opaque_types/mod.rs new file mode 100644 index 000000000..0327b0943 --- /dev/null +++ b/src/opaque_types/mod.rs @@ -0,0 +1,15 @@ +/// A split buffer that owns all of its data. +/// +/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. +#[repr(C, align(8))] +pub struct z_owned_buffer_t { + _0: [u8; 40] +} +/// An owned sample. +/// +/// This is a read only type that can only be constructed by cloning a `z_sample_t`. +/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. +#[repr(C, align(8))] +pub struct zc_owned_sample_t { + _0: [u8; 224] +} diff --git a/src/publisher.rs b/src/publisher.rs index f49d8cd31..6647655bd 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -234,14 +234,17 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t } } -/// Sends a `PUT` message onto the publisher's key expression. +/// Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. +/// +/// This is avoids copies when transfering data that was either: +/// - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher +/// - constructed from a `zc_owned_shmbuf_t` /// /// The payload's encoding can be sepcified through the options. /// /// Parameters: /// session: The zenoh session. /// payload: The value to put. -/// len: The length of the value to put. /// options: The publisher put options. /// Returns: /// ``0`` in case of success, negative values in case of failure. @@ -249,12 +252,15 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_publisher_put( publisher: z_publisher_t, - payload: *const u8, - len: usize, + payload: Option<&mut zc_owned_payload_t>, options: Option<&z_publisher_put_options_t>, ) -> i8 { if let Some(p) = publisher.as_ref() { - let value: Value = std::slice::from_raw_parts(payload, len).into(); + let Some(payload) = payload.and_then(|p| p.take()) else { + log::debug!("Attempted to put without a payload"); + return i8::MIN; + }; + let value: Value = payload.into(); let put = match options { Some(options) => { let mut put = p.put(value.encoding(options.encoding.into())); @@ -282,49 +288,6 @@ pub unsafe extern "C" fn z_publisher_put( } } -/// Sends a `PUT` message onto the publisher's key expression, transfering the buffer ownership. -/// -/// This is avoids copies when transfering data that was either: -/// - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher -/// - constructed from a `zc_owned_shmbuf_t` -/// -/// The payload's encoding can be sepcified through the options. -/// -/// Parameters: -/// session: The zenoh session. -/// payload: The value to put. -/// len: The length of the value to put. -/// options: The publisher put options. -/// Returns: -/// ``0`` in case of success, negative values in case of failure. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_publisher_put_owned( - publisher: z_publisher_t, - payload: Option<&mut zc_owned_payload_t>, - options: Option<&z_publisher_put_options_t>, -) -> i8 { - if let Some(p) = publisher.as_ref() { - let Some(payload) = payload.and_then(|p| p.take()) else { - log::debug!("Attempted to put without a payload"); - return i8::MIN; - }; - let value: Value = payload.into(); - let put = match options { - Some(options) => p.put(value.encoding(options.encoding.into())), - None => p.put(value), - }; - if let Err(e) = put.res_sync() { - log::error!("{}", e); - e.errno().get() - } else { - 0 - } - } else { - i8::MIN - } -} - /// Represents the set of options that can be applied to the delete operation by a previously declared publisher, /// whenever issued via :c:func:`z_publisher_delete`. #[repr(C)] diff --git a/src/pull_subscriber.rs b/src/pull_subscriber.rs index 247484cb1..ebef7064b 100644 --- a/src/pull_subscriber.rs +++ b/src/pull_subscriber.rs @@ -22,7 +22,6 @@ use crate::z_reliability_t; use crate::LOG_INVALID_SESSION; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; -use zenoh::prelude::SplitBuffer; use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; @@ -149,10 +148,7 @@ pub extern "C" fn z_declare_pull_subscriber( Some(s) => { let mut res = s .declare_subscriber(keyexpr) - .callback(move |mut sample| { - if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { - sample.payload = v.into(); - } + .callback(move |sample| { let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }) diff --git a/src/put.rs b/src/put.rs index b5d9f2f94..5c8b8d807 100644 --- a/src/put.rs +++ b/src/put.rs @@ -16,7 +16,6 @@ use crate::keyexpr::*; use crate::session::*; use crate::LOG_INVALID_SESSION; use libc::c_void; -use libc::size_t; use zenoh::prelude::{sync::SyncResolve, Priority, SampleKind}; use zenoh::publication::CongestionControl; use zenoh::sample::AttachmentBuilder; @@ -135,62 +134,6 @@ pub extern "C" fn z_put_options_default() -> z_put_options_t { } } -/// Put data. -/// -/// The payload's encoding can be sepcified through the options. -/// -/// Parameters: -/// session: The zenoh session. -/// keyexpr: The key expression to put. -/// payload: The value to put. -/// len: The length of the value to put. -/// options: The put options. -/// Returns: -/// ``0`` in case of success, negative values in case of failure. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_put( - session: z_session_t, - keyexpr: z_keyexpr_t, - payload: *const u8, - len: size_t, - opts: Option<&z_put_options_t>, -) -> i8 { - match session.upgrade() { - Some(s) => { - let mut res = s - .put(keyexpr, std::slice::from_raw_parts(payload, len)) - .kind(SampleKind::Put); - if let Some(opts) = opts { - res = res - .encoding(opts.encoding) - .congestion_control(opts.congestion_control.into()) - .priority(opts.priority.into()); - if z_attachment_check(&opts.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - opts.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - res = res.with_attachment(attachment_builder.build()); - }; - } - match res.res_sync() { - Err(e) => { - log::error!("{}", e); - e.errno().get() - } - Ok(()) => 0, - } - } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - i8::MIN - } - } -} - /// Put data, transfering the buffer ownership. /// /// This is avoids copies when transfering data that was either: @@ -208,7 +151,7 @@ pub unsafe extern "C" fn z_put( /// ``0`` in case of success, negative values in case of failure. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn zc_put_owned( +pub extern "C" fn z_put( session: z_session_t, keyexpr: z_keyexpr_t, payload: Option<&mut zc_owned_payload_t>, @@ -223,6 +166,15 @@ pub extern "C" fn zc_put_owned( .encoding(opts.encoding) .congestion_control(opts.congestion_control.into()) .priority(opts.priority.into()); + if z_attachment_check(&opts.attachment) { + let mut attachment_builder = AttachmentBuilder::new(); + z_attachment_iterate( + opts.attachment, + insert_in_attachment_builder, + &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, + ); + res = res.with_attachment(attachment_builder.build()); + }; } match res.res_sync() { Err(e) => { diff --git a/src/queryable.rs b/src/queryable.rs index 1906dc735..f5b647473 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -16,17 +16,17 @@ use crate::attachment::{ z_attachment_iterate, z_attachment_null, z_attachment_t, }; use crate::{ - impl_guarded_transmute, z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, - z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, LOG_INVALID_SESSION, + impl_guarded_transmute, z_buffer_t, z_bytes_t, z_closure_query_call, z_encoding_default, + z_encoding_t, z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, + LOG_INVALID_SESSION, }; use libc::c_void; use std::ops::{Deref, DerefMut}; use zenoh::prelude::SessionDeclarations; use zenoh::{ - prelude::{Sample, SplitBuffer}, + prelude::Sample, queryable::{Query, Queryable as CallbackQueryable}, sample::AttachmentBuilder, - value::Value, }; use zenoh_util::core::{zresult::ErrNo, SyncResolve}; @@ -346,14 +346,15 @@ pub extern "C" fn z_query_parameters(query: &z_query_t) -> z_bytes_t { #[no_mangle] pub unsafe extern "C" fn z_query_value(query: &z_query_t) -> z_value_t { match query.as_ref().and_then(|q| q.value()) { - Some(value) => { + Some(value) => + { #[allow(mutable_transmutes)] - if let std::borrow::Cow::Owned(payload) = value.payload.contiguous() { - unsafe { std::mem::transmute::<_, &mut Value>(value).payload = payload.into() } - } value.into() } - None => (&Value::empty()).into(), + None => z_value_t { + payload: z_buffer_t::default(), + encoding: z_encoding_default(), + }, } } diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index a4681b4e9..910f1b89b 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -15,7 +15,6 @@ use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; use zenoh::prelude::SessionDeclarations; -use zenoh::prelude::SplitBuffer; use zenoh_ext::*; use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; @@ -185,10 +184,7 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( } } match sub - .callback(move |mut sample| { - if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { - sample.payload = v.into(); - } + .callback(move |sample| { let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }) diff --git a/src/subscriber.rs b/src/subscriber.rs index 7d15e740a..d82086f7f 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -21,7 +21,6 @@ use crate::z_owned_closure_sample_t; use crate::LOG_INVALID_SESSION; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; -use zenoh::prelude::SplitBuffer; use zenoh::subscriber::Reliability; use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; @@ -179,10 +178,7 @@ pub extern "C" fn z_declare_subscriber( match session.upgrade() { Some(s) => { - let mut res = s.declare_subscriber(keyexpr).callback(move |mut sample| { - if let std::borrow::Cow::Owned(v) = sample.payload.contiguous() { - sample.payload = v.into(); - } + let mut res = s.declare_subscriber(keyexpr).callback(move |sample| { let sample = z_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }); diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 9ade440f3..49827e148 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -260,7 +260,8 @@ int main(int argc, char **argv) { z_encoding_t _ret_encoding = z_encoding_default(); _ret_encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); _ret_put_opt.encoding = _ret_encoding; - _ret_int8 = z_put(z_loan(s1), z_loan(_ret_expr), (const uint8_t *)value, strlen(value), &_ret_put_opt); + zc_owned_payload_t payload = zc_payload_encode_from_string(value); + _ret_int8 = z_put(z_loan(s1), z_loan(_ret_expr), z_move(payload), &_ret_put_opt); assert(_ret_int8 == 0); z_sleep_s(SLEEP); @@ -292,7 +293,8 @@ int main(int argc, char **argv) { assert(z_check(_ret_pub)); z_publisher_put_options_t _ret_pput_opt = z_publisher_put_options_default(); - _ret_int8 = z_publisher_put(z_loan(_ret_pub), (const uint8_t *)value, strlen(value), &_ret_pput_opt); + payload = zc_payload_encode_from_string(value); + _ret_int8 = z_publisher_put(z_loan(_ret_pub), z_move(payload), &_ret_pput_opt); assert(_ret_int8 == 0); z_sleep_s(SLEEP); diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index 868b3878e..789a00ffc 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -61,7 +61,8 @@ int run_publisher() { // values for cache for (int i = 0; i < values_count / 2; ++i) { - z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)values[i], strlen(values[i]), NULL); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } SEM_POST(sem_pub); @@ -70,7 +71,8 @@ int run_publisher() { // values for subscribe for (int i = values_count / 2; i < values_count; ++i) { - z_put(z_loan(s), z_keyexpr(keyexpr), (const uint8_t *)values[i], strlen(values[i]), NULL); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } printf("wait: sem_sub\n"); @@ -91,8 +93,13 @@ void data_handler(const z_sample_t *sample, void *arg) { exit(-1); } z_drop(z_move(keystr)); - - ASSERT_STR_BYTES_EQUAL(values[val_num], z_sample_payload(sample)); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + if (strcmp(values[val_num], z_loan(payload))) { + perror("Unexpected value received"); + z_drop(z_move(payload)); + exit(-1); + } + z_drop(z_move(payload)); printf("data_handler: %i\n", val_num); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index bafdd87ca..a665ad19b 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -55,7 +55,8 @@ int run_publisher() { options.attachment = z_bytes_map_as_attachment(&map); for (int i = 0; i < values_count; ++i) { z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_VAR), z_bytes_from_str(values[i])); - z_publisher_put(z_loan(pub), (const uint8_t *)values[i], strlen(values[i]), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); @@ -73,11 +74,13 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(keystr)); - z_bytes_t payload = z_sample_payload(sample); - if (strncmp(values[val_num], (const char *)payload.start, (int)payload.len)) { + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + if (strcmp(values[val_num], z_loan(payload))) { perror("Unexpected value received"); + z_drop(z_move(payload)); exit(-1); } + z_drop(z_move(payload)); z_bytes_t v_const = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index 6e48fef5a..06d5c87ba 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -49,7 +49,8 @@ int run_publisher() { for (int i = 0; i < values_count; ++i) { z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_publisher_put(z_loan(pub), (const uint8_t *)values[i], strlen(values[i]), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_publisher_put(z_loan(pub), z_move(payload), &options); } z_undeclare_publisher(z_move(pub)); @@ -66,11 +67,13 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(keystr)); - z_bytes_t payload = z_sample_payload(sample); - if (strncmp(values[val_num], (const char *)payload.start, (int)payload.len)) { + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + if (strcmp(values[val_num], z_loan(payload))) { perror("Unexpected value received"); + z_drop(z_move(payload)); exit(-1); } + z_drop(z_move(payload)); if (z_qos_get_congestion_control(z_sample_qos(sample)) != Z_CONGESTION_CONTROL_BLOCK || z_qos_get_priority(z_sample_qos(sample)) != Z_PRIORITY_DATA) { diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 1de9de788..deb28658e 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -110,13 +110,18 @@ int run_get() { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - - ASSERT_STR_BYTES_EQUAL(values[val_num], z_sample_payload(&sample)); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); + if (strcmp(values[val_num], z_loan(payload))) { + perror("Unexpected value received"); + z_drop(z_move(payload)); + exit(-1); + } z_bytes_t v_const = z_attachment_get(z_sample_attachment(&sample), z_bytes_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); z_drop(z_move(keystr)); + z_drop(z_move(payload)); } z_drop(z_move(reply)); z_drop(z_move(channel)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index 9bcc16cc1..dc587e292 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -86,10 +86,15 @@ int run_get() { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - - ASSERT_STR_BYTES_EQUAL(values[val_num], z_sample_payload(&sample)); + z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); + if (strcmp(values[val_num], z_loan(payload))) { + perror("Unexpected value received"); + z_drop(z_move(payload)); + exit(-1); + } z_drop(z_move(keystr)); + z_drop(z_move(payload)); } z_drop(z_move(reply)); z_drop(z_move(channel)); From ed3a164b56b0e55fc17d0826c3aa12bdaf89450e Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Wed, 3 Apr 2024 22:49:47 +0200 Subject: [PATCH 17/75] reply with owned payload --- examples/z_queryable.c | 3 +- examples/z_queryable_with_channels.c | 3 +- include/zenoh_commons.h | 4 +-- src/queryable.rs | 48 ++++++++++++------------- tests/z_api_alignment_test.c | 3 +- tests/z_int_queryable_attachment_test.c | 4 +-- tests/z_int_queryable_test.c | 4 +-- 7 files changed, 33 insertions(+), 36 deletions(-) diff --git a/examples/z_queryable.c b/examples/z_queryable.c index 25d8a959d..5c4ef6dfb 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -33,7 +33,8 @@ void query_handler(const z_query_t *query, void *context) { } z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_query_reply(query, z_keyexpr((const char *)context), (const unsigned char *)value, strlen(value), &options); + zc_owned_payload_t reply_payload = zc_payload_encode_from_string(value); + z_query_reply(query, z_keyexpr((const char *)context), z_move(reply_payload), &options); z_drop(z_move(keystr)); } diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index dfef42532..e68577d2e 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -79,7 +79,8 @@ int main(int argc, char **argv) { } z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_query_reply(&query, keyexpr, (const unsigned char *)value, strlen(value), &options); + zc_owned_payload_t reply_payload = zc_payload_encode_from_string(value); + z_query_reply(&query, keyexpr, z_move(reply_payload), &options); z_drop(z_move(keystr)); z_drop(z_move(oquery)); } diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 26c428c29..a24a9c0b4 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1994,14 +1994,12 @@ struct z_bytes_t z_query_parameters(const struct z_query_t *query); * query: The query to reply to. * key: The key of this reply. * payload: The value of this reply. - * len: The length of the value of this reply. * options: The options of this reply. */ ZENOHC_API int8_t z_query_reply(const struct z_query_t *query, struct z_keyexpr_t key, - const uint8_t *payload, - size_t len, + zc_owned_payload_t *payload, const struct z_query_reply_options_t *options); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. diff --git a/src/queryable.rs b/src/queryable.rs index f5b647473..c55820227 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -17,7 +17,7 @@ use crate::attachment::{ }; use crate::{ impl_guarded_transmute, z_buffer_t, z_bytes_t, z_closure_query_call, z_encoding_default, - z_encoding_t, z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, + z_encoding_t, z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, LOG_INVALID_SESSION, }; use libc::c_void; @@ -273,15 +273,13 @@ pub extern "C" fn z_queryable_check(qable: &z_owned_queryable_t) -> bool { /// query: The query to reply to. /// key: The key of this reply. /// payload: The value of this reply. -/// len: The length of the value of this reply. /// options: The options of this reply. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_query_reply( query: &z_query_t, key: z_keyexpr_t, - payload: *const u8, - len: usize, + payload: Option<&mut zc_owned_payload_t>, options: Option<&z_query_reply_options_t>, ) -> i8 { let Some(query) = query.as_ref() else { @@ -289,30 +287,28 @@ pub unsafe extern "C" fn z_query_reply( return i8::MIN; }; if let Some(key) = &*key { - let mut s = Sample::new( - key.clone().into_owned(), - std::slice::from_raw_parts(payload, len), - ); - if let Some(o) = options { - s.encoding = o.encoding.into(); - if z_attachment_check(&o.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - o.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - s = s.with_attachment(attachment_builder.build()); - }; + if let Some(payload) = payload.and_then(|p| p.take()) { + let mut s = Sample::new(key.clone().into_owned(), payload); + if let Some(o) = options { + s.encoding = o.encoding.into(); + if z_attachment_check(&o.attachment) { + let mut attachment_builder = AttachmentBuilder::new(); + z_attachment_iterate( + o.attachment, + insert_in_attachment_builder, + &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, + ); + s = s.with_attachment(attachment_builder.build()); + }; + } + if let Err(e) = query.reply(Ok(s)).res_sync() { + log::error!("{}", e); + return e.errno().get(); + } + return 0; } - if let Err(e) = query.reply(Ok(s)).res_sync() { - log::error!("{}", e); - return e.errno().get(); - } - 0 - } else { - i8::MIN } + i8::MIN } /// Get a query's key by aliasing it. diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 49827e148..e7b72ef96 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -56,7 +56,8 @@ void query_handler(const z_query_t *query, void *arg) { z_value_t payload_value = z_query_value(query); (void)(payload_value); z_query_reply_options_t _ret_qreply_opt = z_query_reply_options_default(); - z_query_reply(query, z_keyexpr(z_loan(k_str)), (const uint8_t *)value, strlen(value), &_ret_qreply_opt); + zc_owned_payload_t payload = zc_payload_encode_from_string(value); + z_query_reply(query, z_keyexpr(z_loan(k_str)), z_move(payload), &_ret_qreply_opt); z_drop(z_move(k_str)); } diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index deb28658e..26645ad29 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -50,8 +50,8 @@ void query_handler(const z_query_t *query, void *context) { z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); options.attachment = z_bytes_map_as_attachment(&map); - z_query_reply(query, z_keyexpr((const char *)context), (const uint8_t *)values[value_num], - strlen(values[value_num]), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[value_num]); + z_query_reply(query, z_keyexpr((const char *)context), z_move(payload), &options); z_drop(z_move(keystr)); z_drop(z_move(map)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index dc587e292..7cc7f3bfc 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -34,8 +34,8 @@ void query_handler(const z_query_t *query, void *context) { z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_query_reply(query, z_keyexpr((const char *)context), (const uint8_t *)values[value_num], - strlen(values[value_num]), &options); + zc_owned_payload_t payload = zc_payload_encode_from_string(values[value_num]); + z_query_reply(query, z_keyexpr((const char *)context), z_move(payload), &options); z_drop(z_move(keystr)); if (++value_num == values_count) { From cb8dacfa05aa5bae9eff5bb94e045e94b7cd8014 Mon Sep 17 00:00:00 2001 From: yellowhatter Date: Thu, 4 Apr 2024 19:02:25 +0300 Subject: [PATCH 18/75] add separate threadsafe context data type --- include/zenoh_commons.h | 5 ++++- src/context.rs | 16 +++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index f3c22880d..e0058f9e2 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -240,6 +240,9 @@ typedef struct ALIGN(8) z_alloc_layout_threadsafe_t { uint64_t _0[14]; } z_alloc_layout_threadsafe_t; #endif +typedef struct zc_threadsafe_context_data_t { + void *ptr; +} zc_threadsafe_context_data_t; /** * A tread-safe droppable context. * Contexts are idiomatically used in C together with callback interfaces to deliver associated state @@ -255,7 +258,7 @@ typedef struct ALIGN(8) z_alloc_layout_threadsafe_t { * be executed. */ typedef struct zc_threadsafe_context_t { - void *context; + struct zc_threadsafe_context_data_t context; void (*delete_fn)(void*); } zc_threadsafe_context_t; /** diff --git a/src/context.rs b/src/context.rs index cb30a2eac..6bc5cd96f 100644 --- a/src/context.rs +++ b/src/context.rs @@ -82,10 +82,18 @@ impl Drop for Context { #[derive(Debug)] #[repr(C)] pub struct zc_threadsafe_context_t { - context: *mut c_void, + context: zc_threadsafe_context_data_t, delete_fn: unsafe extern "C" fn(*mut c_void), } +#[derive(Debug)] +#[repr(C)] +pub struct zc_threadsafe_context_data_t { + ptr: *mut c_void, +} +unsafe impl Send for zc_threadsafe_context_data_t {} +unsafe impl Sync for zc_threadsafe_context_data_t {} + decl_rust_copy_type!( zenoh:(ThreadsafeContext), c:(zc_threadsafe_context_t) @@ -95,15 +103,13 @@ decl_rust_copy_type!( pub struct ThreadsafeContext(zc_threadsafe_context_t); impl DroppableContext for ThreadsafeContext { fn get(&self) -> *mut c_void { - self.0.context + self.0.context.ptr } } impl Drop for ThreadsafeContext { fn drop(&mut self) { unsafe { - (self.0.delete_fn)(self.0.context); + (self.0.delete_fn)(self.0.context.ptr); } } } -unsafe impl Send for ThreadsafeContext {} -unsafe impl Sync for ThreadsafeContext {} From 6d005bb1e86eebc48a2f5eab187c448345d103eb Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 4 Apr 2024 23:38:42 +0200 Subject: [PATCH 19/75] modified payload decoding functions to return error and take value by pointer --- examples/z_get.c | 9 ++- examples/z_non_blocking_get.c | 7 +- examples/z_pull.c | 7 +- examples/z_query_sub.c | 7 +- examples/z_queryable.c | 8 +- examples/z_queryable_with_channels.c | 7 +- examples/z_sub.c | 7 +- examples/z_sub_attachment.c | 10 ++- include/zenoh_commons.h | 52 +++++++------ include/zenoh_macros.h | 4 +- src/attachment.rs | 10 +-- src/collections.rs | 99 ++++++++++++++++++++++--- src/commons.rs | 40 ++++++++-- src/get.rs | 70 ++--------------- tests/z_int_pub_cache_query_sub_test.c | 9 ++- tests/z_int_pub_sub_attachment_test.c | 9 ++- tests/z_int_pub_sub_test.c | 9 ++- tests/z_int_queryable_attachment_test.c | 9 ++- tests/z_int_queryable_test.c | 9 ++- 19 files changed, 223 insertions(+), 159 deletions(-) diff --git a/examples/z_get.c b/examples/z_get.c index e5a1de104..9866212f7 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -57,18 +57,19 @@ int main(int argc, char **argv) { z_owned_reply_channel_t channel = zc_reply_fifo_new(16); z_get_options_t opts = z_get_options_default(); if (value != NULL) { - opts.value.payload = zc_payload_encode_from_string(value); + opts.payload = zc_payload_encode_from_string(value); } z_get(z_loan(s), keyexpr, "", z_move(channel.send), z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate z_owned_reply_t reply = z_reply_null(); + z_owned_str_t payload_value = z_str_null(); for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); - printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload)); - z_drop(z_move(payload)); + zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index 21437199c..471f7e227 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -51,6 +51,7 @@ int main(int argc, char **argv) { z_get(z_loan(s), keyexpr, "", z_move(channel.send), z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate z_owned_reply_t reply = z_reply_null(); + z_owned_str_t payload_value = z_str_null(); for (bool call_success = z_call(channel.recv, &reply); !call_success || z_check(reply); call_success = z_call(channel.recv, &reply)) { if (!call_success) { @@ -59,9 +60,9 @@ int main(int argc, char **argv) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); - printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload)); - z_drop(z_move(payload)); + zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } else { printf("Received an error\n"); diff --git a/examples/z_pull.c b/examples/z_pull.c index c7daf1172..094dc0a6b 100644 --- a/examples/z_pull.c +++ b/examples/z_pull.c @@ -18,10 +18,11 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - z_loan(payload)); - z_drop(z_move(payload)); + z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index a5b2ec1f9..620dd9594 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -18,10 +18,11 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - z_loan(payload)); - z_drop(z_move(payload)); + z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } diff --git a/examples/z_queryable.c b/examples/z_queryable.c index 5c4ef6dfb..577ef146e 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -24,15 +24,17 @@ void query_handler(const z_query_t *query, void *context) { z_bytes_t pred = z_query_parameters(query); zc_payload_t payload = z_query_value(query).payload; if (zc_payload_len(payload) > 0) { - z_owned_str_t payload_string = zc_payload_decode_into_string(payload); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(payload, &payload_value); printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, - pred.start, z_loan(payload_string)); - z_drop(z_move(payload_string)); + pred.start, z_loan(payload_value)); + z_drop(z_move(payload_value)); } else { printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); } z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); + zc_owned_payload_t reply_payload = zc_payload_encode_from_string(value); z_query_reply(query, z_keyexpr((const char *)context), z_move(reply_payload), &options); z_drop(z_move(keystr)); diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index e68577d2e..6c3ca0df1 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -70,10 +70,11 @@ int main(int argc, char **argv) { z_bytes_t pred = z_query_parameters(&query); zc_payload_t payload = z_query_value(&query).payload; if (zc_payload_len(payload) > 0) { - z_owned_str_t payload_string = zc_payload_decode_into_string(payload); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(payload, &payload_value); printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, - pred.start, z_loan(payload_string)); - z_drop(z_move(payload_string)); + pred.start, z_loan(payload_value)); + z_drop(z_move(payload_value)); } else { printf(">> [Queryable ] Received Query '%s?%.*s'\n", z_loan(keystr), (int)pred.len, pred.start); } diff --git a/examples/z_sub.c b/examples/z_sub.c index c7ea05c9a..ffa63703b 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -18,10 +18,11 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - z_loan(payload)); - z_drop(z_move(payload)); + z_loan(payload_value)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index b3be1f672..b703e6ad6 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -24,8 +24,10 @@ int8_t attachment_reader(z_bytes_t key, z_bytes_t val, void *ctx) { void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); - printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload)); + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), + z_loan(payload_value)); z_attachment_t attachment = z_sample_attachment(sample); // checks if attachment exists @@ -35,11 +37,11 @@ void data_handler(const z_sample_t *sample, void *arg) { // reads particular attachment item z_bytes_t index = z_attachment_get(attachment, z_bytes_from_str("index")); - if (z_check(index)) { + if (z_bytes_is_initialized(&index)) { printf(" message number: %.*s\n", (int)index.len, index.start); } } - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); z_drop(z_move(keystr)); } diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index a24a9c0b4..fe2b58959 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -219,6 +219,10 @@ typedef struct ALIGN(8) z_owned_buffer_t { typedef struct z_buffer_t { struct z_owned_buffer_t *_inner; } z_buffer_t; +typedef struct z_owned_bytes_t { + uint8_t *start; + size_t len; +} z_owned_bytes_t; /** * A map of maybe-owned vector of bytes to owned vector of bytes. * @@ -631,7 +635,7 @@ typedef struct z_encoding_t { */ typedef struct z_owned_encoding_t { enum z_encoding_prefix_t prefix; - struct z_bytes_t suffix; + struct z_owned_bytes_t suffix; bool _dropped; } z_owned_encoding_t; /** @@ -646,17 +650,6 @@ typedef struct z_query_consolidation_t { * The `payload` field may be modified, and Zenoh will take the new values into account. */ typedef struct z_owned_buffer_t zc_owned_payload_t; -/** - * An owned zenoh value. - * - * Members: - * zc_owned_payload_t payload: The payload of this zenoh value. - * z_owned_encoding_t encoding: The encoding of this zenoh value `payload`. - */ -typedef struct z_owned_value_t { - zc_owned_payload_t payload; - struct z_owned_encoding_t encoding; -} z_owned_value_t; /** * Options passed to the :c:func:`z_get` function. * @@ -670,7 +663,8 @@ typedef struct z_owned_value_t { typedef struct z_get_options_t { enum z_query_target_t target; struct z_query_consolidation_t consolidation; - struct z_owned_value_t value; + zc_owned_payload_t payload; + struct z_encoding_t encoding; struct z_attachment_t attachment; uint64_t timeout_ms; } z_get_options_t; @@ -1102,7 +1096,7 @@ ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); /** * Returns the `index`th slice of the buffer, aliasing it. * - * Out of bounds accesses will return `z_bytes_null`. + * Out of bounds accesses will return `z_bytes_empty`. */ ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); /** @@ -1114,13 +1108,23 @@ ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. */ -ZENOHC_API bool z_bytes_check(const struct z_bytes_t *b); +ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *b); +ZENOHC_API struct z_owned_bytes_t z_bytes_clone(const struct z_bytes_t *b); +/** + * Returns the gravestone value for `z_bytes_t` + */ +ZENOHC_API struct z_bytes_t z_bytes_empty(void); /** * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). * - * `str == NULL` will cause this to return `z_bytes_null()` + * `str == NULL` will cause this to return `z_bytes_empty()` */ ZENOHC_API struct z_bytes_t z_bytes_from_str(const char *str); +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_bytes_is_initialized(const struct z_bytes_t *b); +ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *b); /** * Aliases `this` into a generic `z_attachment_t`, allowing it to be passed to corresponding APIs. */ @@ -1211,14 +1215,14 @@ ZENOHC_API struct z_owned_bytes_map_t z_bytes_map_null(void); /** * Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). * - * `str == NULL` will cause this to return `z_bytes_null()` + * `str == NULL` will cause this to return `z_bytes_empty()` */ ZENOHC_API struct z_bytes_t z_bytes_new(const char *str); /** - * Returns the gravestone value for `z_bytes_t` + * Returns the gravestone value for `z_owned_bytes_t` */ -ZENOHC_API struct z_bytes_t z_bytes_null(void); +ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); /** * Constructs a `len` bytes long view starting at `start`. */ @@ -2270,10 +2274,6 @@ ZENOHC_API int8_t z_undeclare_queryable(struct z_owned_queryable_t *qable); */ ZENOHC_API int8_t z_undeclare_subscriber(struct z_owned_subscriber_t *sub); -ZENOHC_API bool z_value_check(const struct z_owned_value_t *value); -ZENOHC_API void z_value_drop(struct z_owned_value_t *value); -ZENOHC_API struct z_value_t z_value_loan(const struct z_owned_value_t *value); -ZENOHC_API struct z_owned_value_t z_value_null(void); /** * Converts the kind of zenoh entity into a string. * @@ -2467,7 +2467,11 @@ ZENOHC_API zc_owned_payload_t zc_payload_clone(zc_payload_t payload); /** * Decodes payload into null-terminated string */ -ZENOHC_API struct z_owned_str_t zc_payload_decode_into_string(zc_payload_t payload); +ZENOHC_API int8_t zc_payload_decode_into_bytes(zc_payload_t payload, struct z_owned_bytes_t *b); +/** + * Decodes payload into null-terminated string + */ +ZENOHC_API int8_t zc_payload_decode_into_string(zc_payload_t payload, struct z_owned_str_t *cstr); /** * Decrements `payload`'s backing refcount, releasing the memory if appropriate. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index dba68f29a..bb50476a5 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -89,7 +89,7 @@ z_keyexpr_t : z_keyexpr_is_initialized, \ z_owned_config_t : z_config_check, \ z_owned_scouting_config_t : z_scouting_config_check, \ - z_bytes_t : z_bytes_check, \ + z_owned_bytes_t : z_bytes_check, \ z_owned_subscriber_t : z_subscriber_check, \ z_owned_pull_subscriber_t : z_pull_subscriber_check, \ z_owned_queryable_t : z_queryable_check, \ @@ -257,7 +257,7 @@ inline bool z_check(const z_owned_keyexpr_t& v) { return z_keyexpr_check(&v); } inline bool z_check(const z_keyexpr_t& v) { return z_keyexpr_is_initialized(&v); } inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } -inline bool z_check(const z_bytes_t& v) { return z_bytes_check(&v); } +inline bool z_check(const z_owned_bytes_t& v) { return z_bytes_check(&v); } inline bool z_check(const zc_owned_payload_t& v) { return zc_payload_check(&v); } inline bool z_check(const zc_owned_shmbuf_t& v) { return zc_shmbuf_check(&v); } inline bool z_check(const zc_owned_shm_manager_t& v) { return zc_shm_manager_check(&v); } diff --git a/src/attachment.rs b/src/attachment.rs index 7b456a9c1..045596c47 100644 --- a/src/attachment.rs +++ b/src/attachment.rs @@ -2,7 +2,7 @@ use std::{borrow::Cow, cell::UnsafeCell, collections::HashMap}; use libc::c_void; -use crate::{impl_guarded_transmute, z_bytes_null, z_bytes_t}; +use crate::{impl_guarded_transmute, z_bytes_empty, z_bytes_t}; use zenoh::sample::{Attachment, AttachmentBuilder}; @@ -101,7 +101,7 @@ pub extern "C" fn z_attachment_get(this: z_attachment_t, key: z_bytes_t) -> z_by let mut context = attachment_get_iterator_context { key, - value: z_bytes_null(), + value: z_bytes_empty(), }; if this.iteration_driver.map_or(false, |iteration_driver| { @@ -113,7 +113,7 @@ pub extern "C" fn z_attachment_get(this: z_attachment_t, key: z_bytes_t) -> z_by }) { context.value } else { - z_bytes_null() + z_bytes_empty() } } @@ -237,12 +237,12 @@ pub extern "C" fn z_bytes_map_is_empty(this: &mut z_owned_bytes_map_t) -> bool { pub extern "C" fn z_bytes_map_get(this: &z_owned_bytes_map_t, key: z_bytes_t) -> z_bytes_t { let this = unsafe { &*this.get() }; let (Some(this), Some(key)) = (this.as_ref(), key.as_slice()) else { - return z_bytes_null(); + return z_bytes_empty(); }; if let Some(value) = this.get(key) { value.as_ref().into() } else { - z_bytes_null() + z_bytes_empty() } } diff --git a/src/collections.rs b/src/collections.rs index e0f2e7afe..2990f1a3a 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -54,15 +54,58 @@ impl Default for z_bytes_t { } } +#[repr(C)] +#[derive(Clone, Debug)] +pub struct z_owned_bytes_t { + pub start: *mut u8, + pub len: size_t, +} + +impl Drop for z_owned_bytes_t { + fn drop(&mut self) { + unsafe { z_bytes_drop(self) } + } +} + +impl z_owned_bytes_t { + pub fn new(data: &[u8]) ->z_owned_bytes_t { + if data.len() == 0 { + return z_bytes_null(); + } + let data = data.to_vec().into_boxed_slice(); + z_owned_bytes_t { + len: data.len(), + start: Box::leak(data).as_mut_ptr(), + } + } + + pub fn preallocate(len: usize) -> z_owned_bytes_t { + let data = vec![0u8; len].into_boxed_slice(); + z_owned_bytes_t { + len, + start: Box::leak(data).as_mut_ptr(), + } + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { + std::ptr::copy_nonoverlapping( + value.as_ptr(), + (self.start as *mut u8).add(start), + value.len(), + ); + } +} + /// Returns ``true`` if `b` is initialized. #[no_mangle] -pub extern "C" fn z_bytes_check(b: &z_bytes_t) -> bool { +pub extern "C" fn z_bytes_is_initialized(b: &z_bytes_t) -> bool { !b.start.is_null() } /// Returns the gravestone value for `z_bytes_t` #[no_mangle] -pub const extern "C" fn z_bytes_null() -> z_bytes_t { +pub const extern "C" fn z_bytes_empty() -> z_bytes_t { z_bytes_t { len: 0, start: core::ptr::null(), @@ -71,12 +114,12 @@ pub const extern "C" fn z_bytes_null() -> z_bytes_t { /// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// `str == NULL` will cause this to return `z_bytes_null()` +/// `str == NULL` will cause this to return `z_bytes_empty()` #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_from_str(str: *const c_char) -> z_bytes_t { if str.is_null() { - z_bytes_null() + z_bytes_empty() } else { let len = unsafe { libc::strlen(str) }; z_bytes_t { @@ -89,7 +132,7 @@ pub unsafe extern "C" fn z_bytes_from_str(str: *const c_char) -> z_bytes_t { #[deprecated = "Renamed to z_bytes_from_str"] /// Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// `str == NULL` will cause this to return `z_bytes_null()` +/// `str == NULL` will cause this to return `z_bytes_empty()` #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_new(str: *const c_char) -> z_bytes_t { @@ -101,7 +144,7 @@ pub unsafe extern "C" fn z_bytes_new(str: *const c_char) -> z_bytes_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_wrap(start: *const u8, len: usize) -> z_bytes_t { if start.is_null() { - z_bytes_null() + z_bytes_empty() } else { z_bytes_t { len, start } } @@ -109,15 +152,49 @@ pub unsafe extern "C" fn z_bytes_wrap(start: *const u8, len: usize) -> z_bytes_t /// Frees `b` and invalidates it for double-drop safety. #[allow(clippy::missing_safety_doc)] -pub(crate) unsafe fn z_bytes_drop(b: &mut z_bytes_t) { +pub unsafe extern "C" fn z_bytes_drop(b: &mut z_owned_bytes_t) { if !b.start.is_null() { std::mem::drop(Box::from_raw( core::ptr::slice_from_raw_parts(b.start, b.len).cast_mut(), )); - b.start = std::ptr::null(); + b.start = std::ptr::null_mut(); + b.len = 0; } } +/// Returns the gravestone value for `z_owned_bytes_t` +#[no_mangle] +pub const extern "C" fn z_bytes_null() -> z_owned_bytes_t { + z_owned_bytes_t { + len: 0, + start: core::ptr::null_mut(), + } +} + +#[no_mangle] +pub const extern "C" fn z_bytes_loan(b: &z_owned_bytes_t) -> z_bytes_t { + z_bytes_t { + len: b.len, + start: b.start, + } +} + +#[no_mangle] +pub extern "C" fn z_bytes_clone(b: &z_bytes_t) -> z_owned_bytes_t { + if !z_bytes_is_initialized(b) { + return z_bytes_null(); + } else { + return z_owned_bytes_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) } ) + } +} + +/// Returns ``true`` if `b` is initialized. +#[no_mangle] +pub extern "C" fn z_bytes_check(b: &z_owned_bytes_t) -> bool { + !b.start.is_null() +} + + impl From for z_bytes_t { #[inline] fn from(pid: ZenohId) -> Self { @@ -276,13 +353,13 @@ pub extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { /// Returns the `index`th slice of the buffer, aliasing it. /// -/// Out of bounds accesses will return `z_bytes_null`. +/// Out of bounds accesses will return `z_bytes_empty`. #[no_mangle] pub extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { match buffer.into() { - None => z_bytes_null(), + None => z_bytes_empty(), Some(buf) => ZBuf::slices(buf) .nth(index) - .map_or(z_bytes_null(), |slice| slice.into()), + .map_or(z_bytes_empty(), |slice| slice.into()), } } diff --git a/src/commons.rs b/src/commons.rs index 249333d66..e8a6bc5d6 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -140,12 +140,13 @@ pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t /// Decodes payload into null-terminated string #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_string(payload: zc_payload_t) -> z_owned_str_t { +pub unsafe extern "C" fn zc_payload_decode_into_string(payload: zc_payload_t, cstr: &mut z_owned_str_t) -> i8 { let payload: Option<&ZBuf> = payload.into(); if payload.is_none() { - return z_str_null(); + *cstr = z_str_null(); + return 0; } - let mut cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); + *cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); let payload = payload.unwrap(); let mut pos = 0; @@ -153,7 +154,27 @@ pub unsafe extern "C" fn zc_payload_decode_into_string(payload: zc_payload_t) -> cstr.insert_unchecked(pos, s); pos += s.len(); } - cstr + return 0; +} + +/// Decodes payload into null-terminated string +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_decode_into_bytes(payload: zc_payload_t, b: &mut z_owned_bytes_t) -> i8 { + let payload: Option<&ZBuf> = payload.into(); + if payload.is_none() { + *b = z_bytes_null(); + return 0; + } + *b = z_owned_bytes_t::preallocate(zc_payload_len(payload.into())); + let payload = payload.unwrap(); + + let mut pos = 0; + for s in payload.slices() { + b.insert_unchecked(pos, s); + pos += s.len(); + } + return 0; } unsafe impl Send for z_bytes_t {} @@ -529,7 +550,7 @@ impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { #[repr(C)] pub struct z_owned_encoding_t { pub prefix: z_encoding_prefix_t, - pub suffix: z_bytes_t, + pub suffix: z_owned_bytes_t, pub _dropped: bool, } @@ -537,7 +558,7 @@ impl z_owned_encoding_t { pub fn null() -> Self { z_owned_encoding_t { prefix: z_encoding_prefix_t::Empty, - suffix: z_bytes_t::default(), + suffix: z_bytes_null(), _dropped: true, } } @@ -595,7 +616,7 @@ pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> z_encoding_t { z_encoding_t { prefix: encoding.prefix, - suffix: encoding.suffix, + suffix: z_bytes_loan(&encoding.suffix), } } @@ -603,7 +624,7 @@ impl From for z_owned_encoding_t { fn from(val: z_encoding_t) -> Self { z_owned_encoding_t { prefix: val.prefix, - suffix: val.suffix, + suffix: z_bytes_clone(&val.suffix), _dropped: false, } } @@ -655,6 +676,9 @@ impl Drop for z_owned_str_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_str_drop(s: &mut z_owned_str_t) { + if s._cstr.is_null() { + return; + } libc::free(std::mem::transmute(s._cstr)); s._cstr = std::ptr::null_mut(); } diff --git a/src/get.rs b/src/get.rs index 17ed9ccbe..3e9e4ded4 100644 --- a/src/get.rs +++ b/src/get.rs @@ -33,15 +33,8 @@ use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, z_attachment_t, }; -use crate::z_encoding_check; -use crate::z_encoding_drop; -use crate::z_encoding_loan; -use crate::z_encoding_null; -use crate::z_owned_encoding_t; +use crate::z_encoding_default; use crate::zc_owned_payload_t; -use crate::zc_payload_check; -use crate::zc_payload_drop; -use crate::zc_payload_loan; use crate::zc_payload_null; use crate::zc_payload_t; use crate::{ @@ -122,45 +115,6 @@ pub struct z_value_t { pub encoding: z_encoding_t, } -/// An owned zenoh value. -/// -/// Members: -/// zc_owned_payload_t payload: The payload of this zenoh value. -/// z_owned_encoding_t encoding: The encoding of this zenoh value `payload`. -#[repr(C)] -pub struct z_owned_value_t { - pub payload: zc_owned_payload_t, - pub encoding: z_owned_encoding_t, -} - -#[no_mangle] -pub extern "C" fn z_value_null() -> z_owned_value_t { - z_owned_value_t { - payload: zc_payload_null(), - encoding: z_encoding_null(), - } -} - -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_value_drop(value: &mut z_owned_value_t) { - z_encoding_drop(&mut value.encoding); - zc_payload_drop(&mut value.payload); -} - -#[no_mangle] -pub extern "C" fn z_value_loan(value: &z_owned_value_t) -> z_value_t { - z_value_t { - payload: zc_payload_loan(&value.payload), - encoding: z_encoding_loan(&value.encoding), - } -} - -#[no_mangle] -pub extern "C" fn z_value_check(value: &z_owned_value_t) -> bool { - zc_payload_check(&value.payload) && z_encoding_check(&value.encoding) -} - /// Yields the contents of the reply by asserting it indicates a failure. /// /// You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. @@ -202,7 +156,8 @@ pub extern "C" fn z_reply_null() -> z_owned_reply_t { pub struct z_get_options_t { pub target: z_query_target_t, pub consolidation: z_query_consolidation_t, - pub value: z_owned_value_t, + pub payload: zc_owned_payload_t, + pub encoding: z_encoding_t, pub attachment: z_attachment_t, pub timeout_ms: u64, } @@ -212,7 +167,8 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { target: QueryTarget::default().into(), consolidation: QueryConsolidation::default().into(), timeout_ms: 0, - value: z_value_null(), + payload: zc_payload_null(), + encoding: z_encoding_default(), attachment: z_attachment_null(), } } @@ -257,22 +213,10 @@ pub unsafe extern "C" fn z_get( .consolidation(options.consolidation) .target(options.target.into()); - if let Some(payload) = options.value.payload.take() { + if let Some(payload) = options.payload.take() { let mut value = Value::new(payload); - if z_encoding_check(&options.value.encoding) { - value = value.encoding(z_encoding_loan(&options.value.encoding).into()); - } - q = q.with_value(value); - } - z_encoding_drop(&mut options.value.encoding); - if zc_payload_check(&options.value.payload) { - let buf: ZBuf = options.value.payload.as_ref().unwrap().clone(); - let mut value = Value::new(buf); - if z_encoding_check(&options.value.encoding) { - value = value.encoding(z_encoding_loan(&options.value.encoding).into()); - } + value = value.encoding(options.encoding.into()); q = q.with_value(value); - z_value_drop(&mut options.value); } if options.timeout_ms != 0 { q = q.timeout(std::time::Duration::from_millis(options.timeout_ms)); diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index 789a00ffc..03a6d893c 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -93,13 +93,14 @@ void data_handler(const z_sample_t *sample, void *arg) { exit(-1); } z_drop(z_move(keystr)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); - if (strcmp(values[val_num], z_loan(payload))) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); exit(-1); } - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); printf("data_handler: %i\n", val_num); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index a665ad19b..ccb2c1e82 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -74,13 +74,14 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(keystr)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); - if (strcmp(values[val_num], z_loan(payload))) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); exit(-1); } - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); z_bytes_t v_const = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index 06d5c87ba..ad5969fa2 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -67,13 +67,14 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(keystr)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(sample)); - if (strcmp(values[val_num], z_loan(payload))) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); exit(-1); } - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); if (z_qos_get_congestion_control(z_sample_qos(sample)) != Z_CONGESTION_CONTROL_BLOCK || z_qos_get_priority(z_sample_qos(sample)) != Z_PRIORITY_DATA) { diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 26645ad29..909da8c24 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -110,10 +110,11 @@ int run_get() { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); - if (strcmp(values[val_num], z_loan(payload))) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); exit(-1); } @@ -121,7 +122,7 @@ int run_get() { ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); z_drop(z_move(keystr)); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); } z_drop(z_move(reply)); z_drop(z_move(channel)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index 7cc7f3bfc..3b3abad94 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -86,15 +86,16 @@ int run_get() { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_owned_str_t payload = zc_payload_decode_into_string(z_sample_payload(&sample)); - if (strcmp(values[val_num], z_loan(payload))) { + z_owned_str_t payload_value = z_str_null(); + zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); exit(-1); } z_drop(z_move(keystr)); - z_drop(z_move(payload)); + z_drop(z_move(payload_value)); } z_drop(z_move(reply)); z_drop(z_move(channel)); From b957f98a304bb870c5715c5bfe8a5d71525706c3 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 5 Apr 2024 12:31:48 +0200 Subject: [PATCH 20/75] generate opaque types data inside build.rs instead of cmake --- CMakeLists.txt | 5 ----- build.rs | 28 ++++++++++++++++++++++++++-- src/collections.rs | 17 ++++++----------- src/commons.rs | 14 ++++++++++---- src/opaque_types/mod.rs | 15 --------------- 5 files changed, 42 insertions(+), 37 deletions(-) delete mode 100644 src/opaque_types/mod.rs diff --git a/CMakeLists.txt b/CMakeLists.txt index aac66278b..00aa5cac2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -179,10 +179,6 @@ set_genexpr_condition(cargo_flags DEBUG $ "--manifest-path=${cargo_toml_dir_debug}/Cargo.toml" "--release;--manifest-path=${cargo_toml_dir_release}/Cargo.toml") set(cargo_flags ${cargo_flags} ${ZENOHC_CARGO_FLAGS}) -set_genexpr_condition(cargo_dep_flags DEBUG $ - "--manifest-path=${CMAKE_CURRENT_SOURCE_DIR}/build-resources/opaque-types/Cargo.toml" - "--release;--manifest-path=${CMAKE_CURRENT_SOURCE_DIR}/build-resources/opaque-types/Cargo.toml") -set(cargo_dep_flags ${cargo_dep_flags} ${ZENOHC_CARGO_FLAGS}) if(ZENOHC_BUILD_WITH_LOGGER_AUTOINIT) set(cargo_flags ${cargo_flags} --features=logger-autoinit) @@ -203,7 +199,6 @@ add_custom_command( OUTPUT ${libs} COMMAND ${CMAKE_COMMAND} -E echo \"RUSTFLAGS = $$RUSTFLAGS\" COMMAND ${CMAKE_COMMAND} -E echo \"cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_flags}\" - COMMAND cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_dep_flags} &> ${CMAKE_CURRENT_SOURCE_DIR}/.build_resources_opaque_types.txt || echo "" COMMAND cargo +${ZENOHC_CARGO_CHANNEL} build ${cargo_flags} VERBATIM COMMAND_EXPAND_LISTS diff --git a/build.rs b/build.rs index 03a271817..b14bdc4cd 100644 --- a/build.rs +++ b/build.rs @@ -1,6 +1,8 @@ use fs2::FileExt; use regex::Regex; use std::io::{Read, Write}; +use std::path::PathBuf; +use std::process::{Command, Stdio}; use std::{borrow::Cow, collections::HashMap, io::BufWriter, path::Path}; const GENERATION_PATH: &str = "include/zenoh-gen.h"; @@ -24,6 +26,8 @@ const HEADER: &str = r"// #endif "; +use std::env; + fn main() { generate_opaque_types(); cbindgen::generate(std::env::var("CARGO_MANIFEST_DIR").unwrap()) @@ -42,9 +46,29 @@ fn main() { println!("cargo:rerun-if-changed=build-resources") } +fn produce_opaque_types_data() -> PathBuf { + let target = env::var("TARGET").unwrap(); + let current_folder = std::env::current_dir().unwrap(); + let manifest_path = current_folder.join("./build-resources/opaque-types/Cargo.toml"); + let output_file_path = current_folder.join("./.build_resources_opaque_types.txt"); + let out_file = std::fs::File::create(output_file_path.clone()).unwrap(); + let stdio = Stdio::from(out_file); + let _ = Command::new("cargo") + .arg("build") + .arg("--target") + .arg(target) + .arg("--manifest-path") + .arg(manifest_path) + .stderr(stdio) + .output() + .unwrap(); + + output_file_path +} + fn generate_opaque_types() { let current_folder = std::env::current_dir().unwrap(); - let path_in = current_folder.join("./.build_resources_opaque_types.txt"); + let path_in = produce_opaque_types_data(); let path_out = current_folder.join("./src/opaque_types/mod.rs"); let data_in = std::fs::read_to_string(path_in).unwrap(); @@ -56,7 +80,7 @@ fn generate_opaque_types() { let s = format!( "#[repr(C, align({align}))] pub struct {type_name} {{ - _0: [u8; {size}] + _0: [u8; {size}], }} " ); diff --git a/src/collections.rs b/src/collections.rs index 2990f1a3a..363c30a89 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -68,8 +68,8 @@ impl Drop for z_owned_bytes_t { } impl z_owned_bytes_t { - pub fn new(data: &[u8]) ->z_owned_bytes_t { - if data.len() == 0 { + pub fn new(data: &[u8]) -> z_owned_bytes_t { + if data.is_empty() { return z_bytes_null(); } let data = data.to_vec().into_boxed_slice(); @@ -83,17 +83,13 @@ impl z_owned_bytes_t { let data = vec![0u8; len].into_boxed_slice(); z_owned_bytes_t { len, - start: Box::leak(data).as_mut_ptr(), + start: Box::leak(data).as_mut_ptr(), } } #[allow(clippy::missing_safety_doc)] pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { - std::ptr::copy_nonoverlapping( - value.as_ptr(), - (self.start as *mut u8).add(start), - value.len(), - ); + std::ptr::copy_nonoverlapping(value.as_ptr(), self.start.add(start), value.len()); } } @@ -182,9 +178,9 @@ pub const extern "C" fn z_bytes_loan(b: &z_owned_bytes_t) -> z_bytes_t { #[no_mangle] pub extern "C" fn z_bytes_clone(b: &z_bytes_t) -> z_owned_bytes_t { if !z_bytes_is_initialized(b) { - return z_bytes_null(); + z_bytes_null() } else { - return z_owned_bytes_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) } ) + z_owned_bytes_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) }) } } @@ -194,7 +190,6 @@ pub extern "C" fn z_bytes_check(b: &z_owned_bytes_t) -> bool { !b.start.is_null() } - impl From for z_bytes_t { #[inline] fn from(pid: ZenohId) -> Self { diff --git a/src/commons.rs b/src/commons.rs index e8a6bc5d6..5f8ede970 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -140,7 +140,10 @@ pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t /// Decodes payload into null-terminated string #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_string(payload: zc_payload_t, cstr: &mut z_owned_str_t) -> i8 { +pub unsafe extern "C" fn zc_payload_decode_into_string( + payload: zc_payload_t, + cstr: &mut z_owned_str_t, +) -> i8 { let payload: Option<&ZBuf> = payload.into(); if payload.is_none() { *cstr = z_str_null(); @@ -154,13 +157,16 @@ pub unsafe extern "C" fn zc_payload_decode_into_string(payload: zc_payload_t, cs cstr.insert_unchecked(pos, s); pos += s.len(); } - return 0; + 0 } /// Decodes payload into null-terminated string #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_bytes(payload: zc_payload_t, b: &mut z_owned_bytes_t) -> i8 { +pub unsafe extern "C" fn zc_payload_decode_into_bytes( + payload: zc_payload_t, + b: &mut z_owned_bytes_t, +) -> i8 { let payload: Option<&ZBuf> = payload.into(); if payload.is_none() { *b = z_bytes_null(); @@ -174,7 +180,7 @@ pub unsafe extern "C" fn zc_payload_decode_into_bytes(payload: zc_payload_t, b: b.insert_unchecked(pos, s); pos += s.len(); } - return 0; + 0 } unsafe impl Send for z_bytes_t {} diff --git a/src/opaque_types/mod.rs b/src/opaque_types/mod.rs deleted file mode 100644 index 0327b0943..000000000 --- a/src/opaque_types/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -/// A split buffer that owns all of its data. -/// -/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. -#[repr(C, align(8))] -pub struct z_owned_buffer_t { - _0: [u8; 40] -} -/// An owned sample. -/// -/// This is a read only type that can only be constructed by cloning a `z_sample_t`. -/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. -#[repr(C, align(8))] -pub struct zc_owned_sample_t { - _0: [u8; 224] -} From f73599feb336f94dc029eb6958abcfbcba47abd6 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 5 Apr 2024 12:36:30 +0200 Subject: [PATCH 21/75] .gitignore update --- .gitignore | 3 ++- src/opaque_types/.gitkeep | 0 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 src/opaque_types/.gitkeep diff --git a/.gitignore b/.gitignore index 8aaf37e32..49b20fcc2 100644 --- a/.gitignore +++ b/.gitignore @@ -73,4 +73,5 @@ dkms.conf include/zenoh_configure.h # Build resources -.build_resources* \ No newline at end of file +.build_resources* +src/opaque_types/mod.rs \ No newline at end of file diff --git a/src/opaque_types/.gitkeep b/src/opaque_types/.gitkeep new file mode 100644 index 000000000..e69de29bb From a3cc34a1c1f54eb9fcfc1d9ff5d9fc3c9d454024 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 5 Apr 2024 16:04:59 +0200 Subject: [PATCH 22/75] extract build.rs instad of current folder to allow build outside of crate root --- build.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/build.rs b/build.rs index b14bdc4cd..51d44a615 100644 --- a/build.rs +++ b/build.rs @@ -46,10 +46,18 @@ fn main() { println!("cargo:rerun-if-changed=build-resources") } +fn get_build_rs_path() -> PathBuf { + let file_path = file!(); + let mut path_buf = PathBuf::new(); + path_buf.push(file_path); + path_buf.parent().unwrap().to_path_buf() +} + fn produce_opaque_types_data() -> PathBuf { let target = env::var("TARGET").unwrap(); - let current_folder = std::env::current_dir().unwrap(); + let current_folder = get_build_rs_path(); let manifest_path = current_folder.join("./build-resources/opaque-types/Cargo.toml"); + println!("cargo:warning={}", current_folder.to_str().unwrap()); let output_file_path = current_folder.join("./.build_resources_opaque_types.txt"); let out_file = std::fs::File::create(output_file_path.clone()).unwrap(); let stdio = Stdio::from(out_file); @@ -67,7 +75,7 @@ fn produce_opaque_types_data() -> PathBuf { } fn generate_opaque_types() { - let current_folder = std::env::current_dir().unwrap(); + let current_folder = get_build_rs_path(); let path_in = produce_opaque_types_data(); let path_out = current_folder.join("./src/opaque_types/mod.rs"); @@ -96,7 +104,7 @@ pub struct {type_name} {{ } fn get_opaque_type_docs() -> HashMap> { - let current_folder = std::env::current_dir().unwrap(); + let current_folder = get_build_rs_path(); let path_in = current_folder.join("./build-resources/opaque-types/src/lib.rs"); let re = Regex::new(r#"get_opaque_type_data!\(.*, "(\w+)"\)"#).unwrap(); let mut comments = std::vec::Vec::::new(); From 142b75299e7e4610328650cd18cf608749c9e0fa Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 5 Apr 2024 16:28:54 +0200 Subject: [PATCH 23/75] remove println! --- build.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/build.rs b/build.rs index 51d44a615..703bde4c1 100644 --- a/build.rs +++ b/build.rs @@ -57,7 +57,6 @@ fn produce_opaque_types_data() -> PathBuf { let target = env::var("TARGET").unwrap(); let current_folder = get_build_rs_path(); let manifest_path = current_folder.join("./build-resources/opaque-types/Cargo.toml"); - println!("cargo:warning={}", current_folder.to_str().unwrap()); let output_file_path = current_folder.join("./.build_resources_opaque_types.txt"); let out_file = std::fs::File::create(output_file_path.clone()).unwrap(); let stdio = Stdio::from(out_file); From 4932ddff7c708380ca8177d7a844981182397ed8 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 5 Apr 2024 17:36:13 +0200 Subject: [PATCH 24/75] move Payload/zBuf-related functionality into separate file --- include/zenoh_commons.h | 4 +- src/collections.rs | 132 +------------------- src/commons.rs | 140 +-------------------- src/lib.rs | 2 + src/payload.rs | 261 ++++++++++++++++++++++++++++++++++++++++ src/put.rs | 1 + 6 files changed, 271 insertions(+), 269 deletions(-) create mode 100644 src/payload.rs diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index fe2b58959..7e6060df7 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -2121,13 +2121,13 @@ ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); * Note that other samples may have received the same buffer, meaning that mutating this buffer may * affect the samples received by other subscribers. */ -ZENOHC_API struct z_owned_buffer_t z_sample_owned_payload(const struct z_sample_t *sample); +ZENOHC_API zc_owned_payload_t z_sample_owned_payload(const struct z_sample_t *sample); /** * The sample's data, the return value aliases the sample. * * If you need ownership of the buffer, you may use `z_sample_owned_payload`. */ -ZENOHC_API struct z_buffer_t z_sample_payload(const struct z_sample_t *sample); +ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); /** * The qos with which the sample was received. */ diff --git a/src/collections.rs b/src/collections.rs index 363c30a89..d55a9fa1b 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -13,14 +13,7 @@ // use libc::{c_char, size_t}; -use std::ops::Deref; -use std::ptr::NonNull; -use zenoh::{ - buffers::{buffer::SplitBuffer, ZBuf}, - prelude::ZenohId, -}; - -use crate::{impl_guarded_transmute, GuardedTransmute}; +use zenoh::prelude::ZenohId; /// A contiguous view of bytes owned by some other entity. /// @@ -235,126 +228,3 @@ impl From<&[u8]> for z_bytes_t { } } } - -pub use crate::z_owned_buffer_t; -impl_guarded_transmute!(noderefs Option, z_owned_buffer_t); -impl Default for z_owned_buffer_t { - fn default() -> Self { - z_buffer_null() - } -} -impl From for z_owned_buffer_t { - fn from(value: ZBuf) -> Self { - Some(value).transmute() - } -} - -impl From> for z_owned_buffer_t { - fn from(value: Option) -> Self { - match value { - Some(value) => value.into(), - None => z_buffer_null(), - } - } -} -impl core::ops::Deref for z_owned_buffer_t { - type Target = Option; - - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } -} -impl core::ops::DerefMut for z_owned_buffer_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { core::mem::transmute(self) } - } -} - -/// The gravestone value for `z_owned_buffer_t`. -#[no_mangle] -pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { - unsafe { core::mem::transmute(None::) } -} - -/// Decrements the buffer's reference counter, destroying it if applicable. -/// -/// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. -#[no_mangle] -pub extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { - core::mem::drop(buffer.take()) -} - -/// Returns `true` if the buffer is in a valid state. -#[no_mangle] -pub extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { - buffer.is_some() -} - -/// Loans the buffer, allowing you to call functions that only need a loan of it. -#[no_mangle] -pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { - buffer.as_ref().into() -} - -/// A loan of a `z_owned_buffer_t`. -/// -/// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. -#[repr(C)] -#[derive(Clone, Copy, Default)] -pub struct z_buffer_t { - _inner: Option>, -} - -impl From> for z_buffer_t { - fn from(value: Option<&ZBuf>) -> Self { - unsafe { core::mem::transmute(value) } - } -} - -impl From for Option<&'static ZBuf> { - fn from(value: z_buffer_t) -> Self { - unsafe { core::mem::transmute(value) } - } -} - -/// Increments the buffer's reference count, returning an owned version of the buffer. -#[no_mangle] -pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { - match buffer._inner { - Some(b) => unsafe { b.as_ref().deref().clone().transmute() }, - None => ZBuf::empty().into(), - } -} - -/// Returns the number of slices in the buffer. -/// -/// If the return value is 0 or 1, then the buffer's data is contiguous in memory. -#[no_mangle] -pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { - match buffer.into() { - None => 0, - Some(buf) => ZBuf::slices(buf).len(), - } -} - -/// Returns total number bytes in the buffer. -#[no_mangle] -pub extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { - match buffer.into() { - None => 0, - Some(buf) => ZBuf::slices(buf).fold(0, |acc, s| acc + s.len()), - } -} - -/// Returns the `index`th slice of the buffer, aliasing it. -/// -/// Out of bounds accesses will return `z_bytes_empty`. -#[no_mangle] -pub extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { - match buffer.into() { - None => z_bytes_empty(), - Some(buf) => ZBuf::slices(buf) - .nth(index) - .map_or(z_bytes_empty(), |slice| slice.into()), - } -} diff --git a/src/commons.rs b/src/commons.rs index 5f8ede970..ed0f9dbf0 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -12,21 +12,18 @@ // ZettaScale Zenoh team, // -use std::any::Any; use std::ops::Deref; -use std::slice; use crate::collections::*; use crate::keyexpr::*; use crate::z_congestion_control_t; use crate::z_id_t; use crate::z_priority_t; +use crate::zc_owned_payload_t; +use crate::zc_payload_t; use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; -use zenoh::buffers::buffer::SplitBuffer; -use zenoh::buffers::ZBuf; -use zenoh::buffers::ZSliceBuffer; use zenoh::prelude::SampleKind; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; @@ -95,135 +92,6 @@ impl From> for z_timestamp_t { } } -/// An owned payload, backed by a reference counted owner. -/// -/// The `payload` field may be modified, and Zenoh will take the new values into account. -#[allow(non_camel_case_types)] -pub type zc_owned_payload_t = z_owned_buffer_t; - -/// Clones the `payload` by incrementing its reference counter. -#[no_mangle] -pub extern "C" fn zc_payload_rcinc(payload: &zc_owned_payload_t) -> zc_owned_payload_t { - z_buffer_clone(z_buffer_loan(payload)) -} -/// Returns `false` if `payload` is the gravestone value. -#[no_mangle] -pub extern "C" fn zc_payload_check(payload: &zc_owned_payload_t) -> bool { - z_buffer_check(payload) -} -/// Decrements `payload`'s backing refcount, releasing the memory if appropriate. -#[no_mangle] -pub extern "C" fn zc_payload_drop(payload: &mut zc_owned_payload_t) { - z_buffer_drop(payload) -} -/// Constructs `zc_owned_payload_t`'s gravestone value. -#[no_mangle] -pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { - z_buffer_null() -} - -/// Returns a :c:type:`zc_payload_t` loaned from `payload`. -#[no_mangle] -pub extern "C" fn zc_payload_loan(payload: &zc_owned_payload_t) -> zc_payload_t { - z_buffer_loan(payload) -} - -#[allow(non_camel_case_types)] -pub type zc_payload_t = z_buffer_t; - -/// Increments internal payload reference count, returning owned payload. -#[no_mangle] -pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t { - z_buffer_clone(payload) -} - -/// Decodes payload into null-terminated string -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_string( - payload: zc_payload_t, - cstr: &mut z_owned_str_t, -) -> i8 { - let payload: Option<&ZBuf> = payload.into(); - if payload.is_none() { - *cstr = z_str_null(); - return 0; - } - *cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); - let payload = payload.unwrap(); - - let mut pos = 0; - for s in payload.slices() { - cstr.insert_unchecked(pos, s); - pos += s.len(); - } - 0 -} - -/// Decodes payload into null-terminated string -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_bytes( - payload: zc_payload_t, - b: &mut z_owned_bytes_t, -) -> i8 { - let payload: Option<&ZBuf> = payload.into(); - if payload.is_none() { - *b = z_bytes_null(); - return 0; - } - *b = z_owned_bytes_t::preallocate(zc_payload_len(payload.into())); - let payload = payload.unwrap(); - - let mut pos = 0; - for s in payload.slices() { - b.insert_unchecked(pos, s); - pos += s.len(); - } - 0 -} - -unsafe impl Send for z_bytes_t {} -unsafe impl Sync for z_bytes_t {} - -impl ZSliceBuffer for z_bytes_t { - fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.start, self.len) } - } - fn as_mut_slice(&mut self) -> &mut [u8] { - unsafe { slice::from_raw_parts_mut(self.start as *mut u8, self.len) } - } - fn as_any(&self) -> &dyn Any { - self - } -} - -/// Encodes byte sequence by aliasing. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_encode_from_bytes(bytes: z_bytes_t) -> zc_owned_payload_t { - ZBuf::from(bytes).into() -} - -/// Encodes a null-terminated string by aliasing. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_encode_from_string( - cstr: *const libc::c_char, -) -> zc_owned_payload_t { - let bytes = z_bytes_t { - start: cstr as *const u8, - len: libc::strlen(cstr), - }; - zc_payload_encode_from_bytes(bytes) -} - -/// Returns total number bytes in the payload. -#[no_mangle] -pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { - z_buffer_len(payload) -} - /// QoS settings of zenoh message. /// #[repr(C)] @@ -290,7 +158,7 @@ pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { /// /// If you need ownership of the buffer, you may use `z_sample_owned_payload`. #[no_mangle] -pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_buffer_t { +pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { Some(&sample.payload).into() } /// Returns the sample's payload after incrementing its internal reference count. @@ -298,7 +166,7 @@ pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_buffer_t { /// Note that other samples may have received the same buffer, meaning that mutating this buffer may /// affect the samples received by other subscribers. #[no_mangle] -pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> z_owned_buffer_t { +pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { sample.payload.clone().into() } /// The sample's kind (put or delete). diff --git a/src/lib.rs b/src/lib.rs index 96cc4bd76..20f766352 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,6 +23,8 @@ mod config; pub use crate::config::*; mod commons; pub use crate::commons::*; +mod payload; +pub use crate::payload::*; mod keyexpr; pub use crate::keyexpr::*; mod info; diff --git a/src/payload.rs b/src/payload.rs new file mode 100644 index 000000000..ba28eb3e4 --- /dev/null +++ b/src/payload.rs @@ -0,0 +1,261 @@ +use core::slice; +use std::{any::Any, ops::Deref, ptr::NonNull}; + +use zenoh::buffers::{buffer::SplitBuffer, ZBuf, ZSliceBuffer}; + +use crate::{ + impl_guarded_transmute, z_bytes_empty, z_bytes_null, z_bytes_t, z_owned_bytes_t, z_owned_str_t, + z_str_null, GuardedTransmute, +}; + +pub use crate::z_owned_buffer_t; +impl_guarded_transmute!(noderefs Option, z_owned_buffer_t); +impl Default for z_owned_buffer_t { + fn default() -> Self { + z_buffer_null() + } +} +impl From for z_owned_buffer_t { + fn from(value: ZBuf) -> Self { + Some(value).transmute() + } +} + +impl From> for z_owned_buffer_t { + fn from(value: Option) -> Self { + match value { + Some(value) => value.into(), + None => z_buffer_null(), + } + } +} +impl core::ops::Deref for z_owned_buffer_t { + type Target = Option; + + fn deref(&self) -> &Self::Target { + unsafe { core::mem::transmute(self) } + } +} +impl core::ops::DerefMut for z_owned_buffer_t { + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { core::mem::transmute(self) } + } +} + +/// The gravestone value for `z_owned_buffer_t`. +#[no_mangle] +pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { + unsafe { core::mem::transmute(None::) } +} + +/// Decrements the buffer's reference counter, destroying it if applicable. +/// +/// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. +#[no_mangle] +pub extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { + core::mem::drop(buffer.take()) +} + +/// Returns `true` if the buffer is in a valid state. +#[no_mangle] +pub extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { + buffer.is_some() +} + +/// Loans the buffer, allowing you to call functions that only need a loan of it. +#[no_mangle] +pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { + buffer.as_ref().into() +} + +/// A loan of a `z_owned_buffer_t`. +/// +/// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. +#[repr(C)] +#[derive(Clone, Copy, Default)] +pub struct z_buffer_t { + _inner: Option>, +} + +impl From> for z_buffer_t { + fn from(value: Option<&ZBuf>) -> Self { + unsafe { core::mem::transmute(value) } + } +} + +impl From for Option<&'static ZBuf> { + fn from(value: z_buffer_t) -> Self { + unsafe { core::mem::transmute(value) } + } +} + +/// Increments the buffer's reference count, returning an owned version of the buffer. +#[no_mangle] +pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { + match buffer._inner { + Some(b) => unsafe { b.as_ref().deref().clone().transmute() }, + None => ZBuf::empty().into(), + } +} + +/// Returns the number of slices in the buffer. +/// +/// If the return value is 0 or 1, then the buffer's data is contiguous in memory. +#[no_mangle] +pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { + match buffer.into() { + None => 0, + Some(buf) => ZBuf::slices(buf).len(), + } +} + +/// Returns total number bytes in the buffer. +#[no_mangle] +pub extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { + match buffer.into() { + None => 0, + Some(buf) => ZBuf::slices(buf).fold(0, |acc, s| acc + s.len()), + } +} + +/// Returns the `index`th slice of the buffer, aliasing it. +/// +/// Out of bounds accesses will return `z_bytes_empty`. +#[no_mangle] +pub extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { + match buffer.into() { + None => z_bytes_empty(), + Some(buf) => ZBuf::slices(buf) + .nth(index) + .map_or(z_bytes_empty(), |slice| slice.into()), + } +} + +/// An owned payload, backed by a reference counted owner. +/// +/// The `payload` field may be modified, and Zenoh will take the new values into account. +#[allow(non_camel_case_types)] +pub type zc_owned_payload_t = z_owned_buffer_t; + +/// Clones the `payload` by incrementing its reference counter. +#[no_mangle] +pub extern "C" fn zc_payload_rcinc(payload: &zc_owned_payload_t) -> zc_owned_payload_t { + z_buffer_clone(z_buffer_loan(payload)) +} +/// Returns `false` if `payload` is the gravestone value. +#[no_mangle] +pub extern "C" fn zc_payload_check(payload: &zc_owned_payload_t) -> bool { + z_buffer_check(payload) +} +/// Decrements `payload`'s backing refcount, releasing the memory if appropriate. +#[no_mangle] +pub extern "C" fn zc_payload_drop(payload: &mut zc_owned_payload_t) { + z_buffer_drop(payload) +} +/// Constructs `zc_owned_payload_t`'s gravestone value. +#[no_mangle] +pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { + z_buffer_null() +} + +/// Returns a :c:type:`zc_payload_t` loaned from `payload`. +#[no_mangle] +pub extern "C" fn zc_payload_loan(payload: &zc_owned_payload_t) -> zc_payload_t { + z_buffer_loan(payload) +} + +#[allow(non_camel_case_types)] +pub type zc_payload_t = z_buffer_t; + +/// Increments internal payload reference count, returning owned payload. +#[no_mangle] +pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t { + z_buffer_clone(payload) +} + +/// Decodes payload into null-terminated string +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_decode_into_string( + payload: zc_payload_t, + cstr: &mut z_owned_str_t, +) -> i8 { + let payload: Option<&ZBuf> = payload.into(); + if payload.is_none() { + *cstr = z_str_null(); + return 0; + } + *cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); + let payload = payload.unwrap(); + + let mut pos = 0; + for s in payload.slices() { + cstr.insert_unchecked(pos, s); + pos += s.len(); + } + 0 +} + +/// Decodes payload into null-terminated string +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_decode_into_bytes( + payload: zc_payload_t, + b: &mut z_owned_bytes_t, +) -> i8 { + let payload: Option<&ZBuf> = payload.into(); + if payload.is_none() { + *b = z_bytes_null(); + return 0; + } + *b = z_owned_bytes_t::preallocate(zc_payload_len(payload.into())); + let payload = payload.unwrap(); + + let mut pos = 0; + for s in payload.slices() { + b.insert_unchecked(pos, s); + pos += s.len(); + } + 0 +} + +unsafe impl Send for z_bytes_t {} +unsafe impl Sync for z_bytes_t {} + +impl ZSliceBuffer for z_bytes_t { + fn as_slice(&self) -> &[u8] { + unsafe { slice::from_raw_parts(self.start, self.len) } + } + fn as_mut_slice(&mut self) -> &mut [u8] { + unsafe { slice::from_raw_parts_mut(self.start as *mut u8, self.len) } + } + fn as_any(&self) -> &dyn Any { + self + } +} + +/// Encodes byte sequence by aliasing. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_encode_from_bytes(bytes: z_bytes_t) -> zc_owned_payload_t { + ZBuf::from(bytes).into() +} + +/// Encodes a null-terminated string by aliasing. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_encode_from_string( + cstr: *const libc::c_char, +) -> zc_owned_payload_t { + let bytes = z_bytes_t { + start: cstr as *const u8, + len: libc::strlen(cstr), + }; + zc_payload_encode_from_bytes(bytes) +} + +/// Returns total number bytes in the payload. +#[no_mangle] +pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { + z_buffer_len(payload) +} diff --git a/src/put.rs b/src/put.rs index 5c8b8d807..5e2d59aec 100644 --- a/src/put.rs +++ b/src/put.rs @@ -14,6 +14,7 @@ use crate::commons::*; use crate::keyexpr::*; use crate::session::*; +use crate::zc_owned_payload_t; use crate::LOG_INVALID_SESSION; use libc::c_void; use zenoh::prelude::{sync::SyncResolve, Priority, SampleKind}; From 90f25783bf5607303aa749b08af228243e0db12a Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 5 Apr 2024 18:24:20 +0200 Subject: [PATCH 25/75] replace unsafe transmutes with safe ones --- src/payload.rs | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/src/payload.rs b/src/payload.rs index ba28eb3e4..2bc82e699 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -9,7 +9,8 @@ use crate::{ }; pub use crate::z_owned_buffer_t; -impl_guarded_transmute!(noderefs Option, z_owned_buffer_t); +impl_guarded_transmute!(Option, z_owned_buffer_t); + impl Default for z_owned_buffer_t { fn default() -> Self { z_buffer_null() @@ -21,31 +22,10 @@ impl From for z_owned_buffer_t { } } -impl From> for z_owned_buffer_t { - fn from(value: Option) -> Self { - match value { - Some(value) => value.into(), - None => z_buffer_null(), - } - } -} -impl core::ops::Deref for z_owned_buffer_t { - type Target = Option; - - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } -} -impl core::ops::DerefMut for z_owned_buffer_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { core::mem::transmute(self) } - } -} - /// The gravestone value for `z_owned_buffer_t`. #[no_mangle] pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { - unsafe { core::mem::transmute(None::) } + None::.transmute() } /// Decrements the buffer's reference counter, destroying it if applicable. @@ -77,15 +57,18 @@ pub struct z_buffer_t { _inner: Option>, } +impl_guarded_transmute!(noderefs Option<&ZBuf>, z_buffer_t); +impl_guarded_transmute!(noderefs z_buffer_t, Option<&'static ZBuf>); + impl From> for z_buffer_t { fn from(value: Option<&ZBuf>) -> Self { - unsafe { core::mem::transmute(value) } + value.transmute() } } impl From for Option<&'static ZBuf> { fn from(value: z_buffer_t) -> Self { - unsafe { core::mem::transmute(value) } + value.transmute() } } From 32ac0af172334bccb9f480053b7e15bd30f04a3d Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 8 Apr 2024 13:26:49 +0200 Subject: [PATCH 26/75] add payload reader --- build-resources/opaque-types/src/lib.rs | 7 ++-- include/zenoh_commons.h | 27 ++++++++++++++++ src/payload.rs | 42 ++++++++++++++++++++++++ tests/z_api_payload_test.c | 43 +++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 tests/z_api_payload_test.c diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 8ef08035c..354e8d999 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,5 +1,5 @@ use zenoh::sample::Sample; -use zenoh::buffers::ZBuf; +use zenoh::buffers::{ZBuf, ZBufReader}; #[macro_export] macro_rules! get_opaque_type_data { @@ -35,4 +35,7 @@ get_opaque_type_data!(Option, "z_owned_buffer_t"); /// /// This is a read only type that can only be constructed by cloning a `z_sample_t`. /// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. -get_opaque_type_data!(Option, "zc_owned_sample_t"); \ No newline at end of file +get_opaque_type_data!(Option, "zc_owned_sample_t"); + +/// A reader for payload data. +get_opaque_type_data!(ZBufReader, "zc_payload_reader"); \ No newline at end of file diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 7e6060df7..41129a653 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -885,6 +885,12 @@ typedef struct zc_owned_liveliness_token_t { typedef struct zc_liveliness_get_options_t { uint32_t timeout_ms; } zc_liveliness_get_options_t; +/** + * A reader for payload data. + */ +typedef struct ALIGN(8) zc_payload_reader { + uint8_t _0[24]; +} zc_payload_reader; /** * An owned sample. * @@ -2500,6 +2506,27 @@ ZENOHC_API zc_owned_payload_t zc_payload_null(void); * Clones the `payload` by incrementing its reference counter. */ ZENOHC_API zc_owned_payload_t zc_payload_rcinc(const zc_owned_payload_t *payload); +/** + * Creates a reader for the specified `payload`. + * + * Returns 0 in case of success, -1 if `payload` is not valid. + */ +ZENOHC_API int8_t zc_payload_reader_init(zc_payload_t payload, struct zc_payload_reader *reader); +/** + * Reads data into specified destination. + * + * Will read at most `len` bytes. + * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. + */ +ZENOHC_API +size_t zc_payload_reader_read(struct zc_payload_reader *reader, + uint8_t *dest, + size_t len); +/** + * Returns number of the remaining bytes in the payload + * + */ +ZENOHC_API size_t zc_payload_reader_remaining(const struct zc_payload_reader *reader); /** * Creates a new blocking fifo channel, returned as a pair of closures. * diff --git a/src/payload.rs b/src/payload.rs index 2bc82e699..e43124bbb 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,6 +1,10 @@ use core::slice; +use std::slice::from_raw_parts_mut; use std::{any::Any, ops::Deref, ptr::NonNull}; +use zenoh::buffers::reader::HasReader; +use zenoh::buffers::reader::Reader; +use zenoh::buffers::ZBufReader; use zenoh::buffers::{buffer::SplitBuffer, ZBuf, ZSliceBuffer}; use crate::{ @@ -242,3 +246,41 @@ pub unsafe extern "C" fn zc_payload_encode_from_string( pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { z_buffer_len(payload) } + + + +pub use crate::zc_payload_reader; +impl_guarded_transmute!(ZBufReader<'static>, zc_payload_reader); +impl_guarded_transmute!(noderefs zc_payload_reader, ZBufReader<'static>); + +/// Creates a reader for the specified `payload`. +/// +/// Returns 0 in case of success, -1 if `payload` is not valid. +#[no_mangle] +pub unsafe extern "C" fn zc_payload_reader_init(payload: zc_payload_t, reader: *mut zc_payload_reader) -> i8 { + if payload._inner.is_none() { + return -1; + } + *reader = payload.transmute().unwrap().reader().transmute(); + 0 +} + + +/// Reads data into specified destination. +/// +/// Will read at most `len` bytes. +/// Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_reader_read(reader: *mut zc_payload_reader, dest: *mut u8, len: usize) -> usize { + let buf = unsafe { from_raw_parts_mut(dest, len) } ; + reader.as_mut().unwrap().read(buf).map(|n| n.get()).unwrap_or(0) +} + +/// Returns number of the remaining bytes in the payload +/// +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_reader_remaining(reader: *const zc_payload_reader) -> usize { + reader.as_ref().unwrap().remaining() +} \ No newline at end of file diff --git a/tests/z_api_payload_test.c b/tests/z_api_payload_test.c new file mode 100644 index 000000000..d2d5da4d4 --- /dev/null +++ b/tests/z_api_payload_test.c @@ -0,0 +1,43 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, + +#include +#include +#include +#include + +#include "zenoh.h" + +#undef NDEBUG +#include + +void test_reader() { + uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + uint8_t data_out[10] = {}; + z_bytes_t bytes = {.start = data, .len = 10 }; + + zc_owned_payload_t payload = zc_payload_encode_from_bytes(bytes); + zc_payload_reader reader; + zc_payload_reader_init(z_loan(payload), &reader); + assert(zc_payload_reader_remaining(&reader) == 10); + + zc_payload_reader_read(&reader, data_out, 5); + assert(zc_payload_reader_remaining(&reader) == 5); + zc_payload_reader_read(&reader, data_out, 5); + assert(zc_payload_reader_remaining(&reader) == 0); + assert(memcmp(data, data_out, 10)); +} + +int main(int argc, char **argv) { + test_reader(); +} From f1cdeda3375a415f7c3fc76b1f9606c8a8a1f1a4 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 8 Apr 2024 14:33:47 +0200 Subject: [PATCH 27/75] fmt and clippy --- src/payload.rs | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/payload.rs b/src/payload.rs index e43124bbb..f7a737ef5 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -247,17 +247,19 @@ pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { z_buffer_len(payload) } - - pub use crate::zc_payload_reader; impl_guarded_transmute!(ZBufReader<'static>, zc_payload_reader); impl_guarded_transmute!(noderefs zc_payload_reader, ZBufReader<'static>); -/// Creates a reader for the specified `payload`. +/// Creates a reader for the specified `payload`. /// /// Returns 0 in case of success, -1 if `payload` is not valid. #[no_mangle] -pub unsafe extern "C" fn zc_payload_reader_init(payload: zc_payload_t, reader: *mut zc_payload_reader) -> i8 { +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_payload_reader_init( + payload: zc_payload_t, + reader: *mut zc_payload_reader, +) -> i8 { if payload._inner.is_none() { return -1; } @@ -265,22 +267,30 @@ pub unsafe extern "C" fn zc_payload_reader_init(payload: zc_payload_t, reader: * 0 } - /// Reads data into specified destination. -/// -/// Will read at most `len` bytes. +/// +/// Will read at most `len` bytes. /// Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_reader_read(reader: *mut zc_payload_reader, dest: *mut u8, len: usize) -> usize { - let buf = unsafe { from_raw_parts_mut(dest, len) } ; - reader.as_mut().unwrap().read(buf).map(|n| n.get()).unwrap_or(0) +pub unsafe extern "C" fn zc_payload_reader_read( + reader: *mut zc_payload_reader, + dest: *mut u8, + len: usize, +) -> usize { + let buf = unsafe { from_raw_parts_mut(dest, len) }; + reader + .as_mut() + .unwrap() + .read(buf) + .map(|n| n.get()) + .unwrap_or(0) } /// Returns number of the remaining bytes in the payload -/// +/// #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_payload_reader_remaining(reader: *const zc_payload_reader) -> usize { reader.as_ref().unwrap().remaining() -} \ No newline at end of file +} From e2df814c1e4ebc5d8f79867a686ff0e1d63769c7 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 8 Apr 2024 14:46:40 +0200 Subject: [PATCH 28/75] make all references to z_buffer_t private --- include/zenoh_commons.h | 70 ++++++++++------------------------------- include/zenoh_macros.h | 22 ++++++------- src/payload.rs | 16 +++++----- 3 files changed, 35 insertions(+), 73 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 41129a653..4326d856f 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -203,22 +203,6 @@ typedef struct z_attachment_t { const void *data; z_attachment_iter_driver_t iteration_driver; } z_attachment_t; -/** - * A split buffer that owns all of its data. - * - * To minimize copies and reallocations, Zenoh may provide you data in split buffers. - */ -typedef struct ALIGN(8) z_owned_buffer_t { - uint8_t _0[40]; -} z_owned_buffer_t; -/** - * A loan of a `z_owned_buffer_t`. - * - * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. - */ -typedef struct z_buffer_t { - struct z_owned_buffer_t *_inner; -} z_buffer_t; typedef struct z_owned_bytes_t { uint8_t *start; size_t len; @@ -644,6 +628,14 @@ typedef struct z_owned_encoding_t { typedef struct z_query_consolidation_t { enum z_consolidation_mode_t mode; } z_query_consolidation_t; +/** + * A split buffer that owns all of its data. + * + * To minimize copies and reallocations, Zenoh may provide you data in split buffers. + */ +typedef struct ALIGN(8) z_owned_buffer_t { + uint8_t _0[40]; +} z_owned_buffer_t; /** * An owned payload, backed by a reference counted owner. * @@ -788,6 +780,14 @@ typedef struct z_query_reply_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_query_reply_options_t; +/** + * A loan of a `z_owned_buffer_t`. + * + * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. + */ +typedef struct z_buffer_t { + struct z_owned_buffer_t *_inner; +} z_buffer_t; typedef struct z_buffer_t zc_payload_t; /** * A zenoh value. @@ -1073,44 +1073,6 @@ ZENOHC_API size_t z_attachment_len(struct z_attachment_t this_); * Returns the gravestone value for `z_attachment_t`. */ ZENOHC_API struct z_attachment_t z_attachment_null(void); -/** - * Returns `true` if the buffer is in a valid state. - */ -ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); -/** - * Increments the buffer's reference count, returning an owned version of the buffer. - */ -ZENOHC_API struct z_owned_buffer_t z_buffer_clone(struct z_buffer_t buffer); -/** - * Decrements the buffer's reference counter, destroying it if applicable. - * - * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. - */ -ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); -/** - * Returns total number bytes in the buffer. - */ -ZENOHC_API size_t z_buffer_len(struct z_buffer_t buffer); -/** - * Loans the buffer, allowing you to call functions that only need a loan of it. - */ -ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); -/** - * The gravestone value for `z_owned_buffer_t`. - */ -ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); -/** - * Returns the `index`th slice of the buffer, aliasing it. - * - * Out of bounds accesses will return `z_bytes_empty`. - */ -ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); -/** - * Returns the number of slices in the buffer. - * - * If the return value is 0 or 1, then the buffer's data is contiguous in memory. - */ -ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index bb50476a5..815b2df85 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -14,7 +14,7 @@ z_owned_hello_t : z_hello_loan, \ z_owned_str_t : z_str_loan, \ z_owned_query_t : z_query_loan, \ - z_owned_buffer_t: z_buffer_loan, \ + zc_owned_payload_t : zc_payload_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan \ )(&x) @@ -43,7 +43,7 @@ z_owned_reply_channel_t * : z_reply_channel_drop, \ z_owned_query_channel_t * : z_query_channel_drop, \ z_owned_bytes_map_t * : z_bytes_map_drop, \ - z_owned_buffer_t * : z_buffer_drop, \ + zc_owned_payload_t * : zc_payload_drop, \ zc_owned_shmbuf_t * : zc_shmbuf_drop, \ zc_owned_shm_manager_t * : zc_shm_manager_drop, \ zc_owned_liveliness_token_t * : zc_liveliness_undeclare_token, \ @@ -74,7 +74,7 @@ z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ z_owned_reply_channel_t * : z_reply_channel_null, \ z_owned_bytes_map_t * : z_bytes_map_null, \ - z_owned_buffer_t * : z_buffer_null, \ + zc_owned_payload_t * : zc_payload_null, \ z_attachment_t * : z_attachment_null, \ zc_owned_shmbuf_t * : zc_shmbuf_null, \ zc_owned_shm_manager_t * : zc_shm_manager_null, \ @@ -89,7 +89,7 @@ z_keyexpr_t : z_keyexpr_is_initialized, \ z_owned_config_t : z_config_check, \ z_owned_scouting_config_t : z_scouting_config_check, \ - z_owned_bytes_t : z_bytes_check, \ + z_owned_bytes_t : z_bytes_check, \ z_owned_subscriber_t : z_subscriber_check, \ z_owned_pull_subscriber_t : z_pull_subscriber_check, \ z_owned_queryable_t : z_queryable_check, \ @@ -99,7 +99,7 @@ z_owned_query_t : z_query_check, \ z_owned_str_t : z_str_check, \ z_owned_bytes_map_t : z_bytes_map_check, \ - z_owned_buffer_t : z_buffer_check, \ + zc_owned_payload_t: zc_payload_check, \ z_attachment_t : z_attachment_check, \ zc_owned_shmbuf_t : zc_shmbuf_check, \ zc_owned_shm_manager_t : zc_shm_manager_check, \ @@ -142,7 +142,7 @@ template<> struct zenoh_loan_type{ typedef z_pull_sub template<> struct zenoh_loan_type{ typedef z_encoding_t type; }; template<> struct zenoh_loan_type{ typedef z_hello_t type; }; template<> struct zenoh_loan_type{ typedef const char* type; }; -template<> struct zenoh_loan_type{ typedef z_buffer_t type; }; +template<> struct zenoh_loan_type{ typedef zc_payload_t type; }; template<> struct zenoh_loan_type{ typedef ze_querying_subscriber_t type; }; template<> inline z_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } @@ -155,7 +155,7 @@ template<> inline z_encoding_t z_loan(const z_owned_encoding_t& x) { return z_en template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } -template<> inline z_buffer_t z_loan(const z_owned_buffer_t& x) { return z_buffer_loan(&x); } +template<> inline zc_payload_t z_loan(const zc_owned_payload& x) { return zc_payload_loan(&x); } template<> inline ze_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } template struct zenoh_drop_type { typedef T type; }; @@ -174,7 +174,7 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -204,7 +204,7 @@ template<> inline void z_drop(z_owned_reply_t* v) { z_reply_drop(v); } template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } template<> inline void z_drop(z_owned_query_t* v) { z_query_drop(v); } template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } -template<> inline void z_drop(z_owned_buffer_t* v) { z_buffer_drop(v); } +template<> inline void z_drop(zc_owned_payload* v) { zc_payload_drop(v); } template<> inline void z_drop(zc_owned_payload_t* v) { zc_payload_drop(v); } template<> inline void z_drop(zc_owned_shmbuf_t* v) { zc_shmbuf_drop(v); } template<> inline void z_drop(zc_owned_shm_manager_t* v) { zc_shm_manager_drop(v); } @@ -234,7 +234,7 @@ inline void z_null(z_owned_reply_t& v) { v = z_reply_null(); } inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } inline void z_null(z_owned_query_t& v) { v = z_query_null(); } inline void z_null(z_owned_str_t& v) { v = z_str_null(); } -inline void z_null(z_owned_buffer_t& v) { v = z_buffer_null(); } +inline void z_null(zc_owned_payload& v) { v = zc_payload_null(); } inline void z_null(zc_owned_payload_t& v) { v = zc_payload_null(); } inline void z_null(zc_owned_shmbuf_t& v) { v = zc_shmbuf_null(); } inline void z_null(zc_owned_shm_manager_t& v) { v = zc_shm_manager_null(); } @@ -269,7 +269,7 @@ inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } inline bool z_check(const z_owned_query_t& v) { return z_query_check(&v); } inline bool z_check(const z_owned_str_t& v) { return z_str_check(&v); } -inline bool z_check(const z_owned_buffer_t& v) { return z_buffer_check(&v); } +inline bool z_check(const zc_owned_payload& v) { return zc_payload_check(&v); } inline bool z_check(const z_owned_bytes_map_t& v) { return z_bytes_map_check(&v); } inline bool z_check(const z_attachment_t& v) { return z_attachment_check(&v); } inline bool z_check(const zc_owned_liveliness_token_t& v) { return zc_liveliness_token_check(&v); } diff --git a/src/payload.rs b/src/payload.rs index f7a737ef5..a1745ba36 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -28,7 +28,7 @@ impl From for z_owned_buffer_t { /// The gravestone value for `z_owned_buffer_t`. #[no_mangle] -pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { +extern "C" fn z_buffer_null() -> z_owned_buffer_t { None::.transmute() } @@ -36,19 +36,19 @@ pub extern "C" fn z_buffer_null() -> z_owned_buffer_t { /// /// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. #[no_mangle] -pub extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { +extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { core::mem::drop(buffer.take()) } /// Returns `true` if the buffer is in a valid state. #[no_mangle] -pub extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { +extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { buffer.is_some() } /// Loans the buffer, allowing you to call functions that only need a loan of it. #[no_mangle] -pub extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { +extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { buffer.as_ref().into() } @@ -78,7 +78,7 @@ impl From for Option<&'static ZBuf> { /// Increments the buffer's reference count, returning an owned version of the buffer. #[no_mangle] -pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { +extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { match buffer._inner { Some(b) => unsafe { b.as_ref().deref().clone().transmute() }, None => ZBuf::empty().into(), @@ -89,7 +89,7 @@ pub extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { /// /// If the return value is 0 or 1, then the buffer's data is contiguous in memory. #[no_mangle] -pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { +extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { match buffer.into() { None => 0, Some(buf) => ZBuf::slices(buf).len(), @@ -98,7 +98,7 @@ pub extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { /// Returns total number bytes in the buffer. #[no_mangle] -pub extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { +extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { match buffer.into() { None => 0, Some(buf) => ZBuf::slices(buf).fold(0, |acc, s| acc + s.len()), @@ -109,7 +109,7 @@ pub extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { /// /// Out of bounds accesses will return `z_bytes_empty`. #[no_mangle] -pub extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { +extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { match buffer.into() { None => z_bytes_empty(), Some(buf) => ZBuf::slices(buf) From 05401fed3b493641e5034453a760fbae7a6cba0a Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 8 Apr 2024 14:49:46 +0200 Subject: [PATCH 29/75] remove reference to z_buffer_t --- src/queryable.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/queryable.rs b/src/queryable.rs index c55820227..3c62fba4d 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -16,7 +16,7 @@ use crate::attachment::{ z_attachment_iterate, z_attachment_null, z_attachment_t, }; use crate::{ - impl_guarded_transmute, z_buffer_t, z_bytes_t, z_closure_query_call, z_encoding_default, + impl_guarded_transmute, zc_payload_t, z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, LOG_INVALID_SESSION, }; @@ -348,7 +348,7 @@ pub unsafe extern "C" fn z_query_value(query: &z_query_t) -> z_value_t { value.into() } None => z_value_t { - payload: z_buffer_t::default(), + payload: zc_payload_t::default(), encoding: z_encoding_default(), }, } From 7a94a55dc296673d49d65d756d9c6f0fcbb13b21 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 8 Apr 2024 14:56:56 +0200 Subject: [PATCH 30/75] fmt --- src/queryable.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/queryable.rs b/src/queryable.rs index 3c62fba4d..dd932188c 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -16,8 +16,8 @@ use crate::attachment::{ z_attachment_iterate, z_attachment_null, z_attachment_t, }; use crate::{ - impl_guarded_transmute, zc_payload_t, z_bytes_t, z_closure_query_call, z_encoding_default, - z_encoding_t, z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, + impl_guarded_transmute, z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, + z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, zc_payload_t, LOG_INVALID_SESSION, }; use libc::c_void; From 0275363057328894f013cf101c3d3c1fa9d202b2 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 8 Apr 2024 15:17:41 +0200 Subject: [PATCH 31/75] explicit zero-intialization --- tests/z_api_payload_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/z_api_payload_test.c b/tests/z_api_payload_test.c index d2d5da4d4..10b1a3177 100644 --- a/tests/z_api_payload_test.c +++ b/tests/z_api_payload_test.c @@ -23,7 +23,7 @@ void test_reader() { uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - uint8_t data_out[10] = {}; + uint8_t data_out[10] = {0}; z_bytes_t bytes = {.start = data, .len = 10 }; zc_owned_payload_t payload = zc_payload_encode_from_bytes(bytes); From 78c84aa2148c6c83714c4f248d23fb63009c898d Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 8 Apr 2024 22:41:57 +0200 Subject: [PATCH 32/75] relinked to explicit_api2, QoS removed --- Cargo.lock | 226 +++++++++++++++++++++++++++------------- Cargo.toml | 10 +- Cargo.toml.in | 10 +- include/zenoh_commons.h | 99 ++++++++++-------- src/commons.rs | 49 ++------- 5 files changed, 227 insertions(+), 167 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7d52c4ed7..d4fb64d25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -259,7 +259,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -383,9 +383,9 @@ checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" [[package]] name = "cbindgen" -version = "0.24.5" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b922faaf31122819ec80c4047cc684c6979a087366c069611e33649bf98e18d" +checksum = "da6bc11b07529f16944307272d5bd9b22530bc7d05751717c9d416586cedab49" dependencies = [ "clap", "heck", @@ -802,7 +802,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -898,6 +898,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + [[package]] name = "hashbrown" version = "0.12.3" @@ -1087,6 +1093,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "iter-read" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c397ca3ea05ad509c4ec451fea28b4771236a376ca1c69fd5143aae0cf8f93c4" + [[package]] name = "itoa" version = "1.0.9" @@ -1285,6 +1297,17 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-bigint-dig" version = "0.8.4" @@ -1443,7 +1466,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -1467,6 +1490,48 @@ dependencies = [ "indexmap 2.0.0", ] +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.58", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1562,9 +1627,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -1619,9 +1684,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -2007,22 +2072,45 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] +[[package]] +name = "serde-pickle" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762ad136a26407c6a80825813600ceeab5e613660d93d79a41f0ec877171e71" +dependencies = [ + "byteorder", + "iter-read", + "num-bigint", + "num-traits", + "serde", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -2038,9 +2126,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", @@ -2143,6 +2231,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -2246,9 +2340,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.33" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -2299,7 +2393,7 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -2351,7 +2445,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -2432,7 +2526,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] @@ -2662,7 +2756,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", "wasm-bindgen-shared", ] @@ -2696,7 +2790,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2953,7 +3047,7 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "base64", @@ -2969,11 +3063,15 @@ dependencies = [ "ordered-float", "paste", "petgraph", + "phf", "rand", "regex", "rustc_version", "serde", + "serde-pickle", + "serde_cbor", "serde_json", + "serde_yaml", "socket2 0.5.6", "stop-token", "tokio", @@ -2996,7 +3094,6 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", - "zenoh-task", "zenoh-transport", "zenoh-util", ] @@ -3004,7 +3101,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "zenoh-collections", ] @@ -3037,7 +3134,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "log", "serde", @@ -3050,12 +3147,12 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "flume", "json5", @@ -3075,7 +3172,7 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-global-executor", "lazy_static", @@ -3087,7 +3184,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "aes", "hmac", @@ -3100,29 +3197,25 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "bincode", "env_logger 0.11.2", "flume", "futures", "log", + "phf", "serde", + "serde_cbor", + "serde_json", "tokio", "zenoh", - "zenoh-core", - "zenoh-macros", - "zenoh-result", - "zenoh-runtime", - "zenoh-sync", - "zenoh-task", - "zenoh-util", ] [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "hashbrown 0.14.0", "keyed-set", @@ -3136,7 +3229,7 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "zenoh-config", @@ -3154,7 +3247,7 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "flume", @@ -3177,7 +3270,7 @@ dependencies = [ [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "base64", @@ -3205,7 +3298,7 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "log", @@ -3223,7 +3316,7 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "base64", @@ -3251,7 +3344,7 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "log", @@ -3272,7 +3365,7 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "futures", @@ -3292,7 +3385,7 @@ dependencies = [ [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "futures-util", @@ -3313,18 +3406,18 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", "zenoh-keyexpr", ] [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "const_format", "libloading", @@ -3340,7 +3433,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "const_format", "rand", @@ -3354,7 +3447,7 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "anyhow", ] @@ -3362,9 +3455,8 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ - "futures", "lazy_static", "tokio", "zenoh-collections", @@ -3374,7 +3466,7 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "log", "serde", @@ -3386,7 +3478,7 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "event-listener 4.0.0", "futures", @@ -3397,23 +3489,10 @@ dependencies = [ "zenoh-runtime", ] -[[package]] -name = "zenoh-task" -version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" -dependencies = [ - "futures", - "log", - "tokio", - "tokio-util", - "zenoh-core", - "zenoh-runtime", -] - [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "flume", @@ -3439,14 +3518,13 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", - "zenoh-task", "zenoh-util", ] [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#02d4783042d50110ccfb79aada420ff5231ae840" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-std", "async-trait", @@ -3482,7 +3560,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.33", + "syn 2.0.58", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 8e0541888..f515f3b10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,13 +51,13 @@ log = "0.4.17" rand = "0.8.5" spin = "0.9.5" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } [build-dependencies] -cbindgen = "0.24.3" +cbindgen = "0.26.0" fs2 = "0.4.3" regex = "1.7.1" serde_yaml = "0.9.19" diff --git a/Cargo.toml.in b/Cargo.toml.in index a8123bcd5..16ea65bf8 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -51,13 +51,13 @@ log = "0.4.17" rand = "0.8.5" spin = "0.9.5" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } [build-dependencies] -cbindgen = "0.24.3" +cbindgen = "0.26.0" fs2 = "0.4.3" regex = "1.7.1" serde_yaml = "0.9.19" diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 4326d856f..a9a95cc1c 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -203,6 +203,22 @@ typedef struct z_attachment_t { const void *data; z_attachment_iter_driver_t iteration_driver; } z_attachment_t; +/** + * A split buffer that owns all of its data. + * + * To minimize copies and reallocations, Zenoh may provide you data in split buffers. + */ +typedef struct ALIGN(8) z_owned_buffer_t { + uint8_t _0[40]; +} z_owned_buffer_t; +/** + * A loan of a `z_owned_buffer_t`. + * + * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. + */ +typedef struct z_buffer_t { + struct z_owned_buffer_t *_inner; +} z_buffer_t; typedef struct z_owned_bytes_t { uint8_t *start; size_t len; @@ -628,14 +644,6 @@ typedef struct z_owned_encoding_t { typedef struct z_query_consolidation_t { enum z_consolidation_mode_t mode; } z_query_consolidation_t; -/** - * A split buffer that owns all of its data. - * - * To minimize copies and reallocations, Zenoh may provide you data in split buffers. - */ -typedef struct ALIGN(8) z_owned_buffer_t { - uint8_t _0[40]; -} z_owned_buffer_t; /** * An owned payload, backed by a reference counted owner. * @@ -736,13 +744,6 @@ typedef struct z_put_options_t { enum z_priority_t priority; struct z_attachment_t attachment; } z_put_options_t; -/** - * QoS settings of zenoh message. - * - */ -typedef struct z_qos_t { - uint8_t _0; -} z_qos_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -780,14 +781,6 @@ typedef struct z_query_reply_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_query_reply_options_t; -/** - * A loan of a `z_owned_buffer_t`. - * - * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. - */ -typedef struct z_buffer_t { - struct z_owned_buffer_t *_inner; -} z_buffer_t; typedef struct z_buffer_t zc_payload_t; /** * A zenoh value. @@ -1073,6 +1066,44 @@ ZENOHC_API size_t z_attachment_len(struct z_attachment_t this_); * Returns the gravestone value for `z_attachment_t`. */ ZENOHC_API struct z_attachment_t z_attachment_null(void); +/** + * Returns `true` if the buffer is in a valid state. + */ +ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); +/** + * Increments the buffer's reference count, returning an owned version of the buffer. + */ +ZENOHC_API struct z_owned_buffer_t z_buffer_clone(struct z_buffer_t buffer); +/** + * Decrements the buffer's reference counter, destroying it if applicable. + * + * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. + */ +ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); +/** + * Returns total number bytes in the buffer. + */ +ZENOHC_API size_t z_buffer_len(struct z_buffer_t buffer); +/** + * Loans the buffer, allowing you to call functions that only need a loan of it. + */ +ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); +/** + * The gravestone value for `z_owned_buffer_t`. + */ +ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); +/** + * Returns the `index`th slice of the buffer, aliasing it. + * + * Out of bounds accesses will return `z_bytes_empty`. + */ +ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); +/** + * Returns the number of slices in the buffer. + * + * If the return value is 0 or 1, then the buffer's data is contiguous in memory. + */ +ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. */ @@ -1845,22 +1876,6 @@ int8_t z_put(struct z_session_t session, * Constructs the default value for :c:type:`z_put_options_t`. */ ZENOHC_API struct z_put_options_t z_put_options_default(void); -/** - * Returns default qos settings. - */ -ZENOHC_API struct z_qos_t z_qos_default(void); -/** - * Returns message congestion control. - */ -ZENOHC_API enum z_congestion_control_t z_qos_get_congestion_control(struct z_qos_t qos); -/** - * Returns message express flag. If set to true, the message is not batched to reduce the latency. - */ -ZENOHC_API bool z_qos_get_express(struct z_qos_t qos); -/** - * Returns message priority. - */ -ZENOHC_API enum z_priority_t z_qos_get_priority(struct z_qos_t qos); /** * Returns the attachment to the query by aliasing. * @@ -2064,6 +2079,8 @@ ZENOHC_API struct z_owned_reply_t z_reply_null(void); ZENOHC_API struct z_sample_t z_reply_ok(const struct z_owned_reply_t *reply); /** + * The qos with which the sample was received. + * TODO: split to methods (priority, congestion_control, express) * The sample's attachment. * * `sample` is aliased by the return value. @@ -2096,10 +2113,6 @@ ZENOHC_API zc_owned_payload_t z_sample_owned_payload(const struct z_sample_t *sa * If you need ownership of the buffer, you may use `z_sample_owned_payload`. */ ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); -/** - * The qos with which the sample was received. - */ -ZENOHC_API struct z_qos_t z_sample_qos(const struct z_sample_t *sample); /** * The samples timestamp */ diff --git a/src/commons.rs b/src/commons.rs index ed0f9dbf0..9031d6628 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -27,7 +27,6 @@ use libc::{c_char, c_ulong}; use zenoh::prelude::SampleKind; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; -use zenoh::sample::QoS; use zenoh::sample::Sample; use zenoh_protocol::core::Timestamp; @@ -92,34 +91,6 @@ impl From> for z_timestamp_t { } } -/// QoS settings of zenoh message. -/// -#[repr(C)] -pub struct z_qos_t(u8); - -impl_guarded_transmute!(QoS, z_qos_t); - -/// Returns message priority. -#[no_mangle] -pub extern "C" fn z_qos_get_priority(qos: z_qos_t) -> z_priority_t { - qos.transmute().priority().into() -} -/// Returns message congestion control. -#[no_mangle] -pub extern "C" fn z_qos_get_congestion_control(qos: z_qos_t) -> z_congestion_control_t { - qos.transmute().congestion_control().into() -} -/// Returns message express flag. If set to true, the message is not batched to reduce the latency. -#[no_mangle] -pub extern "C" fn z_qos_get_express(qos: z_qos_t) -> bool { - qos.transmute().express() -} -/// Returns default qos settings. -#[no_mangle] -pub extern "C" fn z_qos_default() -> z_qos_t { - QoS::default().transmute() -} - /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. @@ -147,19 +118,19 @@ impl<'a> z_sample_t<'a> { /// `sample` is aliased by its return value. #[no_mangle] pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { - (&sample.key_expr).into() + sample.key_expr().into() } /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { - (&sample.encoding).into() + sample.encoding().into() } /// The sample's data, the return value aliases the sample. /// /// If you need ownership of the buffer, you may use `z_sample_owned_payload`. #[no_mangle] pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { - Some(&sample.payload).into() + sample.payload().into() } /// Returns the sample's payload after incrementing its internal reference count. /// @@ -167,29 +138,27 @@ pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { /// affect the samples received by other subscribers. #[no_mangle] pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { - sample.payload.clone().into() + sample.payload().clone().into() } /// The sample's kind (put or delete). #[no_mangle] pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { - sample.kind.into() + sample.kind().into() } /// The samples timestamp #[no_mangle] pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { - sample.timestamp.as_ref().into() + sample.timestamp().into() } /// The qos with which the sample was received. -#[no_mangle] -pub extern "C" fn z_sample_qos(sample: &z_sample_t) -> z_qos_t { - sample.qos.into() -} +/// TODO: split to methods (priority, congestion_control, express) + /// The sample's attachment. /// /// `sample` is aliased by the return value. #[no_mangle] pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { - match &sample.attachment { + match sample.attachment() { Some(attachment) => z_attachment_t { data: attachment as *const _ as *mut c_void, iteration_driver: Some(attachment_iteration_driver), From ef031b34e37045b3aa6ed3f78bb420a21d33258d Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 9 Apr 2024 17:34:04 +0200 Subject: [PATCH 33/75] commons.rs compiles --- Cargo.lock | 33 ++--- Cargo.toml | 16 ++- Cargo.toml.in | 14 ++- include/zenoh_commons.h | 102 +++++---------- src/commons.rs | 269 +++++++--------------------------------- src/get.rs | 2 +- src/payload.rs | 6 +- src/publisher.rs | 9 +- 8 files changed, 113 insertions(+), 338 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4fb64d25..16f5478f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2638,6 +2638,12 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "unzip-n" version = "0.1.2" @@ -3047,7 +3053,6 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "base64", @@ -3101,7 +3106,6 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "zenoh-collections", ] @@ -3125,6 +3129,7 @@ dependencies = [ "regex", "serde_yaml", "spin 0.9.8", + "unwrap-infallible", "zenoh", "zenoh-ext", "zenoh-protocol", @@ -3134,7 +3139,6 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "log", "serde", @@ -3147,12 +3151,10 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "flume", "json5", @@ -3172,7 +3174,6 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-global-executor", "lazy_static", @@ -3184,7 +3185,6 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "aes", "hmac", @@ -3197,7 +3197,6 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "bincode", "env_logger 0.11.2", @@ -3215,7 +3214,6 @@ dependencies = [ [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "hashbrown 0.14.0", "keyed-set", @@ -3229,7 +3227,6 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "zenoh-config", @@ -3247,7 +3244,6 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "flume", @@ -3270,7 +3266,6 @@ dependencies = [ [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "base64", @@ -3298,7 +3293,6 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "log", @@ -3316,7 +3310,6 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "base64", @@ -3344,7 +3337,6 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "log", @@ -3365,7 +3357,6 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "futures", @@ -3385,7 +3376,6 @@ dependencies = [ [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "futures-util", @@ -3406,7 +3396,6 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "proc-macro2", "quote", @@ -3417,7 +3406,6 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "const_format", "libloading", @@ -3433,7 +3421,6 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "const_format", "rand", @@ -3447,7 +3434,6 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "anyhow", ] @@ -3455,7 +3441,6 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "lazy_static", "tokio", @@ -3466,7 +3451,6 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "log", "serde", @@ -3478,7 +3462,6 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "event-listener 4.0.0", "futures", @@ -3492,7 +3475,6 @@ dependencies = [ [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-trait", "flume", @@ -3524,7 +3506,6 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#182eb3a7d9a0422f6d67a1bf0696468d1a486b9a" dependencies = [ "async-std", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index f515f3b10..34366e392 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,11 +50,17 @@ libc = "0.2.139" log = "0.4.17" rand = "0.8.5" spin = "0.9.5" +unwrap-infallible = "0.1.5" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } +#zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +#zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } +#zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } +#zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } + +zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } +zenoh-util = { path = "../zenoh/commons/zenoh-util" } +zenoh-ext = { path = "../zenoh/zenoh-ext" } [build-dependencies] cbindgen = "0.26.0" @@ -64,7 +70,7 @@ serde_yaml = "0.9.19" [lib] path="src/lib.rs" -name = "zenohc" +name = "zenohcd" crate-type = ["cdylib", "staticlib"] doctest = false diff --git a/Cargo.toml.in b/Cargo.toml.in index 16ea65bf8..d31b3d0c6 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -50,11 +50,17 @@ libc = "0.2.139" log = "0.4.17" rand = "0.8.5" spin = "0.9.5" +unwrap-infallible = "0.1.5" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } +#zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +#zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } +#zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } +#zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } + +zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } +zenoh-util = { path = "../zenoh/commons/zenoh-util" } +zenoh-ext = { path = "../zenoh/zenoh-ext" } [build-dependencies] cbindgen = "0.26.0" diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index a9a95cc1c..9e4693788 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -45,54 +45,6 @@ typedef enum z_consolidation_mode_t { Z_CONSOLIDATION_MODE_MONOTONIC = 1, Z_CONSOLIDATION_MODE_LATEST = 2, } z_consolidation_mode_t; -/** - * A :c:type:`z_encoding_t` integer `prefix`. - * - * - **Z_ENCODING_PREFIX_EMPTY** - * - **Z_ENCODING_PREFIX_APP_OCTET_STREAM** - * - **Z_ENCODING_PREFIX_APP_CUSTOM** - * - **Z_ENCODING_PREFIX_TEXT_PLAIN** - * - **Z_ENCODING_PREFIX_APP_PROPERTIES** - * - **Z_ENCODING_PREFIX_APP_JSON** - * - **Z_ENCODING_PREFIX_APP_SQL** - * - **Z_ENCODING_PREFIX_APP_INTEGER** - * - **Z_ENCODING_PREFIX_APP_FLOAT** - * - **Z_ENCODING_PREFIX_APP_XML** - * - **Z_ENCODING_PREFIX_APP_XHTML_XML** - * - **Z_ENCODING_PREFIX_APP_X_WWW_FORM_URLENCODED** - * - **Z_ENCODING_PREFIX_TEXT_JSON** - * - **Z_ENCODING_PREFIX_TEXT_HTML** - * - **Z_ENCODING_PREFIX_TEXT_XML** - * - **Z_ENCODING_PREFIX_TEXT_CSS** - * - **Z_ENCODING_PREFIX_TEXT_CSV** - * - **Z_ENCODING_PREFIX_TEXT_JAVASCRIPT** - * - **Z_ENCODING_PREFIX_IMAGE_JPEG** - * - **Z_ENCODING_PREFIX_IMAGE_PNG** - * - **Z_ENCODING_PREFIX_IMAGE_GIF** - */ -typedef enum z_encoding_prefix_t { - Z_ENCODING_PREFIX_EMPTY = 0, - Z_ENCODING_PREFIX_APP_OCTET_STREAM = 1, - Z_ENCODING_PREFIX_APP_CUSTOM = 2, - Z_ENCODING_PREFIX_TEXT_PLAIN = 3, - Z_ENCODING_PREFIX_APP_PROPERTIES = 4, - Z_ENCODING_PREFIX_APP_JSON = 5, - Z_ENCODING_PREFIX_APP_SQL = 6, - Z_ENCODING_PREFIX_APP_INTEGER = 7, - Z_ENCODING_PREFIX_APP_FLOAT = 8, - Z_ENCODING_PREFIX_APP_XML = 9, - Z_ENCODING_PREFIX_APP_XHTML_XML = 10, - Z_ENCODING_PREFIX_APP_X_WWW_FORM_URLENCODED = 11, - Z_ENCODING_PREFIX_TEXT_JSON = 12, - Z_ENCODING_PREFIX_TEXT_HTML = 13, - Z_ENCODING_PREFIX_TEXT_XML = 14, - Z_ENCODING_PREFIX_TEXT_CSS = 15, - Z_ENCODING_PREFIX_TEXT_CSV = 16, - Z_ENCODING_PREFIX_TEXT_JAVASCRIPT = 17, - Z_ENCODING_PREFIX_IMAGE_JPEG = 18, - Z_ENCODING_PREFIX_IMAGE_PNG = 19, - Z_ENCODING_PREFIX_IMAGE_GIF = 20, -} z_encoding_prefix_t; /** * A :c:type:`z_keyexpr_intersection_level_t`. * @@ -607,37 +559,41 @@ typedef struct z_delete_options_t { enum z_congestion_control_t congestion_control; enum z_priority_t priority; } z_delete_options_t; -/** - * The encoding of a payload, in a MIME-like format. - * - * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. - * - * Members: - * z_encoding_prefix_t prefix: The integer prefix of this encoding. - * z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. - */ -typedef struct z_encoding_t { - enum z_encoding_prefix_t prefix; - struct z_bytes_t suffix; -} z_encoding_t; /** * An owned payload encoding. * - * Members: - * z_encoding_prefix_t prefix: The integer prefix of this encoding. - * z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. - * * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. * * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. */ -typedef struct z_owned_encoding_t { - enum z_encoding_prefix_t prefix; - struct z_owned_bytes_t suffix; - bool _dropped; +#if !defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_owned_encoding_t { + uint64_t _0[4]; } z_owned_encoding_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(4) z_owned_encoding_t { + uint32_t _0[4]; +} z_owned_encoding_t; +#endif +/** + * The encoding of a payload, in a MIME-like format. + * + * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. + * + */ +#if !defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_encoding_t { + uint64_t _0[4]; +} z_encoding_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(4) z_encoding_t { + uint32_t _0[4]; +} z_encoding_t; +#endif /** * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. */ @@ -1527,10 +1483,6 @@ int8_t z_delete(struct z_session_t session, * Constructs the default value for :c:type:`z_put_options_t`. */ ZENOHC_API struct z_delete_options_t z_delete_options_default(void); -/** - * Constructs a specific :c:type:`z_encoding_t`. - */ -ZENOHC_API struct z_encoding_t z_encoding(enum z_encoding_prefix_t prefix, const char *suffix); /** * Returns ``true`` if `encoding` is valid. */ @@ -1543,6 +1495,10 @@ ZENOHC_API struct z_encoding_t z_encoding_default(void); * Frees `encoding`, invalidating it for double-drop safety. */ ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); +/** + * Constructs a specific :c:type:`z_encoding_t`. + */ +ZENOHC_API struct z_owned_encoding_t z_encoding_from_str(const char *s); /** * Returns a :c:type:`z_encoding_t` loaned from `encoding`. */ diff --git a/src/commons.rs b/src/commons.rs index 9031d6628..0fb284322 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -12,23 +12,31 @@ // ZettaScale Zenoh team, // +use std::ffi::CStr; use std::ops::Deref; use crate::collections::*; use crate::keyexpr::*; use crate::z_congestion_control_t; use crate::z_id_t; +use crate::z_owned_buffer_t; use crate::z_priority_t; use crate::zc_owned_payload_t; use crate::zc_payload_t; use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; +use zenoh::buffers::ZBuf; +use zenoh::encoding::Encoding; +use zenoh::payload::Deserialize; +use zenoh::payload::ZSerde; use zenoh::prelude::SampleKind; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; use zenoh::sample::Sample; use zenoh_protocol::core::Timestamp; +use unwrap_infallible::UnwrapInfallible; +use std::convert::Infallible; use crate::attachment::{attachment_iteration_driver, z_attachment_null, z_attachment_t}; @@ -123,22 +131,30 @@ pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { - sample.encoding().into() + Some(sample.encoding()).into() } /// The sample's data, the return value aliases the sample. /// /// If you need ownership of the buffer, you may use `z_sample_owned_payload`. #[no_mangle] pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { - sample.payload().into() + // TODO: here returning reference not to sample's payload, but to temporary copy + // THIS WILL CRASH FOR SURE, MADE IT ONLY TO MAKE IT COMPILE + // Need a way to get reference to sample's payload + let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); + let owned_buffer: z_owned_buffer_t = Some(buffer).into(); + owned_buffer.as_ref().into() } + /// Returns the sample's payload after incrementing its internal reference count. /// /// Note that other samples may have received the same buffer, meaning that mutating this buffer may /// affect the samples received by other subscribers. #[no_mangle] pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { - sample.payload().clone().into() + let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); + let owned_buffer: z_owned_buffer_t = Some(buffer).into(); + owned_buffer.into() } /// The sample's kind (put or delete). #[no_mangle] @@ -204,273 +220,82 @@ pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { None.into() } -/// A :c:type:`z_encoding_t` integer `prefix`. -/// -/// - **Z_ENCODING_PREFIX_EMPTY** -/// - **Z_ENCODING_PREFIX_APP_OCTET_STREAM** -/// - **Z_ENCODING_PREFIX_APP_CUSTOM** -/// - **Z_ENCODING_PREFIX_TEXT_PLAIN** -/// - **Z_ENCODING_PREFIX_APP_PROPERTIES** -/// - **Z_ENCODING_PREFIX_APP_JSON** -/// - **Z_ENCODING_PREFIX_APP_SQL** -/// - **Z_ENCODING_PREFIX_APP_INTEGER** -/// - **Z_ENCODING_PREFIX_APP_FLOAT** -/// - **Z_ENCODING_PREFIX_APP_XML** -/// - **Z_ENCODING_PREFIX_APP_XHTML_XML** -/// - **Z_ENCODING_PREFIX_APP_X_WWW_FORM_URLENCODED** -/// - **Z_ENCODING_PREFIX_TEXT_JSON** -/// - **Z_ENCODING_PREFIX_TEXT_HTML** -/// - **Z_ENCODING_PREFIX_TEXT_XML** -/// - **Z_ENCODING_PREFIX_TEXT_CSS** -/// - **Z_ENCODING_PREFIX_TEXT_CSV** -/// - **Z_ENCODING_PREFIX_TEXT_JAVASCRIPT** -/// - **Z_ENCODING_PREFIX_IMAGE_JPEG** -/// - **Z_ENCODING_PREFIX_IMAGE_PNG** -/// - **Z_ENCODING_PREFIX_IMAGE_GIF** -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(C)] -pub enum z_encoding_prefix_t { - Empty = 0, - AppOctetStream = 1, - AppCustom = 2, - TextPlain = 3, - AppProperties = 4, - AppJson = 5, - AppSql = 6, - AppInteger = 7, - AppFloat = 8, - AppXml = 9, - AppXhtmlXml = 10, - AppXWwwFormUrlencoded = 11, - TextJson = 12, - TextHtml = 13, - TextXml = 14, - TextCss = 15, - TextCsv = 16, - TextJavascript = 17, - ImageJpeg = 18, - ImagePng = 19, - ImageGif = 20, -} - -impl From for zenoh_protocol::core::KnownEncoding { - fn from(val: z_encoding_prefix_t) -> Self { - if cfg!(debug_assertions) { - match val { - z_encoding_prefix_t::Empty => zenoh_protocol::core::KnownEncoding::Empty, - z_encoding_prefix_t::AppOctetStream => { - zenoh_protocol::core::KnownEncoding::AppOctetStream - } - z_encoding_prefix_t::AppCustom => zenoh_protocol::core::KnownEncoding::AppCustom, - z_encoding_prefix_t::TextPlain => zenoh_protocol::core::KnownEncoding::TextPlain, - z_encoding_prefix_t::AppProperties => { - zenoh_protocol::core::KnownEncoding::AppProperties - } - z_encoding_prefix_t::AppJson => zenoh_protocol::core::KnownEncoding::AppJson, - z_encoding_prefix_t::AppSql => zenoh_protocol::core::KnownEncoding::AppSql, - z_encoding_prefix_t::AppInteger => zenoh_protocol::core::KnownEncoding::AppInteger, - z_encoding_prefix_t::AppFloat => zenoh_protocol::core::KnownEncoding::AppFloat, - z_encoding_prefix_t::AppXml => zenoh_protocol::core::KnownEncoding::AppXml, - z_encoding_prefix_t::AppXhtmlXml => { - zenoh_protocol::core::KnownEncoding::AppXhtmlXml - } - z_encoding_prefix_t::AppXWwwFormUrlencoded => { - zenoh_protocol::core::KnownEncoding::AppXWwwFormUrlencoded - } - z_encoding_prefix_t::TextJson => zenoh_protocol::core::KnownEncoding::TextJson, - z_encoding_prefix_t::TextHtml => zenoh_protocol::core::KnownEncoding::TextHtml, - z_encoding_prefix_t::TextXml => zenoh_protocol::core::KnownEncoding::TextXml, - z_encoding_prefix_t::TextCss => zenoh_protocol::core::KnownEncoding::TextCss, - z_encoding_prefix_t::TextCsv => zenoh_protocol::core::KnownEncoding::TextCsv, - z_encoding_prefix_t::TextJavascript => { - zenoh_protocol::core::KnownEncoding::TextJavascript - } - z_encoding_prefix_t::ImageJpeg => zenoh_protocol::core::KnownEncoding::ImageJpeg, - z_encoding_prefix_t::ImagePng => zenoh_protocol::core::KnownEncoding::ImagePng, - z_encoding_prefix_t::ImageGif => zenoh_protocol::core::KnownEncoding::ImageGif, - } - } else { - unsafe { std::mem::transmute(val as u8) } - } - } -} - -impl From for z_encoding_prefix_t { - fn from(val: zenoh_protocol::core::KnownEncoding) -> Self { - if cfg!(debug_assertions) { - match val { - zenoh_protocol::core::KnownEncoding::Empty => z_encoding_prefix_t::Empty, - zenoh_protocol::core::KnownEncoding::AppOctetStream => { - z_encoding_prefix_t::AppOctetStream - } - zenoh_protocol::core::KnownEncoding::AppCustom => z_encoding_prefix_t::AppCustom, - zenoh_protocol::core::KnownEncoding::TextPlain => z_encoding_prefix_t::TextPlain, - zenoh_protocol::core::KnownEncoding::AppProperties => { - z_encoding_prefix_t::AppProperties - } - zenoh_protocol::core::KnownEncoding::AppJson => z_encoding_prefix_t::AppJson, - zenoh_protocol::core::KnownEncoding::AppSql => z_encoding_prefix_t::AppSql, - zenoh_protocol::core::KnownEncoding::AppInteger => z_encoding_prefix_t::AppInteger, - zenoh_protocol::core::KnownEncoding::AppFloat => z_encoding_prefix_t::AppFloat, - zenoh_protocol::core::KnownEncoding::AppXml => z_encoding_prefix_t::AppXml, - zenoh_protocol::core::KnownEncoding::AppXhtmlXml => { - z_encoding_prefix_t::AppXhtmlXml - } - zenoh_protocol::core::KnownEncoding::AppXWwwFormUrlencoded => { - z_encoding_prefix_t::AppXWwwFormUrlencoded - } - zenoh_protocol::core::KnownEncoding::TextJson => z_encoding_prefix_t::TextJson, - zenoh_protocol::core::KnownEncoding::TextHtml => z_encoding_prefix_t::TextHtml, - zenoh_protocol::core::KnownEncoding::TextXml => z_encoding_prefix_t::TextXml, - zenoh_protocol::core::KnownEncoding::TextCss => z_encoding_prefix_t::TextCss, - zenoh_protocol::core::KnownEncoding::TextCsv => z_encoding_prefix_t::TextCsv, - zenoh_protocol::core::KnownEncoding::TextJavascript => { - z_encoding_prefix_t::TextJavascript - } - zenoh_protocol::core::KnownEncoding::ImageJpeg => z_encoding_prefix_t::ImageJpeg, - zenoh_protocol::core::KnownEncoding::ImagePng => z_encoding_prefix_t::ImagePng, - zenoh_protocol::core::KnownEncoding::ImageGif => z_encoding_prefix_t::ImageGif, - } - } else { - unsafe { std::mem::transmute(val as u32) } - } - } -} - /// The encoding of a payload, in a MIME-like format. /// /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. /// -/// Members: -/// z_encoding_prefix_t prefix: The integer prefix of this encoding. -/// z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. -#[repr(C)] -#[derive(Clone, Copy, Debug)] -pub struct z_encoding_t { - pub prefix: z_encoding_prefix_t, - pub suffix: z_bytes_t, -} +#[cfg(not(target_arch = "arm"))] +#[repr(C, align(8))] +pub struct z_encoding_t([u64; 4]); -impl From for zenoh_protocol::core::Encoding { - fn from(enc: z_encoding_t) -> Self { - if enc.suffix.len == 0 { - zenoh_protocol::core::Encoding::Exact(enc.prefix.into()) - } else { - let suffix = unsafe { - let slice: &'static [u8] = - std::slice::from_raw_parts(enc.suffix.start, enc.suffix.len); - std::str::from_utf8_unchecked(slice) - }; - zenoh_protocol::core::Encoding::WithSuffix(enc.prefix.into(), suffix.into()) - } - } -} +#[cfg(target_arch = "arm")] +#[repr(C, align(4))] +pub struct z_encoding_t([u32; 4]); -impl From<&zenoh_protocol::core::Encoding> for z_encoding_t { - fn from(val: &zenoh_protocol::core::Encoding) -> Self { - let suffix = val.suffix(); - z_encoding_t { - prefix: (*val.prefix()).into(), - suffix: z_bytes_t { - start: suffix.as_ptr(), - len: suffix.len(), - }, - } - } -} +impl_guarded_transmute!(Option<&'static Encoding>, z_encoding_t); /// An owned payload encoding. /// -/// Members: -/// z_encoding_prefix_t prefix: The integer prefix of this encoding. -/// z_bytes_t suffix: The suffix of this encoding. `suffix` MUST be a valid UTF-8 string. -/// /// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. /// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -#[repr(C)] -pub struct z_owned_encoding_t { - pub prefix: z_encoding_prefix_t, - pub suffix: z_owned_bytes_t, - pub _dropped: bool, -} - -impl z_owned_encoding_t { - pub fn null() -> Self { - z_owned_encoding_t { - prefix: z_encoding_prefix_t::Empty, - suffix: z_bytes_null(), - _dropped: true, - } - } -} +#[cfg(not(target_arch = "arm"))] +#[repr(C, align(8))] +pub struct z_owned_encoding_t([u64; 4]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(4))] +pub struct z_owned_encoding_t([u32; 4]); + +impl_guarded_transmute!(Option, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] pub extern "C" fn z_encoding_null() -> z_owned_encoding_t { - z_owned_encoding_t::null() + None::.into() } /// Constructs a specific :c:type:`z_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_encoding( - prefix: z_encoding_prefix_t, - suffix: *const c_char, -) -> z_encoding_t { - let suffix = if suffix.is_null() { - z_bytes_t::empty() +pub unsafe extern "C" fn z_encoding_from_str(s: *const c_char) -> z_owned_encoding_t { + if s.is_null() { + z_encoding_null() } else { - z_bytes_t { - start: suffix as *const u8, - len: libc::strlen(suffix), - } - }; - z_encoding_t { prefix, suffix } + let s = CStr::from_ptr(s).to_string_lossy().as_ref(); + Some(Encoding::from(s)).into() + } } /// Constructs a default :c:type:`z_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - (&zenoh_protocol::core::Encoding::default()).into() + let encoding = Some(&Encoding::default()); + encoding.into() } /// Frees `encoding`, invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - z_bytes_drop(&mut encoding.suffix); - encoding._dropped = true + std::mem::drop(encoding.take()); } /// Returns ``true`` if `encoding` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { - !encoding._dropped + encoding.is_some() } /// Returns a :c:type:`z_encoding_t` loaned from `encoding`. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> z_encoding_t { - z_encoding_t { - prefix: encoding.prefix, - suffix: z_bytes_loan(&encoding.suffix), - } -} - -impl From for z_owned_encoding_t { - fn from(val: z_encoding_t) -> Self { - z_owned_encoding_t { - prefix: val.prefix, - suffix: z_bytes_clone(&val.suffix), - _dropped: false, - } - } + encoding.as_ref().into() } /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` diff --git a/src/get.rs b/src/get.rs index 3e9e4ded4..065b9aba9 100644 --- a/src/get.rs +++ b/src/get.rs @@ -215,7 +215,7 @@ pub unsafe extern "C" fn z_get( if let Some(payload) = options.payload.take() { let mut value = Value::new(payload); - value = value.encoding(options.encoding.into()); + value.encoding = options.encoding.into(); q = q.with_value(value); } if options.timeout_ms != 0 { diff --git a/src/payload.rs b/src/payload.rs index a1745ba36..fa6603de6 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -2,10 +2,10 @@ use core::slice; use std::slice::from_raw_parts_mut; use std::{any::Any, ops::Deref, ptr::NonNull}; -use zenoh::buffers::reader::HasReader; -use zenoh::buffers::reader::Reader; +use zenoh::buffers::HasReader; +use zenoh::buffers::Reader; use zenoh::buffers::ZBufReader; -use zenoh::buffers::{buffer::SplitBuffer, ZBuf, ZSliceBuffer}; +use zenoh::buffers::{SplitBuffer, ZBuf, ZSliceBuffer}; use crate::{ impl_guarded_transmute, z_bytes_empty, z_bytes_null, z_bytes_t, z_owned_bytes_t, z_owned_str_t, diff --git a/src/publisher.rs b/src/publisher.rs index 6647655bd..73b14f6a3 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -16,6 +16,8 @@ use crate::zcu_closure_matching_status_call; use crate::zcu_owned_closure_matching_status_t; use std::ops::{Deref, DerefMut}; use zenoh::prelude::SessionDeclarations; +use zenoh::sample::SampleBuilderTrait; +use zenoh::sample::ValueBuilderTrait; use zenoh::{ prelude::{Priority, Value}, publication::MatchingListener, @@ -260,10 +262,9 @@ pub unsafe extern "C" fn z_publisher_put( log::debug!("Attempted to put without a payload"); return i8::MIN; }; - let value: Value = payload.into(); let put = match options { Some(options) => { - let mut put = p.put(value.encoding(options.encoding.into())); + let mut put = p.put(payload).encoding(options.encoding.into()); if z_attachment_check(&options.attachment) { let mut attachment_builder = AttachmentBuilder::new(); z_attachment_iterate( @@ -271,11 +272,11 @@ pub unsafe extern "C" fn z_publisher_put( insert_in_attachment_builder, &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, ); - put = put.with_attachment(attachment_builder.build()); + put = put.attachment(attachment_builder.build()); }; put } - None => p.put(value), + None => p.put(payload), }; if let Err(e) = put.res_sync() { log::error!("{}", e); From 9cf7c5c52caad16057e57e6aa6b1097dcb288d81 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 9 Apr 2024 18:06:41 +0200 Subject: [PATCH 34/75] get compilation fix --- include/zenoh_commons.h | 21 ++++++++--------- src/commons.rs | 1 + src/get.rs | 51 ++++++++++++++++++++++------------------- src/keyexpr.rs | 1 - 4 files changed, 39 insertions(+), 35 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 9e4693788..f5981b620 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -737,18 +737,16 @@ typedef struct z_query_reply_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_query_reply_options_t; -typedef struct z_buffer_t zc_payload_t; -/** - * A zenoh value. - * - * Members: - * zc_payload_t payload: The payload of this zenoh value. - * z_encoding_t encoding: The encoding of this zenoh value `payload`. - */ -typedef struct z_value_t { - zc_payload_t payload; - struct z_encoding_t encoding; +#if !defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_value_t { + uint64_t _0[4]; } z_value_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(4) z_value_t { + uint32_t _0[4]; +} z_value_t; +#endif /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -774,6 +772,7 @@ typedef struct z_owned_reply_channel_t { struct z_owned_closure_reply_t send; struct z_owned_reply_channel_closure_t recv; } z_owned_reply_channel_t; +typedef struct z_buffer_t zc_payload_t; typedef struct z_timestamp_t { uint64_t time; struct z_id_t id; diff --git a/src/commons.rs b/src/commons.rs index 0fb284322..6c76669b7 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -233,6 +233,7 @@ pub struct z_encoding_t([u64; 4]); pub struct z_encoding_t([u32; 4]); impl_guarded_transmute!(Option<&'static Encoding>, z_encoding_t); +impl_guarded_transmute!(z_encoding_t, Option<&'static Encoding>); /// An owned payload encoding. /// diff --git a/src/get.rs b/src/get.rs index 065b9aba9..0effcc28a 100644 --- a/src/get.rs +++ b/src/get.rs @@ -14,6 +14,8 @@ use libc::c_char; use libc::c_void; +use zenoh::encoding::Encoding; +use zenoh::payload; use std::{ convert::TryFrom, ffi::CStr, @@ -105,15 +107,29 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { } /// A zenoh value. -/// -/// Members: -/// zc_payload_t payload: The payload of this zenoh value. -/// z_encoding_t encoding: The encoding of this zenoh value `payload`. +/// +/// + + #[repr(C)] -pub struct z_value_t { - pub payload: zc_payload_t, - pub encoding: z_encoding_t, -} +#[cfg(not(target_arch = "arm"))] +#[repr(C, align(8))] +pub struct z_owned_value_t([u64; 4]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(4))] +pub struct z_owned_value_t([u32; 4]); + +#[cfg(not(target_arch = "arm"))] +#[repr(C, align(8))] +pub struct z_value_t([u64; 4]); + +#[cfg(target_arch = "arm")] +#[repr(C, align(4))] +pub struct z_value_t([u32; 4]); + +impl_guarded_transmute!(Value, z_owned_value_t); +impl_guarded_transmute!(Option<&'static Value>, z_value_t); /// Yields the contents of the reply by asserting it indicates a failure. /// @@ -122,10 +138,7 @@ pub struct z_value_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { if let Some(inner) = reply.as_ref().and_then(|s| s.sample.as_ref().err()) { - z_value_t { - payload: Some(&inner.payload).into(), - encoding: (&inner.encoding).into(), - } + inner.into() } else { panic!("Assertion failed: tried to treat `z_owned_reply_t` as Err despite that not being the case") } @@ -215,7 +228,8 @@ pub unsafe extern "C" fn z_get( if let Some(payload) = options.payload.take() { let mut value = Value::new(payload); - value.encoding = options.encoding.into(); + let encoding: Option<&Encoding> = options.encoding.into(); + value.encoding = encoding.cloned().unwrap_or_default(); q = q.with_value(value); } if options.timeout_ms != 0 { @@ -312,16 +326,6 @@ impl From<&z_value_t> for Value { } } -impl From<&Value> for z_value_t { - #[inline] - fn from(val: &Value) -> z_value_t { - z_value_t { - encoding: (&val.encoding).into(), - payload: Some(&val.payload).into(), - } - } -} - /// Create a default :c:type:`z_query_target_t`. #[no_mangle] pub extern "C" fn z_query_target_default() -> z_query_target_t { @@ -364,6 +368,7 @@ impl From for z_consolidation_mode_t { #[inline] fn from(cm: ConsolidationMode) -> Self { match cm { + ConsolidationMode::Auto => z_consolidation_mode_t::AUTO, ConsolidationMode::None => z_consolidation_mode_t::NONE, ConsolidationMode::Monotonic => z_consolidation_mode_t::MONOTONIC, ConsolidationMode::Latest => z_consolidation_mode_t::LATEST, diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 7742b3948..51c47d211 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -26,7 +26,6 @@ use crate::LOG_INVALID_SESSION; use libc::c_char; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; -use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; use zenoh_util::core::zresult::ErrNo; From c2f72fbe28cbda16a1a34b3f52013a880404af98 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 9 Apr 2024 19:15:20 +0200 Subject: [PATCH 35/75] encoding unfinished --- include/zenoh_commons.h | 94 +------------------------------------- include/zenoh_concrete.h | 22 --------- splitguide.yaml | 1 - src/commons.rs | 22 +++++---- src/info.rs | 2 +- src/lib.rs | 4 +- src/publisher.rs | 3 ++ src/querying_subscriber.rs | 9 ++-- src/session.rs | 2 +- src/subscriber.rs | 66 +++++++++++++------------- 10 files changed, 58 insertions(+), 167 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index f5981b620..f0048010b 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -91,16 +91,6 @@ typedef enum z_query_target_t { Z_QUERY_TARGET_ALL, Z_QUERY_TARGET_ALL_COMPLETE, } z_query_target_t; -/** - * The subscription reliability. - * - * - **Z_RELIABILITY_BEST_EFFORT** - * - **Z_RELIABILITY_RELIABLE** - */ -typedef enum z_reliability_t { - Z_RELIABILITY_BEST_EFFORT, - Z_RELIABILITY_RELIABLE, -} z_reliability_t; typedef enum z_sample_kind_t { Z_SAMPLE_KIND_PUT = 0, Z_SAMPLE_KIND_DELETE = 1, @@ -524,16 +514,6 @@ typedef struct z_publisher_options_t { enum z_congestion_control_t congestion_control; enum z_priority_t priority; } z_publisher_options_t; -/** - * Represents the set of options that can be applied to a pull subscriber, - * upon its declaration via :c:func:`z_declare_pull_subscriber`. - * - * Members: - * z_reliability_t reliability: The subscription reliability. - */ -typedef struct z_pull_subscriber_options_t { - enum z_reliability_t reliability; -} z_pull_subscriber_options_t; /** * Options passed to the :c:func:`z_declare_queryable` function. * @@ -550,7 +530,7 @@ typedef struct z_queryable_options_t { * z_reliability_t reliability: The subscription reliability. */ typedef struct z_subscriber_options_t { - enum z_reliability_t reliability; + } z_subscriber_options_t; /** * Options passed to the :c:func:`z_delete` function. @@ -682,9 +662,6 @@ typedef struct z_publisher_put_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_publisher_put_options_t; -typedef struct z_pull_subscriber_t { - const struct z_owned_pull_subscriber_t *_0; -} z_pull_subscriber_t; /** * Options passed to the :c:func:`z_put` function. * @@ -962,7 +939,6 @@ typedef struct ze_owned_querying_subscriber_t { * uint64_t query_timeout_ms: The timeout to be used for queries. */ typedef struct ze_querying_subscriber_options_t { - enum z_reliability_t reliability; enum zcu_locality_t allowed_origin; struct z_keyexpr_t query_selector; enum z_query_target_t query_target; @@ -1371,44 +1347,6 @@ ZENOHC_API struct z_owned_publisher_t z_declare_publisher(struct z_session_t session, struct z_keyexpr_t keyexpr, const struct z_publisher_options_t *options); -/** - * Declares a pull subscriber for a given key expression. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to subscribe. - * callback: The callback function that will be called each time a data matching the subscribed expression is received. - * opts: additional options for the pull subscriber. - * - * Returns: - * A :c:type:`z_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the pull subscriber is still valid, - * you may use `z_pull_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a subscriber passing ``NULL`` for the options: - * - * .. code-block:: C - * - * z_owned_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); - * - * is equivalent to initializing and passing the default subscriber options: - * - * .. code-block:: C - * - * z_subscriber_options_t opts = z_subscriber_options_default(); - * z_owned_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); - */ -ZENOHC_API -struct z_owned_pull_subscriber_t z_declare_pull_subscriber(struct z_session_t session, - struct z_keyexpr_t keyexpr, - struct z_owned_closure_sample_t *callback, - const struct z_pull_subscriber_options_t *opts); /** * Creates a Queryable for the given key expression. * @@ -1788,23 +1726,6 @@ int8_t z_publisher_put(struct z_publisher_t publisher, * Constructs the default value for :c:type:`z_publisher_put_options_t`. */ ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); -/** - * Returns ``true`` if `sub` is valid. - */ -ZENOHC_API bool z_pull_subscriber_check(const struct z_owned_pull_subscriber_t *sub); -/** - * Returns ``true`` if `sub` is valid. - */ -ZENOHC_API -struct z_pull_subscriber_t z_pull_subscriber_loan(const struct z_owned_pull_subscriber_t *sub); -/** - * Constructs a null safe-to-drop value of 'z_owned_pull_subscriber_t' type - */ -ZENOHC_API struct z_owned_pull_subscriber_t z_pull_subscriber_null(void); -/** - * Constructs the default value for :c:type:`z_pull_subscriber_options_t`. - */ -ZENOHC_API struct z_pull_subscriber_options_t z_pull_subscriber_options_default(void); /** * Put data, transfering the buffer ownership. * @@ -2161,14 +2082,6 @@ ZENOHC_API struct z_owned_subscriber_t z_subscriber_null(void); * Constructs the default value for :c:type:`z_subscriber_options_t`. */ ZENOHC_API struct z_subscriber_options_t z_subscriber_options_default(void); -/** - * Pull data for :c:type:`z_owned_pull_subscriber_t`. The pulled data will be provided - * by calling the **callback** function provided to the :c:func:`z_declare_subscriber` function. - * - * Parameters: - * sub: The :c:type:`z_owned_pull_subscriber_t` to pull from. - */ -ZENOHC_API int8_t z_subscriber_pull(struct z_pull_subscriber_t sub); ZENOHC_API int8_t z_task_init(struct z_task_t *task, const struct z_task_attr_t *_attr, @@ -2193,11 +2106,6 @@ ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned */ ZENOHC_API int8_t z_undeclare_publisher(struct z_owned_publisher_t *publisher); -/** - * Undeclares the given :c:type:`z_owned_pull_subscriber_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -int8_t z_undeclare_pull_subscriber(struct z_owned_pull_subscriber_t *sub); /** * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. * diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 44f208496..8572e956b 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -51,28 +51,6 @@ typedef struct z_query_t { typedef struct z_session_t { size_t _0; } z_session_t; -/** - * An owned zenoh pull subscriber. Destroying the subscriber cancels the subscription. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_owned_pull_subscriber_t { - uint64_t _0[1]; -} z_owned_pull_subscriber_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_owned_pull_subscriber_t { - uint32_t _0[1]; -} z_owned_pull_subscriber_t; -#endif /** * An owned zenoh queryable. * diff --git a/splitguide.yaml b/splitguide.yaml index 4cb19de82..5469f25de 100644 --- a/splitguide.yaml +++ b/splitguide.yaml @@ -9,6 +9,5 @@ zenoh_concrete.h: - z_owned_session_t! - z_session_t! - z_owned_subscriber_t! - - z_owned_pull_subscriber_t! - z_query_t! - z_owned_queryable_t! diff --git a/src/commons.rs b/src/commons.rs index 6c76669b7..2d4e76888 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -131,7 +131,7 @@ pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { - Some(sample.encoding()).into() + sample.encoding().into() } /// The sample's data, the return value aliases the sample. /// @@ -232,8 +232,7 @@ pub struct z_encoding_t([u64; 4]); #[repr(C, align(4))] pub struct z_encoding_t([u32; 4]); -impl_guarded_transmute!(Option<&'static Encoding>, z_encoding_t); -impl_guarded_transmute!(z_encoding_t, Option<&'static Encoding>); +impl_guarded_transmute!(&'static Encoding, z_encoding_t); /// An owned payload encoding. /// @@ -246,16 +245,21 @@ impl_guarded_transmute!(z_encoding_t, Option<&'static Encoding>); #[repr(C, align(8))] pub struct z_owned_encoding_t([u64; 4]); +impl Drop for z_owned_encoding_t { + fn drop(&mut self) { + } +} + #[cfg(target_arch = "arm")] #[repr(C, align(4))] pub struct z_owned_encoding_t([u32; 4]); -impl_guarded_transmute!(Option, z_owned_encoding_t); +impl_guarded_transmute!(Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] pub extern "C" fn z_encoding_null() -> z_owned_encoding_t { - None::.into() + Encoding::default().into() } /// Constructs a specific :c:type:`z_encoding_t`. @@ -266,7 +270,7 @@ pub unsafe extern "C" fn z_encoding_from_str(s: *const c_char) -> z_owned_encodi z_encoding_null() } else { let s = CStr::from_ptr(s).to_string_lossy().as_ref(); - Some(Encoding::from(s)).into() + Encoding::from(s).into() } } @@ -274,7 +278,7 @@ pub unsafe extern "C" fn z_encoding_from_str(s: *const c_char) -> z_owned_encodi #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - let encoding = Some(&Encoding::default()); + let encoding = &Encoding::ZENOH_BYTES; encoding.into() } @@ -282,14 +286,14 @@ pub extern "C" fn z_encoding_default() -> z_encoding_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - std::mem::drop(encoding.take()); + std::mem::drop(std::mem::replace(encoding, z_encoding_null())); } /// Returns ``true`` if `encoding` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { - encoding.is_some() + *encoding == Encoding::default() } /// Returns a :c:type:`z_encoding_t` loaned from `encoding`. diff --git a/src/info.rs b/src/info.rs index 326b468bb..11ef031b3 100644 --- a/src/info.rs +++ b/src/info.rs @@ -13,7 +13,7 @@ // use crate::{session::*, z_closure_zid_call, z_owned_closure_zid_t}; use zenoh::prelude::sync::SyncResolve; -use zenoh::SessionDeclarations; +use zenoh::session::SessionDeclarations; use zenoh_protocol::core::ZenohId; /// Represents a Zenoh ID. diff --git a/src/lib.rs b/src/lib.rs index 20f766352..25d2a7fb8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,8 +41,8 @@ mod session; pub use crate::session::*; mod subscriber; pub use crate::subscriber::*; -mod pull_subscriber; -pub use crate::pull_subscriber::*; +// mod pull_subscriber; +// pub use crate::pull_subscriber::*; mod publisher; pub use crate::publisher::*; mod closures; diff --git a/src/publisher.rs b/src/publisher.rs index 73b14f6a3..26b355897 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -15,7 +15,9 @@ use crate::zcu_closure_matching_status_call; use crate::zcu_owned_closure_matching_status_t; use std::ops::{Deref, DerefMut}; +use zenoh::encoding::Encoding; use zenoh::prelude::SessionDeclarations; +use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; use zenoh::{ @@ -264,6 +266,7 @@ pub unsafe extern "C" fn z_publisher_put( }; let put = match options { Some(options) => { + let encoding = *options.encoding; let mut put = p.put(payload).encoding(options.encoding.into()); if z_attachment_check(&options.attachment) { let mut attachment_builder = AttachmentBuilder::new(); diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 910f1b89b..6f78d6bb9 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -16,13 +16,12 @@ use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; use zenoh::prelude::SessionDeclarations; use zenoh_ext::*; -use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; use crate::{ impl_guarded_transmute, z_closure_sample_call, z_get_options_t, z_keyexpr_t, z_owned_closure_sample_t, z_query_consolidation_none, z_query_consolidation_t, - z_query_target_default, z_query_target_t, z_reliability_t, z_sample_t, z_session_t, + z_query_target_default, z_query_target_t, z_sample_t, z_session_t, zcu_locality_default, zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, LOG_INVALID_SESSION, }; @@ -94,7 +93,7 @@ pub extern "C" fn ze_querying_subscriber_null() -> ze_owned_querying_subscriber_ #[repr(C)] #[allow(non_camel_case_types)] pub struct ze_querying_subscriber_options_t { - reliability: z_reliability_t, + // reliability: z_reliability_t, allowed_origin: zcu_locality_t, query_selector: z_keyexpr_t, query_target: z_query_target_t, @@ -107,7 +106,7 @@ pub struct ze_querying_subscriber_options_t { #[no_mangle] pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscriber_options_t { ze_querying_subscriber_options_t { - reliability: SubInfo::default().reliability.into(), + // reliability: SubInfo::default().reliability.into(), allowed_origin: zcu_locality_default(), query_selector: z_keyexpr_t::null(), query_target: z_query_target_default(), @@ -164,7 +163,7 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( let mut sub = s.declare_subscriber(keyexpr).querying(); if let Some(options) = options { sub = sub - .reliability(options.reliability.into()) + // .reliability(options.reliability.into()) .allowed_origin(options.allowed_origin.into()) .query_target(options.query_target.into()) .query_consolidation(options.query_consolidation) diff --git a/src/session.rs b/src/session.rs index 2caab85ea..f710e1703 100644 --- a/src/session.rs +++ b/src/session.rs @@ -15,7 +15,7 @@ use crate::{config::*, impl_guarded_transmute, zc_init_logger}; use std::sync::{Arc, Weak}; use zenoh::prelude::sync::SyncResolve; -use zenoh::Session; +use zenoh::session::Session; use zenoh_util::core::zresult::ErrNo; /// An owned zenoh session. diff --git a/src/subscriber.rs b/src/subscriber.rs index d82086f7f..acdae4f60 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -21,41 +21,41 @@ use crate::z_owned_closure_sample_t; use crate::LOG_INVALID_SESSION; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; -use zenoh::subscriber::Reliability; -use zenoh_protocol::core::SubInfo; +// use zenoh::subscriber::Reliability; +// use zenoh_protocol::core::SubInfo; use zenoh_util::core::zresult::ErrNo; /// The subscription reliability. /// /// - **Z_RELIABILITY_BEST_EFFORT** /// - **Z_RELIABILITY_RELIABLE** -#[allow(non_camel_case_types, clippy::upper_case_acronyms)] -#[repr(C)] -#[derive(Clone, Copy)] -pub enum z_reliability_t { - BEST_EFFORT, - RELIABLE, -} - -impl From for z_reliability_t { - #[inline] - fn from(r: Reliability) -> Self { - match r { - Reliability::BestEffort => z_reliability_t::BEST_EFFORT, - Reliability::Reliable => z_reliability_t::RELIABLE, - } - } -} - -impl From for Reliability { - #[inline] - fn from(val: z_reliability_t) -> Self { - match val { - z_reliability_t::BEST_EFFORT => Reliability::BestEffort, - z_reliability_t::RELIABLE => Reliability::Reliable, - } - } -} +// #[allow(non_camel_case_types, clippy::upper_case_acronyms)] +// #[repr(C)] +// #[derive(Clone, Copy)] +// pub enum z_reliability_t { +// BEST_EFFORT, +// RELIABLE, +// } + +// impl From for z_reliability_t { +// #[inline] +// fn from(r: Reliability) -> Self { +// match r { +// Reliability::BestEffort => z_reliability_t::BEST_EFFORT, +// Reliability::Reliable => z_reliability_t::RELIABLE, +// } +// } +// } + +// impl From for Reliability { +// #[inline] +// fn from(val: z_reliability_t) -> Self { +// match val { +// z_reliability_t::BEST_EFFORT => Reliability::BestEffort, +// z_reliability_t::RELIABLE => Reliability::Reliable, +// } +// } +// } /**************************************/ /* DECLARATION */ @@ -122,15 +122,15 @@ pub extern "C" fn z_subscriber_loan(p: &z_owned_subscriber_t) -> z_subscriber_t #[allow(non_camel_case_types)] #[repr(C)] pub struct z_subscriber_options_t { - pub reliability: z_reliability_t, + // pub reliability: z_reliability_t, } /// Constructs the default value for :c:type:`z_subscriber_options_t`. #[no_mangle] pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { - let info = SubInfo::default(); + // let info = SubInfo::default(); z_subscriber_options_t { - reliability: info.reliability.into(), + // reliability: info.reliability.into(), } } @@ -183,7 +183,7 @@ pub extern "C" fn z_declare_subscriber( z_closure_sample_call(&closure, &sample) }); if let Some(opts) = opts { - res = res.reliability(opts.reliability.into()) + // res = res.reliability(opts.reliability.into()) } match res.res() { Ok(sub) => z_owned_subscriber_t::new(sub), From d98c79a8a98f54942647b8bbbd704430995d9972 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Tue, 9 Apr 2024 22:43:34 +0200 Subject: [PATCH 36/75] transmute size compile errors --- Cargo.toml | 4 +-- Cargo.toml.in | 2 +- src/commons.rs | 17 +++++++--- src/get.rs | 51 +++++++++++++----------------- src/keyexpr.rs | 1 + src/publisher.rs | 2 +- src/put.rs | 10 ++++-- src/queryable.rs | 80 ++++++++++++++++-------------------------------- 8 files changed, 72 insertions(+), 95 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 34366e392..e4d32cfdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ unwrap-infallible = "0.1.5" zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } zenoh-util = { path = "../zenoh/commons/zenoh-util" } -zenoh-ext = { path = "../zenoh/zenoh-ext" } +zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} [build-dependencies] cbindgen = "0.26.0" @@ -70,7 +70,7 @@ serde_yaml = "0.9.19" [lib] path="src/lib.rs" -name = "zenohcd" +name = "zenohc" crate-type = ["cdylib", "staticlib"] doctest = false diff --git a/Cargo.toml.in b/Cargo.toml.in index d31b3d0c6..59dbda418 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -60,7 +60,7 @@ unwrap-infallible = "0.1.5" zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } zenoh-util = { path = "../zenoh/commons/zenoh-util" } -zenoh-ext = { path = "../zenoh/zenoh-ext" } +zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} [build-dependencies] cbindgen = "0.26.0" diff --git a/src/commons.rs b/src/commons.rs index 2d4e76888..0b23a1eec 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -14,6 +14,7 @@ use std::ffi::CStr; use std::ops::Deref; +use std::ops::DerefMut; use crate::collections::*; use crate::keyexpr::*; @@ -26,7 +27,10 @@ use crate::zc_payload_t; use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; +use std::convert::Infallible; +use unwrap_infallible::UnwrapInfallible; use zenoh::buffers::ZBuf; +use zenoh::encoding; use zenoh::encoding::Encoding; use zenoh::payload::Deserialize; use zenoh::payload::ZSerde; @@ -35,8 +39,6 @@ use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; use zenoh::sample::Sample; use zenoh_protocol::core::Timestamp; -use unwrap_infallible::UnwrapInfallible; -use std::convert::Infallible; use crate::attachment::{attachment_iteration_driver, z_attachment_null, z_attachment_t}; @@ -247,6 +249,8 @@ pub struct z_owned_encoding_t([u64; 4]); impl Drop for z_owned_encoding_t { fn drop(&mut self) { + let encoding = self.deref_mut(); + *encoding = Encoding::default(); } } @@ -286,21 +290,24 @@ pub extern "C" fn z_encoding_default() -> z_encoding_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - std::mem::drop(std::mem::replace(encoding, z_encoding_null())); + let encoding = encoding.deref_mut(); + *encoding = Encoding::default(); } /// Returns ``true`` if `encoding` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { - *encoding == Encoding::default() + let encoding = encoding.deref(); + *encoding != Encoding::default() } /// Returns a :c:type:`z_encoding_t` loaned from `encoding`. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> z_encoding_t { - encoding.as_ref().into() + let encoding = encoding.deref(); + encoding.into() } /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` diff --git a/src/get.rs b/src/get.rs index 0effcc28a..6fd6aff43 100644 --- a/src/get.rs +++ b/src/get.rs @@ -14,14 +14,16 @@ use libc::c_char; use libc::c_void; -use zenoh::encoding::Encoding; -use zenoh::payload; use std::{ convert::TryFrom, ffi::CStr, ops::{Deref, DerefMut}, }; use zenoh::buffers::ZBuf; +use zenoh::encoding::Encoding; +use zenoh::payload; +use zenoh::sample::SampleBuilderTrait; +use zenoh::sample::ValueBuilderTrait; use zenoh::{ prelude::{ConsolidationMode, KeyExpr, QueryTarget}, @@ -107,9 +109,8 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { } /// A zenoh value. -/// -/// - +/// +/// #[repr(C)] #[cfg(not(target_arch = "arm"))] @@ -129,7 +130,18 @@ pub struct z_value_t([u64; 4]); pub struct z_value_t([u32; 4]); impl_guarded_transmute!(Value, z_owned_value_t); -impl_guarded_transmute!(Option<&'static Value>, z_value_t); +impl_guarded_transmute!(&'static Value, z_value_t); + +const Z_VALUE_NULL: Value = Value::empty(); + +impl From> for z_value_t { + fn from(val: Option<&Value>) -> Self { + match val { + Some(val) => val.transmute(), + None => (&Z_VALUE_NULL).transmute(), + } + } +} /// Yields the contents of the reply by asserting it indicates a failure. /// @@ -228,9 +240,8 @@ pub unsafe extern "C" fn z_get( if let Some(payload) = options.payload.take() { let mut value = Value::new(payload); - let encoding: Option<&Encoding> = options.encoding.into(); - value.encoding = encoding.cloned().unwrap_or_default(); - q = q.with_value(value); + value.encoding = **options.encoding; + q = q.value(value); } if options.timeout_ms != 0 { q = q.timeout(std::time::Duration::from_millis(options.timeout_ms)); @@ -242,7 +253,7 @@ pub unsafe extern "C" fn z_get( insert_in_attachment_builder, &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, ); - q = q.with_attachment(attachment_builder.build()); + q = q.attachment(attachment_builder.build()); }; } match q @@ -306,26 +317,6 @@ impl From for QueryTarget { } } -impl From<&z_value_t> for Value { - #[inline] - fn from(val: &z_value_t) -> Value { - let payload: Option<&ZBuf> = val.payload.into(); - let payload = match payload { - Some(b) => b.clone(), - None => ZBuf::empty(), - }; - let encoding = unsafe { - std::str::from_utf8(std::slice::from_raw_parts( - val.encoding.suffix.start, - val.encoding.suffix.len, - )) - .expect("encodings must be UTF8") - }; - let v = Value::new(payload); - v.encoding(zenoh::prelude::Encoding::new(val.encoding.prefix as u8, encoding).unwrap()) - } -} - /// Create a default :c:type:`z_query_target_t`. #[no_mangle] pub extern "C" fn z_query_target_default() -> z_query_target_t { diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 51c47d211..c88b01199 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -24,6 +24,7 @@ use crate::z_str_null; use crate::GuardedTransmute; use crate::LOG_INVALID_SESSION; use libc::c_char; +use zenoh::core::SyncResolve; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::KeyExpr; diff --git a/src/publisher.rs b/src/publisher.rs index 26b355897..47f2bb71f 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -267,7 +267,7 @@ pub unsafe extern "C" fn z_publisher_put( let put = match options { Some(options) => { let encoding = *options.encoding; - let mut put = p.put(payload).encoding(options.encoding.into()); + let mut put = p.put(payload).encoding(*encoding); if z_attachment_check(&options.attachment) { let mut attachment_builder = AttachmentBuilder::new(); z_attachment_iterate( diff --git a/src/put.rs b/src/put.rs index 5e2d59aec..a0c2e88d0 100644 --- a/src/put.rs +++ b/src/put.rs @@ -17,9 +17,13 @@ use crate::session::*; use crate::zc_owned_payload_t; use crate::LOG_INVALID_SESSION; use libc::c_void; +use zenoh::encoding; use zenoh::prelude::{sync::SyncResolve, Priority, SampleKind}; use zenoh::publication::CongestionControl; use zenoh::sample::AttachmentBuilder; +use zenoh::sample::QoSBuilderTrait; +use zenoh::sample::SampleBuilderTrait; +use zenoh::sample::ValueBuilderTrait; use zenoh_util::core::zresult::ErrNo; use crate::attachment::{ @@ -161,10 +165,10 @@ pub extern "C" fn z_put( match session.upgrade() { Some(s) => { if let Some(payload) = payload.and_then(|p| p.take()) { - let mut res = s.put(keyexpr, payload).kind(SampleKind::Put); + let mut res = s.put(keyexpr, payload); if let Some(opts) = opts { res = res - .encoding(opts.encoding) + .encoding(**opts.encoding) .congestion_control(opts.congestion_control.into()) .priority(opts.priority.into()); if z_attachment_check(&opts.attachment) { @@ -174,7 +178,7 @@ pub extern "C" fn z_put( insert_in_attachment_builder, &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, ); - res = res.with_attachment(attachment_builder.build()); + res = res.attachment(attachment_builder.build()); }; } match res.res_sync() { diff --git a/src/queryable.rs b/src/queryable.rs index dd932188c..e6ca2195d 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -100,27 +100,8 @@ impl Deref for z_query_t { #[repr(C)] pub struct z_owned_query_t(*mut c_void); -impl From> for z_owned_query_t { - fn from(value: Option) -> Self { - unsafe { core::mem::transmute(value) } - } -} -impl From for z_owned_query_t { - fn from(value: Query) -> Self { - Some(value).into() - } -} -impl Deref for z_owned_query_t { - type Target = Option; - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } -} -impl DerefMut for z_owned_query_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { core::mem::transmute(self) } - } -} +impl_guarded_transmute!(Option, z_owned_query_t); + impl Drop for z_owned_query_t { fn drop(&mut self) { let _: Option = self.take(); @@ -129,7 +110,7 @@ impl Drop for z_owned_query_t { /// The gravestone value of `z_owned_query_t`. #[no_mangle] pub extern "C" fn z_query_null() -> z_owned_query_t { - unsafe { core::mem::transmute(None::) } + None.into() } /// Returns `false` if `this` is in a gravestone state, `true` otherwise. /// @@ -287,26 +268,28 @@ pub unsafe extern "C" fn z_query_reply( return i8::MIN; }; if let Some(key) = &*key { - if let Some(payload) = payload.and_then(|p| p.take()) { - let mut s = Sample::new(key.clone().into_owned(), payload); - if let Some(o) = options { - s.encoding = o.encoding.into(); - if z_attachment_check(&o.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - o.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - s = s.with_attachment(attachment_builder.build()); - }; - } - if let Err(e) = query.reply(Ok(s)).res_sync() { - log::error!("{}", e); - return e.errno().get(); - } - return 0; - } + // TODO: reimplement with reply builder + // + // if let Some(payload) = payload.and_then(|p| p.take()) { + // let mut s = Sample::new(key.clone().into_owned(), payload); + // if let Some(o) = options { + // s.encoding = o.encoding.into(); + // if z_attachment_check(&o.attachment) { + // let mut attachment_builder = AttachmentBuilder::new(); + // z_attachment_iterate( + // o.attachment, + // insert_in_attachment_builder, + // &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, + // ); + // s = s.with_attachment(attachment_builder.build()); + // }; + // } + // if let Err(e) = query.reply(Ok(s)).res_sync() { + // log::error!("{}", e); + // return e.errno().get(); + // } + // return 0; + // } } i8::MIN } @@ -341,17 +324,8 @@ pub extern "C" fn z_query_parameters(query: &z_query_t) -> z_bytes_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_query_value(query: &z_query_t) -> z_value_t { - match query.as_ref().and_then(|q| q.value()) { - Some(value) => - { - #[allow(mutable_transmutes)] - value.into() - } - None => z_value_t { - payload: zc_payload_t::default(), - encoding: z_encoding_default(), - }, - } + let v = query.as_ref().and_then(|q| q.value()); + v.into() } /// Returns the attachment to the query by aliasing. From 087210dae253f7239777833e37fe402e353bcd21 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 11 Apr 2024 11:22:31 +0200 Subject: [PATCH 37/75] merge main into protocol_changes --- build.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/build.rs b/build.rs index 5b0585cd5..f8df08447 100644 --- a/build.rs +++ b/build.rs @@ -2,7 +2,6 @@ use fs2::FileExt; use regex::Regex; use std::env; use std::io::{Read, Write}; -use std::path::PathBuf; use std::process::{Command, Stdio}; use std::{ borrow::Cow, @@ -32,8 +31,6 @@ const HEADER: &str = r"// #endif "; -use std::env; - fn main() { generate_opaque_types(); cbindgen::generate(std::env::var("CARGO_MANIFEST_DIR").unwrap()) @@ -60,27 +57,6 @@ fn main() { println!("cargo:rerun-if-changed=include"); } -// See: https://github.com/rust-lang/cargo/issues/9661 -// See: https://github.com/rust-lang/cargo/issues/545 -fn cargo_target_dir() -> PathBuf { - let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR should be set")); - let profile = env::var("PROFILE").expect("PROFILE should be set"); - - let mut target_dir = None; - let mut out_dir_path = out_dir.as_path(); - while let Some(parent) = out_dir_path.parent() { - if parent.ends_with(&profile) { - target_dir = Some(parent); - break; - } - out_dir_path = parent; - } - - target_dir - .expect("OUT_DIR should be a child of a PROFILE directory") - .to_path_buf() -} - fn get_build_rs_path() -> PathBuf { let file_path = file!(); let mut path_buf = PathBuf::new(); From f41fb5ab8499bbe882420f766bf49d46c41834ac Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Thu, 11 Apr 2024 17:32:35 +0200 Subject: [PATCH 38/75] compilation fix unfinished --- Cargo.lock | 46 ++++--- build-resources/opaque-types/Cargo.lock | 154 +++++++++++++++++++++--- build-resources/opaque-types/Cargo.toml | 3 +- build-resources/opaque-types/src/lib.rs | 22 +++- include/zenoh_commons.h | 78 ++---------- src/closures/query_channel.rs | 4 +- src/commons.rs | 25 ++-- src/get.rs | 29 +---- src/queryable.rs | 5 +- 9 files changed, 206 insertions(+), 160 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a78021705..072e2a981 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -629,9 +629,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c012a26a7f605efc424dd53697843a72be7dc86ad2d01f7814337794a12231d" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" dependencies = [ "anstream", "anstyle", @@ -976,9 +976,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1213,9 +1213,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" dependencies = [ "value-bag", ] @@ -1899,9 +1899,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +checksum = "99008d7ad0bbbea527ec27bddbc0e432c5b87d8175178cee68d2eec9c4a1813c" dependencies = [ "log", "ring 0.17.6", @@ -2470,7 +2470,7 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.22.2", + "rustls 0.22.3", "rustls-pki-types", "tokio", ] @@ -2719,9 +2719,9 @@ dependencies = [ [[package]] name = "value-bag" -version = "1.4.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" +checksum = "74797339c3b98616c009c7c3eb53a0ce41e85c8ec66bd3db96ed132d20cfdee8" [[package]] name = "vec_map" @@ -3063,7 +3063,7 @@ dependencies = [ "async-trait", "base64", "const_format", - "env_logger 0.11.2", + "env_logger 0.11.3", "event-listener 4.0.0", "flume", "form_urlencoded", @@ -3088,6 +3088,7 @@ dependencies = [ "tokio", "tokio-util", "uhlc", + "unwrap-infallible", "uuid", "vec_map", "zenoh-buffers", @@ -3105,6 +3106,7 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", + "zenoh-task", "zenoh-transport", "zenoh-util", ] @@ -3206,7 +3208,7 @@ name = "zenoh-ext" version = "0.11.0-dev" dependencies = [ "bincode", - "env_logger 0.11.2", + "env_logger 0.11.3", "flume", "futures", "log", @@ -3256,7 +3258,7 @@ dependencies = [ "flume", "futures", "log", - "rustls 0.22.2", + "rustls 0.22.3", "rustls-webpki 0.102.2", "serde", "tokio", @@ -3322,7 +3324,7 @@ dependencies = [ "base64", "futures", "log", - "rustls 0.22.2", + "rustls 0.22.3", "rustls-pemfile 2.0.0", "rustls-pki-types", "rustls-webpki 0.102.2", @@ -3449,6 +3451,7 @@ dependencies = [ name = "zenoh-runtime" version = "0.11.0-dev" dependencies = [ + "futures", "lazy_static", "tokio", "zenoh-collections", @@ -3479,6 +3482,18 @@ dependencies = [ "zenoh-runtime", ] +[[package]] +name = "zenoh-task" +version = "0.11.0-dev" +dependencies = [ + "futures", + "log", + "tokio", + "tokio-util", + "zenoh-core", + "zenoh-runtime", +] + [[package]] name = "zenoh-transport" version = "0.11.0-dev" @@ -3507,6 +3522,7 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", + "zenoh-task", "zenoh-util", ] diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock index a6f37dab3..d7276add6 100644 --- a/build-resources/opaque-types/Cargo.lock +++ b/build-resources/opaque-types/Cargo.lock @@ -383,6 +383,12 @@ version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.6.0" @@ -833,6 +839,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + [[package]] name = "hashbrown" version = "0.13.2" @@ -930,6 +942,12 @@ dependencies = [ "serde", ] +[[package]] +name = "iter-read" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c397ca3ea05ad509c4ec451fea28b4771236a376ca1c69fd5143aae0cf8f93c4" + [[package]] name = "itoa" version = "1.0.11" @@ -1119,6 +1137,26 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -1248,6 +1286,48 @@ dependencies = [ "indexmap", ] +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1596,6 +1676,29 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-pickle" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762ad136a26407c6a80825813600ceeab5e613660d93d79a41f0ec877171e71" +dependencies = [ + "byteorder", + "iter-read", + "num-bigint", + "num-traits", + "serde", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.197" @@ -1694,6 +1797,12 @@ dependencies = [ "libc", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -1926,6 +2035,12 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "unzip-n" version = "0.1.2" @@ -2291,7 +2406,6 @@ checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-trait", "base64", @@ -2307,16 +2421,21 @@ dependencies = [ "ordered-float", "paste", "petgraph", + "phf", "rand", "regex", "rustc_version", "serde", + "serde-pickle", + "serde_cbor", "serde_json", + "serde_yaml", "socket2 0.5.6", "stop-token", "tokio", "tokio-util", "uhlc", + "unwrap-infallible", "uuid", "vec_map", "zenoh-buffers", @@ -2334,6 +2453,7 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", + "zenoh-task", "zenoh-transport", "zenoh-util", ] @@ -2341,7 +2461,6 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "zenoh-collections", ] @@ -2349,7 +2468,6 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "log", "serde", @@ -2362,12 +2480,10 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "flume", "json5", @@ -2387,7 +2503,6 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-global-executor", "lazy_static", @@ -2399,7 +2514,6 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "aes", "hmac", @@ -2412,7 +2526,6 @@ dependencies = [ [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "hashbrown 0.14.3", "keyed-set", @@ -2426,7 +2539,6 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-trait", "zenoh-config", @@ -2438,7 +2550,6 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-trait", "flume", @@ -2461,7 +2572,6 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "proc-macro2", "quote", @@ -2472,7 +2582,6 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "const_format", "libloading", @@ -2488,7 +2597,6 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "const_format", "rand", @@ -2502,7 +2610,6 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "anyhow", ] @@ -2510,8 +2617,8 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ + "futures", "lazy_static", "tokio", "zenoh-collections", @@ -2521,7 +2628,6 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "log", "serde", @@ -2533,7 +2639,6 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "event-listener 4.0.3", "futures", @@ -2544,10 +2649,21 @@ dependencies = [ "zenoh-runtime", ] +[[package]] +name = "zenoh-task" +version = "0.11.0-dev" +dependencies = [ + "futures", + "log", + "tokio", + "tokio-util", + "zenoh-core", + "zenoh-runtime", +] + [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-trait", "flume", @@ -2572,13 +2688,13 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", + "zenoh-task", "zenoh-util", ] [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=main#e04c8613d3c33472edcbde6fde5bd4beeb24f2bf" dependencies = [ "async-std", "async-trait", diff --git a/build-resources/opaque-types/Cargo.toml b/build-resources/opaque-types/Cargo.toml index 6e8319bb0..51bf417a7 100644 --- a/build-resources/opaque-types/Cargo.toml +++ b/build-resources/opaque-types/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" [dependencies] # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } \ No newline at end of file +# zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } +zenoh = { path="../../../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } \ No newline at end of file diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 354e8d999..4a9ebd013 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,13 +1,18 @@ -use zenoh::sample::Sample; use zenoh::buffers::{ZBuf, ZBufReader}; +use zenoh::encoding::Encoding; +use zenoh::query::Reply; +use zenoh::queryable::Query; +use zenoh::sample::Sample; +use zenoh::value::Value; #[macro_export] macro_rules! get_opaque_type_data { -($src_type:ty, $expr:expr) => { + ($src_type:ty, $expr:expr) => { const _: () = { let align = std::mem::align_of::<$src_type>(); let size = std::mem::size_of::<$src_type>(); - let mut msg: [u8; 61] = *b"type: , align: , size: "; + let mut msg: [u8; 61] = + *b"type: , align: , size: "; let mut i = 0; while i < 4 { msg[i as usize + 46] = b'0' + ((align / 10u32.pow(3 - i) as usize) % 10) as u8; @@ -23,7 +28,7 @@ macro_rules! get_opaque_type_data { std::str::from_utf8_unchecked(msg.as_slice()) }); }; - } + }; } /// A split buffer that owns all of its data. @@ -38,4 +43,11 @@ get_opaque_type_data!(Option, "z_owned_buffer_t"); get_opaque_type_data!(Option, "zc_owned_sample_t"); /// A reader for payload data. -get_opaque_type_data!(ZBufReader, "zc_payload_reader"); \ No newline at end of file +get_opaque_type_data!(ZBufReader, "zc_payload_reader"); + +get_opaque_type_data!(&'static Encoding, "z_encoding_t"); +get_opaque_type_data!(Encoding, "z_owned_encoding_t"); +get_opaque_type_data!(Option, "z_owned_reply_t"); +get_opaque_type_data!(Value, "z_owned_value_t"); +get_opaque_type_data!(&'static Value, "z_value_t"); +get_opaque_type_data!(Option, "z_owned_query_t"); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index f0048010b..2b35df84e 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -243,18 +243,8 @@ typedef struct z_owned_closure_hello_t { void (*call)(struct z_owned_hello_t*, void*); void (*drop)(void*); } z_owned_closure_hello_t; -/** - * Owned variant of a Query received by a Queryable. - * - * You may construct it by `z_query_clone`-ing a loaned query. - * When the last `z_owned_query_t` corresponding to a query is destroyed, or the callback that produced the query cloned to build them returns, - * the query will receive its termination signal. - * - * Holding onto an `z_owned_query_t` for too long (10s by default, can be set in `z_get`'s options) will trigger a timeout error - * to be sent to the querier by the infrastructure, and new responses to the outdated query will be silently dropped. - */ -typedef struct z_owned_query_t { - void *_0; +typedef struct ALIGN(8) z_owned_query_t { + uint8_t _0[16]; } z_owned_query_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: @@ -298,25 +288,9 @@ typedef struct z_owned_closure_query_t { void (*call)(const struct z_query_t*, void *context); void (*drop)(void*); } z_owned_closure_query_t; -/** - * An owned reply to a :c:func:`z_get`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_owned_reply_t { - uint64_t _0[30]; -} z_owned_reply_t; -#endif -#if defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_owned_reply_t { - uint64_t _0[19]; + uint8_t _0[256]; } z_owned_reply_t; -#endif /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * @@ -539,41 +513,12 @@ typedef struct z_delete_options_t { enum z_congestion_control_t congestion_control; enum z_priority_t priority; } z_delete_options_t; -/** - * An owned payload encoding. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_owned_encoding_t { - uint64_t _0[4]; -} z_owned_encoding_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_owned_encoding_t { - uint32_t _0[4]; + uint8_t _0[48]; } z_owned_encoding_t; -#endif -/** - * The encoding of a payload, in a MIME-like format. - * - * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. - * - */ -#if !defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_encoding_t { - uint64_t _0[4]; -} z_encoding_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_encoding_t { - uint32_t _0[4]; + uint8_t _0[8]; } z_encoding_t; -#endif /** * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. */ @@ -714,16 +659,9 @@ typedef struct z_query_reply_options_t { struct z_encoding_t encoding; struct z_attachment_t attachment; } z_query_reply_options_t; -#if !defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_value_t { - uint64_t _0[4]; -} z_value_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_value_t { - uint32_t _0[4]; + uint8_t _0[8]; } z_value_t; -#endif /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -823,7 +761,7 @@ typedef struct ALIGN(8) zc_payload_reader { * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. */ typedef struct ALIGN(8) zc_owned_sample_t { - uint8_t _0[224]; + uint8_t _0[240]; } zc_owned_sample_t; typedef struct zc_owned_shmbuf_t { size_t _0[9]; @@ -1965,7 +1903,7 @@ ZENOHC_API struct z_attachment_t z_sample_attachment(const struct z_sample_t *sa /** * The encoding of the payload. */ -ZENOHC_API struct z_encoding_t z_sample_encoding(const struct z_sample_t *sample); +ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); /** * The Key Expression of the sample. * diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index b7a51c9c0..b964add61 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -80,7 +80,7 @@ pub extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { send, recv: From::from(move |receptacle: &mut z_owned_query_t| { *receptacle = match rx.recv() { - Ok(val) => val.into(), + Ok(val) => Some(val).into(), Err(_) => None.into(), }; true @@ -129,7 +129,7 @@ pub extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned_query_ recv: From::from( move |receptacle: &mut z_owned_query_t| match rx.try_recv() { Ok(val) => { - let mut tmp = z_owned_query_t::from(val); + let mut tmp = z_owned_query_t::from(Some(val)); std::mem::swap(&mut tmp, receptacle); true } diff --git a/src/commons.rs b/src/commons.rs index 0b23a1eec..13ff43a0d 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -132,7 +132,9 @@ pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { } /// The encoding of the payload. #[no_mangle] -pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> z_encoding_t { +pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { + let encoding = sample.encoding(); + sample.encoding().into() } /// The sample's data, the return value aliases the sample. @@ -226,15 +228,8 @@ pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { /// /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. /// -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_encoding_t([u64; 4]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_encoding_t([u32; 4]); - -impl_guarded_transmute!(&'static Encoding, z_encoding_t); +pub use crate::z_encoding_t; +impl_guarded_transmute!(noderefs &'static Encoding, z_encoding_t); /// An owned payload encoding. /// @@ -243,9 +238,8 @@ impl_guarded_transmute!(&'static Encoding, z_encoding_t); /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_encoding_t([u64; 4]); +pub use crate::z_owned_encoding_t; +impl_guarded_transmute!(Encoding, z_owned_encoding_t); impl Drop for z_owned_encoding_t { fn drop(&mut self) { @@ -254,11 +248,6 @@ impl Drop for z_owned_encoding_t { } } -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_owned_encoding_t([u32; 4]); - -impl_guarded_transmute!(Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] diff --git a/src/get.rs b/src/get.rs index 6fd6aff43..37ed192e0 100644 --- a/src/get.rs +++ b/src/get.rs @@ -55,14 +55,7 @@ type ReplyInner = Option; /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_reply_t([u64; 30]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(8))] -pub struct z_owned_reply_t([u64; 19]); - +pub use crate::z_owned_reply_t; impl_guarded_transmute!(noderefs ReplyInner, z_owned_reply_t); impl From for z_owned_reply_t { @@ -111,25 +104,9 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { /// A zenoh value. /// /// - -#[repr(C)] -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_value_t([u64; 4]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_owned_value_t([u32; 4]); - -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_value_t([u64; 4]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_value_t([u32; 4]); - +pub use crate::z_owned_value_t; impl_guarded_transmute!(Value, z_owned_value_t); +pub use crate::z_value_t; impl_guarded_transmute!(&'static Value, z_value_t); const Z_VALUE_NULL: Value = Value::empty(); diff --git a/src/queryable.rs b/src/queryable.rs index e6ca2195d..5d21824f4 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -96,10 +96,7 @@ impl Deref for z_query_t { /// /// Holding onto an `z_owned_query_t` for too long (10s by default, can be set in `z_get`'s options) will trigger a timeout error /// to be sent to the querier by the infrastructure, and new responses to the outdated query will be silently dropped. -#[allow(non_camel_case_types)] -#[repr(C)] -pub struct z_owned_query_t(*mut c_void); - +pub use crate::z_owned_query_t; impl_guarded_transmute!(Option, z_owned_query_t); impl Drop for z_owned_query_t { From 95d059013dd7915358ac67a9d1113cbd4c690100 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 12 Apr 2024 19:27:43 +0200 Subject: [PATCH 39/75] transmute rework --- build.rs | 3 +- include/zenoh_commons.h | 4 +- src/commons.rs | 40 ++++++------ src/lib.rs | 3 + src/queryable.rs | 11 ++-- src/transmute.rs | 140 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 173 insertions(+), 28 deletions(-) create mode 100644 src/transmute.rs diff --git a/build.rs b/build.rs index f8df08447..89fffff0d 100644 --- a/build.rs +++ b/build.rs @@ -96,7 +96,8 @@ fn generate_opaque_types() { let re = Regex::new(r"type:(\w+) *, align:0*(\d+), size:0*(\d+)").unwrap(); for (_, [type_name, align, size]) in re.captures_iter(&data_in).map(|c| c.extract()) { let s = format!( - "#[repr(C, align({align}))] + "#[derive(Copy, Clone)] +#[repr(C, align({align}))] pub struct {type_name} {{ _0: [u8; {size}], }} diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 2b35df84e..689944ae2 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1373,7 +1373,7 @@ ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); /** * Constructs a specific :c:type:`z_encoding_t`. */ -ZENOHC_API struct z_owned_encoding_t z_encoding_from_str(const char *s); +ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); /** * Returns a :c:type:`z_encoding_t` loaned from `encoding`. */ @@ -1381,7 +1381,7 @@ ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t * /** * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type */ -ZENOHC_API struct z_owned_encoding_t z_encoding_null(void); +ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); /** * Query data from the matching queryables in the system. * Replies are provided through a callback function. diff --git a/src/commons.rs b/src/commons.rs index 13ff43a0d..ae2b9b744 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -15,9 +15,14 @@ use std::ffi::CStr; use std::ops::Deref; use std::ops::DerefMut; +use std::str::FromStr; use crate::collections::*; +use crate::decl_transmute_copy; use crate::keyexpr::*; +use crate::transmute::InplaceInit; +use crate::transmute::InplaceInitDefault; +use crate::transmute::TransmuteRef; use crate::z_congestion_control_t; use crate::z_id_t; use crate::z_owned_buffer_t; @@ -133,9 +138,8 @@ pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { - let encoding = sample.encoding(); - - sample.encoding().into() + // let encoding = sample.encoding(); + // sample.encoding().transmute() } /// The sample's data, the return value aliases the sample. /// @@ -229,7 +233,9 @@ pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. /// pub use crate::z_encoding_t; -impl_guarded_transmute!(noderefs &'static Encoding, z_encoding_t); +decl_transmute_copy!(&'static Encoding, z_encoding_t); + +// impl_guarded_transmute!(noderefs &'static Encoding, z_encoding_t); /// An owned payload encoding. /// @@ -239,31 +245,26 @@ impl_guarded_transmute!(noderefs &'static Encoding, z_encoding_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. pub use crate::z_owned_encoding_t; -impl_guarded_transmute!(Encoding, z_owned_encoding_t); - -impl Drop for z_owned_encoding_t { - fn drop(&mut self) { - let encoding = self.deref_mut(); - *encoding = Encoding::default(); - } -} - +decl_transmute_ref!(default_inplace_init Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] -pub extern "C" fn z_encoding_null() -> z_owned_encoding_t { - Encoding::default().into() +pub extern "C" fn z_encoding_null(encoding: &mut z_owned_encoding_t) { + encoding.transmute_mut().inplace_default(); } /// Constructs a specific :c:type:`z_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_encoding_from_str(s: *const c_char) -> z_owned_encoding_t { +pub unsafe extern "C" fn z_encoding_from_str(encoding: &mut z_owned_encoding_t, s: *const c_char) -> i8 { if s.is_null() { - z_encoding_null() + z_encoding_null(encoding); + 0 } else { let s = CStr::from_ptr(s).to_string_lossy().as_ref(); - Encoding::from(s).into() + let value = Encoding::from_str(s).unwrap_infallible(); + encoding.transmute_mut().inplace_init(value); + 0 } } @@ -279,8 +280,7 @@ pub extern "C" fn z_encoding_default() -> z_encoding_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - let encoding = encoding.deref_mut(); - *encoding = Encoding::default(); + } /// Returns ``true`` if `encoding` is valid. diff --git a/src/lib.rs b/src/lib.rs index 25d2a7fb8..90a7f27c5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,6 +18,9 @@ mod collections; use std::cmp::min; use std::slice; +#[macro_use] +mod transmute; + pub use crate::collections::*; mod config; pub use crate::config::*; diff --git a/src/queryable.rs b/src/queryable.rs index 5d21824f4..2fd38d296 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -99,11 +99,12 @@ impl Deref for z_query_t { pub use crate::z_owned_query_t; impl_guarded_transmute!(Option, z_owned_query_t); -impl Drop for z_owned_query_t { - fn drop(&mut self) { - let _: Option = self.take(); - } -} +// impl Drop for z_owned_query_t { +// fn drop(&mut self) { +// let _: Option = self.take(); +// } +// } + /// The gravestone value of `z_owned_query_t`. #[no_mangle] pub extern "C" fn z_query_null() -> z_owned_query_t { diff --git a/src/transmute.rs b/src/transmute.rs new file mode 100644 index 000000000..891c39ff8 --- /dev/null +++ b/src/transmute.rs @@ -0,0 +1,140 @@ +// +// Copyright (c) 2017, 2024 ZettaScale Technology. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh team, +// + +pub(crate) trait TransmuteRef { + fn transmute_ref(&self) -> &T; + fn transmute_mut(&mut self) -> &mut T; +} + +pub(crate) trait TransmuteCopy: TransmuteRef { + fn transmute(self) -> T; +} + + +pub(crate) trait InplaceInit: Sized { + // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized + fn inplace_init(&mut self, value: T) -> &mut Self { + unsafe { std::ptr::write(self as *mut Self as *mut T, value) }; + self + } + // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized + fn inplace_default(&mut self) -> &mut Self + where + T: Default, + { + unsafe { std::ptr::write(self as *mut Self as *mut T, T::default()) }; + self + } +} + +pub(crate) trait InplaceInitDefault: Default { + // Default implementation of inplace_init for object implementing Default trait. May be less efficient than a custom implementation + // because it involves a copy of the default value. + fn inplace_default_impl(&mut self) { + unsafe { std::ptr::write(self as *mut Self, Self::default()) }; + } +} + +// For types implementing Default, we can use provide default implementation of InplaceInit through InplaceInitDefault +impl InplaceInit for T { + fn inplace_default(&mut self) -> &mut Self { + self.inplace_default_impl(); + self + } +} + +macro_rules! validate_equivalence { + ($type_a:ty, $type_b:ty) => { + const _: () = { + let align_a = std::mem::align_of::<$type_a>(); + let align_b = std::mem::align_of::<$type_b>(); + if align_a != align_b { + panic!( + "Alingment mismatch: type `{}` has align {}, type `{}` has align {}", + stringify!($type_a), + align_a, + stringify!($type_b), + align_b + ); + } + let size_a = std::mem::size_of::<$type_a>(); + let size_b = std::mem::size_of::<$type_b>(); + if size_a != size_b { + panic!( + "Size mismatch: type `{}` has size {}, type `{}` has size {}", + stringify!($type_a), + size_a, + stringify!($type_b), + size_b + ); + } + }; + }; +} + +#[macro_export] +macro_rules! decl_transmute_ref { + (default_inplace_init $zenoh_type:ty, $c_type:ty) => { + impl InplaceInitDefault for $zenoh_type {} + decl_transmute_ref!(custom_inplace_init $zenoh_type, $c_type); + + }; + (custom_inplace_init $zenoh_type:ty, $c_type:ty) => { + validate_equivalence!($zenoh_type, $c_type); + impl_transmute_ref!($zenoh_type, $c_type); + impl_transmute_ref!($c_type, $zenoh_type); + impl InplaceInit<$zenoh_type> for $c_type { + fn inplace_init(&mut self, value: $zenoh_type) { + self.transmute_mut().inplace_init(value); + } + fn inplace_default(&mut self) { + self.transmute_mut().inplace_default(); + } + } + } +} + +#[macro_export] +macro_rules! decl_transmute_copy { + ($zenoh_type:ty, $c_type:ty) => { + validate_equivalence!($zenoh_type, $c_type); + impl_guarded_transmute_ref!($zenoh_type, $c_type); + impl_guarded_transmute_ref!($c_type, $zenoh_type); + impl_guarded_transmute_copy!($zenoh_type, $c_type); + impl_guarded_transmute_copy!($c_type, $zenoh_type); + }; +} + +macro_rules! impl_transmute_ref { + ($src_type:ty, $dst_type:ty) => { + impl $crate::transmute::TransmuteRef<$dst_type> for $src_type { + fn transmute_ref(&self) -> &$dst_type { + unsafe { std::mem::transmute::<&$src_type, &$dst_type>(self) } + } + fn transmute_mut(&mut self) -> &mut $dst_type { + unsafe { std::mem::transmute::<&mut $src_type, &mut $dst_type>(self) } + } + } + } +} + +macro_rules! impl_transmute_copy { + ($src_type:ty, $dst_type:ty) => { + impl $crate::transmute::TransmuteCopy<$dst_type> for $src_type { + fn transmute(self) -> $dst_type { + unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } + } + } + } +} From fb761dc37600dc123d314021629d0aa57bb689f0 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Fri, 12 Apr 2024 22:22:21 +0200 Subject: [PATCH 40/75] unfinished --- Cargo.lock | 2 -- Cargo.toml | 2 -- Cargo.toml.in | 2 -- src/commons.rs | 18 +++++++----------- src/transmute.rs | 19 ++++++++++--------- 5 files changed, 17 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 072e2a981..336fce624 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3141,8 +3141,6 @@ dependencies = [ "unwrap-infallible", "zenoh", "zenoh-ext", - "zenoh-protocol", - "zenoh-util", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c2d338bd7..e3579e00e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,8 +58,6 @@ unwrap-infallible = "0.1.5" #zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } -zenoh-util = { path = "../zenoh/commons/zenoh-util" } zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} [build-dependencies] diff --git a/Cargo.toml.in b/Cargo.toml.in index a1f441b5d..b68560103 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -58,8 +58,6 @@ unwrap-infallible = "0.1.5" #zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } -zenoh-util = { path = "../zenoh/commons/zenoh-util" } zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} [build-dependencies] diff --git a/src/commons.rs b/src/commons.rs index ae2b9b744..345050822 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -35,15 +35,13 @@ use libc::{c_char, c_ulong}; use std::convert::Infallible; use unwrap_infallible::UnwrapInfallible; use zenoh::buffers::ZBuf; -use zenoh::encoding; -use zenoh::encoding::Encoding; use zenoh::payload::Deserialize; use zenoh::payload::ZSerde; use zenoh::prelude::SampleKind; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; use zenoh::sample::Sample; -use zenoh_protocol::core::Timestamp; +use zenoh::time::Timestamp; use crate::attachment::{attachment_iteration_driver, z_attachment_null, z_attachment_t}; @@ -235,8 +233,6 @@ pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { pub use crate::z_encoding_t; decl_transmute_copy!(&'static Encoding, z_encoding_t); -// impl_guarded_transmute!(noderefs &'static Encoding, z_encoding_t); - /// An owned payload encoding. /// /// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. @@ -256,7 +252,10 @@ pub extern "C" fn z_encoding_null(encoding: &mut z_owned_encoding_t) { /// Constructs a specific :c:type:`z_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_encoding_from_str(encoding: &mut z_owned_encoding_t, s: *const c_char) -> i8 { +pub unsafe extern "C" fn z_encoding_from_str( + encoding: &mut z_owned_encoding_t, + s: *const c_char, +) -> i8 { if s.is_null() { z_encoding_null(encoding); 0 @@ -272,16 +271,13 @@ pub unsafe extern "C" fn z_encoding_from_str(encoding: &mut z_owned_encoding_t, #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - let encoding = &Encoding::ZENOH_BYTES; - encoding.into() + let encoding = Encoding::ZENOH_BYTES; } /// Frees `encoding`, invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - -} +pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) {} /// Returns ``true`` if `encoding` is valid. #[no_mangle] diff --git a/src/transmute.rs b/src/transmute.rs index 891c39ff8..d4f7a5678 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -21,7 +21,6 @@ pub(crate) trait TransmuteCopy: TransmuteRef { fn transmute(self) -> T; } - pub(crate) trait InplaceInit: Sized { // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized fn inplace_init(&mut self, value: T) -> &mut Self { @@ -95,11 +94,13 @@ macro_rules! decl_transmute_ref { impl_transmute_ref!($zenoh_type, $c_type); impl_transmute_ref!($c_type, $zenoh_type); impl InplaceInit<$zenoh_type> for $c_type { - fn inplace_init(&mut self, value: $zenoh_type) { + fn inplace_init(&mut self, value: $zenoh_type) -> &mut Self { self.transmute_mut().inplace_init(value); + self } - fn inplace_default(&mut self) { + fn inplace_default(&mut self) -> &mut Self { self.transmute_mut().inplace_default(); + self } } } @@ -109,10 +110,10 @@ macro_rules! decl_transmute_ref { macro_rules! decl_transmute_copy { ($zenoh_type:ty, $c_type:ty) => { validate_equivalence!($zenoh_type, $c_type); - impl_guarded_transmute_ref!($zenoh_type, $c_type); - impl_guarded_transmute_ref!($c_type, $zenoh_type); - impl_guarded_transmute_copy!($zenoh_type, $c_type); - impl_guarded_transmute_copy!($c_type, $zenoh_type); + impl_transmute_ref!($zenoh_type, $c_type); + impl_transmute_ref!($c_type, $zenoh_type); + impl_transmute_copy!($zenoh_type, $c_type); + impl_transmute_copy!($c_type, $zenoh_type); }; } @@ -126,7 +127,7 @@ macro_rules! impl_transmute_ref { unsafe { std::mem::transmute::<&mut $src_type, &mut $dst_type>(self) } } } - } + }; } macro_rules! impl_transmute_copy { @@ -136,5 +137,5 @@ macro_rules! impl_transmute_copy { unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } } } - } + }; } From 4bc4f203b2c737f23575ac6b913d5120ad45730d Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 00:13:04 +0200 Subject: [PATCH 41/75] *mut MaybeUinit --- src/commons.rs | 22 ++++++++------- src/transmute.rs | 69 +++++++++++++++++++++++++++++------------------- 2 files changed, 55 insertions(+), 36 deletions(-) diff --git a/src/commons.rs b/src/commons.rs index 345050822..90b3480df 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -13,6 +13,7 @@ // use std::ffi::CStr; +use std::mem::MaybeUninit; use std::ops::Deref; use std::ops::DerefMut; use std::str::FromStr; @@ -20,8 +21,10 @@ use std::str::FromStr; use crate::collections::*; use crate::decl_transmute_copy; use crate::keyexpr::*; -use crate::transmute::InplaceInit; -use crate::transmute::InplaceInitDefault; +use crate::transmute::Inplace; +use crate::transmute::InplaceDefault; +use crate::transmute::StaticRef; +use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteRef; use crate::z_congestion_control_t; use crate::z_id_t; @@ -35,6 +38,7 @@ use libc::{c_char, c_ulong}; use std::convert::Infallible; use unwrap_infallible::UnwrapInfallible; use zenoh::buffers::ZBuf; +use zenoh::encoding::Encoding; use zenoh::payload::Deserialize; use zenoh::payload::ZSerde; use zenoh::prelude::SampleKind; @@ -231,7 +235,7 @@ pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. /// pub use crate::z_encoding_t; -decl_transmute_copy!(&'static Encoding, z_encoding_t); +decl_transmute_copy!(StaticRef, z_encoding_t); /// An owned payload encoding. /// @@ -245,24 +249,24 @@ decl_transmute_ref!(default_inplace_init Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] -pub extern "C" fn z_encoding_null(encoding: &mut z_owned_encoding_t) { - encoding.transmute_mut().inplace_default(); +pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit) { + Inplace::empty(encoding); } /// Constructs a specific :c:type:`z_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_from_str( - encoding: &mut z_owned_encoding_t, + encoding: *mut MaybeUninit, s: *const c_char, ) -> i8 { if s.is_null() { - z_encoding_null(encoding); + Inplace::empty(encoding); 0 } else { let s = CStr::from_ptr(s).to_string_lossy().as_ref(); let value = Encoding::from_str(s).unwrap_infallible(); - encoding.transmute_mut().inplace_init(value); + Inplace::init(encoding, value); 0 } } @@ -271,7 +275,7 @@ pub unsafe extern "C" fn z_encoding_from_str( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - let encoding = Encoding::ZENOH_BYTES; + StaticRef::new(&Encoding::ZENOH_BYTES).transmute() } /// Frees `encoding`, invalidating it for double-drop safety. diff --git a/src/transmute.rs b/src/transmute.rs index d4f7a5678..1e4a01427 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -12,6 +12,19 @@ // ZettaScale Zenoh team, // +pub(crate) struct StaticRef(&'static T); +impl StaticRef { + pub(crate) fn new<'a>(value: &'a T) -> Self { + StaticRef(unsafe { std::mem::transmute::<&'a T, &'static T>(value) }) + } +} +impl Clone for StaticRef { + fn clone(&self) -> Self { + StaticRef(self.0) + } +} +impl Copy for StaticRef {} + pub(crate) trait TransmuteRef { fn transmute_ref(&self) -> &T; fn transmute_mut(&mut self) -> &mut T; @@ -21,35 +34,37 @@ pub(crate) trait TransmuteCopy: TransmuteRef { fn transmute(self) -> T; } -pub(crate) trait InplaceInit: Sized { +pub(crate) trait Inplace: Sized { // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized - fn inplace_init(&mut self, value: T) -> &mut Self { - unsafe { std::ptr::write(self as *mut Self as *mut T, value) }; - self + fn init(this: *mut std::mem::MaybeUninit, value: T) { + let this = this as *mut T; + unsafe { std::ptr::write(this, value) }; } - // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized - fn inplace_default(&mut self) -> &mut Self - where - T: Default, - { - unsafe { std::ptr::write(self as *mut Self as *mut T, T::default()) }; - self + // Initialize the object in place with an empty value + fn empty(this: *mut std::mem::MaybeUninit); +} + +pub(crate) trait InplaceDrop: Sized + Inplace { + // Drop the object in place and replaces it with default value + fn drop(this: &mut Self) { + unsafe { std::ptr::drop_in_place(this as *mut Self) }; + Inplace::empty(this as *mut Self as *mut std::mem::MaybeUninit); } } -pub(crate) trait InplaceInitDefault: Default { +pub(crate) trait InplaceDefault: Default { // Default implementation of inplace_init for object implementing Default trait. May be less efficient than a custom implementation - // because it involves a copy of the default value. - fn inplace_default_impl(&mut self) { - unsafe { std::ptr::write(self as *mut Self, Self::default()) }; + // because for `empty` operation it performs a copy of the default value from stack to provided memory + fn default(this: *mut std::mem::MaybeUninit) { + let this = this as *mut Self; + unsafe { std::ptr::write(this, ::default()) }; } } // For types implementing Default, we can use provide default implementation of InplaceInit through InplaceInitDefault -impl InplaceInit for T { - fn inplace_default(&mut self) -> &mut Self { - self.inplace_default_impl(); - self +impl Inplace for T { + fn empty(this: *mut std::mem::MaybeUninit) { + InplaceDefault::default(this); } } @@ -85,7 +100,7 @@ macro_rules! validate_equivalence { #[macro_export] macro_rules! decl_transmute_ref { (default_inplace_init $zenoh_type:ty, $c_type:ty) => { - impl InplaceInitDefault for $zenoh_type {} + impl InplaceDefault for $zenoh_type {} decl_transmute_ref!(custom_inplace_init $zenoh_type, $c_type); }; @@ -93,14 +108,14 @@ macro_rules! decl_transmute_ref { validate_equivalence!($zenoh_type, $c_type); impl_transmute_ref!($zenoh_type, $c_type); impl_transmute_ref!($c_type, $zenoh_type); - impl InplaceInit<$zenoh_type> for $c_type { - fn inplace_init(&mut self, value: $zenoh_type) -> &mut Self { - self.transmute_mut().inplace_init(value); - self + impl Inplace<$zenoh_type> for $c_type { + fn init(this: *mut std::mem::MaybeUninit, value: $zenoh_type) { + let this = this as *mut std::mem::MaybeUninit<$zenoh_type>; + Inplace::init(this, value); } - fn inplace_default(&mut self) -> &mut Self { - self.transmute_mut().inplace_default(); - self + fn empty(this: *mut std::mem::MaybeUninit) { + let this = this as *mut std::mem::MaybeUninit<$zenoh_type>; + Inplace::empty(this); } } } From 1ab939b87bdd11453b5e33715ec5ce614c1b23db Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 00:34:32 +0200 Subject: [PATCH 42/75] transmute encoding --- src/commons.rs | 14 +++++++------- src/transmute.rs | 9 +++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/commons.rs b/src/commons.rs index 90b3480df..ef1f8aa60 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -24,8 +24,8 @@ use crate::keyexpr::*; use crate::transmute::Inplace; use crate::transmute::InplaceDefault; use crate::transmute::StaticRef; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteRef; +use crate::transmute::TransmuteValue; use crate::z_congestion_control_t; use crate::z_id_t; use crate::z_owned_buffer_t; @@ -140,8 +140,8 @@ pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { - // let encoding = sample.encoding(); - // sample.encoding().transmute() + let encoding = sample.encoding(); + StaticRef::new(encoding).transmute_value() } /// The sample's data, the return value aliases the sample. /// @@ -275,7 +275,7 @@ pub unsafe extern "C" fn z_encoding_from_str( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - StaticRef::new(&Encoding::ZENOH_BYTES).transmute() + StaticRef::new(&Encoding::ZENOH_BYTES).transmute_value() } /// Frees `encoding`, invalidating it for double-drop safety. @@ -287,7 +287,7 @@ pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) {} #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { - let encoding = encoding.deref(); + let encoding = encoding.transmute_ref(); *encoding != Encoding::default() } @@ -295,8 +295,8 @@ pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> z_encoding_t { - let encoding = encoding.deref(); - encoding.into() + let encoding = encoding.transmute_ref(); + StaticRef::new(encoding).transmute_value() } /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` diff --git a/src/transmute.rs b/src/transmute.rs index 1e4a01427..e8dffc21e 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -30,8 +30,8 @@ pub(crate) trait TransmuteRef { fn transmute_mut(&mut self) -> &mut T; } -pub(crate) trait TransmuteCopy: TransmuteRef { - fn transmute(self) -> T; +pub(crate) trait TransmuteValue: TransmuteRef { + fn transmute_value(self) -> T; } pub(crate) trait Inplace: Sized { @@ -42,6 +42,7 @@ pub(crate) trait Inplace: Sized { } // Initialize the object in place with an empty value fn empty(this: *mut std::mem::MaybeUninit); + // TODO: for effective inplace_init, we can provide a method that takes a closure that initializes the object in place } pub(crate) trait InplaceDrop: Sized + Inplace { @@ -147,8 +148,8 @@ macro_rules! impl_transmute_ref { macro_rules! impl_transmute_copy { ($src_type:ty, $dst_type:ty) => { - impl $crate::transmute::TransmuteCopy<$dst_type> for $src_type { - fn transmute(self) -> $dst_type { + impl $crate::transmute::TransmuteValue<$dst_type> for $src_type { + fn transmute_value(self) -> $dst_type { unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } } } From 015eed1d53f0d5b84f43aa3e081d56e0f5f1b8a3 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 10:49:16 +0200 Subject: [PATCH 43/75] transmute simplified --- build-resources/opaque-types/src/lib.rs | 2 + include/zenoh_commons.h | 15 ++--- src/commons.rs | 75 +++++++++++-------------- src/transmute.rs | 63 +++++++++------------ 4 files changed, 67 insertions(+), 88 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 4a9ebd013..ca29316ad 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -42,6 +42,8 @@ get_opaque_type_data!(Option, "z_owned_buffer_t"); /// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. get_opaque_type_data!(Option, "zc_owned_sample_t"); +get_opaque_type_data!(&'static Sample, "z_sample_t"); + /// A reader for payload data. get_opaque_type_data!(ZBufReader, "zc_payload_reader"); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 689944ae2..b5f38695a 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -312,13 +312,8 @@ typedef struct z_owned_closure_reply_t { void (*call)(struct z_owned_reply_t*, void*); void (*drop)(void*); } z_owned_closure_reply_t; -/** - * A data sample. - * - * A sample is the value associated to a given resource at a given point in time. - */ -typedef struct z_sample_t { - const void *_inner; +typedef struct ALIGN(8) z_sample_t { + uint8_t _0[8]; } z_sample_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. @@ -2362,11 +2357,11 @@ struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); * unless the value has been dropped already. */ ZENOHC_API -bool zc_sample_check(const struct zc_owned_sample_t *sample); +bool zc_sample_check(const struct z_sample_t *sample); /** * Clone a sample in the cheapest way available. */ -ZENOHC_API struct zc_owned_sample_t zc_sample_clone(const struct z_sample_t *sample); +ZENOHC_API void zc_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); /** * Destroy the sample. */ @@ -2377,7 +2372,7 @@ ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); * Calling this function using a dropped sample is undefined behaviour. */ ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); -ZENOHC_API struct zc_owned_sample_t zc_sample_null(void); +ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); /** * Increments the session's reference count, returning a new owning handle. */ diff --git a/src/commons.rs b/src/commons.rs index ef1f8aa60..a423bc206 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -15,27 +15,21 @@ use std::ffi::CStr; use std::mem::MaybeUninit; use std::ops::Deref; -use std::ops::DerefMut; use std::str::FromStr; -use crate::collections::*; use crate::decl_transmute_copy; use crate::keyexpr::*; +use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; use crate::transmute::InplaceDefault; -use crate::transmute::StaticRef; +use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteRef; -use crate::transmute::TransmuteValue; -use crate::z_congestion_control_t; use crate::z_id_t; use crate::z_owned_buffer_t; -use crate::z_priority_t; use crate::zc_owned_payload_t; use crate::zc_payload_t; -use crate::{impl_guarded_transmute, GuardedTransmute}; use libc::c_void; use libc::{c_char, c_ulong}; -use std::convert::Infallible; use unwrap_infallible::UnwrapInfallible; use zenoh::buffers::ZBuf; use zenoh::encoding::Encoding; @@ -111,37 +105,22 @@ impl From> for z_timestamp_t { /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. -#[repr(C)] -pub struct z_sample_t<'a> { - _inner: &'a (), -} -impl<'a> core::ops::Deref for z_sample_t<'a> { - type Target = Sample; - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute::<&(), &Sample>(self._inner) } - } -} - -impl<'a> z_sample_t<'a> { - pub fn new(sample: &'a Sample) -> Self { - z_sample_t { - _inner: unsafe { core::mem::transmute(sample) }, - } - } -} +use crate::z_sample_t; +decl_transmute_copy!(&'static Option, z_sample_t); /// The Key Expression of the sample. /// /// `sample` is aliased by its return value. #[no_mangle] pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { + let sample = unwrap_ref_unchecked(sample.transmute_copy()); sample.key_expr().into() } /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { - let encoding = sample.encoding(); - StaticRef::new(encoding).transmute_value() + let sample = unwrap_ref_unchecked(sample.transmute_copy()); + sample.encoding().transmute_copy() } /// The sample's data, the return value aliases the sample. /// @@ -151,6 +130,7 @@ pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { // TODO: here returning reference not to sample's payload, but to temporary copy // THIS WILL CRASH FOR SURE, MADE IT ONLY TO MAKE IT COMPILE // Need a way to get reference to sample's payload + let sample = unwrap_ref_unchecked(sample.transmute_copy()); let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); let owned_buffer: z_owned_buffer_t = Some(buffer).into(); owned_buffer.as_ref().into() @@ -162,6 +142,7 @@ pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { /// affect the samples received by other subscribers. #[no_mangle] pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { + let sample = unwrap_ref_unchecked(sample.transmute_copy()); let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); let owned_buffer: z_owned_buffer_t = Some(buffer).into(); owned_buffer.into() @@ -169,11 +150,13 @@ pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payloa /// The sample's kind (put or delete). #[no_mangle] pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { + let sample = unwrap_ref_unchecked(sample.transmute_copy()); sample.kind().into() } /// The samples timestamp #[no_mangle] pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { + let sample = unwrap_ref_unchecked(sample.transmute_copy()); sample.timestamp().into() } /// The qos with which the sample was received. @@ -184,6 +167,7 @@ pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { /// `sample` is aliased by the return value. #[no_mangle] pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { + let sample = unwrap_ref_unchecked(sample.transmute_copy()); match sample.attachment() { Some(attachment) => z_attachment_t { data: attachment as *const _ as *mut c_void, @@ -194,12 +178,15 @@ pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { } pub use crate::zc_owned_sample_t; -impl_guarded_transmute!(Option, zc_owned_sample_t); +decl_transmute_ref!(default_inplace_init Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] -pub extern "C" fn zc_sample_clone(sample: &z_sample_t) -> zc_owned_sample_t { - Some(sample.deref().clone()).into() +pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { + let src = unwrap_ref_unchecked(src.transmute_copy()); + let src = src.deref().clone(); + let dst = zc_owned_sample_t::transmute_uninit_ptr(dst); + Inplace::init(dst, Some(src)); } /// Returns `true` if `sample` is valid. @@ -207,7 +194,8 @@ pub extern "C" fn zc_sample_clone(sample: &z_sample_t) -> zc_owned_sample_t { /// Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed /// unless the value has been dropped already. #[no_mangle] -pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { +pub extern "C" fn zc_sample_check(sample: &z_sample_t) -> bool { + let sample = sample.transmute_copy(); sample.is_some() } @@ -216,18 +204,20 @@ pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> z_sample_t { - z_sample_t::new(unsafe { sample.as_ref().unwrap_unchecked() }) + sample.transmute_ref().transmute_copy() } /// Destroy the sample. #[no_mangle] pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { - core::mem::drop(sample.take()); + let sample = sample.transmute_mut(); + Inplace::drop(sample); } #[no_mangle] -pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { - None.into() +pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { + let sample = zc_owned_sample_t::transmute_uninit_ptr(sample); + Inplace::empty(sample); } /// The encoding of a payload, in a MIME-like format. @@ -235,7 +225,7 @@ pub extern "C" fn zc_sample_null() -> zc_owned_sample_t { /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. /// pub use crate::z_encoding_t; -decl_transmute_copy!(StaticRef, z_encoding_t); +decl_transmute_copy!(&'static Encoding, z_encoding_t); /// An owned payload encoding. /// @@ -250,6 +240,7 @@ decl_transmute_ref!(default_inplace_init Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit) { + let encoding = z_owned_encoding_t::transmute_uninit_ptr(encoding); Inplace::empty(encoding); } @@ -260,6 +251,7 @@ pub unsafe extern "C" fn z_encoding_from_str( encoding: *mut MaybeUninit, s: *const c_char, ) -> i8 { + let encoding = z_owned_encoding_t::transmute_uninit_ptr(encoding); if s.is_null() { Inplace::empty(encoding); 0 @@ -275,7 +267,7 @@ pub unsafe extern "C" fn z_encoding_from_str( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - StaticRef::new(&Encoding::ZENOH_BYTES).transmute_value() + (&Encoding::ZENOH_BYTES).transmute_copy() } /// Frees `encoding`, invalidating it for double-drop safety. @@ -286,7 +278,7 @@ pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) {} /// Returns ``true`` if `encoding` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { +pub extern "C" fn z_encoding_check(encoding: &'static z_owned_encoding_t) -> bool { let encoding = encoding.transmute_ref(); *encoding != Encoding::default() } @@ -294,9 +286,8 @@ pub extern "C" fn z_encoding_check(encoding: &z_owned_encoding_t) -> bool { /// Returns a :c:type:`z_encoding_t` loaned from `encoding`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> z_encoding_t { - let encoding = encoding.transmute_ref(); - StaticRef::new(encoding).transmute_value() +pub extern "C" fn z_encoding_loan(encoding: &'static z_owned_encoding_t) -> z_encoding_t { + encoding.transmute_ref().transmute_copy() } /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` diff --git a/src/transmute.rs b/src/transmute.rs index e8dffc21e..76b9ac9b1 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -12,45 +12,46 @@ // ZettaScale Zenoh team, // -pub(crate) struct StaticRef(&'static T); -impl StaticRef { - pub(crate) fn new<'a>(value: &'a T) -> Self { - StaticRef(unsafe { std::mem::transmute::<&'a T, &'static T>(value) }) - } -} -impl Clone for StaticRef { - fn clone(&self) -> Self { - StaticRef(self.0) - } +// pub fn as_static_ref<'a, T: 'a>(value: &'a T) -> &'static T { +// unsafe { std::mem::transmute::<&'a T, &'static T>(value) } +// } + +pub fn unwrap_ref_unchecked(value: &Option) -> &T { + debug_assert!(value.is_some()); + unsafe { value.as_ref().unwrap_unchecked() } } -impl Copy for StaticRef {} -pub(crate) trait TransmuteRef { +pub(crate) trait TransmuteRef: Sized { fn transmute_ref(&self) -> &T; fn transmute_mut(&mut self) -> &mut T; + fn transmute_uninit_ptr( + this: *mut std::mem::MaybeUninit, + ) -> *mut std::mem::MaybeUninit { + this as *mut std::mem::MaybeUninit + } } -pub(crate) trait TransmuteValue: TransmuteRef { - fn transmute_value(self) -> T; +pub(crate) trait TransmuteCopy: TransmuteRef { + fn transmute_copy(self) -> T; } -pub(crate) trait Inplace: Sized { +pub(crate) trait Inplace: Sized { // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized - fn init(this: *mut std::mem::MaybeUninit, value: T) { - let this = this as *mut T; + fn init(this: *mut std::mem::MaybeUninit, value: Self) { + let this = this as *mut Self; unsafe { std::ptr::write(this, value) }; } + // Initialize the object in place with an empty value fn empty(this: *mut std::mem::MaybeUninit); - // TODO: for effective inplace_init, we can provide a method that takes a closure that initializes the object in place -} -pub(crate) trait InplaceDrop: Sized + Inplace { - // Drop the object in place and replaces it with default value + // Drop the object in place and replaces it with empty value fn drop(this: &mut Self) { - unsafe { std::ptr::drop_in_place(this as *mut Self) }; - Inplace::empty(this as *mut Self as *mut std::mem::MaybeUninit); + let this = this as *mut Self; + unsafe { std::ptr::drop_in_place(this) }; + Inplace::empty(this as *mut std::mem::MaybeUninit); } + // TODO: for effective inplace_init, we can provide a method that takes a closure that initializes the object in place } pub(crate) trait InplaceDefault: Default { @@ -63,7 +64,7 @@ pub(crate) trait InplaceDefault: Default { } // For types implementing Default, we can use provide default implementation of InplaceInit through InplaceInitDefault -impl Inplace for T { +impl Inplace for T { fn empty(this: *mut std::mem::MaybeUninit) { InplaceDefault::default(this); } @@ -109,16 +110,6 @@ macro_rules! decl_transmute_ref { validate_equivalence!($zenoh_type, $c_type); impl_transmute_ref!($zenoh_type, $c_type); impl_transmute_ref!($c_type, $zenoh_type); - impl Inplace<$zenoh_type> for $c_type { - fn init(this: *mut std::mem::MaybeUninit, value: $zenoh_type) { - let this = this as *mut std::mem::MaybeUninit<$zenoh_type>; - Inplace::init(this, value); - } - fn empty(this: *mut std::mem::MaybeUninit) { - let this = this as *mut std::mem::MaybeUninit<$zenoh_type>; - Inplace::empty(this); - } - } } } @@ -148,8 +139,8 @@ macro_rules! impl_transmute_ref { macro_rules! impl_transmute_copy { ($src_type:ty, $dst_type:ty) => { - impl $crate::transmute::TransmuteValue<$dst_type> for $src_type { - fn transmute_value(self) -> $dst_type { + impl $crate::transmute::TransmuteCopy<$dst_type> for $src_type { + fn transmute_copy(self) -> $dst_type { unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } } } From fd2153bd8b659a347b2d34e517632fc22495d537 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 12:39:29 +0200 Subject: [PATCH 44/75] explicit opaque types, renaming --- include/zenoh_commons.h | 2 +- src/commons.rs | 55 +++++++++++++++++++---------------------- src/lib.rs | 3 +-- src/transmute.rs | 4 +-- 4 files changed, 30 insertions(+), 34 deletions(-) diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index b5f38695a..90d1ee819 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -2357,7 +2357,7 @@ struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); * unless the value has been dropped already. */ ZENOHC_API -bool zc_sample_check(const struct z_sample_t *sample); +bool zc_sample_check(const struct zc_owned_sample_t *sample); /** * Clone a sample in the cheapest way available. */ diff --git a/src/commons.rs b/src/commons.rs index a423bc206..902a2361f 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -17,15 +17,14 @@ use std::mem::MaybeUninit; use std::ops::Deref; use std::str::FromStr; -use crate::decl_transmute_copy; use crate::keyexpr::*; +use crate::opaque_types::z_owned_buffer_t; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; use crate::transmute::InplaceDefault; use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteRef; use crate::z_id_t; -use crate::z_owned_buffer_t; use crate::zc_owned_payload_t; use crate::zc_payload_t; use libc::c_void; @@ -105,21 +104,21 @@ impl From> for z_timestamp_t { /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. -use crate::z_sample_t; -decl_transmute_copy!(&'static Option, z_sample_t); +use crate::opaque_types::z_sample_t; +decl_transmute_copy!(&'static Sample, z_sample_t); /// The Key Expression of the sample. /// /// `sample` is aliased by its return value. #[no_mangle] pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); sample.key_expr().into() } /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); sample.encoding().transmute_copy() } /// The sample's data, the return value aliases the sample. @@ -130,7 +129,7 @@ pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { // TODO: here returning reference not to sample's payload, but to temporary copy // THIS WILL CRASH FOR SURE, MADE IT ONLY TO MAKE IT COMPILE // Need a way to get reference to sample's payload - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); let owned_buffer: z_owned_buffer_t = Some(buffer).into(); owned_buffer.as_ref().into() @@ -142,7 +141,7 @@ pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { /// affect the samples received by other subscribers. #[no_mangle] pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); let owned_buffer: z_owned_buffer_t = Some(buffer).into(); owned_buffer.into() @@ -150,13 +149,13 @@ pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payloa /// The sample's kind (put or delete). #[no_mangle] pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); sample.kind().into() } /// The samples timestamp #[no_mangle] pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); sample.timestamp().into() } /// The qos with which the sample was received. @@ -167,7 +166,7 @@ pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { /// `sample` is aliased by the return value. #[no_mangle] pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { - let sample = unwrap_ref_unchecked(sample.transmute_copy()); + let sample = sample.transmute_copy(); match sample.attachment() { Some(attachment) => z_attachment_t { data: attachment as *const _ as *mut c_void, @@ -177,13 +176,13 @@ pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { } } -pub use crate::zc_owned_sample_t; -decl_transmute_ref!(default_inplace_init Option, zc_owned_sample_t); +pub use crate::opaque_types::zc_owned_sample_t; +decl_transmute_owned!(default_inplace_init Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { - let src = unwrap_ref_unchecked(src.transmute_copy()); + let src = src.transmute_copy(); let src = src.deref().clone(); let dst = zc_owned_sample_t::transmute_uninit_ptr(dst); Inplace::init(dst, Some(src)); @@ -194,8 +193,8 @@ pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit bool { - let sample = sample.transmute_copy(); +pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { + let sample = sample.transmute_ref(); sample.is_some() } @@ -204,27 +203,25 @@ pub extern "C" fn zc_sample_check(sample: &z_sample_t) -> bool { /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> z_sample_t { - sample.transmute_ref().transmute_copy() + unwrap_ref_unchecked(sample.transmute_ref()).transmute_copy() } /// Destroy the sample. #[no_mangle] pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { - let sample = sample.transmute_mut(); - Inplace::drop(sample); + Inplace::drop(sample.transmute_mut()); } #[no_mangle] pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { - let sample = zc_owned_sample_t::transmute_uninit_ptr(sample); - Inplace::empty(sample); + Inplace::empty(zc_owned_sample_t::transmute_uninit_ptr(sample)); } /// The encoding of a payload, in a MIME-like format. /// /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. /// -pub use crate::z_encoding_t; +pub use crate::opaque_types::z_encoding_t; decl_transmute_copy!(&'static Encoding, z_encoding_t); /// An owned payload encoding. @@ -234,14 +231,13 @@ decl_transmute_copy!(&'static Encoding, z_encoding_t); /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -pub use crate::z_owned_encoding_t; -decl_transmute_ref!(default_inplace_init Encoding, z_owned_encoding_t); +pub use crate::opaque_types::z_owned_encoding_t; +decl_transmute_owned!(default_inplace_init Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit) { - let encoding = z_owned_encoding_t::transmute_uninit_ptr(encoding); - Inplace::empty(encoding); + Inplace::empty(z_owned_encoding_t::transmute_uninit_ptr(encoding)); } /// Constructs a specific :c:type:`z_encoding_t`. @@ -273,14 +269,15 @@ pub extern "C" fn z_encoding_default() -> z_encoding_t { /// Frees `encoding`, invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) {} +pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { + Inplace::drop(encoding); +} /// Returns ``true`` if `encoding` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_check(encoding: &'static z_owned_encoding_t) -> bool { - let encoding = encoding.transmute_ref(); - *encoding != Encoding::default() + *encoding.transmute_ref() != Encoding::default() } /// Returns a :c:type:`z_encoding_t` loaned from `encoding`. diff --git a/src/lib.rs b/src/lib.rs index 90a7f27c5..90b185add 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,9 +59,8 @@ mod querying_subscriber; pub use querying_subscriber::*; pub mod attachment; pub use platform::*; -pub mod platform; -pub use opaque_types::*; pub mod opaque_types; +pub mod platform; #[cfg(feature = "shared-memory")] mod shm; diff --git a/src/transmute.rs b/src/transmute.rs index 76b9ac9b1..2eccd4117 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -100,10 +100,10 @@ macro_rules! validate_equivalence { } #[macro_export] -macro_rules! decl_transmute_ref { +macro_rules! decl_transmute_owned { (default_inplace_init $zenoh_type:ty, $c_type:ty) => { impl InplaceDefault for $zenoh_type {} - decl_transmute_ref!(custom_inplace_init $zenoh_type, $c_type); + decl_transmute_owned!(custom_inplace_init $zenoh_type, $c_type); }; (custom_inplace_init $zenoh_type:ty, $c_type:ty) => { From 758eb2f03a0f4a1b0f336f735fce639f0a7b4595 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 19:45:06 +0200 Subject: [PATCH 45/75] more structs converted --- build-resources/opaque-types/Cargo.lock | 27 ++++++ build-resources/opaque-types/Cargo.toml | 6 +- build-resources/opaque-types/src/lib.rs | 18 ++++ include/zenoh_commons.h | 118 +----------------------- include/zenoh_concrete.h | 31 +------ src/get.rs | 68 ++++---------- src/info.rs | 2 +- src/keyexpr.rs | 7 +- src/lib.rs | 5 +- src/liveliness.rs | 5 +- src/payload.rs | 10 +- src/publication_cache.rs | 2 - src/publisher.rs | 3 +- src/put.rs | 1 - src/queryable.rs | 81 +++++----------- src/querying_subscriber.rs | 63 +++++-------- src/transmute.rs | 2 +- 17 files changed, 143 insertions(+), 306 deletions(-) diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock index d7276add6..5ed408409 100644 --- a/build-resources/opaque-types/Cargo.lock +++ b/build-resources/opaque-types/Cargo.lock @@ -340,6 +340,15 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -1196,6 +1205,7 @@ name = "opaque-types" version = "0.1.0" dependencies = [ "zenoh", + "zenoh-ext", ] [[package]] @@ -2523,6 +2533,23 @@ dependencies = [ "zenoh-result", ] +[[package]] +name = "zenoh-ext" +version = "0.11.0-dev" +dependencies = [ + "bincode", + "env_logger", + "flume", + "futures", + "log", + "phf", + "serde", + "serde_cbor", + "serde_json", + "tokio", + "zenoh", +] + [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" diff --git a/build-resources/opaque-types/Cargo.toml b/build-resources/opaque-types/Cargo.toml index 51bf417a7..93f88d05d 100644 --- a/build-resources/opaque-types/Cargo.toml +++ b/build-resources/opaque-types/Cargo.toml @@ -8,4 +8,8 @@ edition = "2021" [dependencies] # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` # zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } -zenoh = { path="../../../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } \ No newline at end of file +zenoh = { path = "../../../zenoh/zenoh", features = [ + "shared-memory", + "unstable", +], default-features = false } +zenoh-ext = { path = "../../../zenoh/zenoh-ext", features = ["unstable"] } diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index ca29316ad..698646271 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -2,9 +2,16 @@ use zenoh::buffers::{ZBuf, ZBufReader}; use zenoh::encoding::Encoding; use zenoh::query::Reply; use zenoh::queryable::Query; +use zenoh::queryable::Queryable; use zenoh::sample::Sample; use zenoh::value::Value; +// Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. +// pub struct FetchingSubscriberWrapper { +// fetching_subscriber: zenoh_ext::FetchingSubscriber<'static, ()>, +// session: z_session_t, +// } + #[macro_export] macro_rules! get_opaque_type_data { ($src_type:ty, $expr:expr) => { @@ -53,3 +60,14 @@ get_opaque_type_data!(Option, "z_owned_reply_t"); get_opaque_type_data!(Value, "z_owned_value_t"); get_opaque_type_data!(&'static Value, "z_value_t"); get_opaque_type_data!(Option, "z_owned_query_t"); +get_opaque_type_data!(&'static Query, "z_query_t"); +get_opaque_type_data!(Option>, "z_owned_queryable_t"); +get_opaque_type_data!(&'static Queryable<'static, ()>, "z_queryable_t"); +// get_opaque_type_data!( +// Option>, +// "ze_owned_querying_subscriber_t" +// ); +// get_opaque_type_data!( +// &'static FetchingSubscriberWrapper, +// "ze_querying_subscriber_t" +// ); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 90d1ee819..0d5331ab6 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -842,46 +842,6 @@ typedef struct ze_publication_cache_options_t { size_t history; size_t resources_limit; } ze_publication_cache_options_t; -/** - * An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. - * - * Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ze_owned_querying_subscriber_t { - size_t _0[1]; -} ze_owned_querying_subscriber_t; -/** - * Represents the set of options that can be applied to a querying subscriber, - * upon its declaration via :c:func:`ze_declare_querying_subscriber`. - * - * Members: - * z_reliability_t reliability: The subscription reliability. - * zcu_locality_t allowed_origin: The restriction for the matching publications that will be - * receive by this subscriber. - * z_keyexpr_t query_selector: The selector to be used for queries. - * z_query_target_t query_target: The target to be used for queries. - * z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. - * zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. - * uint64_t query_timeout_ms: The timeout to be used for queries. - */ -typedef struct ze_querying_subscriber_options_t { - enum zcu_locality_t allowed_origin; - struct z_keyexpr_t query_selector; - enum z_query_target_t query_target; - struct z_query_consolidation_t query_consolidation; - enum zcu_reply_keyexpr_t query_accept_replies; - uint64_t query_timeout_ms; -} ze_querying_subscriber_options_t; -typedef struct ze_querying_subscriber_t { - const struct ze_owned_querying_subscriber_t *_0; -} ze_querying_subscriber_t; ZENOHC_API extern const unsigned int Z_ROUTER; ZENOHC_API extern const unsigned int Z_PEER; ZENOHC_API extern const unsigned int Z_CLIENT; @@ -1716,14 +1676,14 @@ ZENOHC_API struct z_owned_query_channel_t z_query_channel_null(void); * This function may not be called with the null pointer, but can be called with the gravestone value. */ ZENOHC_API -bool z_query_check(const struct z_owned_query_t *this_); +bool z_query_check(const struct z_owned_query_t *query); /** * Clones the query, allowing to keep it in an "open" state past the callback's return. * * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). */ ZENOHC_API -struct z_owned_query_t z_query_clone(const struct z_query_t *query); +struct z_owned_query_t z_query_clone(struct z_query_t query); /** * Automatic query consolidation strategy selection. * @@ -1772,7 +1732,7 @@ struct z_query_t z_query_loan(const struct z_owned_query_t *this_); /** * The gravestone value of `z_owned_query_t`. */ -ZENOHC_API struct z_owned_query_t z_query_null(void); +ZENOHC_API void z_query_null(struct z_owned_query_t *query); /** * Get a query's `value selector `_ by aliasing it. */ @@ -1819,7 +1779,7 @@ ZENOHC_API bool z_queryable_check(const struct z_owned_queryable_t *qable); /** * Constructs a null safe-to-drop value of 'z_owned_queryable_t' type */ -ZENOHC_API struct z_owned_queryable_t z_queryable_null(void); +ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. */ @@ -1879,7 +1839,7 @@ bool z_reply_is_ok(const struct z_owned_reply_t *reply); * - overwrite the pointee with this function's return value, * - you are now responsible for dropping your copy of the reply. */ -ZENOHC_API struct z_owned_reply_t z_reply_null(void); +ZENOHC_API void z_reply_null(struct z_owned_reply_t *reply); /** * Yields the contents of the reply by asserting it indicates a success. * @@ -2503,44 +2463,6 @@ ZENOHC_API struct ze_owned_publication_cache_t ze_declare_publication_cache(struct z_session_t session, struct z_keyexpr_t keyexpr, const struct ze_publication_cache_options_t *options); -/** - * Declares a Querying Subscriber for a given key expression. - * - * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t keyexpr: The key expression to subscribe. - * z_owned_closure_sample_t callback: The callback function that will be called each time a data matching the subscribed expression is received. - * ze_querying_subscriber_options_t options: Additional options for the querying subscriber. - * - * Returns: - * :c:type:`ze_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the querying subscriber is still valid, - * you may use `ze_querying_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a subscriber passing ``NULL`` for the options: - * - * .. code-block:: C - * - * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); - * - * is equivalent to initializing and passing the default subscriber options: - * - * .. code-block:: C - * - * z_subscriber_options_t opts = z_subscriber_options_default(); - * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); - */ -ZENOHC_API -struct ze_owned_querying_subscriber_t ze_declare_querying_subscriber(struct z_session_t session, - struct z_keyexpr_t keyexpr, - struct z_owned_closure_sample_t *callback, - const struct ze_querying_subscriber_options_t *options); /** * Returns ``true`` if `pub_cache` is valid. */ @@ -2553,38 +2475,8 @@ ZENOHC_API struct ze_owned_publication_cache_t ze_publication_cache_null(void); * Constructs the default value for :c:type:`ze_publication_cache_options_t`. */ ZENOHC_API struct ze_publication_cache_options_t ze_publication_cache_options_default(void); -/** - * Returns ``true`` if `sub` is valid. - */ -ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subscriber_t *sub); -/** - * Make a :c:type:`ze_owned_querying_subscriber_t` to perform an additional query on a specified selector. - * The queried samples will be merged with the received publications and made available in the subscriber callback. - */ -ZENOHC_API -int8_t ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, - struct z_keyexpr_t selector, - const struct z_get_options_t *options); -/** - * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `p`. - */ -ZENOHC_API -struct ze_querying_subscriber_t ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *p); -/** - * Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type - */ -ZENOHC_API struct ze_owned_querying_subscriber_t ze_querying_subscriber_null(void); -/** - * Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. - */ -ZENOHC_API struct ze_querying_subscriber_options_t ze_querying_subscriber_options_default(void); /** * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. */ ZENOHC_API int8_t ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *pub_cache); -/** - * Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -int8_t ze_undeclare_querying_subscriber(struct ze_owned_querying_subscriber_t *sub); diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 8572e956b..491551ee1 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -36,14 +36,8 @@ typedef struct z_owned_session_t { size_t _0; } z_owned_session_t; -/** - * Loaned variant of a Query received by a Queryable. - * - * Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. - * `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. - */ -typedef struct z_query_t { - void *_0; +typedef struct ALIGN(8) z_query_t { + uint8_t _0[8]; } z_query_t; /** * A loaned zenoh session. @@ -51,28 +45,9 @@ typedef struct z_query_t { typedef struct z_session_t { size_t _0; } z_session_t; -/** - * An owned zenoh queryable. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) typedef struct ALIGN(8) z_owned_queryable_t { - uint64_t _0[4]; + uint8_t _0[32]; } z_owned_queryable_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_owned_queryable_t { - uint32_t _0[4]; -} z_owned_queryable_t; -#endif /** * An owned zenoh subscriber. Destroying the subscriber cancels the subscription. * diff --git a/src/get.rs b/src/get.rs index 37ed192e0..5274a86b5 100644 --- a/src/get.rs +++ b/src/get.rs @@ -14,6 +14,7 @@ use libc::c_char; use libc::c_void; +use std::mem::MaybeUninit; use std::{ convert::TryFrom, ffi::CStr, @@ -31,23 +32,23 @@ use zenoh::{ sample::AttachmentBuilder, value::Value, }; -use zenoh_util::core::{zresult::ErrNo, SyncResolve}; use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, z_attachment_t, }; +use crate::transmute::Inplace; +use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteRef; use crate::z_encoding_default; use crate::zc_owned_payload_t; use crate::zc_payload_null; use crate::zc_payload_t; use crate::{ - impl_guarded_transmute, z_closure_reply_call, z_encoding_t, z_keyexpr_t, - z_owned_closure_reply_t, z_sample_t, z_session_t, GuardedTransmute, LOG_INVALID_SESSION, + opaque_types::z_sample_t, z_closure_reply_call, z_encoding_t, z_keyexpr_t, + z_owned_closure_reply_t, z_session_t, LOG_INVALID_SESSION, }; -type ReplyInner = Option; - /// An owned reply to a :c:func:`z_get`. /// /// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. @@ -55,36 +56,16 @@ type ReplyInner = Option; /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. -pub use crate::z_owned_reply_t; -impl_guarded_transmute!(noderefs ReplyInner, z_owned_reply_t); +pub use crate::opaque_types::z_owned_reply_t; +decl_transmute_owned!(default_inplace_init Option, z_owned_reply_t); -impl From for z_owned_reply_t { - fn from(val: ReplyInner) -> Self { - val.transmute() - } -} -impl From for z_owned_reply_t { - fn from(val: Reply) -> z_owned_reply_t { - Some(val).into() - } -} -impl Deref for z_owned_reply_t { - type Target = ReplyInner; - fn deref(&self) -> &Self::Target { - unsafe { std::mem::transmute::<&Self, &Self::Target>(self) } - } -} -impl DerefMut for z_owned_reply_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { std::mem::transmute::<&mut Self, &mut Self::Target>(self) } - } -} /// Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. /// /// If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_is_ok(reply: &z_owned_reply_t) -> bool { + let reply = reply.transmute_ref(); reply.as_ref().map(|r| r.sample.is_ok()).unwrap_or(false) } @@ -94,8 +75,9 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: &z_owned_reply_t) -> bool { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { + let reply = reply.transmute_ref(); if let Some(sample) = reply.as_ref().and_then(|s| s.sample.as_ref().ok()) { - z_sample_t::new(sample) + sample.transmute_copy() } else { panic!("Assertion failed: tried to treat `z_owned_reply_t` as Ok despite that not being the case") } @@ -104,21 +86,10 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { /// A zenoh value. /// /// -pub use crate::z_owned_value_t; -impl_guarded_transmute!(Value, z_owned_value_t); -pub use crate::z_value_t; -impl_guarded_transmute!(&'static Value, z_value_t); - -const Z_VALUE_NULL: Value = Value::empty(); - -impl From> for z_value_t { - fn from(val: Option<&Value>) -> Self { - match val { - Some(val) => val.transmute(), - None => (&Z_VALUE_NULL).transmute(), - } - } -} +pub use crate::opaque_types::z_owned_value_t; +decl_transmute_owned!(default_inplace_init Value, z_owned_value_t); +pub use crate::opaque_types::z_value_t; +decl_transmute_copy!(&'static Value, z_value_t); /// Yields the contents of the reply by asserting it indicates a failure. /// @@ -126,8 +97,9 @@ impl From> for z_value_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { - if let Some(inner) = reply.as_ref().and_then(|s| s.sample.as_ref().err()) { - inner.into() + let reply = reply.transmute_ref(); + if let Some(value) = reply.as_ref().and_then(|s| s.sample.as_ref().err()) { + value.into() } else { panic!("Assertion failed: tried to treat `z_owned_reply_t` as Err despite that not being the case") } @@ -142,8 +114,8 @@ pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { /// - you are now responsible for dropping your copy of the reply. #[no_mangle] #[allow(improper_ctypes_definitions)] -pub extern "C" fn z_reply_null() -> z_owned_reply_t { - None.into() +pub extern "C" fn z_reply_null(reply: *mut MaybeUninit) { + Inplace::empty(z_owned_reply_t::transmute_uninit_ptr(reply)); } /// Options passed to the :c:func:`z_get` function. diff --git a/src/info.rs b/src/info.rs index 11ef031b3..2ee4d9384 100644 --- a/src/info.rs +++ b/src/info.rs @@ -12,9 +12,9 @@ // ZettaScale Zenoh team, // use crate::{session::*, z_closure_zid_call, z_owned_closure_zid_t}; +use zenoh::config::ZenohId; use zenoh::prelude::sync::SyncResolve; use zenoh::session::SessionDeclarations; -use zenoh_protocol::core::ZenohId; /// Represents a Zenoh ID. /// diff --git a/src/keyexpr.rs b/src/keyexpr.rs index c88b01199..6b7adeacf 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -28,7 +28,6 @@ use zenoh::core::SyncResolve; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::KeyExpr; -use zenoh_util::core::zresult::ErrNo; /// A zenoh-allocated key expression. /// @@ -46,11 +45,11 @@ use zenoh_util::core::zresult::ErrNo; /// - A pure numerical id. /// - The combination of a numerical prefix and a string suffix. /// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. /// /// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. diff --git a/src/lib.rs b/src/lib.rs index 90b185add..547d9178d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,8 +55,9 @@ use libc::c_void; pub use liveliness::*; mod publication_cache; pub use publication_cache::*; -mod querying_subscriber; -pub use querying_subscriber::*; +// Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. +// mod querying_subscriber; +// pub use querying_subscriber::*; pub mod attachment; pub use platform::*; pub mod opaque_types; diff --git a/src/liveliness.rs b/src/liveliness.rs index b3c61a7de..46ec7c8a5 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -16,11 +16,10 @@ use zenoh::{ liveliness::{Liveliness, LivelinessToken}, prelude::SessionDeclarations, }; -use zenoh_util::core::{zresult::ErrNo, SyncResolve}; use crate::{ - z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, z_owned_closure_reply_t, - z_owned_closure_sample_t, z_owned_subscriber_t, z_sample_t, z_session_t, + opaque_types::z_sample_t, z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, + z_owned_closure_reply_t, z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t, }; /// A liveliness token that can be used to provide the network with information about connectivity to its diff --git a/src/payload.rs b/src/payload.rs index fa6603de6..b77b46dd7 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,4 +1,5 @@ use core::slice; +use std::mem::MaybeUninit; use std::slice::from_raw_parts_mut; use std::{any::Any, ops::Deref, ptr::NonNull}; @@ -12,7 +13,7 @@ use crate::{ z_str_null, GuardedTransmute, }; -pub use crate::z_owned_buffer_t; +pub use crate::opaque_types::z_owned_buffer_t; impl_guarded_transmute!(Option, z_owned_buffer_t); impl Default for z_owned_buffer_t { @@ -247,9 +248,8 @@ pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { z_buffer_len(payload) } -pub use crate::zc_payload_reader; -impl_guarded_transmute!(ZBufReader<'static>, zc_payload_reader); -impl_guarded_transmute!(noderefs zc_payload_reader, ZBufReader<'static>); +pub use crate::opaque_types::zc_payload_reader; +decl_transmute_copy!(ZBufReader<'static>, zc_payload_reader); /// Creates a reader for the specified `payload`. /// @@ -258,7 +258,7 @@ impl_guarded_transmute!(noderefs zc_payload_reader, ZBufReader<'static>); #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_payload_reader_init( payload: zc_payload_t, - reader: *mut zc_payload_reader, + reader: *mut MaybeUninit, ) -> i8 { if payload._inner.is_none() { return -1; diff --git a/src/publication_cache.rs b/src/publication_cache.rs index ee4c85959..50e1dad47 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -15,8 +15,6 @@ use std::ops::Deref; use zenoh_ext::SessionExt; -use zenoh_util::core::zresult::ErrNo; -use zenoh_util::core::SyncResolve; use crate::{ impl_guarded_transmute, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t, diff --git a/src/publisher.rs b/src/publisher.rs index 47f2bb71f..c829a8533 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -17,6 +17,7 @@ use crate::zcu_owned_closure_matching_status_t; use std::ops::{Deref, DerefMut}; use zenoh::encoding::Encoding; use zenoh::prelude::SessionDeclarations; +use zenoh::publication::CongestionControl; use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; @@ -26,8 +27,6 @@ use zenoh::{ publication::Publisher, sample::AttachmentBuilder, }; -use zenoh_protocol::core::CongestionControl; -use zenoh_util::core::{zresult::ErrNo, SyncResolve}; use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, diff --git a/src/put.rs b/src/put.rs index a0c2e88d0..59e9e5e3c 100644 --- a/src/put.rs +++ b/src/put.rs @@ -24,7 +24,6 @@ use zenoh::sample::AttachmentBuilder; use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; -use zenoh_util::core::zresult::ErrNo; use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, diff --git a/src/queryable.rs b/src/queryable.rs index 2fd38d296..30baf5af2 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -15,22 +15,22 @@ use crate::attachment::{ attachment_iteration_driver, insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, z_attachment_t, }; +use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteRef}; use crate::{ - impl_guarded_transmute, z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, - z_keyexpr_t, z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, zc_payload_t, + z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, z_keyexpr_t, + z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, zc_payload_t, LOG_INVALID_SESSION, }; use libc::c_void; +use std::mem::MaybeUninit; use std::ops::{Deref, DerefMut}; use zenoh::prelude::SessionDeclarations; use zenoh::{ prelude::Sample, - queryable::{Query, Queryable as CallbackQueryable}, + queryable::{Query, Queryable}, sample::AttachmentBuilder, }; -use zenoh_util::core::{zresult::ErrNo, SyncResolve}; -type Queryable = Option>; /// An owned zenoh queryable. /// /// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. @@ -41,52 +41,22 @@ type Queryable = Option>; /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_queryable_t([u64; 4]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_owned_queryable_t([u32; 4]); - -impl_guarded_transmute!(Queryable, z_owned_queryable_t); - -impl z_owned_queryable_t { - pub fn null() -> Self { - None.into() - } -} +pub use crate::opaque_types::z_owned_queryable_t; +decl_transmute_owned!(default_inplace_init Option>, z_owned_queryable_t); /// Constructs a null safe-to-drop value of 'z_owned_queryable_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_queryable_null() -> z_owned_queryable_t { - z_owned_queryable_t::null() +pub extern "C" fn z_queryable_null(this: *mut MaybeUninit) { + Inplace::empty(z_owned_queryable_t::transmute_uninit_ptr(this)); } -/// Loaned variant of a Query received by a Queryable. +// Loaned variant of a Query received by a Queryable. /// /// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. /// `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. -#[allow(non_camel_case_types)] -#[repr(C)] -pub struct z_query_t(*mut c_void); -impl From<&Query> for z_query_t { - fn from(value: &Query) -> Self { - z_query_t(value as *const _ as *mut _) - } -} -impl From> for z_query_t { - fn from(value: Option<&Query>) -> Self { - value.map_or(Self(core::ptr::null_mut()), Into::into) - } -} -impl Deref for z_query_t { - type Target = Option<&'static Query>; - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } -} +pub use crate::opaque_types::z_query_t; +decl_transmute_copy!(&'static Query, z_query_t); /// Owned variant of a Query received by a Queryable. /// @@ -96,46 +66,43 @@ impl Deref for z_query_t { /// /// Holding onto an `z_owned_query_t` for too long (10s by default, can be set in `z_get`'s options) will trigger a timeout error /// to be sent to the querier by the infrastructure, and new responses to the outdated query will be silently dropped. -pub use crate::z_owned_query_t; -impl_guarded_transmute!(Option, z_owned_query_t); - -// impl Drop for z_owned_query_t { -// fn drop(&mut self) { -// let _: Option = self.take(); -// } -// } +pub use crate::opaque_types::z_owned_query_t; +decl_transmute_owned!(default_inplace_init Option, z_owned_query_t); /// The gravestone value of `z_owned_query_t`. #[no_mangle] -pub extern "C" fn z_query_null() -> z_owned_query_t { - None.into() +pub extern "C" fn z_query_null(query: *mut MaybeUninit) { + Inplace::empty(z_owned_query_t::transmute_uninit_ptr(query)); } /// Returns `false` if `this` is in a gravestone state, `true` otherwise. /// /// This function may not be called with the null pointer, but can be called with the gravestone value. #[no_mangle] -pub extern "C" fn z_query_check(this: &z_owned_query_t) -> bool { - this.is_some() +pub extern "C" fn z_query_check(query: &z_owned_query_t) -> bool { + query.transmute_ref().is_some() } /// Aliases the query. /// /// This function may not be called with the null pointer, but can be called with the gravestone value. #[no_mangle] pub extern "C" fn z_query_loan(this: &z_owned_query_t) -> z_query_t { - this.as_ref().into() + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_copy() } /// Destroys the query, setting `this` to its gravestone value to prevent double-frees. /// /// This function may not be called with the null pointer, but can be called with the gravestone value. #[no_mangle] pub extern "C" fn z_query_drop(this: &mut z_owned_query_t) { - let _: Option = this.take(); + Inplace::drop(this.transmute_mut()) } /// Clones the query, allowing to keep it in an "open" state past the callback's return. /// /// This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). #[no_mangle] -pub extern "C" fn z_query_clone(query: Option<&z_query_t>) -> z_owned_query_t { +pub extern "C" fn z_query_clone(query: z_query_t) -> z_owned_query_t { + let query = query.transmute_copy(); query.and_then(|q| q.cloned()).into() } diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 6f78d6bb9..92e797e2e 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -12,70 +12,55 @@ // ZettaScale Zenoh team, // +use std::mem::MaybeUninit; + use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; use zenoh::prelude::SessionDeclarations; use zenoh_ext::*; -use zenoh_util::core::zresult::ErrNo; +use crate::z_closure_owned_query_call; +use crate::ze_owned_publication_cache_t; use crate::{ - impl_guarded_transmute, z_closure_sample_call, z_get_options_t, z_keyexpr_t, - z_owned_closure_sample_t, z_query_consolidation_none, z_query_consolidation_t, - z_query_target_default, z_query_target_t, z_sample_t, z_session_t, - zcu_locality_default, zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, - LOG_INVALID_SESSION, + impl_guarded_transmute, opaque_types::z_sample_t, z_closure_sample_call, z_get_options_t, + z_keyexpr_t, z_owned_closure_sample_t, z_query_consolidation_none, z_query_consolidation_t, + z_query_target_default, z_query_target_t, z_session_t, zcu_locality_default, zcu_locality_t, + zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, LOG_INVALID_SESSION, }; pub struct FetchingSubscriberWrapper { fetching_subscriber: zenoh_ext::FetchingSubscriber<'static, ()>, session: z_session_t, } -type FetchingSubscriber = Option>; //type FetchingSubscriber = Option>>; /// An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. /// -/// Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. /// /// Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[repr(C)] -pub struct ze_owned_querying_subscriber_t([usize; 1]); +use crate::opaque_types::ze_owned_querying_subscriber_t; +decl_transmute_owned!(default_inplace_init Option>, z_owned_querying_subscriber_t); -impl_guarded_transmute!(FetchingSubscriber, ze_owned_querying_subscriber_t); - -#[repr(C)] -#[allow(non_camel_case_types)] -pub struct ze_querying_subscriber_t<'a>(&'a ze_owned_querying_subscriber_t); - -impl<'a> AsRef for ze_querying_subscriber_t<'a> { - fn as_ref(&self) -> &FetchingSubscriber { - self.0 - } -} - -impl ze_owned_querying_subscriber_t { - pub fn new(sub: zenoh_ext::FetchingSubscriber<'static, ()>, session: z_session_t) -> Self { - Some(Box::new(FetchingSubscriberWrapper { - fetching_subscriber: sub, - session, - })) - .into() - } - pub fn null() -> Self { - None.into() - } -} +use crate::opaque_types::ze_querying_subscriber_t; +decl_transmute_copy!( + &'static Option>, + z_querying_subscriber_t +); /// Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn ze_querying_subscriber_null() -> ze_owned_querying_subscriber_t { - ze_owned_querying_subscriber_t::null() +pub extern "C" fn ze_querying_subscriber_null( + this: *mut MaybeUninit, +) { + let this = ze_owned_querying_subscriber_t::transmute_uninit_ptr(this); + Inplace::empty(this); } /// Represents the set of options that can be applied to a querying subscriber, @@ -251,6 +236,8 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn ze_undeclare_querying_subscriber(sub: &mut ze_owned_querying_subscriber_t) -> i8 { + let sub = sub.transmute_mut(); + if let Some(s) = sub.take() { if let Err(e) = s.fetching_subscriber.close().res_sync() { log::warn!("{}", e); diff --git a/src/transmute.rs b/src/transmute.rs index 2eccd4117..70ec1d863 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -102,7 +102,7 @@ macro_rules! validate_equivalence { #[macro_export] macro_rules! decl_transmute_owned { (default_inplace_init $zenoh_type:ty, $c_type:ty) => { - impl InplaceDefault for $zenoh_type {} + impl $crate::transmute::InplaceDefault for $zenoh_type {} decl_transmute_owned!(custom_inplace_init $zenoh_type, $c_type); }; From 41f2a0bae88f106e2b888762991383000033cbf1 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 20:02:21 +0200 Subject: [PATCH 46/75] commented out all, removed old macro --- include/zenoh-gen.h | 14 + include/zenoh_commons.h | 2465 -------------------------------------- include/zenoh_concrete.h | 55 - src/lib.rs | 175 +-- 4 files changed, 60 insertions(+), 2649 deletions(-) create mode 100644 include/zenoh-gen.h diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h new file mode 100644 index 000000000..0e648f1e9 --- /dev/null +++ b/include/zenoh-gen.h @@ -0,0 +1,14 @@ +#include +#include +#include +#include +#include + + +/** + * Initialises the zenoh runtime logger. + * + * Note that unless you built zenoh-c with the `logger-autoinit` feature disabled, + * this will be performed automatically by `z_open` and `z_scout`. + */ +ZENOHC_API void zc_init_logger(void); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 0d5331ab6..9ef5cb4e1 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -15,2468 +15,3 @@ #define ALIGN(n) #define ZENOHC_API #endif -/** - * The kind of congestion control. - * - * - **BLOCK** - * - **DROP** - */ -typedef enum z_congestion_control_t { - Z_CONGESTION_CONTROL_BLOCK, - Z_CONGESTION_CONTROL_DROP, -} z_congestion_control_t; -/** - * Consolidation mode values. - * - * - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector - * If the selector contains time range properties, consolidation mode `NONE` is used. - * Otherwise the `LATEST` consolidation mode is used. - * - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. - * - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time - * w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple - * replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp - * ts2 > ts1. It optimizes latency. - * - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. - * It optimizes bandwidth. - */ -typedef enum z_consolidation_mode_t { - Z_CONSOLIDATION_MODE_AUTO = -1, - Z_CONSOLIDATION_MODE_NONE = 0, - Z_CONSOLIDATION_MODE_MONOTONIC = 1, - Z_CONSOLIDATION_MODE_LATEST = 2, -} z_consolidation_mode_t; -/** - * A :c:type:`z_keyexpr_intersection_level_t`. - * - * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** - */ -typedef enum z_keyexpr_intersection_level_t { - Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT = 0, - Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS = 1, - Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES = 2, - Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS = 3, -} z_keyexpr_intersection_level_t; -/** - * The priority of zenoh messages. - * - * - **REAL_TIME** - * - **INTERACTIVE_HIGH** - * - **INTERACTIVE_LOW** - * - **DATA_HIGH** - * - **DATA** - * - **DATA_LOW** - * - **BACKGROUND** - */ -typedef enum z_priority_t { - Z_PRIORITY_REAL_TIME = 1, - Z_PRIORITY_INTERACTIVE_HIGH = 2, - Z_PRIORITY_INTERACTIVE_LOW = 3, - Z_PRIORITY_DATA_HIGH = 4, - Z_PRIORITY_DATA = 5, - Z_PRIORITY_DATA_LOW = 6, - Z_PRIORITY_BACKGROUND = 7, -} z_priority_t; -/** - * The Queryables that should be target of a :c:func:`z_get`. - * - * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. - * - **ALL_COMPLETE**: All complete queryables. - * - **ALL**: All matching queryables. - */ -typedef enum z_query_target_t { - Z_QUERY_TARGET_BEST_MATCHING, - Z_QUERY_TARGET_ALL, - Z_QUERY_TARGET_ALL_COMPLETE, -} z_query_target_t; -typedef enum z_sample_kind_t { - Z_SAMPLE_KIND_PUT = 0, - Z_SAMPLE_KIND_DELETE = 1, -} z_sample_kind_t; -typedef enum zcu_locality_t { - ZCU_LOCALITY_ANY = 0, - ZCU_LOCALITY_SESSION_LOCAL = 1, - ZCU_LOCALITY_REMOTE = 2, -} zcu_locality_t; -typedef enum zcu_reply_keyexpr_t { - ZCU_REPLY_KEYEXPR_ANY = 0, - ZCU_REPLY_KEYEXPR_MATCHING_QUERY = 1, -} zcu_reply_keyexpr_t; -/** - * A contiguous view of bytes owned by some other entity. - * - * `start` being `null` is considered a gravestone value, - * and empty slices are represented using a possibly dangling pointer for `start`. - */ -typedef struct z_bytes_t { - const uint8_t *start; - size_t len; -} z_bytes_t; -/** - * The body of a loop over an attachment's key-value pairs. - * - * `key` and `value` are loaned to the body for the duration of a single call. - * `context` is passed transparently through the iteration driver. - * - * Returning `0` is treated as `continue`. - * Returning any other value is treated as `break`. - */ -typedef int8_t (*z_attachment_iter_body_t)(struct z_bytes_t key, - struct z_bytes_t value, - void *context); -/** - * The driver of a loop over an attachment's key-value pairs. - * - * This function is expected to call `loop_body` once for each key-value pair - * within `iterator`, passing `context`, and returning any non-zero value immediately (breaking iteration). - */ -typedef int8_t (*z_attachment_iter_driver_t)(const void *iterator, - z_attachment_iter_body_t loop_body, - void *context); -/** - * A iteration based map of byte slice to byte slice. - * - * `iteration_driver == NULL` marks the gravestone value, as this type is often optional. - * Users are encouraged to use `z_attachment_null` and `z_attachment_check` to interact. - */ -typedef struct z_attachment_t { - const void *data; - z_attachment_iter_driver_t iteration_driver; -} z_attachment_t; -/** - * A split buffer that owns all of its data. - * - * To minimize copies and reallocations, Zenoh may provide you data in split buffers. - */ -typedef struct ALIGN(8) z_owned_buffer_t { - uint8_t _0[40]; -} z_owned_buffer_t; -/** - * A loan of a `z_owned_buffer_t`. - * - * As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. - */ -typedef struct z_buffer_t { - struct z_owned_buffer_t *_inner; -} z_buffer_t; -typedef struct z_owned_bytes_t { - uint8_t *start; - size_t len; -} z_owned_bytes_t; -/** - * A map of maybe-owned vector of bytes to owned vector of bytes. - * - * In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher - */ -typedef struct z_owned_bytes_map_t { - uint64_t _0[2]; - size_t _1[4]; -} z_owned_bytes_map_t; -/** - * Clock - * Uses monotonic clock - */ -typedef struct z_clock_t { - uint64_t t; - const void *t_base; -} z_clock_t; -/** - * Represents a Zenoh ID. - * - * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. - */ -typedef struct z_id_t { - uint8_t id[16]; -} z_id_t; -/** - * An owned array of owned, zenoh allocated, NULL terminated strings. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct z_owned_str_array_t { - char **val; - size_t len; -} z_owned_str_array_t; -/** - * A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. - * - * Members: - * unsigned int whatami: The kind of zenoh entity. - * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). - * z_owned_str_array_t locators: The locators of the scouted entity. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -typedef struct z_owned_hello_t { - unsigned int _whatami; - struct z_id_t _pid; - struct z_owned_str_array_t _locators; -} z_owned_hello_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_hello_t { - void *context; - void (*call)(struct z_owned_hello_t*, void*); - void (*drop)(void*); -} z_owned_closure_hello_t; -typedef struct ALIGN(8) z_owned_query_t { - uint8_t _0[16]; -} z_owned_query_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_owned_query_t { - void *context; - void (*call)(struct z_owned_query_t*, void *context); - void (*drop)(void*); -} z_owned_closure_owned_query_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_query_t { - void *context; - void (*call)(const struct z_query_t*, void *context); - void (*drop)(void*); -} z_owned_closure_query_t; -typedef struct ALIGN(8) z_owned_reply_t { - uint8_t _0[256]; -} z_owned_reply_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_reply_t { - void *context; - void (*call)(struct z_owned_reply_t*, void*); - void (*drop)(void*); -} z_owned_closure_reply_t; -typedef struct ALIGN(8) z_sample_t { - uint8_t _0[8]; -} z_sample_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_sample_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_sample_t { - void *context; - void (*call)(const struct z_sample_t*, void *context); - void (*drop)(void*); -} z_owned_closure_sample_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_zid_t { - void *context; - void (*call)(const struct z_id_t*, void*); - void (*drop)(void*); -} z_owned_closure_zid_t; -/** - * Condvar - * - */ -typedef struct z_condvar_t { - size_t _0; -} z_condvar_t; -/** - * Mutex - * - */ -typedef struct z_mutex_t { - size_t _0; -} z_mutex_t; -/** - * An owned zenoh configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct z_owned_config_t { - void *_0; -} z_owned_config_t; -/** - * A loaned zenoh configuration. - */ -typedef struct z_config_t { - const struct z_owned_config_t *_0; -} z_config_t; -/** - * A zenoh-allocated key expression. - * - * Key expressions can identify a single key or a set of keys. - * - * Examples : - * - ``"key/expression"``. - * - ``"key/ex*"``. - * - * Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` - * for wire and computation efficiency. - * - * A `key expression `_ can be either: - * - A plain string expression. - * - A pure numerical id. - * - The combination of a numerical prefix and a string suffix. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_owned_keyexpr_t { - uint64_t _0[4]; -} z_owned_keyexpr_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_owned_keyexpr_t { - uint32_t _0[5]; -} z_owned_keyexpr_t; -#endif -/** - * A loaned key expression. - * - * Key expressions can identify a single key or a set of keys. - * - * Examples : - * - ``"key/expression"``. - * - ``"key/ex*"``. - * - * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, - * both for local processing and network-wise. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_keyexpr_t { - uint64_t _0[4]; -} z_keyexpr_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_keyexpr_t { - uint32_t _0[5]; -} z_keyexpr_t; -#endif -/** - * An owned zenoh publisher. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_owned_publisher_t { - uint64_t _0[7]; -} z_owned_publisher_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_owned_publisher_t { - uint32_t _0[8]; -} z_owned_publisher_t; -#endif -/** - * Options passed to the :c:func:`z_declare_publisher` function. - * - * Members: - * z_congestion_control_t congestion_control: The congestion control to apply when routing messages from this publisher. - * z_priority_t priority: The priority of messages from this publisher. - */ -typedef struct z_publisher_options_t { - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; -} z_publisher_options_t; -/** - * Options passed to the :c:func:`z_declare_queryable` function. - * - * Members: - * bool complete: The completeness of the Queryable. - */ -typedef struct z_queryable_options_t { - bool complete; -} z_queryable_options_t; -/** - * Options passed to the :c:func:`z_declare_subscriber` or :c:func:`z_declare_pull_subscriber` function. - * - * Members: - * z_reliability_t reliability: The subscription reliability. - */ -typedef struct z_subscriber_options_t { - -} z_subscriber_options_t; -/** - * Options passed to the :c:func:`z_delete` function. - */ -typedef struct z_delete_options_t { - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; -} z_delete_options_t; -typedef struct ALIGN(8) z_owned_encoding_t { - uint8_t _0[48]; -} z_owned_encoding_t; -typedef struct ALIGN(8) z_encoding_t { - uint8_t _0[8]; -} z_encoding_t; -/** - * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. - */ -typedef struct z_query_consolidation_t { - enum z_consolidation_mode_t mode; -} z_query_consolidation_t; -/** - * An owned payload, backed by a reference counted owner. - * - * The `payload` field may be modified, and Zenoh will take the new values into account. - */ -typedef struct z_owned_buffer_t zc_owned_payload_t; -/** - * Options passed to the :c:func:`z_get` function. - * - * Members: - * z_query_target_t target: The Queryables that should be target of the query. - * z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. - * z_value_t value: An optional value to attach to the query. - * z_attachment_t attachment: The attachment to attach to the query. - * uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. - */ -typedef struct z_get_options_t { - enum z_query_target_t target; - struct z_query_consolidation_t consolidation; - zc_owned_payload_t payload; - struct z_encoding_t encoding; - struct z_attachment_t attachment; - uint64_t timeout_ms; -} z_get_options_t; -/** - * An borrowed array of borrowed, zenoh allocated, NULL terminated strings. - */ -typedef struct z_str_array_t { - size_t len; - const char *const *val; -} z_str_array_t; -/** - * A reference-type hello message returned by a zenoh entity to a scout message sent with `z_scout`. - * - * Members: - * unsigned int whatami: The kind of zenoh entity. - * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). - * z_owned_str_array_t locators: The locators of the scouted entity. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -typedef struct z_hello_t { - unsigned int whatami; - struct z_id_t pid; - struct z_str_array_t locators; -} z_hello_t; -/** - * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` - * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with - * `z_check` and `z_str_check` correspondently - */ -typedef struct z_owned_str_t { - char *_cstr; -} z_owned_str_t; -/** - * A loaned zenoh publisher. - */ -typedef struct z_publisher_t { - const struct z_owned_publisher_t *_0; -} z_publisher_t; -/** - * Represents the set of options that can be applied to the delete operation by a previously declared publisher, - * whenever issued via :c:func:`z_publisher_delete`. - */ -typedef struct z_publisher_delete_options_t { - uint8_t __dummy; -} z_publisher_delete_options_t; -/** - * Options passed to the :c:func:`z_publisher_put` function. - * - * Members: - * z_encoding_t encoding: The encoding of the payload. - * z_attachment_t attachment: The attachment to attach to the publication. - */ -typedef struct z_publisher_put_options_t { - struct z_encoding_t encoding; - struct z_attachment_t attachment; -} z_publisher_put_options_t; -/** - * Options passed to the :c:func:`z_put` function. - * - * Members: - * z_encoding_t encoding: The encoding of the payload. - * z_congestion_control_t congestion_control: The congestion control to apply when routing this message. - * z_priority_t priority: The priority of this message. - * z_attachment_t attachment: The attachment to this message. - */ -typedef struct z_put_options_t { - struct z_encoding_t encoding; - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; - struct z_attachment_t attachment; -} z_put_options_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - `this` is a pointer to an arbitrary state. - * - `call` is the typical callback function. `this` will be passed as its last argument. - * - `drop` allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * We guarantee that: - * - `call` will never be called once `drop` has started. - * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_query_channel_closure_t { - void *context; - bool (*call)(struct z_owned_query_t*, void*); - void (*drop)(void*); -} z_owned_query_channel_closure_t; -/** - * A pair of closures - */ -typedef struct z_owned_query_channel_t { - struct z_owned_closure_owned_query_t send; - struct z_owned_query_channel_closure_t recv; -} z_owned_query_channel_t; -/** - * Represents the set of options that can be applied to a query reply, - * sent via :c:func:`z_query_reply`. - * - * Members: - * z_encoding_t encoding: The encoding of the payload. - * z_attachment_t attachment: The attachment to this reply. - */ -typedef struct z_query_reply_options_t { - struct z_encoding_t encoding; - struct z_attachment_t attachment; -} z_query_reply_options_t; -typedef struct ALIGN(8) z_value_t { - uint8_t _0[8]; -} z_value_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - `this` is a pointer to an arbitrary state. - * - `call` is the typical callback function. `this` will be passed as its last argument. - * - `drop` allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * We guarantee that: - * - `call` will never be called once `drop` has started. - * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_reply_channel_closure_t { - void *context; - bool (*call)(struct z_owned_reply_t*, void*); - void (*drop)(void*); -} z_owned_reply_channel_closure_t; -/** - * A pair of closures, the `send` one accepting - */ -typedef struct z_owned_reply_channel_t { - struct z_owned_closure_reply_t send; - struct z_owned_reply_channel_closure_t recv; -} z_owned_reply_channel_t; -typedef struct z_buffer_t zc_payload_t; -typedef struct z_timestamp_t { - uint64_t time; - struct z_id_t id; -} z_timestamp_t; -typedef struct z_owned_scouting_config_t { - struct z_owned_config_t _config; - unsigned long zc_timeout_ms; - uint8_t zc_what; -} z_owned_scouting_config_t; -/** - * A loaned zenoh subscriber. - */ -typedef struct z_subscriber_t { - const struct z_owned_subscriber_t *_0; -} z_subscriber_t; -/** - * Task - * - */ -typedef struct z_task_t { - size_t _0; -} z_task_t; -typedef struct z_task_attr_t { - size_t _0; -} z_task_attr_t; -/** - * Time - * Uses system clock - */ -typedef struct z_time_t { - uint64_t t; -} z_time_t; -/** - * The options for `zc_liveliness_declare_token` - */ -typedef struct zc_owned_liveliness_declaration_options_t { - uint8_t _inner; -} zc_owned_liveliness_declaration_options_t; -/** - * The options for :c:func:`zc_liveliness_declare_subscriber` - */ -typedef struct zc_owned_liveliness_declare_subscriber_options_t { - uint8_t _inner; -} zc_owned_liveliness_declare_subscriber_options_t; -/** - * A liveliness token that can be used to provide the network with information about connectivity to its - * declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key - * expressions. - * - * A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. - */ -typedef struct zc_owned_liveliness_token_t { - size_t _inner[4]; -} zc_owned_liveliness_token_t; -/** - * The options for :c:func:`zc_liveliness_declare_subscriber` - */ -typedef struct zc_liveliness_get_options_t { - uint32_t timeout_ms; -} zc_liveliness_get_options_t; -/** - * A reader for payload data. - */ -typedef struct ALIGN(8) zc_payload_reader { - uint8_t _0[24]; -} zc_payload_reader; -/** - * An owned sample. - * - * This is a read only type that can only be constructed by cloning a `z_sample_t`. - * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. - */ -typedef struct ALIGN(8) zc_owned_sample_t { - uint8_t _0[240]; -} zc_owned_sample_t; -typedef struct zc_owned_shmbuf_t { - size_t _0[9]; -} zc_owned_shmbuf_t; -typedef struct zc_owned_shm_manager_t { - size_t _0; -} zc_owned_shm_manager_t; -/** - * A struct that indicates if there exist Subscribers matching the Publisher's key expression. - * - * Members: - * bool matching: true if there exist Subscribers matching the Publisher's key expression. - */ -typedef struct zcu_matching_status_t { - bool matching; -} zcu_matching_status_t; -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct zcu_owned_closure_matching_status_t { - void *context; - void (*call)(const struct zcu_matching_status_t*, void*); - void (*drop)(void*); -} zcu_owned_closure_matching_status_t; -/** - * An owned zenoh matching listener. Destroying the matching listener cancels the subscription. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) zcu_owned_matching_listener_t { - uint64_t _0[4]; -} zcu_owned_matching_listener_t; -/** - * An owned zenoh publication_cache. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ze_owned_publication_cache_t { - size_t _0[1]; -} ze_owned_publication_cache_t; -/** - * Options passed to the :c:func:`ze_declare_publication_cache` function. - * - * Members: - * z_keyexpr_t queryable_prefix: The prefix used for queryable - * zcu_locality_t queryable_origin: The restriction for the matching queries that will be receive by this - * publication cache - * bool queryable_complete: the `complete` option for the queryable - * size_t history: The the history size - * size_t resources_limit: The limit number of cached resources - */ -typedef struct ze_publication_cache_options_t { - struct z_keyexpr_t queryable_prefix; - enum zcu_locality_t queryable_origin; - bool queryable_complete; - size_t history; - size_t resources_limit; -} ze_publication_cache_options_t; -ZENOHC_API extern const unsigned int Z_ROUTER; -ZENOHC_API extern const unsigned int Z_PEER; -ZENOHC_API extern const unsigned int Z_CLIENT; -ZENOHC_API extern const char *Z_CONFIG_MODE_KEY; -ZENOHC_API extern const char *Z_CONFIG_CONNECT_KEY; -ZENOHC_API extern const char *Z_CONFIG_LISTEN_KEY; -ZENOHC_API extern const char *Z_CONFIG_USER_KEY; -ZENOHC_API extern const char *Z_CONFIG_PASSWORD_KEY; -ZENOHC_API extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; -ZENOHC_API extern const char *Z_CONFIG_MULTICAST_INTERFACE_KEY; -ZENOHC_API extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; -ZENOHC_API extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; -ZENOHC_API extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; -ZENOHC_API extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; -/** - * Returns the gravestone value for `z_attachment_t`. - */ -ZENOHC_API bool z_attachment_check(const struct z_attachment_t *this_); -/** - * Returns the value associated with the key. - */ -ZENOHC_API struct z_bytes_t z_attachment_get(struct z_attachment_t this_, struct z_bytes_t key); -/** - * Returns true if `z_attachment_t` contains no key-value pairs, false otherwise. - */ -ZENOHC_API bool z_attachment_is_empty(struct z_attachment_t this_); -/** - * Iterate over `this`'s key-value pairs, breaking if `body` returns a non-zero - * value for a key-value pair, and returning the latest return value. - * - * `context` is passed to `body` to allow stateful closures. - * - * This function takes no ownership whatsoever. - */ -ZENOHC_API -int8_t z_attachment_iterate(struct z_attachment_t this_, - z_attachment_iter_body_t body, - void *context); -/** - * Returns number of key-value pairs for `z_attachment_t`. - * - * Does so by iterating over all existing key-value pairs. - */ -ZENOHC_API size_t z_attachment_len(struct z_attachment_t this_); -/** - * Returns the gravestone value for `z_attachment_t`. - */ -ZENOHC_API struct z_attachment_t z_attachment_null(void); -/** - * Returns `true` if the buffer is in a valid state. - */ -ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); -/** - * Increments the buffer's reference count, returning an owned version of the buffer. - */ -ZENOHC_API struct z_owned_buffer_t z_buffer_clone(struct z_buffer_t buffer); -/** - * Decrements the buffer's reference counter, destroying it if applicable. - * - * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. - */ -ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); -/** - * Returns total number bytes in the buffer. - */ -ZENOHC_API size_t z_buffer_len(struct z_buffer_t buffer); -/** - * Loans the buffer, allowing you to call functions that only need a loan of it. - */ -ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); -/** - * The gravestone value for `z_owned_buffer_t`. - */ -ZENOHC_API struct z_owned_buffer_t z_buffer_null(void); -/** - * Returns the `index`th slice of the buffer, aliasing it. - * - * Out of bounds accesses will return `z_bytes_empty`. - */ -ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); -/** - * Returns the number of slices in the buffer. - * - * If the return value is 0 or 1, then the buffer's data is contiguous in memory. - */ -ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); -/** - * Returns ``true`` if `b` is initialized. - */ -ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *b); -ZENOHC_API struct z_owned_bytes_t z_bytes_clone(const struct z_bytes_t *b); -/** - * Returns the gravestone value for `z_bytes_t` - */ -ZENOHC_API struct z_bytes_t z_bytes_empty(void); -/** - * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). - * - * `str == NULL` will cause this to return `z_bytes_empty()` - */ -ZENOHC_API struct z_bytes_t z_bytes_from_str(const char *str); -/** - * Returns ``true`` if `b` is initialized. - */ -ZENOHC_API bool z_bytes_is_initialized(const struct z_bytes_t *b); -ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *b); -/** - * Aliases `this` into a generic `z_attachment_t`, allowing it to be passed to corresponding APIs. - */ -ZENOHC_API struct z_attachment_t z_bytes_map_as_attachment(const struct z_owned_bytes_map_t *this_); -/** - * Returns `true` if the map is not in its gravestone state - */ -ZENOHC_API bool z_bytes_map_check(const struct z_owned_bytes_map_t *this_); -/** - * Destroys the map, resetting `this` to its gravestone value. - * - * This function is double-free safe, passing a pointer to the gravestone value will have no effect. - */ -ZENOHC_API void z_bytes_map_drop(struct z_owned_bytes_map_t *this_); -/** - * Constructs a map from the provided attachment, copying keys and values. - * - * If `this` is at gravestone value, the returned value will also be at gravestone value. - */ -ZENOHC_API struct z_owned_bytes_map_t z_bytes_map_from_attachment(struct z_attachment_t this_); -/** - * Constructs a map from the provided attachment, aliasing the attachment's keys and values. - * - * If `this` is at gravestone value, the returned value will also be at gravestone value. - */ -ZENOHC_API -struct z_owned_bytes_map_t z_bytes_map_from_attachment_aliasing(struct z_attachment_t this_); -/** - * Returns the value associated with `key`, returning a gravestone value if: - * - `this` or `key` is in gravestone state. - * - `this` has no value associated to `key` - */ -ZENOHC_API -struct z_bytes_t z_bytes_map_get(const struct z_owned_bytes_map_t *this_, - struct z_bytes_t key); -/** - * Associates `value` to `key` in the map, aliasing them. - * - * Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. - * - * Calling this with `NULL` or the gravestone value is undefined behaviour. - */ -ZENOHC_API -void z_bytes_map_insert_by_alias(const struct z_owned_bytes_map_t *this_, - struct z_bytes_t key, - struct z_bytes_t value); -/** - * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. - * - * Calling this with `NULL` or the gravestone value is undefined behaviour. - */ -ZENOHC_API -void z_bytes_map_insert_by_copy(const struct z_owned_bytes_map_t *this_, - struct z_bytes_t key, - struct z_bytes_t value); -/** - * Returns true if the map is empty, false otherwise. - */ -ZENOHC_API bool z_bytes_map_is_empty(struct z_owned_bytes_map_t *this_); -/** - * Iterates over the key-value pairs in the map. - * - * `body` will be called once per pair, with `ctx` as its last argument. - * If `body` returns a non-zero value, the iteration will stop immediately and the value will be returned. - * Otherwise, this will return 0 once all pairs have been visited. - * `body` is not given ownership of the key nor value, which alias the pairs in the map. - * It is safe to keep these aliases until existing keys are modified/removed, or the map is destroyed. - * Note that this map is unordered. - * - * Calling this with `NULL` or the gravestone value is undefined behaviour. - */ -ZENOHC_API -int8_t z_bytes_map_iter(const struct z_owned_bytes_map_t *this_, - z_attachment_iter_body_t body, - void *ctx); -/** - * Returns number of key-value pairs in the map. - */ -ZENOHC_API size_t z_bytes_map_len(struct z_owned_bytes_map_t *this_); -/** - * Constructs a new map. - */ -ZENOHC_API struct z_owned_bytes_map_t z_bytes_map_new(void); -/** - * Constructs the gravestone value for `z_owned_bytes_map_t` - */ -ZENOHC_API struct z_owned_bytes_map_t z_bytes_map_null(void); -/** - * Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). - * - * `str == NULL` will cause this to return `z_bytes_empty()` - */ -ZENOHC_API -struct z_bytes_t z_bytes_new(const char *str); -/** - * Returns the gravestone value for `z_owned_bytes_t` - */ -ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); -/** - * Constructs a `len` bytes long view starting at `start`. - */ -ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); -ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); -ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); -ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); -ZENOHC_API struct z_clock_t z_clock_now(void); -/** - * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. - * - * Returns a negative value if an error occured while closing the session. - * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. - */ -ZENOHC_API int8_t z_close(struct z_owned_session_t *session); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_hello_call(const struct z_owned_closure_hello_t *closure, - struct z_owned_hello_t *hello); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_hello_drop(struct z_owned_closure_hello_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_hello_t' type - */ -ZENOHC_API struct z_owned_closure_hello_t z_closure_hello_null(void); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_owned_query_call(const struct z_owned_closure_owned_query_t *closure, - struct z_owned_query_t *query); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_owned_query_drop(struct z_owned_closure_owned_query_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type - */ -ZENOHC_API struct z_owned_closure_owned_query_t z_closure_owned_query_null(void); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_query_call(const struct z_owned_closure_query_t *closure, - const struct z_query_t *query); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_query_drop(struct z_owned_closure_query_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type - */ -ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_reply_call(const struct z_owned_closure_reply_t *closure, - struct z_owned_reply_t *sample); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_reply_drop(struct z_owned_closure_reply_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_reply_t' type - */ -ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, - const struct z_sample_t *sample); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_sample_drop(struct z_owned_closure_sample_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_sample_t' type - */ -ZENOHC_API struct z_owned_closure_sample_t z_closure_sample_null(void); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_zid_call(const struct z_owned_closure_zid_t *closure, - const struct z_id_t *sample); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_zid_drop(struct z_owned_closure_zid_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_zid_t' type - */ -ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); -ZENOHC_API int8_t z_condvar_free(struct z_condvar_t *cv); -ZENOHC_API int8_t z_condvar_init(struct z_condvar_t *cv); -ZENOHC_API int8_t z_condvar_signal(struct z_condvar_t *cv); -ZENOHC_API int8_t z_condvar_wait(struct z_condvar_t *cv, struct z_mutex_t *m); -/** - * Returns ``true`` if `config` is valid. - */ -ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); -/** - * Constructs a default, zenoh-allocated, client mode configuration. - * If `peer` is not null, it is added to the configuration as remote peer. - */ -ZENOHC_API struct z_owned_config_t z_config_client(const char *const *peers, size_t n_peers); -/** - * Creates a default, zenoh-allocated, configuration. - */ -ZENOHC_API struct z_owned_config_t z_config_default(void); -/** - * Frees `config`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_config_drop(struct z_owned_config_t *config); -/** - * Returns a :c:type:`z_config_t` loaned from `s`. - */ -ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); -/** - * Return a new, zenoh-allocated, empty configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -ZENOHC_API -struct z_owned_config_t z_config_new(void); -/** - * Constructs a null safe-to-drop value of 'z_owned_config_t' type - */ -ZENOHC_API struct z_owned_config_t z_config_null(void); -/** - * Constructs a default, zenoh-allocated, peer mode configuration. - */ -ZENOHC_API struct z_owned_config_t z_config_peer(void); -/** - * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. - * - * This numerical id will be used on the network to save bandwidth and - * ease the retrieval of the concerned resource in the routing tables. - */ -ZENOHC_API -struct z_owned_keyexpr_t z_declare_keyexpr(struct z_session_t session, - struct z_keyexpr_t keyexpr); -/** - * Declares a publisher for the given key expression. - * - * Data can be put and deleted with this publisher with the help of the - * :c:func:`z_publisher_put` and :c:func:`z_publisher_delete` functions. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to publish. - * options: additional options for the publisher. - * - * Returns: - * A :c:type:`z_owned_publisherr_t`. - * - * To check if the publisher decalration succeeded and if the publisher is still valid, - * you may use `z_publisher_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a publisher passing `NULL` for the options: - * - * .. code-block:: C - * - * z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(expr), NULL); - * - * is equivalent to initializing and passing the default publisher options: - * - * .. code-block:: C - * - * z_publisher_options_t opts = z_publisher_options_default(); - * z_owned_publisher_t sub = z_declare_publisher(z_loan(s), z_keyexpr(expr), &opts); - */ -ZENOHC_API -struct z_owned_publisher_t z_declare_publisher(struct z_session_t session, - struct z_keyexpr_t keyexpr, - const struct z_publisher_options_t *options); -/** - * Creates a Queryable for the given key expression. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression the Queryable will reply to. - * callback: The callback function that will be called each time a matching query is received. - * options: Options for the queryable. - * - * Returns: - * The created :c:type:`z_owned_queryable_t` or ``null`` if the creation failed. - */ -ZENOHC_API -struct z_owned_queryable_t z_declare_queryable(struct z_session_t session, - struct z_keyexpr_t keyexpr, - struct z_owned_closure_query_t *callback, - const struct z_queryable_options_t *options); -/** - * Declare a subscriber for a given key expression. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to subscribe. - * callback: The callback function that will be called each time a data matching the subscribed expression is received. - * opts: The options to be passed to describe the options to be passed to the subscriber declaration. - * - * Returns: - * A :c:type:`z_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the subscriber is still valid, - * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a subscriber passing `NULL` for the options: - * - * .. code-block:: C - * - * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); - * - * is equivalent to initializing and passing the default subscriber options: - * - * .. code-block:: C - * - * z_subscriber_options_t opts = z_subscriber_options_default(); - * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); - */ -ZENOHC_API -struct z_owned_subscriber_t z_declare_subscriber(struct z_session_t session, - struct z_keyexpr_t keyexpr, - struct z_owned_closure_sample_t *callback, - const struct z_subscriber_options_t *opts); -/** - * Delete data. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to delete. - * options: The put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. - */ -ZENOHC_API -int8_t z_delete(struct z_session_t session, - struct z_keyexpr_t keyexpr, - const struct z_delete_options_t *opts); -/** - * Constructs the default value for :c:type:`z_put_options_t`. - */ -ZENOHC_API struct z_delete_options_t z_delete_options_default(void); -/** - * Returns ``true`` if `encoding` is valid. - */ -ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); -/** - * Constructs a default :c:type:`z_encoding_t`. - */ -ZENOHC_API struct z_encoding_t z_encoding_default(void); -/** - * Frees `encoding`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); -/** - * Constructs a specific :c:type:`z_encoding_t`. - */ -ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); -/** - * Returns a :c:type:`z_encoding_t` loaned from `encoding`. - */ -ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); -/** - * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type - */ -ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); -/** - * Query data from the matching queryables in the system. - * Replies are provided through a callback function. - * - * Returns a negative value upon failure. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression matching resources to query. - * parameters: The query's parameters, similar to a url's query segment. - * callback: The callback function that will be called on reception of replies for this query. - * Note that the `reply` parameter of the callback is passed by mutable reference, - * but **will** be dropped once your callback exits to help you avoid memory leaks. - * If you'd rather take ownership, please refer to the documentation of :c:func:`z_reply_null` - * options: additional options for the get. - */ -ZENOHC_API -int8_t z_get(struct z_session_t session, - struct z_keyexpr_t keyexpr, - const char *parameters, - struct z_owned_closure_reply_t *callback, - struct z_get_options_t *options); -ZENOHC_API struct z_get_options_t z_get_options_default(void); -/** - * Returns ``true`` if `hello` is valid. - */ -ZENOHC_API bool z_hello_check(const struct z_owned_hello_t *hello); -/** - * Frees `hello`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_hello_drop(struct z_owned_hello_t *hello); -/** - * Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. - */ -ZENOHC_API struct z_hello_t z_hello_loan(const struct z_owned_hello_t *hello); -/** - * Constructs a gravestone value for hello, useful to steal one from a callback - */ -ZENOHC_API struct z_owned_hello_t z_hello_null(void); -/** - * Fetches the Zenoh IDs of all connected peers. - * - * `callback` will be called once for each ID, is guaranteed to never be called concurrently, - * and is guaranteed to be dropped before this function exits. - * - * Retuns 0 on success, negative values on failure - */ -ZENOHC_API -int8_t z_info_peers_zid(struct z_session_t session, - struct z_owned_closure_zid_t *callback); -/** - * Fetches the Zenoh IDs of all connected routers. - * - * `callback` will be called once for each ID, is guaranteed to never be called concurrently, - * and is guaranteed to be dropped before this function exits. - * - * Retuns 0 on success, negative values on failure. - */ -ZENOHC_API -int8_t z_info_routers_zid(struct z_session_t session, - struct z_owned_closure_zid_t *callback); -/** - * Returns the local Zenoh ID. - * - * Unless the `session` is invalid, that ID is guaranteed to be non-zero. - * In other words, this function returning an array of 16 zeros means you failed - * to pass it a valid session. - */ -ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API struct z_keyexpr_t z_keyexpr(const char *name); -/** - * Returns the key expression's internal string by aliasing it. - * - * Currently exclusive to zenoh-c - */ -ZENOHC_API struct z_bytes_t z_keyexpr_as_bytes(struct z_keyexpr_t keyexpr); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - * The string is canonized in-place before being passed to keyexpr. - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -struct z_keyexpr_t z_keyexpr_autocanonize(char *name); -/** - * Canonizes the passed string in place, possibly shortening it by modifying `len`. - * - * Returns ``0`` upon success, negative values upon failure. - * Returns a negative value if canonization failed, which indicates that the passed string was an invalid - * key expression for reasons other than a non-canon form. - * - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -int8_t z_keyexpr_canonize(char *start, - size_t *len); -/** - * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. - * - * Returns ``0`` upon success, negative values upon failure. - * Returns a negative value if canonization failed, which indicates that the passed string was an invalid - * key expression for reasons other than a non-canon form. - * - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -int8_t z_keyexpr_canonize_null_terminated(char *start); -/** - * Returns ``true`` if `keyexpr` is valid. - */ -ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); -/** - * Performs string concatenation and returns the result as a `z_owned_keyexpr_t`. - * In case of error, the return value will be set to its invalidated state. - * - * You should probably prefer `z_keyexpr_join` as Zenoh may then take advantage of the hierachical separation it inserts. - * - * To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, - * as this would extremely likely cause bugs. - */ -ZENOHC_API -struct z_owned_keyexpr_t z_keyexpr_concat(struct z_keyexpr_t left, - const char *right_start, - size_t right_len); -/** - * Frees `keyexpr` and invalidates it for double-drop safety. - */ -ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); -/** - * Returns ``0`` if both ``left`` and ``right`` are equal. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. - */ -ZENOHC_API -int8_t z_keyexpr_equals(struct z_keyexpr_t left, - struct z_keyexpr_t right); -/** - * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set - * defined by ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. - */ -ZENOHC_API -int8_t z_keyexpr_includes(struct z_keyexpr_t left, - struct z_keyexpr_t right); -/** - * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the - * sets defined by ``left`` and ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. - */ -ZENOHC_API -int8_t z_keyexpr_intersects(struct z_keyexpr_t left, - struct z_keyexpr_t right); -/** - * Returns ``0`` if the passed string is a valid (and canon) key expression. - * Otherwise returns error value - */ -ZENOHC_API int8_t z_keyexpr_is_canon(const char *start, size_t len); -/** - * Returns ``true`` if `keyexpr` is initialized. - */ -ZENOHC_API bool z_keyexpr_is_initialized(const struct z_keyexpr_t *keyexpr); -/** - * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. - * In case of error, the return value will be set to its invalidated state. - */ -ZENOHC_API -struct z_owned_keyexpr_t z_keyexpr_join(struct z_keyexpr_t left, - struct z_keyexpr_t right); -/** - * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. - */ -ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *keyexpr); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. - */ -ZENOHC_API struct z_owned_keyexpr_t z_keyexpr_new(const char *name); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. - */ -ZENOHC_API -struct z_owned_keyexpr_t z_keyexpr_new_autocanonize(const char *name); -/** - * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type - */ -ZENOHC_API struct z_owned_keyexpr_t z_keyexpr_null(void); -/** - * Returns the relation between `left` and `right` from `left`'s point of view. - * - * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. - */ -ZENOHC_API -enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, - struct z_keyexpr_t right); -/** - * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. - * The user is responsible of droping the returned string using `z_drop` - */ -ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t keyexpr); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions: - * - * - `name` MUST be valid UTF8. - * - `name` MUST follow the Key Expression specification, ie: - * - * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. - * - any instance of `**` may only be lead or followed by `/`. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -struct z_keyexpr_t z_keyexpr_unchecked(const char *name); -ZENOHC_API int8_t z_mutex_free(struct z_mutex_t *m); -ZENOHC_API int8_t z_mutex_init(struct z_mutex_t *m); -ZENOHC_API int8_t z_mutex_lock(struct z_mutex_t *m); -ZENOHC_API int8_t z_mutex_try_lock(struct z_mutex_t *m); -ZENOHC_API int8_t z_mutex_unlock(struct z_mutex_t *m); -/** - * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. - */ -ZENOHC_API -struct z_owned_session_t z_open(struct z_owned_config_t *config); -/** - * Returns ``true`` if `pub` is valid. - */ -ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); -/** - * Sends a `DELETE` message onto the publisher's key expression. - * - * Returns: - * ``0`` in case of success, ``1`` in case of failure. - */ -ZENOHC_API -int8_t z_publisher_delete(struct z_publisher_t publisher, - const struct z_publisher_delete_options_t *_options); -/** - * Constructs the default values for the delete operation via a publisher entity. - * - * Returns: - * Returns the constructed :c:type:`z_publisher_delete_options_t`. - */ -ZENOHC_API struct z_publisher_delete_options_t z_publisher_delete_options_default(void); -/** - * Returns the key expression of the publisher - */ -ZENOHC_API struct z_owned_keyexpr_t z_publisher_keyexpr(struct z_publisher_t publisher); -/** - * Returns a :c:type:`z_publisher_t` loaned from `p`. - */ -ZENOHC_API struct z_publisher_t z_publisher_loan(const struct z_owned_publisher_t *p); -/** - * Constructs a null safe-to-drop value of 'z_owned_publisher_t' type - */ -ZENOHC_API struct z_owned_publisher_t z_publisher_null(void); -/** - * Constructs the default value for :c:type:`z_publisher_options_t`. - */ -ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); -/** - * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. - * - * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher - * - constructed from a `zc_owned_shmbuf_t` - * - * The payload's encoding can be sepcified through the options. - * - * Parameters: - * session: The zenoh session. - * payload: The value to put. - * options: The publisher put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. - */ -ZENOHC_API -int8_t z_publisher_put(struct z_publisher_t publisher, - zc_owned_payload_t *payload, - const struct z_publisher_put_options_t *options); -/** - * Constructs the default value for :c:type:`z_publisher_put_options_t`. - */ -ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); -/** - * Put data, transfering the buffer ownership. - * - * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher - * - constructed from a `zc_owned_shmbuf_t` - * - * The payload's encoding can be sepcified through the options. - * - * Parameters: - * session: The zenoh session. - * keyexpr: The key expression to put. - * payload: The value to put. - * options: The put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. - */ -ZENOHC_API -int8_t z_put(struct z_session_t session, - struct z_keyexpr_t keyexpr, - zc_owned_payload_t *payload, - const struct z_put_options_t *opts); -/** - * Constructs the default value for :c:type:`z_put_options_t`. - */ -ZENOHC_API struct z_put_options_t z_put_options_default(void); -/** - * Returns the attachment to the query by aliasing. - * - * `z_check(return_value) == false` if there was no attachment to the query. - */ -ZENOHC_API struct z_attachment_t z_query_attachment(const struct z_query_t *query); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -bool z_query_channel_closure_call(const struct z_owned_query_channel_closure_t *closure, - struct z_owned_query_t *sample); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_query_channel_closure_drop(struct z_owned_query_channel_closure_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_query_channel_closure_t' type - */ -ZENOHC_API struct z_owned_query_channel_closure_t z_query_channel_closure_null(void); -ZENOHC_API void z_query_channel_drop(struct z_owned_query_channel_t *channel); -/** - * Constructs a null safe-to-drop value of 'z_owned_query_channel_t' type - */ -ZENOHC_API struct z_owned_query_channel_t z_query_channel_null(void); -/** - * Returns `false` if `this` is in a gravestone state, `true` otherwise. - * - * This function may not be called with the null pointer, but can be called with the gravestone value. - */ -ZENOHC_API -bool z_query_check(const struct z_owned_query_t *query); -/** - * Clones the query, allowing to keep it in an "open" state past the callback's return. - * - * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). - */ -ZENOHC_API -struct z_owned_query_t z_query_clone(struct z_query_t query); -/** - * Automatic query consolidation strategy selection. - * - * A query consolidation strategy will automatically be selected depending the query selector. - * If the selector contains time range properties, no consolidation is performed. - * Otherwise the :c:func:`z_query_consolidation_latest` strategy is used. - * - * Returns: - * Returns the constructed :c:type:`z_query_consolidation_t`. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_auto(void); -/** - * Creates a default :c:type:`z_query_consolidation_t` (consolidation mode AUTO). - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_default(void); -/** - * Latest value consolidation. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_latest(void); -/** - * Monotonic consolidation. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_monotonic(void); -/** - * Disable consolidation. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_none(void); -/** - * Destroys the query, setting `this` to its gravestone value to prevent double-frees. - * - * This function may not be called with the null pointer, but can be called with the gravestone value. - */ -ZENOHC_API -void z_query_drop(struct z_owned_query_t *this_); -/** - * Get a query's key by aliasing it. - */ -ZENOHC_API struct z_keyexpr_t z_query_keyexpr(const struct z_query_t *query); -/** - * Aliases the query. - * - * This function may not be called with the null pointer, but can be called with the gravestone value. - */ -ZENOHC_API -struct z_query_t z_query_loan(const struct z_owned_query_t *this_); -/** - * The gravestone value of `z_owned_query_t`. - */ -ZENOHC_API void z_query_null(struct z_owned_query_t *query); -/** - * Get a query's `value selector `_ by aliasing it. - */ -ZENOHC_API -struct z_bytes_t z_query_parameters(const struct z_query_t *query); -/** - * Send a reply to a query. - * - * This function must be called inside of a Queryable callback passing the - * query received as parameters of the callback function. This function can - * be called multiple times to send multiple replies to a query. The reply - * will be considered complete when the Queryable callback returns. - * - * Parameters: - * query: The query to reply to. - * key: The key of this reply. - * payload: The value of this reply. - * options: The options of this reply. - */ -ZENOHC_API -int8_t z_query_reply(const struct z_query_t *query, - struct z_keyexpr_t key, - zc_owned_payload_t *payload, - const struct z_query_reply_options_t *options); -/** - * Constructs the default value for :c:type:`z_query_reply_options_t`. - */ -ZENOHC_API struct z_query_reply_options_t z_query_reply_options_default(void); -/** - * Create a default :c:type:`z_query_target_t`. - */ -ZENOHC_API enum z_query_target_t z_query_target_default(void); -/** - * Get a query's `payload value `_ by aliasing it. - * - * **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** - */ -ZENOHC_API -struct z_value_t z_query_value(const struct z_query_t *query); -/** - * Returns ``true`` if `qable` is valid. - */ -ZENOHC_API bool z_queryable_check(const struct z_owned_queryable_t *qable); -/** - * Constructs a null safe-to-drop value of 'z_owned_queryable_t' type - */ -ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); -/** - * Constructs the default value for :c:type:`z_query_reply_options_t`. - */ -ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); -ZENOHC_API void z_random_fill(void *buf, size_t len); -ZENOHC_API uint16_t z_random_u16(void); -ZENOHC_API uint32_t z_random_u32(void); -ZENOHC_API uint64_t z_random_u64(void); -ZENOHC_API uint8_t z_random_u8(void); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -bool z_reply_channel_closure_call(const struct z_owned_reply_channel_closure_t *closure, - struct z_owned_reply_t *sample); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_reply_channel_closure_drop(struct z_owned_reply_channel_closure_t *closure); -/** - * Constructs a null safe-to-drop value of 'z_owned_reply_channel_closure_t' type - */ -ZENOHC_API struct z_owned_reply_channel_closure_t z_reply_channel_closure_null(void); -ZENOHC_API void z_reply_channel_drop(struct z_owned_reply_channel_t *channel); -/** - * Constructs a null safe-to-drop value of 'z_owned_reply_channel_t' type - */ -ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); -/** - * Returns ``true`` if `reply_data` is valid. - */ -ZENOHC_API bool z_reply_check(const struct z_owned_reply_t *reply_data); -/** - * Frees `reply_data`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_reply_drop(struct z_owned_reply_t *reply_data); -/** - * Yields the contents of the reply by asserting it indicates a failure. - * - * You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. - */ -ZENOHC_API -struct z_value_t z_reply_err(const struct z_owned_reply_t *reply); -/** - * Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. - * - * If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. - */ -ZENOHC_API -bool z_reply_is_ok(const struct z_owned_reply_t *reply); -/** - * Returns an invalidated :c:type:`z_owned_reply_t`. - * - * This is useful when you wish to take ownership of a value from a callback to :c:func:`z_get`: - * - * - copy the value of the callback's argument's pointee, - * - overwrite the pointee with this function's return value, - * - you are now responsible for dropping your copy of the reply. - */ -ZENOHC_API void z_reply_null(struct z_owned_reply_t *reply); -/** - * Yields the contents of the reply by asserting it indicates a success. - * - * You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. - */ -ZENOHC_API -struct z_sample_t z_reply_ok(const struct z_owned_reply_t *reply); -/** - * The qos with which the sample was received. - * TODO: split to methods (priority, congestion_control, express) - * The sample's attachment. - * - * `sample` is aliased by the return value. - */ -ZENOHC_API struct z_attachment_t z_sample_attachment(const struct z_sample_t *sample); -/** - * The encoding of the payload. - */ -ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); -/** - * The Key Expression of the sample. - * - * `sample` is aliased by its return value. - */ -ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); -/** - * The sample's kind (put or delete). - */ -ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); -/** - * Returns the sample's payload after incrementing its internal reference count. - * - * Note that other samples may have received the same buffer, meaning that mutating this buffer may - * affect the samples received by other subscribers. - */ -ZENOHC_API zc_owned_payload_t z_sample_owned_payload(const struct z_sample_t *sample); -/** - * The sample's data, the return value aliases the sample. - * - * If you need ownership of the buffer, you may use `z_sample_owned_payload`. - */ -ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); -/** - * The samples timestamp - */ -ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); -/** - * Scout for routers and/or peers. - * - * Parameters: - * what: A whatami bitmask of zenoh entities kind to scout for. - * config: A set of properties to configure the scouting. - * timeout: The time (in milliseconds) that should be spent scouting. - * - * Returns 0 if successful, negative values upon failure. - */ -ZENOHC_API -int8_t z_scout(struct z_owned_scouting_config_t *config, - struct z_owned_closure_hello_t *callback); -ZENOHC_API bool z_scouting_config_check(const struct z_owned_scouting_config_t *config); -ZENOHC_API struct z_owned_scouting_config_t z_scouting_config_default(void); -ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); -ZENOHC_API struct z_owned_scouting_config_t z_scouting_config_from(struct z_config_t config); -ZENOHC_API struct z_owned_scouting_config_t z_scouting_config_null(void); -/** - * Returns ``true`` if `session` is valid. - */ -ZENOHC_API bool z_session_check(const struct z_owned_session_t *session); -/** - * Returns a :c:type:`z_session_t` loaned from `s`. - * - * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. - * - * # Safety - * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, - * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) - * have been destroyed is UB (likely SEGFAULT) - */ -ZENOHC_API -struct z_session_t z_session_loan(const struct z_owned_session_t *s); -/** - * Constructs a null safe-to-drop value of 'z_owned_session_t' type - */ -ZENOHC_API struct z_owned_session_t z_session_null(void); -ZENOHC_API int8_t z_sleep_ms(size_t time); -ZENOHC_API int8_t z_sleep_s(size_t time); -ZENOHC_API int8_t z_sleep_us(size_t time); -/** - * Returns ``true`` if `strs` is valid. - */ -ZENOHC_API bool z_str_array_check(const struct z_owned_str_array_t *strs); -/** - * Frees `strs` and invalidates it for double-drop safety. - */ -ZENOHC_API void z_str_array_drop(struct z_owned_str_array_t *strs); -/** - * Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. - */ -ZENOHC_API struct z_str_array_t z_str_array_loan(const struct z_owned_str_array_t *strs); -/** - * Returns ``true`` if `s` is a valid string - */ -ZENOHC_API bool z_str_check(const struct z_owned_str_t *s); -/** - * Frees `z_owned_str_t`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_str_drop(struct z_owned_str_t *s); -/** - * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. - */ -ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); -/** - * Returns undefined `z_owned_str_t` - */ -ZENOHC_API struct z_owned_str_t z_str_null(void); -/** - * Returns ``true`` if `sub` is valid. - */ -ZENOHC_API bool z_subscriber_check(const struct z_owned_subscriber_t *sub); -/** - * Returns the key expression of the subscriber. - */ -ZENOHC_API struct z_owned_keyexpr_t z_subscriber_keyexpr(struct z_subscriber_t subscriber); -/** - * Returns a :c:type:`z_subscriber_t` loaned from `p`. - */ -ZENOHC_API struct z_subscriber_t z_subscriber_loan(const struct z_owned_subscriber_t *p); -/** - * Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type - */ -ZENOHC_API struct z_owned_subscriber_t z_subscriber_null(void); -/** - * Constructs the default value for :c:type:`z_subscriber_options_t`. - */ -ZENOHC_API struct z_subscriber_options_t z_subscriber_options_default(void); -ZENOHC_API -int8_t z_task_init(struct z_task_t *task, - const struct z_task_attr_t *_attr, - void (*fun)(void *arg), - void *arg); -ZENOHC_API int8_t z_task_join(struct z_task_t *task); -ZENOHC_API uint64_t z_time_elapsed_ms(const struct z_time_t *time); -ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); -ZENOHC_API uint64_t z_time_elapsed_us(const struct z_time_t *time); -ZENOHC_API struct z_time_t z_time_now(void); -ZENOHC_API const char *z_time_now_as_str(const char *buf, size_t len); -/** - * Returns ``true`` if `ts` is a valid timestamp - */ -ZENOHC_API bool z_timestamp_check(struct z_timestamp_t ts); -/** - * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. - */ -ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); -/** - * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -int8_t z_undeclare_publisher(struct z_owned_publisher_t *publisher); -/** - * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. - * - * Parameters: - * qable: The :c:type:`z_owned_queryable_t` to undeclare. - */ -ZENOHC_API int8_t z_undeclare_queryable(struct z_owned_queryable_t *qable); -/** - * Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -int8_t z_undeclare_subscriber(struct z_owned_subscriber_t *sub); -/** - * Converts the kind of zenoh entity into a string. - * - * Parameters: - * whatami: A whatami bitmask of zenoh entity kind. - * buf: Buffer to write a null-terminated string to. - * len: Maximum number of bytes that can be written to the `buf`. - * - * Returns 0 if successful, negative values if whatami contains an invalid bitmask or `buf` is null, - * or number of remaining bytes, if the null-terminated string size exceeds `len`. - */ -ZENOHC_API int8_t z_whatami_to_str(uint8_t whatami, char *buf, size_t len); -/** - * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. - */ -ZENOHC_API -struct z_owned_config_t zc_config_from_file(const char *path); -/** - * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. - * - * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). - */ -ZENOHC_API -struct z_owned_config_t zc_config_from_str(const char *s); -/** - * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. - * Use `z_drop` to safely deallocate this string - */ -ZENOHC_API -struct z_owned_str_t zc_config_get(struct z_config_t config, - const char *key); -/** - * Inserts a JSON-serialized `value` at the `key` position of the configuration. - * - * Returns 0 if successful, a negative value otherwise. - */ -ZENOHC_API -int8_t zc_config_insert_json(struct z_config_t config, - const char *key, - const char *value); -/** - * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. - */ -ZENOHC_API -struct z_owned_str_t zc_config_to_string(struct z_config_t config); -/** - * Initialises the zenoh runtime logger. - * - * Note that unless you built zenoh-c with the `logger-autoinit` feature disabled, - * this will be performed automatically by `z_open` and `z_scout`. - */ -ZENOHC_API void zc_init_logger(void); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API struct z_keyexpr_t zc_keyexpr_from_slice(const char *name, size_t len); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - * The string is canonized in-place before being passed to keyexpr. - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -struct z_keyexpr_t zc_keyexpr_from_slice_autocanonize(char *name, - size_t *len); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions: - * - `name` MUST be valid UTF8. - * - `name` MUST follow the Key Expression specification, ie: - * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. - * - any instance of ``**`` may only be lead or followed by ``/``. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -struct z_keyexpr_t zc_keyexpr_from_slice_unchecked(const char *start, - size_t len); -/** - * Returns `true` if the options are valid. - */ -ZENOHC_API -bool zc_liveliness_declaration_options_check(const struct zc_owned_liveliness_declaration_options_t *_opts); -/** - * Destroys the options. - */ -ZENOHC_API -void zc_liveliness_declaration_options_drop(struct zc_owned_liveliness_declaration_options_t *opts); -/** - * The gravestone value for `zc_owned_liveliness_declaration_options_t` - */ -ZENOHC_API -struct zc_owned_liveliness_declaration_options_t zc_liveliness_declaration_options_null(void); -/** - * Declares a subscriber on liveliness tokens that intersect `key`. - * - * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t keyexpr: The key expression to subscribe. - * z_owned_closure_sample_t callback: The callback function that will be called each time a - * liveliness token status changed. - * zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. - * - * Returns: - * A :c:type:`z_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the subscriber is still valid, - * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -ZENOHC_API -struct z_owned_subscriber_t zc_liveliness_declare_subscriber(struct z_session_t session, - struct z_keyexpr_t key, - struct z_owned_closure_sample_t *callback, - const struct zc_owned_liveliness_declare_subscriber_options_t *_options); -/** - * Constructs and declares a liveliness token on the network. - * - * Liveliness token subscribers on an intersecting key expression will receive a PUT sample when connectivity - * is achieved, and a DELETE sample if it's lost. - * - * Passing `NULL` as options is valid and equivalent to a pointer to the default options. - */ -ZENOHC_API -struct zc_owned_liveliness_token_t zc_liveliness_declare_token(struct z_session_t session, - struct z_keyexpr_t key, - const struct zc_owned_liveliness_declaration_options_t *_options); -/** - * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. - * - * Note that the same "value stealing" tricks apply as with a normal :c:func:`z_get` - * - * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. - */ -ZENOHC_API -int8_t zc_liveliness_get(struct z_session_t session, - struct z_keyexpr_t key, - struct z_owned_closure_reply_t *callback, - const struct zc_liveliness_get_options_t *options); -/** - * Returns `true` if the options are valid. - */ -ZENOHC_API bool zc_liveliness_get_options_check(const struct zc_liveliness_get_options_t *_opts); -/** - * The gravestone value for `zc_liveliness_get_options_t` - */ -ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_default(void); -/** - * Destroys the options. - */ -ZENOHC_API void zc_liveliness_get_options_drop(struct zc_liveliness_get_options_t *opts); -/** - * The gravestone value for `zc_liveliness_get_options_t` - */ -ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_null(void); -/** - * Returns `true` if the options are valid. - */ -ZENOHC_API -bool zc_liveliness_subscriber_options_check(const struct zc_owned_liveliness_declare_subscriber_options_t *_opts); -/** - * Destroys the options. - */ -ZENOHC_API -void zc_liveliness_subscriber_options_drop(struct zc_owned_liveliness_declare_subscriber_options_t *opts); -/** - * The gravestone value for `zc_owned_liveliness_declare_subscriber_options_t` - */ -ZENOHC_API -struct zc_owned_liveliness_declare_subscriber_options_t zc_liveliness_subscriber_options_null(void); -/** - * Returns `true` unless the token is at its gravestone value. - */ -ZENOHC_API bool zc_liveliness_token_check(const struct zc_owned_liveliness_token_t *token); -/** - * The gravestone value for liveliness tokens. - */ -ZENOHC_API struct zc_owned_liveliness_token_t zc_liveliness_token_null(void); -/** - * Destroys a liveliness token, notifying subscribers of its destruction. - */ -ZENOHC_API void zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t *token); -/** - * Returns `false` if `payload` is the gravestone value. - */ -ZENOHC_API bool zc_payload_check(const zc_owned_payload_t *payload); -/** - * Increments internal payload reference count, returning owned payload. - */ -ZENOHC_API zc_owned_payload_t zc_payload_clone(zc_payload_t payload); -/** - * Decodes payload into null-terminated string - */ -ZENOHC_API int8_t zc_payload_decode_into_bytes(zc_payload_t payload, struct z_owned_bytes_t *b); -/** - * Decodes payload into null-terminated string - */ -ZENOHC_API int8_t zc_payload_decode_into_string(zc_payload_t payload, struct z_owned_str_t *cstr); -/** - * Decrements `payload`'s backing refcount, releasing the memory if appropriate. - */ -ZENOHC_API void zc_payload_drop(zc_owned_payload_t *payload); -/** - * Encodes byte sequence by aliasing. - */ -ZENOHC_API zc_owned_payload_t zc_payload_encode_from_bytes(struct z_bytes_t bytes); -/** - * Encodes a null-terminated string by aliasing. - */ -ZENOHC_API zc_owned_payload_t zc_payload_encode_from_string(const char *cstr); -/** - * Returns total number bytes in the payload. - */ -ZENOHC_API size_t zc_payload_len(zc_payload_t payload); -/** - * Returns a :c:type:`zc_payload_t` loaned from `payload`. - */ -ZENOHC_API zc_payload_t zc_payload_loan(const zc_owned_payload_t *payload); -/** - * Constructs `zc_owned_payload_t`'s gravestone value. - */ -ZENOHC_API zc_owned_payload_t zc_payload_null(void); -/** - * Clones the `payload` by incrementing its reference counter. - */ -ZENOHC_API zc_owned_payload_t zc_payload_rcinc(const zc_owned_payload_t *payload); -/** - * Creates a reader for the specified `payload`. - * - * Returns 0 in case of success, -1 if `payload` is not valid. - */ -ZENOHC_API int8_t zc_payload_reader_init(zc_payload_t payload, struct zc_payload_reader *reader); -/** - * Reads data into specified destination. - * - * Will read at most `len` bytes. - * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. - */ -ZENOHC_API -size_t zc_payload_reader_read(struct zc_payload_reader *reader, - uint8_t *dest, - size_t len); -/** - * Returns number of the remaining bytes in the payload - * - */ -ZENOHC_API size_t zc_payload_reader_remaining(const struct zc_payload_reader *reader); -/** - * Creates a new blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, - * which it will then return; or until the `send` closure is dropped and all queries have been consumed, - * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_query_channel_t zc_query_fifo_new(size_t bound); -/** - * Creates a new non-blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, - * which it will then return; or until the `send` closure is dropped and all queries have been consumed, - * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_query_channel_t zc_query_non_blocking_fifo_new(size_t bound); -/** - * Creates a new blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, - * which it will then return; or until the `send` closure is dropped and all replies have been consumed, - * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); -/** - * Creates a new non-blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, - * which it will then return; or until the `send` closure is dropped and all replies have been consumed, - * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); -/** - * Returns `true` if `sample` is valid. - * - * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed - * unless the value has been dropped already. - */ -ZENOHC_API -bool zc_sample_check(const struct zc_owned_sample_t *sample); -/** - * Clone a sample in the cheapest way available. - */ -ZENOHC_API void zc_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); -/** - * Destroy the sample. - */ -ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); -/** - * Borrow the sample, allowing calling its accessor methods. - * - * Calling this function using a dropped sample is undefined behaviour. - */ -ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); -ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); -/** - * Increments the session's reference count, returning a new owning handle. - */ -ZENOHC_API struct z_owned_session_t zc_session_rcinc(struct z_session_t session); -/** - * Allocates a buffer of size `capacity` in the manager's memory. - * - * # Safety - * Calling this function concurrently with other shm functions on the same manager is UB. - */ -ZENOHC_API -struct zc_owned_shmbuf_t zc_shm_alloc(const struct zc_owned_shm_manager_t *manager, - size_t capacity); -/** - * Runs a defragmentation pass on the SHM manager. - * - * Note that this doesn't trigger a garbage collection pass, nor does it move currently allocated data. - * - * # Safety - * Calling this function concurrently with other shm functions on the same manager is UB. - */ -ZENOHC_API -size_t zc_shm_defrag(const struct zc_owned_shm_manager_t *manager); -/** - * Runs a garbage collection pass on the SHM manager. - * - * Returns the number of bytes that have been freed by the pass. - * - * # Safety - * Calling this function concurrently with other shm functions on the same manager is UB. - */ -ZENOHC_API size_t zc_shm_gc(const struct zc_owned_shm_manager_t *manager); -ZENOHC_API bool zc_shm_manager_check(const struct zc_owned_shm_manager_t *manager); -ZENOHC_API void zc_shm_manager_drop(struct zc_owned_shm_manager_t *manager); -ZENOHC_API -struct zc_owned_shm_manager_t zc_shm_manager_new(struct z_session_t session, - const char *id, - size_t size); -ZENOHC_API struct zc_owned_shm_manager_t zc_shm_manager_null(void); -/** - * Returns the capacity of the SHM buffer. - */ -ZENOHC_API size_t zc_shmbuf_capacity(const struct zc_owned_shmbuf_t *buf); -/** - * Returns `false` if `buf` is in its gravestone state. - */ -ZENOHC_API bool zc_shmbuf_check(const struct zc_owned_shmbuf_t *buf); -/** - * Drops the SHM buffer, decrementing its backing reference counter. - */ -ZENOHC_API void zc_shmbuf_drop(struct zc_owned_shmbuf_t *buf); -/** - * Constructs an owned payload from an owned SHM buffer. - */ -ZENOHC_API zc_owned_payload_t zc_shmbuf_into_payload(struct zc_owned_shmbuf_t *buf); -/** - * Returns the length of the SHM buffer. - * - * Note that when constructing an SHM buffer, length is defaulted to its capacity. - */ -ZENOHC_API size_t zc_shmbuf_length(const struct zc_owned_shmbuf_t *buf); -/** - * Constructs a null safe-to-drop value of type `zc_owned_shmbuf_t` - */ -ZENOHC_API struct zc_owned_shmbuf_t zc_shmbuf_null(void); -/** - * Returns the start of the SHM buffer. - */ -ZENOHC_API uint8_t *zc_shmbuf_ptr(const struct zc_owned_shmbuf_t *buf); -/** - * Sets the length of the SHM buffer. - * - * This lets Zenoh know how much of the data to write over the network when sending the value to non-SHM-compatible neighboors. - */ -ZENOHC_API -void zc_shmbuf_set_length(const struct zc_owned_shmbuf_t *buf, - size_t len); -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void zcu_closure_matching_status_call(const struct zcu_owned_closure_matching_status_t *closure, - const struct zcu_matching_status_t *sample); -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API -void zcu_closure_matching_status_drop(struct zcu_owned_closure_matching_status_t *closure); -/** - * Constructs a null safe-to-drop value of 'zcu_owned_closure_matching_status_t' type - */ -ZENOHC_API struct zcu_owned_closure_matching_status_t zcu_closure_matching_status_null(void); -ZENOHC_API enum zcu_locality_t zcu_locality_default(void); -/** - * Register callback for notifying subscribers matching. - */ -ZENOHC_API -struct zcu_owned_matching_listener_t zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, - struct zcu_owned_closure_matching_status_t *callback); -ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); -/** - * Declares a Publication Cache. - * - * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t keyexpr: The key expression to publish. - * ze_publication_cache_options_t options: Additional options for the publication_cache. - * - * Returns: - * :c:type:`ze_owned_publication_cache_t`. - * - * - * Example: - * Declaring a publication cache `NULL` for the options: - * - * .. code-block:: C - * - * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), NULL); - * - * is equivalent to initializing and passing the default publication cache options: - * - * .. code-block:: C - * - * ze_publication_cache_options_t opts = ze_publication_cache_options_default(); - * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), &opts); - */ -ZENOHC_API -struct ze_owned_publication_cache_t ze_declare_publication_cache(struct z_session_t session, - struct z_keyexpr_t keyexpr, - const struct ze_publication_cache_options_t *options); -/** - * Returns ``true`` if `pub_cache` is valid. - */ -ZENOHC_API bool ze_publication_cache_check(const struct ze_owned_publication_cache_t *pub_cache); -/** - * Constructs a null safe-to-drop value of 'ze_owned_publication_cache_t' type - */ -ZENOHC_API struct ze_owned_publication_cache_t ze_publication_cache_null(void); -/** - * Constructs the default value for :c:type:`ze_publication_cache_options_t`. - */ -ZENOHC_API struct ze_publication_cache_options_t ze_publication_cache_options_default(void); -/** - * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -int8_t ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *pub_cache); diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 491551ee1..9ef5cb4e1 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -15,58 +15,3 @@ #define ALIGN(n) #define ZENOHC_API #endif -#include -#include -#include -#include -#include -#define DEFAULT_SCOUTING_TIMEOUT 1000 -/** - * An owned zenoh session. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct z_owned_session_t { - size_t _0; -} z_owned_session_t; -typedef struct ALIGN(8) z_query_t { - uint8_t _0[8]; -} z_query_t; -/** - * A loaned zenoh session. - */ -typedef struct z_session_t { - size_t _0; -} z_session_t; -typedef struct ALIGN(8) z_owned_queryable_t { - uint8_t _0[32]; -} z_owned_queryable_t; -/** - * An owned zenoh subscriber. Destroying the subscriber cancels the subscription. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -#if !defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_owned_subscriber_t { - uint64_t _0[1]; -} z_owned_subscriber_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(4) z_owned_subscriber_t { - uint32_t _0[1]; -} z_owned_subscriber_t; -#endif diff --git a/src/lib.rs b/src/lib.rs index 547d9178d..cc4b631f8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,139 +14,56 @@ #![allow(non_camel_case_types)] -mod collections; -use std::cmp::min; -use std::slice; +// mod collections; +// use std::cmp::min; +// use std::slice; #[macro_use] mod transmute; -pub use crate::collections::*; -mod config; -pub use crate::config::*; -mod commons; -pub use crate::commons::*; -mod payload; -pub use crate::payload::*; -mod keyexpr; -pub use crate::keyexpr::*; -mod info; -pub use crate::info::*; -mod get; -pub use crate::get::*; -mod queryable; -pub use crate::queryable::*; -mod put; -pub use crate::put::*; -mod scouting; -pub use crate::scouting::*; -mod session; -pub use crate::session::*; -mod subscriber; -pub use crate::subscriber::*; -// mod pull_subscriber; -// pub use crate::pull_subscriber::*; -mod publisher; -pub use crate::publisher::*; -mod closures; -pub use closures::*; -mod liveliness; -use libc::c_void; -pub use liveliness::*; -mod publication_cache; -pub use publication_cache::*; -// Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. -// mod querying_subscriber; -// pub use querying_subscriber::*; -pub mod attachment; -pub use platform::*; -pub mod opaque_types; -pub mod platform; -#[cfg(feature = "shared-memory")] -mod shm; - -trait GuardedTransmute { - fn transmute(self) -> D; -} - -/// For internal use only. -/// -/// This macro is used to establish the equivalence between a Rust type (first parameter) and a C layout (second parameter). -/// -/// It automatically implements `From`, `Deref` and `DerefMut` to make writing code around these equivalent types. -/// -/// Because carrying around the proper semantics of lifetimes is hard, this macro fails to produce working code when lifetimes are -/// present in either parameter. You may then call it with the `noderefs` prefix to avoid the offending implementations being defined. -#[macro_export] -macro_rules! impl_guarded_transmute { - ($src_type:ty, $dst_type:ty) => { - impl_guarded_transmute!(noderefs $src_type, $dst_type); - impl From<$src_type> for $dst_type { - fn from(value: $src_type) -> $dst_type { - unsafe { core::mem::transmute(value) } - } - } - impl core::ops::Deref for $dst_type { - type Target = $src_type; - fn deref(&self) -> &$src_type { - unsafe { core::mem::transmute(self) } - } - } - impl core::ops::DerefMut for $dst_type { - fn deref_mut(&mut self) -> &mut $src_type { - unsafe { core::mem::transmute(self) } - } - } - - }; - (noderefs $src_type:ty, $dst_type:ty) => { - const _: () = { - let src = std::mem::align_of::<$src_type>(); - let dst = std::mem::align_of::<$dst_type>(); - if src != dst { - let mut msg: [u8; 20] = *b"src: , dst: "; - let mut i = 0; - while i < 4 { - msg[i as usize + 5] = b'0' + ((src / 10u32.pow(3 - i) as usize) % 10) as u8; - msg[i as usize + 16] = b'0' + ((dst / 10u32.pow(3 - i) as usize) % 10) as u8; - i += 1; - } - panic!("{}", unsafe { - std::str::from_utf8_unchecked(msg.as_slice()) - }); - } - }; - impl $crate::GuardedTransmute<$dst_type> for $src_type { - fn transmute(self) -> $dst_type { - unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } - } - } - }; - ($src_type:ty, $dst_type:ty, $($gen: tt)*) => { - impl<$($gen)*> $crate::GuardedTransmute<$dst_type> for $src_type { - fn transmute(self) -> $dst_type { - unsafe { std::mem::transmute::<$src_type, $dst_type>(self) } - } - } - impl<$($gen)*> From<$src_type> for $dst_type { - fn from(value: $src_type) -> $dst_type { - unsafe { core::mem::transmute(value) } - } - } - impl<$($gen)*> core::ops::Deref for $dst_type { - type Target = $src_type; - fn deref(&self) -> &$src_type { - unsafe { core::mem::transmute(self) } - } - } - impl<$($gen)*> core::ops::DerefMut for $dst_type { - fn deref_mut(&mut self) -> &mut $src_type { - unsafe { core::mem::transmute(self) } - } - } - - }; -} +// pub use crate::collections::*; +// mod config; +// pub use crate::config::*; +// mod commons; +// pub use crate::commons::*; +// mod payload; +// pub use crate::payload::*; +// mod keyexpr; +// pub use crate::keyexpr::*; +// mod info; +// pub use crate::info::*; +// mod get; +// pub use crate::get::*; +// mod queryable; +// pub use crate::queryable::*; +// mod put; +// pub use crate::put::*; +// mod scouting; +// pub use crate::scouting::*; +// mod session; +// pub use crate::session::*; +// mod subscriber; +// pub use crate::subscriber::*; +// // mod pull_subscriber; +// // pub use crate::pull_subscriber::*; +// mod publisher; +// pub use crate::publisher::*; +// mod closures; +// pub use closures::*; +// mod liveliness; +// use libc::c_void; +// pub use liveliness::*; +// mod publication_cache; +// pub use publication_cache::*; +// // Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. +// // mod querying_subscriber; +// // pub use querying_subscriber::*; +// pub mod attachment; +// pub use platform::*; +// pub mod opaque_types; +// pub mod platform; +// #[cfg(feature = "shared-memory")] +// mod shm; pub(crate) const LOG_INVALID_SESSION: &str = "Invalid session"; From 34c471b737c4b24101c83831fb236dae6dda0bfb Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sat, 13 Apr 2024 20:05:44 +0200 Subject: [PATCH 47/75] disabled header split, compiles --- build.rs | 4 +-- include/zenoh-gen.h | 60 +++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 8 +++--- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/build.rs b/build.rs index 89fffff0d..97a90078a 100644 --- a/build.rs +++ b/build.rs @@ -39,8 +39,8 @@ fn main() { configure(); let split_guide = SplitGuide::from_yaml(SPLITGUIDE_PATH); - split_bindings(&split_guide).unwrap(); - text_replace(split_guide.rules.iter().map(|(name, _)| name.as_str())); + // split_bindings(&split_guide).unwrap(); + // text_replace(split_guide.rules.iter().map(|(name, _)| name.as_str())); fs_extra::copy_items( &["include"], diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index 0e648f1e9..ee1325666 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -5,6 +5,66 @@ #include +typedef struct z_owned_bytes_t { + uint8_t *start; + size_t len; +} z_owned_bytes_t; + +/** + * A contiguous view of bytes owned by some other entity. + * + * `start` being `null` is considered a gravestone value, + * and empty slices are represented using a possibly dangling pointer for `start`. + */ +typedef struct z_bytes_t { + const uint8_t *start; + size_t len; +} z_bytes_t; + +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *b); + +ZENOHC_API struct z_owned_bytes_t z_bytes_clone(const struct z_bytes_t *b); + +/** + * Returns the gravestone value for `z_bytes_t` + */ +ZENOHC_API struct z_bytes_t z_bytes_empty(void); + +/** + * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * `str == NULL` will cause this to return `z_bytes_empty()` + */ +ZENOHC_API struct z_bytes_t z_bytes_from_str(const char *str); + +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_bytes_is_initialized(const struct z_bytes_t *b); + +ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *b); + +/** + * Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * `str == NULL` will cause this to return `z_bytes_empty()` + */ +ZENOHC_API +struct z_bytes_t z_bytes_new(const char *str); + +/** + * Returns the gravestone value for `z_owned_bytes_t` + */ +ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); + +/** + * Constructs a `len` bytes long view starting at `start`. + */ +ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); + /** * Initialises the zenoh runtime logger. * diff --git a/src/lib.rs b/src/lib.rs index cc4b631f8..ddae302f6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,9 +14,10 @@ #![allow(non_camel_case_types)] -// mod collections; -// use std::cmp::min; -// use std::slice; +mod collections; +use libc::c_void; +use std::cmp::min; +use std::slice; #[macro_use] mod transmute; @@ -51,7 +52,6 @@ mod transmute; // mod closures; // pub use closures::*; // mod liveliness; -// use libc::c_void; // pub use liveliness::*; // mod publication_cache; // pub use publication_cache::*; From 8a6ef172cb6c3d3fe28e58c443cb234a004b7448 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 14 Apr 2024 13:40:37 +0200 Subject: [PATCH 48/75] session weak remove started --- build-resources/opaque-types/src/lib.rs | 14 + include/zenoh-gen.h | 419 ++++++++++++++++++++++++ src/keyexpr.rs | 166 ++++------ src/lib.rs | 10 +- src/session.rs | 69 +--- src/transmute.rs | 6 +- 6 files changed, 516 insertions(+), 168 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 698646271..df6b91701 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,9 +1,12 @@ +use std::sync::Arc; use zenoh::buffers::{ZBuf, ZBufReader}; use zenoh::encoding::Encoding; +use zenoh::key_expr::KeyExpr; use zenoh::query::Reply; use zenoh::queryable::Query; use zenoh::queryable::Queryable; use zenoh::sample::Sample; +use zenoh::session::Session; use zenoh::value::Value; // Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. @@ -56,13 +59,18 @@ get_opaque_type_data!(ZBufReader, "zc_payload_reader"); get_opaque_type_data!(&'static Encoding, "z_encoding_t"); get_opaque_type_data!(Encoding, "z_owned_encoding_t"); + get_opaque_type_data!(Option, "z_owned_reply_t"); + get_opaque_type_data!(Value, "z_owned_value_t"); get_opaque_type_data!(&'static Value, "z_value_t"); + get_opaque_type_data!(Option, "z_owned_query_t"); get_opaque_type_data!(&'static Query, "z_query_t"); + get_opaque_type_data!(Option>, "z_owned_queryable_t"); get_opaque_type_data!(&'static Queryable<'static, ()>, "z_queryable_t"); + // get_opaque_type_data!( // Option>, // "ze_owned_querying_subscriber_t" @@ -71,3 +79,9 @@ get_opaque_type_data!(&'static Queryable<'static, ()>, "z_queryable_t"); // &'static FetchingSubscriberWrapper, // "ze_querying_subscriber_t" // ); + +get_opaque_type_data!(Option>, "z_owned_keyexpr_t"); +get_opaque_type_data!(&'static KeyExpr<'_>, "z_keyexpr_t"); + +get_opaque_type_data!(Option>, "z_owned_session_t"); +get_opaque_type_data!(&'static Session, "z_session_t"); diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index ee1325666..7ebf978cb 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -5,6 +5,21 @@ #include +/** + * A :c:type:`z_keyexpr_intersection_level_t`. + * + * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** + */ +typedef enum z_keyexpr_intersection_level_t { + Z_KEYEXPR_INTERSECTION_LEVEL_T_DISJOINT = 0, + Z_KEYEXPR_INTERSECTION_LEVEL_T_INTERSECTS = 1, + Z_KEYEXPR_INTERSECTION_LEVEL_T_INCLUDES = 2, + Z_KEYEXPR_INTERSECTION_LEVEL_T_EQUALS = 3, +} z_keyexpr_intersection_level_t; + typedef struct z_owned_bytes_t { uint8_t *start; size_t len; @@ -21,6 +36,73 @@ typedef struct z_bytes_t { size_t len; } z_bytes_t; +typedef struct ALIGN(8) z_owned_session_t { + uint8_t _0[8]; +} z_owned_session_t; + +/** + * An owned zenoh configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct z_owned_config_t { + void *_0; +} z_owned_config_t; + +/** + * A loaned zenoh configuration. + */ +typedef struct z_config_t { + const struct z_owned_config_t *_0; +} z_config_t; + +typedef struct ALIGN(8) z_owned_keyexpr_t { + uint8_t _0[32]; +} z_owned_keyexpr_t; + +typedef struct ALIGN(8) z_session_t { + uint8_t _0[8]; +} z_session_t; + +typedef struct ALIGN(8) z_keyexpr_t { + uint8_t _0[8]; +} z_keyexpr_t; + +extern const unsigned int Z_ROUTER; + +extern const unsigned int Z_PEER; + +extern const unsigned int Z_CLIENT; + +extern const char *Z_CONFIG_MODE_KEY; + +extern const char *Z_CONFIG_CONNECT_KEY; + +extern const char *Z_CONFIG_LISTEN_KEY; + +extern const char *Z_CONFIG_USER_KEY; + +extern const char *Z_CONFIG_PASSWORD_KEY; + +extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; + +extern const char *Z_CONFIG_MULTICAST_INTERFACE_KEY; + +extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; + +extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; + +extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; + +extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; + /** * Returns ``true`` if `b` is initialized. */ @@ -65,6 +147,308 @@ ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); */ ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); +/** + * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * + * Returns a negative value if an error occured while closing the session. + * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + */ +ZENOHC_API int8_t z_close(struct z_owned_session_t *session); + +/** + * Returns ``true`` if `config` is valid. + */ +ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); + +/** + * Constructs a default, zenoh-allocated, client mode configuration. + * If `peer` is not null, it is added to the configuration as remote peer. + */ +ZENOHC_API struct z_owned_config_t z_config_client(const char *const *peers, size_t n_peers); + +/** + * Creates a default, zenoh-allocated, configuration. + */ +ZENOHC_API struct z_owned_config_t z_config_default(void); + +/** + * Frees `config`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_config_drop(struct z_owned_config_t *config); + +/** + * Returns a :c:type:`z_config_t` loaned from `s`. + */ +ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); + +/** + * Return a new, zenoh-allocated, empty configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +ZENOHC_API +struct z_owned_config_t z_config_new(void); + +/** + * Constructs a null safe-to-drop value of 'z_owned_config_t' type + */ +ZENOHC_API struct z_owned_config_t z_config_null(void); + +/** + * Constructs a default, zenoh-allocated, peer mode configuration. + */ +ZENOHC_API struct z_owned_config_t z_config_peer(void); + +/** + * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. + * + * This numerical id will be used on the network to save bandwidth and + * ease the retrieval of the concerned resource in the routing tables. + */ +ZENOHC_API +int8_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, + struct z_session_t session, + struct z_keyexpr_t keyexpr); + +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API struct z_keyexpr_t z_keyexpr(const char *name); + +/** + * Returns the key expression's internal string by aliasing it. + * + * Currently exclusive to zenoh-c + */ +ZENOHC_API struct z_bytes_t z_keyexpr_as_bytes(struct z_keyexpr_t keyexpr); + +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + * The string is canonized in-place before being passed to keyexpr. + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +struct z_keyexpr_t z_keyexpr_autocanonize(char *name); + +/** + * Canonizes the passed string in place, possibly shortening it by modifying `len`. + * + * Returns ``0`` upon success, negative values upon failure. + * Returns a negative value if canonization failed, which indicates that the passed string was an invalid + * key expression for reasons other than a non-canon form. + * + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +int8_t z_keyexpr_canonize(char *start, + size_t *len); + +/** + * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. + * + * Returns ``0`` upon success, negative values upon failure. + * Returns a negative value if canonization failed, which indicates that the passed string was an invalid + * key expression for reasons other than a non-canon form. + * + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +int8_t z_keyexpr_canonize_null_terminated(char *start); + +/** + * Returns ``true`` if `keyexpr` is valid. + */ +ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); + +/** + * Performs string concatenation and returns the result as a `z_owned_keyexpr_t`. + * In case of error, the return value will be set to its invalidated state. + * + * You should probably prefer `z_keyexpr_join` as Zenoh may then take advantage of the hierachical separation it inserts. + * + * To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, + * as this would extremely likely cause bugs. + */ +ZENOHC_API +struct z_owned_keyexpr_t z_keyexpr_concat(struct z_keyexpr_t left, + const char *right_start, + size_t right_len); + +/** + * Frees `keyexpr` and invalidates it for double-drop safety. + */ +ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); + +/** + * Returns ``0`` if both ``left`` and ``right`` are equal. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. + */ +ZENOHC_API +int8_t z_keyexpr_equals(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set + * defined by ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. + */ +ZENOHC_API +int8_t z_keyexpr_includes(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the + * sets defined by ``left`` and ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. + */ +ZENOHC_API +int8_t z_keyexpr_intersects(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Returns ``0`` if the passed string is a valid (and canon) key expression. + * Otherwise returns error value + */ +ZENOHC_API int8_t z_keyexpr_is_canon(const char *start, size_t len); + +/** + * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. + * In case of error, the return value will be set to its invalidated state. + */ +ZENOHC_API +struct z_owned_keyexpr_t z_keyexpr_join(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + */ +ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *keyexpr); + +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. + */ +ZENOHC_API int8_t z_keyexpr_new(struct z_owned_keyexpr_t *this_, const char *name); + +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. + */ +ZENOHC_API +int8_t z_keyexpr_new_autocanonize(struct z_owned_keyexpr_t *this_, + const char *name); + +/** + * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type + */ +ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); + +/** + * Returns the relation between `left` and `right` from `left`'s point of view. + * + * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. + */ +ZENOHC_API +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. + * The user is responsible of droping the returned string using `z_drop` + */ +ZENOHC_API z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t keyexpr); + +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions: + * + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * + * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. + * - any instance of `**` may only be lead or followed by `/`. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API +struct z_keyexpr_t z_keyexpr_unchecked(const char *name); + +/** + * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + */ +ZENOHC_API +struct z_owned_session_t z_open(struct z_owned_config_t *config); + +/** + * Returns ``true`` if `session` is valid. + */ +ZENOHC_API bool z_session_check(const struct z_owned_session_t *session); + +/** + * Returns a :c:type:`z_session_t` loaned from `s`. + * + * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. + * + * # Safety + * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, + * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) + * have been destroyed is UB (likely SEGFAULT) + */ +ZENOHC_API +struct z_session_t z_session_loan(const struct z_owned_session_t *s); + +/** + * Constructs a null safe-to-drop value of 'z_owned_session_t' type + */ +ZENOHC_API void z_session_null(struct z_owned_session_t *s); + +/** + * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. + */ +ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); + +/** + * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. + */ +ZENOHC_API +struct z_owned_config_t zc_config_from_file(const char *path); + +/** + * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. + * + * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). + */ +ZENOHC_API +struct z_owned_config_t zc_config_from_str(const char *s); + +/** + * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. + * Use `z_drop` to safely deallocate this string + */ +ZENOHC_API +z_owned_str_t zc_config_get(struct z_config_t config, + const char *key); + +/** + * Inserts a JSON-serialized `value` at the `key` position of the configuration. + * + * Returns 0 if successful, a negative value otherwise. + */ +ZENOHC_API +int8_t zc_config_insert_json(struct z_config_t config, + const char *key, + const char *value); + +/** + * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. + */ +ZENOHC_API +z_owned_str_t zc_config_to_string(struct z_config_t config); + /** * Initialises the zenoh runtime logger. * @@ -72,3 +456,38 @@ ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); * this will be performed automatically by `z_open` and `z_scout`. */ ZENOHC_API void zc_init_logger(void); + +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API struct z_keyexpr_t zc_keyexpr_from_slice(const char *name, size_t len); + +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + * The string is canonized in-place before being passed to keyexpr. + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +struct z_keyexpr_t zc_keyexpr_from_slice_autocanonize(char *name, + size_t *len); + +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions: + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. + * - any instance of ``**`` may only be lead or followed by ``/``. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API +struct z_keyexpr_t zc_keyexpr_from_slice_unchecked(const char *start, + size_t len); + +/** + * Increments the session's reference count, returning a new owning handle. + */ +ZENOHC_API struct z_owned_session_t zc_session_rcinc(struct z_session_t session); diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 6b7adeacf..a97691ad7 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -13,17 +13,20 @@ // use std::convert::TryFrom; +use std::mem::MaybeUninit; use std::ops::Deref; use std::ops::DerefMut; -use crate::impl_guarded_transmute; -use crate::session::*; +use crate::transmute::unwrap_ref_unchecked; +use crate::transmute::Inplace; +use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteRef; use crate::z_bytes_t; use crate::z_owned_str_t; use crate::z_str_null; -use crate::GuardedTransmute; use crate::LOG_INVALID_SESSION; use libc::c_char; +use zenoh::core::ErrNo; use zenoh::core::SyncResolve; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; @@ -53,52 +56,45 @@ use zenoh::prelude::KeyExpr; /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_keyexpr_t([u64; 4]); -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_owned_keyexpr_t([u32; 5]); - -impl_guarded_transmute!(Option>, z_owned_keyexpr_t); - -impl From> for z_owned_keyexpr_t { - fn from(val: KeyExpr<'static>) -> Self { - Some(val).into() - } -} -impl z_owned_keyexpr_t { - pub fn null() -> Self { - None::.into() - } -} +pub use crate::opaque_types::z_owned_keyexpr_t; +decl_transmute_owned!(default_inplace_init Option>, z_owned_keyexpr_t); /// Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_keyexpr_null() -> z_owned_keyexpr_t { - z_owned_keyexpr_t::null() +pub extern "C" fn z_keyexpr_null(this: *mut MaybeUninit) { + Inplace::empty(z_owned_keyexpr_t::transmute_uninit_ptr(this)); } /// Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_new(name: *const c_char) -> z_owned_keyexpr_t { +pub unsafe extern "C" fn z_keyexpr_new( + this: *mut MaybeUninit, + name: *const c_char, +) -> i8 { + let this = z_owned_keyexpr_t::transmute_uninit_ptr(this); if name.is_null() { - return z_owned_keyexpr_t::null(); + Inplace::empty(this); + return -1; } let name = std::slice::from_raw_parts(name as _, libc::strlen(name)); match std::str::from_utf8(name) { Ok(name) => match KeyExpr::try_from(name) { - Ok(v) => v.into_owned().into(), + Ok(v) => { + Inplace::init(this, Some(v)); + 0 + } Err(e) => { log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + -1 } }, Err(e) => { log::error!("{}", e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + -1 } } } @@ -106,25 +102,35 @@ pub unsafe extern "C" fn z_keyexpr_new(name: *const c_char) -> z_owned_keyexpr_t /// Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_new_autocanonize(name: *const c_char) -> z_owned_keyexpr_t { +pub unsafe extern "C" fn z_keyexpr_new_autocanonize( + this: *mut MaybeUninit, + name: *const c_char, +) -> i8 { + let this = z_owned_keyexpr_t::transmute_uninit_ptr(this); if name.is_null() { - return z_owned_keyexpr_t::null(); + Inplace::empty(this); + return -1; } let name = std::slice::from_raw_parts(name as _, libc::strlen(name)); match std::str::from_utf8(name) { Ok(name) => { let name_owned = name.to_owned(); match KeyExpr::autocanonize(name_owned) { - Ok(v) => v.into_owned().into(), + Ok(v) => { + Inplace::init(this, Some(v)); + 0 + } Err(e) => { log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + -1 } } } Err(e) => { log::error!("{}", e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + -1 } } } @@ -132,21 +138,21 @@ pub unsafe extern "C" fn z_keyexpr_new_autocanonize(name: *const c_char) -> z_ow /// Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. #[no_mangle] pub extern "C" fn z_keyexpr_loan(keyexpr: &z_owned_keyexpr_t) -> z_keyexpr_t { - keyexpr.as_ref().map(|k| k.borrowing_clone()).into() + unwrap_ref_unchecked(keyexpr.transmute_ref()).transmute_copy() } /// Frees `keyexpr` and invalidates it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_keyexpr_drop(keyexpr: &mut z_owned_keyexpr_t) { - std::mem::drop(keyexpr.take()) + Inplace::drop(keyexpr.transmute_mut()); } /// Returns ``true`` if `keyexpr` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_keyexpr_check(keyexpr: &z_owned_keyexpr_t) -> bool { - keyexpr.deref().is_some() + keyexpr.transmute_ref().is_some() } /// A loaned key expression. @@ -159,49 +165,9 @@ pub extern "C" fn z_keyexpr_check(keyexpr: &z_owned_keyexpr_t) -> bool { /// /// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, /// both for local processing and network-wise. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_keyexpr_t([u64; 4]); -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_keyexpr_t([u32; 5]); - -impl_guarded_transmute!(noderefs Option>, z_keyexpr_t); -impl_guarded_transmute!(noderefs z_keyexpr_t, z_owned_keyexpr_t); - -impl<'a> From> for z_keyexpr_t { - fn from(val: KeyExpr<'a>) -> Self { - Some(val).into() - } -} - -impl From for z_owned_keyexpr_t { - fn from(oke: z_keyexpr_t) -> Self { - oke.transmute() - } -} +pub use crate::opaque_types::z_keyexpr_t; +decl_transmute_copy!(&'static KeyExpr<'static>, z_keyexpr_t); -impl<'a> From>> for z_keyexpr_t { - fn from(val: Option>) -> Self { - val.transmute() - } -} -impl Deref for z_keyexpr_t { - type Target = Option>; - fn deref(&self) -> &Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl DerefMut for z_keyexpr_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl z_keyexpr_t { - pub fn null() -> Self { - None.into() - } -} #[derive(Debug, Clone, Copy)] pub struct UninitializedKeyExprError; impl std::fmt::Display for UninitializedKeyExprError { @@ -210,24 +176,6 @@ impl std::fmt::Display for UninitializedKeyExprError { } } impl std::error::Error for UninitializedKeyExprError {} -impl<'a> TryFrom for KeyExpr<'a> { - type Error = UninitializedKeyExprError; - fn try_from(value: z_keyexpr_t) -> Result { - match value.as_ref() { - Some(ke) => { - Ok(unsafe { std::mem::transmute::>(ke.borrowing_clone()) }) - } - None => Err(UninitializedKeyExprError), - } - } -} - -/// Returns ``true`` if `keyexpr` is initialized. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_keyexpr_is_initialized(keyexpr: &z_keyexpr_t) -> bool { - keyexpr.deref().is_some() -} /// Returns ``0`` if the passed string is a valid (and canon) key expression. /// Otherwise returns error value @@ -448,27 +396,29 @@ impl<'a> From<&'a KeyExpr<'a>> for z_keyexpr_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_declare_keyexpr( + this: *mut MaybeUninit, session: z_session_t, keyexpr: z_keyexpr_t, -) -> z_owned_keyexpr_t { - let key_expr = match keyexpr.as_ref() { - Some(ke) => ke, - None => { - log::warn!("{}", UninitializedKeyExprError); - return z_owned_keyexpr_t::null(); - } - }; +) -> i8 { + let this = z_owned_keyexpr_t::transmute_uninit_ptr(this); + let key_expr = keyexpr.transmute_copy(); + let session = session.transmute_ref(); match session.upgrade() { Some(s) => match s.declare_keyexpr(key_expr).res_sync() { - Ok(id) => id.into_owned().into(), + Ok(id) => { + id.into_owned().into(); + // TODO: store id to keyexpr + } Err(e) => { log::debug!("{}", e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + i8::MIN } }, None => { log::debug!("{}", LOG_INVALID_SESSION); - z_owned_keyexpr_t::null() + Inplace::empty(this); + i8::MIN } } } diff --git a/src/lib.rs b/src/lib.rs index ddae302f6..705c08b6e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,15 +21,16 @@ use std::slice; #[macro_use] mod transmute; +mod opaque_types; -// pub use crate::collections::*; -// mod config; +pub use crate::collections::*; +mod config; // pub use crate::config::*; // mod commons; // pub use crate::commons::*; // mod payload; // pub use crate::payload::*; -// mod keyexpr; +mod keyexpr; // pub use crate::keyexpr::*; // mod info; // pub use crate::info::*; @@ -41,7 +42,7 @@ mod transmute; // pub use crate::put::*; // mod scouting; // pub use crate::scouting::*; -// mod session; +mod session; // pub use crate::session::*; // mod subscriber; // pub use crate::subscriber::*; @@ -60,7 +61,6 @@ mod transmute; // // pub use querying_subscriber::*; // pub mod attachment; // pub use platform::*; -// pub mod opaque_types; // pub mod platform; // #[cfg(feature = "shared-memory")] // mod shm; diff --git a/src/session.rs b/src/session.rs index f710e1703..b369530cf 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,7 +12,10 @@ // ZettaScale Zenoh team, // +use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef}; use crate::{config::*, impl_guarded_transmute, zc_init_logger}; +use std::mem::MaybeUninit; +use std::ops::Deref; use std::sync::{Arc, Weak}; use zenoh::prelude::sync::SyncResolve; use zenoh::session::Session; @@ -20,51 +23,20 @@ use zenoh_util::core::zresult::ErrNo; /// An owned zenoh session. /// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. /// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[repr(C)] -pub struct z_owned_session_t(usize); - -impl_guarded_transmute!(Option>, z_owned_session_t); - -impl AsRef>> for z_session_t { - fn as_ref(&self) -> &Option> { - unsafe { std::mem::transmute(self) } - } -} - -impl z_session_t { - pub fn upgrade(&self) -> Option> { - self.as_ref().as_ref().and_then(Weak::upgrade) - } -} - -impl From>> for z_session_t { - fn from(val: Option>) -> Self { - unsafe { std::mem::transmute(val) } - } -} - -impl z_owned_session_t { - pub fn new(session: Arc) -> Self { - Some(session).into() - } - pub fn null() -> Self { - None::>.into() - } -} +use crate::opaque_types::z_owned_session_t; +decl_transmute_owned!(Option>, z_owned_session_t); /// A loaned zenoh session. -#[allow(non_camel_case_types)] -#[derive(Clone, Copy)] -#[repr(C)] -pub struct z_session_t(usize); +use crate::opaque_types::z_session_t; +decl_transmute_copy!(&'static Session, z_session_t); /// Returns a :c:type:`z_session_t` loaned from `s`. /// @@ -76,22 +48,17 @@ pub struct z_session_t(usize); /// have been destroyed is UB (likely SEGFAULT) #[no_mangle] pub extern "C" fn z_session_loan(s: &z_owned_session_t) -> z_session_t { - match s.as_ref() { - Some(s) => { - let mut weak = Arc::downgrade(s); - unsafe { std::ptr::drop_in_place(&mut weak) }; - Some(weak) - } - None => None, - } - .into() + let s = s.transmute_ref(); + let s = unwrap_ref_unchecked(s); + let s = s.as_ref(); + s.transmute_copy() } /// Constructs a null safe-to-drop value of 'z_owned_session_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_session_null() -> z_owned_session_t { - z_owned_session_t::null() +pub extern "C" fn z_session_null(s: *mut MaybeUninit) { + Inplace::empty(z_owned_session_t::transmute_uninit_ptr(s)); } /// Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. diff --git a/src/transmute.rs b/src/transmute.rs index 70ec1d863..ddc38824a 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -31,7 +31,7 @@ pub(crate) trait TransmuteRef: Sized { } } -pub(crate) trait TransmuteCopy: TransmuteRef { +pub(crate) trait TransmuteCopy { fn transmute_copy(self) -> T; } @@ -101,7 +101,7 @@ macro_rules! validate_equivalence { #[macro_export] macro_rules! decl_transmute_owned { - (default_inplace_init $zenoh_type:ty, $c_type:ty) => { + ($zenoh_type:ty, $c_type:ty) => { impl $crate::transmute::InplaceDefault for $zenoh_type {} decl_transmute_owned!(custom_inplace_init $zenoh_type, $c_type); @@ -117,8 +117,6 @@ macro_rules! decl_transmute_owned { macro_rules! decl_transmute_copy { ($zenoh_type:ty, $c_type:ty) => { validate_equivalence!($zenoh_type, $c_type); - impl_transmute_ref!($zenoh_type, $c_type); - impl_transmute_ref!($c_type, $zenoh_type); impl_transmute_copy!($zenoh_type, $c_type); impl_transmute_copy!($c_type, $zenoh_type); }; From ae9d39b26ed3f114ea03f271adcadced72b2a786 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 14 Apr 2024 14:55:38 +0200 Subject: [PATCH 49/75] session updated --- build-resources/opaque-types/src/lib.rs | 4 + include/zenoh-gen.h | 376 +----------------------- src/lib.rs | 7 +- src/session.rs | 38 ++- 4 files changed, 43 insertions(+), 382 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index df6b91701..bdbc6eeb9 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,5 +1,6 @@ use std::sync::Arc; use zenoh::buffers::{ZBuf, ZBufReader}; +use zenoh::config::Config; use zenoh::encoding::Encoding; use zenoh::key_expr::KeyExpr; use zenoh::query::Reply; @@ -85,3 +86,6 @@ get_opaque_type_data!(&'static KeyExpr<'_>, "z_keyexpr_t"); get_opaque_type_data!(Option>, "z_owned_session_t"); get_opaque_type_data!(&'static Session, "z_session_t"); + +get_opaque_type_data!(Option>, "z_owned_config_t"); +get_opaque_type_data!(&'static Config, "z_config_t"); diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index 7ebf978cb..fdaac4c70 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -5,21 +5,6 @@ #include -/** - * A :c:type:`z_keyexpr_intersection_level_t`. - * - * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** - */ -typedef enum z_keyexpr_intersection_level_t { - Z_KEYEXPR_INTERSECTION_LEVEL_T_DISJOINT = 0, - Z_KEYEXPR_INTERSECTION_LEVEL_T_INTERSECTS = 1, - Z_KEYEXPR_INTERSECTION_LEVEL_T_INCLUDES = 2, - Z_KEYEXPR_INTERSECTION_LEVEL_T_EQUALS = 3, -} z_keyexpr_intersection_level_t; - typedef struct z_owned_bytes_t { uint8_t *start; size_t len; @@ -40,69 +25,14 @@ typedef struct ALIGN(8) z_owned_session_t { uint8_t _0[8]; } z_owned_session_t; -/** - * An owned zenoh configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct z_owned_config_t { - void *_0; +typedef struct ALIGN(8) z_owned_config_t { + uint8_t _0[8]; } z_owned_config_t; -/** - * A loaned zenoh configuration. - */ -typedef struct z_config_t { - const struct z_owned_config_t *_0; -} z_config_t; - -typedef struct ALIGN(8) z_owned_keyexpr_t { - uint8_t _0[32]; -} z_owned_keyexpr_t; - typedef struct ALIGN(8) z_session_t { uint8_t _0[8]; } z_session_t; -typedef struct ALIGN(8) z_keyexpr_t { - uint8_t _0[8]; -} z_keyexpr_t; - -extern const unsigned int Z_ROUTER; - -extern const unsigned int Z_PEER; - -extern const unsigned int Z_CLIENT; - -extern const char *Z_CONFIG_MODE_KEY; - -extern const char *Z_CONFIG_CONNECT_KEY; - -extern const char *Z_CONFIG_LISTEN_KEY; - -extern const char *Z_CONFIG_USER_KEY; - -extern const char *Z_CONFIG_PASSWORD_KEY; - -extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; - -extern const char *Z_CONFIG_MULTICAST_INTERFACE_KEY; - -extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; - -extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; - -extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; - -extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; - /** * Returns ``true`` if `b` is initialized. */ @@ -155,233 +85,12 @@ ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); */ ZENOHC_API int8_t z_close(struct z_owned_session_t *session); -/** - * Returns ``true`` if `config` is valid. - */ -ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); - -/** - * Constructs a default, zenoh-allocated, client mode configuration. - * If `peer` is not null, it is added to the configuration as remote peer. - */ -ZENOHC_API struct z_owned_config_t z_config_client(const char *const *peers, size_t n_peers); - -/** - * Creates a default, zenoh-allocated, configuration. - */ -ZENOHC_API struct z_owned_config_t z_config_default(void); - -/** - * Frees `config`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_config_drop(struct z_owned_config_t *config); - -/** - * Returns a :c:type:`z_config_t` loaned from `s`. - */ -ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); - -/** - * Return a new, zenoh-allocated, empty configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -ZENOHC_API -struct z_owned_config_t z_config_new(void); - -/** - * Constructs a null safe-to-drop value of 'z_owned_config_t' type - */ -ZENOHC_API struct z_owned_config_t z_config_null(void); - -/** - * Constructs a default, zenoh-allocated, peer mode configuration. - */ -ZENOHC_API struct z_owned_config_t z_config_peer(void); - -/** - * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. - * - * This numerical id will be used on the network to save bandwidth and - * ease the retrieval of the concerned resource in the routing tables. - */ -ZENOHC_API -int8_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, - struct z_session_t session, - struct z_keyexpr_t keyexpr); - -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API struct z_keyexpr_t z_keyexpr(const char *name); - -/** - * Returns the key expression's internal string by aliasing it. - * - * Currently exclusive to zenoh-c - */ -ZENOHC_API struct z_bytes_t z_keyexpr_as_bytes(struct z_keyexpr_t keyexpr); - -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - * The string is canonized in-place before being passed to keyexpr. - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -struct z_keyexpr_t z_keyexpr_autocanonize(char *name); - -/** - * Canonizes the passed string in place, possibly shortening it by modifying `len`. - * - * Returns ``0`` upon success, negative values upon failure. - * Returns a negative value if canonization failed, which indicates that the passed string was an invalid - * key expression for reasons other than a non-canon form. - * - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -int8_t z_keyexpr_canonize(char *start, - size_t *len); - -/** - * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. - * - * Returns ``0`` upon success, negative values upon failure. - * Returns a negative value if canonization failed, which indicates that the passed string was an invalid - * key expression for reasons other than a non-canon form. - * - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -int8_t z_keyexpr_canonize_null_terminated(char *start); - -/** - * Returns ``true`` if `keyexpr` is valid. - */ -ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); - -/** - * Performs string concatenation and returns the result as a `z_owned_keyexpr_t`. - * In case of error, the return value will be set to its invalidated state. - * - * You should probably prefer `z_keyexpr_join` as Zenoh may then take advantage of the hierachical separation it inserts. - * - * To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, - * as this would extremely likely cause bugs. - */ -ZENOHC_API -struct z_owned_keyexpr_t z_keyexpr_concat(struct z_keyexpr_t left, - const char *right_start, - size_t right_len); - -/** - * Frees `keyexpr` and invalidates it for double-drop safety. - */ -ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); - -/** - * Returns ``0`` if both ``left`` and ``right`` are equal. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. - */ -ZENOHC_API -int8_t z_keyexpr_equals(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set - * defined by ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. - */ -ZENOHC_API -int8_t z_keyexpr_includes(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the - * sets defined by ``left`` and ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. - */ -ZENOHC_API -int8_t z_keyexpr_intersects(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Returns ``0`` if the passed string is a valid (and canon) key expression. - * Otherwise returns error value - */ -ZENOHC_API int8_t z_keyexpr_is_canon(const char *start, size_t len); - -/** - * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. - * In case of error, the return value will be set to its invalidated state. - */ -ZENOHC_API -struct z_owned_keyexpr_t z_keyexpr_join(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. - */ -ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *keyexpr); - -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. - */ -ZENOHC_API int8_t z_keyexpr_new(struct z_owned_keyexpr_t *this_, const char *name); - -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. - */ -ZENOHC_API -int8_t z_keyexpr_new_autocanonize(struct z_owned_keyexpr_t *this_, - const char *name); - -/** - * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type - */ -ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); - -/** - * Returns the relation between `left` and `right` from `left`'s point of view. - * - * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. - */ -ZENOHC_API -enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. - * The user is responsible of droping the returned string using `z_drop` - */ -ZENOHC_API z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t keyexpr); - -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions: - * - * - `name` MUST be valid UTF8. - * - `name` MUST follow the Key Expression specification, ie: - * - * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. - * - any instance of `**` may only be lead or followed by `/`. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -struct z_keyexpr_t z_keyexpr_unchecked(const char *name); - /** * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. */ ZENOHC_API -struct z_owned_session_t z_open(struct z_owned_config_t *config); +int8_t z_open(struct z_owned_session_t *this_, + struct z_owned_config_t *config); /** * Returns ``true`` if `session` is valid. @@ -406,49 +115,6 @@ struct z_session_t z_session_loan(const struct z_owned_session_t *s); */ ZENOHC_API void z_session_null(struct z_owned_session_t *s); -/** - * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. - */ -ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); - -/** - * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. - */ -ZENOHC_API -struct z_owned_config_t zc_config_from_file(const char *path); - -/** - * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. - * - * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). - */ -ZENOHC_API -struct z_owned_config_t zc_config_from_str(const char *s); - -/** - * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. - * Use `z_drop` to safely deallocate this string - */ -ZENOHC_API -z_owned_str_t zc_config_get(struct z_config_t config, - const char *key); - -/** - * Inserts a JSON-serialized `value` at the `key` position of the configuration. - * - * Returns 0 if successful, a negative value otherwise. - */ -ZENOHC_API -int8_t zc_config_insert_json(struct z_config_t config, - const char *key, - const char *value); - -/** - * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. - */ -ZENOHC_API -z_owned_str_t zc_config_to_string(struct z_config_t config); - /** * Initialises the zenoh runtime logger. * @@ -457,37 +123,9 @@ z_owned_str_t zc_config_to_string(struct z_config_t config); */ ZENOHC_API void zc_init_logger(void); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API struct z_keyexpr_t zc_keyexpr_from_slice(const char *name, size_t len); - -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - * The string is canonized in-place before being passed to keyexpr. - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -struct z_keyexpr_t zc_keyexpr_from_slice_autocanonize(char *name, - size_t *len); - -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions: - * - `name` MUST be valid UTF8. - * - `name` MUST follow the Key Expression specification, ie: - * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. - * - any instance of ``**`` may only be lead or followed by ``/``. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -struct z_keyexpr_t zc_keyexpr_from_slice_unchecked(const char *start, - size_t len); - /** * Increments the session's reference count, returning a new owning handle. */ -ZENOHC_API struct z_owned_session_t zc_session_rcinc(struct z_session_t session); +ZENOHC_API +int8_t zc_session_rcinc(struct z_owned_session_t *dst, + const struct z_owned_session_t *src); diff --git a/src/lib.rs b/src/lib.rs index 705c08b6e..df56e8ead 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,16 +21,17 @@ use std::slice; #[macro_use] mod transmute; -mod opaque_types; +pub mod opaque_types; +pub use crate::opaque_types::*; pub use crate::collections::*; -mod config; +// mod config; // pub use crate::config::*; // mod commons; // pub use crate::commons::*; // mod payload; // pub use crate::payload::*; -mod keyexpr; +// mod keyexpr; // pub use crate::keyexpr::*; // mod info; // pub use crate::info::*; diff --git a/src/session.rs b/src/session.rs index b369530cf..7f758d330 100644 --- a/src/session.rs +++ b/src/session.rs @@ -13,13 +13,13 @@ // use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef}; -use crate::{config::*, impl_guarded_transmute, zc_init_logger}; +use crate::{config::*, z_owned_config_t, zc_init_logger}; use std::mem::MaybeUninit; use std::ops::Deref; use std::sync::{Arc, Weak}; +use zenoh::core::ErrNo; use zenoh::prelude::sync::SyncResolve; use zenoh::session::Session; -use zenoh_util::core::zresult::ErrNo; /// An owned zenoh session. /// @@ -64,23 +64,31 @@ pub extern "C" fn z_session_null(s: *mut MaybeUninit) { /// Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_open(config: &mut z_owned_config_t) -> z_owned_session_t { +pub extern "C" fn z_open( + this: *mut MaybeUninit, + config: &mut z_owned_config_t, +) -> i8 { + let this = z_owned_session_t::transmute_uninit_ptr(this); if cfg!(feature = "logger-autoinit") { zc_init_logger(); } - let config = match config.as_mut().take() { Some(c) => c, None => { log::error!("Config not provided"); - return z_owned_session_t::null(); + Inplace::empty(this); + return -1; } }; match zenoh::open(*config).res() { - Ok(s) => z_owned_session_t::new(Arc::new(s)), + Ok(s) => { + Inplace::init(this, Some(Arc::new(s))); + 0 + } Err(e) => { log::error!("Error opening session: {}", e); - z_owned_session_t::null() + Inplace::empty(this); + -1 } } } @@ -89,7 +97,7 @@ pub extern "C" fn z_open(config: &mut z_owned_config_t) -> z_owned_session_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_session_check(session: &z_owned_session_t) -> bool { - session.as_ref().is_some() + session.transmute_ref().is_some() } /// Closes a zenoh session. This drops and invalidates `session` for double-drop safety. @@ -99,6 +107,7 @@ pub extern "C" fn z_session_check(session: &z_owned_session_t) -> bool { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_close(session: &mut z_owned_session_t) -> i8 { + let session = session.transmute_mut(); let Some(s) = session.take() else { return 0; }; @@ -117,6 +126,15 @@ pub extern "C" fn z_close(session: &mut z_owned_session_t) -> i8 { /// Increments the session's reference count, returning a new owning handle. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn zc_session_rcinc(session: z_session_t) -> z_owned_session_t { - session.as_ref().as_ref().and_then(|s| s.upgrade()).into() +pub extern "C" fn zc_session_rcinc( + dst: *mut MaybeUninit, + src: &z_owned_session_t, +) -> i8 { + // session.as_ref().as_ref().and_then(|s| s.upgrade()).into() + let dst = z_owned_session_t::transmute_uninit_ptr(dst); + let Some(src) = src.transmute_ref() else { + return -1; + }; + Inplace::init(dst, Some(src.clone())); + 0 } From 3e541d9017ac7e4e8730e77a38b36a5a9931c19a Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Sun, 14 Apr 2024 22:05:26 +0200 Subject: [PATCH 50/75] payload compiles --- build-resources/opaque-types/src/lib.rs | 4 +- include/zenoh-gen.h | 356 +++++++++++++++++++++--- src/commons.rs | 1 - src/config.rs | 52 ++-- src/lib.rs | 12 +- src/payload.rs | 176 +++++------- src/transmute.rs | 18 ++ 7 files changed, 436 insertions(+), 183 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index bdbc6eeb9..66a5fc44e 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -46,6 +46,7 @@ macro_rules! get_opaque_type_data { /// /// To minimize copies and reallocations, Zenoh may provide you data in split buffers. get_opaque_type_data!(Option, "z_owned_buffer_t"); +get_opaque_type_data!(&'static ZBuf, "z_buffer_t"); /// An owned sample. /// @@ -56,7 +57,8 @@ get_opaque_type_data!(Option, "zc_owned_sample_t"); get_opaque_type_data!(&'static Sample, "z_sample_t"); /// A reader for payload data. -get_opaque_type_data!(ZBufReader, "zc_payload_reader"); +get_opaque_type_data!(Option>, "zc_owned_payload_reader"); +get_opaque_type_data!(&'static ZBufReader, "zc_payload_reader"); get_opaque_type_data!(&'static Encoding, "z_encoding_t"); get_opaque_type_data!(Encoding, "z_owned_encoding_t"); diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index fdaac4c70..41fca39e9 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -5,10 +5,34 @@ #include -typedef struct z_owned_bytes_t { - uint8_t *start; - size_t len; -} z_owned_bytes_t; +typedef enum z_sample_kind_t { + Z_SAMPLE_KIND_T_PUT = 0, + Z_SAMPLE_KIND_T_DELETE = 1, +} z_sample_kind_t; + +typedef enum zcu_locality_t { + ZCU_LOCALITY_T_ANY = 0, + ZCU_LOCALITY_T_SESSION_LOCAL = 1, + ZCU_LOCALITY_T_REMOTE = 2, +} zcu_locality_t; + +typedef enum zcu_reply_keyexpr_t { + ZCU_REPLY_KEYEXPR_T_ANY = 0, + ZCU_REPLY_KEYEXPR_T_MATCHING_QUERY = 1, +} zcu_reply_keyexpr_t; + +/** + * A split buffer that owns all of its data. + * + * To minimize copies and reallocations, Zenoh may provide you data in split buffers. + */ +typedef struct ALIGN(8) z_owned_buffer_t { + uint8_t _0[40]; +} z_owned_buffer_t; + +typedef struct ALIGN(8) z_buffer_t { + uint8_t _0[8]; +} z_buffer_t; /** * A contiguous view of bytes owned by some other entity. @@ -21,17 +45,116 @@ typedef struct z_bytes_t { size_t len; } z_bytes_t; -typedef struct ALIGN(8) z_owned_session_t { +typedef struct z_owned_bytes_t { + uint8_t *start; + size_t len; +} z_owned_bytes_t; + +typedef struct ALIGN(8) z_owned_encoding_t { + uint8_t _0[48]; +} z_owned_encoding_t; + +typedef struct ALIGN(8) z_encoding_t { uint8_t _0[8]; -} z_owned_session_t; +} z_encoding_t; -typedef struct ALIGN(8) z_owned_config_t { +typedef struct ALIGN(8) z_sample_t { uint8_t _0[8]; -} z_owned_config_t; +} z_sample_t; + +typedef struct ALIGN(8) z_keyexpr_t { + uint8_t _0[8]; +} z_keyexpr_t; + +/** + * An owned payload, backed by a reference counted owner. + * + * The `payload` field may be modified, and Zenoh will take the new values into account. + */ +typedef struct z_owned_buffer_t zc_owned_payload_t; + +typedef struct z_buffer_t zc_payload_t; + +typedef struct z_timestamp_t { + uint64_t time; + z_id_t id; +} z_timestamp_t; + +/** + * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` + * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with + * `z_check` and `z_str_check` correspondently + */ +typedef struct z_owned_str_t { + char *_cstr; +} z_owned_str_t; + +/** + * A reader for payload data. + */ +typedef struct ALIGN(8) zc_owned_payload_reader { + uint8_t _0[24]; +} zc_owned_payload_reader; -typedef struct ALIGN(8) z_session_t { +typedef struct ALIGN(8) zc_payload_reader { uint8_t _0[8]; -} z_session_t; +} zc_payload_reader; + +/** + * An owned sample. + * + * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + */ +typedef struct ALIGN(8) zc_owned_sample_t { + uint8_t _0[240]; +} zc_owned_sample_t; + +/** + * Returns `true` if the buffer is in a valid state. + */ +ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); + +/** + * Increments the buffer's reference count, returning an owned version of the buffer. + */ +ZENOHC_API void z_buffer_clone(struct z_owned_buffer_t *dst, const struct z_owned_buffer_t *buffer); + +/** + * Decrements the buffer's reference counter, destroying it if applicable. + * + * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. + */ +ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); + +/** + * Returns total number bytes in the buffer. + */ +ZENOHC_API size_t z_buffer_len(struct z_buffer_t buffer); + +/** + * Loans the buffer, allowing you to call functions that only need a loan of it. + */ +ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); + +/** + * The gravestone value for `z_owned_buffer_t`. + */ +ZENOHC_API void z_buffer_null(struct z_owned_buffer_t *this_); + +/** + * Returns the `index`th slice of the buffer, aliasing it. + * + * Out of bounds accesses will return `z_bytes_empty`. + */ +ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); + +/** + * Returns the number of slices in the buffer. + * + * If the return value is 0 or 1, then the buffer's data is contiguous in memory. + */ +ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); /** * Returns ``true`` if `b` is initialized. @@ -78,42 +201,105 @@ ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); /** - * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * Returns ``true`` if `encoding` is valid. + */ +ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); + +/** + * Constructs a default :c:type:`z_encoding_t`. + */ +ZENOHC_API struct z_encoding_t z_encoding_default(void); + +/** + * Frees `encoding`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); + +/** + * Constructs a specific :c:type:`z_encoding_t`. + */ +ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); + +/** + * Returns a :c:type:`z_encoding_t` loaned from `encoding`. + */ +ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); + +/** + * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type + */ +ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); + +/** + * The qos with which the sample was received. + * TODO: split to methods (priority, congestion_control, express) + * The sample's attachment. * - * Returns a negative value if an error occured while closing the session. - * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + * `sample` is aliased by the return value. */ -ZENOHC_API int8_t z_close(struct z_owned_session_t *session); +ZENOHC_API z_attachment_t z_sample_attachment(const struct z_sample_t *sample); /** - * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + * The encoding of the payload. */ -ZENOHC_API -int8_t z_open(struct z_owned_session_t *this_, - struct z_owned_config_t *config); +ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); /** - * Returns ``true`` if `session` is valid. + * The Key Expression of the sample. + * + * `sample` is aliased by its return value. */ -ZENOHC_API bool z_session_check(const struct z_owned_session_t *session); +ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); /** - * Returns a :c:type:`z_session_t` loaned from `s`. + * The sample's kind (put or delete). + */ +ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); + +/** + * Returns the sample's payload after incrementing its internal reference count. * - * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. + * Note that other samples may have received the same buffer, meaning that mutating this buffer may + * affect the samples received by other subscribers. + */ +ZENOHC_API zc_owned_payload_t z_sample_owned_payload(const struct z_sample_t *sample); + +/** + * The sample's data, the return value aliases the sample. * - * # Safety - * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, - * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) - * have been destroyed is UB (likely SEGFAULT) + * If you need ownership of the buffer, you may use `z_sample_owned_payload`. */ -ZENOHC_API -struct z_session_t z_session_loan(const struct z_owned_session_t *s); +ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); /** - * Constructs a null safe-to-drop value of 'z_owned_session_t' type + * The samples timestamp */ -ZENOHC_API void z_session_null(struct z_owned_session_t *s); +ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); + +/** + * Returns ``true`` if `s` is a valid string + */ +ZENOHC_API bool z_str_check(const struct z_owned_str_t *s); + +/** + * Frees `z_owned_str_t`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_str_drop(struct z_owned_str_t *s); + +/** + * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. + */ +ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); + +/** + * Returns undefined `z_owned_str_t` + */ +ZENOHC_API struct z_owned_str_t z_str_null(void); + +/** + * Returns ``true`` if `ts` is a valid timestamp + */ +ZENOHC_API bool z_timestamp_check(struct z_timestamp_t ts); /** * Initialises the zenoh runtime logger. @@ -124,8 +310,112 @@ ZENOHC_API void z_session_null(struct z_owned_session_t *s); ZENOHC_API void zc_init_logger(void); /** - * Increments the session's reference count, returning a new owning handle. + * Returns `false` if `payload` is the gravestone value. + */ +ZENOHC_API bool zc_payload_check(const zc_owned_payload_t *payload); + +/** + * Increments internal payload reference count, returning owned payload. + */ +ZENOHC_API void zc_payload_clone(zc_owned_payload_t *dst, const zc_owned_payload_t *payload); + +/** + * Decodes payload into null-terminated string + */ +ZENOHC_API int8_t zc_payload_decode_into_bytes(zc_payload_t payload, struct z_owned_bytes_t *b); + +/** + * Decodes payload into null-terminated string + */ +ZENOHC_API int8_t zc_payload_decode_into_string(zc_payload_t payload, struct z_owned_str_t *cstr); + +/** + * Decrements `payload`'s backing refcount, releasing the memory if appropriate. + */ +ZENOHC_API void zc_payload_drop(zc_owned_payload_t *payload); + +/** + * Encodes byte sequence by aliasing. + */ +ZENOHC_API void zc_payload_encode_from_bytes(zc_owned_payload_t *dst, struct z_bytes_t bytes); + +/** + * Encodes a null-terminated string by aliasing. + */ +ZENOHC_API void zc_payload_encode_from_string(zc_owned_payload_t *dst, const char *cstr); + +/** + * Returns total number bytes in the payload. + */ +ZENOHC_API size_t zc_payload_len(zc_payload_t payload); + +/** + * Returns a :c:type:`zc_payload_t` loaned from `payload`. + */ +ZENOHC_API zc_payload_t zc_payload_loan(const zc_owned_payload_t *payload); + +/** + * Constructs `zc_owned_payload_t`'s gravestone value. + */ +ZENOHC_API void zc_payload_null(zc_owned_payload_t *this_); + +/** + * Clones the `payload` by incrementing its reference counter. + */ +ZENOHC_API void zc_payload_rcinc(zc_owned_payload_t *dst, const zc_owned_payload_t *payload); + +/** + * Creates a reader for the specified `payload`. + * + * Returns 0 in case of success, -1 if `payload` is not valid. + */ +ZENOHC_API void zc_payload_reader_init(struct zc_owned_payload_reader *this_, zc_payload_t payload); + +/** + * Reads data into specified destination. + * + * Will read at most `len` bytes. + * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. */ ZENOHC_API -int8_t zc_session_rcinc(struct z_owned_session_t *dst, - const struct z_owned_session_t *src); +size_t zc_payload_reader_read(struct zc_payload_reader reader, + uint8_t *dest, + size_t len); + +/** + * Returns number of the remaining bytes in the payload + * + */ +ZENOHC_API size_t zc_payload_reader_remaining(struct zc_payload_reader reader); + +/** + * Returns `true` if `sample` is valid. + * + * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed + * unless the value has been dropped already. + */ +ZENOHC_API +bool zc_sample_check(const struct zc_owned_sample_t *sample); + +/** + * Clone a sample in the cheapest way available. + */ +ZENOHC_API void zc_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); + +/** + * Destroy the sample. + */ +ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); + +/** + * Borrow the sample, allowing calling its accessor methods. + * + * Calling this function using a dropped sample is undefined behaviour. + */ +ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); + +ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); + +ZENOHC_API enum zcu_locality_t zcu_locality_default(void); + +ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); diff --git a/src/commons.rs b/src/commons.rs index 902a2361f..72739ebbd 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -17,7 +17,6 @@ use std::mem::MaybeUninit; use std::ops::Deref; use std::str::FromStr; -use crate::keyexpr::*; use crate::opaque_types::z_owned_buffer_t; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; diff --git a/src/config.rs b/src/config.rs index 80e3a38f1..70f4ba776 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,8 +13,10 @@ // use libc::{c_char, c_uint}; use std::ffi::CStr; +use std::mem::MaybeUninit; use zenoh::config::{Config, ValidatedMap, WhatAmI}; +use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef}; use crate::{impl_guarded_transmute, z_owned_str_t, z_str_null}; #[no_mangle] @@ -58,9 +60,8 @@ pub static Z_CONFIG_ADD_TIMESTAMP_KEY: &c_char = unsafe { &*(b"timestamping/enabled\0".as_ptr() as *const c_char) }; /// A loaned zenoh configuration. -#[repr(C)] -#[allow(non_camel_case_types)] -pub struct z_config_t(*const z_owned_config_t); +pub use crate::opaque_types::z_config_t; +decl_transmute_copy!(&'static Config, z_config_t); /// An owned zenoh configuration. /// @@ -72,39 +73,16 @@ pub struct z_config_t(*const z_owned_config_t); /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[repr(C)] -pub struct z_owned_config_t(*mut ()); -impl_guarded_transmute!(Option>, z_owned_config_t); +pub use crate::opaque_types::z_owned_config_t; +decl_transmute_owned!(Option>, z_owned_config_t); /// Returns a :c:type:`z_config_t` loaned from `s`. #[no_mangle] pub extern "C" fn z_config_loan(s: &z_owned_config_t) -> z_config_t { - z_config_t(s) -} -impl AsRef>> for z_config_t { - fn as_ref(&self) -> &Option> { - unsafe { (*self.0).as_ref() } - } -} -impl AsMut>> for z_config_t { - fn as_mut(&mut self) -> &mut Option> { - unsafe { (*(self.0 as *mut z_owned_config_t)).as_mut() } - } -} -impl AsRef>> for z_owned_config_t { - fn as_ref(&self) -> &Option> { - unsafe { std::mem::transmute(self) } - } -} -impl AsMut>> for z_owned_config_t { - fn as_mut(&mut self) -> &mut Option> { - unsafe { std::mem::transmute(self) } - } -} -impl z_owned_config_t { - pub fn null() -> Self { - None.into() - } + let s = s.transmute_ref(); + let s = unwrap_ref_unchecked(s); + let s = s.as_ref(); + s.transmute_copy() } /// Return a new, zenoh-allocated, empty configuration. @@ -118,15 +96,17 @@ impl z_owned_config_t { /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. #[no_mangle] -pub extern "C" fn z_config_new() -> z_owned_config_t { +pub extern "C" fn z_config_new(this: *mut MaybeUninit) { + let this = z_owned_config_t::transmute_uninit_ptr(this); let config: Box = Box::default(); - unsafe { z_owned_config_t(std::mem::transmute(Some(config))) } + Inplace::init(this, Some(config)); } /// Constructs a null safe-to-drop value of 'z_owned_config_t' type #[no_mangle] -pub extern "C" fn z_config_null() -> z_owned_config_t { - z_owned_config_t::null() +pub extern "C" fn z_config_null(this: *mut MaybeUninit) { + let this = z_owned_config_t::transmute_uninit_ptr(this); + Inplace::empty(this); } /// Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. diff --git a/src/lib.rs b/src/lib.rs index df56e8ead..113d5182d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,6 @@ #![allow(non_camel_case_types)] -mod collections; use libc::c_void; use std::cmp::min; use std::slice; @@ -24,13 +23,14 @@ mod transmute; pub mod opaque_types; pub use crate::opaque_types::*; +mod collections; pub use crate::collections::*; // mod config; // pub use crate::config::*; -// mod commons; -// pub use crate::commons::*; -// mod payload; -// pub use crate::payload::*; +mod commons; +pub use crate::commons::*; +mod payload; +pub use crate::payload::*; // mod keyexpr; // pub use crate::keyexpr::*; // mod info; @@ -43,7 +43,7 @@ pub use crate::collections::*; // pub use crate::put::*; // mod scouting; // pub use crate::scouting::*; -mod session; +// mod session; // pub use crate::session::*; // mod subscriber; // pub use crate::subscriber::*; diff --git a/src/payload.rs b/src/payload.rs index b77b46dd7..6e723e329 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,36 +1,24 @@ +use crate::transmute::{ + unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef, TransmuteUninitPtr, +}; +use crate::{z_bytes_empty, z_bytes_t, z_owned_bytes_t, z_owned_str_t}; use core::slice; +use std::any::Any; use std::mem::MaybeUninit; use std::slice::from_raw_parts_mut; -use std::{any::Any, ops::Deref, ptr::NonNull}; - use zenoh::buffers::HasReader; use zenoh::buffers::Reader; use zenoh::buffers::ZBufReader; use zenoh::buffers::{SplitBuffer, ZBuf, ZSliceBuffer}; -use crate::{ - impl_guarded_transmute, z_bytes_empty, z_bytes_null, z_bytes_t, z_owned_bytes_t, z_owned_str_t, - z_str_null, GuardedTransmute, -}; - pub use crate::opaque_types::z_owned_buffer_t; -impl_guarded_transmute!(Option, z_owned_buffer_t); - -impl Default for z_owned_buffer_t { - fn default() -> Self { - z_buffer_null() - } -} -impl From for z_owned_buffer_t { - fn from(value: ZBuf) -> Self { - Some(value).transmute() - } -} +decl_transmute_owned!(Option, z_owned_buffer_t); /// The gravestone value for `z_owned_buffer_t`. #[no_mangle] -extern "C" fn z_buffer_null() -> z_owned_buffer_t { - None::.transmute() +extern "C" fn z_buffer_null(this: *mut MaybeUninit) { + let this = z_owned_buffer_t::transmute_uninit_ptr(this); + Inplace::empty(this); } /// Decrements the buffer's reference counter, destroying it if applicable. @@ -38,52 +26,37 @@ extern "C" fn z_buffer_null() -> z_owned_buffer_t { /// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. #[no_mangle] extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { - core::mem::drop(buffer.take()) + let buffer = buffer.transmute_mut(); + Inplace::drop(buffer); } /// Returns `true` if the buffer is in a valid state. #[no_mangle] extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { - buffer.is_some() + buffer.transmute_ref().is_some() } /// Loans the buffer, allowing you to call functions that only need a loan of it. #[no_mangle] extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { - buffer.as_ref().into() + let buffer = buffer.transmute_ref(); + let buffer = unwrap_ref_unchecked(buffer); + buffer.transmute_copy() } /// A loan of a `z_owned_buffer_t`. /// /// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. -#[repr(C)] -#[derive(Clone, Copy, Default)] -pub struct z_buffer_t { - _inner: Option>, -} - -impl_guarded_transmute!(noderefs Option<&ZBuf>, z_buffer_t); -impl_guarded_transmute!(noderefs z_buffer_t, Option<&'static ZBuf>); - -impl From> for z_buffer_t { - fn from(value: Option<&ZBuf>) -> Self { - value.transmute() - } -} - -impl From for Option<&'static ZBuf> { - fn from(value: z_buffer_t) -> Self { - value.transmute() - } -} +pub use crate::opaque_types::z_buffer_t; +decl_transmute_copy!(&'static ZBuf, z_buffer_t); /// Increments the buffer's reference count, returning an owned version of the buffer. #[no_mangle] -extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { - match buffer._inner { - Some(b) => unsafe { b.as_ref().deref().clone().transmute() }, - None => ZBuf::empty().into(), - } +extern "C" fn z_buffer_clone(dst: *mut MaybeUninit, buffer: &z_owned_buffer_t) { + let dst = dst.transmute_uninit_ptr(); + let buffer = buffer.transmute_ref(); + let buffer = buffer.as_ref().map(Clone::clone); + Inplace::init(dst, buffer); } /// Returns the number of slices in the buffer. @@ -91,19 +64,13 @@ extern "C" fn z_buffer_clone(buffer: z_buffer_t) -> z_owned_buffer_t { /// If the return value is 0 or 1, then the buffer's data is contiguous in memory. #[no_mangle] extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { - match buffer.into() { - None => 0, - Some(buf) => ZBuf::slices(buf).len(), - } + ZBuf::slices(buffer.transmute_copy()).len() } /// Returns total number bytes in the buffer. #[no_mangle] extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { - match buffer.into() { - None => 0, - Some(buf) => ZBuf::slices(buf).fold(0, |acc, s| acc + s.len()), - } + ZBuf::slices(buffer.transmute_copy()).fold(0, |acc, s| acc + s.len()) } /// Returns the `index`th slice of the buffer, aliasing it. @@ -111,12 +78,10 @@ extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { /// Out of bounds accesses will return `z_bytes_empty`. #[no_mangle] extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { - match buffer.into() { - None => z_bytes_empty(), - Some(buf) => ZBuf::slices(buf) - .nth(index) - .map_or(z_bytes_empty(), |slice| slice.into()), - } + let buf = buffer.transmute_copy(); + ZBuf::slices(buf) + .nth(index) + .map_or(z_bytes_empty(), |slice| slice.into()) } /// An owned payload, backed by a reference counted owner. @@ -127,8 +92,11 @@ pub type zc_owned_payload_t = z_owned_buffer_t; /// Clones the `payload` by incrementing its reference counter. #[no_mangle] -pub extern "C" fn zc_payload_rcinc(payload: &zc_owned_payload_t) -> zc_owned_payload_t { - z_buffer_clone(z_buffer_loan(payload)) +pub extern "C" fn zc_payload_rcinc( + dst: *mut MaybeUninit, + payload: &zc_owned_payload_t, +) { + z_buffer_clone(dst, payload) } /// Returns `false` if `payload` is the gravestone value. #[no_mangle] @@ -142,8 +110,8 @@ pub extern "C" fn zc_payload_drop(payload: &mut zc_owned_payload_t) { } /// Constructs `zc_owned_payload_t`'s gravestone value. #[no_mangle] -pub extern "C" fn zc_payload_null() -> zc_owned_payload_t { - z_buffer_null() +pub extern "C" fn zc_payload_null(this: *mut MaybeUninit) { + z_buffer_null(this); } /// Returns a :c:type:`zc_payload_t` loaned from `payload`. @@ -157,8 +125,11 @@ pub type zc_payload_t = z_buffer_t; /// Increments internal payload reference count, returning owned payload. #[no_mangle] -pub extern "C" fn zc_payload_clone(payload: zc_payload_t) -> zc_owned_payload_t { - z_buffer_clone(payload) +pub extern "C" fn zc_payload_clone( + dst: *mut MaybeUninit, + payload: &zc_owned_payload_t, +) { + z_buffer_clone(dst, payload) } /// Decodes payload into null-terminated string @@ -168,14 +139,8 @@ pub unsafe extern "C" fn zc_payload_decode_into_string( payload: zc_payload_t, cstr: &mut z_owned_str_t, ) -> i8 { - let payload: Option<&ZBuf> = payload.into(); - if payload.is_none() { - *cstr = z_str_null(); - return 0; - } - *cstr = z_owned_str_t::preallocate(zc_payload_len(payload.into())); - let payload = payload.unwrap(); - + *cstr = z_owned_str_t::preallocate(zc_payload_len(payload)); + let payload = payload.transmute_copy(); let mut pos = 0; for s in payload.slices() { cstr.insert_unchecked(pos, s); @@ -191,14 +156,8 @@ pub unsafe extern "C" fn zc_payload_decode_into_bytes( payload: zc_payload_t, b: &mut z_owned_bytes_t, ) -> i8 { - let payload: Option<&ZBuf> = payload.into(); - if payload.is_none() { - *b = z_bytes_null(); - return 0; - } - *b = z_owned_bytes_t::preallocate(zc_payload_len(payload.into())); - let payload = payload.unwrap(); - + *b = z_owned_bytes_t::preallocate(zc_payload_len(payload)); + let payload = payload.transmute_copy(); let mut pos = 0; for s in payload.slices() { b.insert_unchecked(pos, s); @@ -225,21 +184,27 @@ impl ZSliceBuffer for z_bytes_t { /// Encodes byte sequence by aliasing. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_encode_from_bytes(bytes: z_bytes_t) -> zc_owned_payload_t { - ZBuf::from(bytes).into() +pub unsafe extern "C" fn zc_payload_encode_from_bytes( + dst: *mut MaybeUninit, + bytes: z_bytes_t, +) { + let dst = dst.transmute_uninit_ptr(); + let buf = ZBuf::from(bytes); + Inplace::init(dst, Some(buf)); } /// Encodes a null-terminated string by aliasing. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_payload_encode_from_string( + dst: *mut MaybeUninit, cstr: *const libc::c_char, -) -> zc_owned_payload_t { +) { let bytes = z_bytes_t { start: cstr as *const u8, len: libc::strlen(cstr), }; - zc_payload_encode_from_bytes(bytes) + zc_payload_encode_from_bytes(dst, bytes); } /// Returns total number bytes in the payload. @@ -248,8 +213,11 @@ pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { z_buffer_len(payload) } +pub use crate::opaque_types::zc_owned_payload_reader; +decl_transmute_owned!(Option>, zc_owned_payload_reader); + pub use crate::opaque_types::zc_payload_reader; -decl_transmute_copy!(ZBufReader<'static>, zc_payload_reader); +decl_transmute_copy!(&'static ZBufReader<'static>, zc_payload_reader); /// Creates a reader for the specified `payload`. /// @@ -257,14 +225,13 @@ decl_transmute_copy!(ZBufReader<'static>, zc_payload_reader); #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_payload_reader_init( + this: *mut MaybeUninit, payload: zc_payload_t, - reader: *mut MaybeUninit, -) -> i8 { - if payload._inner.is_none() { - return -1; - } - *reader = payload.transmute().unwrap().reader().transmute(); - 0 +) { + let this = this.transmute_uninit_ptr(); + let payload = payload.transmute_copy(); + let reader = payload.reader(); + Inplace::init(this, Some(reader)); } /// Reads data into specified destination. @@ -274,23 +241,20 @@ pub unsafe extern "C" fn zc_payload_reader_init( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_payload_reader_read( - reader: *mut zc_payload_reader, + reader: zc_payload_reader, dest: *mut u8, len: usize, ) -> usize { + let reader = reader.transmute_copy(); let buf = unsafe { from_raw_parts_mut(dest, len) }; - reader - .as_mut() - .unwrap() - .read(buf) - .map(|n| n.get()) - .unwrap_or(0) + reader.read(buf).map(|n| n.get()).unwrap_or(0) } /// Returns number of the remaining bytes in the payload /// #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_reader_remaining(reader: *const zc_payload_reader) -> usize { - reader.as_ref().unwrap().remaining() +pub unsafe extern "C" fn zc_payload_reader_remaining(reader: zc_payload_reader) -> usize { + let reader = reader.transmute_copy(); + reader.remaining() } diff --git a/src/transmute.rs b/src/transmute.rs index ddc38824a..6a62a2b66 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -35,6 +35,10 @@ pub(crate) trait TransmuteCopy { fn transmute_copy(self) -> T; } +pub(crate) trait TransmuteUninitPtr: Sized { + fn transmute_uninit_ptr(self) -> *mut std::mem::MaybeUninit; +} + pub(crate) trait Inplace: Sized { // Initialize the object in place with a memcpy of the provided value. Assumes that the memory passed to the function is uninitialized fn init(this: *mut std::mem::MaybeUninit, value: Self) { @@ -110,6 +114,8 @@ macro_rules! decl_transmute_owned { validate_equivalence!($zenoh_type, $c_type); impl_transmute_ref!($zenoh_type, $c_type); impl_transmute_ref!($c_type, $zenoh_type); + impl_transmute_uninit_ptr!($zenoh_type, $c_type); + impl_transmute_uninit_ptr!($c_type, $zenoh_type); } } @@ -119,6 +125,8 @@ macro_rules! decl_transmute_copy { validate_equivalence!($zenoh_type, $c_type); impl_transmute_copy!($zenoh_type, $c_type); impl_transmute_copy!($c_type, $zenoh_type); + impl_transmute_uninit_ptr!($zenoh_type, $c_type); + impl_transmute_uninit_ptr!($c_type, $zenoh_type); }; } @@ -144,3 +152,13 @@ macro_rules! impl_transmute_copy { } }; } + +macro_rules! impl_transmute_uninit_ptr { + ($src_type:ty, $dst_type:ty) => { + impl $crate::transmute::TransmuteUninitPtr<$dst_type> for *mut MaybeUninit<$src_type> { + fn transmute_uninit_ptr(self) -> *mut std::mem::MaybeUninit<$dst_type> { + self as *mut std::mem::MaybeUninit<$dst_type> + } + } + }; +} From 34bf5627a4537b0de306779a9fe5bfcb76e64524 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 15 Apr 2024 00:02:53 +0200 Subject: [PATCH 51/75] calling transmute_unitini_ptr as method --- src/commons.rs | 8 ++++---- src/payload.rs | 2 +- src/transmute.rs | 5 ----- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/commons.rs b/src/commons.rs index 72739ebbd..5bc998d49 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -183,7 +183,7 @@ decl_transmute_owned!(default_inplace_init Option, zc_owned_sample_t); pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { let src = src.transmute_copy(); let src = src.deref().clone(); - let dst = zc_owned_sample_t::transmute_uninit_ptr(dst); + let dst = dst.transmute_uninit_ptr(); Inplace::init(dst, Some(src)); } @@ -213,7 +213,7 @@ pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { #[no_mangle] pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { - Inplace::empty(zc_owned_sample_t::transmute_uninit_ptr(sample)); + Inplace::empty(sample.transmute_uninit_ptr()); } /// The encoding of a payload, in a MIME-like format. @@ -236,7 +236,7 @@ decl_transmute_owned!(default_inplace_init Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit) { - Inplace::empty(z_owned_encoding_t::transmute_uninit_ptr(encoding)); + Inplace::empty(encoding.transmute_uninit_ptr()); } /// Constructs a specific :c:type:`z_encoding_t`. @@ -246,7 +246,7 @@ pub unsafe extern "C" fn z_encoding_from_str( encoding: *mut MaybeUninit, s: *const c_char, ) -> i8 { - let encoding = z_owned_encoding_t::transmute_uninit_ptr(encoding); + let encoding = encoding.transmute_uninit_ptr(); if s.is_null() { Inplace::empty(encoding); 0 diff --git a/src/payload.rs b/src/payload.rs index 6e723e329..8959e8ac2 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -17,7 +17,7 @@ decl_transmute_owned!(Option, z_owned_buffer_t); /// The gravestone value for `z_owned_buffer_t`. #[no_mangle] extern "C" fn z_buffer_null(this: *mut MaybeUninit) { - let this = z_owned_buffer_t::transmute_uninit_ptr(this); + let this = this.transmute_uninit_ptr(); Inplace::empty(this); } diff --git a/src/transmute.rs b/src/transmute.rs index 6a62a2b66..3fe026532 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -24,11 +24,6 @@ pub fn unwrap_ref_unchecked(value: &Option) -> &T { pub(crate) trait TransmuteRef: Sized { fn transmute_ref(&self) -> &T; fn transmute_mut(&mut self) -> &mut T; - fn transmute_uninit_ptr( - this: *mut std::mem::MaybeUninit, - ) -> *mut std::mem::MaybeUninit { - this as *mut std::mem::MaybeUninit - } } pub(crate) trait TransmuteCopy { From fb8fa048338928c2cd844d93009b48856dd7dde3 Mon Sep 17 00:00:00 2001 From: Michael Ilyin Date: Mon, 15 Apr 2024 15:53:59 +0200 Subject: [PATCH 52/75] config partially updated --- build-resources/opaque-types/src/lib.rs | 3 + include/zenoh-gen.h | 184 +++++++++++++++++++++++- src/config.rs | 28 ++-- src/info.rs | 7 +- src/lib.rs | 8 +- 5 files changed, 206 insertions(+), 24 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 66a5fc44e..d2ad923ac 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use zenoh::buffers::{ZBuf, ZBufReader}; use zenoh::config::Config; +use zenoh::config::ZenohId; use zenoh::encoding::Encoding; use zenoh::key_expr::KeyExpr; use zenoh::query::Reply; @@ -91,3 +92,5 @@ get_opaque_type_data!(&'static Session, "z_session_t"); get_opaque_type_data!(Option>, "z_owned_config_t"); get_opaque_type_data!(&'static Config, "z_config_t"); + +get_opaque_type_data!(ZenohId, "z_id_t"); diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index 41fca39e9..a97ed1ddc 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -50,6 +50,18 @@ typedef struct z_owned_bytes_t { size_t len; } z_owned_bytes_t; +typedef struct ALIGN(8) z_owned_session_t { + uint8_t _0[8]; +} z_owned_session_t; + +typedef struct ALIGN(8) z_owned_config_t { + uint8_t _0[8]; +} z_owned_config_t; + +typedef struct ALIGN(8) z_config_t { + uint8_t _0[8]; +} z_config_t; + typedef struct ALIGN(8) z_owned_encoding_t { uint8_t _0[48]; } z_owned_encoding_t; @@ -75,11 +87,19 @@ typedef struct z_owned_buffer_t zc_owned_payload_t; typedef struct z_buffer_t zc_payload_t; +typedef struct ALIGN(1) z_id_t { + uint8_t _0[16]; +} z_id_t; + typedef struct z_timestamp_t { uint64_t time; - z_id_t id; + struct z_id_t id; } z_timestamp_t; +typedef struct ALIGN(8) z_session_t { + uint8_t _0[8]; +} z_session_t; + /** * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with @@ -110,6 +130,34 @@ typedef struct ALIGN(8) zc_owned_sample_t { uint8_t _0[240]; } zc_owned_sample_t; +extern const unsigned int Z_ROUTER; + +extern const unsigned int Z_PEER; + +extern const unsigned int Z_CLIENT; + +extern const char *Z_CONFIG_MODE_KEY; + +extern const char *Z_CONFIG_CONNECT_KEY; + +extern const char *Z_CONFIG_LISTEN_KEY; + +extern const char *Z_CONFIG_USER_KEY; + +extern const char *Z_CONFIG_PASSWORD_KEY; + +extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; + +extern const char *Z_CONFIG_MULTICAST_INTERFACE_KEY; + +extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; + +extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; + +extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; + +extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; + /** * Returns `true` if the buffer is in a valid state. */ @@ -200,6 +248,65 @@ ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); */ ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); +/** + * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * + * Returns a negative value if an error occured while closing the session. + * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + */ +ZENOHC_API int8_t z_close(struct z_owned_session_t *session); + +/** + * Returns ``true`` if `config` is valid. + */ +ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); + +/** + * Constructs a default, zenoh-allocated, client mode configuration. + * If `peer` is not null, it is added to the configuration as remote peer. + */ +ZENOHC_API struct z_owned_config_t z_config_client(const char *const *peers, size_t n_peers); + +/** + * Creates a default, zenoh-allocated, configuration. + */ +ZENOHC_API struct z_owned_config_t z_config_default(void); + +/** + * Frees `config`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_config_drop(struct z_owned_config_t *config); + +/** + * Returns a :c:type:`z_config_t` loaned from `s`. + */ +ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); + +/** + * Return a new, zenoh-allocated, empty configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +ZENOHC_API +void z_config_new(struct z_owned_config_t *this_); + +/** + * Constructs a null safe-to-drop value of 'z_owned_config_t' type + */ +ZENOHC_API void z_config_null(struct z_owned_config_t *this_); + +/** + * Constructs a default, zenoh-allocated, peer mode configuration. + */ +ZENOHC_API struct z_owned_config_t z_config_peer(void); + /** * Returns ``true`` if `encoding` is valid. */ @@ -230,6 +337,13 @@ ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t * */ ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); +/** + * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + */ +ZENOHC_API +int8_t z_open(struct z_owned_session_t *this_, + struct z_owned_config_t *config); + /** * The qos with which the sample was received. * TODO: split to methods (priority, congestion_control, express) @@ -276,6 +390,29 @@ ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); */ ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); +/** + * Returns ``true`` if `session` is valid. + */ +ZENOHC_API bool z_session_check(const struct z_owned_session_t *session); + +/** + * Returns a :c:type:`z_session_t` loaned from `s`. + * + * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. + * + * # Safety + * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, + * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) + * have been destroyed is UB (likely SEGFAULT) + */ +ZENOHC_API +struct z_session_t z_session_loan(const struct z_owned_session_t *s); + +/** + * Constructs a null safe-to-drop value of 'z_owned_session_t' type + */ +ZENOHC_API void z_session_null(struct z_owned_session_t *s); + /** * Returns ``true`` if `s` is a valid string */ @@ -301,6 +438,44 @@ ZENOHC_API struct z_owned_str_t z_str_null(void); */ ZENOHC_API bool z_timestamp_check(struct z_timestamp_t ts); +/** + * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. + */ +ZENOHC_API +struct z_owned_config_t zc_config_from_file(const char *path); + +/** + * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. + * + * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). + */ +ZENOHC_API +struct z_owned_config_t zc_config_from_str(const char *s); + +/** + * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. + * Use `z_drop` to safely deallocate this string + */ +ZENOHC_API +struct z_owned_str_t zc_config_get(struct z_config_t config, + const char *key); + +/** + * Inserts a JSON-serialized `value` at the `key` position of the configuration. + * + * Returns 0 if successful, a negative value otherwise. + */ +ZENOHC_API +int8_t zc_config_insert_json(struct z_config_t config, + const char *key, + const char *value); + +/** + * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. + */ +ZENOHC_API +struct z_owned_str_t zc_config_to_string(struct z_config_t config); + /** * Initialises the zenoh runtime logger. * @@ -416,6 +591,13 @@ ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *samp ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); +/** + * Increments the session's reference count, returning a new owning handle. + */ +ZENOHC_API +int8_t zc_session_rcinc(struct z_owned_session_t *dst, + const struct z_owned_session_t *src); + ZENOHC_API enum zcu_locality_t zcu_locality_default(void); ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); diff --git a/src/config.rs b/src/config.rs index 70f4ba776..824a45e37 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,8 +16,10 @@ use std::ffi::CStr; use std::mem::MaybeUninit; use zenoh::config::{Config, ValidatedMap, WhatAmI}; -use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef}; -use crate::{impl_guarded_transmute, z_owned_str_t, z_str_null}; +use crate::transmute::{ + unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef, TransmuteUninitPtr, +}; +use crate::{z_owned_str_t, z_str_null}; #[no_mangle] pub static Z_ROUTER: c_uint = WhatAmI::Router as c_uint; @@ -97,7 +99,7 @@ pub extern "C" fn z_config_loan(s: &z_owned_config_t) -> z_config_t { /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. #[no_mangle] pub extern "C" fn z_config_new(this: *mut MaybeUninit) { - let this = z_owned_config_t::transmute_uninit_ptr(this); + let this = this.transmute_uninit_ptr(); let config: Box = Box::default(); Inplace::init(this, Some(config)); } @@ -105,7 +107,7 @@ pub extern "C" fn z_config_new(this: *mut MaybeUninit) { /// Constructs a null safe-to-drop value of 'z_owned_config_t' type #[no_mangle] pub extern "C" fn z_config_null(this: *mut MaybeUninit) { - let this = z_owned_config_t::transmute_uninit_ptr(this); + let this = this.transmute_uninit_ptr(); Inplace::empty(this); } @@ -114,12 +116,12 @@ pub extern "C" fn z_config_null(this: *mut MaybeUninit) { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char) -> z_owned_str_t { + let config = config.transmute_copy(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, Err(_) => return z_str_null(), }; - - let val = config.as_ref().as_ref().and_then(|c| c.get_json(key).ok()); + let val = config.get_json(key).ok(); match val { Some(val) => val.as_bytes().into(), None => z_str_null(), @@ -132,18 +134,14 @@ pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char) - #[no_mangle] #[allow(clippy::missing_safety_doc, unused_must_use)] pub unsafe extern "C" fn zc_config_insert_json( - mut config: z_config_t, + config: z_config_t, key: *const c_char, value: *const c_char, ) -> i8 { + let config = config.transmute_copy(); let key = CStr::from_ptr(key); let value = CStr::from_ptr(value); - match config - .as_mut() - .as_mut() - .expect("uninitialized config") - .insert_json5(&key.to_string_lossy(), &value.to_string_lossy()) - { + match config.insert_json5(&key.to_string_lossy(), &value.to_string_lossy()) { Ok(_) => 0, Err(_) => i8::MIN, } @@ -153,12 +151,14 @@ pub unsafe extern "C" fn zc_config_insert_json( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_config_drop(config: &mut z_owned_config_t) { - std::mem::drop(config.as_mut().take()) + let config = config.transmute_mut(); + Inplace::drop(config); } /// Returns ``true`` if `config` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_config_check(config: &z_owned_config_t) -> bool { + let config = config.transmute_ref(); config.as_ref().is_some() } diff --git a/src/info.rs b/src/info.rs index 2ee4d9384..b4e523d8a 100644 --- a/src/info.rs +++ b/src/info.rs @@ -19,11 +19,8 @@ use zenoh::session::SessionDeclarations; /// Represents a Zenoh ID. /// /// In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. -#[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct z_id_t { - pub id: [u8; 16], -} +pub use crate::opaque_types::z_id_t; +decl_transmute_copy!(ZenohId, z_id_t); /// Returns the local Zenoh ID. /// diff --git a/src/lib.rs b/src/lib.rs index 113d5182d..dde332eaf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,8 +25,8 @@ pub use crate::opaque_types::*; mod collections; pub use crate::collections::*; -// mod config; -// pub use crate::config::*; +mod config; +pub use crate::config::*; mod commons; pub use crate::commons::*; mod payload; @@ -43,8 +43,8 @@ pub use crate::payload::*; // pub use crate::put::*; // mod scouting; // pub use crate::scouting::*; -// mod session; -// pub use crate::session::*; +mod session; +pub use crate::session::*; // mod subscriber; // pub use crate::subscriber::*; // // mod pull_subscriber; From e20e80b116a48bd5a65fb3f5ea2bb66e1da3079d Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 19 Apr 2024 20:37:13 +0200 Subject: [PATCH 53/75] some progress --- Cargo.lock | 244 +-- Cargo.toml | 2 + build-resources/opaque-types/Cargo.lock | 247 +-- build-resources/opaque-types/src/lib.rs | 243 ++- build.rs | 29 +- docs/api.rst | 32 +- examples/z_get.c | 4 +- examples/z_non_blocking_get.c | 2 +- examples/z_ping.c | 2 +- examples/z_pong.c | 4 +- examples/z_pub.c | 2 +- examples/z_pub_attachment.c | 10 +- examples/z_pub_cache.c | 2 +- examples/z_pub_shm.c | 2 +- examples/z_pub_thr.c | 2 +- examples/z_pull.c | 2 +- examples/z_put.c | 8 +- examples/z_query_sub.c | 2 +- examples/z_queryable.c | 10 +- examples/z_queryable_with_channels.c | 10 +- examples/z_sub.c | 2 +- examples/z_sub_attachment.c | 10 +- include/zenoh-gen.h | 2045 ++++++++++++++++++++--- include/zenoh_macros.h | 48 +- src/attachment.rs | 416 ----- src/closures/query_channel.rs | 129 +- src/closures/query_closure.rs | 10 +- src/closures/reply_closure.rs | 14 +- src/closures/response_channel.rs | 122 +- src/collections.rs | 322 +++- src/commons.rs | 378 +++-- src/config.rs | 103 +- src/errors.rs | 7 + src/get.rs | 276 +-- src/info.rs | 47 +- src/keyexpr.rs | 481 +++--- src/lib.rs | 30 +- src/payload.rs | 320 ++-- src/publisher.rs | 338 ++-- src/put.rs | 92 +- src/queryable.rs | 240 ++- src/scouting.rs | 59 +- src/session.rs | 36 +- src/shm.rs | 6 +- src/transmute.rs | 47 + tests/z_api_alignment_test.c | 8 +- tests/z_api_attachment_test.c | 44 +- tests/z_api_null_drop_test.c | 4 +- tests/z_api_payload_test.c | 18 +- tests/z_int_pub_cache_query_sub_test.c | 6 +- tests/z_int_pub_sub_attachment_test.c | 16 +- tests/z_int_pub_sub_test.c | 4 +- tests/z_int_queryable_attachment_test.c | 28 +- tests/z_int_queryable_test.c | 6 +- 54 files changed, 3991 insertions(+), 2580 deletions(-) delete mode 100644 src/attachment.rs create mode 100644 src/errors.rs diff --git a/Cargo.lock b/Cargo.lock index 336fce624..c10ee7ae4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,6 +35,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -70,54 +71,6 @@ dependencies = [ "libc", ] -[[package]] -name = "anstream" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" - -[[package]] -name = "anstyle-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - [[package]] name = "anyhow" version = "1.0.75" @@ -463,12 +416,6 @@ dependencies = [ "os_str_bytes", ] -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - [[package]] name = "concurrent-queue" version = "2.2.0" @@ -604,16 +551,6 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbfc4744c1b8f2a09adc0e55242f60b1af195d88596bd8700be74418c056c555" -[[package]] -name = "env_filter" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" -dependencies = [ - "log", - "regex", -] - [[package]] name = "env_logger" version = "0.10.2" @@ -627,19 +564,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "env_logger" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "humantime", - "log", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -1229,6 +1153,15 @@ dependencies = [ "twox-hash", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.6.3" @@ -1303,6 +1236,16 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint" version = "0.4.4" @@ -1414,6 +1357,12 @@ version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking" version = "2.1.0" @@ -1755,8 +1704,17 @@ checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.3.8", + "regex-syntax 0.7.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1767,9 +1725,15 @@ checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.7.5" @@ -2186,6 +2150,15 @@ dependencies = [ "keccak", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shared_memory" version = "0.12.4" @@ -2402,6 +2375,16 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2542,6 +2525,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", ] [[package]] @@ -2678,12 +2704,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - [[package]] name = "uuid" version = "1.4.1" @@ -2717,6 +2737,12 @@ dependencies = [ "unzip-n", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "value-bag" version = "1.8.1" @@ -3060,17 +3086,16 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" name = "zenoh" version = "0.11.0-dev" dependencies = [ + "ahash", "async-trait", "base64", "const_format", - "env_logger 0.11.3", "event-listener 4.0.0", "flume", "form_urlencoded", "futures", "git-version", "lazy_static", - "log", "ordered-float", "paste", "petgraph", @@ -3087,6 +3112,7 @@ dependencies = [ "stop-token", "tokio", "tokio-util", + "tracing", "uhlc", "unwrap-infallible", "uuid", @@ -3126,7 +3152,7 @@ dependencies = [ "async-trait", "cbindgen", "chrono", - "env_logger 0.10.2", + "env_logger", "fs2", "fs_extra", "futures", @@ -3141,14 +3167,16 @@ dependencies = [ "unwrap-infallible", "zenoh", "zenoh-ext", + "zenoh-protocol", + "zenoh-util", ] [[package]] name = "zenoh-codec" version = "0.11.0-dev" dependencies = [ - "log", "serde", + "tracing", "uhlc", "zenoh-buffers", "zenoh-protocol", @@ -3165,12 +3193,12 @@ version = "0.11.0-dev" dependencies = [ "flume", "json5", - "log", "num_cpus", "secrecy", "serde", "serde_json", "serde_yaml", + "tracing", "validated_struct", "zenoh-core", "zenoh-protocol", @@ -3206,16 +3234,16 @@ name = "zenoh-ext" version = "0.11.0-dev" dependencies = [ "bincode", - "env_logger 0.11.3", "flume", "futures", - "log", "phf", "serde", "serde_cbor", "serde_json", "tokio", + "tracing", "zenoh", + "zenoh-util", ] [[package]] @@ -3255,12 +3283,12 @@ dependencies = [ "async-trait", "flume", "futures", - "log", "rustls 0.22.3", "rustls-webpki 0.102.2", "serde", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-codec", "zenoh-core", @@ -3277,7 +3305,6 @@ dependencies = [ "async-trait", "base64", "futures", - "log", "quinn", "rustls 0.21.7", "rustls-native-certs 0.7.0", @@ -3287,6 +3314,8 @@ dependencies = [ "tokio", "tokio-rustls 0.24.1", "tokio-util", + "tracing", + "zenoh-collections", "zenoh-config", "zenoh-core", "zenoh-link-commons", @@ -3302,9 +3331,9 @@ name = "zenoh-link-tcp" version = "0.11.0-dev" dependencies = [ "async-trait", - "log", "tokio", "tokio-util", + "tracing", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", @@ -3321,7 +3350,6 @@ dependencies = [ "async-trait", "base64", "futures", - "log", "rustls 0.22.3", "rustls-pemfile 2.0.0", "rustls-pki-types", @@ -3330,7 +3358,9 @@ dependencies = [ "tokio", "tokio-rustls 0.25.0", "tokio-util", + "tracing", "webpki-roots", + "zenoh-collections", "zenoh-config", "zenoh-core", "zenoh-link-commons", @@ -3346,10 +3376,10 @@ name = "zenoh-link-udp" version = "0.11.0-dev" dependencies = [ "async-trait", - "log", "socket2 0.5.6", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-collections", "zenoh-core", @@ -3367,10 +3397,10 @@ version = "0.11.0-dev" dependencies = [ "async-trait", "futures", - "log", "nix 0.27.1", "tokio", "tokio-util", + "tracing", "uuid", "zenoh-core", "zenoh-link-commons", @@ -3386,10 +3416,10 @@ version = "0.11.0-dev" dependencies = [ "async-trait", "futures-util", - "log", "tokio", "tokio-tungstenite", "tokio-util", + "tracing", "url", "zenoh-core", "zenoh-link-commons", @@ -3416,9 +3446,9 @@ version = "0.11.0-dev" dependencies = [ "const_format", "libloading", - "log", "serde", "serde_json", + "tracing", "zenoh-keyexpr", "zenoh-macros", "zenoh-result", @@ -3434,6 +3464,7 @@ dependencies = [ "serde", "uhlc", "zenoh-buffers", + "zenoh-collections", "zenoh-keyexpr", "zenoh-result", ] @@ -3452,7 +3483,7 @@ dependencies = [ "futures", "lazy_static", "tokio", - "zenoh-collections", + "zenoh-protocol", "zenoh-result", ] @@ -3460,9 +3491,9 @@ dependencies = [ name = "zenoh-shm" version = "0.11.0-dev" dependencies = [ - "log", "serde", "shared_memory", + "tracing", "zenoh-buffers", "zenoh-result", ] @@ -3485,9 +3516,9 @@ name = "zenoh-task" version = "0.11.0-dev" dependencies = [ "futures", - "log", "tokio", "tokio-util", + "tracing", "zenoh-core", "zenoh-runtime", ] @@ -3498,7 +3529,6 @@ version = "0.11.0-dev" dependencies = [ "async-trait", "flume", - "log", "lz4_flex", "paste", "rand", @@ -3508,6 +3538,7 @@ dependencies = [ "sha3", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-codec", "zenoh-collections", @@ -3536,10 +3567,11 @@ dependencies = [ "lazy_static", "libc", "libloading", - "log", "pnet_datalink", "shellexpand", "tokio", + "tracing", + "tracing-subscriber", "winapi", "zenoh-core", "zenoh-result", diff --git a/Cargo.toml b/Cargo.toml index e3579e00e..767d9a3a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,6 +59,8 @@ unwrap-infallible = "0.1.5" zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} +zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } +zenoh-util = { path = "../zenoh/commons/zenoh-util" } [build-dependencies] cbindgen = "0.26.0" diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock index 5ed408409..b3cd2f5b5 100644 --- a/build-resources/opaque-types/Cargo.lock +++ b/build-resources/opaque-types/Cargo.lock @@ -35,6 +35,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -55,54 +56,6 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" -[[package]] -name = "anstream" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" - -[[package]] -name = "anstyle-parse" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - [[package]] name = "anyhow" version = "1.0.81" @@ -432,12 +385,6 @@ dependencies = [ "inout", ] -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - [[package]] name = "concurrent-queue" version = "2.4.0" @@ -530,29 +477,6 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" -[[package]] -name = "env_filter" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "humantime", - "log", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -1083,6 +1007,15 @@ dependencies = [ "twox-hash", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.7.2" @@ -1146,6 +1079,16 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint" version = "0.4.4" @@ -1223,6 +1166,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking" version = "2.2.0" @@ -1506,8 +1455,17 @@ checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1518,9 +1476,15 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.3", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.3" @@ -1776,6 +1740,15 @@ dependencies = [ "keccak", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shared_memory" version = "0.12.4" @@ -1822,6 +1795,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + [[package]] name = "socket2" version = "0.4.10" @@ -1917,6 +1896,16 @@ dependencies = [ "syn 2.0.55", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "token-cell" version = "1.5.0" @@ -1976,14 +1965,72 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.55", +] + [[package]] name = "tracing-core" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] [[package]] name = "twox-hash" @@ -2062,12 +2109,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - [[package]] name = "uuid" version = "1.8.0" @@ -2101,6 +2142,12 @@ dependencies = [ "unzip-n", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "value-bag" version = "1.8.1" @@ -2417,17 +2464,16 @@ checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" name = "zenoh" version = "0.11.0-dev" dependencies = [ + "ahash", "async-trait", "base64", "const_format", - "env_logger", "event-listener 4.0.3", "flume", "form_urlencoded", "futures", "git-version", "lazy_static", - "log", "ordered-float", "paste", "petgraph", @@ -2444,6 +2490,7 @@ dependencies = [ "stop-token", "tokio", "tokio-util", + "tracing", "uhlc", "unwrap-infallible", "uuid", @@ -2479,8 +2526,8 @@ dependencies = [ name = "zenoh-codec" version = "0.11.0-dev" dependencies = [ - "log", "serde", + "tracing", "uhlc", "zenoh-buffers", "zenoh-protocol", @@ -2497,12 +2544,12 @@ version = "0.11.0-dev" dependencies = [ "flume", "json5", - "log", "num_cpus", "secrecy", "serde", "serde_json", "serde_yaml", + "tracing", "validated_struct", "zenoh-core", "zenoh-protocol", @@ -2538,16 +2585,16 @@ name = "zenoh-ext" version = "0.11.0-dev" dependencies = [ "bincode", - "env_logger", "flume", "futures", - "log", "phf", "serde", "serde_cbor", "serde_json", "tokio", + "tracing", "zenoh", + "zenoh-util", ] [[package]] @@ -2581,12 +2628,12 @@ dependencies = [ "async-trait", "flume", "futures", - "log", "rustls", "rustls-webpki", "serde", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-codec", "zenoh-core", @@ -2612,9 +2659,9 @@ version = "0.11.0-dev" dependencies = [ "const_format", "libloading", - "log", "serde", "serde_json", + "tracing", "zenoh-keyexpr", "zenoh-macros", "zenoh-result", @@ -2630,6 +2677,7 @@ dependencies = [ "serde", "uhlc", "zenoh-buffers", + "zenoh-collections", "zenoh-keyexpr", "zenoh-result", ] @@ -2648,7 +2696,7 @@ dependencies = [ "futures", "lazy_static", "tokio", - "zenoh-collections", + "zenoh-protocol", "zenoh-result", ] @@ -2656,9 +2704,9 @@ dependencies = [ name = "zenoh-shm" version = "0.11.0-dev" dependencies = [ - "log", "serde", "shared_memory", + "tracing", "zenoh-buffers", "zenoh-result", ] @@ -2681,9 +2729,9 @@ name = "zenoh-task" version = "0.11.0-dev" dependencies = [ "futures", - "log", "tokio", "tokio-util", + "tracing", "zenoh-core", "zenoh-runtime", ] @@ -2694,7 +2742,6 @@ version = "0.11.0-dev" dependencies = [ "async-trait", "flume", - "log", "lz4_flex", "paste", "rand", @@ -2703,6 +2750,7 @@ dependencies = [ "sha3", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-codec", "zenoh-collections", @@ -2731,10 +2779,11 @@ dependencies = [ "lazy_static", "libc", "libloading", - "log", "pnet_datalink", "shellexpand", "tokio", + "tracing", + "tracing-subscriber", "winapi", "zenoh-core", "zenoh-result", diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index d2ad923ac..dd5443d73 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,14 +1,20 @@ +use std::borrow::Cow; +use std::collections::HashMap; use std::sync::Arc; -use zenoh::buffers::{ZBuf, ZBufReader}; use zenoh::config::Config; use zenoh::config::ZenohId; use zenoh::encoding::Encoding; +use zenoh::handlers::DefaultHandler; use zenoh::key_expr::KeyExpr; +use zenoh::bytes::{ZBytes, ZBytesReader}; +use zenoh::publication::MatchingListener; +use zenoh::publication::Publisher; use zenoh::query::Reply; use zenoh::queryable::Query; use zenoh::queryable::Queryable; use zenoh::sample::Sample; use zenoh::session::Session; +use zenoh::time::Timestamp; use zenoh::value::Value; // Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. @@ -19,78 +25,233 @@ use zenoh::value::Value; #[macro_export] macro_rules! get_opaque_type_data { - ($src_type:ty, $expr:expr) => { + ($src_type:ty, $name:ident) => { const _: () = { - let align = std::mem::align_of::<$src_type>(); - let size = std::mem::size_of::<$src_type>(); - let mut msg: [u8; 61] = - *b"type: , align: , size: "; - let mut i = 0; - while i < 4 { - msg[i as usize + 46] = b'0' + ((align / 10u32.pow(3 - i) as usize) % 10) as u8; - msg[i as usize + 57] = b'0' + ((size / 10u32.pow(3 - i) as usize) % 10) as u8; - i += 1; + const fn get_num_digits(n: usize) -> usize { + let mut out = 0; + let mut res = n; + while res > 0 { + out += 1; + res = res / 10; + } + if out == 0 { + out = 1; + } + out } - let mut i: usize = 0; - while i < $expr.len() { - msg[i as usize + 5] = $expr.as_bytes()[i]; - i += 1; + + const fn write_str(src: &[u8], mut dst: [u8; MSG_LEN], offset: usize) -> [u8; MSG_LEN] { + let mut i = 0; + while i < src.len() { + dst[i + offset] = src[i]; + i += 1; + } + dst + } + + const fn write_num(src: usize, mut dst: [u8; MSG_LEN], offset: usize) -> [u8; MSG_LEN] { + let mut i = 0; + let num_digits = get_num_digits(src) as u32; + while i < num_digits { + dst[i as usize + offset] = b'0' + ((src / 10u32.pow(num_digits - i - 1) as usize) % 10) as u8; + i += 1; + } + dst } + + const DST_NAME: &str = stringify!($name); + const ALIGN: usize = std::mem::align_of::<$src_type>(); + const SIZE: usize = std::mem::size_of::<$src_type>(); + const TYPE_TOKEN: [u8; 6] = *b"type: "; + const ALIGN_TOKEN: [u8; 9] = *b", align: "; + const SIZE_TOKEN: [u8; 8] = *b", size: "; + const SIZE_NUM_DIGITS: usize = get_num_digits(SIZE); + const ALIGN_NUM_DIGITS: usize = get_num_digits(ALIGN); + const MSG_LEN: usize = TYPE_TOKEN.len() + ALIGN_TOKEN.len() + SIZE_TOKEN.len() + SIZE_NUM_DIGITS + ALIGN_NUM_DIGITS + DST_NAME.len(); + const TYPE_OFFSET: usize = TYPE_TOKEN.len(); + const ALIGN_OFFSET: usize = TYPE_OFFSET + DST_NAME.len() + ALIGN_TOKEN.len(); + const SIZE_OFFSET: usize = ALIGN_OFFSET + ALIGN_NUM_DIGITS + SIZE_TOKEN.len(); + let mut msg: [u8; MSG_LEN] = [b' '; MSG_LEN]; + + msg = write_str(&TYPE_TOKEN, msg, 0); + msg = write_str(&DST_NAME.as_bytes(), msg, TYPE_OFFSET); + msg = write_str(&ALIGN_TOKEN, msg, ALIGN_OFFSET - ALIGN_TOKEN.len()); + msg = write_num(ALIGN, msg, ALIGN_OFFSET); + msg = write_str(&SIZE_TOKEN, msg, SIZE_OFFSET - SIZE_TOKEN.len()); + msg = write_num(SIZE, msg, SIZE_OFFSET); + panic!("{}", unsafe { std::str::from_utf8_unchecked(msg.as_slice()) }); }; - }; + } } /// A split buffer that owns all of its data. /// /// To minimize copies and reallocations, Zenoh may provide you data in split buffers. -get_opaque_type_data!(Option, "z_owned_buffer_t"); -get_opaque_type_data!(&'static ZBuf, "z_buffer_t"); +get_opaque_type_data!(Option, z_owned_bytes_t); +/// A loaned payload. +get_opaque_type_data!(&'static ZBytes, z_bytes_t); + +/// A map of maybe-owned vector of bytes to maybe-owned vector of bytes. +/// +/// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher +get_opaque_type_data!(Option, Cow<'static, [u8]>>>, z_owned_slice_map_t); +get_opaque_type_data!(&'static HashMap, Cow<'static, [u8]>>, z_slice_map_t); /// An owned sample. /// /// This is a read only type that can only be constructed by cloning a `z_sample_t`. /// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. -get_opaque_type_data!(Option, "zc_owned_sample_t"); - -get_opaque_type_data!(&'static Sample, "z_sample_t"); +get_opaque_type_data!(Option, zc_owned_sample_t); +get_opaque_type_data!(&'static Sample, z_sample_t); /// A reader for payload data. -get_opaque_type_data!(Option>, "zc_owned_payload_reader"); -get_opaque_type_data!(&'static ZBufReader, "zc_payload_reader"); +get_opaque_type_data!(Option>, z_owned_bytes_t_reader_t); +get_opaque_type_data!(&'static ZBytesReader<'static>, z_bytes_reader_t); -get_opaque_type_data!(&'static Encoding, "z_encoding_t"); -get_opaque_type_data!(Encoding, "z_owned_encoding_t"); +/// The encoding of a payload, in a MIME-like format. +/// +/// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. +get_opaque_type_data!(&'static Encoding, z_encoding_t); +get_opaque_type_data!(Encoding, z_owned_encoding_t); -get_opaque_type_data!(Option, "z_owned_reply_t"); +/// An owned reply to a :c:func:`z_get`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. +get_opaque_type_data!(Option, z_owned_reply_t); +get_opaque_type_data!(&'static Reply, z_reply_t); -get_opaque_type_data!(Value, "z_owned_value_t"); -get_opaque_type_data!(&'static Value, "z_value_t"); +/// A zenoh value. +get_opaque_type_data!(Value, z_owned_value_t); +get_opaque_type_data!(&'static Value, z_value_t); -get_opaque_type_data!(Option, "z_owned_query_t"); -get_opaque_type_data!(&'static Query, "z_query_t"); +// Loaned variant of a Query received by a Queryable. +/// +/// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. +/// `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. +get_opaque_type_data!(Option, z_owned_query_t); +get_opaque_type_data!(&'static Query, z_query_t); -get_opaque_type_data!(Option>, "z_owned_queryable_t"); -get_opaque_type_data!(&'static Queryable<'static, ()>, "z_queryable_t"); +/// An owned zenoh queryable. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, z_owned_queryable_t); +get_opaque_type_data!(&'static Queryable<'static, ()>, z_queryable_t); // get_opaque_type_data!( // Option>, -// "ze_owned_querying_subscriber_t" +// ze_owned_querying_subscriber_t // ); // get_opaque_type_data!( // &'static FetchingSubscriberWrapper, -// "ze_querying_subscriber_t" +// ze_querying_subscriber_t // ); -get_opaque_type_data!(Option>, "z_owned_keyexpr_t"); -get_opaque_type_data!(&'static KeyExpr<'_>, "z_keyexpr_t"); +/// A zenoh-allocated key expression. +/// +/// Key expressions can identify a single key or a set of keys. +/// +/// Examples : +/// - ``"key/expression"``. +/// - ``"key/ex*"``. +/// +/// Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` +/// for wire and computation efficiency. +/// +/// A `key expression `_ can be either: +/// - A plain string expression. +/// - A pure numerical id. +/// - The combination of a numerical prefix and a string suffix. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, z_owned_keyexpr_t); +/// A loaned key expression. +/// +/// Key expressions can identify a single key or a set of keys. +/// +/// Examples : +/// - ``"key/expression"``. +/// - ``"key/ex*"``. +/// +/// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, +/// both for local processing and network-wise. +get_opaque_type_data!(&'static KeyExpr<'_>, z_keyexpr_t); + +/// An owned zenoh session. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, z_owned_session_t); +get_opaque_type_data!(&'static Session, z_session_t); -get_opaque_type_data!(Option>, "z_owned_session_t"); -get_opaque_type_data!(&'static Session, "z_session_t"); +/// An owned zenoh configuration. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, z_owned_config_t); +/// A loaned zenoh configuration. +get_opaque_type_data!(&'static Config, z_config_t); + +/// Represents a Zenoh ID. +/// +/// In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. +get_opaque_type_data!(ZenohId, z_id_t); -get_opaque_type_data!(Option>, "z_owned_config_t"); -get_opaque_type_data!(&'static Config, "z_config_t"); +get_opaque_type_data!(Timestamp, z_timestamp_t); + +/// An owned zenoh publisher. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, z_owned_publisher_t); +get_opaque_type_data!(&'static Publisher<'static>, z_publisher_t); -get_opaque_type_data!(ZenohId, "z_id_t"); +/// An owned zenoh matching listener. Destroying the matching listener cancels the subscription. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, zcu_owned_matching_listener_t); diff --git a/build.rs b/build.rs index 97a90078a..120b308f7 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,5 @@ use fs2::FileExt; +use fs_extra::dir::remove; use regex::Regex; use std::env; use std::io::{Read, Write}; @@ -91,9 +92,12 @@ fn generate_opaque_types() { let data_in = std::fs::read_to_string(path_in).unwrap(); let mut data_out = String::new(); - let docs = get_opaque_type_docs(); + data_out += "#[rustfmt::skip] +#[allow(clippy::all)] +"; + let mut docs = get_opaque_type_docs(); - let re = Regex::new(r"type:(\w+) *, align:0*(\d+), size:0*(\d+)").unwrap(); + let re = Regex::new(r"type: (\w+), align: (\d+), size: (\d+)").unwrap(); for (_, [type_name, align, size]) in re.captures_iter(&data_in).map(|c| c.extract()) { let s = format!( "#[derive(Copy, Clone)] @@ -103,21 +107,25 @@ pub struct {type_name} {{ }} " ); - if let Some(doc) = docs.get(type_name) { - for d in doc { - data_out += d; - data_out += "\r\n"; - } + let doc = docs.remove(type_name).expect(&format!( + "Failed to extract docs for opaque type: {type_name}" + )); + for d in doc { + data_out += &d; + data_out += "\r\n"; } data_out += &s; } + for d in docs.keys() { + panic!("Failed to find type information for opaque type: {d}"); + } std::fs::write(path_out, data_out).unwrap(); } fn get_opaque_type_docs() -> HashMap> { let current_folder = get_build_rs_path(); let path_in = current_folder.join("./build-resources/opaque-types/src/lib.rs"); - let re = Regex::new(r#"get_opaque_type_data!\(.*, "(\w+)"\)"#).unwrap(); + let re = Regex::new(r#"(?m)^\s*get_opaque_type_data!\(\s*(.*)\s*,\s*(\w+)\)"#).unwrap(); let mut comments = std::vec::Vec::::new(); let mut res = HashMap::>::new(); @@ -126,11 +134,8 @@ fn get_opaque_type_docs() -> HashMap> { comments.push(line.to_string()); continue; } - if comments.is_empty() { - continue; - } if let Some(c) = re.captures(line) { - res.insert(c[1].to_string(), comments.clone()); + res.insert(c[2].to_string(), comments.clone()); } comments.clear(); } diff --git a/docs/api.rst b/docs/api.rst index 758c405b5..046ede892 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -22,29 +22,29 @@ Generic types Bytes ----- -.. autocstruct:: zenoh_commons.h::z_bytes_t +.. autocstruct:: zenoh_commons.h::z_slice_t -.. autocfunction:: zenoh_commons.h::z_bytes_new -.. autocfunction:: zenoh_commons.h::z_bytes_check -.. autocfunction:: zenoh_commons.h::z_bytes_null +.. autocfunction:: zenoh_commons.h::z_slice_new +.. autocfunction:: zenoh_commons.h::z_slice_check +.. autocfunction:: zenoh_commons.h::z_slice_null Bytes map --------- .. autocstruct:: zenoh_commons.h::z_owned_bytes_map_t -.. autocfunction:: zenoh_commons.h::z_bytes_map_new -.. autocfunction:: zenoh_commons.h::z_bytes_map_check -.. autocfunction:: zenoh_commons.h::z_bytes_map_null -.. autocfunction:: zenoh_commons.h::z_bytes_map_drop -.. autocfunction:: zenoh_commons.h::z_bytes_map_get -.. autocfunction:: zenoh_commons.h::z_bytes_map_len -.. autocfunction:: zenoh_commons.h::z_bytes_map_is_empty -.. autocfunction:: zenoh_commons.h::z_bytes_map_insert_by_alias -.. autocfunction:: zenoh_commons.h::z_bytes_map_insert_by_copy -.. autocfunction:: zenoh_commons.h::z_bytes_map_iter -.. autocfunction:: zenoh_commons.h::z_bytes_map_from_attachment -.. autocfunction:: zenoh_commons.h::z_bytes_map_from_attachment_aliasing +.. autocfunction:: zenoh_commons.h::z_slice_map_new +.. autocfunction:: zenoh_commons.h::z_slice_map_check +.. autocfunction:: zenoh_commons.h::z_slice_map_null +.. autocfunction:: zenoh_commons.h::z_slice_map_drop +.. autocfunction:: zenoh_commons.h::z_slice_map_get +.. autocfunction:: zenoh_commons.h::z_slice_map_len +.. autocfunction:: zenoh_commons.h::z_slice_map_is_empty +.. autocfunction:: zenoh_commons.h::z_slice_map_insert_by_alias +.. autocfunction:: zenoh_commons.h::z_slice_map_insert_by_copy +.. autocfunction:: zenoh_commons.h::z_slice_map_iter +.. autocfunction:: zenoh_commons.h::z_slice_map_from_attachment +.. autocfunction:: zenoh_commons.h::z_slice_map_from_attachment_aliasing .. Scouting .. ======== diff --git a/examples/z_get.c b/examples/z_get.c index 9866212f7..d8f90b35e 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -57,7 +57,7 @@ int main(int argc, char **argv) { z_owned_reply_channel_t channel = zc_reply_fifo_new(16); z_get_options_t opts = z_get_options_default(); if (value != NULL) { - opts.payload = zc_payload_encode_from_string(value); + opts.payload = z_bytes_encode_from_string(value); } z_get(z_loan(s), keyexpr, "", z_move(channel.send), z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate @@ -67,7 +67,7 @@ int main(int argc, char **argv) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); z_drop(z_move(payload_value)); z_drop(z_move(keystr)); diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index 471f7e227..30df45daf 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -60,7 +60,7 @@ int main(int argc, char **argv) { if (z_reply_is_ok(&reply)) { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); z_drop(z_move(payload_value)); z_drop(z_move(keystr)); diff --git a/examples/z_ping.c b/examples/z_ping.c index a5c0954d0..8f8adb2f7 100644 --- a/examples/z_ping.c +++ b/examples/z_ping.c @@ -54,7 +54,7 @@ int main(int argc, char** argv) { for (int i = 0; i < args.size; i++) { data[i] = i % 10; } - zc_owned_payload_t payload = zc_payload_encode_from_bytes((z_bytes_t){.start = data, .len = args.size}); + z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_slice_t){.start = data, .len = args.size}); z_mutex_lock(&mutex); if (args.warmup_ms) { printf("Warming up for %dms...\n", args.warmup_ms); diff --git a/examples/z_pong.c b/examples/z_pong.c index 772280696..3da1150bb 100644 --- a/examples/z_pong.c +++ b/examples/z_pong.c @@ -5,8 +5,8 @@ void callback(const z_sample_t* sample, void* context) { z_publisher_t pub = z_loan(*(z_owned_publisher_t*)context); -#ifdef ZENOH_C // The zc_owned_payload_t API is exclusive to zenoh-c, but allows avoiding some copies. - zc_owned_payload_t payload = z_sample_owned_payload(sample); +#ifdef ZENOH_C // The z_owned_bytes_t API is exclusive to zenoh-c, but allows avoiding some copies. + z_owned_bytes_t payload = z_sample_owned_payload(sample); z_publisher_put(pub, z_move(payload), NULL); #endif } diff --git a/examples/z_pub.c b/examples/z_pub.c index 9dd496153..29ccd5c8e 100644 --- a/examples/z_pub.c +++ b/examples/z_pub.c @@ -71,7 +71,7 @@ int main(int argc, char **argv) { printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_owned_bytes_t payload = z_bytes_encode_from_string(buf); z_publisher_put(z_loan(pub), z_move(payload), &options); } diff --git a/examples/z_pub_attachment.c b/examples/z_pub_attachment.c index 530d9dc29..c45b25811 100644 --- a/examples/z_pub_attachment.c +++ b/examples/z_pub_attachment.c @@ -52,13 +52,13 @@ int main(int argc, char **argv) { options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); // allocate attachment map - z_owned_bytes_map_t map = z_bytes_map_new(); + z_owned_bytes_map_t map = z_slice_map_new(); // set it as an attachment - options.attachment = z_bytes_map_as_attachment(&map); + options.attachment = z_slice_map_as_attachment(&map); // add some value - z_bytes_map_insert_by_alias(&map, z_bytes_from_str("source"), z_bytes_from_str("C")); + z_slice_map_insert_by_alias(&map, z_slice_from_str("source"), z_slice_from_str("C")); char buf[256]; char buf_ind[16]; @@ -67,11 +67,11 @@ int main(int argc, char **argv) { // add some other attachment value sprintf(buf_ind, "%d", idx); - z_bytes_map_insert_by_alias(&map, z_bytes_from_str("index"), z_bytes_from_str(buf_ind)); + z_slice_map_insert_by_alias(&map, z_slice_from_str("index"), z_slice_from_str(buf_ind)); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_owned_bytes_t payload = z_bytes_encode_from_string(buf); z_publisher_put(z_loan(pub), z_move(payload), &options); } diff --git a/examples/z_pub_cache.c b/examples/z_pub_cache.c index 622896948..7594fee1f 100644 --- a/examples/z_pub_cache.c +++ b/examples/z_pub_cache.c @@ -63,7 +63,7 @@ int main(int argc, char **argv) { z_sleep_s(1); sprintf(buf, "[%4d] %s", idx, value); printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - zc_owned_payload_t payload = zc_payload_encode_from_string(buf); + z_owned_bytes_t payload = z_bytes_encode_from_string(buf); z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } diff --git a/examples/z_pub_shm.c b/examples/z_pub_shm.c index 3c032e02f..c7bb1684d 100644 --- a/examples/z_pub_shm.c +++ b/examples/z_pub_shm.c @@ -83,7 +83,7 @@ int main(int argc, char **argv) { printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - zc_owned_payload_t payload = zc_shmbuf_into_payload(z_move(shmbuf)); + z_owned_bytes_t payload = zc_shmbuf_into_payload(z_move(shmbuf)); z_publisher_put(z_loan(pub), z_move(payload), &options); } diff --git a/examples/z_pub_thr.c b/examples/z_pub_thr.c index e0568973c..0298ceacf 100644 --- a/examples/z_pub_thr.c +++ b/examples/z_pub_thr.c @@ -54,7 +54,7 @@ int main(int argc, char **argv) { } while (1) { - zc_owned_payload_t payload = zc_payload_encode_from_bytes((z_bytes_t){.start = value, .len = len}); + z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_slice_t){.start = value, .len = len}); z_publisher_put(z_loan(pub), z_move(payload), NULL); } diff --git a/examples/z_pull.c b/examples/z_pull.c index 094dc0a6b..8016da577 100644 --- a/examples/z_pull.c +++ b/examples/z_pull.c @@ -19,7 +19,7 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload_value)); z_drop(z_move(payload_value)); diff --git a/examples/z_put.c b/examples/z_put.c index 503fb5c36..c74f95672 100644 --- a/examples/z_put.c +++ b/examples/z_put.c @@ -23,8 +23,8 @@ int main(int argc, char **argv) { if (argc > 1) keyexpr = argv[1]; if (argc > 2) value = argv[2]; - z_owned_bytes_map_t attachment = z_bytes_map_new(); - z_bytes_map_insert_by_alias(&attachment, z_bytes_from_str("hello"), z_bytes_from_str("there")); + z_owned_bytes_map_t attachment = z_slice_map_new(); + z_slice_map_insert_by_alias(&attachment, z_slice_from_str("hello"), z_slice_from_str("there")); z_owned_config_t config = z_config_default(); if (argc > 3) { @@ -47,8 +47,8 @@ int main(int argc, char **argv) { printf("Putting Data ('%s': '%s')...\n", keyexpr, value); z_put_options_t options = z_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - options.attachment = z_bytes_map_as_attachment(&attachment); - zc_owned_payload_t payload = zc_payload_encode_from_string(value); + options.attachment = z_slice_map_as_attachment(&attachment); + z_owned_bytes_t payload = z_bytes_encode_from_string(value); int res = z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), &options); if (res < 0) { printf("Put failed...\n"); diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index 620dd9594..a2f878019 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -19,7 +19,7 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload_value)); z_drop(z_move(payload_value)); diff --git a/examples/z_queryable.c b/examples/z_queryable.c index 577ef146e..4342c6746 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -21,11 +21,11 @@ z_keyexpr_t keyexpr; void query_handler(const z_query_t *query, void *context) { z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_bytes_t pred = z_query_parameters(query); - zc_payload_t payload = z_query_value(query).payload; - if (zc_payload_len(payload) > 0) { + z_slice_t pred = z_query_parameters(query); + z_bytes_t payload = z_query_value(query).payload; + if (z_bytes_len(payload) > 0) { z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(payload, &payload_value); + z_bytes_decode_into_string(payload, &payload_value); printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, pred.start, z_loan(payload_value)); z_drop(z_move(payload_value)); @@ -35,7 +35,7 @@ void query_handler(const z_query_t *query, void *context) { z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - zc_owned_payload_t reply_payload = zc_payload_encode_from_string(value); + z_owned_bytes_t reply_payload = z_bytes_encode_from_string(value); z_query_reply(query, z_keyexpr((const char *)context), z_move(reply_payload), &options); z_drop(z_move(keystr)); } diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index 6c3ca0df1..422ad3971 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -67,11 +67,11 @@ int main(int argc, char **argv) { for (z_call(channel.recv, &oquery); z_check(oquery); z_call(channel.recv, &oquery)) { z_query_t query = z_loan(oquery); z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(&query)); - z_bytes_t pred = z_query_parameters(&query); - zc_payload_t payload = z_query_value(&query).payload; - if (zc_payload_len(payload) > 0) { + z_slice_t pred = z_query_parameters(&query); + z_bytes_t payload = z_query_value(&query).payload; + if (z_bytes_len(payload) > 0) { z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(payload, &payload_value); + z_bytes_decode_into_string(payload, &payload_value); printf(">> [Queryable ] Received Query '%s?%.*s' with value '%s'\n", z_loan(keystr), (int)pred.len, pred.start, z_loan(payload_value)); z_drop(z_move(payload_value)); @@ -80,7 +80,7 @@ int main(int argc, char **argv) { } z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - zc_owned_payload_t reply_payload = zc_payload_encode_from_string(value); + z_owned_bytes_t reply_payload = z_bytes_encode_from_string(value); z_query_reply(&query, keyexpr, z_move(reply_payload), &options); z_drop(z_move(keystr)); z_drop(z_move(oquery)); diff --git a/examples/z_sub.c b/examples/z_sub.c index ffa63703b..f549d1561 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -19,7 +19,7 @@ const char *kind_to_str(z_sample_kind_t kind); void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload_value)); z_drop(z_move(payload_value)); diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index b703e6ad6..6c1ea68be 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -17,7 +17,7 @@ const char *kind_to_str(z_sample_kind_t kind); -int8_t attachment_reader(z_bytes_t key, z_bytes_t val, void *ctx) { +int8_t attachment_reader(z_slice_t key, z_slice_t val, void *ctx) { printf(" attachment: %.*s: '%.*s'\n", (int)key.len, key.start, (int)val.len, val.start); return 0; } @@ -25,19 +25,19 @@ int8_t attachment_reader(z_bytes_t key, z_bytes_t val, void *ctx) { void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload_value)); - z_attachment_t attachment = z_sample_attachment(sample); + z_bytes_t attachment = z_sample_attachment(sample); // checks if attachment exists if (z_check(attachment)) { // reads full attachment z_attachment_iterate(attachment, attachment_reader, NULL); // reads particular attachment item - z_bytes_t index = z_attachment_get(attachment, z_bytes_from_str("index")); - if (z_bytes_is_initialized(&index)) { + z_slice_t index = z_attachment_get(attachment, z_slice_from_str("index")); + if (z_slice_is_initialized(&index)) { printf(" message number: %.*s\n", (int)index.len, index.start); } } diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index a97ed1ddc..1761f69b2 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -5,6 +5,91 @@ #include + + +#define DEFAULT_SCOUTING_TIMEOUT 1000 + +/** + * The kind of congestion control. + * + * - **BLOCK** + * - **DROP** + */ +typedef enum z_congestion_control_t { + Z_CONGESTION_CONTROL_T_BLOCK, + Z_CONGESTION_CONTROL_T_DROP, +} z_congestion_control_t; + +/** + * Consolidation mode values. + * + * - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector + * If the selector contains time range properties, consolidation mode `NONE` is used. + * Otherwise the `LATEST` consolidation mode is used. + * - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. + * - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time + * w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple + * replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp + * ts2 > ts1. It optimizes latency. + * - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. + * It optimizes bandwidth. + */ +typedef enum z_consolidation_mode_t { + Z_CONSOLIDATION_MODE_T_AUTO = -1, + Z_CONSOLIDATION_MODE_T_NONE = 0, + Z_CONSOLIDATION_MODE_T_MONOTONIC = 1, + Z_CONSOLIDATION_MODE_T_LATEST = 2, +} z_consolidation_mode_t; + +/** + * A :c:type:`z_keyexpr_intersection_level_t`. + * + * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** + */ +typedef enum z_keyexpr_intersection_level_t { + Z_KEYEXPR_INTERSECTION_LEVEL_T_DISJOINT = 0, + Z_KEYEXPR_INTERSECTION_LEVEL_T_INTERSECTS = 1, + Z_KEYEXPR_INTERSECTION_LEVEL_T_INCLUDES = 2, + Z_KEYEXPR_INTERSECTION_LEVEL_T_EQUALS = 3, +} z_keyexpr_intersection_level_t; + +/** + * The priority of zenoh messages. + * + * - **REAL_TIME** + * - **INTERACTIVE_HIGH** + * - **INTERACTIVE_LOW** + * - **DATA_HIGH** + * - **DATA** + * - **DATA_LOW** + * - **BACKGROUND** + */ +typedef enum z_priority_t { + Z_PRIORITY_T_REAL_TIME = 1, + Z_PRIORITY_T_INTERACTIVE_HIGH = 2, + Z_PRIORITY_T_INTERACTIVE_LOW = 3, + Z_PRIORITY_T_DATA_HIGH = 4, + Z_PRIORITY_T_DATA = 5, + Z_PRIORITY_T_DATA_LOW = 6, + Z_PRIORITY_T_BACKGROUND = 7, +} z_priority_t; + +/** + * The Queryables that should be target of a :c:func:`z_get`. + * + * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. + * - **ALL_COMPLETE**: All complete queryables. + * - **ALL**: All matching queryables. + */ +typedef enum z_query_target_t { + Z_QUERY_TARGET_T_BEST_MATCHING, + Z_QUERY_TARGET_T_ALL, + Z_QUERY_TARGET_T_ALL_COMPLETE, +} z_query_target_t; + typedef enum z_sample_kind_t { Z_SAMPLE_KIND_T_PUT = 0, Z_SAMPLE_KIND_T_DELETE = 1, @@ -26,13 +111,41 @@ typedef enum zcu_reply_keyexpr_t { * * To minimize copies and reallocations, Zenoh may provide you data in split buffers. */ -typedef struct ALIGN(8) z_owned_buffer_t { +typedef struct ALIGN(8) z_owned_bytes_t { uint8_t _0[40]; -} z_owned_buffer_t; +} z_owned_bytes_t; -typedef struct ALIGN(8) z_buffer_t { +typedef int8_t ZCError; + +/** + * A loaned payload. + */ +typedef struct ALIGN(8) z_bytes_t { uint8_t _0[8]; -} z_buffer_t; +} z_bytes_t; + +typedef struct z_owned_slice_t { + uint8_t *start; + size_t len; +} z_owned_slice_t; + +/** + * A map of maybe-owned vector of bytes to maybe-owned vector of bytes. + * + * In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher + */ +typedef struct ALIGN(8) z_owned_slice_map_t { + uint8_t _0[48]; +} z_owned_slice_map_t; + +/** + * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` + * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with + * `z_check` and `z_str_check` correspondently + */ +typedef struct z_owned_str_t { + char *_cstr; +} z_owned_str_t; /** * A contiguous view of bytes owned by some other entity. @@ -40,111 +153,645 @@ typedef struct ALIGN(8) z_buffer_t { * `start` being `null` is considered a gravestone value, * and empty slices are represented using a possibly dangling pointer for `start`. */ -typedef struct z_bytes_t { +typedef struct z_slice_t { const uint8_t *start; size_t len; -} z_bytes_t; +} z_slice_t; -typedef struct z_owned_bytes_t { - uint8_t *start; - size_t len; -} z_owned_bytes_t; +typedef struct ALIGN(8) z_slice_map_t { + uint8_t _0[8]; +} z_slice_map_t; + +/** + * A reader for payload data. + */ +typedef struct ALIGN(8) z_owned_bytes_t_reader_t { + uint8_t _0[24]; +} z_owned_bytes_t_reader_t; + +typedef struct ALIGN(8) z_bytes_reader_t { + uint8_t _0[8]; +} z_bytes_reader_t; +/** + * An owned zenoh session. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ typedef struct ALIGN(8) z_owned_session_t { uint8_t _0[8]; } z_owned_session_t; -typedef struct ALIGN(8) z_owned_config_t { - uint8_t _0[8]; -} z_owned_config_t; +/** + * Represents a Zenoh ID. + * + * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. + */ +typedef struct ALIGN(1) z_id_t { + uint8_t _0[16]; +} z_id_t; -typedef struct ALIGN(8) z_config_t { +/** + * An owned array of owned, zenoh allocated, NULL terminated strings. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct z_owned_str_array_t { + char **val; + size_t len; +} z_owned_str_array_t; + +/** + * A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. + * + * Members: + * unsigned int whatami: The kind of zenoh entity. + * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). + * z_owned_str_array_t locators: The locators of the scouted entity. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +typedef struct z_owned_hello_t { + unsigned int _whatami; + struct z_id_t _pid; + struct z_owned_str_array_t _locators; +} z_owned_hello_t; + +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_hello_t { + void *context; + void (*call)(struct z_owned_hello_t*, void*); + void (*drop)(void*); +} z_owned_closure_hello_t; + +/** + * + * Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. + * `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. + */ +typedef struct ALIGN(8) z_owned_query_t { + uint8_t _0[16]; +} z_owned_query_t; + +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_owned_query_t { + void *context; + void (*call)(struct z_owned_query_t*, void *context); + void (*drop)(void*); +} z_owned_closure_owned_query_t; + +typedef struct ALIGN(8) z_query_t { uint8_t _0[8]; -} z_config_t; +} z_query_t; -typedef struct ALIGN(8) z_owned_encoding_t { - uint8_t _0[48]; -} z_owned_encoding_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(z_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_query_t { + void *context; + void (*call)(struct z_query_t, void *context); + void (*drop)(void*); +} z_owned_closure_query_t; -typedef struct ALIGN(8) z_encoding_t { +typedef struct ALIGN(8) z_reply_t { uint8_t _0[8]; -} z_encoding_t; +} z_reply_t; + +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_reply_t { + void *context; + void (*call)(struct z_reply_t, void*); + void (*drop)(void*); +} z_owned_closure_reply_t; typedef struct ALIGN(8) z_sample_t { uint8_t _0[8]; } z_sample_t; -typedef struct ALIGN(8) z_keyexpr_t { - uint8_t _0[8]; -} z_keyexpr_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_sample_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_sample_t { + void *context; + void (*call)(const struct z_sample_t*, void *context); + void (*drop)(void*); +} z_owned_closure_sample_t; /** - * An owned payload, backed by a reference counted owner. + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. * - * The `payload` field may be modified, and Zenoh will take the new values into account. + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. */ -typedef struct z_owned_buffer_t zc_owned_payload_t; +typedef struct z_owned_closure_zid_t { + void *context; + void (*call)(const struct z_id_t*, void*); + void (*drop)(void*); +} z_owned_closure_zid_t; -typedef struct z_buffer_t zc_payload_t; +/** + * An owned zenoh configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_config_t { + uint8_t _0[8]; +} z_owned_config_t; -typedef struct ALIGN(1) z_id_t { - uint8_t _0[16]; -} z_id_t; +/** + * A loaned zenoh configuration. + */ +typedef struct ALIGN(8) z_config_t { + uint8_t _0[8]; +} z_config_t; -typedef struct z_timestamp_t { - uint64_t time; - struct z_id_t id; -} z_timestamp_t; +/** + * A zenoh-allocated key expression. + * + * Key expressions can identify a single key or a set of keys. + * + * Examples : + * - ``"key/expression"``. + * - ``"key/ex*"``. + * + * Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` + * for wire and computation efficiency. + * + * A `key expression `_ can be either: + * - A plain string expression. + * - A pure numerical id. + * - The combination of a numerical prefix and a string suffix. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_keyexpr_t { + uint8_t _0[32]; +} z_owned_keyexpr_t; typedef struct ALIGN(8) z_session_t { uint8_t _0[8]; } z_session_t; /** - * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` - * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with - * `z_check` and `z_str_check` correspondently + * A loaned key expression. + * + * Key expressions can identify a single key or a set of keys. + * + * Examples : + * - ``"key/expression"``. + * - ``"key/ex*"``. + * + * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, + * both for local processing and network-wise. */ -typedef struct z_owned_str_t { - char *_cstr; -} z_owned_str_t; +typedef struct ALIGN(8) z_keyexpr_t { + uint8_t _0[8]; +} z_keyexpr_t; /** - * A reader for payload data. + * Options passed to the :c:func:`z_declare_publisher` function. + * + * Members: + * z_congestion_control_t congestion_control: The congestion control to apply when routing messages from this publisher. + * z_priority_t priority: The priority of messages from this publisher. */ -typedef struct ALIGN(8) zc_owned_payload_reader { - uint8_t _0[24]; -} zc_owned_payload_reader; +typedef struct z_publisher_options_t { + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; +} z_publisher_options_t; -typedef struct ALIGN(8) zc_payload_reader { - uint8_t _0[8]; -} zc_payload_reader; +/** + * An owned zenoh publisher. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_publisher_t { + uint8_t _0[56]; +} z_owned_publisher_t; /** - * An owned sample. + * Options passed to the :c:func:`z_declare_queryable` function. * - * This is a read only type that can only be constructed by cloning a `z_sample_t`. - * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + * Members: + * bool complete: The completeness of the Queryable. */ -typedef struct ALIGN(8) zc_owned_sample_t { - uint8_t _0[240]; -} zc_owned_sample_t; +typedef struct z_queryable_options_t { + bool complete; +} z_queryable_options_t; -extern const unsigned int Z_ROUTER; +/** + * An owned zenoh queryable. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_queryable_t { + uint8_t _0[32]; +} z_owned_queryable_t; -extern const unsigned int Z_PEER; +typedef struct ALIGN(8) z_owned_encoding_t { + uint8_t _0[48]; +} z_owned_encoding_t; -extern const unsigned int Z_CLIENT; +/** + * The encoding of a payload, in a MIME-like format. + * + * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. + */ +typedef struct ALIGN(8) z_encoding_t { + uint8_t _0[8]; +} z_encoding_t; -extern const char *Z_CONFIG_MODE_KEY; +/** + * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. + */ +typedef struct z_query_consolidation_t { + enum z_consolidation_mode_t mode; +} z_query_consolidation_t; -extern const char *Z_CONFIG_CONNECT_KEY; +/** + * Options passed to the :c:func:`z_get` function. + * + * Members: + * z_query_target_t target: The Queryables that should be target of the query. + * z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. + * z_value_t value: An optional value to attach to the query. + * z_bytes_t attachment: The attachment to attach to the query. + * uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. + */ +typedef struct z_get_options_t { + enum z_query_target_t target; + struct z_query_consolidation_t consolidation; + struct z_owned_bytes_t *payload; + struct z_owned_encoding_t *encoding; + struct z_owned_bytes_t *attachment; + uint64_t timeout_ms; +} z_get_options_t; + +/** + * An borrowed array of borrowed, zenoh allocated, NULL terminated strings. + */ +typedef struct z_str_array_t { + size_t len; + const char *const *val; +} z_str_array_t; -extern const char *Z_CONFIG_LISTEN_KEY; +/** + * A reference-type hello message returned by a zenoh entity to a scout message sent with `z_scout`. + * + * Members: + * unsigned int whatami: The kind of zenoh entity. + * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). + * z_owned_str_array_t locators: The locators of the scouted entity. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +typedef struct z_hello_t { + unsigned int whatami; + struct z_id_t pid; + struct z_str_array_t locators; +} z_hello_t; -extern const char *Z_CONFIG_USER_KEY; +typedef struct ALIGN(8) z_publisher_t { + uint8_t _0[8]; +} z_publisher_t; -extern const char *Z_CONFIG_PASSWORD_KEY; +/** + * Represents the set of options that can be applied to the delete operation by a previously declared publisher, + * whenever issued via :c:func:`z_publisher_delete`. + */ +typedef struct z_publisher_delete_options_t { + uint8_t __dummy; +} z_publisher_delete_options_t; + +/** + * Options passed to the :c:func:`z_publisher_put` function. + * + * Members: + * z_owned_encoding_t encoding: The encoding of the payload. + * z_owned_bytes_t attachment: The attachment to attach to the publication. + */ +typedef struct z_publisher_put_options_t { + struct z_owned_encoding_t *encoding; + struct z_owned_bytes_t *attachment; +} z_publisher_put_options_t; + +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * - `this` is a pointer to an arbitrary state. + * - `call` is the typical callback function. `this` will be passed as its last argument. + * - `drop` allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * We guarantee that: + * - `call` will never be called once `drop` has started. + * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_query_channel_closure_t { + void *context; + bool (*call)(struct z_owned_query_t*, void*); + void (*drop)(void*); +} z_owned_query_channel_closure_t; + +/** + * A pair of closures + */ +typedef struct z_owned_query_channel_t { + struct z_owned_closure_query_t send; + struct z_owned_query_channel_closure_t recv; +} z_owned_query_channel_t; + +/** + * Represents the set of options that can be applied to a query reply, + * sent via :c:func:`z_query_reply`. + * + * Members: + * z_owned_encoding_t encoding: The encoding of the payload. + * z_owned_bytes_t attachment: The attachment to this reply. + */ +typedef struct z_query_reply_options_t { + struct z_owned_encoding_t *encoding; + struct z_owned_bytes_t *attachment; +} z_query_reply_options_t; + +typedef struct ALIGN(8) z_value_t { + uint8_t _0[8]; +} z_value_t; + +/** + * An owned reply to a :c:func:`z_get`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_reply_t { + uint8_t _0[256]; +} z_owned_reply_t; + +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * - `this` is a pointer to an arbitrary state. + * - `call` is the typical callback function. `this` will be passed as its last argument. + * - `drop` allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * We guarantee that: + * - `call` will never be called once `drop` has started. + * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_reply_channel_closure_t { + void *context; + bool (*call)(struct z_owned_reply_t*, void*); + void (*drop)(void*); +} z_owned_reply_channel_closure_t; + +/** + * A pair of closures, the `send` one accepting + */ +typedef struct z_owned_reply_channel_t { + struct z_owned_closure_reply_t send; + struct z_owned_reply_channel_closure_t recv; +} z_owned_reply_channel_t; + +typedef struct ALIGN(8) z_timestamp_t { + uint8_t _0[24]; +} z_timestamp_t; + +typedef struct z_owned_scouting_config_t { + struct z_owned_config_t _config; + unsigned long zc_timeout_ms; + uint8_t zc_what; +} z_owned_scouting_config_t; + +/** + * The body of a loop over a z_slice_map's key-value pairs. + * + * `key` and `value` are loaned to the body for the duration of a single call. + * `context` is passed transparently through the iteration driver. + * + * Returning `true` is treated as `continue`. + */ +typedef bool (*z_slice_map_iter_body_t)(struct z_slice_t key, struct z_slice_t value, void *context); + +/** + * An owned sample. + * + * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + */ +typedef struct ALIGN(8) zc_owned_sample_t { + uint8_t _0[240]; +} zc_owned_sample_t; + +/** + * A struct that indicates if there exist Subscribers matching the Publisher's key expression. + * + * Members: + * bool matching: true if there exist Subscribers matching the Publisher's key expression. + */ +typedef struct zcu_matching_status_t { + bool matching; +} zcu_matching_status_t; + +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct zcu_owned_closure_matching_status_t { + void *context; + void (*call)(const struct zcu_matching_status_t*, void*); + void (*drop)(void*); +} zcu_owned_closure_matching_status_t; + +/** + * An owned zenoh matching listener. Destroying the matching listener cancels the subscription. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) zcu_owned_matching_listener_t { + uint8_t _0[40]; +} zcu_owned_matching_listener_t; + +#define Z_OK 0 + +#define Z_EINVAL -1 + +#define Z_EPARSE -2 + +#define Z_EIO -3 + +#define Z_ENETWORK -4 + +#define Z_EGENERIC INT8_MIN + +extern const unsigned int Z_ROUTER; + +extern const unsigned int Z_PEER; + +extern const unsigned int Z_CLIENT; + +extern const char *Z_CONFIG_MODE_KEY; + +extern const char *Z_CONFIG_CONNECT_KEY; + +extern const char *Z_CONFIG_LISTEN_KEY; + +extern const char *Z_CONFIG_USER_KEY; + +extern const char *Z_CONFIG_PASSWORD_KEY; extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; @@ -159,205 +806,956 @@ extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; /** - * Returns `true` if the buffer is in a valid state. + * Returns `true` if the payload is in a valid state. + */ +ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *payload); + +/** + * Increments the payload's reference count, returning an owned version of it. + */ +ZENOHC_API void z_bytes_clone(const struct z_owned_bytes_t *src, struct z_owned_bytes_t *dst); + +/** + * Decodes payload into owned bytes + */ +ZENOHC_API ZCError z_bytes_decode_into_bytes(struct z_bytes_t payload, struct z_owned_slice_t *dst); + +/** + * Decodes payload into bytes map. + */ +ZENOHC_API +ZCError z_bytes_decode_into_bytes_map(struct z_bytes_t payload, + struct z_owned_slice_map_t *dst); + +/** + * Decodes payload into null-terminated string. + */ +ZENOHC_API ZCError z_bytes_decode_into_string(struct z_bytes_t payload, struct z_owned_str_t *dst); + +/** + * Decrements the payload's reference counter, destroying it if applicable. + * + * `this` will be reset to `z_buffer_null`, preventing UB on double-frees. + */ +ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); + +/** + * Encodes byte sequence by aliasing. + */ +ZENOHC_API void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, struct z_slice_t bytes); + +/** + * Encodes bytes map by copying. + */ +ZENOHC_API +void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, + struct z_slice_map_t bytes_map); + +/** + * Encodes a null-terminated string by aliasing. + */ +ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const char *cstr); + +/** + * Returns total number bytes in the payload. + */ +ZENOHC_API size_t z_bytes_len(struct z_bytes_t payload); + +/** + * Loans the payload, allowing you to call functions that only need a loan of it. + */ +ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *payload); + +/** + * The gravestone value for `z_owned_bytes_t`. + */ +ZENOHC_API void z_bytes_null(struct z_owned_bytes_t *this_); + +ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_t_reader_t *reader); + +ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_t_reader_t *this_); + +ZENOHC_API +struct z_bytes_reader_t z_bytes_reader_loan(const struct z_owned_bytes_t_reader_t *reader); + +/** + * Creates a reader for the specified `payload`. + * + * Returns 0 in case of success, -1 if `payload` is not valid. + */ +ZENOHC_API +void z_bytes_reader_new(struct z_bytes_t payload, + struct z_owned_bytes_t_reader_t *this_); + +ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_t_reader_t *this_); + +/** + * Reads data into specified destination. + * + * Will read at most `len` bytes. + * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. + */ +ZENOHC_API +size_t z_bytes_reader_read(struct z_bytes_reader_t reader, + uint8_t *dest, + size_t len); + +/** + * Sets the `reader` position indicator for the payload to the value pointed to by offset. + * The new position is exactly offset bytes measured from the beginning of the payload if origin is SEEK_SET, + * from the current reader position if origin is SEEK_CUR, and from the end of the payload if origin is SEEK_END. + * Return ​0​ upon success, negative error code otherwise. + */ +ZENOHC_API +ZCError z_bytes_reader_seek(struct z_bytes_reader_t reader, + int64_t offset, + int origin); + +/** + * Returns the read position indicator. + * Returns read position indicator on success or -1L if failure occurs. + */ +ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t reader); + +/** + * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * + * Returns a negative value if an error occured while closing the session. + * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + */ +ZENOHC_API int8_t z_close(struct z_owned_session_t *session); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_hello_call(const struct z_owned_closure_hello_t *closure, + struct z_owned_hello_t *hello); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_hello_drop(struct z_owned_closure_hello_t *closure); + +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_hello_t' type + */ +ZENOHC_API struct z_owned_closure_hello_t z_closure_hello_null(void); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_owned_query_call(const struct z_owned_closure_owned_query_t *closure, + struct z_owned_query_t *query); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_owned_query_drop(struct z_owned_closure_owned_query_t *closure); + +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type + */ +ZENOHC_API struct z_owned_closure_owned_query_t z_closure_owned_query_null(void); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_query_call(const struct z_owned_closure_query_t *closure, + struct z_query_t query); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_query_drop(struct z_owned_closure_query_t *closure); + +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type + */ +ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_reply_call(const struct z_owned_closure_reply_t *closure, + struct z_reply_t reply); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_reply_drop(struct z_owned_closure_reply_t *closure); + +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_reply_t' type + */ +ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, + const struct z_sample_t *sample); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_sample_drop(struct z_owned_closure_sample_t *closure); + +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_sample_t' type + */ +ZENOHC_API struct z_owned_closure_sample_t z_closure_sample_null(void); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_zid_call(const struct z_owned_closure_zid_t *closure, + const struct z_id_t *sample); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_zid_drop(struct z_owned_closure_zid_t *closure); + +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_zid_t' type + */ +ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); + +/** + * Returns ``true`` if `config` is valid. + */ +ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); + +/** + * Constructs a default, zenoh-allocated, client mode configuration. + * If `peer` is not null, it is added to the configuration as remote peer. + */ +ZENOHC_API +ZCError z_config_client(const char *const *peers, + size_t n_peers, + struct z_owned_config_t *this_); + +/** + * Clones the config. + */ +ZENOHC_API void z_config_clone(const struct z_config_t *src, struct z_owned_config_t *dst); + +/** + * Frees `config`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_config_drop(struct z_owned_config_t *config); + +/** + * Returns a :c:type:`z_config_t` loaned from `s`. + */ +ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); + +/** + * Return a new, zenoh-allocated, empty configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +ZENOHC_API +void z_config_new(struct z_owned_config_t *this_); + +/** + * Constructs a null safe-to-drop value of 'z_owned_config_t' type + */ +ZENOHC_API void z_config_null(struct z_owned_config_t *this_); + +/** + * Constructs a default, zenoh-allocated, peer mode configuration. + */ +ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); + +/** + * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. + * + * This numerical id will be used on the network to save bandwidth and + * ease the retrieval of the concerned resource in the routing tables. + */ +ZENOHC_API +ZCError z_declare_keyexpr(struct z_owned_keyexpr_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr); + +/** + * Declares a publisher for the given key expression. + * + * Data can be put and deleted with this publisher with the help of the + * :c:func:`z_publisher_put` and :c:func:`z_publisher_delete` functions. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to publish. + * options: additional options for the publisher. + * + * Returns: + * A :c:type:`z_owned_publisherr_t`. + * + * To check if the publisher decalration succeeded and if the publisher is still valid, + * you may use `z_publisher_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * Example: + * Declaring a publisher passing `NULL` for the options: + * + * .. code-block:: C + * + * z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(expr), NULL); + * + * is equivalent to initializing and passing the default publisher options: + * + * .. code-block:: C + * + * z_publisher_options_t opts = z_publisher_options_default(); + * z_owned_publisher_t sub = z_declare_publisher(z_loan(s), z_keyexpr(expr), &opts); + */ +ZENOHC_API +ZCError z_declare_publisher(struct z_session_t session, + struct z_keyexpr_t key_expr, + const struct z_publisher_options_t *options, + struct z_owned_publisher_t *this_); + +/** + * Creates a Queryable for the given key expression. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression the Queryable will reply to. + * callback: The callback function that will be called each time a matching query is received. + * options: Options for the queryable. + * + * Returns: + * The created :c:type:`z_owned_queryable_t` or ``null`` if the creation failed. + */ +ZENOHC_API +ZCError z_declare_queryable(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_query_t *callback, + const struct z_queryable_options_t *options, + struct z_owned_queryable_t *this_); + +/** + * Returns ``true`` if `encoding` is valid. + */ +ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); + +/** + * Constructs a default :c:type:`z_encoding_t`. + */ +ZENOHC_API struct z_encoding_t z_encoding_default(void); + +/** + * Frees `encoding`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); + +/** + * Constructs a specific :c:type:`z_encoding_t`. + */ +ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); + +/** + * Returns a :c:type:`z_encoding_t` loaned from `encoding`. + */ +ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); + +/** + * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type + */ +ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); + +/** + * Query data from the matching queryables in the system. + * Replies are provided through a callback function. + * + * Returns a negative value upon failure. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression matching resources to query. + * parameters: The query's parameters, similar to a url's query segment. + * callback: The callback function that will be called on reception of replies for this query. + * Note that the `reply` parameter of the callback is passed by mutable reference, + * but **will** be dropped once your callback exits to help you avoid memory leaks. + * If you'd rather take ownership, please refer to the documentation of :c:func:`z_reply_null` + * options: additional options for the get. + */ +ZENOHC_API +ZCError z_get(struct z_session_t session, + struct z_keyexpr_t key_expr, + const char *parameters, + struct z_owned_closure_reply_t *callback, + struct z_get_options_t options); + +ZENOHC_API struct z_get_options_t z_get_options_default(void); + +/** + * Returns ``true`` if `hello` is valid. + */ +ZENOHC_API bool z_hello_check(const struct z_owned_hello_t *hello); + +/** + * Frees `hello`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_hello_drop(struct z_owned_hello_t *hello); + +/** + * Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. + */ +ZENOHC_API struct z_hello_t z_hello_loan(const struct z_owned_hello_t *hello); + +/** + * Constructs a gravestone value for hello, useful to steal one from a callback + */ +ZENOHC_API struct z_owned_hello_t z_hello_null(void); + +/** + * Fetches the Zenoh IDs of all connected peers. + * + * `callback` will be called once for each ID, is guaranteed to never be called concurrently, + * and is guaranteed to be dropped before this function exits. + * + * Retuns 0 on success, negative values on failure + */ +ZENOHC_API +ZCError z_info_peers_zid(struct z_session_t session, + struct z_owned_closure_zid_t *callback); + +/** + * Fetches the Zenoh IDs of all connected routers. + * + * `callback` will be called once for each ID, is guaranteed to never be called concurrently, + * and is guaranteed to be dropped before this function exits. + * + * Retuns 0 on success, negative values on failure. + */ +ZENOHC_API +ZCError z_info_routers_zid(struct z_session_t session, + struct z_owned_closure_zid_t *callback); + +/** + * Returns the local Zenoh ID. + * + * Unless the `session` is invalid, that ID is guaranteed to be non-zero. + * In other words, this function returning an array of 16 zeros means you failed + * to pass it a valid session. + */ +ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); + +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API ZCError z_keyexpr(struct z_owned_keyexpr_t *this_, const char *name); + +/** + * Returns the key expression's internal string by aliasing it. + * + * Currently exclusive to zenoh-c + */ +ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(struct z_keyexpr_t ke); + +/** + * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. + * The string is canonized in-place before being passed to keyexpr. + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +ZCError z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, + char *name); + +/** + * Canonizes the passed string in place, possibly shortening it by modifying `len`. + * + * Returns ``0`` upon success, negative values upon failure. + * Returns a negative value if canonization failed, which indicates that the passed string was an invalid + * key expression for reasons other than a non-canon form. + * + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +ZCError z_keyexpr_canonize(char *start, + size_t *len); + +/** + * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. + * + * Returns ``0`` upon success, negative values upon failure. + * Returns a negative value if canonization failed, which indicates that the passed string was an invalid + * key expression for reasons other than a non-canon form. + * + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +ZCError z_keyexpr_canonize_null_terminated(char *start); + +/** + * Returns ``true`` if `keyexpr` is valid. + */ +ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); + +/** + * Performs string concatenation and returns the result as a `z_owned_keyexpr_t`. + * In case of error, the return value will be set to its invalidated state. + * + * You should probably prefer `z_keyexpr_join` as Zenoh may then take advantage of the hierachical separation it inserts. + * + * To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, + * as this would extremely likely cause bugs. + */ +ZENOHC_API +ZCError z_keyexpr_concat(struct z_keyexpr_t left, + const char *right_start, + size_t right_len, + struct z_owned_keyexpr_t *this_); + +/** + * Frees `keyexpr` and invalidates it for double-drop safety. + */ +ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); + +/** + * Returns ``0`` if both ``left`` and ``right`` are equal. + */ +ZENOHC_API bool z_keyexpr_equals(struct z_keyexpr_t left, struct z_keyexpr_t right); + +/** + * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set + * defined by ``right``. + */ +ZENOHC_API +bool z_keyexpr_includes(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the + * sets defined by ``left`` and ``right``. + */ +ZENOHC_API +bool z_keyexpr_intersects(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Returns ``0`` if the passed string is a valid (and canon) key expression. + * Otherwise returns error value + */ +ZENOHC_API ZCError z_keyexpr_is_canon(const char *start, size_t len); + +/** + * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. + * In case of error, the return value will be set to its invalidated state. + */ +ZENOHC_API +ZCError z_keyexpr_join(struct z_keyexpr_t left, + struct z_keyexpr_t right, + struct z_owned_keyexpr_t *this_); + +/** + * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + */ +ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); + +/** + * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. + */ +ZENOHC_API ZCError z_keyexpr_new(const char *name, struct z_owned_keyexpr_t *this_); + +/** + * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. + */ +ZENOHC_API +ZCError z_keyexpr_new_autocanonize(const char *name, + struct z_owned_keyexpr_t *this_); + +/** + * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type + */ +ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); + +/** + * Returns the relation between `left` and `right` from `left`'s point of view. + * + * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. + */ +ZENOHC_API +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, + struct z_keyexpr_t right); + +/** + * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. + * The user is responsible of droping the returned string using `z_drop` + */ +ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t ke); + +/** + * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * + * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. + * - any instance of `**` may only be lead or followed by `/`. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API +void z_keyexpr_unchecked(struct z_owned_keyexpr_t *this_, + const char *name); + +/** + * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + * Config value is always consumed upon function return. + */ +ZENOHC_API +ZCError z_open(struct z_owned_session_t *this_, + struct z_owned_config_t *config); + +/** + * Returns ``true`` if `pub` is valid. + */ +ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); + +/** + * Sends a `DELETE` message onto the publisher's key expression. + * + * Returns: + * ``0`` in case of success, ``1`` in case of failure. + */ +ZENOHC_API +ZCError z_publisher_delete(struct z_publisher_t publisher, + struct z_publisher_delete_options_t _options); + +/** + * Constructs the default values for the delete operation via a publisher entity. + * + * Returns: + * Returns the constructed :c:type:`z_publisher_delete_options_t`. + */ +ZENOHC_API struct z_publisher_delete_options_t z_publisher_delete_options_default(void); + +/** + * Returns the key expression of the publisher + */ +ZENOHC_API struct z_keyexpr_t z_publisher_keyexpr(struct z_publisher_t publisher); + +/** + * Returns a :c:type:`z_publisher_t` loaned from `p`. + */ +ZENOHC_API struct z_publisher_t z_publisher_loan(const struct z_owned_publisher_t *p); + +/** + * Constructs a null safe-to-drop value of 'z_owned_publisher_t' type + */ +ZENOHC_API void z_publisher_null(struct z_owned_publisher_t *this_); + +/** + * Constructs the default value for :c:type:`z_publisher_options_t`. + */ +ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); + +/** + * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. + * + * This is avoids copies when transfering data that was either: + * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher + * - constructed from a `zc_owned_shmbuf_t` + * + * The payload and all owned options fields are consumed upon function return. + * + * Parameters: + * session: The zenoh session. + * payload: The value to put. + * options: The publisher put options. + * Returns: + * ``0`` in case of success, negative values in case of failure. */ -ZENOHC_API bool z_buffer_check(const struct z_owned_buffer_t *buffer); +ZENOHC_API +ZCError z_publisher_put(struct z_publisher_t publisher, + struct z_owned_bytes_t *payload, + struct z_publisher_put_options_t options); /** - * Increments the buffer's reference count, returning an owned version of the buffer. + * Constructs the default value for :c:type:`z_publisher_put_options_t`. */ -ZENOHC_API void z_buffer_clone(struct z_owned_buffer_t *dst, const struct z_owned_buffer_t *buffer); +ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); /** - * Decrements the buffer's reference counter, destroying it if applicable. + * Gets the attachment to the query by aliasing. * - * `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. + * Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. */ -ZENOHC_API void z_buffer_drop(struct z_owned_buffer_t *buffer); +ZENOHC_API struct z_bytes_t z_query_attachment(struct z_query_t query); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +bool z_query_channel_closure_call(const struct z_owned_query_channel_closure_t *closure, + struct z_owned_query_t *query); /** - * Returns total number bytes in the buffer. + * Drops the closure. Droping an uninitialized closure is a no-op. */ -ZENOHC_API size_t z_buffer_len(struct z_buffer_t buffer); +ZENOHC_API void z_query_channel_closure_drop(struct z_owned_query_channel_closure_t *closure); /** - * Loans the buffer, allowing you to call functions that only need a loan of it. + * Constructs a null safe-to-drop value of 'z_owned_query_channel_closure_t' type */ -ZENOHC_API struct z_buffer_t z_buffer_loan(const struct z_owned_buffer_t *buffer); +ZENOHC_API struct z_owned_query_channel_closure_t z_query_channel_closure_null(void); + +ZENOHC_API void z_query_channel_drop(struct z_owned_query_channel_t *channel); /** - * The gravestone value for `z_owned_buffer_t`. + * Constructs a null safe-to-drop value of 'z_owned_query_channel_t' type */ -ZENOHC_API void z_buffer_null(struct z_owned_buffer_t *this_); +ZENOHC_API struct z_owned_query_channel_t z_query_channel_null(void); /** - * Returns the `index`th slice of the buffer, aliasing it. + * Returns `false` if `this` is in a gravestone state, `true` otherwise. * - * Out of bounds accesses will return `z_bytes_empty`. + * This function may not be called with the null pointer, but can be called with the gravestone value. */ -ZENOHC_API struct z_bytes_t z_buffer_slice_at(struct z_buffer_t buffer, size_t index); +ZENOHC_API +bool z_query_check(const struct z_owned_query_t *query); /** - * Returns the number of slices in the buffer. + * Clones the query, allowing to keep it in an "open" state past the callback's return. * - * If the return value is 0 or 1, then the buffer's data is contiguous in memory. + * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). */ -ZENOHC_API size_t z_buffer_slice_count(struct z_buffer_t buffer); +ZENOHC_API +void z_query_clone(struct z_owned_query_t *this_, + struct z_query_t query); /** - * Returns ``true`` if `b` is initialized. + * Automatic query consolidation strategy selection. + * + * A query consolidation strategy will automatically be selected depending the query selector. + * If the selector contains time range properties, no consolidation is performed. + * Otherwise the :c:func:`z_query_consolidation_latest` strategy is used. + * + * Returns: + * Returns the constructed :c:type:`z_query_consolidation_t`. + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_auto(void); + +/** + * Creates a default :c:type:`z_query_consolidation_t` (consolidation mode AUTO). */ -ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *b); +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_default(void); -ZENOHC_API struct z_owned_bytes_t z_bytes_clone(const struct z_bytes_t *b); +/** + * Latest value consolidation. + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_latest(void); /** - * Returns the gravestone value for `z_bytes_t` + * Monotonic consolidation. */ -ZENOHC_API struct z_bytes_t z_bytes_empty(void); +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_monotonic(void); /** - * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). - * - * `str == NULL` will cause this to return `z_bytes_empty()` + * Disable consolidation. */ -ZENOHC_API struct z_bytes_t z_bytes_from_str(const char *str); +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_none(void); /** - * Returns ``true`` if `b` is initialized. + * Destroys the query, setting `this` to its gravestone value to prevent double-frees. + * + * This function may not be called with the null pointer, but can be called with the gravestone value. */ -ZENOHC_API bool z_bytes_is_initialized(const struct z_bytes_t *b); +ZENOHC_API +void z_query_drop(struct z_owned_query_t *this_); -ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *b); +/** + * Get a query's key by aliasing it. + */ +ZENOHC_API struct z_keyexpr_t z_query_keyexpr(struct z_query_t query); /** - * Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * Aliases the query. * - * `str == NULL` will cause this to return `z_bytes_empty()` + * This function may not be called with the null pointer, but can be called with the gravestone value. */ ZENOHC_API -struct z_bytes_t z_bytes_new(const char *str); +struct z_query_t z_query_loan(const struct z_owned_query_t *this_); /** - * Returns the gravestone value for `z_owned_bytes_t` + * The gravestone value of `z_owned_query_t`. */ -ZENOHC_API struct z_owned_bytes_t z_bytes_null(void); +ZENOHC_API void z_query_null(struct z_owned_query_t *this_); /** - * Constructs a `len` bytes long view starting at `start`. + * Get a query's `value selector `_ by aliasing it. */ -ZENOHC_API struct z_bytes_t z_bytes_wrap(const uint8_t *start, size_t len); +ZENOHC_API +struct z_slice_t z_query_parameters(struct z_query_t query); /** - * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * Send a reply to a query. * - * Returns a negative value if an error occured while closing the session. - * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + * This function must be called inside of a Queryable callback passing the + * query received as parameters of the callback function. This function can + * be called multiple times to send multiple replies to a query. The reply + * will be considered complete when the Queryable callback returns. + * + * Parameters: + * query: The query to reply to. + * key_expr: The key of this reply. + * payload: The value of this reply. + * options: The options of this reply. + * + * The payload and all owned options fields are consumed upon function return. */ -ZENOHC_API int8_t z_close(struct z_owned_session_t *session); +ZENOHC_API +ZCError z_query_reply(struct z_query_t query, + struct z_keyexpr_t key_expr, + struct z_owned_bytes_t *payload, + struct z_query_reply_options_t options); /** - * Returns ``true`` if `config` is valid. + * Constructs the default value for :c:type:`z_query_reply_options_t`. */ -ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); +ZENOHC_API struct z_query_reply_options_t z_query_reply_options_default(void); /** - * Constructs a default, zenoh-allocated, client mode configuration. - * If `peer` is not null, it is added to the configuration as remote peer. + * Create a default :c:type:`z_query_target_t`. */ -ZENOHC_API struct z_owned_config_t z_config_client(const char *const *peers, size_t n_peers); +ZENOHC_API enum z_query_target_t z_query_target_default(void); /** - * Creates a default, zenoh-allocated, configuration. + * Gets a query's `payload value `_ by aliasing it. + * + * **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** + * Before calling this funciton, the user must ensure that `z_query_has_value` returns true. */ -ZENOHC_API struct z_owned_config_t z_config_default(void); +ZENOHC_API +struct z_value_t z_query_value(struct z_query_t query); /** - * Frees `config`, invalidating it for double-drop safety. + * Returns ``true`` if `qable` is valid. */ -ZENOHC_API void z_config_drop(struct z_owned_config_t *config); +ZENOHC_API bool z_queryable_check(const struct z_owned_queryable_t *qable); /** - * Returns a :c:type:`z_config_t` loaned from `s`. + * Constructs a null safe-to-drop value of 'z_owned_queryable_t' type */ -ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); +ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); /** - * Return a new, zenoh-allocated, empty configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * Constructs the default value for :c:type:`z_query_reply_options_t`. + */ +ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); + +/** + * Calls the closure. Calling an uninitialized closure is a no-op. */ ZENOHC_API -void z_config_new(struct z_owned_config_t *this_); +bool z_reply_channel_closure_call(const struct z_owned_reply_channel_closure_t *closure, + struct z_owned_reply_t *reply); /** - * Constructs a null safe-to-drop value of 'z_owned_config_t' type + * Drops the closure. Droping an uninitialized closure is a no-op. */ -ZENOHC_API void z_config_null(struct z_owned_config_t *this_); +ZENOHC_API void z_reply_channel_closure_drop(struct z_owned_reply_channel_closure_t *closure); /** - * Constructs a default, zenoh-allocated, peer mode configuration. + * Constructs a null safe-to-drop value of 'z_owned_reply_channel_closure_t' type */ -ZENOHC_API struct z_owned_config_t z_config_peer(void); +ZENOHC_API struct z_owned_reply_channel_closure_t z_reply_channel_closure_null(void); + +ZENOHC_API void z_reply_channel_drop(struct z_owned_reply_channel_t *channel); /** - * Returns ``true`` if `encoding` is valid. + * Constructs a null safe-to-drop value of 'z_owned_reply_channel_t' type */ -ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); +ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); /** - * Constructs a default :c:type:`z_encoding_t`. + * Returns ``true`` if `reply` is valid. */ -ZENOHC_API struct z_encoding_t z_encoding_default(void); +ZENOHC_API bool z_reply_check(const struct z_owned_reply_t *this_); + +ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, struct z_reply_t reply); /** - * Frees `encoding`, invalidating it for double-drop safety. + * Frees `reply`, invalidating it for double-drop safety. */ -ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); +ZENOHC_API void z_reply_drop(struct z_owned_reply_t *this_); /** - * Constructs a specific :c:type:`z_encoding_t`. + * Yields the contents of the reply by asserting it indicates a failure. + * + * You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. */ -ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); +ZENOHC_API +struct z_value_t z_reply_err(struct z_reply_t reply); /** - * Returns a :c:type:`z_encoding_t` loaned from `encoding`. + * Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. + * + * If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. */ -ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); +ZENOHC_API +bool z_reply_is_ok(struct z_reply_t reply); /** - * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type + * Returns an invalidated :c:type:`z_owned_reply_t`. + * + * This is useful when you wish to take ownership of a value from a callback to :c:func:`z_get`: + * + * - copy the value of the callback's argument's pointee, + * - overwrite the pointee with this function's return value, + * - you are now responsible for dropping your copy of the reply. */ -ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); +ZENOHC_API void z_reply_null(struct z_owned_reply_t *this_); /** - * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + * Yields the contents of the reply by asserting it indicates a success. + * + * You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. */ ZENOHC_API -int8_t z_open(struct z_owned_session_t *this_, - struct z_owned_config_t *config); +struct z_sample_t z_reply_ok(struct z_reply_t reply); /** - * The qos with which the sample was received. - * TODO: split to methods (priority, congestion_control, express) - * The sample's attachment. + * Gets sample's attachment. * - * `sample` is aliased by the return value. + * Before calling this function, ensure that `zc_sample_has_attachment` returns true */ -ZENOHC_API z_attachment_t z_sample_attachment(const struct z_sample_t *sample); +ZENOHC_API struct z_bytes_t z_sample_attachment(struct z_sample_t sample); /** * The encoding of the payload. */ ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); +/** + * The qos with which the sample was received. + * TODO: split to methods (priority, congestion_control, express) + * Checks if sample contains an attachment. + */ +ZENOHC_API bool z_sample_has_attachment(struct z_sample_t sample); + /** * The Key Expression of the sample. * @@ -371,24 +1769,45 @@ ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); /** - * Returns the sample's payload after incrementing its internal reference count. + * The sample's data, the return value aliases the sample. * - * Note that other samples may have received the same buffer, meaning that mutating this buffer may - * affect the samples received by other subscribers. */ -ZENOHC_API zc_owned_payload_t z_sample_owned_payload(const struct z_sample_t *sample); +ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); /** - * The sample's data, the return value aliases the sample. + * The samples timestamp * - * If you need ownership of the buffer, you may use `z_sample_owned_payload`. + * Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. */ -ZENOHC_API zc_payload_t z_sample_payload(const struct z_sample_t *sample); +ZENOHC_API +bool z_sample_timestamp(const struct z_sample_t *sample, + struct z_timestamp_t *timestamp_out); /** - * The samples timestamp + * Scout for routers and/or peers. + * + * Parameters: + * what: A whatami bitmask of zenoh entities kind to scout for. + * config: A set of properties to configure the scouting. + * timeout: The time (in milliseconds) that should be spent scouting. + * + * Returns 0 if successful, negative values upon failure. */ -ZENOHC_API struct z_timestamp_t z_sample_timestamp(const struct z_sample_t *sample); +ZENOHC_API +ZCError z_scout(struct z_owned_scouting_config_t *config, + struct z_owned_closure_hello_t *callback); + +ZENOHC_API bool z_scouting_config_check(const struct z_owned_scouting_config_t *config); + +ZENOHC_API void z_scouting_config_default(struct z_owned_scouting_config_t *this_); + +ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); + +ZENOHC_API +void z_scouting_config_from(struct z_config_t config, + struct z_owned_scouting_config_t *this_); + +ZENOHC_API void z_scouting_config_null(struct z_owned_scouting_config_t *this_); /** * Returns ``true`` if `session` is valid. @@ -413,6 +1832,130 @@ struct z_session_t z_session_loan(const struct z_owned_session_t *s); */ ZENOHC_API void z_session_null(struct z_owned_session_t *s); +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *b); + +ZENOHC_API struct z_owned_slice_t z_slice_clone(const struct z_slice_t *b); + +/** + * Returns the gravestone value for `z_slice_t` + */ +ZENOHC_API struct z_slice_t z_slice_empty(void); + +/** + * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * `str == NULL` will cause this to return `z_slice_empty()` + */ +ZENOHC_API struct z_slice_t z_slice_from_str(const char *str); + +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_slice_is_initialized(const struct z_slice_t *b); + +ZENOHC_API struct z_slice_t z_slice_loan(const struct z_owned_slice_t *b); + +/** + * Returns `true` if the map is not in its gravestone state + */ +ZENOHC_API bool z_slice_map_check(const struct z_owned_slice_map_t *map); + +/** + * Destroys the map, resetting `this` to its gravestone value. + * + * This function is double-free safe, passing a pointer to the gravestone value will have no effect. + */ +ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); + +/** + * Returns the value associated with `key`, returning a gravestone value if: + * - `key` is in gravestone state. + */ +ZENOHC_API struct z_slice_t z_slice_map_get(struct z_slice_map_t this_, struct z_slice_t key); + +/** + * Associates `value` to `key` in the map, aliasing them. + * + * Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. + * + * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. + */ +ZENOHC_API +ZCError z_slice_map_insert_by_alias(struct z_slice_map_t this_, + struct z_slice_t key, + struct z_slice_t value); + +/** + * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. + * + * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. + */ +ZENOHC_API +ZCError z_slice_map_insert_by_copy(struct z_slice_map_t this_, + struct z_slice_t key, + struct z_slice_t value); + +/** + * Returns true if the map is empty, false otherwise. + */ +ZENOHC_API bool z_slice_map_is_empty(struct z_slice_map_t this_); + +ZENOHC_API +void z_slice_map_iterate(const struct z_slice_map_t *this_, + z_slice_map_iter_body_t body, + void *context); + +/** + * Returns number of key-value pairs in the map. + */ +ZENOHC_API size_t z_slice_map_len(struct z_slice_map_t this_); + +/** + * Constructs a new empty map. + */ +ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); + +/** + * Constructs the gravestone value for `z_owned_slice_map_t` + */ +ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); + +/** + * Deprecated in favor of `z_slice_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * `str == NULL` will cause this to return `z_slice_empty()` + */ +ZENOHC_API +struct z_slice_t z_slice_new(const char *str); + +/** + * Returns the gravestone value for `z_owned_slice_t` + */ +ZENOHC_API struct z_owned_slice_t z_slice_null(void); + +/** + * Constructs a `len` bytes long view starting at `start`. + */ +ZENOHC_API struct z_slice_t z_slice_wrap(const uint8_t *start, size_t len); + +/** + * Returns ``true`` if `strs` is valid. + */ +ZENOHC_API bool z_str_array_check(const struct z_owned_str_array_t *strs); + +/** + * Frees `strs` and invalidates it for double-drop safety. + */ +ZENOHC_API void z_str_array_drop(struct z_owned_str_array_t *strs); + +/** + * Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. + */ +ZENOHC_API struct z_str_array_t z_str_array_loan(const struct z_owned_str_array_t *strs); + /** * Returns ``true`` if `s` is a valid string */ @@ -433,16 +1976,49 @@ ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); */ ZENOHC_API struct z_owned_str_t z_str_null(void); +ZENOHC_API struct z_id_t z_timestamp_get_id(const struct z_timestamp_t *timestamp); + +ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp); + +/** + * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. + * The keyxpr is consumed. + */ +ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); + +/** + * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError z_undeclare_publisher(struct z_owned_publisher_t *publisher); + +/** + * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. + * + * Parameters: + * qable: The :c:type:`z_owned_queryable_t` to undeclare. + */ +ZENOHC_API ZCError z_undeclare_queryable(struct z_owned_queryable_t *qable); + /** - * Returns ``true`` if `ts` is a valid timestamp + * Converts the kind of zenoh entity into a string. + * + * Parameters: + * whatami: A whatami bitmask of zenoh entity kind. + * buf: Buffer to write a null-terminated string to. + * len: Maximum number of bytes that can be written to the `buf`. + * + * Returns 0 if successful, negative values if whatami contains an invalid bitmask or `buf` is null, + * or number of remaining bytes, if the null-terminated string size exceeds `len`. */ -ZENOHC_API bool z_timestamp_check(struct z_timestamp_t ts); +ZENOHC_API int8_t z_whatami_to_str(uint8_t whatami, char *buf, size_t len); /** * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. */ ZENOHC_API -struct z_owned_config_t zc_config_from_file(const char *path); +ZCError zc_config_from_file(const char *path, + struct z_owned_config_t *this_); /** * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. @@ -450,7 +2026,8 @@ struct z_owned_config_t zc_config_from_file(const char *path); * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). */ ZENOHC_API -struct z_owned_config_t zc_config_from_str(const char *s); +ZCError zc_config_from_str(const char *s, + struct z_owned_config_t *this_); /** * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. @@ -485,83 +2062,93 @@ struct z_owned_str_t zc_config_to_string(struct z_config_t config); ZENOHC_API void zc_init_logger(void); /** - * Returns `false` if `payload` is the gravestone value. - */ -ZENOHC_API bool zc_payload_check(const zc_owned_payload_t *payload); - -/** - * Increments internal payload reference count, returning owned payload. - */ -ZENOHC_API void zc_payload_clone(zc_owned_payload_t *dst, const zc_owned_payload_t *payload); - -/** - * Decodes payload into null-terminated string - */ -ZENOHC_API int8_t zc_payload_decode_into_bytes(zc_payload_t payload, struct z_owned_bytes_t *b); - -/** - * Decodes payload into null-terminated string - */ -ZENOHC_API int8_t zc_payload_decode_into_string(zc_payload_t payload, struct z_owned_str_t *cstr); - -/** - * Decrements `payload`'s backing refcount, releasing the memory if appropriate. - */ -ZENOHC_API void zc_payload_drop(zc_owned_payload_t *payload); - -/** - * Encodes byte sequence by aliasing. - */ -ZENOHC_API void zc_payload_encode_from_bytes(zc_owned_payload_t *dst, struct z_bytes_t bytes); - -/** - * Encodes a null-terminated string by aliasing. - */ -ZENOHC_API void zc_payload_encode_from_string(zc_owned_payload_t *dst, const char *cstr); - -/** - * Returns total number bytes in the payload. + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. */ -ZENOHC_API size_t zc_payload_len(zc_payload_t payload); +ZENOHC_API +ZCError zc_keyexpr_from_slice(struct z_owned_keyexpr_t *this_, + const char *name, + size_t len); /** - * Returns a :c:type:`zc_payload_t` loaned from `payload`. + * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. + * The string is canonized in-place before being passed to keyexpr. + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). */ -ZENOHC_API zc_payload_t zc_payload_loan(const zc_owned_payload_t *payload); +ZENOHC_API +ZCError zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, + char *name, + size_t *len); /** - * Constructs `zc_owned_payload_t`'s gravestone value. + * Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. + * - any instance of ``**`` may only be lead or followed by ``/``. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. */ -ZENOHC_API void zc_payload_null(zc_owned_payload_t *this_); +ZENOHC_API +void zc_keyexpr_from_slice_unchecked(struct z_owned_keyexpr_t *this_, + const char *start, + size_t len); /** - * Clones the `payload` by incrementing its reference counter. + * Creates a new blocking fifo channel, returned as a pair of closures. + * + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, + * which it will then return; or until the `send` closure is dropped and all queries have been consumed, + * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. */ -ZENOHC_API void zc_payload_rcinc(zc_owned_payload_t *dst, const zc_owned_payload_t *payload); +ZENOHC_API +struct z_owned_query_channel_t zc_query_fifo_new(size_t bound); /** - * Creates a reader for the specified `payload`. + * Creates a new non-blocking fifo channel, returned as a pair of closures. * - * Returns 0 in case of success, -1 if `payload` is not valid. + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, + * which it will then return; or until the `send` closure is dropped and all queries have been consumed, + * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. */ -ZENOHC_API void zc_payload_reader_init(struct zc_owned_payload_reader *this_, zc_payload_t payload); +ZENOHC_API +struct z_owned_query_channel_t zc_query_non_blocking_fifo_new(size_t bound); /** - * Reads data into specified destination. + * Creates a new blocking fifo channel, returned as a pair of closures. * - * Will read at most `len` bytes. - * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, + * which it will then return; or until the `send` closure is dropped and all replies have been consumed, + * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. */ ZENOHC_API -size_t zc_payload_reader_read(struct zc_payload_reader reader, - uint8_t *dest, - size_t len); +struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); /** - * Returns number of the remaining bytes in the payload + * Creates a new non-blocking fifo channel, returned as a pair of closures. + * + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. * + * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, + * which it will then return; or until the `send` closure is dropped and all replies have been consumed, + * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. */ -ZENOHC_API size_t zc_payload_reader_remaining(struct zc_payload_reader reader); +ZENOHC_API +struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); /** * Returns `true` if `sample` is valid. @@ -598,6 +2185,32 @@ ZENOHC_API int8_t zc_session_rcinc(struct z_owned_session_t *dst, const struct z_owned_session_t *src); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void zcu_closure_matching_status_call(const struct zcu_owned_closure_matching_status_t *closure, + const struct zcu_matching_status_t *sample); + +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API +void zcu_closure_matching_status_drop(struct zcu_owned_closure_matching_status_t *closure); + +/** + * Constructs a null safe-to-drop value of 'zcu_owned_closure_matching_status_t' type + */ +ZENOHC_API struct zcu_owned_closure_matching_status_t zcu_closure_matching_status_null(void); + ZENOHC_API enum zcu_locality_t zcu_locality_default(void); +/** + * Register callback for notifying subscribers matching. + */ +ZENOHC_API +ZCError zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, + struct zcu_owned_closure_matching_status_t *callback, + struct zcu_owned_matching_listener_t *this_); + ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 815b2df85..a2d0582b1 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -14,7 +14,7 @@ z_owned_hello_t : z_hello_loan, \ z_owned_str_t : z_str_loan, \ z_owned_query_t : z_query_loan, \ - zc_owned_payload_t : zc_payload_loan, \ + z_owned_bytes_t : z_bytes_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan \ )(&x) @@ -42,8 +42,8 @@ z_owned_query_channel_closure_t * : z_query_channel_closure_drop, \ z_owned_reply_channel_t * : z_reply_channel_drop, \ z_owned_query_channel_t * : z_query_channel_drop, \ - z_owned_bytes_map_t * : z_bytes_map_drop, \ - zc_owned_payload_t * : zc_payload_drop, \ + z_owned_bytes_map_t * : z_slice_map_drop, \ + z_owned_bytes_t * : z_bytes_drop, \ zc_owned_shmbuf_t * : zc_shmbuf_drop, \ zc_owned_shm_manager_t * : zc_shm_manager_drop, \ zc_owned_liveliness_token_t * : zc_liveliness_undeclare_token, \ @@ -73,9 +73,9 @@ zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_null, \ z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ z_owned_reply_channel_t * : z_reply_channel_null, \ - z_owned_bytes_map_t * : z_bytes_map_null, \ - zc_owned_payload_t * : zc_payload_null, \ - z_attachment_t * : z_attachment_null, \ + z_owned_bytes_map_t * : z_slice_map_null, \ + z_owned_bytes_t * : z_bytes_null, \ + z_bytes_t * : z_attachment_null, \ zc_owned_shmbuf_t * : zc_shmbuf_null, \ zc_owned_shm_manager_t * : zc_shm_manager_null, \ ze_owned_publication_cache_t * : ze_publication_cache_null, \ @@ -89,7 +89,7 @@ z_keyexpr_t : z_keyexpr_is_initialized, \ z_owned_config_t : z_config_check, \ z_owned_scouting_config_t : z_scouting_config_check, \ - z_owned_bytes_t : z_bytes_check, \ + z_owned_bytes_t : z_slice_check, \ z_owned_subscriber_t : z_subscriber_check, \ z_owned_pull_subscriber_t : z_pull_subscriber_check, \ z_owned_queryable_t : z_queryable_check, \ @@ -98,9 +98,9 @@ z_owned_hello_t : z_hello_check, \ z_owned_query_t : z_query_check, \ z_owned_str_t : z_str_check, \ - z_owned_bytes_map_t : z_bytes_map_check, \ - zc_owned_payload_t: zc_payload_check, \ - z_attachment_t : z_attachment_check, \ + z_owned_bytes_map_t : z_slice_map_check, \ + z_owned_bytes_t: z_bytes_check, \ + z_bytes_t : z_attachment_check, \ zc_owned_shmbuf_t : zc_shmbuf_check, \ zc_owned_shm_manager_t : zc_shm_manager_check, \ zc_owned_liveliness_token_t : zc_liveliness_token_check, \ @@ -142,7 +142,7 @@ template<> struct zenoh_loan_type{ typedef z_pull_sub template<> struct zenoh_loan_type{ typedef z_encoding_t type; }; template<> struct zenoh_loan_type{ typedef z_hello_t type; }; template<> struct zenoh_loan_type{ typedef const char* type; }; -template<> struct zenoh_loan_type{ typedef zc_payload_t type; }; +template<> struct zenoh_loan_type{ typedef z_bytes_t type; }; template<> struct zenoh_loan_type{ typedef ze_querying_subscriber_t type; }; template<> inline z_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } @@ -155,7 +155,7 @@ template<> inline z_encoding_t z_loan(const z_owned_encoding_t& x) { return z_en template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } -template<> inline zc_payload_t z_loan(const zc_owned_payload& x) { return zc_payload_loan(&x); } +template<> inline z_bytes_t z_loan(const z_owned_bytes_t& x) { return z_bytes_loan(&x); } template<> inline ze_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } template struct zenoh_drop_type { typedef T type; }; @@ -174,8 +174,8 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -204,8 +204,8 @@ template<> inline void z_drop(z_owned_reply_t* v) { z_reply_drop(v); } template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } template<> inline void z_drop(z_owned_query_t* v) { z_query_drop(v); } template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } -template<> inline void z_drop(zc_owned_payload* v) { zc_payload_drop(v); } -template<> inline void z_drop(zc_owned_payload_t* v) { zc_payload_drop(v); } +template<> inline void z_drop(z_owned_bytes_t* v) { z_bytes_drop(v); } +template<> inline void z_drop(z_owned_bytes_t* v) { z_bytes_drop(v); } template<> inline void z_drop(zc_owned_shmbuf_t* v) { zc_shmbuf_drop(v); } template<> inline void z_drop(zc_owned_shm_manager_t* v) { zc_shm_manager_drop(v); } template<> inline void z_drop(z_owned_closure_sample_t* v) { z_closure_sample_drop(v); } @@ -216,7 +216,7 @@ template<> inline void z_drop(z_owned_closure_zid_t* v) { z_closure_zid_drop(v); template<> inline void z_drop(zcu_owned_closure_matching_status_t* v) { zcu_closure_matching_status_drop(v); } template<> inline void z_drop(z_owned_reply_channel_closure_t* v) { z_reply_channel_closure_drop(v); } template<> inline void z_drop(z_owned_reply_channel_t* v) { z_reply_channel_drop(v); } -template<> inline void z_drop(z_owned_bytes_map_t* v) { z_bytes_map_drop(v); } +template<> inline void z_drop(z_owned_bytes_map_t* v) { z_slice_map_drop(v); } template<> inline void z_drop(zc_owned_liveliness_token_t* v) { zc_liveliness_undeclare_token(v); } template<> inline int8_t z_drop(ze_owned_publication_cache_t* v) { return ze_undeclare_publication_cache(v); } template<> inline int8_t z_drop(ze_owned_querying_subscriber_t* v) { return ze_undeclare_querying_subscriber(v); } @@ -234,8 +234,8 @@ inline void z_null(z_owned_reply_t& v) { v = z_reply_null(); } inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } inline void z_null(z_owned_query_t& v) { v = z_query_null(); } inline void z_null(z_owned_str_t& v) { v = z_str_null(); } -inline void z_null(zc_owned_payload& v) { v = zc_payload_null(); } -inline void z_null(zc_owned_payload_t& v) { v = zc_payload_null(); } +inline void z_null(z_owned_bytes_t& v) { v = z_bytes_null(); } +inline void z_null(z_owned_bytes_t& v) { v = z_bytes_null(); } inline void z_null(zc_owned_shmbuf_t& v) { v = zc_shmbuf_null(); } inline void z_null(zc_owned_shm_manager_t& v) { v = zc_shm_manager_null(); } inline void z_null(z_owned_closure_sample_t& v) { v = z_closure_sample_null(); } @@ -246,7 +246,7 @@ inline void z_null(z_owned_closure_zid_t& v) { v = z_closure_zid_null(); } inline void z_null(zcu_owned_closure_matching_status_t& v) { v = zcu_closure_matching_status_null(); } inline void z_null(z_owned_reply_channel_closure_t& v) { v = z_reply_channel_closure_null(); } inline void z_null(z_owned_reply_channel_t& v) { v = z_reply_channel_null(); } -inline void z_null(z_owned_bytes_map_t& v) { v = z_bytes_map_null(); } +inline void z_null(z_owned_bytes_map_t& v) { v = z_slice_map_null(); } inline void z_null(zc_owned_liveliness_token_t& v) { v = zc_liveliness_token_null(); } inline void z_null(ze_owned_publication_cache_t& v) { v = ze_publication_cache_null(); } inline void z_null(ze_owned_querying_subscriber_t& v) { v = ze_querying_subscriber_null(); } @@ -257,8 +257,8 @@ inline bool z_check(const z_owned_keyexpr_t& v) { return z_keyexpr_check(&v); } inline bool z_check(const z_keyexpr_t& v) { return z_keyexpr_is_initialized(&v); } inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } +inline bool z_check(const z_owned_bytes_t& v) { return z_slice_check(&v); } inline bool z_check(const z_owned_bytes_t& v) { return z_bytes_check(&v); } -inline bool z_check(const zc_owned_payload_t& v) { return zc_payload_check(&v); } inline bool z_check(const zc_owned_shmbuf_t& v) { return zc_shmbuf_check(&v); } inline bool z_check(const zc_owned_shm_manager_t& v) { return zc_shm_manager_check(&v); } inline bool z_check(const z_owned_subscriber_t& v) { return z_subscriber_check(&v); } @@ -269,9 +269,9 @@ inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } inline bool z_check(const z_owned_query_t& v) { return z_query_check(&v); } inline bool z_check(const z_owned_str_t& v) { return z_str_check(&v); } -inline bool z_check(const zc_owned_payload& v) { return zc_payload_check(&v); } -inline bool z_check(const z_owned_bytes_map_t& v) { return z_bytes_map_check(&v); } -inline bool z_check(const z_attachment_t& v) { return z_attachment_check(&v); } +inline bool z_check(const z_owned_bytes_t& v) { return z_bytes_check(&v); } +inline bool z_check(const z_owned_bytes_map_t& v) { return z_slice_map_check(&v); } +inline bool z_check(constz_bytes_t& v) { return z_attachment_check(&v); } inline bool z_check(const zc_owned_liveliness_token_t& v) { return zc_liveliness_token_check(&v); } inline bool z_check(const ze_owned_publication_cache_t& v) { return ze_publication_cache_check(&v); } inline bool z_check(const ze_owned_querying_subscriber_t& v) { return ze_querying_subscriber_check(&v); } diff --git a/src/attachment.rs b/src/attachment.rs deleted file mode 100644 index 045596c47..000000000 --- a/src/attachment.rs +++ /dev/null @@ -1,416 +0,0 @@ -use std::{borrow::Cow, cell::UnsafeCell, collections::HashMap}; - -use libc::c_void; - -use crate::{impl_guarded_transmute, z_bytes_empty, z_bytes_t}; - -use zenoh::sample::{Attachment, AttachmentBuilder}; - -/// The body of a loop over an attachment's key-value pairs. -/// -/// `key` and `value` are loaned to the body for the duration of a single call. -/// `context` is passed transparently through the iteration driver. -/// -/// Returning `0` is treated as `continue`. -/// Returning any other value is treated as `break`. -#[allow(non_camel_case_types)] -pub type z_attachment_iter_body_t = - extern "C" fn(key: z_bytes_t, value: z_bytes_t, context: *mut c_void) -> i8; - -/// The driver of a loop over an attachment's key-value pairs. -/// -/// This function is expected to call `loop_body` once for each key-value pair -/// within `iterator`, passing `context`, and returning any non-zero value immediately (breaking iteration). -#[allow(non_camel_case_types)] -pub type z_attachment_iter_driver_t = Option< - extern "C" fn( - iterator: *const c_void, - loop_body: z_attachment_iter_body_t, - context: *mut c_void, - ) -> i8, ->; - -/// A iteration based map of byte slice to byte slice. -/// -/// `iteration_driver == NULL` marks the gravestone value, as this type is often optional. -/// Users are encouraged to use `z_attachment_null` and `z_attachment_check` to interact. -#[repr(C)] -#[derive(Clone, Copy)] -pub struct z_attachment_t { - pub data: *const c_void, - pub iteration_driver: z_attachment_iter_driver_t, -} - -/// Returns the gravestone value for `z_attachment_t`. -#[no_mangle] -pub extern "C" fn z_attachment_check(this: &z_attachment_t) -> bool { - this.iteration_driver.is_some() -} - -/// Returns the gravestone value for `z_attachment_t`. -#[no_mangle] -pub extern "C" fn z_attachment_null() -> z_attachment_t { - z_attachment_t { - data: core::ptr::null_mut(), - iteration_driver: None, - } -} - -/// Iterate over `this`'s key-value pairs, breaking if `body` returns a non-zero -/// value for a key-value pair, and returning the latest return value. -/// -/// `context` is passed to `body` to allow stateful closures. -/// -/// This function takes no ownership whatsoever. -#[no_mangle] -pub extern "C" fn z_attachment_iterate( - this: z_attachment_t, - body: z_attachment_iter_body_t, - context: *mut c_void, -) -> i8 { - if let Some(driver) = this.iteration_driver { - return driver(this.data, body, context); - } - log::error!("Invalid iteration_driver"); - i8::MIN -} - -/// Returns the value associated with the key. -#[no_mangle] -pub extern "C" fn z_attachment_get(this: z_attachment_t, key: z_bytes_t) -> z_bytes_t { - struct attachment_get_iterator_context { - key: z_bytes_t, - value: z_bytes_t, - } - - extern "C" fn attachment_get_iterator( - key: z_bytes_t, - value: z_bytes_t, - context: *mut c_void, - ) -> i8 { - unsafe { - let context = &mut *(context as *mut attachment_get_iterator_context); - if context.key.as_slice() == key.as_slice() { - context.value = value; - 1 - } else { - 0 - } - } - } - - let mut context = attachment_get_iterator_context { - key, - value: z_bytes_empty(), - }; - - if this.iteration_driver.map_or(false, |iteration_driver| { - (iteration_driver)( - this.data, - attachment_get_iterator, - &mut context as *mut _ as *mut c_void, - ) != 0 - }) { - context.value - } else { - z_bytes_empty() - } -} - -fn _z_attachment_len(this: z_attachment_t, check_if_non_empty: bool) -> usize { - match this.iteration_driver.as_ref() { - None => 0, - Some(iteration_driver) => { - struct count_context_t { - count: usize, - stop_if_not_empty: bool, - } - - extern "C" fn attachment_count_iterator( - _key: z_bytes_t, - _value: z_bytes_t, - context: *mut c_void, - ) -> i8 { - unsafe { - let context = &mut *(context as *mut count_context_t); - context.count += 1; - if context.stop_if_not_empty { - 1 - } else { - 0 - } - } - } - let mut count_context = count_context_t { - count: 0, - stop_if_not_empty: check_if_non_empty, - }; - (iteration_driver)( - this.data, - attachment_count_iterator, - &mut count_context as *mut _ as *mut c_void, - ); - count_context.count - } - } -} - -/// Returns number of key-value pairs for `z_attachment_t`. -/// -/// Does so by iterating over all existing key-value pairs. -#[no_mangle] -pub extern "C" fn z_attachment_len(this: z_attachment_t) -> usize { - _z_attachment_len(this, false) -} - -/// Returns true if `z_attachment_t` contains no key-value pairs, false otherwise. -#[no_mangle] -pub extern "C" fn z_attachment_is_empty(this: z_attachment_t) -> bool { - _z_attachment_len(this, true) == 0 -} - -/// A map of maybe-owned vector of bytes to owned vector of bytes. -/// -/// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher -#[repr(C)] -pub struct z_owned_bytes_map_t { - _0: [u64; 2], - _1: [usize; 4], -} - -impl_guarded_transmute!(noderefs - Option, Cow<'static, [u8]>>>, - z_owned_bytes_map_t -); - -impl core::ops::Deref for z_owned_bytes_map_t { - type Target = UnsafeCell, Cow<'static, [u8]>>>>; - fn deref(&self) -> &Self::Target { - unsafe { core::mem::transmute(self) } - } -} - -/// Constructs a new map. -#[no_mangle] -pub extern "C" fn z_bytes_map_new() -> z_owned_bytes_map_t { - unsafe { core::mem::transmute(Some(HashMap::, Cow<[u8]>>::new())) } -} - -/// Constructs the gravestone value for `z_owned_bytes_map_t` -#[no_mangle] -pub extern "C" fn z_bytes_map_null() -> z_owned_bytes_map_t { - unsafe { core::mem::transmute(None::, Cow<[u8]>>>) } -} - -/// Returns `true` if the map is not in its gravestone state -#[no_mangle] -pub extern "C" fn z_bytes_map_check(this: &z_owned_bytes_map_t) -> bool { - unsafe { &*this.get() }.is_some() -} -/// Destroys the map, resetting `this` to its gravestone value. -/// -/// This function is double-free safe, passing a pointer to the gravestone value will have no effect. -#[no_mangle] -pub extern "C" fn z_bytes_map_drop(this: &mut z_owned_bytes_map_t) { - let this = unsafe { &mut *this.get() }; - this.take(); -} - -/// Returns number of key-value pairs in the map. -#[no_mangle] -pub extern "C" fn z_bytes_map_len(this: &mut z_owned_bytes_map_t) -> usize { - let this = unsafe { &*this.get() }; - this.as_ref().map(|m| m.len()).unwrap_or(0) -} - -/// Returns true if the map is empty, false otherwise. -#[no_mangle] -pub extern "C" fn z_bytes_map_is_empty(this: &mut z_owned_bytes_map_t) -> bool { - let this = unsafe { &*this.get() }; - this.as_ref().map(|m| m.is_empty()).unwrap_or(true) -} - -/// Returns the value associated with `key`, returning a gravestone value if: -/// - `this` or `key` is in gravestone state. -/// - `this` has no value associated to `key` -#[no_mangle] -pub extern "C" fn z_bytes_map_get(this: &z_owned_bytes_map_t, key: z_bytes_t) -> z_bytes_t { - let this = unsafe { &*this.get() }; - let (Some(this), Some(key)) = (this.as_ref(), key.as_slice()) else { - return z_bytes_empty(); - }; - if let Some(value) = this.get(key) { - value.as_ref().into() - } else { - z_bytes_empty() - } -} - -/// Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. -/// -/// Calling this with `NULL` or the gravestone value is undefined behaviour. -#[no_mangle] -pub extern "C" fn z_bytes_map_insert_by_copy( - this: &z_owned_bytes_map_t, - key: z_bytes_t, - value: z_bytes_t, -) { - let this = unsafe { &mut *this.get() }; - if let (Some(this), Some(key), Some(value)) = (this.as_mut(), key.as_slice(), value.as_slice()) - { - this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())); - } -} - -/// Associates `value` to `key` in the map, aliasing them. -/// -/// Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. -/// -/// Calling this with `NULL` or the gravestone value is undefined behaviour. -#[no_mangle] -pub extern "C" fn z_bytes_map_insert_by_alias( - this: &z_owned_bytes_map_t, - key: z_bytes_t, - value: z_bytes_t, -) { - let this = unsafe { &mut *this.get() }; - if let (Some(this), Some(key), Some(value)) = (this.as_mut(), key.as_slice(), value.as_slice()) - { - unsafe { - this.insert( - Cow::Borrowed(core::mem::transmute(key)), - Cow::Borrowed(core::mem::transmute(value)), - ) - }; - } -} - -/// Iterates over the key-value pairs in the map. -/// -/// `body` will be called once per pair, with `ctx` as its last argument. -/// If `body` returns a non-zero value, the iteration will stop immediately and the value will be returned. -/// Otherwise, this will return 0 once all pairs have been visited. -/// `body` is not given ownership of the key nor value, which alias the pairs in the map. -/// It is safe to keep these aliases until existing keys are modified/removed, or the map is destroyed. -/// Note that this map is unordered. -/// -/// Calling this with `NULL` or the gravestone value is undefined behaviour. -#[no_mangle] -pub extern "C" fn z_bytes_map_iter( - this: &z_owned_bytes_map_t, - body: z_attachment_iter_body_t, - ctx: *mut c_void, -) -> i8 { - let this = unsafe { &*this.get() }; - if let Some(this) = this.as_ref() { - for (key, value) in this.iter() { - let result = body(key.as_ref().into(), value.as_ref().into(), ctx); - if result != 0 { - return result; - } - } - } - 0 -} - -const Z_BYTES_MAP_ITERATION_DRIVER: z_attachment_iter_driver_t = - Some(unsafe { core::mem::transmute(z_bytes_map_iter as extern "C" fn(_, _, _) -> i8) }); - -pub(crate) extern "C" fn insert_in_attachment_builder( - key: z_bytes_t, - value: z_bytes_t, - ctx: *mut c_void, -) -> i8 { - let attachment_builder_ref: &mut AttachmentBuilder = - unsafe { &mut *(ctx as *mut AttachmentBuilder) }; - attachment_builder_ref.insert(key.as_slice().unwrap(), value.as_slice().unwrap()); - 0 -} - -pub(crate) extern "C" fn attachment_iteration_driver( - this: *const c_void, - body: z_attachment_iter_body_t, - ctx: *mut c_void, -) -> i8 { - let attachments_ref: &Attachment = unsafe { &*(this as *mut Attachment) }; - for (key, value) in attachments_ref.iter() { - let result = body(key.as_ref().into(), value.as_ref().into(), ctx); - if result != 0 { - return result; - } - } - 0 -} - -/// Aliases `this` into a generic `z_attachment_t`, allowing it to be passed to corresponding APIs. -#[no_mangle] -pub extern "C" fn z_bytes_map_as_attachment(this: &z_owned_bytes_map_t) -> z_attachment_t { - if z_bytes_map_check(this) { - z_attachment_t { - data: this as *const z_owned_bytes_map_t as *mut _, - iteration_driver: Z_BYTES_MAP_ITERATION_DRIVER, - } - } else { - z_attachment_t { - data: core::ptr::null_mut(), - iteration_driver: None, - } - } -} - -extern "C" fn bytes_map_from_attachment_iterator( - key: z_bytes_t, - value: z_bytes_t, - ctx: *mut c_void, -) -> i8 { - let map = unsafe { &*ctx.cast::() }; - z_bytes_map_insert_by_copy(map, key, value); - 0 -} -extern "C" fn bytes_map_from_attachment_iterator_by_alias( - key: z_bytes_t, - value: z_bytes_t, - ctx: *mut c_void, -) -> i8 { - let map = unsafe { &*ctx.cast::() }; - z_bytes_map_insert_by_alias(map, key, value); - 0 -} - -/// Constructs a map from the provided attachment, copying keys and values. -/// -/// If `this` is at gravestone value, the returned value will also be at gravestone value. -#[no_mangle] -pub extern "C" fn z_bytes_map_from_attachment(this: z_attachment_t) -> z_owned_bytes_map_t { - if z_attachment_check(&this) { - let mut map = z_bytes_map_new(); - z_attachment_iterate( - this, - bytes_map_from_attachment_iterator, - &mut map as *mut _ as *mut _, - ); - map - } else { - z_bytes_map_null() - } -} - -/// Constructs a map from the provided attachment, aliasing the attachment's keys and values. -/// -/// If `this` is at gravestone value, the returned value will also be at gravestone value. -#[no_mangle] -pub extern "C" fn z_bytes_map_from_attachment_aliasing( - this: z_attachment_t, -) -> z_owned_bytes_map_t { - if z_attachment_check(&this) { - let mut map = z_bytes_map_new(); - z_attachment_iterate( - this, - bytes_map_from_attachment_iterator_by_alias, - &mut map as *mut _ as *mut _, - ); - map - } else { - z_bytes_map_null() - } -} diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index b964add61..9860e926d 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -1,6 +1,6 @@ -use crate::{z_closure_owned_query_drop, z_owned_closure_owned_query_t, z_owned_query_t}; +use crate::{z_closure_query_drop, z_owned_closure_query_t, z_owned_query_t, z_query_clone, z_query_null, z_query_t}; use libc::c_void; -use std::sync::mpsc::TryRecvError; +use std::{mem::MaybeUninit, sync::mpsc::{Receiver, TryRecvError}}; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// - `this` is a pointer to an arbitrary state. @@ -16,49 +16,40 @@ use std::sync::mpsc::TryRecvError; #[repr(C)] pub struct z_owned_query_channel_closure_t { context: *mut c_void, - call: Option bool>, + call: Option, *mut c_void) -> bool>, drop: Option, } /// A pair of closures #[repr(C)] pub struct z_owned_query_channel_t { - pub send: z_owned_closure_owned_query_t, + pub send: z_owned_closure_query_t, pub recv: z_owned_query_channel_closure_t, } #[no_mangle] pub extern "C" fn z_query_channel_drop(channel: &mut z_owned_query_channel_t) { - z_closure_owned_query_drop(&mut channel.send); + z_closure_query_drop(&mut channel.send); z_query_channel_closure_drop(&mut channel.recv); } /// Constructs a null safe-to-drop value of 'z_owned_query_channel_t' type #[no_mangle] pub extern "C" fn z_query_channel_null() -> z_owned_query_channel_t { z_owned_query_channel_t { - send: z_owned_closure_owned_query_t::empty(), + send: z_owned_closure_query_t::empty(), recv: z_owned_query_channel_closure_t::empty(), } } -/// Creates a new blocking fifo channel, returned as a pair of closures. -/// -/// If `bound` is different from 0, that channel will be bound and apply back-pressure when full. -/// -/// The `send` end should be passed as callback to a `z_get` call. -/// -/// The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, -/// which it will then return; or until the `send` closure is dropped and all queries have been consumed, -/// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. -#[no_mangle] -pub extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { - let (send, rx) = if bound == 0 { +unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver) { + if bound == 0 { let (tx, rx) = std::sync::mpsc::channel(); ( - From::from(move |query: &mut z_owned_query_t| { - if let Some(query) = query.take() { - if let Err(e) = tx.send(query) { - log::error!("Attempted to push onto a closed query_fifo: {}", e) - } + From::from(move |query: z_query_t| { + let mut this = MaybeUninit::::uninit(); + z_query_clone(&mut this as *mut MaybeUninit, query); + let this = this.assume_init(); + if let Err(e) = tx.send(this) { + log::error!("Attempted to push onto a closed reply_fifo: {}", e); } }), rx, @@ -66,23 +57,40 @@ pub extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { } else { let (tx, rx) = std::sync::mpsc::sync_channel(bound); ( - From::from(move |query: &mut z_owned_query_t| { - if let Some(query) = query.take() { - if let Err(e) = tx.send(query) { - log::error!("Attempted to push onto a closed query_fifo: {}", e) - } + From::from(move |query: z_query_t| { + let mut this = MaybeUninit::::uninit(); + z_query_clone(&mut this as *mut MaybeUninit, query); + let this = this.assume_init(); + if let Err(e) = tx.send(this) { + log::error!("Attempted to push onto a closed reply_fifo: {}", e); } }), rx, ) - }; + } +} + + +/// Creates a new blocking fifo channel, returned as a pair of closures. +/// +/// If `bound` is different from 0, that channel will be bound and apply back-pressure when full. +/// +/// The `send` end should be passed as callback to a `z_get` call. +/// +/// The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, +/// which it will then return; or until the `send` closure is dropped and all queries have been consumed, +/// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. +#[no_mangle] +pub unsafe extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { + let (send, rx) = get_send_recv_ends(bound); z_owned_query_channel_t { send, - recv: From::from(move |receptacle: &mut z_owned_query_t| { - *receptacle = match rx.recv() { - Ok(val) => Some(val).into(), - Err(_) => None.into(), - }; + recv: From::from(move |this: *mut MaybeUninit| { + if let Ok(val) = rx.recv() { + (*this).write(val); + } else { + z_query_null(this); + } true }), } @@ -98,51 +106,26 @@ pub extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { /// which it will then return; or until the `send` closure is dropped and all queries have been consumed, /// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. #[no_mangle] -pub extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned_query_channel_t { - let (send, rx) = if bound == 0 { - let (tx, rx) = std::sync::mpsc::channel(); - ( - From::from(move |query: &mut z_owned_query_t| { - if let Some(query) = query.take() { - if let Err(e) = tx.send(query) { - log::error!("Attempted to push onto a closed query_fifo: {}", e) - } - } - }), - rx, - ) - } else { - let (tx, rx) = std::sync::mpsc::sync_channel(bound); - ( - From::from(move |query: &mut z_owned_query_t| { - if let Some(query) = query.take() { - if let Err(e) = tx.send(query) { - log::error!("Attempted to push onto a closed query_fifo: {}", e) - } - } - }), - rx, - ) - }; +pub unsafe extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned_query_channel_t { + let (send, rx) = get_send_recv_ends(bound); z_owned_query_channel_t { send, - recv: From::from( - move |receptacle: &mut z_owned_query_t| match rx.try_recv() { + recv: From::from(move |this: *mut MaybeUninit| { + match rx.try_recv() { Ok(val) => { - let mut tmp = z_owned_query_t::from(Some(val)); - std::mem::swap(&mut tmp, receptacle); + (*this).write(val); true } Err(TryRecvError::Disconnected) => { - receptacle.take(); + z_query_null(this); true } Err(TryRecvError::Empty) => { - receptacle.take(); + z_query_null(this); false } - }, - ), + } + }), } } @@ -175,10 +158,10 @@ pub extern "C" fn z_query_channel_closure_null() -> z_owned_query_channel_closur #[no_mangle] pub extern "C" fn z_query_channel_closure_call( closure: &z_owned_query_channel_closure_t, - sample: &mut z_owned_query_t, + query: *mut MaybeUninit, ) -> bool { match closure.call { - Some(call) => call(sample, closure.context), + Some(call) => call(query, closure.context), None => { log::error!("Attempted to call an uninitialized closure!"); true @@ -191,11 +174,11 @@ pub extern "C" fn z_query_channel_closure_drop(closure: &mut z_owned_query_chann let mut empty_closure = z_owned_query_channel_closure_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl bool> From for z_owned_query_channel_closure_t { +impl) -> bool> From for z_owned_query_channel_closure_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call bool>( - query: &mut z_owned_query_t, + extern "C" fn call) -> bool>( + query: *mut MaybeUninit, this: *mut c_void, ) -> bool { let this = unsafe { &*(this as *const F) }; diff --git a/src/closures/query_closure.rs b/src/closures/query_closure.rs index 22ad4bc28..f0387bc45 100644 --- a/src/closures/query_closure.rs +++ b/src/closures/query_closure.rs @@ -4,7 +4,7 @@ use libc::c_void; /// /// Members: /// void *context: a pointer to an arbitrary state. -/// void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. +/// void *call(z_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. /// void *drop(void*): allows the callback's state to be freed. /// /// Closures are not guaranteed not to be called concurrently. @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_query_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } impl z_owned_closure_query_t { @@ -45,7 +45,7 @@ pub extern "C" fn z_closure_query_null() -> z_owned_closure_query_t { } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_query_call(closure: &z_owned_closure_query_t, query: &z_query_t) { +pub extern "C" fn z_closure_query_call(closure: &z_owned_closure_query_t, query: z_query_t) { match closure.call { Some(call) => call(query, closure.context), None => log::error!("Attempted to call an uninitialized closure!"), @@ -57,10 +57,10 @@ pub extern "C" fn z_closure_query_drop(closure: &mut z_owned_closure_query_t) { let mut empty_closure = z_owned_closure_query_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_query_t { +impl From for z_owned_closure_query_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(sample: &z_query_t, this: *mut c_void) { + extern "C" fn call(sample: z_query_t, this: *mut c_void) { let this = unsafe { &*(this as *const F) }; this(sample) } diff --git a/src/closures/reply_closure.rs b/src/closures/reply_closure.rs index 1aa8a9b44..e7fdc721f 100644 --- a/src/closures/reply_closure.rs +++ b/src/closures/reply_closure.rs @@ -1,4 +1,4 @@ -use crate::z_owned_reply_t; +use crate::z_reply_t; use libc::c_void; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_reply_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } @@ -48,10 +48,10 @@ pub extern "C" fn z_closure_reply_null() -> z_owned_closure_reply_t { #[no_mangle] pub extern "C" fn z_closure_reply_call( closure: &z_owned_closure_reply_t, - sample: &mut z_owned_reply_t, + reply: z_reply_t, ) { match closure.call { - Some(call) => call(sample, closure.context), + Some(call) => call(reply, closure.context), None => { log::error!("Attempted to call an uninitialized closure!"); } @@ -63,11 +63,11 @@ pub extern "C" fn z_closure_reply_drop(closure: &mut z_owned_closure_reply_t) { let mut empty_closure = z_owned_closure_reply_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_reply_t { +impl From for z_owned_closure_reply_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call( - response: &mut z_owned_reply_t, + extern "C" fn call( + response: z_reply_t, this: *mut c_void, ) { let this = unsafe { &*(this as *const F) }; diff --git a/src/closures/response_channel.rs b/src/closures/response_channel.rs index 0ea046d5d..8375a7e5e 100644 --- a/src/closures/response_channel.rs +++ b/src/closures/response_channel.rs @@ -1,6 +1,6 @@ -use crate::{z_closure_reply_drop, z_owned_closure_reply_t, z_owned_reply_t}; +use crate::{ z_closure_reply_drop, z_owned_closure_reply_t, z_owned_reply_t, z_reply_clone, z_reply_null, z_reply_t}; use libc::c_void; -use std::sync::mpsc::TryRecvError; +use std::{mem::MaybeUninit, sync::mpsc::{Receiver, TryRecvError}}; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// - `this` is a pointer to an arbitrary state. /// - `call` is the typical callback function. `this` will be passed as its last argument. @@ -15,7 +15,7 @@ use std::sync::mpsc::TryRecvError; #[repr(C)] pub struct z_owned_reply_channel_closure_t { context: *mut c_void, - call: Option bool>, + call: Option, *mut c_void) -> bool>, drop: Option, } @@ -39,25 +39,16 @@ pub extern "C" fn z_reply_channel_null() -> z_owned_reply_channel_t { } } -/// Creates a new blocking fifo channel, returned as a pair of closures. -/// -/// If `bound` is different from 0, that channel will be bound and apply back-pressure when full. -/// -/// The `send` end should be passed as callback to a `z_get` call. -/// -/// The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, -/// which it will then return; or until the `send` closure is dropped and all replies have been consumed, -/// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. -#[no_mangle] -pub extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channel_t { - let (send, rx) = if bound == 0 { +unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver) { + if bound == 0 { let (tx, rx) = std::sync::mpsc::channel(); ( - From::from(move |reply: &mut z_owned_reply_t| { - if let Some(reply) = reply.take() { - if let Err(e) = tx.send(reply) { - log::error!("Attempted to push onto a closed reply_fifo: {}", e) - } + From::from(move |reply: z_reply_t| { + let mut this = MaybeUninit::::uninit(); + z_reply_clone(&mut this as *mut MaybeUninit, reply); + let this = this.assume_init(); + if let Err(e) = tx.send(this) { + log::error!("Attempted to push onto a closed reply_fifo: {}", e); } }), rx, @@ -65,23 +56,38 @@ pub extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channel_t { } else { let (tx, rx) = std::sync::mpsc::sync_channel(bound); ( - From::from(move |reply: &mut z_owned_reply_t| { - if let Some(reply) = reply.take() { - if let Err(e) = tx.send(reply) { - log::error!("Attempted to push onto a closed reply_fifo: {}", e) - } + From::from(move |reply: z_reply_t| { + let mut this = MaybeUninit::::uninit(); + z_reply_clone(&mut this as *mut MaybeUninit, reply); + let this = this.assume_init(); + if let Err(e) = tx.send(this) { + log::error!("Attempted to push onto a closed reply_fifo: {}", e); } }), rx, ) - }; + } +} +/// Creates a new blocking fifo channel, returned as a pair of closures. +/// +/// If `bound` is different from 0, that channel will be bound and apply back-pressure when full. +/// +/// The `send` end should be passed as callback to a `z_get` call. +/// +/// The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, +/// which it will then return; or until the `send` closure is dropped and all replies have been consumed, +/// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. +#[no_mangle] +pub unsafe extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channel_t { + let (send, rx) = get_send_recv_ends(bound); z_owned_reply_channel_t { send, - recv: From::from(move |receptacle: &mut z_owned_reply_t| { - *receptacle = match rx.recv() { - Ok(val) => val.into(), - Err(_) => None.into(), - }; + recv: From::from(move |this: *mut MaybeUninit| { + if let Ok(val) = rx.recv() { + (*this).write(val); + } else { + z_reply_null(this); + } true }), } @@ -97,52 +103,26 @@ pub extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channel_t { /// which it will then return; or until the `send` closure is dropped and all replies have been consumed, /// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. #[no_mangle] -pub extern "C" fn zc_reply_non_blocking_fifo_new(bound: usize) -> z_owned_reply_channel_t { - let (send, rx) = if bound == 0 { - let (tx, rx) = std::sync::mpsc::channel(); - ( - From::from(move |reply: &mut z_owned_reply_t| { - if let Some(reply) = reply.take() { - if let Err(e) = tx.send(reply) { - log::error!("Attempted to push onto a closed reply_fifo: {}", e) - } - } - }), - rx, - ) - } else { - let (tx, rx) = std::sync::mpsc::sync_channel(bound); - ( - From::from(move |reply: &mut z_owned_reply_t| { - if let Some(reply) = reply.take() { - if let Err(e) = tx.send(reply) { - log::error!("Attempted to push onto a closed reply_fifo: {}", e) - } - } - }), - rx, - ) - }; - +pub unsafe extern "C" fn zc_reply_non_blocking_fifo_new(bound: usize) -> z_owned_reply_channel_t { + let (send, rx) = get_send_recv_ends(bound); z_owned_reply_channel_t { send, - recv: From::from( - move |receptacle: &mut z_owned_reply_t| match rx.try_recv() { + recv: From::from(move |this: *mut MaybeUninit| { + match rx.try_recv() { Ok(val) => { - let mut tmp = z_owned_reply_t::from(val); - std::mem::swap(&mut tmp, receptacle); + (*this).write(val); true } Err(TryRecvError::Disconnected) => { - receptacle.take(); + z_reply_null(this); true } Err(TryRecvError::Empty) => { - receptacle.take(); + z_reply_null(this); false } - }, - ), + } + }), } } @@ -175,10 +155,10 @@ pub extern "C" fn z_reply_channel_closure_null() -> z_owned_reply_channel_closur #[no_mangle] pub extern "C" fn z_reply_channel_closure_call( closure: &z_owned_reply_channel_closure_t, - sample: &mut z_owned_reply_t, + reply: *mut MaybeUninit, ) -> bool { match closure.call { - Some(call) => call(sample, closure.context), + Some(call) => call(reply, closure.context), None => { log::error!("Attempted to call an uninitialized closure!"); true @@ -191,11 +171,11 @@ pub extern "C" fn z_reply_channel_closure_drop(closure: &mut z_owned_reply_chann let mut empty_closure = z_owned_reply_channel_closure_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl bool> From for z_owned_reply_channel_closure_t { +impl) -> bool> From for z_owned_reply_channel_closure_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call bool>( - response: &mut z_owned_reply_t, + extern "C" fn call) -> bool>( + response: *mut MaybeUninit, this: *mut c_void, ) -> bool { let this = unsafe { &*(this as *const F) }; diff --git a/src/collections.rs b/src/collections.rs index d55a9fa1b..b75ca2d63 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -12,36 +12,43 @@ // ZettaScale Zenoh team, // -use libc::{c_char, size_t}; +use std::borrow::Cow; +use std::collections::HashMap; +use std::mem::MaybeUninit; + +use libc::{c_char, c_void, size_t}; use zenoh::prelude::ZenohId; +use crate::errors; +use crate::transmute::{Inplace, InplaceDefault, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}; + /// A contiguous view of bytes owned by some other entity. /// /// `start` being `null` is considered a gravestone value, /// and empty slices are represented using a possibly dangling pointer for `start`. #[repr(C)] #[derive(Clone, Copy, Debug)] -pub struct z_bytes_t { +pub struct z_slice_t { pub start: *const u8, pub len: size_t, } -impl z_bytes_t { - pub fn as_slice(&self) -> Option<&[u8]> { +impl z_slice_t { + pub fn as_slice(&self) -> Option<&'static [u8]> { if self.start.is_null() { return None; } Some(unsafe { core::slice::from_raw_parts(self.start, self.len) }) } pub fn empty() -> Self { - z_bytes_t { + z_slice_t { start: std::ptr::null(), len: 0, } } } -impl Default for z_bytes_t { +impl Default for z_slice_t { fn default() -> Self { Self::empty() } @@ -49,32 +56,32 @@ impl Default for z_bytes_t { #[repr(C)] #[derive(Clone, Debug)] -pub struct z_owned_bytes_t { +pub struct z_owned_slice_t { pub start: *mut u8, pub len: size_t, } -impl Drop for z_owned_bytes_t { +impl Drop for z_owned_slice_t { fn drop(&mut self) { - unsafe { z_bytes_drop(self) } + unsafe { z_slice_drop(self) } } } -impl z_owned_bytes_t { - pub fn new(data: &[u8]) -> z_owned_bytes_t { +impl z_owned_slice_t { + pub fn new(data: &[u8]) -> z_owned_slice_t { if data.is_empty() { - return z_bytes_null(); + return z_slice_null(); } let data = data.to_vec().into_boxed_slice(); - z_owned_bytes_t { + z_owned_slice_t { len: data.len(), start: Box::leak(data).as_mut_ptr(), } } - pub fn preallocate(len: usize) -> z_owned_bytes_t { + pub fn preallocate(len: usize) -> z_owned_slice_t { let data = vec![0u8; len].into_boxed_slice(); - z_owned_bytes_t { + z_owned_slice_t { len, start: Box::leak(data).as_mut_ptr(), } @@ -86,16 +93,22 @@ impl z_owned_bytes_t { } } +impl Default for z_owned_slice_t { + fn default() -> Self { + z_slice_null() + } +} + /// Returns ``true`` if `b` is initialized. #[no_mangle] -pub extern "C" fn z_bytes_is_initialized(b: &z_bytes_t) -> bool { +pub extern "C" fn z_slice_is_initialized(b: &z_slice_t) -> bool { !b.start.is_null() } -/// Returns the gravestone value for `z_bytes_t` +/// Returns the gravestone value for `z_slice_t` #[no_mangle] -pub const extern "C" fn z_bytes_empty() -> z_bytes_t { - z_bytes_t { +pub const extern "C" fn z_slice_empty() -> z_slice_t { + z_slice_t { len: 0, start: core::ptr::null(), } @@ -103,45 +116,45 @@ pub const extern "C" fn z_bytes_empty() -> z_bytes_t { /// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// `str == NULL` will cause this to return `z_bytes_empty()` +/// `str == NULL` will cause this to return `z_slice_empty()` #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_from_str(str: *const c_char) -> z_bytes_t { +pub unsafe extern "C" fn z_slice_from_str(str: *const c_char) -> z_slice_t { if str.is_null() { - z_bytes_empty() + z_slice_empty() } else { let len = unsafe { libc::strlen(str) }; - z_bytes_t { + z_slice_t { len, start: str.cast(), } } } -#[deprecated = "Renamed to z_bytes_from_str"] -/// Deprecated in favor of `z_bytes_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). +#[deprecated = "Renamed to z_slice_from_str"] +/// Deprecated in favor of `z_slice_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// `str == NULL` will cause this to return `z_bytes_empty()` +/// `str == NULL` will cause this to return `z_slice_empty()` #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_new(str: *const c_char) -> z_bytes_t { - z_bytes_from_str(str) +pub unsafe extern "C" fn z_slice_new(str: *const c_char) -> z_slice_t { + z_slice_from_str(str) } /// Constructs a `len` bytes long view starting at `start`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_wrap(start: *const u8, len: usize) -> z_bytes_t { +pub unsafe extern "C" fn z_slice_wrap(start: *const u8, len: usize) -> z_slice_t { if start.is_null() { - z_bytes_empty() + z_slice_empty() } else { - z_bytes_t { len, start } + z_slice_t { len, start } } } /// Frees `b` and invalidates it for double-drop safety. #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_drop(b: &mut z_owned_bytes_t) { +pub unsafe extern "C" fn z_slice_drop(b: &mut z_owned_slice_t) { if !b.start.is_null() { std::mem::drop(Box::from_raw( core::ptr::slice_from_raw_parts(b.start, b.len).cast_mut(), @@ -151,43 +164,43 @@ pub unsafe extern "C" fn z_bytes_drop(b: &mut z_owned_bytes_t) { } } -/// Returns the gravestone value for `z_owned_bytes_t` +/// Returns the gravestone value for `z_owned_slice_t` #[no_mangle] -pub const extern "C" fn z_bytes_null() -> z_owned_bytes_t { - z_owned_bytes_t { +pub const extern "C" fn z_slice_null() -> z_owned_slice_t { + z_owned_slice_t { len: 0, start: core::ptr::null_mut(), } } #[no_mangle] -pub const extern "C" fn z_bytes_loan(b: &z_owned_bytes_t) -> z_bytes_t { - z_bytes_t { +pub const extern "C" fn z_slice_loan(b: &z_owned_slice_t) -> z_slice_t { + z_slice_t { len: b.len, start: b.start, } } #[no_mangle] -pub extern "C" fn z_bytes_clone(b: &z_bytes_t) -> z_owned_bytes_t { - if !z_bytes_is_initialized(b) { - z_bytes_null() +pub extern "C" fn z_slice_clone(b: &z_slice_t, ) -> z_owned_slice_t { + if !z_slice_is_initialized(b) { + z_slice_null() } else { - z_owned_bytes_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) }) + z_owned_slice_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) }) } } /// Returns ``true`` if `b` is initialized. #[no_mangle] -pub extern "C" fn z_bytes_check(b: &z_owned_bytes_t) -> bool { +pub extern "C" fn z_slice_check(b: &z_owned_slice_t) -> bool { !b.start.is_null() } -impl From for z_bytes_t { +impl From for z_slice_t { #[inline] fn from(pid: ZenohId) -> Self { let pid = pid.to_le_bytes().to_vec().into_boxed_slice(); - let res = z_bytes_t { + let res = z_slice_t { start: pid.as_ptr(), len: pid.len() as size_t, }; @@ -196,12 +209,12 @@ impl From for z_bytes_t { } } -impl From> for z_bytes_t { +impl From> for z_slice_t { #[inline] fn from(pid: Option) -> Self { match pid { Some(pid) => pid.into(), - None => z_bytes_t { + None => z_slice_t { start: std::ptr::null(), len: 0, }, @@ -209,8 +222,8 @@ impl From> for z_bytes_t { } } -impl From for String { - fn from(s: z_bytes_t) -> Self { +impl From for String { + fn from(s: z_slice_t) -> Self { unsafe { String::from_utf8( Box::from_raw(std::slice::from_raw_parts_mut(s.start as *mut u8, s.len)).into(), @@ -220,11 +233,220 @@ impl From for String { } } -impl From<&[u8]> for z_bytes_t { +impl From<&[u8]> for z_slice_t { fn from(s: &[u8]) -> Self { - z_bytes_t { + z_slice_t { start: s.as_ptr(), len: s.len(), } } } + +impl InplaceDefault for z_owned_slice_t {} + + +/// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` +/// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with +/// `z_check` and `z_str_check` correspondently +#[repr(C)] +pub struct z_owned_str_t { + pub _cstr: *mut libc::c_char, +} + +impl z_owned_str_t { + #[allow(clippy::missing_safety_doc)] + pub unsafe fn preallocate(len: usize) -> z_owned_str_t { + let cstr = libc::malloc(len + 1) as *mut libc::c_char; + *cstr.add(len) = 0; + z_owned_str_t { _cstr: cstr } + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { + std::ptr::copy_nonoverlapping( + value.as_ptr(), + (self._cstr as *mut u8).add(start), + value.len(), + ); + } +} + +impl From<&[u8]> for z_owned_str_t { + fn from(value: &[u8]) -> Self { + unsafe { + let mut cstr = Self::preallocate(value.len()); + cstr.insert_unchecked(0, value); + cstr + } + } +} + +impl Drop for z_owned_str_t { + fn drop(&mut self) { + unsafe { z_str_drop(self) } + } +} + +impl Default for z_owned_str_t { + fn default() -> Self { + z_str_null() + } +} + +/// Frees `z_owned_str_t`, invalidating it for double-drop safety. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_str_drop(s: &mut z_owned_str_t) { + if s._cstr.is_null() { + return; + } + libc::free(std::mem::transmute(s._cstr)); + s._cstr = std::ptr::null_mut(); +} + +/// Returns ``true`` if `s` is a valid string +#[no_mangle] +pub extern "C" fn z_str_check(s: &z_owned_str_t) -> bool { + !s._cstr.is_null() +} + +/// Returns undefined `z_owned_str_t` +#[no_mangle] +pub extern "C" fn z_str_null() -> z_owned_str_t { + z_owned_str_t { + _cstr: std::ptr::null_mut(), + } +} + +/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. +#[no_mangle] +pub extern "C" fn z_str_loan(s: &z_owned_str_t) -> *const libc::c_char { + s._cstr +} + +impl InplaceDefault for z_owned_str_t {} + +pub use crate::opaque_types::z_owned_slice_map_t; +pub use crate::opaque_types::z_slice_map_t; + +pub type ZHashMap = HashMap, Cow<'static, [u8]>>; +pub use crate::opaque_types::z_config_t; +decl_transmute_handle!(HashMap, Cow<'static, [u8]>>, z_slice_map_t); + +pub use crate::opaque_types::z_owned_config_t; +decl_transmute_owned!(Option, z_owned_slice_map_t); + +/// Constructs a new empty map. +#[no_mangle] +pub extern "C" fn z_slice_map_new(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + let map = ZHashMap::new(); + Inplace::init(this, Some(map)); +} + +/// Constructs the gravestone value for `z_owned_slice_map_t` +#[no_mangle] +pub extern "C" fn z_slice_map_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); +} + +/// Returns `true` if the map is not in its gravestone state +#[no_mangle] +pub extern "C" fn z_slice_map_check(map: &z_owned_slice_map_t) -> bool { + let map = map.transmute_ref(); + map.as_ref().is_some() +} + +/// Destroys the map, resetting `this` to its gravestone value. +/// +/// This function is double-free safe, passing a pointer to the gravestone value will have no effect. +#[no_mangle] +pub extern "C" fn z_slice_map_drop(this: &mut z_owned_slice_map_t) { + let this = this.transmute_mut(); + Inplace::drop(this); +} + +/// Returns number of key-value pairs in the map. +#[no_mangle] +pub extern "C" fn z_slice_map_len(this: z_slice_map_t) -> usize { + this.transmute_ref().len() +} + +/// Returns true if the map is empty, false otherwise. +#[no_mangle] +pub extern "C" fn z_slice_map_is_empty(this: z_slice_map_t) -> bool { + z_slice_map_len(this) == 0 +} + +/// The body of a loop over a z_slice_map's key-value pairs. +/// +/// `key` and `value` are loaned to the body for the duration of a single call. +/// `context` is passed transparently through the iteration driver. +/// +/// Returning `true` is treated as `continue`. +#[allow(non_camel_case_types)] +pub type z_slice_map_iter_body_t = + extern "C" fn(key: z_slice_t, value: z_slice_t, context: *mut c_void) -> bool; + +#[no_mangle] +pub extern "C" fn z_slice_map_iterate(this: &z_slice_map_t, body: z_slice_map_iter_body_t, context: *mut c_void) { + let this = this.transmute_ref(); + for (key, value) in this { + if !body(key.as_ref().into(), value.as_ref().into(), context) { + break; + } + } +} + +/// Returns the value associated with `key`, returning a gravestone value if: +/// - `key` is in gravestone state. +#[no_mangle] +pub extern "C" fn z_slice_map_get(this: z_slice_map_t, key: z_slice_t) -> z_slice_t { + if !z_slice_is_initialized(&key) { + return z_slice_empty(); + } + let m = this.transmute_mut(); + let key = key.as_slice().unwrap(); + m.get(key).map(|s| s.as_ref().into()).unwrap_or( z_slice_empty()) +} + +/// Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. +/// +/// Returns 0 in case of success, -1 if one of the arguments were in gravestone state. +#[no_mangle] +pub extern "C" fn z_slice_map_insert_by_copy( + this: z_slice_map_t, + key: z_slice_t, + value: z_slice_t, +) -> errors::ZCError { + let this = this.transmute_mut(); + if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) + { + this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())); + errors::Z_OK + } else { + errors::Z_EINVAL + } +} + +/// Associates `value` to `key` in the map, aliasing them. +/// +/// Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. +/// +/// Returns 0 in case of success, -1 if one of the arguments were in gravestone state. +#[no_mangle] +pub extern "C" fn z_slice_map_insert_by_alias( + this: z_slice_map_t, + key: z_slice_t, + value: z_slice_t, +) -> errors::ZCError { + let this = this.transmute_mut(); + if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) + { + this.insert(Cow::Borrowed(key), Cow::Borrowed(value)); + errors::Z_OK + } else { + errors::Z_EINVAL + } +} \ No newline at end of file diff --git a/src/commons.rs b/src/commons.rs index 5bc998d49..ba29657be 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -14,32 +14,31 @@ use std::ffi::CStr; use std::mem::MaybeUninit; -use std::ops::Deref; use std::str::FromStr; -use crate::opaque_types::z_owned_buffer_t; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; -use crate::transmute::InplaceDefault; use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; +use crate::transmute::TransmuteUninitPtr; use crate::z_id_t; -use crate::zc_owned_payload_t; -use crate::zc_payload_t; -use libc::c_void; +use crate::z_bytes_t; +use crate::z_keyexpr_t; use libc::{c_char, c_ulong}; use unwrap_infallible::UnwrapInfallible; -use zenoh::buffers::ZBuf; use zenoh::encoding::Encoding; -use zenoh::payload::Deserialize; -use zenoh::payload::ZSerde; use zenoh::prelude::SampleKind; +use zenoh::publication::CongestionControl; +use zenoh::publication::Priority; +use zenoh::query::ConsolidationMode; +use zenoh::query::Mode; +use zenoh::query::QueryTarget; use zenoh::query::ReplyKeyExpr; use zenoh::sample::Locality; use zenoh::sample::Sample; use zenoh::time::Timestamp; - -use crate::attachment::{attachment_iteration_driver, z_attachment_null, z_attachment_t}; +use zenoh::value::Value; /// A zenoh unsigned integer #[allow(non_camel_case_types)] @@ -70,36 +69,20 @@ impl From for SampleKind { } } } +use crate::opaque_types::z_timestamp_t; +decl_transmute_copy!(Timestamp, z_timestamp_t); -#[repr(C)] -pub struct z_timestamp_t { - time: u64, - id: z_id_t, +#[no_mangle] +pub extern "C" fn z_timestamp_npt64_time(timestamp: &z_timestamp_t) -> u64 { + timestamp.transmute_copy().get_time().0 } -/// Returns ``true`` if `ts` is a valid timestamp #[no_mangle] -pub extern "C" fn z_timestamp_check(ts: z_timestamp_t) -> bool { - ts.id.id.iter().any(|byte| *byte != 0) -} -impl From> for z_timestamp_t { - fn from(ts: Option<&Timestamp>) -> Self { - if let Some(ts) = ts { - z_timestamp_t { - time: ts.get_time().as_u64(), - id: z_id_t { - id: ts.get_id().to_le_bytes(), - }, - } - } else { - z_timestamp_t { - time: 0, - id: z_id_t { id: [0u8; 16] }, - } - } - } +pub unsafe extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t { + timestamp.transmute_copy().get_id().to_le_bytes().into() } + /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. @@ -122,29 +105,12 @@ pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { } /// The sample's data, the return value aliases the sample. /// -/// If you need ownership of the buffer, you may use `z_sample_owned_payload`. #[no_mangle] -pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> zc_payload_t { - // TODO: here returning reference not to sample's payload, but to temporary copy - // THIS WILL CRASH FOR SURE, MADE IT ONLY TO MAKE IT COMPILE - // Need a way to get reference to sample's payload +pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_bytes_t { let sample = sample.transmute_copy(); - let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); - let owned_buffer: z_owned_buffer_t = Some(buffer).into(); - owned_buffer.as_ref().into() + sample.payload().transmute_handle() } -/// Returns the sample's payload after incrementing its internal reference count. -/// -/// Note that other samples may have received the same buffer, meaning that mutating this buffer may -/// affect the samples received by other subscribers. -#[no_mangle] -pub extern "C" fn z_sample_owned_payload(sample: &z_sample_t) -> zc_owned_payload_t { - let sample = sample.transmute_copy(); - let buffer: ZBuf = ZSerde.deserialize(sample.payload()).unwrap_infallible(); - let owned_buffer: z_owned_buffer_t = Some(buffer).into(); - owned_buffer.into() -} /// The sample's kind (put or delete). #[no_mangle] pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { @@ -152,37 +118,45 @@ pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { sample.kind().into() } /// The samples timestamp +/// +/// Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. #[no_mangle] -pub extern "C" fn z_sample_timestamp(sample: &z_sample_t) -> z_timestamp_t { +pub extern "C" fn z_sample_timestamp(sample: &z_sample_t, timestamp_out: &mut z_timestamp_t) -> bool { let sample = sample.transmute_copy(); - sample.timestamp().into() + if let Some(t) = sample.timestamp() { + *timestamp_out = t.transmute_copy(); + true + } else { + false + } } /// The qos with which the sample was received. /// TODO: split to methods (priority, congestion_control, express) -/// The sample's attachment. +/// Checks if sample contains an attachment. +#[no_mangle] +pub extern "C" fn z_sample_has_attachment(sample: z_sample_t) -> bool { + let sample = sample.transmute_copy(); + sample.attachment().is_some() +} + +/// Gets sample's attachment. /// -/// `sample` is aliased by the return value. +/// Before calling this function, ensure that `zc_sample_has_attachment` returns true #[no_mangle] -pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> z_attachment_t { +pub extern "C" fn z_sample_attachment(sample: z_sample_t) -> z_bytes_t { let sample = sample.transmute_copy(); - match sample.attachment() { - Some(attachment) => z_attachment_t { - data: attachment as *const _ as *mut c_void, - iteration_driver: Some(attachment_iteration_driver), - }, - None => z_attachment_null(), - } + sample.attachment().expect("Sample does not have an attachment").transmute_handle() } pub use crate::opaque_types::zc_owned_sample_t; -decl_transmute_owned!(default_inplace_init Option, zc_owned_sample_t); +decl_transmute_owned!(Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { let src = src.transmute_copy(); - let src = src.deref().clone(); + let src = src.clone(); let dst = dst.transmute_uninit_ptr(); Inplace::init(dst, Some(src)); } @@ -201,7 +175,7 @@ pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { /// /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] -pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> z_sample_t { +pub extern "C" fn zc_sample_loan(sample: &'static zc_owned_sample_t) -> z_sample_t { unwrap_ref_unchecked(sample.transmute_ref()).transmute_copy() } @@ -216,10 +190,6 @@ pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { Inplace::empty(sample.transmute_uninit_ptr()); } -/// The encoding of a payload, in a MIME-like format. -/// -/// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. -/// pub use crate::opaque_types::z_encoding_t; decl_transmute_copy!(&'static Encoding, z_encoding_t); @@ -231,7 +201,7 @@ decl_transmute_copy!(&'static Encoding, z_encoding_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. pub use crate::opaque_types::z_owned_encoding_t; -decl_transmute_owned!(default_inplace_init Encoding, z_owned_encoding_t); +decl_transmute_owned!(Encoding, z_owned_encoding_t); /// Constructs a null safe-to-drop value of 'z_owned_encoding_t' type #[no_mangle] @@ -251,8 +221,8 @@ pub unsafe extern "C" fn z_encoding_from_str( Inplace::empty(encoding); 0 } else { - let s = CStr::from_ptr(s).to_string_lossy().as_ref(); - let value = Encoding::from_str(s).unwrap_infallible(); + let s = CStr::from_ptr(s).to_string_lossy(); + let value = Encoding::from_str(s.as_ref()).unwrap_infallible(); Inplace::init(encoding, value); 0 } @@ -269,7 +239,7 @@ pub extern "C" fn z_encoding_default() -> z_encoding_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_drop(encoding: &mut z_owned_encoding_t) { - Inplace::drop(encoding); + Inplace::drop(encoding.transmute_mut()); } /// Returns ``true`` if `encoding` is valid. @@ -286,78 +256,11 @@ pub extern "C" fn z_encoding_loan(encoding: &'static z_owned_encoding_t) -> z_en encoding.transmute_ref().transmute_copy() } -/// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` -/// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with -/// `z_check` and `z_str_check` correspondently -#[repr(C)] -pub struct z_owned_str_t { - pub _cstr: *mut libc::c_char, -} - -impl z_owned_str_t { - #[allow(clippy::missing_safety_doc)] - pub unsafe fn preallocate(len: usize) -> z_owned_str_t { - let cstr = libc::malloc(len + 1) as *mut libc::c_char; - *cstr.add(len) = 0; - z_owned_str_t { _cstr: cstr } - } - - #[allow(clippy::missing_safety_doc)] - pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { - std::ptr::copy_nonoverlapping( - value.as_ptr(), - (self._cstr as *mut u8).add(start), - value.len(), - ); - } -} - -impl From<&[u8]> for z_owned_str_t { - fn from(value: &[u8]) -> Self { - unsafe { - let mut cstr = Self::preallocate(value.len()); - cstr.insert_unchecked(0, value); - cstr - } - } -} -impl Drop for z_owned_str_t { - fn drop(&mut self) { - unsafe { z_str_drop(self) } - } -} - -/// Frees `z_owned_str_t`, invalidating it for double-drop safety. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_str_drop(s: &mut z_owned_str_t) { - if s._cstr.is_null() { - return; - } - libc::free(std::mem::transmute(s._cstr)); - s._cstr = std::ptr::null_mut(); -} - -/// Returns ``true`` if `s` is a valid string -#[no_mangle] -pub extern "C" fn z_str_check(s: &z_owned_str_t) -> bool { - !s._cstr.is_null() -} - -/// Returns undefined `z_owned_str_t` -#[no_mangle] -pub extern "C" fn z_str_null() -> z_owned_str_t { - z_owned_str_t { - _cstr: std::ptr::null_mut(), - } -} - -/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. -#[no_mangle] -pub extern "C" fn z_str_loan(s: &z_owned_str_t) -> *const libc::c_char { - s._cstr -} +pub use crate::opaque_types::z_owned_value_t; +decl_transmute_owned!(Value, z_owned_value_t); +pub use crate::opaque_types::z_value_t; +decl_transmute_copy!(&'static Value, z_value_t); #[repr(C)] #[derive(Clone, Copy, Debug)] @@ -421,3 +324,182 @@ impl From for ReplyKeyExpr { pub extern "C" fn zcu_reply_keyexpr_default() -> zcu_reply_keyexpr_t { ReplyKeyExpr::default().into() } + + +/// The Queryables that should be target of a :c:func:`z_get`. +/// +/// - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. +/// - **ALL_COMPLETE**: All complete queryables. +/// - **ALL**: All matching queryables. +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Clone, Copy)] +pub enum z_query_target_t { + BEST_MATCHING, + ALL, + ALL_COMPLETE, +} + +impl From for z_query_target_t { + #[inline] + fn from(t: QueryTarget) -> Self { + match t { + QueryTarget::BestMatching => z_query_target_t::BEST_MATCHING, + QueryTarget::All => z_query_target_t::ALL, + QueryTarget::AllComplete => z_query_target_t::ALL_COMPLETE, + } + } +} + +impl From for QueryTarget { + #[inline] + fn from(val: z_query_target_t) -> Self { + match val { + z_query_target_t::BEST_MATCHING => QueryTarget::BestMatching, + z_query_target_t::ALL => QueryTarget::All, + z_query_target_t::ALL_COMPLETE => QueryTarget::AllComplete, + } + } +} + +/// Create a default :c:type:`z_query_target_t`. +#[no_mangle] +pub extern "C" fn z_query_target_default() -> z_query_target_t { + QueryTarget::default().into() +} + +/// Consolidation mode values. +/// +/// - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector +/// If the selector contains time range properties, consolidation mode `NONE` is used. +/// Otherwise the `LATEST` consolidation mode is used. +/// - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. +/// - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time +/// w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple +/// replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp +/// ts2 > ts1. It optimizes latency. +/// - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. +/// It optimizes bandwidth. +#[repr(C)] +#[derive(Clone, Copy, Default)] +pub enum z_consolidation_mode_t { + AUTO = -1, + #[default] + NONE = 0, + MONOTONIC = 1, + LATEST = 2, +} + +impl From> for z_consolidation_mode_t { + #[inline] + fn from(cm: Mode) -> Self { + match cm { + Mode::Manual(cm) => Self::from(cm), + Mode::Auto => z_consolidation_mode_t::AUTO, + } + } +} + +impl From for z_consolidation_mode_t { + #[inline] + fn from(cm: ConsolidationMode) -> Self { + match cm { + ConsolidationMode::Auto => z_consolidation_mode_t::AUTO, + ConsolidationMode::None => z_consolidation_mode_t::NONE, + ConsolidationMode::Monotonic => z_consolidation_mode_t::MONOTONIC, + ConsolidationMode::Latest => z_consolidation_mode_t::LATEST, + } + } +} + +impl From for Mode { + #[inline] + fn from(val: z_consolidation_mode_t) -> Self { + match val { + z_consolidation_mode_t::AUTO => Mode::Auto, + z_consolidation_mode_t::NONE => Mode::Manual(ConsolidationMode::None), + z_consolidation_mode_t::MONOTONIC => Mode::Manual(ConsolidationMode::Monotonic), + z_consolidation_mode_t::LATEST => Mode::Manual(ConsolidationMode::Latest), + } + } +} + +/// The priority of zenoh messages. +/// +/// - **REAL_TIME** +/// - **INTERACTIVE_HIGH** +/// - **INTERACTIVE_LOW** +/// - **DATA_HIGH** +/// - **DATA** +/// - **DATA_LOW** +/// - **BACKGROUND** +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Clone, Copy)] +pub enum z_priority_t { + REAL_TIME = 1, + INTERACTIVE_HIGH = 2, + INTERACTIVE_LOW = 3, + DATA_HIGH = 4, + DATA = 5, + DATA_LOW = 6, + BACKGROUND = 7, +} + +impl From for z_priority_t { + fn from(p: Priority) -> Self { + match p { + Priority::RealTime => z_priority_t::REAL_TIME, + Priority::InteractiveHigh => z_priority_t::INTERACTIVE_HIGH, + Priority::InteractiveLow => z_priority_t::INTERACTIVE_LOW, + Priority::DataHigh => z_priority_t::DATA_HIGH, + Priority::Data => z_priority_t::DATA, + Priority::DataLow => z_priority_t::DATA_LOW, + Priority::Background => z_priority_t::BACKGROUND, + } + } +} + +impl From for Priority { + fn from(p: z_priority_t) -> Self { + match p { + z_priority_t::REAL_TIME => Priority::RealTime, + z_priority_t::INTERACTIVE_HIGH => Priority::InteractiveHigh, + z_priority_t::INTERACTIVE_LOW => Priority::InteractiveLow, + z_priority_t::DATA_HIGH => Priority::DataHigh, + z_priority_t::DATA => Priority::Data, + z_priority_t::DATA_LOW => Priority::DataLow, + z_priority_t::BACKGROUND => Priority::Background, + } + } +} + +/// The kind of congestion control. +/// +/// - **BLOCK** +/// - **DROP** +#[allow(non_camel_case_types)] +#[repr(C)] +#[derive(Clone, Copy)] +pub enum z_congestion_control_t { + BLOCK, + DROP, +} + +impl From for z_congestion_control_t { + fn from(cc: CongestionControl) -> Self { + match cc { + CongestionControl::Block => z_congestion_control_t::BLOCK, + CongestionControl::Drop => z_congestion_control_t::DROP, + } + } +} + +impl From for CongestionControl { + fn from(cc: z_congestion_control_t) -> Self { + match cc { + z_congestion_control_t::BLOCK => CongestionControl::Block, + z_congestion_control_t::DROP => CongestionControl::Drop, + } + } +} \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index 824a45e37..23ef45a88 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,10 +16,11 @@ use std::ffi::CStr; use std::mem::MaybeUninit; use zenoh::config::{Config, ValidatedMap, WhatAmI}; +use crate::errors::{ZCError, Z_EPARSE}; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef, TransmuteUninitPtr, + unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }; -use crate::{z_owned_str_t, z_str_null}; +use crate::{errors, z_owned_str_t, z_str_null}; #[no_mangle] pub static Z_ROUTER: c_uint = WhatAmI::Router as c_uint; @@ -61,30 +62,19 @@ pub static Z_CONFIG_SCOUTING_DELAY_KEY: &c_char = pub static Z_CONFIG_ADD_TIMESTAMP_KEY: &c_char = unsafe { &*(b"timestamping/enabled\0".as_ptr() as *const c_char) }; -/// A loaned zenoh configuration. pub use crate::opaque_types::z_config_t; -decl_transmute_copy!(&'static Config, z_config_t); +decl_transmute_handle!(Config, z_config_t); -/// An owned zenoh configuration. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. pub use crate::opaque_types::z_owned_config_t; decl_transmute_owned!(Option>, z_owned_config_t); /// Returns a :c:type:`z_config_t` loaned from `s`. #[no_mangle] -pub extern "C" fn z_config_loan(s: &z_owned_config_t) -> z_config_t { +pub extern "C" fn z_config_loan(s: &'static z_owned_config_t) -> z_config_t { let s = s.transmute_ref(); let s = unwrap_ref_unchecked(s); let s = s.as_ref(); - s.transmute_copy() + s.transmute_handle() } /// Return a new, zenoh-allocated, empty configuration. @@ -111,12 +101,21 @@ pub extern "C" fn z_config_null(this: *mut MaybeUninit) { Inplace::empty(this); } +/// Clones the config. +#[no_mangle] +pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit) { + let src = src.transmute_ref(); + let src = Box::new(src.clone()); + let dst = dst.transmute_uninit_ptr(); + Inplace::init(dst, Some(src)); +} + /// Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. /// Use `z_drop` to safely deallocate this string #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char) -> z_owned_str_t { - let config = config.transmute_copy(); + let config = config.transmute_ref(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, Err(_) => return z_str_null(), @@ -138,7 +137,7 @@ pub unsafe extern "C" fn zc_config_insert_json( key: *const c_char, value: *const c_char, ) -> i8 { - let config = config.transmute_copy(); + let config = config.transmute_mut(); let key = CStr::from_ptr(key); let value = CStr::from_ptr(value); match config.insert_json5(&key.to_string_lossy(), &value.to_string_lossy()) { @@ -162,36 +161,37 @@ pub extern "C" fn z_config_check(config: &z_owned_config_t) -> bool { config.as_ref().is_some() } -/// Creates a default, zenoh-allocated, configuration. -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_config_default() -> z_owned_config_t { - z_config_new() -} - /// Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. /// /// Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_config_from_str(s: *const c_char) -> z_owned_config_t { +pub unsafe extern "C" fn zc_config_from_str( + s: *const c_char, + this: *mut MaybeUninit, +) -> errors::ZCError { + let mut res = errors::Z_OK; if s.is_null() { - z_config_null() + z_config_null(this); + res = errors::Z_EINVAL; } else { let conf_str = CStr::from_ptr(s); - let props: Option = json5::from_str(&conf_str.to_string_lossy()).ok(); - z_owned_config_t(std::mem::transmute(props.map(Box::new))) + let props: Option> = json5::from_str(&conf_str.to_string_lossy()) + .ok() + .map(|v| Box::new(v)); + if props.is_none() { + res = Z_EPARSE; + } + Inplace::init(this.transmute_uninit_ptr(), props); } + res } /// Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn zc_config_to_string(config: z_config_t) -> z_owned_str_t { - let config: &Config = match config.as_ref() { - Some(c) => c, - None => return z_str_null(), - }; + let config: &Config = config.transmute_ref(); match json5::to_string(config) { Ok(s) => s.as_bytes().into(), Err(_) => z_str_null(), @@ -201,28 +201,39 @@ pub extern "C" fn zc_config_to_string(config: z_config_t) -> z_owned_str_t { /// Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn zc_config_from_file(path: *const c_char) -> z_owned_config_t { +pub unsafe extern "C" fn zc_config_from_file( + path: *const c_char, + this: *mut MaybeUninit, +) -> errors::ZCError { let path_str = CStr::from_ptr(path); - z_owned_config_t(std::mem::transmute(match path_str.to_str() { + let mut res = errors::Z_OK; + let config = match path_str.to_str() { Ok(path) => match zenoh::config::Config::from_file(path) { Ok(c) => Some(Box::new(c)), Err(e) => { log::error!("Couldn't read config from {}: {}", path, e); + res = errors::Z_EPARSE; None } }, Err(e) => { log::error!("Invalid path '{}': {}", path_str.to_string_lossy(), e); + res = errors::Z_EIO; None } - })) + }; + Inplace::init(this.transmute_uninit_ptr(), config); + res } /// Constructs a default, zenoh-allocated, peer mode configuration. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_config_peer() -> z_owned_config_t { - unsafe { z_owned_config_t(std::mem::transmute(Some(Box::new(zenoh::config::peer())))) } +pub extern "C" fn z_config_peer(this: *mut MaybeUninit) { + Inplace::init( + this.transmute_uninit_ptr(), + Some(Box::new(zenoh::config::peer())), + ); } /// Constructs a default, zenoh-allocated, client mode configuration. @@ -232,7 +243,9 @@ pub extern "C" fn z_config_peer() -> z_owned_config_t { pub unsafe extern "C" fn z_config_client( peers: *const *const c_char, n_peers: usize, -) -> z_owned_config_t { + this: *mut MaybeUninit, +) -> ZCError { + let mut res = errors::Z_OK; let locators = if peers.is_null() { Vec::new() } else if let Ok(locators) = std::slice::from_raw_parts(peers, n_peers) @@ -243,6 +256,7 @@ pub unsafe extern "C" fn z_config_client( |mut acc, it| match it { Err(e) => { log::error!("Error parsing peer address: {}", e); + res = errors::Z_EPARSE; Err(()) } Ok(loc) => { @@ -254,9 +268,12 @@ pub unsafe extern "C" fn z_config_client( { locators } else { - return z_owned_config_t(std::mem::transmute(None::>)); + z_config_null(this); + return res; }; - z_owned_config_t(std::mem::transmute(Some(Box::new(zenoh::config::client( - locators, - ))))) + Inplace::init( + this.transmute_uninit_ptr(), + Some(Box::new(zenoh::config::client(locators))), + ); + res } diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 000000000..90e8508de --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,7 @@ +pub type ZCError = i8; +pub const Z_OK: ZCError = 0; +pub const Z_EINVAL: ZCError = -1; +pub const Z_EPARSE: ZCError = -2; +pub const Z_EIO: ZCError = -3; +pub const Z_ENETWORK: ZCError = -4; +pub const Z_EGENERIC: ZCError = i8::MIN; \ No newline at end of file diff --git a/src/get.rs b/src/get.rs index 5274a86b5..de8e9d183 100644 --- a/src/get.rs +++ b/src/get.rs @@ -13,60 +13,46 @@ // use libc::c_char; -use libc::c_void; -use std::mem::MaybeUninit; -use std::{ - convert::TryFrom, - ffi::CStr, - ops::{Deref, DerefMut}, -}; -use zenoh::buffers::ZBuf; -use zenoh::encoding::Encoding; -use zenoh::payload; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; +use std::mem::MaybeUninit; +use std::ptr::null_mut; +use std::ffi::CStr; -use zenoh::{ - prelude::{ConsolidationMode, KeyExpr, QueryTarget}, - query::{Mode, QueryConsolidation, Reply}, - sample::AttachmentBuilder, - value::Value, -}; +use zenoh::prelude::{ConsolidationMode, QueryTarget, Mode, QueryConsolidation, Reply}; -use crate::attachment::{ - insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, - z_attachment_t, -}; +use crate::errors; use crate::transmute::Inplace; use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; +use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; -use crate::z_encoding_default; -use crate::zc_owned_payload_t; -use crate::zc_payload_null; -use crate::zc_payload_t; +use crate::transmute::TransmuteUninitPtr; +use crate::z_consolidation_mode_t; +use crate::z_owned_encoding_t; +use crate::z_query_target_t; +use crate::z_sample_t; +use crate::z_owned_bytes_t; +use crate::z_value_t; use crate::{ - opaque_types::z_sample_t, z_closure_reply_call, z_encoding_t, z_keyexpr_t, - z_owned_closure_reply_t, z_session_t, LOG_INVALID_SESSION, + z_closure_reply_call, z_keyexpr_t, + z_owned_closure_reply_t, z_session_t, }; +use zenoh::prelude::SyncResolve; -/// An owned reply to a :c:func:`z_get`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. pub use crate::opaque_types::z_owned_reply_t; -decl_transmute_owned!(default_inplace_init Option, z_owned_reply_t); +decl_transmute_owned!(Option, z_owned_reply_t); +pub use crate::opaque_types::z_reply_t; +decl_transmute_handle!(Reply, z_reply_t); /// Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. /// /// If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_is_ok(reply: &z_owned_reply_t) -> bool { +pub unsafe extern "C" fn z_reply_is_ok(reply: z_reply_t) -> bool { let reply = reply.transmute_ref(); - reply.as_ref().map(|r| r.sample.is_ok()).unwrap_or(false) + reply.result().is_ok() } /// Yields the contents of the reply by asserting it indicates a success. @@ -74,35 +60,19 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: &z_owned_reply_t) -> bool { /// You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_ok(reply: &z_owned_reply_t) -> z_sample_t { +pub unsafe extern "C" fn z_reply_ok(reply: z_reply_t) -> z_sample_t { let reply = reply.transmute_ref(); - if let Some(sample) = reply.as_ref().and_then(|s| s.sample.as_ref().ok()) { - sample.transmute_copy() - } else { - panic!("Assertion failed: tried to treat `z_owned_reply_t` as Ok despite that not being the case") - } + reply.result().expect("Reply does not contain a sample").transmute_copy() } -/// A zenoh value. -/// -/// -pub use crate::opaque_types::z_owned_value_t; -decl_transmute_owned!(default_inplace_init Value, z_owned_value_t); -pub use crate::opaque_types::z_value_t; -decl_transmute_copy!(&'static Value, z_value_t); - /// Yields the contents of the reply by asserting it indicates a failure. /// /// You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { +pub unsafe extern "C" fn z_reply_err(reply: z_reply_t) -> z_value_t { let reply = reply.transmute_ref(); - if let Some(value) = reply.as_ref().and_then(|s| s.sample.as_ref().err()) { - value.into() - } else { - panic!("Assertion failed: tried to treat `z_owned_reply_t` as Err despite that not being the case") - } + reply.result().expect_err("Reply does not contain error").transmute_copy() } /// Returns an invalidated :c:type:`z_owned_reply_t`. @@ -113,9 +83,13 @@ pub unsafe extern "C" fn z_reply_err(reply: &z_owned_reply_t) -> z_value_t { /// - overwrite the pointee with this function's return value, /// - you are now responsible for dropping your copy of the reply. #[no_mangle] -#[allow(improper_ctypes_definitions)] -pub extern "C" fn z_reply_null(reply: *mut MaybeUninit) { - Inplace::empty(z_owned_reply_t::transmute_uninit_ptr(reply)); +pub extern "C" fn z_reply_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); +} + +#[no_mangle] +pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: z_reply_t) { + Inplace::init(this.transmute_uninit_ptr(), Some(reply.transmute_ref().clone())); } /// Options passed to the :c:func:`z_get` function. @@ -124,15 +98,15 @@ pub extern "C" fn z_reply_null(reply: *mut MaybeUninit) { /// z_query_target_t target: The Queryables that should be target of the query. /// z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. /// z_value_t value: An optional value to attach to the query. -/// z_attachment_t attachment: The attachment to attach to the query. +/// z_bytes_t attachment: The attachment to attach to the query. /// uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. #[repr(C)] pub struct z_get_options_t { pub target: z_query_target_t, pub consolidation: z_query_consolidation_t, - pub payload: zc_owned_payload_t, - pub encoding: z_encoding_t, - pub attachment: z_attachment_t, + pub payload: *mut z_owned_bytes_t, + pub encoding: *mut z_owned_encoding_t, + pub attachment: *mut z_owned_bytes_t, pub timeout_ms: u64, } #[no_mangle] @@ -141,9 +115,9 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { target: QueryTarget::default().into(), consolidation: QueryConsolidation::default().into(), timeout_ms: 0, - payload: zc_payload_null(), - encoding: z_encoding_default(), - attachment: z_attachment_null(), + payload: null_mut(), + encoding: null_mut(), + attachment: null_mut(), } } @@ -154,7 +128,7 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { /// /// Parameters: /// session: The zenoh session. -/// keyexpr: The key expression matching resources to query. +/// key_expr: The key expression matching resources to query. /// parameters: The query's parameters, similar to a url's query segment. /// callback: The callback function that will be called on reception of replies for this query. /// Note that the `reply` parameter of the callback is passed by mutable reference, @@ -165,11 +139,11 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { #[no_mangle] pub unsafe extern "C" fn z_get( session: z_session_t, - keyexpr: z_keyexpr_t, + key_expr: z_keyexpr_t, parameters: *const c_char, callback: &mut z_owned_closure_reply_t, - options: Option<&mut z_get_options_t>, -) -> i8 { + options: z_get_options_t, +) -> errors::ZCError { let mut closure = z_owned_closure_reply_t::empty(); std::mem::swap(callback, &mut closure); let p = if parameters.is_null() { @@ -177,155 +151,51 @@ pub unsafe extern "C" fn z_get( } else { CStr::from_ptr(parameters).to_str().unwrap() }; - let Some(s) = session.upgrade() else { - log::error!("{LOG_INVALID_SESSION}"); - return i8::MIN; - }; - let mut q = s.get(KeyExpr::try_from(keyexpr).unwrap().with_parameters(p)); - if let Some(options) = options { - q = q - .consolidation(options.consolidation) - .target(options.target.into()); + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); - if let Some(payload) = options.payload.take() { - let mut value = Value::new(payload); - value.encoding = **options.encoding; - q = q.value(value); - } - if options.timeout_ms != 0 { - q = q.timeout(std::time::Duration::from_millis(options.timeout_ms)); + let mut get = session.get(key_expr.clone().with_parameters(p)); + if !options.payload.is_null() { + if let Some(payload) = unsafe { *options.payload }.transmute_mut().extract() { + get = get.payload(payload); } - if z_attachment_check(&options.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - options.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - q = q.attachment(attachment_builder.build()); - }; } - match q - .callback(move |response| z_closure_reply_call(&closure, &mut response.into())) + if !options.encoding.is_null() { + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); + get = get.encoding(encoding); + } + if !options.attachment.is_null() { + let attachment = unsafe { *options.payload }.transmute_mut().extract(); + get = get.attachment(attachment); + } + + get = get.consolidation(options.consolidation) + .timeout(std::time::Duration::from_millis(options.timeout_ms)) + .target(options.target.into()); + match get + .callback(move |response| { + z_closure_reply_call(&closure, response.transmute_handle()) }) .res_sync() { - Ok(()) => 0, + Ok(()) => errors::Z_OK, Err(e) => { log::error!("{}", e); - e.errno().get() + errors::Z_EGENERIC } } } -/// Frees `reply_data`, invalidating it for double-drop safety. +/// Frees `reply`, invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_drop(reply_data: &mut z_owned_reply_t) { - std::mem::drop(reply_data.take()); +pub unsafe extern "C" fn z_reply_drop(this: &mut z_owned_reply_t) { + Inplace::drop(this.transmute_mut()) } -/// Returns ``true`` if `reply_data` is valid. +/// Returns ``true`` if `reply` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_check(reply_data: &z_owned_reply_t) -> bool { - reply_data.is_some() -} - -/// The Queryables that should be target of a :c:func:`z_get`. -/// -/// - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. -/// - **ALL_COMPLETE**: All complete queryables. -/// - **ALL**: All matching queryables. -#[allow(non_camel_case_types)] -#[repr(C)] -#[derive(Clone, Copy)] -pub enum z_query_target_t { - BEST_MATCHING, - ALL, - ALL_COMPLETE, -} - -impl From for z_query_target_t { - #[inline] - fn from(t: QueryTarget) -> Self { - match t { - QueryTarget::BestMatching => z_query_target_t::BEST_MATCHING, - QueryTarget::All => z_query_target_t::ALL, - QueryTarget::AllComplete => z_query_target_t::ALL_COMPLETE, - } - } -} - -impl From for QueryTarget { - #[inline] - fn from(val: z_query_target_t) -> Self { - match val { - z_query_target_t::BEST_MATCHING => QueryTarget::BestMatching, - z_query_target_t::ALL => QueryTarget::All, - z_query_target_t::ALL_COMPLETE => QueryTarget::AllComplete, - } - } -} - -/// Create a default :c:type:`z_query_target_t`. -#[no_mangle] -pub extern "C" fn z_query_target_default() -> z_query_target_t { - QueryTarget::default().into() -} - -/// Consolidation mode values. -/// -/// - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector -/// If the selector contains time range properties, consolidation mode `NONE` is used. -/// Otherwise the `LATEST` consolidation mode is used. -/// - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. -/// - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time -/// w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple -/// replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp -/// ts2 > ts1. It optimizes latency. -/// - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. -/// It optimizes bandwidth. -#[repr(C)] -#[derive(Clone, Copy, Default)] -pub enum z_consolidation_mode_t { - AUTO = -1, - #[default] - NONE = 0, - MONOTONIC = 1, - LATEST = 2, -} - -impl From> for z_consolidation_mode_t { - #[inline] - fn from(cm: Mode) -> Self { - match cm { - Mode::Manual(cm) => Self::from(cm), - Mode::Auto => z_consolidation_mode_t::AUTO, - } - } -} - -impl From for z_consolidation_mode_t { - #[inline] - fn from(cm: ConsolidationMode) -> Self { - match cm { - ConsolidationMode::Auto => z_consolidation_mode_t::AUTO, - ConsolidationMode::None => z_consolidation_mode_t::NONE, - ConsolidationMode::Monotonic => z_consolidation_mode_t::MONOTONIC, - ConsolidationMode::Latest => z_consolidation_mode_t::LATEST, - } - } -} - -impl From for Mode { - #[inline] - fn from(val: z_consolidation_mode_t) -> Self { - match val { - z_consolidation_mode_t::AUTO => Mode::Auto, - z_consolidation_mode_t::NONE => Mode::Manual(ConsolidationMode::None), - z_consolidation_mode_t::MONOTONIC => Mode::Manual(ConsolidationMode::Monotonic), - z_consolidation_mode_t::LATEST => Mode::Manual(ConsolidationMode::Latest), - } - } +pub unsafe extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { + this.transmute_ref().is_some() } /// The replies consolidation strategy to apply on replies to a :c:func:`z_get`. diff --git a/src/info.rs b/src/info.rs index b4e523d8a..6a2558a66 100644 --- a/src/info.rs +++ b/src/info.rs @@ -1,3 +1,4 @@ +use crate::transmute::TransmuteCopy; // // Copyright (c) 2017, 2022 ZettaScale Technology. // @@ -11,17 +12,21 @@ // Contributors: // ZettaScale Zenoh team, // -use crate::{session::*, z_closure_zid_call, z_owned_closure_zid_t}; +use std::mem::MaybeUninit; +use crate::{errors, z_closure_zid_call, z_owned_closure_zid_t, z_session_t}; use zenoh::config::ZenohId; use zenoh::prelude::sync::SyncResolve; use zenoh::session::SessionDeclarations; -/// Represents a Zenoh ID. -/// -/// In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. pub use crate::opaque_types::z_id_t; decl_transmute_copy!(ZenohId, z_id_t); +impl From<[u8;16]> for z_id_t { + fn from(value: [u8;16]) -> Self { + unsafe { std::mem::transmute(value) } + } +} + /// Returns the local Zenoh ID. /// /// Unless the `session` is invalid, that ID is guaranteed to be non-zero. @@ -30,10 +35,8 @@ decl_transmute_copy!(ZenohId, z_id_t); #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_info_zid(session: z_session_t) -> z_id_t { - match session.upgrade() { - Some(s) => std::mem::transmute::(s.info().zid().res_sync()), - None => z_id_t { id: [0; 16] }, - } + let session = session.transmute_copy(); + session.info().zid().res_sync().transmute_copy() } /// Fetches the Zenoh IDs of all connected peers. @@ -47,18 +50,14 @@ pub unsafe extern "C" fn z_info_zid(session: z_session_t) -> z_id_t { pub unsafe extern "C" fn z_info_peers_zid( session: z_session_t, callback: &mut z_owned_closure_zid_t, -) -> i8 { +) -> errors::ZCError { let mut closure = z_owned_closure_zid_t::empty(); std::mem::swap(&mut closure, callback); - match session.upgrade() { - Some(s) => { - for id in s.info().peers_zid().res_sync() { - z_closure_zid_call(&closure, &std::mem::transmute(id)); - } - 0 - } - None => i8::MIN, + let session = session.transmute_copy(); + for id in session.info().peers_zid().res_sync() { + z_closure_zid_call(&closure, &id.transmute_copy()); } + errors::Z_OK } /// Fetches the Zenoh IDs of all connected routers. @@ -72,16 +71,12 @@ pub unsafe extern "C" fn z_info_peers_zid( pub unsafe extern "C" fn z_info_routers_zid( session: z_session_t, callback: &mut z_owned_closure_zid_t, -) -> i8 { +) -> errors::ZCError { let mut closure = z_owned_closure_zid_t::empty(); std::mem::swap(&mut closure, callback); - match session.upgrade() { - Some(s) => { - for id in s.info().routers_zid().res_sync() { - z_closure_zid_call(&closure, &std::mem::transmute(id)); - } - 0 - } - None => i8::MIN, + let session = session.transmute_copy(); + for id in session.info().routers_zid().res_sync() { + z_closure_zid_call(&closure, &id.transmute_copy()); } + errors::Z_OK } diff --git a/src/keyexpr.rs b/src/keyexpr.rs index a97691ad7..cf19224fa 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -12,133 +12,129 @@ // ZettaScale Zenoh team, // -use std::convert::TryFrom; use std::mem::MaybeUninit; -use std::ops::Deref; -use std::ops::DerefMut; +use crate::errors; +use crate::errors::ZCError; +use crate::errors::Z_OK; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; +use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; -use crate::z_bytes_t; +use crate::transmute::TransmuteUninitPtr; +use crate::z_slice_t; use crate::z_owned_str_t; -use crate::z_str_null; -use crate::LOG_INVALID_SESSION; +use crate::z_session_t; use libc::c_char; -use zenoh::core::ErrNo; use zenoh::core::SyncResolve; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::KeyExpr; +use std::error::Error; -/// A zenoh-allocated key expression. -/// -/// Key expressions can identify a single key or a set of keys. -/// -/// Examples : -/// - ``"key/expression"``. -/// - ``"key/ex*"``. -/// -/// Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` -/// for wire and computation efficiency. -/// -/// A `key expression `_ can be either: -/// - A plain string expression. -/// - A pure numerical id. -/// - The combination of a numerical prefix and a string suffix. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. pub use crate::opaque_types::z_owned_keyexpr_t; -decl_transmute_owned!(default_inplace_init Option>, z_owned_keyexpr_t); +decl_transmute_owned!(Option>, z_owned_keyexpr_t); /// Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_keyexpr_null(this: *mut MaybeUninit) { - Inplace::empty(z_owned_keyexpr_t::transmute_uninit_ptr(this)); + Inplace::empty(this.transmute_uninit_ptr()); +} + +fn keyexpr_create_inner(name: &mut str, should_auto_canonize: bool, should_copy: bool) -> Result, Box> { + if should_copy { + let s = name.to_owned(); + match should_auto_canonize { + true => KeyExpr::<'static>::autocanonize(s), + false => KeyExpr::<'static>::try_from(s), + } + } else { + match should_auto_canonize { + true => KeyExpr::<'static>::autocanonize(name), + false => KeyExpr::<'static>::try_from(name), + } + } +} + +#[allow(clippy::missing_safety_doc)] +#[no_mangle] +unsafe fn keyexpr_create(name: &'static mut [u8], should_auto_canonize: bool, should_copy: bool) -> Result, errors::ZCError> { + match std::str::from_utf8_mut(name) { + Ok(name) => { + match keyexpr_create_inner(name, should_auto_canonize, should_copy) { + Ok(v) => { + Ok(v) + } + Err(e) => { + log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); + Err(errors::Z_EINVAL) + } + } + }, + Err(e) => { + log::error!("{}", e); + Err(errors::Z_EPARSE) + } + } } + -/// Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. + +/// Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_keyexpr_new( - this: *mut MaybeUninit, name: *const c_char, -) -> i8 { - let this = z_owned_keyexpr_t::transmute_uninit_ptr(this); + this: *mut MaybeUninit, +) -> errors::ZCError { if name.is_null() { - Inplace::empty(this); - return -1; + return errors::Z_EINVAL; } - let name = std::slice::from_raw_parts(name as _, libc::strlen(name)); - match std::str::from_utf8(name) { - Ok(name) => match KeyExpr::try_from(name) { - Ok(v) => { - Inplace::init(this, Some(v)); - 0 - } - Err(e) => { - log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); - Inplace::empty(this); - -1 - } + let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); + let this = this.transmute_uninit_ptr(); + match keyexpr_create(name, false, true) { + Ok(ke) => { + Inplace::init(this, Some(ke)); + errors::Z_OK }, Err(e) => { - log::error!("{}", e); Inplace::empty(this); - -1 + e } } } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. +/// Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_keyexpr_new_autocanonize( - this: *mut MaybeUninit, name: *const c_char, -) -> i8 { - let this = z_owned_keyexpr_t::transmute_uninit_ptr(this); + this: *mut MaybeUninit, +) -> ZCError { if name.is_null() { - Inplace::empty(this); - return -1; + return errors::Z_EINVAL; } - let name = std::slice::from_raw_parts(name as _, libc::strlen(name)); - match std::str::from_utf8(name) { - Ok(name) => { - let name_owned = name.to_owned(); - match KeyExpr::autocanonize(name_owned) { - Ok(v) => { - Inplace::init(this, Some(v)); - 0 - } - Err(e) => { - log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); - Inplace::empty(this); - -1 - } - } - } + let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); + let this = this.transmute_uninit_ptr(); + match keyexpr_create(name, true, true) { + Ok(ke) => { + Inplace::init(this, Some(ke)); + errors::Z_OK + }, Err(e) => { - log::error!("{}", e); Inplace::empty(this); - -1 + e } } } /// Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. #[no_mangle] -pub extern "C" fn z_keyexpr_loan(keyexpr: &z_owned_keyexpr_t) -> z_keyexpr_t { - unwrap_ref_unchecked(keyexpr.transmute_ref()).transmute_copy() +pub extern "C" fn z_keyexpr_loan(key_expr: &'static z_owned_keyexpr_t) -> z_keyexpr_t { + unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() } /// Frees `keyexpr` and invalidates it for double-drop safety. @@ -166,7 +162,7 @@ pub extern "C" fn z_keyexpr_check(keyexpr: &z_owned_keyexpr_t) -> bool { /// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, /// both for local processing and network-wise. pub use crate::opaque_types::z_keyexpr_t; -decl_transmute_copy!(&'static KeyExpr<'static>, z_keyexpr_t); +decl_transmute_handle!(KeyExpr<'static>, z_keyexpr_t); #[derive(Debug, Clone, Copy)] pub struct UninitializedKeyExprError; @@ -181,20 +177,11 @@ impl std::error::Error for UninitializedKeyExprError {} /// Otherwise returns error value #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_is_canon(start: *const c_char, len: usize) -> i8 { - let name = std::slice::from_raw_parts(start as _, len); - match std::str::from_utf8(name) { - Ok(name) => match keyexpr::new(name) { - Ok(_) => 0, - Err(e) => { - log::error!("Couldn't construct a keyexpr from `{}`: {}", name, e); - e.errno().get() - } - }, - Err(e) => { - log::error!("{:02x?} is not valid UTF8 {}", name, e); - i8::MIN - } +pub unsafe extern "C" fn z_keyexpr_is_canon(start: *const c_char, len: usize) -> ZCError { + let name = std::slice::from_raw_parts_mut(start as _, len); + match keyexpr_create(name, false, false) { + Ok(_) => errors::Z_OK, + Err(e) => e, } } @@ -207,12 +194,12 @@ pub unsafe extern "C" fn z_keyexpr_is_canon(start: *const c_char, len: usize) -> /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_canonize_null_terminated(start: *mut c_char) -> i8 { +pub unsafe extern "C" fn z_keyexpr_canonize_null_terminated(start: *mut c_char) -> ZCError { let mut len = libc::strlen(start); match z_keyexpr_canonize(start, &mut len) { - 0 => { + Z_OK => { *start.add(len) = 0; - 0 + Z_OK } err => err, } @@ -226,90 +213,104 @@ pub unsafe extern "C" fn z_keyexpr_canonize_null_terminated(start: *mut c_char) /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) -> i8 { +pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) -> ZCError { let name = std::slice::from_raw_parts_mut(start as _, *len); - match std::str::from_utf8_mut(name) { - Ok(mut name) => match keyexpr::autocanonize(&mut name) { - Ok(k) => { - *len = k.len(); - 0 - } - Err(e) => { - log::error!("Canonization error: {e}"); - e.errno().get() - } + match keyexpr_create(name, true, false) { + Ok(ke) => { + *len = ke.len(); + errors::Z_OK }, - Err(e) => { - log::error!("{:02x?} is not valid UTF8 {}", name, e); - i8::MIN - } + Err(e) => e, } } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string. -/// It is a loaned key expression that aliases `name`. +/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn zc_keyexpr_from_slice(name: *const c_char, len: usize) -> z_keyexpr_t { - let name = std::slice::from_raw_parts(name as _, len); - match std::str::from_utf8(name) { - Ok(name) => match KeyExpr::try_from(name) { - Ok(v) => v.into(), - Err(e) => { - log::error!("Couldn't construct a keyexpr from `{}`: {}", name, e); - z_keyexpr_t::null() - } +pub unsafe extern "C" fn zc_keyexpr_from_slice(this: *mut MaybeUninit, name: *const c_char, len: usize) -> ZCError { + let this = this.transmute_uninit_ptr(); + if name.is_null() { + Inplace::empty(this); + return errors::Z_EINVAL; + } + let name = std::slice::from_raw_parts_mut(name as _, len); + + match keyexpr_create(name, false, false) { + Ok(ke) => { + Inplace::init(this, Some(ke)); + errors::Z_OK }, Err(e) => { - log::error!("{:02x?} is not valid UTF8 {}", name, e); - z_keyexpr_t::null() + Inplace::empty(this); + e } } } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string. -/// It is a loaned key expression that aliases `name`. +/// Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. /// The string is canonized in-place before being passed to keyexpr. /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( + this: *mut MaybeUninit, name: *mut c_char, len: &mut usize, -) -> z_keyexpr_t { - if z_keyexpr_canonize(name, len) < 0 { - return z_keyexpr_t::null(); +) -> ZCError { + let this = this.transmute_uninit_ptr(); + if name.is_null() { + Inplace::empty(this); + return errors::Z_EINVAL; + } + let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); + + match keyexpr_create(name, true, false) { + Ok(ke) => { + *len = ke.len(); + Inplace::init(this, Some(ke)); + errors::Z_OK + }, + Err(e) => { + Inplace::empty(this); + e + } } - zc_keyexpr_from_slice(name, *len) } /// Constructs a :c:type:`z_keyexpr_t` departing from a string. /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr(name: *const c_char) -> z_keyexpr_t { +pub unsafe extern "C" fn z_keyexpr(this: *mut MaybeUninit, name: *const c_char) -> ZCError { if name.is_null() { - z_keyexpr_t::null() + Inplace::empty(this.transmute_uninit_ptr()); + return errors::Z_EINVAL; } else { - zc_keyexpr_from_slice(name, libc::strlen(name)) + let len = libc::strlen(name); + zc_keyexpr_from_slice(this, name, len) } } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string. -/// It is a loaned key expression that aliases `name`. +/// Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. /// The string is canonized in-place before being passed to keyexpr. /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_autocanonize(name: *mut c_char) -> z_keyexpr_t { - if name.is_null() || z_keyexpr_canonize_null_terminated(name) < 0 { - z_keyexpr_t::null() +pub unsafe extern "C" fn z_keyexpr_autocanonize(this: *mut MaybeUninit, name: *mut c_char) -> ZCError { + if name.is_null() { + Inplace::empty(this.transmute_uninit_ptr()); + return errors::Z_EINVAL; } else { - z_keyexpr(name) + let mut len = libc::strlen(name); + let res = zc_keyexpr_from_slice_autocanonize(this, name, &mut len); + if res == errors::Z_OK { + *name.add(len) = 0; + } + res } } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: /// - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. @@ -320,16 +321,17 @@ pub unsafe extern "C" fn z_keyexpr_autocanonize(name: *mut c_char) -> z_keyexpr_ #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( + this: *mut MaybeUninit, start: *const c_char, len: usize, -) -> z_keyexpr_t { +) { let name = std::slice::from_raw_parts(start as _, len); let name = std::str::from_utf8_unchecked(name); let name: KeyExpr = keyexpr::from_str_unchecked(name).into(); - name.into() + Inplace::init(this.transmute_uninit_ptr(), Some(name)); } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string without checking any of `z_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: /// /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: @@ -341,19 +343,16 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_unchecked(name: *const c_char) -> z_keyexpr_t { - zc_keyexpr_from_slice_unchecked(name, libc::strlen(name)) +pub unsafe extern "C" fn z_keyexpr_unchecked(this: *mut MaybeUninit, name: *const c_char) { + zc_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) } /// Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. /// The user is responsible of droping the returned string using `z_drop` #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_to_string(keyexpr: z_keyexpr_t) -> z_owned_str_t { - match keyexpr.as_ref() { - Some(ke) => ke.as_bytes().into(), - None => z_str_null(), - } +pub unsafe extern "C" fn z_keyexpr_to_string(ke: z_keyexpr_t) -> z_owned_str_t { + ke.transmute_ref().as_bytes().into() } /// Returns the key expression's internal string by aliasing it. @@ -361,28 +360,17 @@ pub unsafe extern "C" fn z_keyexpr_to_string(keyexpr: z_keyexpr_t) -> z_owned_st /// Currently exclusive to zenoh-c #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_keyexpr_as_bytes(keyexpr: z_keyexpr_t) -> z_bytes_t { - match keyexpr.as_ref() { - Some(ke) => z_bytes_t { - start: ke.as_ptr(), - len: ke.len(), - }, - None => z_bytes_t { - start: std::ptr::null(), - len: 0, - }, +pub extern "C" fn z_keyexpr_as_bytes(ke: z_keyexpr_t) -> z_slice_t { + let ke = ke.transmute_ref(); + z_slice_t { + start: ke.as_ptr(), + len: ke.len() } } -impl<'a> From<&'a z_owned_keyexpr_t> for z_keyexpr_t { - fn from(oke: &'a z_owned_keyexpr_t) -> Self { - unsafe { std::mem::transmute_copy(oke) } - } -} - -impl<'a> From<&'a KeyExpr<'a>> for z_keyexpr_t { - fn from(key: &'a KeyExpr<'a>) -> Self { - key.borrowing_clone().into() +impl<'a> From<&'static KeyExpr<'static>> for z_keyexpr_t { + fn from(key: &'static KeyExpr<'static>) -> Self { + key.transmute_handle() } } @@ -398,103 +386,70 @@ impl<'a> From<&'a KeyExpr<'a>> for z_keyexpr_t { pub extern "C" fn z_declare_keyexpr( this: *mut MaybeUninit, session: z_session_t, - keyexpr: z_keyexpr_t, -) -> i8 { - let this = z_owned_keyexpr_t::transmute_uninit_ptr(this); - let key_expr = keyexpr.transmute_copy(); - let session = session.transmute_ref(); - match session.upgrade() { - Some(s) => match s.declare_keyexpr(key_expr).res_sync() { - Ok(id) => { - id.into_owned().into(); - // TODO: store id to keyexpr - } - Err(e) => { - log::debug!("{}", e); - Inplace::empty(this); - i8::MIN - } - }, - None => { - log::debug!("{}", LOG_INVALID_SESSION); + key_expr: z_keyexpr_t, +) -> ZCError { + let this = this.transmute_uninit_ptr(); + let key_expr = key_expr.transmute_ref(); + let session = session.transmute_copy(); + match session.declare_keyexpr(key_expr).res_sync() { + Ok(id) => { + Inplace::init(this, Some(id.into_owned())); + errors::Z_OK + } + Err(e) => { + log::debug!("{}", e); Inplace::empty(this); - i8::MIN + errors::Z_EGENERIC } } } /// Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. +/// The keyxpr is consumed. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_undeclare_keyexpr(session: z_session_t, kexpr: &mut z_owned_keyexpr_t) -> i8 { - let Some(kexpr) = kexpr.deref_mut().take() else { + let Some(kexpr) = kexpr.transmute_mut().take() else { log::debug!("Attempted to undeclare dropped keyexpr"); return i8::MIN; }; - - match session.upgrade() { - Some(s) => match s.undeclare(kexpr).res() { - Ok(()) => 0, - Err(e) => { - log::debug!("{}", e); - e.errno().get() - } - }, - None => { - log::debug!("{}", LOG_INVALID_SESSION); - i8::MIN + let session = session.transmute_copy(); + match session.undeclare(kexpr).res() { + Ok(()) => errors::Z_OK, + Err(e) => { + log::debug!("{}", e); + errors::Z_EGENERIC } } } #[allow(clippy::missing_safety_doc)] #[no_mangle] -/// Returns ``0`` if both ``left`` and ``right`` are equal. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. -pub extern "C" fn z_keyexpr_equals(left: z_keyexpr_t, right: z_keyexpr_t) -> i8 { - match (&*left, &*right) { - (Some(l), Some(r)) => { - if *l == *r { - 0 - } else { - -1 - } - } - _ => i8::MIN, - } +/// Returns ``0`` if both ``left`` and ``right`` are equal. +pub extern "C" fn z_keyexpr_equals(left: z_keyexpr_t, right: z_keyexpr_t) -> bool { + let l = left.transmute_ref(); + let r = right.transmute_ref(); + *l == *r } #[allow(clippy::missing_safety_doc)] #[no_mangle] /// Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the -/// sets defined by ``left`` and ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. -pub extern "C" fn z_keyexpr_intersects(left: z_keyexpr_t, right: z_keyexpr_t) -> i8 { - match (&*left, &*right) { - (Some(l), Some(r)) => { - if l.intersects(r) { - 0 - } else { - -1 - } - } - _ => i8::MIN, - } +/// sets defined by ``left`` and ``right``. +pub extern "C" fn z_keyexpr_intersects(left: z_keyexpr_t, right: z_keyexpr_t) -> bool { + let l = left.transmute_ref(); + let r = right.transmute_ref(); + l.intersects(r) } #[allow(clippy::missing_safety_doc)] #[no_mangle] /// Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set -/// defined by ``right``. Otherwise, it returns a ``-1``, or other ``negative value`` for errors. -pub extern "C" fn z_keyexpr_includes(left: z_keyexpr_t, right: z_keyexpr_t) -> i8 { - match (&*left, &*right) { - (Some(l), Some(r)) => { - if l.includes(r) { - 0 - } else { - -1 - } - } - _ => i8::MIN, - } +/// defined by ``right``. +pub extern "C" fn z_keyexpr_includes(left: z_keyexpr_t, right: z_keyexpr_t) -> bool { + let l = left.transmute_ref(); + let r = right.transmute_ref(); + l.includes(r) } #[allow(clippy::missing_safety_doc)] @@ -510,11 +465,10 @@ pub unsafe extern "C" fn z_keyexpr_concat( left: z_keyexpr_t, right_start: *const c_char, right_len: usize, -) -> z_owned_keyexpr_t { - let left = match left.as_ref() { - Some(l) => l, - None => return z_owned_keyexpr_t::null(), - }; + this: *mut MaybeUninit +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); + let left = left.transmute_ref(); let right = std::slice::from_raw_parts(right_start as _, right_len); let right = match std::str::from_utf8(right) { Ok(r) => r, @@ -525,14 +479,19 @@ pub unsafe extern "C" fn z_keyexpr_concat( left, e ); - return z_owned_keyexpr_t::null(); + Inplace::empty(this); + return errors::Z_EINVAL; } }; match left.concat(right) { - Ok(result) => result.into(), + Ok(result) => { + Inplace::init(this, Some(result)); + errors::Z_OK + } Err(e) => { log::error!("{}", e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + errors::Z_EGENERIC } } } @@ -541,20 +500,19 @@ pub unsafe extern "C" fn z_keyexpr_concat( #[no_mangle] /// Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. /// In case of error, the return value will be set to its invalidated state. -pub extern "C" fn z_keyexpr_join(left: z_keyexpr_t, right: z_keyexpr_t) -> z_owned_keyexpr_t { - let left = match left.as_ref() { - Some(l) => l, - None => return z_owned_keyexpr_t::null(), - }; - let right = match right.as_ref() { - Some(r) => r, - None => return z_owned_keyexpr_t::null(), - }; +pub extern "C" fn z_keyexpr_join(left: z_keyexpr_t, right: z_keyexpr_t, this: *mut MaybeUninit) -> errors::ZCError { + let left = left.transmute_ref(); + let right = right.transmute_ref(); + let this = this.transmute_uninit_ptr(); match left.join(right.as_str()) { - Ok(result) => result.into(), + Ok(result) => { + Inplace::init(this, Some(result)); + errors::Z_OK + } Err(e) => { log::error!("{}", e); - z_owned_keyexpr_t::null() + Inplace::empty(this); + errors::Z_EGENERIC } } } @@ -593,8 +551,7 @@ pub extern "C" fn z_keyexpr_relation_to( left: z_keyexpr_t, right: z_keyexpr_t, ) -> z_keyexpr_intersection_level_t { - match (&*left, &*right) { - (Some(l), Some(r)) => l.relation_to(r).into(), - _ => z_keyexpr_intersection_level_t::DISJOINT, - } + let l = left.transmute_ref(); + let r = right.transmute_ref(); + l.relation_to(r).into() } diff --git a/src/lib.rs b/src/lib.rs index dde332eaf..ad25e1e28 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,6 +24,7 @@ pub mod opaque_types; pub use crate::opaque_types::*; mod collections; +pub mod errors; pub use crate::collections::*; mod config; pub use crate::config::*; @@ -31,28 +32,28 @@ mod commons; pub use crate::commons::*; mod payload; pub use crate::payload::*; -// mod keyexpr; -// pub use crate::keyexpr::*; -// mod info; -// pub use crate::info::*; -// mod get; -// pub use crate::get::*; -// mod queryable; -// pub use crate::queryable::*; +mod keyexpr; +pub use crate::keyexpr::*; +mod info; +pub use crate::info::*; +mod get; +pub use crate::get::*; +mod queryable; +pub use crate::queryable::*; // mod put; // pub use crate::put::*; -// mod scouting; -// pub use crate::scouting::*; +mod scouting; +pub use crate::scouting::*; mod session; pub use crate::session::*; // mod subscriber; // pub use crate::subscriber::*; // // mod pull_subscriber; // // pub use crate::pull_subscriber::*; -// mod publisher; -// pub use crate::publisher::*; -// mod closures; -// pub use closures::*; +mod publisher; +pub use crate::publisher::*; +mod closures; +pub use closures::*; // mod liveliness; // pub use liveliness::*; // mod publication_cache; @@ -60,7 +61,6 @@ pub use crate::session::*; // // Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. // // mod querying_subscriber; // // pub use querying_subscriber::*; -// pub mod attachment; // pub use platform::*; // pub mod platform; // #[cfg(feature = "shared-memory")] diff --git a/src/payload.rs b/src/payload.rs index 8959e8ac2..4ed3feb3e 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,175 +1,116 @@ +use crate::errors::{self, ZCError}; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef, TransmuteUninitPtr, + unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }; -use crate::{z_bytes_empty, z_bytes_t, z_owned_bytes_t, z_owned_str_t}; +use crate::{z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, ZHashMap}; use core::slice; use std::any::Any; +use std::borrow::Cow; +use std::io::{Read, Seek, SeekFrom}; use std::mem::MaybeUninit; use std::slice::from_raw_parts_mut; -use zenoh::buffers::HasReader; -use zenoh::buffers::Reader; -use zenoh::buffers::ZBufReader; -use zenoh::buffers::{SplitBuffer, ZBuf, ZSliceBuffer}; +use zenoh::buffers::{ZSlice, ZSliceBuffer}; +use zenoh::bytes::{ZBytes, ZBytesReader}; -pub use crate::opaque_types::z_owned_buffer_t; -decl_transmute_owned!(Option, z_owned_buffer_t); +pub use crate::opaque_types::z_owned_bytes_t; +decl_transmute_owned!(Option, z_owned_bytes_t); -/// The gravestone value for `z_owned_buffer_t`. +/// The gravestone value for `z_owned_bytes_t`. #[no_mangle] -extern "C" fn z_buffer_null(this: *mut MaybeUninit) { +extern "C" fn z_bytes_null(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); Inplace::empty(this); } -/// Decrements the buffer's reference counter, destroying it if applicable. +/// Decrements the payload's reference counter, destroying it if applicable. /// -/// `buffer` will be reset to `z_buffer_null`, preventing UB on double-frees. +/// `this` will be reset to `z_buffer_null`, preventing UB on double-frees. #[no_mangle] -extern "C" fn z_buffer_drop(buffer: &mut z_owned_buffer_t) { - let buffer = buffer.transmute_mut(); - Inplace::drop(buffer); +extern "C" fn z_bytes_drop(this: &mut z_owned_bytes_t) { + let this = this.transmute_mut(); + Inplace::drop(this); } -/// Returns `true` if the buffer is in a valid state. +/// Returns `true` if the payload is in a valid state. #[no_mangle] -extern "C" fn z_buffer_check(buffer: &z_owned_buffer_t) -> bool { - buffer.transmute_ref().is_some() +extern "C" fn z_bytes_check(payload: &z_owned_bytes_t) -> bool { + payload.transmute_ref().is_some() } -/// Loans the buffer, allowing you to call functions that only need a loan of it. +/// Loans the payload, allowing you to call functions that only need a loan of it. #[no_mangle] -extern "C" fn z_buffer_loan(buffer: &z_owned_buffer_t) -> z_buffer_t { - let buffer = buffer.transmute_ref(); - let buffer = unwrap_ref_unchecked(buffer); - buffer.transmute_copy() +extern "C" fn z_bytes_loan(payload: &'static z_owned_bytes_t) -> z_bytes_t { + let payload = payload.transmute_ref(); + let payload = unwrap_ref_unchecked(payload); + payload.transmute_handle() } -/// A loan of a `z_owned_buffer_t`. -/// -/// As it is a split buffer, it may contain more than one slice. It's number of slices is returned by `z_buffer_slice_count`. -pub use crate::opaque_types::z_buffer_t; -decl_transmute_copy!(&'static ZBuf, z_buffer_t); +pub use crate::opaque_types::z_bytes_t; +decl_transmute_handle!(ZBytes, z_bytes_t); -/// Increments the buffer's reference count, returning an owned version of the buffer. +/// Increments the payload's reference count, returning an owned version of it. #[no_mangle] -extern "C" fn z_buffer_clone(dst: *mut MaybeUninit, buffer: &z_owned_buffer_t) { +extern "C" fn z_bytes_clone(src: &z_owned_bytes_t, dst: *mut MaybeUninit) { let dst = dst.transmute_uninit_ptr(); - let buffer = buffer.transmute_ref(); - let buffer = buffer.as_ref().map(Clone::clone); - Inplace::init(dst, buffer); -} - -/// Returns the number of slices in the buffer. -/// -/// If the return value is 0 or 1, then the buffer's data is contiguous in memory. -#[no_mangle] -extern "C" fn z_buffer_slice_count(buffer: z_buffer_t) -> usize { - ZBuf::slices(buffer.transmute_copy()).len() + let src = src.transmute_ref(); + let src = src.as_ref().map(Clone::clone); + Inplace::init(dst, src); } -/// Returns total number bytes in the buffer. -#[no_mangle] -extern "C" fn z_buffer_len(buffer: z_buffer_t) -> usize { - ZBuf::slices(buffer.transmute_copy()).fold(0, |acc, s| acc + s.len()) -} - -/// Returns the `index`th slice of the buffer, aliasing it. -/// -/// Out of bounds accesses will return `z_bytes_empty`. -#[no_mangle] -extern "C" fn z_buffer_slice_at(buffer: z_buffer_t, index: usize) -> z_bytes_t { - let buf = buffer.transmute_copy(); - ZBuf::slices(buf) - .nth(index) - .map_or(z_bytes_empty(), |slice| slice.into()) -} - -/// An owned payload, backed by a reference counted owner. -/// -/// The `payload` field may be modified, and Zenoh will take the new values into account. -#[allow(non_camel_case_types)] -pub type zc_owned_payload_t = z_owned_buffer_t; - -/// Clones the `payload` by incrementing its reference counter. -#[no_mangle] -pub extern "C" fn zc_payload_rcinc( - dst: *mut MaybeUninit, - payload: &zc_owned_payload_t, -) { - z_buffer_clone(dst, payload) -} -/// Returns `false` if `payload` is the gravestone value. -#[no_mangle] -pub extern "C" fn zc_payload_check(payload: &zc_owned_payload_t) -> bool { - z_buffer_check(payload) -} -/// Decrements `payload`'s backing refcount, releasing the memory if appropriate. -#[no_mangle] -pub extern "C" fn zc_payload_drop(payload: &mut zc_owned_payload_t) { - z_buffer_drop(payload) -} -/// Constructs `zc_owned_payload_t`'s gravestone value. -#[no_mangle] -pub extern "C" fn zc_payload_null(this: *mut MaybeUninit) { - z_buffer_null(this); -} - -/// Returns a :c:type:`zc_payload_t` loaned from `payload`. +/// Returns total number bytes in the payload. #[no_mangle] -pub extern "C" fn zc_payload_loan(payload: &zc_owned_payload_t) -> zc_payload_t { - z_buffer_loan(payload) +extern "C" fn z_bytes_len(payload: z_bytes_t) -> usize { + payload.transmute_ref().len() } -#[allow(non_camel_case_types)] -pub type zc_payload_t = z_buffer_t; - -/// Increments internal payload reference count, returning owned payload. +/// Decodes payload into null-terminated string. #[no_mangle] -pub extern "C" fn zc_payload_clone( - dst: *mut MaybeUninit, - payload: &zc_owned_payload_t, -) { - z_buffer_clone(dst, payload) +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_bytes_decode_into_string( + payload: z_bytes_t, + dst: *mut MaybeUninit, +) -> ZCError { + let len = z_bytes_len(payload); + let cstr = z_owned_str_t::preallocate(len); + let payload = payload.transmute_ref(); + payload.reader().read(from_raw_parts_mut(cstr._cstr as *mut u8, len)); + Inplace::init(dst, cstr); + errors::Z_OK } -/// Decodes payload into null-terminated string +/// Decodes payload into bytes map. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_string( - payload: zc_payload_t, - cstr: &mut z_owned_str_t, -) -> i8 { - *cstr = z_owned_str_t::preallocate(zc_payload_len(payload)); - let payload = payload.transmute_copy(); - let mut pos = 0; - for s in payload.slices() { - cstr.insert_unchecked(pos, s); - pos += s.len(); - } - 0 +pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( + payload: z_bytes_t, + dst: *mut MaybeUninit, +) -> ZCError { + let dst = dst.transmute_uninit_ptr(); + let payload = payload.transmute_ref(); + let hm = ZHashMap::from_iter(payload.iter::<(Cow<'static, [u8]>, Cow<'static, [u8]>)>()); + Inplace::init(dst, Some(hm)); + errors::Z_OK } -/// Decodes payload into null-terminated string +/// Decodes payload into owned bytes #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_decode_into_bytes( - payload: zc_payload_t, - b: &mut z_owned_bytes_t, -) -> i8 { - *b = z_owned_bytes_t::preallocate(zc_payload_len(payload)); - let payload = payload.transmute_copy(); - let mut pos = 0; - for s in payload.slices() { - b.insert_unchecked(pos, s); - pos += s.len(); - } - 0 +pub unsafe extern "C" fn z_bytes_decode_into_bytes( + payload: z_bytes_t, + dst: *mut MaybeUninit, +) -> ZCError { + let len = z_bytes_len(payload); + let b = z_owned_slice_t::preallocate(len); + let payload = payload.transmute_ref(); + payload.reader().read(from_raw_parts_mut(b.start, len)); + Inplace::init(dst, b); + errors::Z_OK } -unsafe impl Send for z_bytes_t {} -unsafe impl Sync for z_bytes_t {} +unsafe impl Send for z_slice_t {} +unsafe impl Sync for z_slice_t {} -impl ZSliceBuffer for z_bytes_t { +impl ZSliceBuffer for z_slice_t { fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.start, self.len) } } @@ -184,77 +125,132 @@ impl ZSliceBuffer for z_bytes_t { /// Encodes byte sequence by aliasing. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_encode_from_bytes( - dst: *mut MaybeUninit, - bytes: z_bytes_t, +pub unsafe extern "C" fn z_bytes_encode_from_bytes( + this: *mut MaybeUninit, + bytes: z_slice_t, ) { - let dst = dst.transmute_uninit_ptr(); - let buf = ZBuf::from(bytes); - Inplace::init(dst, Some(buf)); + let this = this.transmute_uninit_ptr(); + let payload = ZBytes::from(ZSlice::from(bytes)); + Inplace::init(this, Some(payload)); +} + +/// Encodes bytes map by copying. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_bytes_encode_from_bytes_map( + this: *mut MaybeUninit, + bytes_map: z_slice_map_t, +) { + let dst = this.transmute_uninit_ptr(); + let hm = bytes_map.transmute_ref(); + let payload = ZBytes::from_iter(hm.iter()); + Inplace::init(dst, Some(payload)); } /// Encodes a null-terminated string by aliasing. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_encode_from_string( - dst: *mut MaybeUninit, +pub unsafe extern "C" fn z_bytes_encode_from_string( + this: *mut MaybeUninit, cstr: *const libc::c_char, ) { - let bytes = z_bytes_t { + let bytes = z_slice_t { start: cstr as *const u8, len: libc::strlen(cstr), }; - zc_payload_encode_from_bytes(dst, bytes); -} - -/// Returns total number bytes in the payload. -#[no_mangle] -pub extern "C" fn zc_payload_len(payload: zc_payload_t) -> usize { - z_buffer_len(payload) + z_bytes_encode_from_bytes(this, bytes); } -pub use crate::opaque_types::zc_owned_payload_reader; -decl_transmute_owned!(Option>, zc_owned_payload_reader); +pub use crate::opaque_types::z_owned_bytes_t_reader_t; +decl_transmute_owned!(Option>, z_owned_bytes_t_reader_t); -pub use crate::opaque_types::zc_payload_reader; -decl_transmute_copy!(&'static ZBufReader<'static>, zc_payload_reader); +pub use crate::opaque_types::z_bytes_reader_t; +decl_transmute_handle!(ZBytesReader<'static>, z_bytes_reader_t); /// Creates a reader for the specified `payload`. /// /// Returns 0 in case of success, -1 if `payload` is not valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_reader_init( - this: *mut MaybeUninit, - payload: zc_payload_t, +pub unsafe extern "C" fn z_bytes_reader_new( + payload: z_bytes_t, + this: *mut MaybeUninit, ) { let this = this.transmute_uninit_ptr(); - let payload = payload.transmute_copy(); + let payload = payload.transmute_ref(); let reader = payload.reader(); Inplace::init(this, Some(reader)); } +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_bytes_reader_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_bytes_reader_check(reader: &z_owned_bytes_t_reader_t) -> bool { + let reader = reader.transmute_ref(); + reader.as_ref().is_some() +} + +#[no_mangle] +extern "C" fn z_bytes_reader_drop(this: &mut z_owned_bytes_t_reader_t) { + let reader = this.transmute_mut(); + Inplace::drop(reader); +} + +#[no_mangle] +extern "C" fn z_bytes_reader_loan(reader: &'static z_owned_bytes_t_reader_t) -> z_bytes_reader_t { + let reader = reader.transmute_ref(); + let reader = unwrap_ref_unchecked(reader); + reader.transmute_handle() +} + /// Reads data into specified destination. /// /// Will read at most `len` bytes. /// Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_reader_read( - reader: zc_payload_reader, +pub unsafe extern "C" fn z_bytes_reader_read( + reader: z_bytes_reader_t, dest: *mut u8, len: usize, ) -> usize { - let reader = reader.transmute_copy(); + let reader = reader.transmute_mut(); let buf = unsafe { from_raw_parts_mut(dest, len) }; - reader.read(buf).map(|n| n.get()).unwrap_or(0) + reader.read(buf).unwrap_or(0) } -/// Returns number of the remaining bytes in the payload -/// +/// Sets the `reader` position indicator for the payload to the value pointed to by offset. +/// The new position is exactly offset bytes measured from the beginning of the payload if origin is SEEK_SET, +/// from the current reader position if origin is SEEK_CUR, and from the end of the payload if origin is SEEK_END. +/// Return ​0​ upon success, negative error code otherwise. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_bytes_reader_seek(reader: z_bytes_reader_t, offset: i64, origin: libc::c_int) -> ZCError { + let reader = reader.transmute_mut(); + let pos = match origin { + libc::SEEK_SET => offset.try_into().map(|r| SeekFrom::Start(r)), + libc::SEEK_CUR => Ok(SeekFrom::Current(offset)), + libc::SEEK_END => Ok(SeekFrom::End(offset)), + _ => { return errors::Z_EINVAL; } + }; + match pos.map(|p| reader.seek(p)) { + Ok(_) => 0, + Err(_) => errors::Z_EINVAL + } +} + +/// Returns the read position indicator. +/// Returns read position indicator on success or -1L if failure occurs. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_payload_reader_remaining(reader: zc_payload_reader) -> usize { - let reader = reader.transmute_copy(); - reader.remaining() +pub unsafe extern "C" fn z_bytes_reader_tell(reader: z_bytes_reader_t) -> i64 { + let reader = reader.transmute_mut(); + reader.stream_position().map(|p| p as i64).unwrap_or(-1) } + diff --git a/src/publisher.rs b/src/publisher.rs index c829a8533..833798959 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -12,32 +12,36 @@ // ZettaScale Zenoh team, // +use crate::errors; +use crate::transmute::unwrap_ref_unchecked; +use crate::transmute::Inplace; +use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; +use crate::transmute::TransmuteIntoHandle; +use crate::transmute::TransmuteRef; +use crate::transmute::TransmuteUninitPtr; +use crate::z_owned_encoding_t; use crate::zcu_closure_matching_status_call; use crate::zcu_owned_closure_matching_status_t; -use std::ops::{Deref, DerefMut}; -use zenoh::encoding::Encoding; +use std::mem::MaybeUninit; +use std::ptr; +use zenoh::handlers::DefaultHandler; use zenoh::prelude::SessionDeclarations; use zenoh::publication::CongestionControl; use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; use zenoh::{ - prelude::{Priority, Value}, + prelude::Priority, publication::MatchingListener, publication::Publisher, - sample::AttachmentBuilder, }; -use crate::attachment::{ - insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, - z_attachment_t, -}; -use libc::c_void; +use zenoh::prelude::SyncResolve; use crate::{ - impl_guarded_transmute, z_congestion_control_t, z_encoding_default, z_encoding_t, z_keyexpr_t, - z_owned_keyexpr_t, z_priority_t, z_session_t, zc_owned_payload_t, GuardedTransmute, - UninitializedKeyExprError, LOG_INVALID_SESSION, + z_congestion_control_t, z_keyexpr_t, + z_priority_t, z_session_t, z_owned_bytes_t }; /// Options passed to the :c:func:`z_declare_publisher` function. @@ -60,47 +64,10 @@ pub extern "C" fn z_publisher_options_default() -> z_publisher_options_t { } } -/// An owned zenoh publisher. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_publisher_t([u64; 7]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_owned_publisher_t([u32; 8]); - -impl_guarded_transmute!(noderefs Option>, z_owned_publisher_t); - -impl<'a> From>> for z_owned_publisher_t { - fn from(val: Option) -> Self { - val.transmute() - } -} -impl Deref for z_owned_publisher_t { - type Target = Option>; - fn deref(&self) -> &Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl DerefMut for z_owned_publisher_t { - fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { std::mem::transmute(self) } - } -} -impl z_owned_publisher_t { - pub fn null() -> Self { - None.into() - } -} +pub use crate::opaque_types::z_owned_publisher_t; +decl_transmute_owned!(Option>, z_owned_publisher_t); +pub use crate::opaque_types::z_publisher_t; +decl_transmute_copy!(&'static Publisher<'static>, z_publisher_t); /// Declares a publisher for the given key expression. /// @@ -109,7 +76,7 @@ impl z_owned_publisher_t { /// /// Parameters: /// session: The zenoh session. -/// keyexpr: The key expression to publish. +/// key_expr: The key expression to publish. /// options: additional options for the publisher. /// /// Returns: @@ -139,92 +106,64 @@ impl z_owned_publisher_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_publisher( session: z_session_t, - keyexpr: z_keyexpr_t, + key_expr: z_keyexpr_t, options: Option<&z_publisher_options_t>, -) -> z_owned_publisher_t { - match session.upgrade() { - Some(s) => { - let keyexpr = keyexpr.deref().as_ref().map(|s| s.clone().into_owned()); - if let Some(key_expr) = keyexpr { - let mut p = s.declare_publisher(key_expr); - if let Some(options) = options { - p = p - .congestion_control(options.congestion_control.into()) - .priority(options.priority.into()); - } - match p.res_sync() { - Err(e) => { - log::error!("{}", e); - None - } - Ok(publisher) => Some(publisher), - } - } else { - log::error!("{}", UninitializedKeyExprError); - None - } + this: *mut MaybeUninit, +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref().clone().into_owned(); + let mut p = session.declare_publisher(key_expr); + if let Some(options) = options { + p = p + .congestion_control(options.congestion_control.into()) + .priority(options.priority.into()); + } + match p.res_sync() { + Err(e) => { + log::error!("{}", e); + Inplace::empty(this); + errors::Z_EGENERIC } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - None + Ok(publisher) => { + Inplace::init(this, Some(publisher)); + errors::Z_OK } } - .into() } /// Constructs a null safe-to-drop value of 'z_owned_publisher_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_publisher_null() -> z_owned_publisher_t { - z_owned_publisher_t::null() +pub extern "C" fn z_publisher_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); } /// Returns ``true`` if `pub` is valid. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_publisher_check(pbl: &z_owned_publisher_t) -> bool { - pbl.as_ref().is_some() -} - -/// A loaned zenoh publisher. -#[allow(non_camel_case_types)] -#[derive(Clone, Copy)] -#[repr(C)] -pub struct z_publisher_t(*const z_owned_publisher_t); - -impl<'a> AsRef>> for z_owned_publisher_t { - fn as_ref(&self) -> &'a Option> { - unsafe { std::mem::transmute(self) } - } -} - -impl<'a> AsMut>> for z_owned_publisher_t { - fn as_mut(&mut self) -> &'a mut Option> { - unsafe { std::mem::transmute(self) } - } -} - -impl<'a> AsRef>> for z_publisher_t { - fn as_ref(&self) -> &'a Option> { - unsafe { (*self.0).as_ref() } - } +pub extern "C" fn z_publisher_check(pbl: &'static z_owned_publisher_t) -> bool { + pbl.transmute_ref().is_some() } /// Returns a :c:type:`z_publisher_t` loaned from `p`. #[no_mangle] -pub extern "C" fn z_publisher_loan(p: &z_owned_publisher_t) -> z_publisher_t { - z_publisher_t(p) +pub extern "C" fn z_publisher_loan(p: &'static z_owned_publisher_t) -> z_publisher_t { + let p = p.transmute_ref(); + let p = unwrap_ref_unchecked(p); + p.transmute_copy() } /// Options passed to the :c:func:`z_publisher_put` function. /// /// Members: -/// z_encoding_t encoding: The encoding of the payload. -/// z_attachment_t attachment: The attachment to attach to the publication. +/// z_owned_encoding_t encoding: The encoding of the payload. +/// z_owned_bytes_t attachment: The attachment to attach to the publication. #[repr(C)] pub struct z_publisher_put_options_t { - pub encoding: z_encoding_t, - pub attachment: z_attachment_t, + pub encoding: *mut z_owned_encoding_t, + pub attachment: *mut z_owned_bytes_t, } /// Constructs the default value for :c:type:`z_publisher_put_options_t`. @@ -232,8 +171,8 @@ pub struct z_publisher_put_options_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t { z_publisher_put_options_t { - encoding: z_encoding_default(), - attachment: z_attachment_null(), + encoding: ptr::null_mut(), + attachment: ptr::null_mut(), } } @@ -243,7 +182,7 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t /// - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher /// - constructed from a `zc_owned_shmbuf_t` /// -/// The payload's encoding can be sepcified through the options. +/// The payload and all owned options fields are consumed upon function return. /// /// Parameters: /// session: The zenoh session. @@ -255,39 +194,34 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_publisher_put( publisher: z_publisher_t, - payload: Option<&mut zc_owned_payload_t>, - options: Option<&z_publisher_put_options_t>, -) -> i8 { - if let Some(p) = publisher.as_ref() { - let Some(payload) = payload.and_then(|p| p.take()) else { - log::debug!("Attempted to put without a payload"); - return i8::MIN; - }; - let put = match options { - Some(options) => { - let encoding = *options.encoding; - let mut put = p.put(payload).encoding(*encoding); - if z_attachment_check(&options.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - options.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - put = put.attachment(attachment_builder.build()); - }; - put - } - None => p.put(payload), - }; - if let Err(e) = put.res_sync() { - log::error!("{}", e); - e.errno().get() - } else { - 0 + payload: &mut z_owned_bytes_t, + options: z_publisher_put_options_t, +) -> errors::ZCError { + let publisher = publisher.transmute_copy(); + let payload = match payload.transmute_mut().extract() { + Some(p) => p, + None => { + log::debug!("Attempted to put with a null payload"); + return errors::Z_EINVAL; } + }; + + let mut put = publisher.put(payload); + + if !options.encoding.is_null() { + let encoding = unsafe{ *options.encoding }.transmute_mut().extract(); + put = put.encoding(encoding); + }; + if !options.attachment.is_null() { + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + put = put.attachment(attachment); + } + + if let Err(e) = put.res_sync() { + log::error!("{}", e); + errors::Z_EGENERIC } else { - i8::MIN + errors::Z_OK } } @@ -315,60 +249,28 @@ pub extern "C" fn z_publisher_delete_options_default() -> z_publisher_delete_opt #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_publisher_delete( publisher: z_publisher_t, - _options: *const z_publisher_delete_options_t, -) -> i8 { - if let Some(p) = publisher.as_ref() { - if let Err(e) = p.delete().res_sync() { - log::error!("{}", e); - e.errno().get() - } else { - 0 - } + _options: z_publisher_delete_options_t, +) -> errors::ZCError { + let publisher = publisher.transmute_copy(); + + if let Err(e) = publisher.delete().res_sync() { + log::error!("{}", e); + errors::Z_EGENERIC } else { - i8::MIN + errors::Z_OK } } /// Returns the key expression of the publisher #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_owned_keyexpr_t { - if let Some(p) = publisher.as_ref() { - p.key_expr().clone().into() - } else { - z_keyexpr_t::null().into() - } +pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_keyexpr_t { + let publisher = publisher.transmute_copy(); + publisher.key_expr().transmute_handle() } -/// An owned zenoh matching listener. Destroying the matching listener cancels the subscription. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[repr(C, align(8))] -pub struct zcu_owned_matching_listener_t([u64; 4]); - -impl_guarded_transmute!(noderefs - Option>, - zcu_owned_matching_listener_t -); - -impl From>> for zcu_owned_matching_listener_t { - fn from(val: Option>) -> Self { - val.transmute() - } -} - -impl zcu_owned_matching_listener_t { - pub fn null() -> Self { - None.into() - } -} +pub use crate::opaque_types::zcu_owned_matching_listener_t; +decl_transmute_owned!(Option>, zcu_owned_matching_listener_t); /// A struct that indicates if there exist Subscribers matching the Publisher's key expression. /// @@ -386,38 +288,42 @@ pub struct zcu_matching_status_t { pub extern "C" fn zcu_publisher_matching_listener_callback( publisher: z_publisher_t, callback: &mut zcu_owned_closure_matching_status_t, -) -> zcu_owned_matching_listener_t { + this: *mut MaybeUninit +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); let mut closure = zcu_owned_closure_matching_status_t::empty(); std::mem::swap(callback, &mut closure); - { - if let Some(p) = publisher.as_ref() { - let listener = p - .matching_listener() - .callback_mut(move |matching_status| { - let status = zcu_matching_status_t { - matching: matching_status.matching_subscribers(), - }; - zcu_closure_matching_status_call(&closure, &status); - }) - .res() - .unwrap(); - Some(listener) - } else { - None - } + let publisher = publisher.transmute_copy(); + let listener = publisher + .matching_listener() + .callback_mut(move |matching_status| { + let status = zcu_matching_status_t { + matching: matching_status.matching_subscribers(), + }; + zcu_closure_matching_status_call(&closure, &status); + }) + .res(); + match listener { + Ok(l) => { + Inplace::empty(this); + errors::Z_OK + }, + Err(e) => { + log::error!("{}", e); + errors::Z_EGENERIC + } } - .into() } /// Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_undeclare_publisher(publisher: &mut z_owned_publisher_t) -> i8 { - if let Some(p) = publisher.take() { +pub extern "C" fn z_undeclare_publisher(publisher: &mut z_owned_publisher_t) -> errors::ZCError { + if let Some(p) = publisher.transmute_mut().extract().take() { if let Err(e) = p.undeclare().res_sync() { log::error!("{}", e); - return e.errno().get(); + return errors::Z_EGENERIC; } } - 0 + errors::Z_OK } diff --git a/src/put.rs b/src/put.rs index 59e9e5e3c..c2d1bddd2 100644 --- a/src/put.rs +++ b/src/put.rs @@ -14,7 +14,7 @@ use crate::commons::*; use crate::keyexpr::*; use crate::session::*; -use crate::zc_owned_payload_t; +use crate::z_owned_bytes_t; use crate::LOG_INVALID_SESSION; use libc::c_void; use zenoh::encoding; @@ -27,103 +27,23 @@ use zenoh::sample::ValueBuilderTrait; use crate::attachment::{ insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, - z_attachment_t, + z_bytes_t, }; -/// The priority of zenoh messages. -/// -/// - **REAL_TIME** -/// - **INTERACTIVE_HIGH** -/// - **INTERACTIVE_LOW** -/// - **DATA_HIGH** -/// - **DATA** -/// - **DATA_LOW** -/// - **BACKGROUND** -#[allow(non_camel_case_types)] -#[repr(C)] -#[derive(Clone, Copy)] -pub enum z_priority_t { - REAL_TIME = 1, - INTERACTIVE_HIGH = 2, - INTERACTIVE_LOW = 3, - DATA_HIGH = 4, - DATA = 5, - DATA_LOW = 6, - BACKGROUND = 7, -} - -impl From for z_priority_t { - fn from(p: Priority) -> Self { - match p { - Priority::RealTime => z_priority_t::REAL_TIME, - Priority::InteractiveHigh => z_priority_t::INTERACTIVE_HIGH, - Priority::InteractiveLow => z_priority_t::INTERACTIVE_LOW, - Priority::DataHigh => z_priority_t::DATA_HIGH, - Priority::Data => z_priority_t::DATA, - Priority::DataLow => z_priority_t::DATA_LOW, - Priority::Background => z_priority_t::BACKGROUND, - } - } -} - -impl From for Priority { - fn from(p: z_priority_t) -> Self { - match p { - z_priority_t::REAL_TIME => Priority::RealTime, - z_priority_t::INTERACTIVE_HIGH => Priority::InteractiveHigh, - z_priority_t::INTERACTIVE_LOW => Priority::InteractiveLow, - z_priority_t::DATA_HIGH => Priority::DataHigh, - z_priority_t::DATA => Priority::Data, - z_priority_t::DATA_LOW => Priority::DataLow, - z_priority_t::BACKGROUND => Priority::Background, - } - } -} - -/// The kind of congestion control. -/// -/// - **BLOCK** -/// - **DROP** -#[allow(non_camel_case_types)] -#[repr(C)] -#[derive(Clone, Copy)] -pub enum z_congestion_control_t { - BLOCK, - DROP, -} - -impl From for z_congestion_control_t { - fn from(cc: CongestionControl) -> Self { - match cc { - CongestionControl::Block => z_congestion_control_t::BLOCK, - CongestionControl::Drop => z_congestion_control_t::DROP, - } - } -} - -impl From for CongestionControl { - fn from(cc: z_congestion_control_t) -> Self { - match cc { - z_congestion_control_t::BLOCK => CongestionControl::Block, - z_congestion_control_t::DROP => CongestionControl::Drop, - } - } -} - /// Options passed to the :c:func:`z_put` function. /// /// Members: /// z_encoding_t encoding: The encoding of the payload. /// z_congestion_control_t congestion_control: The congestion control to apply when routing this message. /// z_priority_t priority: The priority of this message. -/// z_attachment_t attachment: The attachment to this message. +/// z_bytes_t attachment: The attachment to this message. #[repr(C)] #[allow(non_camel_case_types)] pub struct z_put_options_t { pub encoding: z_encoding_t, pub congestion_control: z_congestion_control_t, pub priority: z_priority_t, - pub attachment: z_attachment_t, + pub attachment:z_bytes_t, } /// Constructs the default value for :c:type:`z_put_options_t`. @@ -158,7 +78,7 @@ pub extern "C" fn z_put_options_default() -> z_put_options_t { pub extern "C" fn z_put( session: z_session_t, keyexpr: z_keyexpr_t, - payload: Option<&mut zc_owned_payload_t>, + payload: Option<&mut z_owned_bytes_t>, opts: Option<&z_put_options_t>, ) -> i8 { match session.upgrade() { @@ -188,7 +108,7 @@ pub extern "C" fn z_put( Ok(()) => 0, } } else { - log::debug!("zc_payload_null was provided as payload for put"); + log::debug!("z_bytes_null was provided as payload for put"); i8::MIN } } diff --git a/src/queryable.rs b/src/queryable.rs index 30baf5af2..875918cab 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -11,52 +11,29 @@ // Contributors: // ZettaScale Zenoh team, // -use crate::attachment::{ - attachment_iteration_driver, insert_in_attachment_builder, z_attachment_check, - z_attachment_iterate, z_attachment_null, z_attachment_t, -}; -use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteRef}; +use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}; use crate::{ - z_bytes_t, z_closure_query_call, z_encoding_default, z_encoding_t, z_keyexpr_t, - z_owned_closure_query_t, z_session_t, z_value_t, zc_owned_payload_t, zc_payload_t, - LOG_INVALID_SESSION, + errors, z_slice_t, z_closure_query_call, z_keyexpr_t,z_owned_bytes_t, z_owned_closure_query_t, z_owned_encoding_t, z_session_t, z_value_t, z_bytes_t }; -use libc::c_void; +use zenoh::sample::{SampleBuilderTrait, ValueBuilderTrait}; use std::mem::MaybeUninit; -use std::ops::{Deref, DerefMut}; +use std::ptr::null_mut; use zenoh::prelude::SessionDeclarations; -use zenoh::{ - prelude::Sample, - queryable::{Query, Queryable}, - sample::AttachmentBuilder, -}; +use zenoh::prelude::{Query, Queryable}; +use zenoh::prelude::SyncResolve; -/// An owned zenoh queryable. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. pub use crate::opaque_types::z_owned_queryable_t; -decl_transmute_owned!(default_inplace_init Option>, z_owned_queryable_t); +decl_transmute_owned!(Option>, z_owned_queryable_t); /// Constructs a null safe-to-drop value of 'z_owned_queryable_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_queryable_null(this: *mut MaybeUninit) { - Inplace::empty(z_owned_queryable_t::transmute_uninit_ptr(this)); + Inplace::empty(this.transmute_uninit_ptr()); } -// Loaned variant of a Query received by a Queryable. -/// -/// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. -/// `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. pub use crate::opaque_types::z_query_t; -decl_transmute_copy!(&'static Query, z_query_t); +decl_transmute_handle!(Query, z_query_t); /// Owned variant of a Query received by a Queryable. /// @@ -67,12 +44,12 @@ decl_transmute_copy!(&'static Query, z_query_t); /// Holding onto an `z_owned_query_t` for too long (10s by default, can be set in `z_get`'s options) will trigger a timeout error /// to be sent to the querier by the infrastructure, and new responses to the outdated query will be silently dropped. pub use crate::opaque_types::z_owned_query_t; -decl_transmute_owned!(default_inplace_init Option, z_owned_query_t); +decl_transmute_owned!(Option, z_owned_query_t); /// The gravestone value of `z_owned_query_t`. #[no_mangle] -pub extern "C" fn z_query_null(query: *mut MaybeUninit) { - Inplace::empty(z_owned_query_t::transmute_uninit_ptr(query)); +pub extern "C" fn z_query_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); } /// Returns `false` if `this` is in a gravestone state, `true` otherwise. /// @@ -85,10 +62,10 @@ pub extern "C" fn z_query_check(query: &z_owned_query_t) -> bool { /// /// This function may not be called with the null pointer, but can be called with the gravestone value. #[no_mangle] -pub extern "C" fn z_query_loan(this: &z_owned_query_t) -> z_query_t { +pub extern "C" fn z_query_loan(this: &'static z_owned_query_t) -> z_query_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); - this.transmute_copy() + this.transmute_handle() } /// Destroys the query, setting `this` to its gravestone value to prevent double-frees. /// @@ -101,9 +78,11 @@ pub extern "C" fn z_query_drop(this: &mut z_owned_query_t) { /// /// This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). #[no_mangle] -pub extern "C" fn z_query_clone(query: z_query_t) -> z_owned_query_t { - let query = query.transmute_copy(); - query.and_then(|q| q.cloned()).into() +pub extern "C" fn z_query_clone(this: *mut MaybeUninit, query: z_query_t) { + let query = query.transmute_ref(); + let query = query.clone(); + let this = this.transmute_uninit_ptr(); + Inplace::init(this, Some(query)); } /// Options passed to the :c:func:`z_declare_queryable` function. @@ -126,13 +105,13 @@ pub extern "C" fn z_queryable_options_default() -> z_queryable_options_t { /// sent via :c:func:`z_query_reply`. /// /// Members: -/// z_encoding_t encoding: The encoding of the payload. -/// z_attachment_t attachment: The attachment to this reply. +/// z_owned_encoding_t encoding: The encoding of the payload. +/// z_owned_bytes_t attachment: The attachment to this reply. #[allow(non_camel_case_types)] #[repr(C)] pub struct z_query_reply_options_t { - pub encoding: z_encoding_t, - pub attachment: z_attachment_t, + pub encoding: *mut z_owned_encoding_t, + pub attachment: *mut z_owned_bytes_t, } /// Constructs the default value for :c:type:`z_query_reply_options_t`. @@ -140,8 +119,8 @@ pub struct z_query_reply_options_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_query_reply_options_default() -> z_query_reply_options_t { z_query_reply_options_t { - encoding: z_encoding_default(), - attachment: z_attachment_null(), + encoding: null_mut(), + attachment: null_mut(), } } @@ -149,7 +128,7 @@ pub extern "C" fn z_query_reply_options_default() -> z_query_reply_options_t { /// /// Parameters: /// session: The zenoh session. -/// keyexpr: The key expression the Queryable will reply to. +/// key_expr: The key expression the Queryable will reply to. /// callback: The callback function that will be called each time a matching query is received. /// options: Options for the queryable. /// @@ -159,30 +138,33 @@ pub extern "C" fn z_query_reply_options_default() -> z_query_reply_options_t { #[no_mangle] pub extern "C" fn z_declare_queryable( session: z_session_t, - keyexpr: z_keyexpr_t, + key_expr: z_keyexpr_t, callback: &mut z_owned_closure_query_t, options: Option<&z_queryable_options_t>, -) -> z_owned_queryable_t { + this: *mut MaybeUninit +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_query_t::empty(); std::mem::swap(&mut closure, callback); - - let session = match session.upgrade() { - Some(s) => s, - None => { - log::error!("{}", LOG_INVALID_SESSION); - return None.into(); - } - }; + let session = session.transmute_copy(); + let keyexpr = key_expr.transmute_ref(); let mut builder = session.declare_queryable(keyexpr); if let Some(options) = options { builder = builder.complete(options.complete); } - builder - .callback(move |query| z_closure_query_call(&closure, &z_query_t::from(&query))) - .res_sync() - .map_err(|e| log::error!("{}", e)) - .ok() - .into() + let queryable = builder + .callback(move |query| z_closure_query_call(&closure, query.transmute_handle())) + .res_sync(); + match queryable { + Ok(q) => { + Inplace::init(this, Some(q)); + errors::Z_OK + } + Err(e) => { + log::error!("{}", e); + errors::Z_EGENERIC + } + } } /// Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. @@ -191,21 +173,20 @@ pub extern "C" fn z_declare_queryable( /// qable: The :c:type:`z_owned_queryable_t` to undeclare. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_undeclare_queryable(qable: &mut z_owned_queryable_t) -> i8 { - if let Some(qable) = qable.take() { +pub extern "C" fn z_undeclare_queryable(qable: &mut z_owned_queryable_t) -> errors::ZCError { + if let Some(qable) = qable.transmute_mut().extract().take() { if let Err(e) = qable.undeclare().res_sync() { log::error!("{}", e); - return e.errno().get(); + return errors::Z_EGENERIC; } } - 0 + errors::Z_OK } /// Returns ``true`` if `qable` is valid. -#[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_queryable_check(qable: &z_owned_queryable_t) -> bool { - qable.as_ref().is_some() + qable.transmute_ref().is_some() } /// Send a reply to a query. @@ -217,93 +198,90 @@ pub extern "C" fn z_queryable_check(qable: &z_owned_queryable_t) -> bool { /// /// Parameters: /// query: The query to reply to. -/// key: The key of this reply. +/// key_expr: The key of this reply. /// payload: The value of this reply. /// options: The options of this reply. +/// +/// The payload and all owned options fields are consumed upon function return. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_query_reply( - query: &z_query_t, - key: z_keyexpr_t, - payload: Option<&mut zc_owned_payload_t>, - options: Option<&z_query_reply_options_t>, -) -> i8 { - let Some(query) = query.as_ref() else { - log::error!("Called `z_query_reply` with invalidated `query`"); - return i8::MIN; + query: z_query_t, + key_expr: z_keyexpr_t, + payload: &mut z_owned_bytes_t, + options: z_query_reply_options_t, +) -> errors::ZCError { + let query = query.transmute_ref(); + let key_expr = key_expr.transmute_ref(); + + let payload = match payload.transmute_mut().extract() { + Some(p) => p, + None => { + log::debug!("Attempted to reply with a null payload"); + return errors::Z_EINVAL; + } + }; + + let mut reply = query.reply(key_expr, payload); + + if !options.encoding.is_null() { + let encoding = unsafe{ *options.encoding }.transmute_mut().extract(); + reply = reply.encoding(encoding); }; - if let Some(key) = &*key { - // TODO: reimplement with reply builder - // - // if let Some(payload) = payload.and_then(|p| p.take()) { - // let mut s = Sample::new(key.clone().into_owned(), payload); - // if let Some(o) = options { - // s.encoding = o.encoding.into(); - // if z_attachment_check(&o.attachment) { - // let mut attachment_builder = AttachmentBuilder::new(); - // z_attachment_iterate( - // o.attachment, - // insert_in_attachment_builder, - // &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - // ); - // s = s.with_attachment(attachment_builder.build()); - // }; - // } - // if let Err(e) = query.reply(Ok(s)).res_sync() { - // log::error!("{}", e); - // return e.errno().get(); - // } - // return 0; - // } + if !options.attachment.is_null() { + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + reply = reply.attachment(attachment); } - i8::MIN + + if let Err(e) = reply.res_sync() { + log::error!("{}", e); + return errors::Z_EGENERIC; + } + return errors::Z_OK; } /// Get a query's key by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_keyexpr(query: &z_query_t) -> z_keyexpr_t { - let Some(query) = query.as_ref() else { - return z_keyexpr_t::null(); - }; - query.key_expr().borrowing_clone().into() +pub extern "C" fn z_query_keyexpr(query: z_query_t) -> z_keyexpr_t { + query.transmute_ref().key_expr().transmute_handle() } /// Get a query's `value selector `_ by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_parameters(query: &z_query_t) -> z_bytes_t { - let Some(query) = query.as_ref() else { - return z_bytes_t::empty(); - }; - let complement = query.parameters(); - z_bytes_t { - start: complement.as_ptr(), - len: complement.len(), +pub extern "C" fn z_query_parameters(query: z_query_t) -> z_slice_t { + let query = query.transmute_ref(); + let params = query.parameters().as_str(); + z_slice_t { + start: params.as_ptr(), + len: params.len(), } } -/// Get a query's `payload value `_ by aliasing it. +/// Checks if query contains a payload value. +pub extern "C" fn z_query_has_value(query: z_query_t) -> bool { + query.transmute_ref().value().is_some() +} + +/// Checks if query contains an attachment. +pub extern "C" fn z_query_has_attachment(query: z_query_t) -> bool { + query.transmute_ref().attachment().is_some() +} + +/// Gets a query's `payload value `_ by aliasing it. /// /// **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** -#[allow(clippy::missing_safety_doc)] +/// Before calling this funciton, the user must ensure that `z_query_has_value` returns true. #[no_mangle] -pub unsafe extern "C" fn z_query_value(query: &z_query_t) -> z_value_t { - let v = query.as_ref().and_then(|q| q.value()); - v.into() +pub extern "C" fn z_query_value(query: z_query_t) -> z_value_t { + query.transmute_ref().value().expect("Query does not contain a value").transmute_copy() } -/// Returns the attachment to the query by aliasing. +/// Gets the attachment to the query by aliasing. /// -/// `z_check(return_value) == false` if there was no attachment to the query. -#[allow(clippy::missing_safety_doc)] +/// Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. #[no_mangle] -pub unsafe extern "C" fn z_query_attachment(query: &z_query_t) -> z_attachment_t { - match query.as_ref().and_then(|q| q.attachment()) { - Some(attachment) => z_attachment_t { - data: attachment as *const _ as *mut c_void, - iteration_driver: Some(attachment_iteration_driver), - }, - None => z_attachment_null(), - } +pub extern "C" fn z_query_attachment(query: z_query_t) -> z_bytes_t { + query.transmute_ref().attachment().expect("Query does not contain an attachment").transmute_handle() } diff --git a/src/scouting.rs b/src/scouting.rs index c7dd80be7..61cba7426 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -12,12 +12,11 @@ // ZettaScale Zenoh team, // use crate::{ - z_closure_hello_call, z_config_check, z_config_default, z_config_null, z_config_t, z_id_t, - z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, CopyableToCArray, + errors::{self, Z_OK}, transmute::{Inplace, TransmuteRef}, z_closure_hello_call, z_config_check, z_config_clone, z_config_drop, z_config_new, z_config_null, z_config_t, z_id_t, z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, CopyableToCArray }; use async_std::task; use libc::{c_char, c_uint, c_ulong, size_t}; -use std::{ffi::CString, os::raw::c_void}; +use std::{ffi::CString, mem::MaybeUninit, os::raw::c_void}; use zenoh::scouting::Hello; use zenoh_protocol::core::{whatami::WhatAmIMatcher, WhatAmI}; use zenoh_util::core::AsyncResolve; @@ -157,7 +156,7 @@ pub extern "C" fn z_hello_loan(hello: &z_owned_hello_t) -> z_hello_t { pub extern "C" fn z_hello_null() -> z_owned_hello_t { z_owned_hello_t { _whatami: 0, - _pid: z_id_t { id: [0; 16] }, + _pid: [0; 16].into(), _locators: z_owned_str_array_t { val: std::ptr::null_mut(), len: 0, @@ -188,32 +187,47 @@ pub const DEFAULT_SCOUTING_TIMEOUT: c_ulong = 1000; #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_scouting_config_null() -> z_owned_scouting_config_t { - z_owned_scouting_config_t { - _config: z_config_null(), +pub extern "C" fn z_scouting_config_null(this: *mut MaybeUninit) { + let mut _config = MaybeUninit::::uninit(); + z_config_null(&mut _config as *mut MaybeUninit); + let _config = unsafe { _config.assume_init() }; + + let config = z_owned_scouting_config_t { + _config, zc_timeout_ms: DEFAULT_SCOUTING_TIMEOUT, zc_what: DEFAULT_SCOUTING_WHAT, - } + }; + (unsafe { &mut *this }).write(config); } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_scouting_config_default() -> z_owned_scouting_config_t { - z_owned_scouting_config_t { - _config: z_config_default(), +pub extern "C" fn z_scouting_config_default(this: *mut MaybeUninit) { + let mut _config = MaybeUninit::::uninit(); + z_config_new(&mut _config as *mut MaybeUninit); + let _config = unsafe { _config.assume_init() }; + + let config = z_owned_scouting_config_t { + _config, zc_timeout_ms: DEFAULT_SCOUTING_TIMEOUT, zc_what: DEFAULT_SCOUTING_WHAT, - } + }; + (unsafe { &mut *this }).write(config); } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_scouting_config_from(config: z_config_t) -> z_owned_scouting_config_t { - z_owned_scouting_config_t { - _config: config.as_ref().clone().into(), +pub extern "C" fn z_scouting_config_from(config: z_config_t, this: *mut MaybeUninit) { + let mut dst = MaybeUninit::uninit(); + z_config_clone(&config, &mut dst as *mut _); + let _config = unsafe { dst.assume_init() }; + + let config = z_owned_scouting_config_t { + _config, zc_timeout_ms: DEFAULT_SCOUTING_TIMEOUT, zc_what: DEFAULT_SCOUTING_WHAT, - } + }; + (unsafe { &mut *this }).write(config); } #[no_mangle] @@ -225,7 +239,7 @@ pub extern "C" fn z_scouting_config_check(config: &z_owned_scouting_config_t) -> #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_scouting_config_drop(config: &mut z_owned_scouting_config_t) { - std::mem::drop(std::mem::replace(config, z_scouting_config_null())); + z_config_drop(&mut config._config) } /// Scout for routers and/or peers. @@ -241,16 +255,17 @@ pub extern "C" fn z_scouting_config_drop(config: &mut z_owned_scouting_config_t) pub extern "C" fn z_scout( config: &mut z_owned_scouting_config_t, callback: &mut z_owned_closure_hello_t, -) -> i8 { +) -> errors::ZCError { if cfg!(feature = "logger-autoinit") { zc_init_logger(); } - let config = std::mem::replace(config, z_scouting_config_null()); let what = WhatAmIMatcher::try_from(config.zc_what).unwrap_or(WhatAmI::Router | WhatAmI::Peer); #[allow(clippy::unnecessary_cast)] // Required for multi-target let timeout = config.zc_timeout_ms as u64; - let mut config = config._config; - let config = config.as_mut().take().expect("invalid config"); + let config = match config._config.transmute_mut().extract().take() { + Some(c) => c, + None => { return errors::Z_EINVAL ;} + }; let mut closure = z_owned_closure_hello_t::empty(); std::mem::swap(&mut closure, callback); @@ -266,7 +281,7 @@ pub extern "C" fn z_scout( async_std::task::sleep(std::time::Duration::from_millis(timeout)).await; std::mem::drop(scout); }); - 0 + Z_OK } /// Converts the kind of zenoh entity into a string. diff --git a/src/session.rs b/src/session.rs index 7f758d330..86682da16 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,25 +12,14 @@ // ZettaScale Zenoh team, // -use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef}; -use crate::{config::*, z_owned_config_t, zc_init_logger}; +use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef, TransmuteUninitPtr}; +use crate::{errors, z_owned_config_t, zc_init_logger}; use std::mem::MaybeUninit; -use std::ops::Deref; -use std::sync::{Arc, Weak}; +use std::sync::Arc; use zenoh::core::ErrNo; use zenoh::prelude::sync::SyncResolve; use zenoh::session::Session; -/// An owned zenoh session. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. use crate::opaque_types::z_owned_session_t; decl_transmute_owned!(Option>, z_owned_session_t); @@ -47,7 +36,7 @@ decl_transmute_copy!(&'static Session, z_session_t); /// attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) /// have been destroyed is UB (likely SEGFAULT) #[no_mangle] -pub extern "C" fn z_session_loan(s: &z_owned_session_t) -> z_session_t { +pub extern "C" fn z_session_loan(s: &'static z_owned_session_t) -> z_session_t { let s = s.transmute_ref(); let s = unwrap_ref_unchecked(s); let s = s.as_ref(); @@ -58,37 +47,38 @@ pub extern "C" fn z_session_loan(s: &z_owned_session_t) -> z_session_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_session_null(s: *mut MaybeUninit) { - Inplace::empty(z_owned_session_t::transmute_uninit_ptr(s)); + Inplace::empty(s.transmute_uninit_ptr()); } /// Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. +/// Config value is always consumed upon function return. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_open( this: *mut MaybeUninit, config: &mut z_owned_config_t, -) -> i8 { - let this = z_owned_session_t::transmute_uninit_ptr(this); +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); if cfg!(feature = "logger-autoinit") { zc_init_logger(); } - let config = match config.as_mut().take() { + let config = match config.transmute_mut().take() { Some(c) => c, None => { log::error!("Config not provided"); Inplace::empty(this); - return -1; + return errors::Z_EINVAL; } }; match zenoh::open(*config).res() { Ok(s) => { Inplace::init(this, Some(Arc::new(s))); - 0 + errors::Z_OK } Err(e) => { log::error!("Error opening session: {}", e); Inplace::empty(this); - -1 + errors::Z_ENETWORK } } } @@ -131,7 +121,7 @@ pub extern "C" fn zc_session_rcinc( src: &z_owned_session_t, ) -> i8 { // session.as_ref().as_ref().and_then(|s| s.upgrade()).into() - let dst = z_owned_session_t::transmute_uninit_ptr(dst); + let dst = dst.transmute_uninit_ptr(); let Some(src) = src.transmute_ref() else { return -1; }; diff --git a/src/shm.rs b/src/shm.rs index 50f8b7236..52f9d51cd 100644 --- a/src/shm.rs +++ b/src/shm.rs @@ -23,7 +23,7 @@ use zenoh::{ shm::{SharedMemoryBuf, SharedMemoryManager}, }; -use crate::{z_session_t, zc_owned_payload_t, zc_payload_null}; +use crate::{z_session_t, z_owned_bytes_t, z_bytes_null}; #[repr(C)] pub struct zc_owned_shm_manager_t(usize); @@ -179,10 +179,10 @@ pub extern "C" fn zc_shmbuf_null() -> zc_owned_shmbuf_t { /// Constructs an owned payload from an owned SHM buffer. #[no_mangle] -pub extern "C" fn zc_shmbuf_into_payload(buf: &mut zc_owned_shmbuf_t) -> zc_owned_payload_t { +pub extern "C" fn zc_shmbuf_into_payload(buf: &mut zc_owned_shmbuf_t) -> z_owned_bytes_t { match buf.get_mut().take() { Some(buf) => ZBuf::from(buf).try_into().unwrap_or_default(), - None => zc_payload_null(), + None => z_bytes_null(), } } diff --git a/src/transmute.rs b/src/transmute.rs index 3fe026532..4aaa3d157 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -16,6 +16,8 @@ // unsafe { std::mem::transmute::<&'a T, &'static T>(value) } // } +use std::mem::MaybeUninit; + pub fn unwrap_ref_unchecked(value: &Option) -> &T { debug_assert!(value.is_some()); unsafe { value.as_ref().unwrap_unchecked() } @@ -26,6 +28,15 @@ pub(crate) trait TransmuteRef: Sized { fn transmute_mut(&mut self) -> &mut T; } +pub(crate) trait TransmuteFromHandle: Sized { + fn transmute_ref(self) -> &'static T; + fn transmute_mut(self) -> &'static mut T; +} + +pub(crate) trait TransmuteIntoHandle: Sized { + fn transmute_handle(&self) -> T; +} + pub(crate) trait TransmuteCopy { fn transmute_copy(self) -> T; } @@ -50,6 +61,15 @@ pub(crate) trait Inplace: Sized { unsafe { std::ptr::drop_in_place(this) }; Inplace::empty(this as *mut std::mem::MaybeUninit); } + + // Move the object out of this, leaving it in empty state + fn extract(self: &mut Self) -> Self { + let mut out: MaybeUninit = MaybeUninit::uninit(); + Self::empty(&mut out); + let mut out = unsafe { out.assume_init() }; + std::mem::swap(&mut out, self); + out + } // TODO: for effective inplace_init, we can provide a method that takes a closure that initializes the object in place } @@ -125,6 +145,14 @@ macro_rules! decl_transmute_copy { }; } +#[macro_export] +macro_rules! decl_transmute_handle { + ($zenoh_type:ty, $c_type:ty) => { + validate_equivalence!(&'static $zenoh_type, $c_type); + impl_transmute_handle!($c_type, $zenoh_type); + }; +} + macro_rules! impl_transmute_ref { ($src_type:ty, $dst_type:ty) => { impl $crate::transmute::TransmuteRef<$dst_type> for $src_type { @@ -157,3 +185,22 @@ macro_rules! impl_transmute_uninit_ptr { } }; } + + +macro_rules! impl_transmute_handle { + ($c_type:ty, $zenoh_type:ty) => { + impl $crate::transmute::TransmuteFromHandle<$zenoh_type> for $c_type { + fn transmute_ref(self) -> &'static $zenoh_type { + unsafe { std::mem::transmute::<$c_type, &'static $zenoh_type>(self) } + } + fn transmute_mut(self) -> &'static mut $zenoh_type { + unsafe { std::mem::transmute::<$c_type, &'static mut $zenoh_type>(self) } + } + } + impl $crate::transmute::TransmuteIntoHandle<$c_type> for $zenoh_type { + fn transmute_handle(& self) -> $c_type { + unsafe { std::mem::transmute::<& $zenoh_type, $c_type>(self) } + } + } + }; +} \ No newline at end of file diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index e7b72ef96..062c7c7ad 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -51,12 +51,12 @@ void query_handler(const z_query_t *query, void *arg) { } #endif - z_bytes_t pred = z_query_parameters(query); + z_slice_t pred = z_query_parameters(query); (void)(pred); z_value_t payload_value = z_query_value(query); (void)(payload_value); z_query_reply_options_t _ret_qreply_opt = z_query_reply_options_default(); - zc_owned_payload_t payload = zc_payload_encode_from_string(value); + z_owned_bytes_t payload = z_bytes_encode_from_string(value); z_query_reply(query, z_keyexpr(z_loan(k_str)), z_move(payload), &_ret_qreply_opt); z_drop(z_move(k_str)); @@ -261,7 +261,7 @@ int main(int argc, char **argv) { z_encoding_t _ret_encoding = z_encoding_default(); _ret_encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); _ret_put_opt.encoding = _ret_encoding; - zc_owned_payload_t payload = zc_payload_encode_from_string(value); + z_owned_bytes_t payload = z_bytes_encode_from_string(value); _ret_int8 = z_put(z_loan(s1), z_loan(_ret_expr), z_move(payload), &_ret_put_opt); assert(_ret_int8 == 0); @@ -294,7 +294,7 @@ int main(int argc, char **argv) { assert(z_check(_ret_pub)); z_publisher_put_options_t _ret_pput_opt = z_publisher_put_options_default(); - payload = zc_payload_encode_from_string(value); + payload = z_bytes_encode_from_string(value); _ret_int8 = z_publisher_put(z_loan(_ret_pub), z_move(payload), &_ret_pput_opt); assert(_ret_int8 == 0); diff --git a/tests/z_api_attachment_test.c b/tests/z_api_attachment_test.c index 737048e9b..7669a3605 100644 --- a/tests/z_api_attachment_test.c +++ b/tests/z_api_attachment_test.c @@ -23,31 +23,31 @@ void writting_through_map_by_alias_read_by_get() { // Writing - z_owned_bytes_map_t map = z_bytes_map_new(); - z_bytes_map_insert_by_alias(&map, z_bytes_from_str("k1"), z_bytes_from_str("v1")); - z_bytes_map_insert_by_alias(&map, z_bytes_from_str("k2"), z_bytes_from_str("v2")); - z_attachment_t attachment = z_bytes_map_as_attachment(&map); + z_owned_bytes_map_t map = z_slice_map_new(); + z_slice_map_insert_by_alias(&map, z_slice_from_str("k1"), z_slice_from_str("v1")); + z_slice_map_insert_by_alias(&map, z_slice_from_str("k2"), z_slice_from_str("v2")); + z_bytes_t attachment = z_slice_map_as_attachment(&map); // Elements check - assert(z_bytes_map_len(&map) == 2); + assert(z_slice_map_len(&map) == 2); assert(z_attachment_len(attachment) == 2); assert(!z_attachment_is_empty(attachment)); - z_bytes_t a1 = z_attachment_get(attachment, z_bytes_from_str("k1")); + z_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); ASSERT_STR_BYTES_EQUAL("v1", a1); - z_bytes_t a2 = z_attachment_get(attachment, z_bytes_from_str("k2")); + z_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); ASSERT_STR_BYTES_EQUAL("v2", a2); - z_bytes_t a_non = z_attachment_get(attachment, z_bytes_from_str("k_non")); + z_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); assert(a_non.start == NULL); assert(a_non.len == 0); z_drop(z_move(map)); } -int8_t _attachment_reader(z_bytes_t key, z_bytes_t value, void* ctx) { +int8_t _attachment_reader(z_slice_t key, z_slice_t value, void* ctx) { assert((size_t)ctx == 42); if (!strncmp(key.start, "k1", key.len)) { assert(!strncmp(value.start, "v1", value.len)); @@ -60,13 +60,13 @@ int8_t _attachment_reader(z_bytes_t key, z_bytes_t value, void* ctx) { void writting_through_map_by_copy_read_by_iter() { // Writing - z_owned_bytes_map_t map = z_bytes_map_new(); - z_bytes_map_insert_by_copy(&map, z_bytes_from_str("k1"), z_bytes_from_str("v1")); - z_bytes_map_insert_by_copy(&map, z_bytes_from_str("k2"), z_bytes_from_str("v2")); - z_attachment_t attachment = z_bytes_map_as_attachment(&map); + z_owned_bytes_map_t map = z_slice_map_new(); + z_slice_map_insert_by_copy(&map, z_slice_from_str("k1"), z_slice_from_str("v1")); + z_slice_map_insert_by_copy(&map, z_slice_from_str("k2"), z_slice_from_str("v2")); + z_bytes_t attachment = z_slice_map_as_attachment(&map); // Elements check - assert(z_bytes_map_len(&map) == 2); + assert(z_slice_map_len(&map) == 2); assert(z_attachment_len(attachment) == 2); assert(!z_attachment_is_empty(attachment)); @@ -78,38 +78,38 @@ void writting_through_map_by_copy_read_by_iter() { int8_t _iteration_driver(const void* data, z_attachment_iter_body_t body, void* ctx) { int8_t ret = 0; - ret = body(z_bytes_from_str("k1"), z_bytes_from_str("v1"), ctx); + ret = body(z_slice_from_str("k1"), z_slice_from_str("v1"), ctx); if (ret) { return ret; } - ret = body(z_bytes_from_str("k2"), z_bytes_from_str("v2"), ctx); + ret = body(z_slice_from_str("k2"), z_slice_from_str("v2"), ctx); return ret; } void writting_no_map_read_by_get() { - z_attachment_t attachment = {.data = NULL, .iteration_driver = &_iteration_driver}; + z_bytes_t attachment = {.data = NULL, .iteration_driver = &_iteration_driver}; // Elements check assert(z_attachment_len(attachment) == 2); assert(!z_attachment_is_empty(attachment)); - z_bytes_t a1 = z_attachment_get(attachment, z_bytes_from_str("k1")); + z_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); ASSERT_STR_BYTES_EQUAL("v1", a1); - z_bytes_t a2 = z_attachment_get(attachment, z_bytes_from_str("k2")); + z_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); ASSERT_STR_BYTES_EQUAL("v2", a2); - z_bytes_t a_non = z_attachment_get(attachment, z_bytes_from_str("k_non")); + z_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); assert(a_non.start == NULL); assert(a_non.len == 0); } void invalid_attachment_safety() { - z_attachment_t attachment = z_attachment_null(); + z_bytes_t attachment = z_attachment_null(); assert(z_attachment_is_empty(attachment)); assert(z_attachment_len(attachment) == 0); - z_bytes_t a_non = z_attachment_get(attachment, z_bytes_from_str("k_non")); + z_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); assert(a_non.start == NULL); assert(a_non.len == 0); diff --git a/tests/z_api_null_drop_test.c b/tests/z_api_null_drop_test.c index 814d80e7c..b82f27aef 100644 --- a/tests/z_api_null_drop_test.c +++ b/tests/z_api_null_drop_test.c @@ -43,7 +43,7 @@ int main(int argc, char **argv) { z_owned_reply_channel_closure_t reply_channel_closure_null_1 = z_reply_channel_closure_null(); z_owned_reply_channel_t reply_channel_null_1 = z_reply_channel_null(); z_owned_str_t str_null_1 = z_str_null(); - zc_owned_payload_t payload_null_1 = zc_payload_null(); + z_owned_bytes_t payload_null_1 = z_bytes_null(); zc_owned_shmbuf_t shmbuf_null_1 = zc_shmbuf_null(); zc_owned_shm_manager_t shm_manager_null_1 = zc_shm_manager_null(); @@ -88,7 +88,7 @@ int main(int argc, char **argv) { z_owned_reply_channel_closure_t reply_channel_closure_null_2; z_owned_reply_channel_t reply_channel_null_2; z_owned_str_t str_null_2; - zc_owned_payload_t payload_null_2; + z_owned_bytes_t payload_null_2; zc_owned_shmbuf_t shmbuf_null_2; zc_owned_shm_manager_t shm_manager_null_2; diff --git a/tests/z_api_payload_test.c b/tests/z_api_payload_test.c index 10b1a3177..9d8df0076 100644 --- a/tests/z_api_payload_test.c +++ b/tests/z_api_payload_test.c @@ -24,17 +24,17 @@ void test_reader() { uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; uint8_t data_out[10] = {0}; - z_bytes_t bytes = {.start = data, .len = 10 }; + z_slice_t bytes = {.start = data, .len = 10 }; - zc_owned_payload_t payload = zc_payload_encode_from_bytes(bytes); - zc_payload_reader reader; - zc_payload_reader_init(z_loan(payload), &reader); - assert(zc_payload_reader_remaining(&reader) == 10); + z_owned_bytes_t payload = z_bytes_encode_from_bytes(bytes); + z_bytes_reader reader; + z_bytes_reader_init(z_loan(payload), &reader); + assert(z_bytes_reader_remaining(&reader) == 10); - zc_payload_reader_read(&reader, data_out, 5); - assert(zc_payload_reader_remaining(&reader) == 5); - zc_payload_reader_read(&reader, data_out, 5); - assert(zc_payload_reader_remaining(&reader) == 0); + z_bytes_reader_read(&reader, data_out, 5); + assert(z_bytes_reader_remaining(&reader) == 5); + z_bytes_reader_read(&reader, data_out, 5); + assert(z_bytes_reader_remaining(&reader) == 0); assert(memcmp(data, data_out, 10)); } diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index 03a6d893c..e0246ad01 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -61,7 +61,7 @@ int run_publisher() { // values for cache for (int i = 0; i < values_count / 2; ++i) { - zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_owned_bytes_t payload = z_bytes_encode_from_string(values[i]); z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } @@ -71,7 +71,7 @@ int run_publisher() { // values for subscribe for (int i = values_count / 2; i < values_count; ++i) { - zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_owned_bytes_t payload = z_bytes_encode_from_string(values[i]); z_put(z_loan(s), z_keyexpr(keyexpr), z_move(payload), NULL); } @@ -94,7 +94,7 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(keystr)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); z_drop(z_move(payload_value)); diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index ccb2c1e82..63bb54f4a 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -47,15 +47,15 @@ int run_publisher() { return -1; } - z_owned_bytes_map_t map = z_bytes_map_new(); - z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_CONST), z_bytes_from_str(V_CONST)); + z_owned_bytes_map_t map = z_slice_map_new(); + z_slice_map_insert_by_copy(&map, z_slice_from_str(K_CONST), z_slice_from_str(V_CONST)); z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - options.attachment = z_bytes_map_as_attachment(&map); + options.attachment = z_slice_map_as_attachment(&map); for (int i = 0; i < values_count; ++i) { - z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_VAR), z_bytes_from_str(values[i])); - zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_slice_map_insert_by_copy(&map, z_slice_from_str(K_VAR), z_slice_from_str(values[i])); + z_owned_bytes_t payload = z_bytes_encode_from_string(values[i]); z_publisher_put(z_loan(pub), z_move(payload), &options); } @@ -75,7 +75,7 @@ void data_handler(const z_sample_t *sample, void *arg) { z_drop(z_move(keystr)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); z_drop(z_move(payload_value)); @@ -83,10 +83,10 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(payload_value)); - z_bytes_t v_const = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_CONST)); + z_slice_t v_const = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); - z_bytes_t v_var = z_attachment_get(z_sample_attachment(sample), z_bytes_from_str(K_VAR)); + z_slice_t v_var = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_VAR)); ASSERT_STR_BYTES_EQUAL(values[val_num], v_var); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index ad5969fa2..6d681bb49 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -49,7 +49,7 @@ int run_publisher() { for (int i = 0; i < values_count; ++i) { z_publisher_put_options_t options = z_publisher_put_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - zc_owned_payload_t payload = zc_payload_encode_from_string(values[i]); + z_owned_bytes_t payload = z_bytes_encode_from_string(values[i]); z_publisher_put(z_loan(pub), z_move(payload), &options); } @@ -68,7 +68,7 @@ void data_handler(const z_sample_t *sample, void *arg) { z_drop(z_move(keystr)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); z_drop(z_move(payload_value)); diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 909da8c24..9ea97fe8f 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -33,24 +33,24 @@ void query_handler(const z_query_t *query, void *context) { static int value_num = 0; z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_bytes_t pred = z_query_parameters(query); + z_slice_t pred = z_query_parameters(query); z_value_t payload_value = z_query_value(query); - z_attachment_t attachment = z_query_attachment(query); + z_bytes_t attachment = z_query_attachment(query); - z_bytes_t v_const = z_attachment_get(attachment, z_bytes_from_str(K_CONST)); + z_slice_t v_const = z_attachment_get(attachment, z_slice_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); - z_bytes_t v_var = z_attachment_get(attachment, z_bytes_from_str(K_VAR)); + z_slice_t v_var = z_attachment_get(attachment, z_slice_from_str(K_VAR)); ASSERT_STR_BYTES_EQUAL(values[value_num], v_var); - z_owned_bytes_map_t map = z_bytes_map_new(); - z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_CONST), z_bytes_from_str(V_CONST)); + z_owned_bytes_map_t map = z_slice_map_new(); + z_slice_map_insert_by_copy(&map, z_slice_from_str(K_CONST), z_slice_from_str(V_CONST)); z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - options.attachment = z_bytes_map_as_attachment(&map); - zc_owned_payload_t payload = zc_payload_encode_from_string(values[value_num]); + options.attachment = z_slice_map_as_attachment(&map); + z_owned_bytes_t payload = z_bytes_encode_from_string(values[value_num]); z_query_reply(query, z_keyexpr((const char *)context), z_move(payload), &options); z_drop(z_move(keystr)); z_drop(z_move(map)); @@ -93,14 +93,14 @@ int run_get() { return -1; } - z_owned_bytes_map_t map = z_bytes_map_new(); - z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_CONST), z_bytes_from_str(V_CONST)); + z_owned_bytes_map_t map = z_slice_map_new(); + z_slice_map_insert_by_copy(&map, z_slice_from_str(K_CONST), z_slice_from_str(V_CONST)); z_get_options_t opts = z_get_options_default(); - opts.attachment = z_bytes_map_as_attachment(&map); + opts.attachment = z_slice_map_as_attachment(&map); for (int val_num = 0; val_num < values_count; ++val_num) { - z_bytes_map_insert_by_copy(&map, z_bytes_from_str(K_VAR), z_bytes_from_str(values[val_num])); + z_slice_map_insert_by_copy(&map, z_slice_from_str(K_VAR), z_slice_from_str(values[val_num])); z_owned_reply_channel_t channel = zc_reply_fifo_new(16); z_get(z_loan(s), z_keyexpr(keyexpr), "", z_move(channel.send), &opts); @@ -111,14 +111,14 @@ int run_get() { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); z_drop(z_move(payload_value)); exit(-1); } - z_bytes_t v_const = z_attachment_get(z_sample_attachment(&sample), z_bytes_from_str(K_CONST)); + z_slice_t v_const = z_attachment_get(z_sample_attachment(&sample), z_slice_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); z_drop(z_move(keystr)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index 3b3abad94..b63686ecb 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -29,12 +29,12 @@ void query_handler(const z_query_t *query, void *context) { static int value_num = 0; z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_bytes_t pred = z_query_parameters(query); + z_slice_t pred = z_query_parameters(query); z_value_t payload_value = z_query_value(query); z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - zc_owned_payload_t payload = zc_payload_encode_from_string(values[value_num]); + z_owned_bytes_t payload = z_bytes_encode_from_string(values[value_num]); z_query_reply(query, z_keyexpr((const char *)context), z_move(payload), &options); z_drop(z_move(keystr)); @@ -87,7 +87,7 @@ int run_get() { z_sample_t sample = z_reply_ok(&reply); z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); z_owned_str_t payload_value = z_str_null(); - zc_payload_decode_into_string(z_sample_payload(&sample), &payload_value); + z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { perror("Unexpected value received"); z_drop(z_move(payload_value)); From 931ca4903281196547ca9f8323511c46a4e7118d Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Mon, 22 Apr 2024 19:44:04 +0200 Subject: [PATCH 54/75] all builds except shm --- Cargo.lock | 9 +- Cargo.toml | 1 + Cargo.toml.in | 1 + build-resources/opaque-types/Cargo.lock | 1 + build-resources/opaque-types/Cargo.toml | 1 + build-resources/opaque-types/src/lib.rs | 135 ++--- include/zenoh-gen.h | 635 +++++++++++++++++++++++- src/closures/sample_closure.rs | 10 +- src/commons.rs | 21 +- src/errors.rs | 5 + src/get.rs | 2 +- src/keyexpr.rs | 4 +- src/lib.rs | 25 +- src/liveliness.rs | 210 +++----- src/payload.rs | 7 +- src/platform/synchronization.rs | 329 +++++------- src/publication_cache.rs | 126 ++--- src/publisher.rs | 2 +- src/put.rs | 141 +++--- src/querying_subscriber.rs | 220 ++++---- src/subscriber.rs | 208 ++++---- src/transmute.rs | 37 +- 22 files changed, 1266 insertions(+), 864 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c10ee7ae4..3ebd15726 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,18 +433,18 @@ checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "const_format" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c990efc7a285731f9a4378d81aff2f0e85a2c8781a05ef0f8baa8dac54d0ff48" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e026b6ce194a874cb9cf32cd5772d1ef9767cc8fcb5765948d74f37a9d8b2bf6" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" dependencies = [ "proc-macro2", "quote", @@ -3152,6 +3152,7 @@ dependencies = [ "async-trait", "cbindgen", "chrono", + "const_format", "env_logger", "fs2", "fs_extra", diff --git a/Cargo.toml b/Cargo.toml index 767d9a3a3..4e62df310 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ log = "0.4.17" rand = "0.8.5" spin = "0.9.5" unwrap-infallible = "0.1.5" +const_format = "0.2.32" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` #zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } #zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } diff --git a/Cargo.toml.in b/Cargo.toml.in index b68560103..af0cd4fa0 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -51,6 +51,7 @@ log = "0.4.17" rand = "0.8.5" spin = "0.9.5" unwrap-infallible = "0.1.5" +const_format = "0.2.32" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` #zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } #zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock index b3cd2f5b5..87d494976 100644 --- a/build-resources/opaque-types/Cargo.lock +++ b/build-resources/opaque-types/Cargo.lock @@ -1147,6 +1147,7 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" name = "opaque-types" version = "0.1.0" dependencies = [ + "const_format", "zenoh", "zenoh-ext", ] diff --git a/build-resources/opaque-types/Cargo.toml b/build-resources/opaque-types/Cargo.toml index 93f88d05d..a1c020ed4 100644 --- a/build-resources/opaque-types/Cargo.toml +++ b/build-resources/opaque-types/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` # zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } +const_format = "0.2.32" zenoh = { path = "../../../zenoh/zenoh", features = [ "shared-memory", "unstable", diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index dd5443d73..846e887a3 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -1,12 +1,17 @@ use std::borrow::Cow; use std::collections::HashMap; use std::sync::Arc; +use std::sync::Condvar; +use std::sync::Mutex; +use std::sync::MutexGuard; +use std::thread::JoinHandle; use zenoh::config::Config; use zenoh::config::ZenohId; use zenoh::encoding::Encoding; use zenoh::handlers::DefaultHandler; use zenoh::key_expr::KeyExpr; use zenoh::bytes::{ZBytes, ZBytesReader}; +use zenoh::liveliness::LivelinessToken; use zenoh::publication::MatchingListener; use zenoh::publication::Publisher; use zenoh::query::Reply; @@ -14,75 +19,22 @@ use zenoh::queryable::Query; use zenoh::queryable::Queryable; use zenoh::sample::Sample; use zenoh::session::Session; +use zenoh::subscriber::Subscriber; use zenoh::time::Timestamp; use zenoh::value::Value; -// Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. -// pub struct FetchingSubscriberWrapper { -// fetching_subscriber: zenoh_ext::FetchingSubscriber<'static, ()>, -// session: z_session_t, -// } - #[macro_export] macro_rules! get_opaque_type_data { ($src_type:ty, $name:ident) => { const _: () = { - const fn get_num_digits(n: usize) -> usize { - let mut out = 0; - let mut res = n; - while res > 0 { - out += 1; - res = res / 10; - } - if out == 0 { - out = 1; - } - out - } - - const fn write_str(src: &[u8], mut dst: [u8; MSG_LEN], offset: usize) -> [u8; MSG_LEN] { - let mut i = 0; - while i < src.len() { - dst[i + offset] = src[i]; - i += 1; - } - dst - } - - const fn write_num(src: usize, mut dst: [u8; MSG_LEN], offset: usize) -> [u8; MSG_LEN] { - let mut i = 0; - let num_digits = get_num_digits(src) as u32; - while i < num_digits { - dst[i as usize + offset] = b'0' + ((src / 10u32.pow(num_digits - i - 1) as usize) % 10) as u8; - i += 1; - } - dst - } - + use const_format::concatcp; const DST_NAME: &str = stringify!($name); const ALIGN: usize = std::mem::align_of::<$src_type>(); const SIZE: usize = std::mem::size_of::<$src_type>(); - const TYPE_TOKEN: [u8; 6] = *b"type: "; - const ALIGN_TOKEN: [u8; 9] = *b", align: "; - const SIZE_TOKEN: [u8; 8] = *b", size: "; - const SIZE_NUM_DIGITS: usize = get_num_digits(SIZE); - const ALIGN_NUM_DIGITS: usize = get_num_digits(ALIGN); - const MSG_LEN: usize = TYPE_TOKEN.len() + ALIGN_TOKEN.len() + SIZE_TOKEN.len() + SIZE_NUM_DIGITS + ALIGN_NUM_DIGITS + DST_NAME.len(); - const TYPE_OFFSET: usize = TYPE_TOKEN.len(); - const ALIGN_OFFSET: usize = TYPE_OFFSET + DST_NAME.len() + ALIGN_TOKEN.len(); - const SIZE_OFFSET: usize = ALIGN_OFFSET + ALIGN_NUM_DIGITS + SIZE_TOKEN.len(); - let mut msg: [u8; MSG_LEN] = [b' '; MSG_LEN]; - - msg = write_str(&TYPE_TOKEN, msg, 0); - msg = write_str(&DST_NAME.as_bytes(), msg, TYPE_OFFSET); - msg = write_str(&ALIGN_TOKEN, msg, ALIGN_OFFSET - ALIGN_TOKEN.len()); - msg = write_num(ALIGN, msg, ALIGN_OFFSET); - msg = write_str(&SIZE_TOKEN, msg, SIZE_OFFSET - SIZE_TOKEN.len()); - msg = write_num(SIZE, msg, SIZE_OFFSET); - - panic!("{}", unsafe { - std::str::from_utf8_unchecked(msg.as_slice()) - }); + const INFO_MESSAGE: &str = concatcp!( + "type: ", DST_NAME, ", align: ", ALIGN, ", size: ", SIZE + ); + panic!("{}", INFO_MESSAGE); }; } } @@ -151,14 +103,18 @@ get_opaque_type_data!(&'static Query, z_query_t); get_opaque_type_data!(Option>, z_owned_queryable_t); get_opaque_type_data!(&'static Queryable<'static, ()>, z_queryable_t); -// get_opaque_type_data!( -// Option>, -// ze_owned_querying_subscriber_t -// ); -// get_opaque_type_data!( -// &'static FetchingSubscriberWrapper, -// ze_querying_subscriber_t -// ); +/// An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. +/// +/// Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t); +get_opaque_type_data!(&'static (zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_querying_subscriber_t); /// A zenoh-allocated key expression. /// @@ -255,3 +211,48 @@ get_opaque_type_data!(&'static Publisher<'static>, z_publisher_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, zcu_owned_matching_listener_t); + + +/// An owned zenoh subscriber. Destroying the subscriber cancels the subscription. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, z_owned_subscriber_t); +get_opaque_type_data!(&'static Subscriber<'static, ()>, z_subscriber_t); + +/// A liveliness token that can be used to provide the network with information about connectivity to its +/// declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key +/// expressions. +/// +/// A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. +get_opaque_type_data!(Option>, zc_owned_liveliness_token_t); +get_opaque_type_data!(&'static LivelinessToken<'static>, zc_liveliness_token_t); + + +/// An owned zenoh publication_cache. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +get_opaque_type_data!(Option>, ze_owned_publication_cache_t); +get_opaque_type_data!(&'static zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); + + +get_opaque_type_data!(Option<(Mutex<()>, Option>)>, z_owned_mutex_t); +get_opaque_type_data!(&'static (Mutex<()>, Option>), z_mutex_t); + +get_opaque_type_data!(Option, z_owned_condvar_t); +get_opaque_type_data!(&'static Condvar, z_condvar_t); + +get_opaque_type_data!(Option>, z_owned_task_t); \ No newline at end of file diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h index 1761f69b2..19b3fc6c9 100644 --- a/include/zenoh-gen.h +++ b/include/zenoh-gen.h @@ -90,6 +90,17 @@ typedef enum z_query_target_t { Z_QUERY_TARGET_T_ALL_COMPLETE, } z_query_target_t; +/** + * The subscription reliability. + * + * - **Z_RELIABILITY_BEST_EFFORT** + * - **Z_RELIABILITY_RELIABLE** + */ +typedef enum z_reliability_t { + Z_RELIABILITY_T_BEST_EFFORT, + Z_RELIABILITY_T_RELIABLE, +} z_reliability_t; + typedef enum z_sample_kind_t { Z_SAMPLE_KIND_T_PUT = 0, Z_SAMPLE_KIND_T_DELETE = 1, @@ -173,6 +184,15 @@ typedef struct ALIGN(8) z_bytes_reader_t { uint8_t _0[8]; } z_bytes_reader_t; +/** + * Clock + * Uses monotonic clock + */ +typedef struct z_clock_t { + uint64_t t; + const void *t_base; +} z_clock_t; + /** * An owned zenoh session. * @@ -346,7 +366,7 @@ typedef struct ALIGN(8) z_sample_t { * * Members: * void *context: a pointer to an arbitrary state. - * void *call(const struct z_sample_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *call(struct z_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. * void *drop(void*): allows the callback's state to be freed. * * Closures are not guaranteed not to be called concurrently. @@ -359,7 +379,7 @@ typedef struct ALIGN(8) z_sample_t { */ typedef struct z_owned_closure_sample_t { void *context; - void (*call)(const struct z_sample_t*, void *context); + void (*call)(struct z_sample_t, void *context); void (*drop)(void*); } z_owned_closure_sample_t; @@ -385,6 +405,18 @@ typedef struct z_owned_closure_zid_t { void (*drop)(void*); } z_owned_closure_zid_t; +typedef struct ALIGN(8) z_owned_condvar_t { + uint8_t _0[24]; +} z_owned_condvar_t; + +typedef struct ALIGN(8) z_condvar_t { + uint8_t _0[8]; +} z_condvar_t; + +typedef struct ALIGN(8) z_mutex_t { + uint8_t _0[8]; +} z_mutex_t; + /** * An owned zenoh configuration. * @@ -512,6 +544,40 @@ typedef struct ALIGN(8) z_owned_queryable_t { uint8_t _0[32]; } z_owned_queryable_t; +/** + * An owned zenoh subscriber. Destroying the subscriber cancels the subscription. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_subscriber_t { + uint8_t _0[32]; +} z_owned_subscriber_t; + +/** + * Options passed to the :c:func:`z_declare_subscriber` or :c:func:`z_declare_pull_subscriber` function. + * + * Members: + * z_reliability_t reliability: The subscription reliability. + */ +typedef struct z_subscriber_options_t { + enum z_reliability_t reliability; +} z_subscriber_options_t; + +/** + * Options passed to the :c:func:`z_delete` function. + */ +typedef struct z_delete_options_t { + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; +} z_delete_options_t; + typedef struct ALIGN(8) z_owned_encoding_t { uint8_t _0[48]; } z_owned_encoding_t; @@ -579,6 +645,10 @@ typedef struct z_hello_t { struct z_str_array_t locators; } z_hello_t; +typedef struct ALIGN(8) z_owned_mutex_t { + uint8_t _0[32]; +} z_owned_mutex_t; + typedef struct ALIGN(8) z_publisher_t { uint8_t _0[8]; } z_publisher_t; @@ -603,6 +673,22 @@ typedef struct z_publisher_put_options_t { struct z_owned_bytes_t *attachment; } z_publisher_put_options_t; +/** + * Options passed to the :c:func:`z_put` function. + * + * Members: + * z_encoding_t encoding: The encoding of the payload. + * z_congestion_control_t congestion_control: The congestion control to apply when routing this message. + * z_priority_t priority: The priority of this message. + * z_bytes_t attachment: The attachment to this message. + */ +typedef struct z_put_options_t { + struct z_owned_encoding_t *encoding; + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; + struct z_owned_bytes_t *attachment; +} z_put_options_t; + /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * - `this` is a pointer to an arbitrary state. @@ -707,6 +793,58 @@ typedef struct z_owned_scouting_config_t { */ typedef bool (*z_slice_map_iter_body_t)(struct z_slice_t key, struct z_slice_t value, void *context); +typedef struct ALIGN(8) z_subscriber_t { + uint8_t _0[8]; +} z_subscriber_t; + +typedef struct ALIGN(8) z_owned_task_t { + uint8_t _0[24]; +} z_owned_task_t; + +typedef struct z_task_attr_t { + size_t _0; +} z_task_attr_t; + +/** + * Time + * Uses system clock + */ +typedef struct z_time_t { + uint64_t t; +} z_time_t; + +/** + * The options for `zc_liveliness_declare_token` + */ +typedef struct zc_liveliness_declaration_options_t { + uint8_t _dummy; +} zc_liveliness_declaration_options_t; + +/** + * The options for :c:func:`zc_liveliness_declare_subscriber` + */ +typedef struct zc_liveliness_declare_subscriber_options_t { + uint8_t _dummy; +} zc_liveliness_declare_subscriber_options_t; + +/** + * A liveliness token that can be used to provide the network with information about connectivity to its + * declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key + * expressions. + * + * A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. + */ +typedef struct ALIGN(8) zc_owned_liveliness_token_t { + uint8_t _0[32]; +} zc_owned_liveliness_token_t; + +/** + * The options for :c:func:`zc_liveliness_declare_subscriber` + */ +typedef struct zc_liveliness_get_options_t { + uint32_t timeout_ms; +} zc_liveliness_get_options_t; + /** * An owned sample. * @@ -765,6 +903,85 @@ typedef struct ALIGN(8) zcu_owned_matching_listener_t { uint8_t _0[40]; } zcu_owned_matching_listener_t; +/** + * An owned zenoh publication_cache. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) ze_owned_publication_cache_t { + uint8_t _0[96]; +} ze_owned_publication_cache_t; + +/** + * Options passed to the :c:func:`ze_declare_publication_cache` function. + * + * Members: + * z_keyexpr_t queryable_prefix: The prefix used for queryable + * zcu_locality_t queryable_origin: The restriction for the matching queries that will be receive by this + * publication cache + * bool queryable_complete: the `complete` option for the queryable + * size_t history: The the history size + * size_t resources_limit: The limit number of cached resources + */ +typedef struct ze_publication_cache_options_t { + const struct z_keyexpr_t *queryable_prefix; + enum zcu_locality_t queryable_origin; + bool queryable_complete; + size_t history; + size_t resources_limit; +} ze_publication_cache_options_t; + +/** + * An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. + * + * Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) ze_owned_querying_subscriber_t { + uint8_t _0[64]; +} ze_owned_querying_subscriber_t; + +/** + * Represents the set of options that can be applied to a querying subscriber, + * upon its declaration via :c:func:`ze_declare_querying_subscriber`. + * + * Members: + * z_reliability_t reliability: The subscription reliability. + * zcu_locality_t allowed_origin: The restriction for the matching publications that will be + * receive by this subscriber. + * z_keyexpr_t query_selector: The selector to be used for queries. + * z_query_target_t query_target: The target to be used for queries. + * z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. + * zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. + * uint64_t query_timeout_ms: The timeout to be used for queries. + */ +typedef struct ze_querying_subscriber_options_t { + enum z_reliability_t reliability; + enum zcu_locality_t allowed_origin; + const struct z_keyexpr_t *query_selector; + enum z_query_target_t query_target; + struct z_query_consolidation_t query_consolidation; + enum zcu_reply_keyexpr_t query_accept_replies; + uint64_t query_timeout_ms; +} ze_querying_subscriber_options_t; + +typedef struct ALIGN(8) ze_querying_subscriber_t { + uint8_t _0[8]; +} ze_querying_subscriber_t; + #define Z_OK 0 #define Z_EINVAL -1 @@ -775,6 +992,14 @@ typedef struct ALIGN(8) zcu_owned_matching_listener_t { #define Z_ENETWORK -4 +#define Z_EBUSY_MUTEX -16 + +#define Z_EINVAL_MUTEX -22 + +#define Z_EAGAIN_MUTEX -11 + +#define Z_EPOISON_MUTEX -22 + #define Z_EGENERIC INT8_MIN extern const unsigned int Z_ROUTER; @@ -917,6 +1142,14 @@ ZCError z_bytes_reader_seek(struct z_bytes_reader_t reader, */ ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t reader); +ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); + +ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); + +ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); + +ZENOHC_API struct z_clock_t z_clock_now(void); + /** * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. * @@ -998,7 +1231,7 @@ ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); */ ZENOHC_API void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, - const struct z_sample_t *sample); + struct z_sample_t sample); /** * Drops the closure. Droping an uninitialized closure is a no-op. @@ -1027,6 +1260,20 @@ ZENOHC_API void z_closure_zid_drop(struct z_owned_closure_zid_t *closure); */ ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); +ZENOHC_API bool z_condvar_check(const struct z_owned_condvar_t *this_); + +ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); + +ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); + +ZENOHC_API struct z_condvar_t z_condvar_loan(const struct z_owned_condvar_t *this_); + +ZENOHC_API void z_condvar_null(struct z_owned_condvar_t *this_); + +ZENOHC_API ZCError z_condvar_signal(struct z_condvar_t this_); + +ZENOHC_API ZCError z_condvar_wait(struct z_condvar_t this_, struct z_mutex_t m); + /** * Returns ``true`` if `config` is valid. */ @@ -1152,6 +1399,66 @@ ZCError z_declare_queryable(struct z_session_t session, const struct z_queryable_options_t *options, struct z_owned_queryable_t *this_); +/** + * Declare a subscriber for a given key expression. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to subscribe. + * callback: The callback function that will be called each time a data matching the subscribed expression is received. + * opts: The options to be passed to describe the options to be passed to the subscriber declaration. + * + * Returns: + * A :c:type:`z_owned_subscriber_t`. + * + * To check if the subscription succeeded and if the subscriber is still valid, + * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * Example: + * Declaring a subscriber passing `NULL` for the options: + * + * .. code-block:: C + * + * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); + * + * is equivalent to initializing and passing the default subscriber options: + * + * .. code-block:: C + * + * z_subscriber_options_t opts = z_subscriber_options_default(); + * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); + */ +ZENOHC_API +ZCError z_declare_subscriber(struct z_owned_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct z_subscriber_options_t options); + +/** + * Delete data. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to delete. + * options: The put options. + * Returns: + * ``0`` in case of success, negative values in case of failure. + */ +ZENOHC_API +ZCError z_delete(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_delete_options_t opts); + +/** + * Constructs the default value for :c:type:`z_put_options_t`. + */ +ZENOHC_API struct z_delete_options_t z_delete_options_default(void); + /** * Returns ``true`` if `encoding` is valid. */ @@ -1421,6 +1728,20 @@ ZENOHC_API void z_keyexpr_unchecked(struct z_owned_keyexpr_t *this_, const char *name); +ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); + +ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); + +ZENOHC_API ZCError z_mutex_init(struct z_owned_mutex_t *this_); + +ZENOHC_API struct z_mutex_t z_mutex_loan(const struct z_owned_mutex_t *this_); + +ZENOHC_API ZCError z_mutex_lock(struct z_mutex_t this_); + +ZENOHC_API ZCError z_mutex_try_lock(struct z_mutex_t this_); + +ZENOHC_API ZCError z_mutex_unlock(struct z_mutex_t this_); + /** * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. * Config value is always consumed upon function return. @@ -1498,6 +1819,32 @@ ZCError z_publisher_put(struct z_publisher_t publisher, */ ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); +/** + * Put data, transfering its ownership. + * + * + * The payload's encoding and attachment can be sepcified through the options. These values are consumed upon function + * return. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to put. + * payload: The value to put (consumed upon function return). + * options: The put options. + * Returns: + * ``0`` in case of success, negative error values in case of failure. + */ +ZENOHC_API +ZCError z_put(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_bytes_t *payload, + struct z_put_options_t options); + +/** + * Constructs the default value for :c:type:`z_put_options_t`. + */ +ZENOHC_API struct z_put_options_t z_put_options_default(void); + /** * Gets the attachment to the query by aliasing. * @@ -1666,6 +2013,16 @@ ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); */ ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); +ZENOHC_API void z_random_fill(void *buf, size_t len); + +ZENOHC_API uint16_t z_random_u16(void); + +ZENOHC_API uint32_t z_random_u32(void); + +ZENOHC_API uint64_t z_random_u64(void); + +ZENOHC_API uint8_t z_random_u8(void); + /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1832,6 +2189,12 @@ struct z_session_t z_session_loan(const struct z_owned_session_t *s); */ ZENOHC_API void z_session_null(struct z_owned_session_t *s); +ZENOHC_API int8_t z_sleep_ms(size_t time); + +ZENOHC_API int8_t z_sleep_s(size_t time); + +ZENOHC_API int8_t z_sleep_us(size_t time); + /** * Returns ``true`` if `b` is initialized. */ @@ -1976,6 +2339,61 @@ ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); */ ZENOHC_API struct z_owned_str_t z_str_null(void); +/** + * Returns ``true`` if `sub` is valid. + */ +ZENOHC_API bool z_subscriber_check(const struct z_owned_subscriber_t *subscriber); + +/** + * Returns the key expression of the subscriber. + */ +ZENOHC_API struct z_keyexpr_t z_subscriber_keyexpr(struct z_subscriber_t subscriber); + +/** + * Returns a :c:type:`z_subscriber_t` loaned from `this`. + */ +ZENOHC_API struct z_subscriber_t z_subscriber_loan(const struct z_owned_subscriber_t *this_); + +/** + * Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type + */ +ZENOHC_API void z_subscriber_null(struct z_owned_subscriber_t *this_); + +/** + * Constructs the default value for :c:type:`z_subscriber_options_t`. + */ +ZENOHC_API struct z_subscriber_options_t z_subscriber_options_default(void); + +ZENOHC_API bool z_task_check(const struct z_owned_task_t *this_); + +/** + * Detaches the task and releases all allocated resources. + */ +ZENOHC_API void z_task_detach(struct z_owned_task_t *this_); + +ZENOHC_API +ZCError z_task_init(struct z_owned_task_t *this_, + const struct z_task_attr_t *_attr, + void (*fun)(void *arg), + void *arg); + +/** + * Joins the task and releases all allocated resources + */ +ZENOHC_API ZCError z_task_join(struct z_owned_task_t *this_); + +ZENOHC_API void z_task_null(struct z_owned_task_t *this_); + +ZENOHC_API uint64_t z_time_elapsed_ms(const struct z_time_t *time); + +ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); + +ZENOHC_API uint64_t z_time_elapsed_us(const struct z_time_t *time); + +ZENOHC_API struct z_time_t z_time_now(void); + +ZENOHC_API const char *z_time_now_as_str(const char *buf, size_t len); + ZENOHC_API struct z_id_t z_timestamp_get_id(const struct z_timestamp_t *timestamp); ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp); @@ -2000,6 +2418,12 @@ ZCError z_undeclare_publisher(struct z_owned_publisher_t *publisher); */ ZENOHC_API ZCError z_undeclare_queryable(struct z_owned_queryable_t *qable); +/** + * Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); + /** * Converts the kind of zenoh entity into a string. * @@ -2094,6 +2518,82 @@ void zc_keyexpr_from_slice_unchecked(struct z_owned_keyexpr_t *this_, const char *start, size_t len); +ZENOHC_API +struct zc_liveliness_declaration_options_t zc_liveliness_declaration_options_default(void); + +/** + * Declares a subscriber on liveliness tokens that intersect `key`. + * + * Parameters: + * z_session_t session: The zenoh session. + * z_keyexpr_t key_expr: The key expression to subscribe. + * z_owned_closure_sample_t callback: The callback function that will be called each time a + * liveliness token status changed. + * zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. + * + * Returns: + * A :c:type:`z_owned_subscriber_t`. + * + * To check if the subscription succeeded and if the subscriber is still valid, + * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +ZENOHC_API +ZCError zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct zc_liveliness_declare_subscriber_options_t _options); + +/** + * Constructs and declares a liveliness token on the network. + * + * Liveliness token subscribers on an intersecting key expression will receive a PUT sample when connectivity + * is achieved, and a DELETE sample if it's lost. + * + * Passing `NULL` as options is valid and equivalent to a pointer to the default options. + */ +ZENOHC_API +ZCError zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct zc_liveliness_declaration_options_t _options); + +/** + * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. + * + * Note that the same "value stealing" tricks apply as with a normal :c:func:`z_get` + * + * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. + */ +ZENOHC_API +ZCError zc_liveliness_get(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_reply_t *callback, + struct zc_liveliness_get_options_t options); + +/** + * The gravestone value for `zc_liveliness_get_options_t` + */ +ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_default(void); + +ZENOHC_API +struct zc_liveliness_declare_subscriber_options_t zc_liveliness_subscriber_options_default(void); + +/** + * Returns `true` unless the token is at its gravestone value. + */ +ZENOHC_API bool zc_liveliness_token_check(const struct zc_owned_liveliness_token_t *this_); + +/** + * The gravestone value for liveliness tokens. + */ +ZENOHC_API void zc_liveliness_token_null(struct zc_owned_liveliness_token_t *this_); + +/** + * Destroys a liveliness token, notifying subscribers of its destruction. + */ +ZENOHC_API ZCError zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t *this_); + /** * Creates a new blocking fifo channel, returned as a pair of closures. * @@ -2214,3 +2714,132 @@ ZCError zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, struct zcu_owned_matching_listener_t *this_); ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); + +/** + * Declares a Publication Cache. + * + * Parameters: + * z_session_t session: The zenoh session. + * z_keyexpr_t key_expr: The key expression to publish. + * ze_publication_cache_options_t options: Additional options for the publication_cache. + * + * Returns: + * :c:type:`ze_owned_publication_cache_t`. + * + * + * Example: + * Declaring a publication cache `NULL` for the options: + * + * .. code-block:: C + * + * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), NULL); + * + * is equivalent to initializing and passing the default publication cache options: + * + * .. code-block:: C + * + * ze_publication_cache_options_t opts = ze_publication_cache_options_default(); + * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), &opts); + */ +ZENOHC_API +ZCError ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct ze_publication_cache_options_t options); + +/** + * Declares a Querying Subscriber for a given key expression. + * + * Parameters: + * z_session_t session: The zenoh session. + * z_keyexpr_t keyexpr: The key expression to subscribe. + * z_owned_closure_sample_t callback: The callback function that will be called each time a data matching the subscribed expression is received. + * ze_querying_subscriber_options_t options: Additional options for the querying subscriber. + * + * Returns: + * :c:type:`ze_owned_subscriber_t`. + * + * To check if the subscription succeeded and if the querying subscriber is still valid, + * you may use `ze_querying_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * + * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * Example: + * Declaring a subscriber passing ``NULL`` for the options: + * + * .. code-block:: C + * + * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); + * + * is equivalent to initializing and passing the default subscriber options: + * + * .. code-block:: C + * + * z_subscriber_options_t opts = z_subscriber_options_default(); + * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); + */ +ZENOHC_API +ZCError ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct ze_querying_subscriber_options_t options); + +/** + * Returns ``true`` if `pub_cache` is valid. + */ +ZENOHC_API bool ze_publication_cache_check(const struct ze_owned_publication_cache_t *this_); + +/** + * Constructs a null safe-to-drop value of 'ze_owned_publication_cache_t' type + */ +ZENOHC_API void ze_publication_cache_null(struct ze_owned_publication_cache_t *this_); + +/** + * Constructs the default value for :c:type:`ze_publication_cache_options_t`. + */ +ZENOHC_API struct ze_publication_cache_options_t ze_publication_cache_options_default(void); + +/** + * Returns ``true`` if `this` is valid. + */ +ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subscriber_t *this_); + +/** + * Make a :c:type:`ze_owned_querying_subscriber_t` to perform an additional query on a specified selector. + * The queried samples will be merged with the received publications and made available in the subscriber callback. + */ +ZENOHC_API +ZCError ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, + struct z_keyexpr_t selector, + const struct z_get_options_t *options); + +/** + * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. + */ +ZENOHC_API +struct ze_querying_subscriber_t ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); + +/** + * Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type + */ +ZENOHC_API void ze_querying_subscriber_null(struct ze_owned_querying_subscriber_t *this_); + +/** + * Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. + */ +ZENOHC_API struct ze_querying_subscriber_options_t ze_querying_subscriber_options_default(void); + +/** + * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *this_); + +/** + * Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError ze_undeclare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_); diff --git a/src/closures/sample_closure.rs b/src/closures/sample_closure.rs index 6f0e55707..4d95cf177 100644 --- a/src/closures/sample_closure.rs +++ b/src/closures/sample_closure.rs @@ -4,7 +4,7 @@ use libc::c_void; /// /// Members: /// void *context: a pointer to an arbitrary state. -/// void *call(const struct z_sample_t*, const void *context): the typical callback function. `context` will be passed as its last argument. +/// void *call(struct z_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. /// void *drop(void*): allows the callback's state to be freed. /// /// Closures are not guaranteed not to be called concurrently. @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_sample_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } impl z_owned_closure_sample_t { @@ -47,7 +47,7 @@ pub extern "C" fn z_closure_sample_null() -> z_owned_closure_sample_t { /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_sample_call(closure: &z_owned_closure_sample_t, sample: &z_sample_t) { +pub extern "C" fn z_closure_sample_call(closure: &z_owned_closure_sample_t, sample: z_sample_t) { match closure.call { Some(call) => call(sample, closure.context), None => log::error!("Attempted to call an uninitialized closure!"), @@ -60,10 +60,10 @@ pub extern "C" fn z_closure_sample_drop(closure: &mut z_owned_closure_sample_t) let mut empty_closure = z_owned_closure_sample_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_sample_t { +impl From for z_owned_closure_sample_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(sample: &z_sample_t, this: *mut c_void) { + extern "C" fn call(sample: z_sample_t, this: *mut c_void) { let this = unsafe { &*(this as *const F) }; this(sample) } diff --git a/src/commons.rs b/src/commons.rs index ba29657be..fb245e40b 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -19,6 +19,7 @@ use std::str::FromStr; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; @@ -87,34 +88,34 @@ pub unsafe extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t /// /// A sample is the value associated to a given resource at a given point in time. use crate::opaque_types::z_sample_t; -decl_transmute_copy!(&'static Sample, z_sample_t); +decl_transmute_handle!(Sample, z_sample_t); /// The Key Expression of the sample. /// /// `sample` is aliased by its return value. #[no_mangle] pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); sample.key_expr().into() } /// The encoding of the payload. #[no_mangle] pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); sample.encoding().transmute_copy() } /// The sample's data, the return value aliases the sample. /// #[no_mangle] pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_bytes_t { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); sample.payload().transmute_handle() } /// The sample's kind (put or delete). #[no_mangle] pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); sample.kind().into() } /// The samples timestamp @@ -122,7 +123,7 @@ pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { /// Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. #[no_mangle] pub extern "C" fn z_sample_timestamp(sample: &z_sample_t, timestamp_out: &mut z_timestamp_t) -> bool { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); if let Some(t) = sample.timestamp() { *timestamp_out = t.transmute_copy(); true @@ -136,7 +137,7 @@ pub extern "C" fn z_sample_timestamp(sample: &z_sample_t, timestamp_out: &mut z_ /// Checks if sample contains an attachment. #[no_mangle] pub extern "C" fn z_sample_has_attachment(sample: z_sample_t) -> bool { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); sample.attachment().is_some() } @@ -145,7 +146,7 @@ pub extern "C" fn z_sample_has_attachment(sample: z_sample_t) -> bool { /// Before calling this function, ensure that `zc_sample_has_attachment` returns true #[no_mangle] pub extern "C" fn z_sample_attachment(sample: z_sample_t) -> z_bytes_t { - let sample = sample.transmute_copy(); + let sample = sample.transmute_ref(); sample.attachment().expect("Sample does not have an attachment").transmute_handle() } @@ -155,7 +156,7 @@ decl_transmute_owned!(Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { - let src = src.transmute_copy(); + let src = src.transmute_ref(); let src = src.clone(); let dst = dst.transmute_uninit_ptr(); Inplace::init(dst, Some(src)); @@ -176,7 +177,7 @@ pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] pub extern "C" fn zc_sample_loan(sample: &'static zc_owned_sample_t) -> z_sample_t { - unwrap_ref_unchecked(sample.transmute_ref()).transmute_copy() + unwrap_ref_unchecked(sample.transmute_ref()).transmute_handle() } /// Destroy the sample. diff --git a/src/errors.rs b/src/errors.rs index 90e8508de..298752442 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -4,4 +4,9 @@ pub const Z_EINVAL: ZCError = -1; pub const Z_EPARSE: ZCError = -2; pub const Z_EIO: ZCError = -3; pub const Z_ENETWORK: ZCError = -4; +// negativ pthread error codes (due to convention to return negative values on error) +pub const Z_EBUSY_MUTEX: ZCError = -16; +pub const Z_EINVAL_MUTEX: ZCError = -22; +pub const Z_EAGAIN_MUTEX: ZCError = -11; +pub const Z_EPOISON_MUTEX: ZCError = -22; // same as Z_EINVAL_MUTEX pub const Z_EGENERIC: ZCError = i8::MIN; \ No newline at end of file diff --git a/src/get.rs b/src/get.rs index de8e9d183..9a6855559 100644 --- a/src/get.rs +++ b/src/get.rs @@ -62,7 +62,7 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: z_reply_t) -> bool { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_ok(reply: z_reply_t) -> z_sample_t { let reply = reply.transmute_ref(); - reply.result().expect("Reply does not contain a sample").transmute_copy() + reply.result().expect("Reply does not contain a sample").transmute_handle() } /// Yields the contents of the reply by asserting it indicates a failure. diff --git a/src/keyexpr.rs b/src/keyexpr.rs index cf19224fa..9d4cc194b 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -44,7 +44,7 @@ pub extern "C" fn z_keyexpr_null(this: *mut MaybeUninit) { Inplace::empty(this.transmute_uninit_ptr()); } -fn keyexpr_create_inner(name: &mut str, should_auto_canonize: bool, should_copy: bool) -> Result, Box> { +fn keyexpr_create_inner(name: &'static mut str, should_auto_canonize: bool, should_copy: bool) -> Result, Box> { if should_copy { let s = name.to_owned(); match should_auto_canonize { @@ -69,7 +69,7 @@ unsafe fn keyexpr_create(name: &'static mut [u8], should_auto_canonize: bool, sh Ok(v) } Err(e) => { - log::error!("Couldn't construct a keyexpr from {:02x?}: {}", name, e); + log::error!("Couldn't construct a keyexpr: {}", e); Err(errors::Z_EINVAL) } } diff --git a/src/lib.rs b/src/lib.rs index ad25e1e28..6e6f5843e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,29 +40,28 @@ mod get; pub use crate::get::*; mod queryable; pub use crate::queryable::*; -// mod put; -// pub use crate::put::*; +mod put; +pub use crate::put::*; mod scouting; pub use crate::scouting::*; mod session; pub use crate::session::*; -// mod subscriber; -// pub use crate::subscriber::*; +mod subscriber; +pub use crate::subscriber::*; // // mod pull_subscriber; // // pub use crate::pull_subscriber::*; mod publisher; pub use crate::publisher::*; mod closures; pub use closures::*; -// mod liveliness; -// pub use liveliness::*; -// mod publication_cache; -// pub use publication_cache::*; -// // Disabled due to dependency on z_session_t. To be reworked as for autogeneration this dependency is cicrular. -// // mod querying_subscriber; -// // pub use querying_subscriber::*; -// pub use platform::*; -// pub mod platform; +mod liveliness; +pub use liveliness::*; +mod publication_cache; +pub use publication_cache::*; +mod querying_subscriber; +pub use querying_subscriber::*; +pub use platform::*; +pub mod platform; // #[cfg(feature = "shared-memory")] // mod shm; diff --git a/src/liveliness.rs b/src/liveliness.rs index 46ec7c8a5..ec50a7798 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -12,76 +12,46 @@ // ZettaScale Zenoh Team, // +use std::mem::MaybeUninit; +use zenoh::prelude::SyncResolve; use zenoh::{ - liveliness::{Liveliness, LivelinessToken}, - prelude::SessionDeclarations, + liveliness::{Liveliness, LivelinessToken}, prelude::SessionDeclarations }; +use crate::transmute::TransmuteIntoHandle; use crate::{ - opaque_types::z_sample_t, z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, - z_owned_closure_reply_t, z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t, + errors, transmute::{Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}, z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, z_owned_closure_reply_t, z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t }; -/// A liveliness token that can be used to provide the network with information about connectivity to its -/// declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key -/// expressions. -/// -/// A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. -#[repr(C)] -pub struct zc_owned_liveliness_token_t { - _inner: [usize; 4], -} +use crate::opaque_types::zc_owned_liveliness_token_t; +use crate::opaque_types::zc_liveliness_token_t; +decl_transmute_owned!(Option>, zc_owned_liveliness_token_t); +decl_transmute_handle!(LivelinessToken<'static>, zc_liveliness_token_t); /// The gravestone value for liveliness tokens. #[no_mangle] -pub extern "C" fn zc_liveliness_token_null() -> zc_owned_liveliness_token_t { - zc_owned_liveliness_token_t { _inner: [0; 4] } +pub extern "C" fn zc_liveliness_token_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); } /// Returns `true` unless the token is at its gravestone value. #[no_mangle] -pub extern "C" fn zc_liveliness_token_check(token: &zc_owned_liveliness_token_t) -> bool { - token._inner.iter().any(|v| *v != 0) +pub extern "C" fn zc_liveliness_token_check(this: &zc_owned_liveliness_token_t) -> bool { + this.transmute_ref().is_some() } /// The options for `zc_liveliness_declare_token` #[repr(C)] -pub struct zc_owned_liveliness_declaration_options_t { - _inner: u8, -} -/// The gravestone value for `zc_owned_liveliness_declaration_options_t` -#[no_mangle] -pub extern "C" fn zc_liveliness_declaration_options_null( -) -> zc_owned_liveliness_declaration_options_t { - zc_owned_liveliness_declaration_options_t { _inner: 0 } -} -/// Returns `true` if the options are valid. -#[no_mangle] -pub extern "C" fn zc_liveliness_declaration_options_check( - _opts: &zc_owned_liveliness_declaration_options_t, -) -> bool { - true +pub struct zc_liveliness_declaration_options_t { + _dummy: u8, } -/// Destroys the options. + #[no_mangle] -pub extern "C" fn zc_liveliness_declaration_options_drop( - opts: &mut zc_owned_liveliness_declaration_options_t, -) { - *opts = zc_liveliness_declaration_options_null() -} -impl From> for zc_owned_liveliness_token_t { - fn from(value: LivelinessToken<'static>) -> Self { - unsafe { core::mem::transmute(value) } - } -} -impl From for Option> { - fn from(value: zc_owned_liveliness_token_t) -> Self { - if value._inner.iter().all(|v| *v == 0) { - None - } else { - Some(unsafe { core::mem::transmute(value) }) - } - } +pub extern "C" fn zc_liveliness_declaration_options_default( +) -> zc_liveliness_declaration_options_t { + zc_liveliness_declaration_options_t { _dummy: 0 } } + /// Constructs and declares a liveliness token on the network. /// /// Liveliness token subscribers on an intersecting key expression will receive a PUT sample when connectivity @@ -90,67 +60,57 @@ impl From for Option> { /// Passing `NULL` as options is valid and equivalent to a pointer to the default options. #[no_mangle] pub extern "C" fn zc_liveliness_declare_token( + this: *mut MaybeUninit, session: z_session_t, - key: z_keyexpr_t, - _options: Option<&zc_owned_liveliness_declaration_options_t>, -) -> zc_owned_liveliness_token_t { - let Some(session) = session.upgrade() else { - log::error!("Failed to declare liveliness token: provided session was invalid"); - return zc_liveliness_token_null(); - }; - match session.liveliness().declare_token(key).res() { - Ok(token) => unsafe { core::mem::transmute(token) }, + key_expr: z_keyexpr_t, + _options: zc_liveliness_declaration_options_t, +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); + match session.liveliness().declare_token(key_expr).res() { + Ok(token) => { + Inplace::init(this, Some(token)); + errors::Z_OK + }, Err(e) => { - log::error!("Failed to declare liveliness token: {e}"); - zc_liveliness_token_null() + log::error!("Failed to undeclare token: {e}"); + Inplace::empty(this); + errors::Z_EGENERIC } } } /// Destroys a liveliness token, notifying subscribers of its destruction. #[no_mangle] -pub extern "C" fn zc_liveliness_undeclare_token(token: &mut zc_owned_liveliness_token_t) { - let Some(token): Option = - core::mem::replace(token, zc_liveliness_token_null()).into() - else { - return; - }; - if let Err(e) = token.undeclare().res() { - log::error!("Failed to undeclare token: {e}"); +pub extern "C" fn zc_liveliness_undeclare_token(this: &mut zc_owned_liveliness_token_t) -> errors::ZCError { + let this = this.transmute_mut(); + if let Some(token) = this.extract().take() { + if let Err(e) = token.undeclare().res() { + log::error!("Failed to undeclare token: {e}"); + return errors::Z_EGENERIC; + } } + errors::Z_OK } /// The options for :c:func:`zc_liveliness_declare_subscriber` #[repr(C)] -pub struct zc_owned_liveliness_declare_subscriber_options_t { - _inner: u8, +pub struct zc_liveliness_declare_subscriber_options_t { + _dummy: u8, } -/// The gravestone value for `zc_owned_liveliness_declare_subscriber_options_t` -#[no_mangle] -pub extern "C" fn zc_liveliness_subscriber_options_null( -) -> zc_owned_liveliness_declare_subscriber_options_t { - zc_owned_liveliness_declare_subscriber_options_t { _inner: 0 } -} -/// Returns `true` if the options are valid. -#[no_mangle] -pub extern "C" fn zc_liveliness_subscriber_options_check( - _opts: &zc_owned_liveliness_declare_subscriber_options_t, -) -> bool { - true -} -/// Destroys the options. + #[no_mangle] -pub extern "C" fn zc_liveliness_subscriber_options_drop( - opts: &mut zc_owned_liveliness_declare_subscriber_options_t, -) { - *opts = zc_liveliness_subscriber_options_null() +pub extern "C" fn zc_liveliness_subscriber_options_default( +) -> zc_liveliness_declare_subscriber_options_t { + zc_liveliness_declare_subscriber_options_t { _dummy: 0 } } /// Declares a subscriber on liveliness tokens that intersect `key`. /// /// Parameters: /// z_session_t session: The zenoh session. -/// z_keyexpr_t keyexpr: The key expression to subscribe. +/// z_keyexpr_t key_expr: The key expression to subscribe. /// z_owned_closure_sample_t callback: The callback function that will be called each time a /// liveliness token status changed. /// zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. @@ -162,29 +122,33 @@ pub extern "C" fn zc_liveliness_subscriber_options_drop( /// you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. #[no_mangle] pub extern "C" fn zc_liveliness_declare_subscriber( + this: *mut MaybeUninit, session: z_session_t, - key: z_keyexpr_t, + key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - _options: Option<&zc_owned_liveliness_declare_subscriber_options_t>, -) -> z_owned_subscriber_t { - let Some(session) = session.upgrade() else { - log::error!("Failed to declare liveliness token: provided session was invalid"); - return z_owned_subscriber_t::null(); - }; + _options: zc_liveliness_declare_subscriber_options_t, +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); + let session = session.transmute_copy(); let callback = core::mem::replace(callback, z_owned_closure_sample_t::empty()); + let key_expr = key_expr.transmute_ref(); match session .liveliness() - .declare_subscriber(key) + .declare_subscriber(key_expr) .callback(move |sample| { - let sample = z_sample_t::new(&sample); - z_closure_sample_call(&callback, &sample) + let sample = sample.transmute_handle(); + z_closure_sample_call(&callback, sample) }) .res() { - Ok(token) => z_owned_subscriber_t::new(token), + Ok(subscriber) => { + Inplace::init(this, Some(subscriber)); + errors::Z_OK + } Err(e) => { log::error!("Failed to subscribe to liveliness: {e}"); - z_owned_subscriber_t::null() + Inplace::empty(this); + errors::Z_EGENERIC } } } @@ -194,26 +158,12 @@ pub extern "C" fn zc_liveliness_declare_subscriber( pub struct zc_liveliness_get_options_t { timeout_ms: u32, } -/// The gravestone value for `zc_liveliness_get_options_t` -#[no_mangle] -pub extern "C" fn zc_liveliness_get_options_null() -> zc_liveliness_get_options_t { - zc_liveliness_get_options_t { timeout_ms: 0 } -} + /// The gravestone value for `zc_liveliness_get_options_t` #[no_mangle] pub extern "C" fn zc_liveliness_get_options_default() -> zc_liveliness_get_options_t { zc_liveliness_get_options_t { timeout_ms: 10000 } } -/// Returns `true` if the options are valid. -#[no_mangle] -pub extern "C" fn zc_liveliness_get_options_check(_opts: &zc_liveliness_get_options_t) -> bool { - true -} -/// Destroys the options. -#[no_mangle] -pub extern "C" fn zc_liveliness_get_options_drop(opts: &mut zc_liveliness_get_options_t) { - *opts = zc_liveliness_get_options_null() -} /// Queries liveliness tokens currently on the network with a key expression intersecting with `key`. /// @@ -223,27 +173,23 @@ pub extern "C" fn zc_liveliness_get_options_drop(opts: &mut zc_liveliness_get_op #[no_mangle] pub extern "C" fn zc_liveliness_get( session: z_session_t, - key: z_keyexpr_t, + key_expr: z_keyexpr_t, callback: &mut z_owned_closure_reply_t, - options: Option<&zc_liveliness_get_options_t>, -) -> i8 { - let Some(session) = session.upgrade() else { - log::error!("Failed to declare liveliness token: provided session was invalid"); - return i8::MIN; - }; + options: zc_liveliness_get_options_t, +) -> errors::ZCError { + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); let callback = core::mem::replace(callback, z_owned_closure_reply_t::empty()); let liveliness: Liveliness<'static> = session.liveliness(); let mut builder = liveliness - .get(key) - .callback(move |response| z_closure_reply_call(&callback, &mut response.into())); - if let Some(options) = options { - builder = builder.timeout(core::time::Duration::from_millis(options.timeout_ms as u64)) - } + .get(key_expr) + .callback(move |response| z_closure_reply_call(&callback, response.transmute_handle())); + builder = builder.timeout(core::time::Duration::from_millis(options.timeout_ms as u64)); match builder.res() { - Ok(()) => 0, + Ok(()) => errors::Z_OK, Err(e) => { log::error!("Failed to subscribe to liveliness: {e}"); - e.errno().get() + errors::Z_EGENERIC } } } diff --git a/src/payload.rs b/src/payload.rs index 4ed3feb3e..2dd56c7d9 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -5,7 +5,6 @@ use crate::transmute::{ use crate::{z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, ZHashMap}; use core::slice; use std::any::Any; -use std::borrow::Cow; use std::io::{Read, Seek, SeekFrom}; use std::mem::MaybeUninit; use std::slice::from_raw_parts_mut; @@ -87,7 +86,11 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( ) -> ZCError { let dst = dst.transmute_uninit_ptr(); let payload = payload.transmute_ref(); - let hm = ZHashMap::from_iter(payload.iter::<(Cow<'static, [u8]>, Cow<'static, [u8]>)>()); + let iter = payload.iter::<(Vec, Vec)>(); + let mut hm = ZHashMap::new(); + for (k, v) in iter { + hm.insert(k.into(), v.into()); + } Inplace::init(dst, Some(hm)); errors::Z_OK } diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index a16664352..fa6523128 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -1,240 +1,186 @@ use std::{ - sync::{Condvar, Mutex, MutexGuard}, - thread::{self, JoinHandle}, + mem::MaybeUninit, sync::{Condvar, Mutex, MutexGuard}, thread::{self, JoinHandle} }; use libc::c_void; -use crate::{impl_guarded_transmute, GuardedTransmute}; +use crate::{errors, transmute::{unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}}; +pub use crate::opaque_types::z_owned_mutex_t; +pub use crate::opaque_types::z_mutex_t; -pub struct ZMutex<'a> { - mutex: Mutex<()>, - lock: Option>, -} - -pub struct ZMutexPtr { - data: Option>>, -} - -/// Mutex -/// -#[repr(C)] -#[derive(Clone, Copy)] -pub struct z_mutex_t(usize); +decl_transmute_owned!(Option<(Mutex<()>, Option>)>, z_owned_mutex_t); +decl_transmute_handle!((Mutex<()>, Option>), z_mutex_t); -impl_guarded_transmute!(noderefs z_mutex_t, ZMutexPtr); -impl_guarded_transmute!(noderefs ZMutexPtr, z_mutex_t); -// using the same error codes as in GNU pthreads, but with negative sign -// due to convention to return negative values on error -const EBUSY: i8 = -16; -const EINVAL: i8 = -22; -const EAGAIN: i8 = -11; -const EPOISON: i8 = -22; // same as EINVAL +#[no_mangle] +pub extern "C" fn z_mutex_init(this: *mut MaybeUninit) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); + let m = (Mutex::<()>::new(()), None::>); + Inplace::init(this, Some(m)); + errors::Z_OK +} #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_init(m: *mut z_mutex_t) -> i8 { - if m.is_null() { - return EINVAL; - } - let t = ZMutexPtr { - data: Some(Box::new(ZMutex { - mutex: Mutex::new(()), - lock: None, - })), - }; - *m = t.transmute(); - 0 +pub extern "C" fn z_mutex_drop(this: &mut z_owned_mutex_t) { + let _ = this.transmute_mut().extract().take(); } #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_free(m: *mut z_mutex_t) -> i8 { - if m.is_null() { - return EINVAL; - } - let mut t = (*m).transmute(); +pub extern "C" fn z_mutex_check(this: &z_owned_mutex_t) -> bool { + this.transmute_ref().is_some() +} - t.data.take(); - *m = t.transmute(); - 0 +#[no_mangle] +pub extern "C" fn z_mutex_loan(this: &z_owned_mutex_t) -> z_mutex_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() } + #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_lock(m: *mut z_mutex_t) -> i8 { - if m.is_null() { - return EINVAL; - } - let mut t = (*m).transmute(); - if t.data.is_none() { - return EINVAL; - } - let mut_data = t.data.as_mut().unwrap(); - match mut_data.mutex.lock() { +pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::ZCError { + let this = this.transmute_mut(); + + match this.0.lock() { Ok(new_lock) => { - let old_lock = mut_data.lock.replace(std::mem::transmute(new_lock)); + let old_lock = this.1.replace(new_lock); std::mem::forget(old_lock); } Err(_) => { - return EPOISON; + return errors::Z_EPOISON_MUTEX; } } - - *m = t.transmute(); - 0 + errors::Z_OK } #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_unlock(m: *mut z_mutex_t) -> i8 { - if m.is_null() { - return EINVAL; - } - let mut t = (*m).transmute(); - if t.data.is_none() { - return EINVAL; - } - let mut_data = t.data.as_mut().unwrap(); - if mut_data.lock.is_none() { - return EINVAL; +pub extern "C" fn z_mutex_unlock(this: z_mutex_t) -> errors::ZCError { + let this = this.transmute_mut(); + if this.1.is_none() { + return errors::Z_EINVAL_MUTEX; } else { - mut_data.lock.take(); + this.1.take(); } - *m = t.transmute(); - 0 + errors::Z_OK } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_try_lock(m: *mut z_mutex_t) -> i8 { - if m.is_null() { - return EINVAL; - } - let mut t = (*m).transmute(); - if t.data.is_none() { - return EINVAL; - } - let mut_data = t.data.as_mut().unwrap(); - let mut ret: i8 = 0; - match mut_data.mutex.try_lock() { +pub unsafe extern "C" fn z_mutex_try_lock(this: z_mutex_t) -> errors::ZCError { + let this = this.transmute_mut(); + match this.0.try_lock() { Ok(new_lock) => { - let old_lock = mut_data.lock.replace(std::mem::transmute(new_lock)); + let old_lock = this.1.replace(new_lock); std::mem::forget(old_lock); } Err(_) => { - ret = EBUSY; + return errors::Z_EBUSY_MUTEX; } } - *m = t.transmute(); - ret + errors::Z_OK } -struct ZCondvarPtr { - data: Option>, + +pub use crate::opaque_types::z_owned_condvar_t; +pub use crate::opaque_types::z_condvar_t; + +decl_transmute_owned!(Option, z_owned_condvar_t); +decl_transmute_handle!(Condvar, z_condvar_t); + +#[no_mangle] +pub extern "C" fn z_condvar_init(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::init(this, Some(Condvar::new())); } -/// Condvar -/// -#[repr(C)] -#[derive(Clone, Copy)] -pub struct z_condvar_t(usize); +#[no_mangle] +pub extern "C" fn z_condvar_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); +} -impl_guarded_transmute!(noderefs z_condvar_t, ZCondvarPtr); -impl_guarded_transmute!(noderefs ZCondvarPtr, z_condvar_t); +#[no_mangle] +pub extern "C" fn z_condvar_drop(this: &mut z_owned_condvar_t) { + let _ = this.transmute_mut().extract().take(); +} #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_init(cv: *mut z_condvar_t) -> i8 { - if cv.is_null() { - return EINVAL; - } - let t: ZCondvarPtr = ZCondvarPtr { - data: Some(Box::new(Condvar::new())), - }; - *cv = t.transmute(); - 0 +pub extern "C" fn z_condvar_check(this: &z_owned_condvar_t) -> bool { + this.transmute_ref().is_some() } #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_free(cv: *mut z_condvar_t) -> i8 { - if cv.is_null() { - return EINVAL; - } - let mut t = (*cv).transmute(); - if t.data.is_none() { - return EINVAL; - } - t.data.take(); - *cv = t.transmute(); - 0 +pub extern "C" fn z_condvar_loan(this: &z_owned_condvar_t) -> z_condvar_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() } #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_signal(cv: *mut z_condvar_t) -> i8 { - if cv.is_null() { - return EINVAL; - } - let t = (*cv).transmute(); - if t.data.is_none() { - return EINVAL; - } - t.data.as_ref().unwrap().notify_one(); - *cv = t.transmute(); - 0 +pub extern "C" fn z_condvar_signal(this: z_condvar_t) -> errors::ZCError { + let this = this.transmute_mut(); + this.notify_one(); + errors::Z_OK } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_wait(cv: *mut z_condvar_t, m: *mut z_mutex_t) -> i8 { - if cv.is_null() { - return EINVAL; +pub unsafe extern "C" fn z_condvar_wait(this: z_condvar_t, m: z_mutex_t) -> errors::ZCError { + let this = this.transmute_mut(); + let m = m.transmute_mut(); + if m.1.is_none() { + return errors::Z_EINVAL_MUTEX; // lock was not aquired prior to wait call } - let tcv = (*cv).transmute(); - if tcv.data.is_none() { - return EINVAL; - } - if m.is_null() { - return EINVAL; - } - let mut tm = (*m).transmute(); - if tm.data.is_none() || tm.data.as_ref().unwrap().lock.is_none() { - return EINVAL; - } - let mut_data = tm.data.as_mut().unwrap(); - let lock = mut_data.lock.take().unwrap(); - match tcv.data.as_ref().unwrap().wait(lock) { - Ok(new_lock) => mut_data.lock = Some(std::mem::transmute(new_lock)), - Err(_) => return EPOISON, + + let lock = m.1.take().unwrap(); + match this.wait(lock) { + Ok(new_lock) => m.1 = Some(new_lock), + Err(_) => return errors::Z_EPOISON_MUTEX, } - *cv = tcv.transmute(); - *m = tm.transmute(); - 0 -} -struct ZTask { - join_handle: JoinHandle<()>, + errors::Z_OK } -struct ZTaskPtr { - data: Option>, -} +pub use crate::opaque_types::z_owned_task_t; -/// Task -/// -#[repr(C)] -#[derive(Clone, Copy)] -pub struct z_task_t(usize); +decl_transmute_owned!(Option>, z_owned_task_t); #[repr(C)] #[derive(Clone, Copy)] pub struct z_task_attr_t(usize); -impl_guarded_transmute!(noderefs z_task_t, ZTaskPtr); -impl_guarded_transmute!(noderefs ZTaskPtr, z_task_t); +#[no_mangle] +pub extern "C" fn z_task_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); +} + +/// Detaches the task and releases all allocated resources. +#[no_mangle] +pub extern "C" fn z_task_detach(this: &mut z_owned_task_t) { + let _ = this.transmute_mut().extract().take(); +} + +/// Joins the task and releases all allocated resources +#[no_mangle] +pub extern "C" fn z_task_join(this: &mut z_owned_task_t) -> errors::ZCError { + let this = this.transmute_mut().extract().take(); + if let Some(task) = this { + match task.join() { + Ok(_) => errors::Z_OK, + Err(_) => errors::Z_EINVAL_MUTEX, + } + } else { + errors::Z_OK + } +} + +#[no_mangle] +pub extern "C" fn z_task_check(this: &z_owned_task_t) -> bool { + this.transmute_ref().is_some() +} + struct FunArgPair { fun: unsafe extern "C" fn(arg: *mut c_void), @@ -252,42 +198,19 @@ unsafe impl Send for FunArgPair {} #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_task_init( - task: *mut z_task_t, + this: *mut MaybeUninit, _attr: *const z_task_attr_t, fun: unsafe extern "C" fn(arg: *mut c_void), arg: *mut c_void, -) -> i8 { - if task.is_null() { - return EINVAL; - } - - let mut ttask = ZTaskPtr { data: None }; +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); let fun_arg_pair = FunArgPair { fun, arg }; - let mut ret = 0; match thread::Builder::new().spawn(move || fun_arg_pair.call()) { - Ok(join_handle) => ttask.data = Some(Box::new(ZTask { join_handle })), - Err(_) => ret = EAGAIN, + Ok(join_handle) => { + Inplace::init(this, Some(join_handle)); + }, + Err(_) => return errors::Z_EAGAIN_MUTEX, } - *task = ttask.transmute(); - ret -} - -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_task_join(task: *mut z_task_t) -> i8 { - if task.is_null() { - return EINVAL; - } - let mut ttask = (*task).transmute(); - if ttask.data.is_none() { - return EINVAL; - } - let data = ttask.data.take(); - let ret = match data.unwrap().join_handle.join() { - Ok(_) => 0, - Err(_) => EINVAL, - }; - *task = ttask.transmute(); - ret -} + errors::Z_OK +} \ No newline at end of file diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 50e1dad47..dadc91cc3 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -12,13 +12,15 @@ // ZettaScale Zenoh team, // -use std::ops::Deref; +use std::mem::MaybeUninit; +use zenoh::prelude::SyncResolve; +use std::ptr::null; use zenoh_ext::SessionExt; +use crate::transmute::{Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}; use crate::{ - impl_guarded_transmute, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t, - UninitializedKeyExprError, + errors, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t }; /// Options passed to the :c:func:`ze_declare_publication_cache` function. @@ -32,7 +34,7 @@ use crate::{ /// size_t resources_limit: The limit number of cached resources #[repr(C)] pub struct ze_publication_cache_options_t { - pub queryable_prefix: z_keyexpr_t, + pub queryable_prefix: *const z_keyexpr_t, pub queryable_origin: zcu_locality_t, pub queryable_complete: bool, pub history: usize, @@ -43,7 +45,7 @@ pub struct ze_publication_cache_options_t { #[no_mangle] pub extern "C" fn ze_publication_cache_options_default() -> ze_publication_cache_options_t { ze_publication_cache_options_t { - queryable_prefix: z_keyexpr_t::null(), + queryable_prefix: null(), queryable_origin: zcu_locality_default(), queryable_complete: false, history: 1, @@ -51,36 +53,16 @@ pub extern "C" fn ze_publication_cache_options_default() -> ze_publication_cache } } -/// An owned zenoh publication_cache. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[repr(C)] -pub struct ze_owned_publication_cache_t([usize; 1]); - -type PublicationCache = Option>>; -impl_guarded_transmute!(PublicationCache, ze_owned_publication_cache_t); - -impl ze_owned_publication_cache_t { - pub fn new(pub_cache: zenoh_ext::PublicationCache<'static>) -> Self { - Some(Box::new(pub_cache)).into() - } - pub fn null() -> Self { - None.into() - } -} +pub use crate::opaque_types::ze_owned_publication_cache_t; +pub use crate::opaque_types::ze_publication_cache_t; +decl_transmute_owned!(Option>, ze_owned_publication_cache_t); +decl_transmute_handle!(zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); /// Declares a Publication Cache. /// /// Parameters: /// z_session_t session: The zenoh session. -/// z_keyexpr_t keyexpr: The key expression to publish. +/// z_keyexpr_t key_expr: The key expression to publish. /// ze_publication_cache_options_t options: Additional options for the publication_cache. /// /// Returns: @@ -103,74 +85,64 @@ impl ze_owned_publication_cache_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn ze_declare_publication_cache( + this: *mut MaybeUninit, session: z_session_t, - keyexpr: z_keyexpr_t, - options: Option<&ze_publication_cache_options_t>, -) -> ze_owned_publication_cache_t { - match session.upgrade() { - Some(s) => { - let keyexpr = keyexpr.deref().as_ref().map(|s| s.clone().into_owned()); - if let Some(key_expr) = keyexpr { - let mut p = s.declare_publication_cache(key_expr); - if let Some(options) = options { - p = p.history(options.history); - p = p.queryable_allowed_origin(options.queryable_origin.into()); - p = p.queryable_complete(options.queryable_complete); - if options.resources_limit != 0 { - p = p.resources_limit(options.resources_limit) - } - if options.queryable_prefix.deref().is_some() { - let queryable_prefix = options - .queryable_prefix - .deref() - .as_ref() - .map(|s| s.clone().into_owned()); - if let Some(queryable_prefix) = queryable_prefix { - p = p.queryable_prefix(queryable_prefix) - } - } - } - match p.res_sync() { - Ok(publication_cache) => ze_owned_publication_cache_t::new(publication_cache), - Err(e) => { - log::error!("{}", e); - ze_owned_publication_cache_t::null() - } - } - } else { - log::error!("{}", UninitializedKeyExprError); - ze_owned_publication_cache_t::null() - } + key_expr: z_keyexpr_t, + options: ze_publication_cache_options_t, +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); + let mut p = session.declare_publication_cache(key_expr); + p = p.history(options.history); + p = p.queryable_allowed_origin(options.queryable_origin.into()); + p = p.queryable_complete(options.queryable_complete); + if options.resources_limit != 0 { + p = p.resources_limit(options.resources_limit) + } + if !options.queryable_prefix.is_null() { + let queryable_prefix = unsafe { *options.queryable_prefix }.transmute_ref(); + p = p.queryable_prefix(queryable_prefix.clone()); + } + match p.res_sync() { + Ok(publication_cache) => { + Inplace::init(this, Some(publication_cache)); + errors::Z_OK + } + Err(e) => { + log::error!("{}", e); + Inplace::empty(this); + errors::Z_EGENERIC } - None => ze_owned_publication_cache_t::null(), } } /// Constructs a null safe-to-drop value of 'ze_owned_publication_cache_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn ze_publication_cache_null() -> ze_owned_publication_cache_t { - ze_owned_publication_cache_t::null() +pub extern "C" fn ze_publication_cache_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); } /// Returns ``true`` if `pub_cache` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn ze_publication_cache_check(pub_cache: &ze_owned_publication_cache_t) -> bool { - pub_cache.as_ref().is_some() +pub extern "C" fn ze_publication_cache_check(this: &ze_owned_publication_cache_t) -> bool { + this.transmute_ref().is_some() } /// Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn ze_undeclare_publication_cache( - pub_cache: &mut ze_owned_publication_cache_t, -) -> i8 { - if let Some(p) = pub_cache.take() { + this: &mut ze_owned_publication_cache_t, +) -> errors::ZCError { + if let Some(p) = this.transmute_mut().extract().take() { if let Err(e) = p.close().res_sync() { log::error!("{}", e); - return e.errno().get(); + return errors::Z_EGENERIC; } } - 0 + errors::Z_OK } diff --git a/src/publisher.rs b/src/publisher.rs index 833798959..2ebf4c410 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -304,7 +304,7 @@ pub extern "C" fn zcu_publisher_matching_listener_callback( }) .res(); match listener { - Ok(l) => { + Ok(_) => { Inplace::empty(this); errors::Z_OK }, diff --git a/src/put.rs b/src/put.rs index c2d1bddd2..5457dd522 100644 --- a/src/put.rs +++ b/src/put.rs @@ -1,3 +1,5 @@ +use std::ptr::null_mut; + // // Copyright (c) 2017, 2022 ZettaScale Technology. // @@ -12,24 +14,25 @@ // ZettaScale Zenoh team, // use crate::commons::*; +use crate::errors; use crate::keyexpr::*; use crate::session::*; +use crate::transmute::Inplace; +use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; +use crate::transmute::TransmuteRef; use crate::z_owned_bytes_t; +use crate::z_session_t; use crate::LOG_INVALID_SESSION; use libc::c_void; use zenoh::encoding; +use zenoh::key_expr; use zenoh::prelude::{sync::SyncResolve, Priority, SampleKind}; use zenoh::publication::CongestionControl; -use zenoh::sample::AttachmentBuilder; use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; -use crate::attachment::{ - insert_in_attachment_builder, z_attachment_check, z_attachment_iterate, z_attachment_null, - z_bytes_t, -}; - /// Options passed to the :c:func:`z_put` function. /// /// Members: @@ -40,10 +43,10 @@ use crate::attachment::{ #[repr(C)] #[allow(non_camel_case_types)] pub struct z_put_options_t { - pub encoding: z_encoding_t, + pub encoding: *mut z_owned_encoding_t, pub congestion_control: z_congestion_control_t, pub priority: z_priority_t, - pub attachment:z_bytes_t, + pub attachment: *mut z_owned_bytes_t, } /// Constructs the default value for :c:type:`z_put_options_t`. @@ -51,71 +54,60 @@ pub struct z_put_options_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_put_options_default() -> z_put_options_t { z_put_options_t { - encoding: z_encoding_default(), + encoding: null_mut(), congestion_control: CongestionControl::default().into(), priority: Priority::default().into(), - attachment: z_attachment_null(), + attachment: null_mut(), } } -/// Put data, transfering the buffer ownership. +/// Put data, transfering its ownership. /// -/// This is avoids copies when transfering data that was either: -/// - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher -/// - constructed from a `zc_owned_shmbuf_t` /// -/// The payload's encoding can be sepcified through the options. +/// The payload's encoding and attachment can be sepcified through the options. These values are consumed upon function +/// return. /// /// Parameters: /// session: The zenoh session. -/// keyexpr: The key expression to put. -/// payload: The value to put. +/// key_expr: The key expression to put. +/// payload: The value to put (consumed upon function return). /// options: The put options. /// Returns: -/// ``0`` in case of success, negative values in case of failure. +/// ``0`` in case of success, negative error values in case of failure. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_put( session: z_session_t, - keyexpr: z_keyexpr_t, - payload: Option<&mut z_owned_bytes_t>, - opts: Option<&z_put_options_t>, -) -> i8 { - match session.upgrade() { - Some(s) => { - if let Some(payload) = payload.and_then(|p| p.take()) { - let mut res = s.put(keyexpr, payload); - if let Some(opts) = opts { - res = res - .encoding(**opts.encoding) - .congestion_control(opts.congestion_control.into()) - .priority(opts.priority.into()); - if z_attachment_check(&opts.attachment) { - let mut attachment_builder = AttachmentBuilder::new(); - z_attachment_iterate( - opts.attachment, - insert_in_attachment_builder, - &mut attachment_builder as *mut AttachmentBuilder as *mut c_void, - ); - res = res.attachment(attachment_builder.build()); - }; - } - match res.res_sync() { - Err(e) => { - log::error!("{}", e); - e.errno().get() - } - Ok(()) => 0, - } - } else { - log::debug!("z_bytes_null was provided as payload for put"); - i8::MIN - } - } + key_expr: z_keyexpr_t, + payload: &mut z_owned_bytes_t, + options: z_put_options_t, +) -> errors::ZCError { + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); + let payload = match payload.transmute_mut().extract() { + Some(p) => p, None => { - log::debug!("{}", LOG_INVALID_SESSION); - i8::MIN + log::debug!("Attempted to put with a null payload"); + return errors::Z_EINVAL; } + }; + + let mut put = session.put(key_expr, payload); + + if !options.encoding.is_null() { + let encoding = unsafe{ *options.encoding }.transmute_mut().extract(); + put = put.encoding(encoding); + }; + if !options.attachment.is_null() { + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + put = put.attachment(attachment); + } + + if let Err(e) = put.res_sync() { + log::error!("{}", e); + errors::Z_EGENERIC + } else { + errors::Z_OK } } @@ -141,7 +133,7 @@ pub unsafe extern "C" fn z_delete_options_default() -> z_delete_options_t { /// /// Parameters: /// session: The zenoh session. -/// keyexpr: The key expression to delete. +/// key_expr: The key expression to delete. /// options: The put options. /// Returns: /// ``0`` in case of success, negative values in case of failure. @@ -149,28 +141,21 @@ pub unsafe extern "C" fn z_delete_options_default() -> z_delete_options_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_delete( session: z_session_t, - keyexpr: z_keyexpr_t, - opts: Option<&z_delete_options_t>, -) -> i8 { - match session.upgrade() { - Some(s) => { - let mut res = s.delete(keyexpr); - if let Some(opts) = opts { - res = res - .congestion_control(opts.congestion_control.into()) - .priority(opts.priority.into()); - } - match res.res_sync() { - Err(e) => { - log::error!("{}", e); - e.errno().get() - } - Ok(()) => 0, - } - } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - i8::MIN + key_expr: z_keyexpr_t, + opts: z_delete_options_t, +) -> errors::ZCError { + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); + let del + = session.delete(key_expr) + .congestion_control(opts.congestion_control.into()) + .priority(opts.priority.into()); + + match del.res_sync() { + Err(e) => { + log::error!("{}", e); + errors::Z_EGENERIC } + Ok(()) => errors::Z_OK, } } diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 92e797e2e..4ab406708 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -13,45 +13,37 @@ // use std::mem::MaybeUninit; +use std::ptr::null; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::KeyExpr; use zenoh::prelude::SessionDeclarations; +use zenoh::session; +use zenoh::session::Session; +use zenoh::subscriber::Reliability; use zenoh_ext::*; -use crate::z_closure_owned_query_call; -use crate::ze_owned_publication_cache_t; -use crate::{ - impl_guarded_transmute, opaque_types::z_sample_t, z_closure_sample_call, z_get_options_t, - z_keyexpr_t, z_owned_closure_sample_t, z_query_consolidation_none, z_query_consolidation_t, +use crate::errors; +use crate::transmute::unwrap_ref_unchecked; +use crate::transmute::Inplace; +use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; +use crate::transmute::TransmuteIntoHandle; +use crate::transmute::TransmuteRef; +use crate::transmute::TransmuteUninitPtr; +use crate::z_keyexpr_t; +use crate::z_owned_closure_sample_t; +use crate::z_reliability_t; +use crate::{z_closure_sample_call, z_get_options_t, + z_query_consolidation_none, z_query_consolidation_t, z_query_target_default, z_query_target_t, z_session_t, zcu_locality_default, zcu_locality_t, - zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, LOG_INVALID_SESSION, + zcu_reply_keyexpr_default, zcu_reply_keyexpr_t }; -pub struct FetchingSubscriberWrapper { - fetching_subscriber: zenoh_ext::FetchingSubscriber<'static, ()>, - session: z_session_t, -} -//type FetchingSubscriber = Option>>; - -/// An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. -/// -/// Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. use crate::opaque_types::ze_owned_querying_subscriber_t; -decl_transmute_owned!(default_inplace_init Option>, z_owned_querying_subscriber_t); - use crate::opaque_types::ze_querying_subscriber_t; -decl_transmute_copy!( - &'static Option>, - z_querying_subscriber_t -); +decl_transmute_owned!(Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t); +decl_transmute_handle!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_querying_subscriber_t); /// Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type #[no_mangle] @@ -59,7 +51,7 @@ decl_transmute_copy!( pub extern "C" fn ze_querying_subscriber_null( this: *mut MaybeUninit, ) { - let this = ze_owned_querying_subscriber_t::transmute_uninit_ptr(this); + let this = this.transmute_uninit_ptr(); Inplace::empty(this); } @@ -78,9 +70,9 @@ pub extern "C" fn ze_querying_subscriber_null( #[repr(C)] #[allow(non_camel_case_types)] pub struct ze_querying_subscriber_options_t { - // reliability: z_reliability_t, + reliability: z_reliability_t, allowed_origin: zcu_locality_t, - query_selector: z_keyexpr_t, + query_selector: *const z_keyexpr_t, query_target: z_query_target_t, query_consolidation: z_query_consolidation_t, query_accept_replies: zcu_reply_keyexpr_t, @@ -91,9 +83,9 @@ pub struct ze_querying_subscriber_options_t { #[no_mangle] pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscriber_options_t { ze_querying_subscriber_options_t { - // reliability: SubInfo::default().reliability.into(), + reliability: Reliability::BestEffort.into(), allowed_origin: zcu_locality_default(), - query_selector: z_keyexpr_t::null(), + query_selector: null(), query_target: z_query_target_default(), query_consolidation: z_query_consolidation_none(), query_accept_replies: zcu_reply_keyexpr_default(), @@ -135,55 +127,46 @@ pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscr #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn ze_declare_querying_subscriber( + this: *mut MaybeUninit, session: z_session_t, - keyexpr: z_keyexpr_t, + key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - options: Option<&ze_querying_subscriber_options_t>, -) -> ze_owned_querying_subscriber_t { + options: ze_querying_subscriber_options_t, +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); - - match session.upgrade() { - Some(s) => { - let mut sub = s.declare_subscriber(keyexpr).querying(); - if let Some(options) = options { - sub = sub - // .reliability(options.reliability.into()) - .allowed_origin(options.allowed_origin.into()) - .query_target(options.query_target.into()) - .query_consolidation(options.query_consolidation) - .query_accept_replies(options.query_accept_replies.into()); - if options.query_selector.is_some() { - let query_selector = options - .query_selector - .as_ref() - .map(|s| s.clone().into_owned()); - if let Some(query_selector) = query_selector { - sub = sub.query_selector(query_selector) - } - } - if options.query_timeout_ms != 0 { - sub = sub - .query_timeout(std::time::Duration::from_millis(options.query_timeout_ms)); - } - } - match sub - .callback(move |sample| { - let sample = z_sample_t::new(&sample); - z_closure_sample_call(&closure, &sample) - }) - .res() - { - Ok(sub) => ze_owned_querying_subscriber_t::new(sub, session), - Err(e) => { - log::debug!("{}", e); - ze_owned_querying_subscriber_t::null() - } - } + let session = session.transmute_copy(); + let mut sub = session.declare_subscriber(key_expr.transmute_ref()).querying(); + sub = sub + .reliability(options.reliability.into()) + .allowed_origin(options.allowed_origin.into()) + .query_target(options.query_target.into()) + .query_consolidation(options.query_consolidation) + .query_accept_replies(options.query_accept_replies.into()); + if !options.query_selector.is_null() { + let query_selector = unsafe { *options.query_selector }.transmute_ref().clone(); + sub = sub.query_selector(query_selector) + } + if options.query_timeout_ms != 0 { + sub = sub + .query_timeout(std::time::Duration::from_millis(options.query_timeout_ms)); + } + let sub = sub + .callback(move |sample| { + let sample = sample.transmute_handle(); + z_closure_sample_call(&closure, sample); + }); + match sub.res() + { + Ok(sub) => { + Inplace::init(this, Some((sub, session))); + errors::Z_OK } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - ze_owned_querying_subscriber_t::null() + Err(e) => { + log::debug!("{}", e); + Inplace::empty(this); + errors::Z_EGENERIC } } } @@ -196,68 +179,57 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( sub: ze_querying_subscriber_t, selector: z_keyexpr_t, options: Option<&z_get_options_t>, -) -> i8 { +) -> errors::ZCError { unsafe impl Sync for z_get_options_t {} - - if let Some(sub) = sub.as_ref() { - match sub.session.upgrade() { - Some(s) => { - if let Err(e) = sub - .fetching_subscriber - .fetch({ - let selector = KeyExpr::try_from(selector).unwrap(); - move |cb| match options { - Some(options) => s - .get(selector) - .target(options.target.into()) - .consolidation(options.consolidation) - .timeout(std::time::Duration::from_millis(options.timeout_ms)) - .callback(cb) - .res_sync(), - None => s.get(selector).callback(cb).res_sync(), - } - }) - .res() - { - log::debug!("{}", e); - return -1; - } - } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - return -1; - } + let sub = sub.transmute_ref(); + let session = sub.1; + let selector = selector.transmute_ref().clone(); + if let Err(e) = sub.0 + .fetch({ + let selector = KeyExpr::try_from(selector).unwrap(); + move |cb| match options { + Some(options) => session + .get(selector) + .target(options.target.into()) + .consolidation(options.consolidation) + .timeout(std::time::Duration::from_millis(options.timeout_ms)) + .callback(cb) + .res_sync(), + None => session.get(selector).callback(cb).res_sync(), } + }) + .res() + { + log::debug!("{}", e); + return errors::Z_EGENERIC; } - 0 + errors::Z_OK } /// Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn ze_undeclare_querying_subscriber(sub: &mut ze_owned_querying_subscriber_t) -> i8 { - let sub = sub.transmute_mut(); - - if let Some(s) = sub.take() { - if let Err(e) = s.fetching_subscriber.close().res_sync() { - log::warn!("{}", e); - return e.errno().get(); +pub extern "C" fn ze_undeclare_querying_subscriber(this: &mut ze_owned_querying_subscriber_t) -> errors::ZCError { + if let Some(s) = this.transmute_mut().extract().take() { + if let Err(e) = s.0.close().res_sync() { + log::error!("{}", e); + return errors::Z_EGENERIC } } - 0 + errors::Z_OK } -/// Returns ``true`` if `sub` is valid. +/// Returns ``true`` if `this` is valid. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn ze_querying_subscriber_check(sub: &ze_owned_querying_subscriber_t) -> bool { - sub.as_ref().is_some() +pub extern "C" fn ze_querying_subscriber_check(this: &ze_owned_querying_subscriber_t) -> bool { + this.transmute_ref().is_some() } -/// Returns a :c:type:`ze_querying_subscriber_loan` loaned from `p`. +/// Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. #[no_mangle] -pub extern "C" fn ze_querying_subscriber_loan( - p: &ze_owned_querying_subscriber_t, -) -> ze_querying_subscriber_t { - ze_querying_subscriber_t(p) +pub extern "C" fn ze_querying_subscriber_loan(this: &ze_owned_querying_subscriber_t,) -> ze_querying_subscriber_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() } diff --git a/src/subscriber.rs b/src/subscriber.rs index acdae4f60..ceab769cf 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -12,107 +12,76 @@ // ZettaScale Zenoh team, // -use crate::commons::*; -use crate::impl_guarded_transmute; +use std::mem::MaybeUninit; + +use crate::errors; use crate::keyexpr::*; -use crate::session::*; +use crate::transmute::unwrap_ref_unchecked; +use crate::transmute::Inplace; +use crate::transmute::TransmuteCopy; +use crate::transmute::TransmuteFromHandle; +use crate::transmute::TransmuteIntoHandle; +use crate::transmute::TransmuteRef; +use crate::transmute::TransmuteUninitPtr; use crate::z_closure_sample_call; use crate::z_owned_closure_sample_t; -use crate::LOG_INVALID_SESSION; +use crate::z_session_t; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; -// use zenoh::subscriber::Reliability; -// use zenoh_protocol::core::SubInfo; -use zenoh_util::core::zresult::ErrNo; +use zenoh::subscriber::Reliability; +use zenoh::subscriber::Subscriber; /// The subscription reliability. /// /// - **Z_RELIABILITY_BEST_EFFORT** /// - **Z_RELIABILITY_RELIABLE** -// #[allow(non_camel_case_types, clippy::upper_case_acronyms)] -// #[repr(C)] -// #[derive(Clone, Copy)] -// pub enum z_reliability_t { -// BEST_EFFORT, -// RELIABLE, -// } - -// impl From for z_reliability_t { -// #[inline] -// fn from(r: Reliability) -> Self { -// match r { -// Reliability::BestEffort => z_reliability_t::BEST_EFFORT, -// Reliability::Reliable => z_reliability_t::RELIABLE, -// } -// } -// } - -// impl From for Reliability { -// #[inline] -// fn from(val: z_reliability_t) -> Self { -// match val { -// z_reliability_t::BEST_EFFORT => Reliability::BestEffort, -// z_reliability_t::RELIABLE => Reliability::Reliable, -// } -// } -// } - -/**************************************/ -/* DECLARATION */ -/**************************************/ -type Subscriber = Option>>; - -/// An owned zenoh subscriber. Destroying the subscriber cancels the subscription. -/// -/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. -/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. -/// -/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. -/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. -/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. -/// -/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -#[cfg(not(target_arch = "arm"))] -#[repr(C, align(8))] -pub struct z_owned_subscriber_t([u64; 1]); - -#[cfg(target_arch = "arm")] -#[repr(C, align(4))] -pub struct z_owned_subscriber_t([u32; 1]); - -impl_guarded_transmute!(Subscriber, z_owned_subscriber_t); +#[allow(non_camel_case_types, clippy::upper_case_acronyms)] +#[repr(C)] +#[derive(Clone, Copy)] +pub enum z_reliability_t { + BEST_EFFORT, + RELIABLE, +} -impl z_owned_subscriber_t { - pub fn new(sub: zenoh::subscriber::Subscriber<'static, ()>) -> Self { - Some(Box::new(sub)).into() - } - pub fn null() -> Self { - None.into() +impl From for z_reliability_t { +#[inline] + fn from(r: Reliability) -> Self { + match r { + Reliability::BestEffort => z_reliability_t::BEST_EFFORT, + Reliability::Reliable => z_reliability_t::RELIABLE, + } } } -/// Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type -#[no_mangle] -pub extern "C" fn z_subscriber_null() -> z_owned_subscriber_t { - z_owned_subscriber_t::null() +impl From for Reliability { +#[inline] + fn from(val: z_reliability_t) -> Self { + match val { + z_reliability_t::BEST_EFFORT => Reliability::BestEffort, + z_reliability_t::RELIABLE => Reliability::Reliable, + } + } } -/// A loaned zenoh subscriber. -#[allow(non_camel_case_types)] -#[derive(Clone, Copy)] -#[repr(C)] -pub struct z_subscriber_t(*const z_owned_subscriber_t); +pub use crate::opaque_types::z_owned_subscriber_t; +pub use crate::opaque_types::z_subscriber_t; -impl AsRef for z_subscriber_t { - fn as_ref(&self) -> &Subscriber { - unsafe { &(*self.0) } - } +decl_transmute_owned!(Option>, z_owned_subscriber_t); +decl_transmute_handle!(Subscriber<'static, ()>, z_subscriber_t); + +/// Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type +#[no_mangle] +pub extern "C" fn z_subscriber_null(this: *mut MaybeUninit) { + let this = this.transmute_uninit_ptr(); + Inplace::empty(this); } -/// Returns a :c:type:`z_subscriber_t` loaned from `p`. +/// Returns a :c:type:`z_subscriber_t` loaned from `this`. #[no_mangle] -pub extern "C" fn z_subscriber_loan(p: &z_owned_subscriber_t) -> z_subscriber_t { - z_subscriber_t(p) +pub extern "C" fn z_subscriber_loan(this: &z_owned_subscriber_t) -> z_subscriber_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() } /// Options passed to the :c:func:`z_declare_subscriber` or :c:func:`z_declare_pull_subscriber` function. @@ -122,15 +91,14 @@ pub extern "C" fn z_subscriber_loan(p: &z_owned_subscriber_t) -> z_subscriber_t #[allow(non_camel_case_types)] #[repr(C)] pub struct z_subscriber_options_t { - // pub reliability: z_reliability_t, + pub reliability: z_reliability_t, } /// Constructs the default value for :c:type:`z_subscriber_options_t`. #[no_mangle] pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { - // let info = SubInfo::default(); z_subscriber_options_t { - // reliability: info.reliability.into(), + reliability: Reliability::BestEffort.into() } } @@ -138,7 +106,7 @@ pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { /// /// Parameters: /// session: The zenoh session. -/// keyexpr: The key expression to subscribe. +/// key_expr: The key expression to subscribe. /// callback: The callback function that will be called each time a data matching the subscribed expression is received. /// opts: The options to be passed to describe the options to be passed to the subscriber declaration. /// @@ -168,34 +136,33 @@ pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_subscriber( + this: *mut MaybeUninit, session: z_session_t, - keyexpr: z_keyexpr_t, + key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - opts: Option<&z_subscriber_options_t>, -) -> z_owned_subscriber_t { + options: z_subscriber_options_t, +) -> errors::ZCError { + let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); - - match session.upgrade() { - Some(s) => { - let mut res = s.declare_subscriber(keyexpr).callback(move |sample| { - let sample = z_sample_t::new(&sample); - z_closure_sample_call(&closure, &sample) - }); - if let Some(opts) = opts { - // res = res.reliability(opts.reliability.into()) - } - match res.res() { - Ok(sub) => z_owned_subscriber_t::new(sub), - Err(e) => { - log::debug!("{}", e); - z_owned_subscriber_t::null() - } - } - } - None => { - log::debug!("{}", LOG_INVALID_SESSION); - z_owned_subscriber_t::null() + let session = session.transmute_copy(); + let key_expr = key_expr.transmute_ref(); + let subscriber + = session.declare_subscriber(key_expr).callback(move |sample| { + let sample = sample.transmute_handle(); + z_closure_sample_call(&closure, sample) + }); + + let subscriber = subscriber.reliability(options.reliability.into()); + match subscriber.res() { + Ok(sub) => { + Inplace::init(this, Some(sub)); + errors::Z_OK + }, + Err(e) => { + log::error!("{}", e); + Inplace::empty(this); + errors::Z_EGENERIC } } } @@ -203,30 +170,27 @@ pub extern "C" fn z_declare_subscriber( /// Returns the key expression of the subscriber. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_subscriber_keyexpr(subscriber: z_subscriber_t) -> z_owned_keyexpr_t { - if let Some(p) = subscriber.as_ref() { - p.key_expr().clone().into() - } else { - z_keyexpr_t::null().into() - } +pub extern "C" fn z_subscriber_keyexpr(subscriber: z_subscriber_t) -> z_keyexpr_t { + let subscriber = subscriber.transmute_ref(); + subscriber.key_expr().transmute_handle() } /// Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_undeclare_subscriber(sub: &mut z_owned_subscriber_t) -> i8 { - if let Some(s) = sub.take() { +pub extern "C" fn z_undeclare_subscriber(subscriber: &mut z_owned_subscriber_t) -> errors::ZCError { + if let Some(s) = subscriber.transmute_mut().extract().take() { if let Err(e) = s.undeclare().res_sync() { - log::warn!("{}", e); - return e.errno().get(); + log::error!("{}", e); + return errors::Z_EGENERIC } } - 0 + errors::Z_OK } /// Returns ``true`` if `sub` is valid. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_subscriber_check(sub: &z_owned_subscriber_t) -> bool { - sub.as_ref().is_some() +pub extern "C" fn z_subscriber_check(subscriber: &z_owned_subscriber_t) -> bool { + subscriber.transmute_ref().is_some() } diff --git a/src/transmute.rs b/src/transmute.rs index 4aaa3d157..cafe930ea 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -92,27 +92,24 @@ impl Inplace for T { macro_rules! validate_equivalence { ($type_a:ty, $type_b:ty) => { const _: () = { - let align_a = std::mem::align_of::<$type_a>(); - let align_b = std::mem::align_of::<$type_b>(); - if align_a != align_b { - panic!( - "Alingment mismatch: type `{}` has align {}, type `{}` has align {}", - stringify!($type_a), - align_a, - stringify!($type_b), - align_b - ); + use const_format::concatcp; + const TYPE_NAME_A: &str = stringify!($type_a); + const TYPE_NAME_B: &str = stringify!($type_b); + const ALIGN_A: usize = std::mem::align_of::<$type_a>(); + const ALIGN_B: usize = std::mem::align_of::<$type_b>(); + if ALIGN_A != ALIGN_B { + const ERR_MESSAGE: &str = concatcp!( + "Alingment mismatch: type ", TYPE_NAME_A, " has alignment ", ALIGN_A, + " while type ", TYPE_NAME_B, " has alignment ", ALIGN_B); + panic!("{}", ERR_MESSAGE); } - let size_a = std::mem::size_of::<$type_a>(); - let size_b = std::mem::size_of::<$type_b>(); - if size_a != size_b { - panic!( - "Size mismatch: type `{}` has size {}, type `{}` has size {}", - stringify!($type_a), - size_a, - stringify!($type_b), - size_b - ); + const SIZE_A: usize = std::mem::size_of::<$type_a>(); + const SIZE_B: usize = std::mem::size_of::<$type_b>(); + if SIZE_A != SIZE_B { + const ERR_MESSAGE: &str = concatcp!( + "Size mismatch: type ", TYPE_NAME_A, " has size ", SIZE_A, + " while type ", TYPE_NAME_B, " has size ", SIZE_B); + panic!("{}", ERR_MESSAGE); } }; }; From 6a92b922e09df8e9da77ddf1977fb6b5f8454dc1 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 23 Apr 2024 09:38:34 +0200 Subject: [PATCH 55/75] fixes --- build.rs | 4 +- include/zenoh-gen.h | 2845 ------------------------------------ include/zenoh_commons.h | 2390 ++++++++++++++++++++++++++++++ include/zenoh_concrete.h | 67 + src/commons.rs | 10 +- src/get.rs | 4 +- src/info.rs | 8 +- src/keyexpr.rs | 4 +- src/liveliness.rs | 6 +- src/payload.rs | 39 +- src/publication_cache.rs | 2 +- src/publisher.rs | 15 +- src/put.rs | 4 +- src/queryable.rs | 4 +- src/querying_subscriber.rs | 4 +- src/session.rs | 22 +- src/subscriber.rs | 4 +- 17 files changed, 2526 insertions(+), 2906 deletions(-) delete mode 100644 include/zenoh-gen.h diff --git a/build.rs b/build.rs index 120b308f7..83eabc4f8 100644 --- a/build.rs +++ b/build.rs @@ -40,8 +40,8 @@ fn main() { configure(); let split_guide = SplitGuide::from_yaml(SPLITGUIDE_PATH); - // split_bindings(&split_guide).unwrap(); - // text_replace(split_guide.rules.iter().map(|(name, _)| name.as_str())); + split_bindings(&split_guide).unwrap(); + text_replace(split_guide.rules.iter().map(|(name, _)| name.as_str())); fs_extra::copy_items( &["include"], diff --git a/include/zenoh-gen.h b/include/zenoh-gen.h deleted file mode 100644 index 19b3fc6c9..000000000 --- a/include/zenoh-gen.h +++ /dev/null @@ -1,2845 +0,0 @@ -#include -#include -#include -#include -#include - - - - -#define DEFAULT_SCOUTING_TIMEOUT 1000 - -/** - * The kind of congestion control. - * - * - **BLOCK** - * - **DROP** - */ -typedef enum z_congestion_control_t { - Z_CONGESTION_CONTROL_T_BLOCK, - Z_CONGESTION_CONTROL_T_DROP, -} z_congestion_control_t; - -/** - * Consolidation mode values. - * - * - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector - * If the selector contains time range properties, consolidation mode `NONE` is used. - * Otherwise the `LATEST` consolidation mode is used. - * - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. - * - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time - * w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple - * replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp - * ts2 > ts1. It optimizes latency. - * - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. - * It optimizes bandwidth. - */ -typedef enum z_consolidation_mode_t { - Z_CONSOLIDATION_MODE_T_AUTO = -1, - Z_CONSOLIDATION_MODE_T_NONE = 0, - Z_CONSOLIDATION_MODE_T_MONOTONIC = 1, - Z_CONSOLIDATION_MODE_T_LATEST = 2, -} z_consolidation_mode_t; - -/** - * A :c:type:`z_keyexpr_intersection_level_t`. - * - * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** - * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** - */ -typedef enum z_keyexpr_intersection_level_t { - Z_KEYEXPR_INTERSECTION_LEVEL_T_DISJOINT = 0, - Z_KEYEXPR_INTERSECTION_LEVEL_T_INTERSECTS = 1, - Z_KEYEXPR_INTERSECTION_LEVEL_T_INCLUDES = 2, - Z_KEYEXPR_INTERSECTION_LEVEL_T_EQUALS = 3, -} z_keyexpr_intersection_level_t; - -/** - * The priority of zenoh messages. - * - * - **REAL_TIME** - * - **INTERACTIVE_HIGH** - * - **INTERACTIVE_LOW** - * - **DATA_HIGH** - * - **DATA** - * - **DATA_LOW** - * - **BACKGROUND** - */ -typedef enum z_priority_t { - Z_PRIORITY_T_REAL_TIME = 1, - Z_PRIORITY_T_INTERACTIVE_HIGH = 2, - Z_PRIORITY_T_INTERACTIVE_LOW = 3, - Z_PRIORITY_T_DATA_HIGH = 4, - Z_PRIORITY_T_DATA = 5, - Z_PRIORITY_T_DATA_LOW = 6, - Z_PRIORITY_T_BACKGROUND = 7, -} z_priority_t; - -/** - * The Queryables that should be target of a :c:func:`z_get`. - * - * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. - * - **ALL_COMPLETE**: All complete queryables. - * - **ALL**: All matching queryables. - */ -typedef enum z_query_target_t { - Z_QUERY_TARGET_T_BEST_MATCHING, - Z_QUERY_TARGET_T_ALL, - Z_QUERY_TARGET_T_ALL_COMPLETE, -} z_query_target_t; - -/** - * The subscription reliability. - * - * - **Z_RELIABILITY_BEST_EFFORT** - * - **Z_RELIABILITY_RELIABLE** - */ -typedef enum z_reliability_t { - Z_RELIABILITY_T_BEST_EFFORT, - Z_RELIABILITY_T_RELIABLE, -} z_reliability_t; - -typedef enum z_sample_kind_t { - Z_SAMPLE_KIND_T_PUT = 0, - Z_SAMPLE_KIND_T_DELETE = 1, -} z_sample_kind_t; - -typedef enum zcu_locality_t { - ZCU_LOCALITY_T_ANY = 0, - ZCU_LOCALITY_T_SESSION_LOCAL = 1, - ZCU_LOCALITY_T_REMOTE = 2, -} zcu_locality_t; - -typedef enum zcu_reply_keyexpr_t { - ZCU_REPLY_KEYEXPR_T_ANY = 0, - ZCU_REPLY_KEYEXPR_T_MATCHING_QUERY = 1, -} zcu_reply_keyexpr_t; - -/** - * A split buffer that owns all of its data. - * - * To minimize copies and reallocations, Zenoh may provide you data in split buffers. - */ -typedef struct ALIGN(8) z_owned_bytes_t { - uint8_t _0[40]; -} z_owned_bytes_t; - -typedef int8_t ZCError; - -/** - * A loaned payload. - */ -typedef struct ALIGN(8) z_bytes_t { - uint8_t _0[8]; -} z_bytes_t; - -typedef struct z_owned_slice_t { - uint8_t *start; - size_t len; -} z_owned_slice_t; - -/** - * A map of maybe-owned vector of bytes to maybe-owned vector of bytes. - * - * In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher - */ -typedef struct ALIGN(8) z_owned_slice_map_t { - uint8_t _0[48]; -} z_owned_slice_map_t; - -/** - * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` - * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with - * `z_check` and `z_str_check` correspondently - */ -typedef struct z_owned_str_t { - char *_cstr; -} z_owned_str_t; - -/** - * A contiguous view of bytes owned by some other entity. - * - * `start` being `null` is considered a gravestone value, - * and empty slices are represented using a possibly dangling pointer for `start`. - */ -typedef struct z_slice_t { - const uint8_t *start; - size_t len; -} z_slice_t; - -typedef struct ALIGN(8) z_slice_map_t { - uint8_t _0[8]; -} z_slice_map_t; - -/** - * A reader for payload data. - */ -typedef struct ALIGN(8) z_owned_bytes_t_reader_t { - uint8_t _0[24]; -} z_owned_bytes_t_reader_t; - -typedef struct ALIGN(8) z_bytes_reader_t { - uint8_t _0[8]; -} z_bytes_reader_t; - -/** - * Clock - * Uses monotonic clock - */ -typedef struct z_clock_t { - uint64_t t; - const void *t_base; -} z_clock_t; - -/** - * An owned zenoh session. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_session_t { - uint8_t _0[8]; -} z_owned_session_t; - -/** - * Represents a Zenoh ID. - * - * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. - */ -typedef struct ALIGN(1) z_id_t { - uint8_t _0[16]; -} z_id_t; - -/** - * An owned array of owned, zenoh allocated, NULL terminated strings. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct z_owned_str_array_t { - char **val; - size_t len; -} z_owned_str_array_t; - -/** - * A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. - * - * Members: - * unsigned int whatami: The kind of zenoh entity. - * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). - * z_owned_str_array_t locators: The locators of the scouted entity. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -typedef struct z_owned_hello_t { - unsigned int _whatami; - struct z_id_t _pid; - struct z_owned_str_array_t _locators; -} z_owned_hello_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_hello_t { - void *context; - void (*call)(struct z_owned_hello_t*, void*); - void (*drop)(void*); -} z_owned_closure_hello_t; - -/** - * - * Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. - * `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. - */ -typedef struct ALIGN(8) z_owned_query_t { - uint8_t _0[16]; -} z_owned_query_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_owned_query_t { - void *context; - void (*call)(struct z_owned_query_t*, void *context); - void (*drop)(void*); -} z_owned_closure_owned_query_t; - -typedef struct ALIGN(8) z_query_t { - uint8_t _0[8]; -} z_query_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(z_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_query_t { - void *context; - void (*call)(struct z_query_t, void *context); - void (*drop)(void*); -} z_owned_closure_query_t; - -typedef struct ALIGN(8) z_reply_t { - uint8_t _0[8]; -} z_reply_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_reply_t { - void *context; - void (*call)(struct z_reply_t, void*); - void (*drop)(void*); -} z_owned_closure_reply_t; - -typedef struct ALIGN(8) z_sample_t { - uint8_t _0[8]; -} z_sample_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(struct z_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_sample_t { - void *context; - void (*call)(struct z_sample_t, void *context); - void (*drop)(void*); -} z_owned_closure_sample_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_closure_zid_t { - void *context; - void (*call)(const struct z_id_t*, void*); - void (*drop)(void*); -} z_owned_closure_zid_t; - -typedef struct ALIGN(8) z_owned_condvar_t { - uint8_t _0[24]; -} z_owned_condvar_t; - -typedef struct ALIGN(8) z_condvar_t { - uint8_t _0[8]; -} z_condvar_t; - -typedef struct ALIGN(8) z_mutex_t { - uint8_t _0[8]; -} z_mutex_t; - -/** - * An owned zenoh configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_config_t { - uint8_t _0[8]; -} z_owned_config_t; - -/** - * A loaned zenoh configuration. - */ -typedef struct ALIGN(8) z_config_t { - uint8_t _0[8]; -} z_config_t; - -/** - * A zenoh-allocated key expression. - * - * Key expressions can identify a single key or a set of keys. - * - * Examples : - * - ``"key/expression"``. - * - ``"key/ex*"``. - * - * Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` - * for wire and computation efficiency. - * - * A `key expression `_ can be either: - * - A plain string expression. - * - A pure numerical id. - * - The combination of a numerical prefix and a string suffix. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_keyexpr_t { - uint8_t _0[32]; -} z_owned_keyexpr_t; - -typedef struct ALIGN(8) z_session_t { - uint8_t _0[8]; -} z_session_t; - -/** - * A loaned key expression. - * - * Key expressions can identify a single key or a set of keys. - * - * Examples : - * - ``"key/expression"``. - * - ``"key/ex*"``. - * - * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, - * both for local processing and network-wise. - */ -typedef struct ALIGN(8) z_keyexpr_t { - uint8_t _0[8]; -} z_keyexpr_t; - -/** - * Options passed to the :c:func:`z_declare_publisher` function. - * - * Members: - * z_congestion_control_t congestion_control: The congestion control to apply when routing messages from this publisher. - * z_priority_t priority: The priority of messages from this publisher. - */ -typedef struct z_publisher_options_t { - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; -} z_publisher_options_t; - -/** - * An owned zenoh publisher. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_publisher_t { - uint8_t _0[56]; -} z_owned_publisher_t; - -/** - * Options passed to the :c:func:`z_declare_queryable` function. - * - * Members: - * bool complete: The completeness of the Queryable. - */ -typedef struct z_queryable_options_t { - bool complete; -} z_queryable_options_t; - -/** - * An owned zenoh queryable. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_queryable_t { - uint8_t _0[32]; -} z_owned_queryable_t; - -/** - * An owned zenoh subscriber. Destroying the subscriber cancels the subscription. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_subscriber_t { - uint8_t _0[32]; -} z_owned_subscriber_t; - -/** - * Options passed to the :c:func:`z_declare_subscriber` or :c:func:`z_declare_pull_subscriber` function. - * - * Members: - * z_reliability_t reliability: The subscription reliability. - */ -typedef struct z_subscriber_options_t { - enum z_reliability_t reliability; -} z_subscriber_options_t; - -/** - * Options passed to the :c:func:`z_delete` function. - */ -typedef struct z_delete_options_t { - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; -} z_delete_options_t; - -typedef struct ALIGN(8) z_owned_encoding_t { - uint8_t _0[48]; -} z_owned_encoding_t; - -/** - * The encoding of a payload, in a MIME-like format. - * - * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. - */ -typedef struct ALIGN(8) z_encoding_t { - uint8_t _0[8]; -} z_encoding_t; - -/** - * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. - */ -typedef struct z_query_consolidation_t { - enum z_consolidation_mode_t mode; -} z_query_consolidation_t; - -/** - * Options passed to the :c:func:`z_get` function. - * - * Members: - * z_query_target_t target: The Queryables that should be target of the query. - * z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. - * z_value_t value: An optional value to attach to the query. - * z_bytes_t attachment: The attachment to attach to the query. - * uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. - */ -typedef struct z_get_options_t { - enum z_query_target_t target; - struct z_query_consolidation_t consolidation; - struct z_owned_bytes_t *payload; - struct z_owned_encoding_t *encoding; - struct z_owned_bytes_t *attachment; - uint64_t timeout_ms; -} z_get_options_t; - -/** - * An borrowed array of borrowed, zenoh allocated, NULL terminated strings. - */ -typedef struct z_str_array_t { - size_t len; - const char *const *val; -} z_str_array_t; - -/** - * A reference-type hello message returned by a zenoh entity to a scout message sent with `z_scout`. - * - * Members: - * unsigned int whatami: The kind of zenoh entity. - * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). - * z_owned_str_array_t locators: The locators of the scouted entity. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -typedef struct z_hello_t { - unsigned int whatami; - struct z_id_t pid; - struct z_str_array_t locators; -} z_hello_t; - -typedef struct ALIGN(8) z_owned_mutex_t { - uint8_t _0[32]; -} z_owned_mutex_t; - -typedef struct ALIGN(8) z_publisher_t { - uint8_t _0[8]; -} z_publisher_t; - -/** - * Represents the set of options that can be applied to the delete operation by a previously declared publisher, - * whenever issued via :c:func:`z_publisher_delete`. - */ -typedef struct z_publisher_delete_options_t { - uint8_t __dummy; -} z_publisher_delete_options_t; - -/** - * Options passed to the :c:func:`z_publisher_put` function. - * - * Members: - * z_owned_encoding_t encoding: The encoding of the payload. - * z_owned_bytes_t attachment: The attachment to attach to the publication. - */ -typedef struct z_publisher_put_options_t { - struct z_owned_encoding_t *encoding; - struct z_owned_bytes_t *attachment; -} z_publisher_put_options_t; - -/** - * Options passed to the :c:func:`z_put` function. - * - * Members: - * z_encoding_t encoding: The encoding of the payload. - * z_congestion_control_t congestion_control: The congestion control to apply when routing this message. - * z_priority_t priority: The priority of this message. - * z_bytes_t attachment: The attachment to this message. - */ -typedef struct z_put_options_t { - struct z_owned_encoding_t *encoding; - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; - struct z_owned_bytes_t *attachment; -} z_put_options_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - `this` is a pointer to an arbitrary state. - * - `call` is the typical callback function. `this` will be passed as its last argument. - * - `drop` allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * We guarantee that: - * - `call` will never be called once `drop` has started. - * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_query_channel_closure_t { - void *context; - bool (*call)(struct z_owned_query_t*, void*); - void (*drop)(void*); -} z_owned_query_channel_closure_t; - -/** - * A pair of closures - */ -typedef struct z_owned_query_channel_t { - struct z_owned_closure_query_t send; - struct z_owned_query_channel_closure_t recv; -} z_owned_query_channel_t; - -/** - * Represents the set of options that can be applied to a query reply, - * sent via :c:func:`z_query_reply`. - * - * Members: - * z_owned_encoding_t encoding: The encoding of the payload. - * z_owned_bytes_t attachment: The attachment to this reply. - */ -typedef struct z_query_reply_options_t { - struct z_owned_encoding_t *encoding; - struct z_owned_bytes_t *attachment; -} z_query_reply_options_t; - -typedef struct ALIGN(8) z_value_t { - uint8_t _0[8]; -} z_value_t; - -/** - * An owned reply to a :c:func:`z_get`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) z_owned_reply_t { - uint8_t _0[256]; -} z_owned_reply_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - `this` is a pointer to an arbitrary state. - * - `call` is the typical callback function. `this` will be passed as its last argument. - * - `drop` allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * We guarantee that: - * - `call` will never be called once `drop` has started. - * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct z_owned_reply_channel_closure_t { - void *context; - bool (*call)(struct z_owned_reply_t*, void*); - void (*drop)(void*); -} z_owned_reply_channel_closure_t; - -/** - * A pair of closures, the `send` one accepting - */ -typedef struct z_owned_reply_channel_t { - struct z_owned_closure_reply_t send; - struct z_owned_reply_channel_closure_t recv; -} z_owned_reply_channel_t; - -typedef struct ALIGN(8) z_timestamp_t { - uint8_t _0[24]; -} z_timestamp_t; - -typedef struct z_owned_scouting_config_t { - struct z_owned_config_t _config; - unsigned long zc_timeout_ms; - uint8_t zc_what; -} z_owned_scouting_config_t; - -/** - * The body of a loop over a z_slice_map's key-value pairs. - * - * `key` and `value` are loaned to the body for the duration of a single call. - * `context` is passed transparently through the iteration driver. - * - * Returning `true` is treated as `continue`. - */ -typedef bool (*z_slice_map_iter_body_t)(struct z_slice_t key, struct z_slice_t value, void *context); - -typedef struct ALIGN(8) z_subscriber_t { - uint8_t _0[8]; -} z_subscriber_t; - -typedef struct ALIGN(8) z_owned_task_t { - uint8_t _0[24]; -} z_owned_task_t; - -typedef struct z_task_attr_t { - size_t _0; -} z_task_attr_t; - -/** - * Time - * Uses system clock - */ -typedef struct z_time_t { - uint64_t t; -} z_time_t; - -/** - * The options for `zc_liveliness_declare_token` - */ -typedef struct zc_liveliness_declaration_options_t { - uint8_t _dummy; -} zc_liveliness_declaration_options_t; - -/** - * The options for :c:func:`zc_liveliness_declare_subscriber` - */ -typedef struct zc_liveliness_declare_subscriber_options_t { - uint8_t _dummy; -} zc_liveliness_declare_subscriber_options_t; - -/** - * A liveliness token that can be used to provide the network with information about connectivity to its - * declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key - * expressions. - * - * A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. - */ -typedef struct ALIGN(8) zc_owned_liveliness_token_t { - uint8_t _0[32]; -} zc_owned_liveliness_token_t; - -/** - * The options for :c:func:`zc_liveliness_declare_subscriber` - */ -typedef struct zc_liveliness_get_options_t { - uint32_t timeout_ms; -} zc_liveliness_get_options_t; - -/** - * An owned sample. - * - * This is a read only type that can only be constructed by cloning a `z_sample_t`. - * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. - */ -typedef struct ALIGN(8) zc_owned_sample_t { - uint8_t _0[240]; -} zc_owned_sample_t; - -/** - * A struct that indicates if there exist Subscribers matching the Publisher's key expression. - * - * Members: - * bool matching: true if there exist Subscribers matching the Publisher's key expression. - */ -typedef struct zcu_matching_status_t { - bool matching; -} zcu_matching_status_t; - -/** - * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: - * - * Members: - * void *context: a pointer to an arbitrary state. - * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. - * void *drop(void*): allows the callback's state to be freed. - * - * Closures are not guaranteed not to be called concurrently. - * - * It is guaranteed that: - * - * - `call` will never be called once `drop` has started. - * - `drop` will only be called **once**, and **after every** `call` has ended. - * - The two previous guarantees imply that `call` and `drop` are never called concurrently. - */ -typedef struct zcu_owned_closure_matching_status_t { - void *context; - void (*call)(const struct zcu_matching_status_t*, void*); - void (*drop)(void*); -} zcu_owned_closure_matching_status_t; - -/** - * An owned zenoh matching listener. Destroying the matching listener cancels the subscription. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) zcu_owned_matching_listener_t { - uint8_t _0[40]; -} zcu_owned_matching_listener_t; - -/** - * An owned zenoh publication_cache. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) ze_owned_publication_cache_t { - uint8_t _0[96]; -} ze_owned_publication_cache_t; - -/** - * Options passed to the :c:func:`ze_declare_publication_cache` function. - * - * Members: - * z_keyexpr_t queryable_prefix: The prefix used for queryable - * zcu_locality_t queryable_origin: The restriction for the matching queries that will be receive by this - * publication cache - * bool queryable_complete: the `complete` option for the queryable - * size_t history: The the history size - * size_t resources_limit: The limit number of cached resources - */ -typedef struct ze_publication_cache_options_t { - const struct z_keyexpr_t *queryable_prefix; - enum zcu_locality_t queryable_origin; - bool queryable_complete; - size_t history; - size_t resources_limit; -} ze_publication_cache_options_t; - -/** - * An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. - * - * Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -typedef struct ALIGN(8) ze_owned_querying_subscriber_t { - uint8_t _0[64]; -} ze_owned_querying_subscriber_t; - -/** - * Represents the set of options that can be applied to a querying subscriber, - * upon its declaration via :c:func:`ze_declare_querying_subscriber`. - * - * Members: - * z_reliability_t reliability: The subscription reliability. - * zcu_locality_t allowed_origin: The restriction for the matching publications that will be - * receive by this subscriber. - * z_keyexpr_t query_selector: The selector to be used for queries. - * z_query_target_t query_target: The target to be used for queries. - * z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. - * zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. - * uint64_t query_timeout_ms: The timeout to be used for queries. - */ -typedef struct ze_querying_subscriber_options_t { - enum z_reliability_t reliability; - enum zcu_locality_t allowed_origin; - const struct z_keyexpr_t *query_selector; - enum z_query_target_t query_target; - struct z_query_consolidation_t query_consolidation; - enum zcu_reply_keyexpr_t query_accept_replies; - uint64_t query_timeout_ms; -} ze_querying_subscriber_options_t; - -typedef struct ALIGN(8) ze_querying_subscriber_t { - uint8_t _0[8]; -} ze_querying_subscriber_t; - -#define Z_OK 0 - -#define Z_EINVAL -1 - -#define Z_EPARSE -2 - -#define Z_EIO -3 - -#define Z_ENETWORK -4 - -#define Z_EBUSY_MUTEX -16 - -#define Z_EINVAL_MUTEX -22 - -#define Z_EAGAIN_MUTEX -11 - -#define Z_EPOISON_MUTEX -22 - -#define Z_EGENERIC INT8_MIN - -extern const unsigned int Z_ROUTER; - -extern const unsigned int Z_PEER; - -extern const unsigned int Z_CLIENT; - -extern const char *Z_CONFIG_MODE_KEY; - -extern const char *Z_CONFIG_CONNECT_KEY; - -extern const char *Z_CONFIG_LISTEN_KEY; - -extern const char *Z_CONFIG_USER_KEY; - -extern const char *Z_CONFIG_PASSWORD_KEY; - -extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; - -extern const char *Z_CONFIG_MULTICAST_INTERFACE_KEY; - -extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; - -extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; - -extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; - -extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; - -/** - * Returns `true` if the payload is in a valid state. - */ -ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *payload); - -/** - * Increments the payload's reference count, returning an owned version of it. - */ -ZENOHC_API void z_bytes_clone(const struct z_owned_bytes_t *src, struct z_owned_bytes_t *dst); - -/** - * Decodes payload into owned bytes - */ -ZENOHC_API ZCError z_bytes_decode_into_bytes(struct z_bytes_t payload, struct z_owned_slice_t *dst); - -/** - * Decodes payload into bytes map. - */ -ZENOHC_API -ZCError z_bytes_decode_into_bytes_map(struct z_bytes_t payload, - struct z_owned_slice_map_t *dst); - -/** - * Decodes payload into null-terminated string. - */ -ZENOHC_API ZCError z_bytes_decode_into_string(struct z_bytes_t payload, struct z_owned_str_t *dst); - -/** - * Decrements the payload's reference counter, destroying it if applicable. - * - * `this` will be reset to `z_buffer_null`, preventing UB on double-frees. - */ -ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); - -/** - * Encodes byte sequence by aliasing. - */ -ZENOHC_API void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, struct z_slice_t bytes); - -/** - * Encodes bytes map by copying. - */ -ZENOHC_API -void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, - struct z_slice_map_t bytes_map); - -/** - * Encodes a null-terminated string by aliasing. - */ -ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const char *cstr); - -/** - * Returns total number bytes in the payload. - */ -ZENOHC_API size_t z_bytes_len(struct z_bytes_t payload); - -/** - * Loans the payload, allowing you to call functions that only need a loan of it. - */ -ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *payload); - -/** - * The gravestone value for `z_owned_bytes_t`. - */ -ZENOHC_API void z_bytes_null(struct z_owned_bytes_t *this_); - -ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_t_reader_t *reader); - -ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_t_reader_t *this_); - -ZENOHC_API -struct z_bytes_reader_t z_bytes_reader_loan(const struct z_owned_bytes_t_reader_t *reader); - -/** - * Creates a reader for the specified `payload`. - * - * Returns 0 in case of success, -1 if `payload` is not valid. - */ -ZENOHC_API -void z_bytes_reader_new(struct z_bytes_t payload, - struct z_owned_bytes_t_reader_t *this_); - -ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_t_reader_t *this_); - -/** - * Reads data into specified destination. - * - * Will read at most `len` bytes. - * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. - */ -ZENOHC_API -size_t z_bytes_reader_read(struct z_bytes_reader_t reader, - uint8_t *dest, - size_t len); - -/** - * Sets the `reader` position indicator for the payload to the value pointed to by offset. - * The new position is exactly offset bytes measured from the beginning of the payload if origin is SEEK_SET, - * from the current reader position if origin is SEEK_CUR, and from the end of the payload if origin is SEEK_END. - * Return ​0​ upon success, negative error code otherwise. - */ -ZENOHC_API -ZCError z_bytes_reader_seek(struct z_bytes_reader_t reader, - int64_t offset, - int origin); - -/** - * Returns the read position indicator. - * Returns read position indicator on success or -1L if failure occurs. - */ -ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t reader); - -ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); - -ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); - -ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); - -ZENOHC_API struct z_clock_t z_clock_now(void); - -/** - * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. - * - * Returns a negative value if an error occured while closing the session. - * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. - */ -ZENOHC_API int8_t z_close(struct z_owned_session_t *session); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_hello_call(const struct z_owned_closure_hello_t *closure, - struct z_owned_hello_t *hello); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_hello_drop(struct z_owned_closure_hello_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_hello_t' type - */ -ZENOHC_API struct z_owned_closure_hello_t z_closure_hello_null(void); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_owned_query_call(const struct z_owned_closure_owned_query_t *closure, - struct z_owned_query_t *query); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_owned_query_drop(struct z_owned_closure_owned_query_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type - */ -ZENOHC_API struct z_owned_closure_owned_query_t z_closure_owned_query_null(void); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_query_call(const struct z_owned_closure_query_t *closure, - struct z_query_t query); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_query_drop(struct z_owned_closure_query_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type - */ -ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_reply_call(const struct z_owned_closure_reply_t *closure, - struct z_reply_t reply); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_reply_drop(struct z_owned_closure_reply_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_reply_t' type - */ -ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, - struct z_sample_t sample); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_sample_drop(struct z_owned_closure_sample_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_sample_t' type - */ -ZENOHC_API struct z_owned_closure_sample_t z_closure_sample_null(void); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void z_closure_zid_call(const struct z_owned_closure_zid_t *closure, - const struct z_id_t *sample); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_closure_zid_drop(struct z_owned_closure_zid_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_closure_zid_t' type - */ -ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); - -ZENOHC_API bool z_condvar_check(const struct z_owned_condvar_t *this_); - -ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); - -ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); - -ZENOHC_API struct z_condvar_t z_condvar_loan(const struct z_owned_condvar_t *this_); - -ZENOHC_API void z_condvar_null(struct z_owned_condvar_t *this_); - -ZENOHC_API ZCError z_condvar_signal(struct z_condvar_t this_); - -ZENOHC_API ZCError z_condvar_wait(struct z_condvar_t this_, struct z_mutex_t m); - -/** - * Returns ``true`` if `config` is valid. - */ -ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); - -/** - * Constructs a default, zenoh-allocated, client mode configuration. - * If `peer` is not null, it is added to the configuration as remote peer. - */ -ZENOHC_API -ZCError z_config_client(const char *const *peers, - size_t n_peers, - struct z_owned_config_t *this_); - -/** - * Clones the config. - */ -ZENOHC_API void z_config_clone(const struct z_config_t *src, struct z_owned_config_t *dst); - -/** - * Frees `config`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_config_drop(struct z_owned_config_t *config); - -/** - * Returns a :c:type:`z_config_t` loaned from `s`. - */ -ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); - -/** - * Return a new, zenoh-allocated, empty configuration. - * - * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. - * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -ZENOHC_API -void z_config_new(struct z_owned_config_t *this_); - -/** - * Constructs a null safe-to-drop value of 'z_owned_config_t' type - */ -ZENOHC_API void z_config_null(struct z_owned_config_t *this_); - -/** - * Constructs a default, zenoh-allocated, peer mode configuration. - */ -ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); - -/** - * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. - * - * This numerical id will be used on the network to save bandwidth and - * ease the retrieval of the concerned resource in the routing tables. - */ -ZENOHC_API -ZCError z_declare_keyexpr(struct z_owned_keyexpr_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr); - -/** - * Declares a publisher for the given key expression. - * - * Data can be put and deleted with this publisher with the help of the - * :c:func:`z_publisher_put` and :c:func:`z_publisher_delete` functions. - * - * Parameters: - * session: The zenoh session. - * key_expr: The key expression to publish. - * options: additional options for the publisher. - * - * Returns: - * A :c:type:`z_owned_publisherr_t`. - * - * To check if the publisher decalration succeeded and if the publisher is still valid, - * you may use `z_publisher_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a publisher passing `NULL` for the options: - * - * .. code-block:: C - * - * z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(expr), NULL); - * - * is equivalent to initializing and passing the default publisher options: - * - * .. code-block:: C - * - * z_publisher_options_t opts = z_publisher_options_default(); - * z_owned_publisher_t sub = z_declare_publisher(z_loan(s), z_keyexpr(expr), &opts); - */ -ZENOHC_API -ZCError z_declare_publisher(struct z_session_t session, - struct z_keyexpr_t key_expr, - const struct z_publisher_options_t *options, - struct z_owned_publisher_t *this_); - -/** - * Creates a Queryable for the given key expression. - * - * Parameters: - * session: The zenoh session. - * key_expr: The key expression the Queryable will reply to. - * callback: The callback function that will be called each time a matching query is received. - * options: Options for the queryable. - * - * Returns: - * The created :c:type:`z_owned_queryable_t` or ``null`` if the creation failed. - */ -ZENOHC_API -ZCError z_declare_queryable(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_query_t *callback, - const struct z_queryable_options_t *options, - struct z_owned_queryable_t *this_); - -/** - * Declare a subscriber for a given key expression. - * - * Parameters: - * session: The zenoh session. - * key_expr: The key expression to subscribe. - * callback: The callback function that will be called each time a data matching the subscribed expression is received. - * opts: The options to be passed to describe the options to be passed to the subscriber declaration. - * - * Returns: - * A :c:type:`z_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the subscriber is still valid, - * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a subscriber passing `NULL` for the options: - * - * .. code-block:: C - * - * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); - * - * is equivalent to initializing and passing the default subscriber options: - * - * .. code-block:: C - * - * z_subscriber_options_t opts = z_subscriber_options_default(); - * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); - */ -ZENOHC_API -ZCError z_declare_subscriber(struct z_owned_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_sample_t *callback, - struct z_subscriber_options_t options); - -/** - * Delete data. - * - * Parameters: - * session: The zenoh session. - * key_expr: The key expression to delete. - * options: The put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. - */ -ZENOHC_API -ZCError z_delete(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_delete_options_t opts); - -/** - * Constructs the default value for :c:type:`z_put_options_t`. - */ -ZENOHC_API struct z_delete_options_t z_delete_options_default(void); - -/** - * Returns ``true`` if `encoding` is valid. - */ -ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); - -/** - * Constructs a default :c:type:`z_encoding_t`. - */ -ZENOHC_API struct z_encoding_t z_encoding_default(void); - -/** - * Frees `encoding`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); - -/** - * Constructs a specific :c:type:`z_encoding_t`. - */ -ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); - -/** - * Returns a :c:type:`z_encoding_t` loaned from `encoding`. - */ -ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); - -/** - * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type - */ -ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); - -/** - * Query data from the matching queryables in the system. - * Replies are provided through a callback function. - * - * Returns a negative value upon failure. - * - * Parameters: - * session: The zenoh session. - * key_expr: The key expression matching resources to query. - * parameters: The query's parameters, similar to a url's query segment. - * callback: The callback function that will be called on reception of replies for this query. - * Note that the `reply` parameter of the callback is passed by mutable reference, - * but **will** be dropped once your callback exits to help you avoid memory leaks. - * If you'd rather take ownership, please refer to the documentation of :c:func:`z_reply_null` - * options: additional options for the get. - */ -ZENOHC_API -ZCError z_get(struct z_session_t session, - struct z_keyexpr_t key_expr, - const char *parameters, - struct z_owned_closure_reply_t *callback, - struct z_get_options_t options); - -ZENOHC_API struct z_get_options_t z_get_options_default(void); - -/** - * Returns ``true`` if `hello` is valid. - */ -ZENOHC_API bool z_hello_check(const struct z_owned_hello_t *hello); - -/** - * Frees `hello`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_hello_drop(struct z_owned_hello_t *hello); - -/** - * Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. - */ -ZENOHC_API struct z_hello_t z_hello_loan(const struct z_owned_hello_t *hello); - -/** - * Constructs a gravestone value for hello, useful to steal one from a callback - */ -ZENOHC_API struct z_owned_hello_t z_hello_null(void); - -/** - * Fetches the Zenoh IDs of all connected peers. - * - * `callback` will be called once for each ID, is guaranteed to never be called concurrently, - * and is guaranteed to be dropped before this function exits. - * - * Retuns 0 on success, negative values on failure - */ -ZENOHC_API -ZCError z_info_peers_zid(struct z_session_t session, - struct z_owned_closure_zid_t *callback); - -/** - * Fetches the Zenoh IDs of all connected routers. - * - * `callback` will be called once for each ID, is guaranteed to never be called concurrently, - * and is guaranteed to be dropped before this function exits. - * - * Retuns 0 on success, negative values on failure. - */ -ZENOHC_API -ZCError z_info_routers_zid(struct z_session_t session, - struct z_owned_closure_zid_t *callback); - -/** - * Returns the local Zenoh ID. - * - * Unless the `session` is invalid, that ID is guaranteed to be non-zero. - * In other words, this function returning an array of 16 zeros means you failed - * to pass it a valid session. - */ -ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); - -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API ZCError z_keyexpr(struct z_owned_keyexpr_t *this_, const char *name); - -/** - * Returns the key expression's internal string by aliasing it. - * - * Currently exclusive to zenoh-c - */ -ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(struct z_keyexpr_t ke); - -/** - * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. - * The string is canonized in-place before being passed to keyexpr. - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -ZCError z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, - char *name); - -/** - * Canonizes the passed string in place, possibly shortening it by modifying `len`. - * - * Returns ``0`` upon success, negative values upon failure. - * Returns a negative value if canonization failed, which indicates that the passed string was an invalid - * key expression for reasons other than a non-canon form. - * - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -ZCError z_keyexpr_canonize(char *start, - size_t *len); - -/** - * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. - * - * Returns ``0`` upon success, negative values upon failure. - * Returns a negative value if canonization failed, which indicates that the passed string was an invalid - * key expression for reasons other than a non-canon form. - * - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -ZCError z_keyexpr_canonize_null_terminated(char *start); - -/** - * Returns ``true`` if `keyexpr` is valid. - */ -ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); - -/** - * Performs string concatenation and returns the result as a `z_owned_keyexpr_t`. - * In case of error, the return value will be set to its invalidated state. - * - * You should probably prefer `z_keyexpr_join` as Zenoh may then take advantage of the hierachical separation it inserts. - * - * To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, - * as this would extremely likely cause bugs. - */ -ZENOHC_API -ZCError z_keyexpr_concat(struct z_keyexpr_t left, - const char *right_start, - size_t right_len, - struct z_owned_keyexpr_t *this_); - -/** - * Frees `keyexpr` and invalidates it for double-drop safety. - */ -ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); - -/** - * Returns ``0`` if both ``left`` and ``right`` are equal. - */ -ZENOHC_API bool z_keyexpr_equals(struct z_keyexpr_t left, struct z_keyexpr_t right); - -/** - * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set - * defined by ``right``. - */ -ZENOHC_API -bool z_keyexpr_includes(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the - * sets defined by ``left`` and ``right``. - */ -ZENOHC_API -bool z_keyexpr_intersects(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Returns ``0`` if the passed string is a valid (and canon) key expression. - * Otherwise returns error value - */ -ZENOHC_API ZCError z_keyexpr_is_canon(const char *start, size_t len); - -/** - * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. - * In case of error, the return value will be set to its invalidated state. - */ -ZENOHC_API -ZCError z_keyexpr_join(struct z_keyexpr_t left, - struct z_keyexpr_t right, - struct z_owned_keyexpr_t *this_); - -/** - * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. - */ -ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); - -/** - * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. - */ -ZENOHC_API ZCError z_keyexpr_new(const char *name, struct z_owned_keyexpr_t *this_); - -/** - * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. - */ -ZENOHC_API -ZCError z_keyexpr_new_autocanonize(const char *name, - struct z_owned_keyexpr_t *this_); - -/** - * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type - */ -ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); - -/** - * Returns the relation between `left` and `right` from `left`'s point of view. - * - * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. - */ -ZENOHC_API -enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, - struct z_keyexpr_t right); - -/** - * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. - * The user is responsible of droping the returned string using `z_drop` - */ -ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t ke); - -/** - * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: - * - * - `name` MUST be valid UTF8. - * - `name` MUST follow the Key Expression specification, ie: - * - * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. - * - any instance of `**` may only be lead or followed by `/`. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -void z_keyexpr_unchecked(struct z_owned_keyexpr_t *this_, - const char *name); - -ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); - -ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); - -ZENOHC_API ZCError z_mutex_init(struct z_owned_mutex_t *this_); - -ZENOHC_API struct z_mutex_t z_mutex_loan(const struct z_owned_mutex_t *this_); - -ZENOHC_API ZCError z_mutex_lock(struct z_mutex_t this_); - -ZENOHC_API ZCError z_mutex_try_lock(struct z_mutex_t this_); - -ZENOHC_API ZCError z_mutex_unlock(struct z_mutex_t this_); - -/** - * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. - * Config value is always consumed upon function return. - */ -ZENOHC_API -ZCError z_open(struct z_owned_session_t *this_, - struct z_owned_config_t *config); - -/** - * Returns ``true`` if `pub` is valid. - */ -ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); - -/** - * Sends a `DELETE` message onto the publisher's key expression. - * - * Returns: - * ``0`` in case of success, ``1`` in case of failure. - */ -ZENOHC_API -ZCError z_publisher_delete(struct z_publisher_t publisher, - struct z_publisher_delete_options_t _options); - -/** - * Constructs the default values for the delete operation via a publisher entity. - * - * Returns: - * Returns the constructed :c:type:`z_publisher_delete_options_t`. - */ -ZENOHC_API struct z_publisher_delete_options_t z_publisher_delete_options_default(void); - -/** - * Returns the key expression of the publisher - */ -ZENOHC_API struct z_keyexpr_t z_publisher_keyexpr(struct z_publisher_t publisher); - -/** - * Returns a :c:type:`z_publisher_t` loaned from `p`. - */ -ZENOHC_API struct z_publisher_t z_publisher_loan(const struct z_owned_publisher_t *p); - -/** - * Constructs a null safe-to-drop value of 'z_owned_publisher_t' type - */ -ZENOHC_API void z_publisher_null(struct z_owned_publisher_t *this_); - -/** - * Constructs the default value for :c:type:`z_publisher_options_t`. - */ -ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); - -/** - * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. - * - * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher - * - constructed from a `zc_owned_shmbuf_t` - * - * The payload and all owned options fields are consumed upon function return. - * - * Parameters: - * session: The zenoh session. - * payload: The value to put. - * options: The publisher put options. - * Returns: - * ``0`` in case of success, negative values in case of failure. - */ -ZENOHC_API -ZCError z_publisher_put(struct z_publisher_t publisher, - struct z_owned_bytes_t *payload, - struct z_publisher_put_options_t options); - -/** - * Constructs the default value for :c:type:`z_publisher_put_options_t`. - */ -ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); - -/** - * Put data, transfering its ownership. - * - * - * The payload's encoding and attachment can be sepcified through the options. These values are consumed upon function - * return. - * - * Parameters: - * session: The zenoh session. - * key_expr: The key expression to put. - * payload: The value to put (consumed upon function return). - * options: The put options. - * Returns: - * ``0`` in case of success, negative error values in case of failure. - */ -ZENOHC_API -ZCError z_put(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_bytes_t *payload, - struct z_put_options_t options); - -/** - * Constructs the default value for :c:type:`z_put_options_t`. - */ -ZENOHC_API struct z_put_options_t z_put_options_default(void); - -/** - * Gets the attachment to the query by aliasing. - * - * Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. - */ -ZENOHC_API struct z_bytes_t z_query_attachment(struct z_query_t query); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -bool z_query_channel_closure_call(const struct z_owned_query_channel_closure_t *closure, - struct z_owned_query_t *query); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_query_channel_closure_drop(struct z_owned_query_channel_closure_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_query_channel_closure_t' type - */ -ZENOHC_API struct z_owned_query_channel_closure_t z_query_channel_closure_null(void); - -ZENOHC_API void z_query_channel_drop(struct z_owned_query_channel_t *channel); - -/** - * Constructs a null safe-to-drop value of 'z_owned_query_channel_t' type - */ -ZENOHC_API struct z_owned_query_channel_t z_query_channel_null(void); - -/** - * Returns `false` if `this` is in a gravestone state, `true` otherwise. - * - * This function may not be called with the null pointer, but can be called with the gravestone value. - */ -ZENOHC_API -bool z_query_check(const struct z_owned_query_t *query); - -/** - * Clones the query, allowing to keep it in an "open" state past the callback's return. - * - * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). - */ -ZENOHC_API -void z_query_clone(struct z_owned_query_t *this_, - struct z_query_t query); - -/** - * Automatic query consolidation strategy selection. - * - * A query consolidation strategy will automatically be selected depending the query selector. - * If the selector contains time range properties, no consolidation is performed. - * Otherwise the :c:func:`z_query_consolidation_latest` strategy is used. - * - * Returns: - * Returns the constructed :c:type:`z_query_consolidation_t`. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_auto(void); - -/** - * Creates a default :c:type:`z_query_consolidation_t` (consolidation mode AUTO). - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_default(void); - -/** - * Latest value consolidation. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_latest(void); - -/** - * Monotonic consolidation. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_monotonic(void); - -/** - * Disable consolidation. - */ -ZENOHC_API struct z_query_consolidation_t z_query_consolidation_none(void); - -/** - * Destroys the query, setting `this` to its gravestone value to prevent double-frees. - * - * This function may not be called with the null pointer, but can be called with the gravestone value. - */ -ZENOHC_API -void z_query_drop(struct z_owned_query_t *this_); - -/** - * Get a query's key by aliasing it. - */ -ZENOHC_API struct z_keyexpr_t z_query_keyexpr(struct z_query_t query); - -/** - * Aliases the query. - * - * This function may not be called with the null pointer, but can be called with the gravestone value. - */ -ZENOHC_API -struct z_query_t z_query_loan(const struct z_owned_query_t *this_); - -/** - * The gravestone value of `z_owned_query_t`. - */ -ZENOHC_API void z_query_null(struct z_owned_query_t *this_); - -/** - * Get a query's `value selector `_ by aliasing it. - */ -ZENOHC_API -struct z_slice_t z_query_parameters(struct z_query_t query); - -/** - * Send a reply to a query. - * - * This function must be called inside of a Queryable callback passing the - * query received as parameters of the callback function. This function can - * be called multiple times to send multiple replies to a query. The reply - * will be considered complete when the Queryable callback returns. - * - * Parameters: - * query: The query to reply to. - * key_expr: The key of this reply. - * payload: The value of this reply. - * options: The options of this reply. - * - * The payload and all owned options fields are consumed upon function return. - */ -ZENOHC_API -ZCError z_query_reply(struct z_query_t query, - struct z_keyexpr_t key_expr, - struct z_owned_bytes_t *payload, - struct z_query_reply_options_t options); - -/** - * Constructs the default value for :c:type:`z_query_reply_options_t`. - */ -ZENOHC_API struct z_query_reply_options_t z_query_reply_options_default(void); - -/** - * Create a default :c:type:`z_query_target_t`. - */ -ZENOHC_API enum z_query_target_t z_query_target_default(void); - -/** - * Gets a query's `payload value `_ by aliasing it. - * - * **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** - * Before calling this funciton, the user must ensure that `z_query_has_value` returns true. - */ -ZENOHC_API -struct z_value_t z_query_value(struct z_query_t query); - -/** - * Returns ``true`` if `qable` is valid. - */ -ZENOHC_API bool z_queryable_check(const struct z_owned_queryable_t *qable); - -/** - * Constructs a null safe-to-drop value of 'z_owned_queryable_t' type - */ -ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); - -/** - * Constructs the default value for :c:type:`z_query_reply_options_t`. - */ -ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); - -ZENOHC_API void z_random_fill(void *buf, size_t len); - -ZENOHC_API uint16_t z_random_u16(void); - -ZENOHC_API uint32_t z_random_u32(void); - -ZENOHC_API uint64_t z_random_u64(void); - -ZENOHC_API uint8_t z_random_u8(void); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -bool z_reply_channel_closure_call(const struct z_owned_reply_channel_closure_t *closure, - struct z_owned_reply_t *reply); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API void z_reply_channel_closure_drop(struct z_owned_reply_channel_closure_t *closure); - -/** - * Constructs a null safe-to-drop value of 'z_owned_reply_channel_closure_t' type - */ -ZENOHC_API struct z_owned_reply_channel_closure_t z_reply_channel_closure_null(void); - -ZENOHC_API void z_reply_channel_drop(struct z_owned_reply_channel_t *channel); - -/** - * Constructs a null safe-to-drop value of 'z_owned_reply_channel_t' type - */ -ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); - -/** - * Returns ``true`` if `reply` is valid. - */ -ZENOHC_API bool z_reply_check(const struct z_owned_reply_t *this_); - -ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, struct z_reply_t reply); - -/** - * Frees `reply`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_reply_drop(struct z_owned_reply_t *this_); - -/** - * Yields the contents of the reply by asserting it indicates a failure. - * - * You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. - */ -ZENOHC_API -struct z_value_t z_reply_err(struct z_reply_t reply); - -/** - * Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. - * - * If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. - */ -ZENOHC_API -bool z_reply_is_ok(struct z_reply_t reply); - -/** - * Returns an invalidated :c:type:`z_owned_reply_t`. - * - * This is useful when you wish to take ownership of a value from a callback to :c:func:`z_get`: - * - * - copy the value of the callback's argument's pointee, - * - overwrite the pointee with this function's return value, - * - you are now responsible for dropping your copy of the reply. - */ -ZENOHC_API void z_reply_null(struct z_owned_reply_t *this_); - -/** - * Yields the contents of the reply by asserting it indicates a success. - * - * You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. - */ -ZENOHC_API -struct z_sample_t z_reply_ok(struct z_reply_t reply); - -/** - * Gets sample's attachment. - * - * Before calling this function, ensure that `zc_sample_has_attachment` returns true - */ -ZENOHC_API struct z_bytes_t z_sample_attachment(struct z_sample_t sample); - -/** - * The encoding of the payload. - */ -ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); - -/** - * The qos with which the sample was received. - * TODO: split to methods (priority, congestion_control, express) - * Checks if sample contains an attachment. - */ -ZENOHC_API bool z_sample_has_attachment(struct z_sample_t sample); - -/** - * The Key Expression of the sample. - * - * `sample` is aliased by its return value. - */ -ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); - -/** - * The sample's kind (put or delete). - */ -ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); - -/** - * The sample's data, the return value aliases the sample. - * - */ -ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); - -/** - * The samples timestamp - * - * Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. - */ -ZENOHC_API -bool z_sample_timestamp(const struct z_sample_t *sample, - struct z_timestamp_t *timestamp_out); - -/** - * Scout for routers and/or peers. - * - * Parameters: - * what: A whatami bitmask of zenoh entities kind to scout for. - * config: A set of properties to configure the scouting. - * timeout: The time (in milliseconds) that should be spent scouting. - * - * Returns 0 if successful, negative values upon failure. - */ -ZENOHC_API -ZCError z_scout(struct z_owned_scouting_config_t *config, - struct z_owned_closure_hello_t *callback); - -ZENOHC_API bool z_scouting_config_check(const struct z_owned_scouting_config_t *config); - -ZENOHC_API void z_scouting_config_default(struct z_owned_scouting_config_t *this_); - -ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); - -ZENOHC_API -void z_scouting_config_from(struct z_config_t config, - struct z_owned_scouting_config_t *this_); - -ZENOHC_API void z_scouting_config_null(struct z_owned_scouting_config_t *this_); - -/** - * Returns ``true`` if `session` is valid. - */ -ZENOHC_API bool z_session_check(const struct z_owned_session_t *session); - -/** - * Returns a :c:type:`z_session_t` loaned from `s`. - * - * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. - * - * # Safety - * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, - * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) - * have been destroyed is UB (likely SEGFAULT) - */ -ZENOHC_API -struct z_session_t z_session_loan(const struct z_owned_session_t *s); - -/** - * Constructs a null safe-to-drop value of 'z_owned_session_t' type - */ -ZENOHC_API void z_session_null(struct z_owned_session_t *s); - -ZENOHC_API int8_t z_sleep_ms(size_t time); - -ZENOHC_API int8_t z_sleep_s(size_t time); - -ZENOHC_API int8_t z_sleep_us(size_t time); - -/** - * Returns ``true`` if `b` is initialized. - */ -ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *b); - -ZENOHC_API struct z_owned_slice_t z_slice_clone(const struct z_slice_t *b); - -/** - * Returns the gravestone value for `z_slice_t` - */ -ZENOHC_API struct z_slice_t z_slice_empty(void); - -/** - * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). - * - * `str == NULL` will cause this to return `z_slice_empty()` - */ -ZENOHC_API struct z_slice_t z_slice_from_str(const char *str); - -/** - * Returns ``true`` if `b` is initialized. - */ -ZENOHC_API bool z_slice_is_initialized(const struct z_slice_t *b); - -ZENOHC_API struct z_slice_t z_slice_loan(const struct z_owned_slice_t *b); - -/** - * Returns `true` if the map is not in its gravestone state - */ -ZENOHC_API bool z_slice_map_check(const struct z_owned_slice_map_t *map); - -/** - * Destroys the map, resetting `this` to its gravestone value. - * - * This function is double-free safe, passing a pointer to the gravestone value will have no effect. - */ -ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); - -/** - * Returns the value associated with `key`, returning a gravestone value if: - * - `key` is in gravestone state. - */ -ZENOHC_API struct z_slice_t z_slice_map_get(struct z_slice_map_t this_, struct z_slice_t key); - -/** - * Associates `value` to `key` in the map, aliasing them. - * - * Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. - * - * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. - */ -ZENOHC_API -ZCError z_slice_map_insert_by_alias(struct z_slice_map_t this_, - struct z_slice_t key, - struct z_slice_t value); - -/** - * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. - * - * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. - */ -ZENOHC_API -ZCError z_slice_map_insert_by_copy(struct z_slice_map_t this_, - struct z_slice_t key, - struct z_slice_t value); - -/** - * Returns true if the map is empty, false otherwise. - */ -ZENOHC_API bool z_slice_map_is_empty(struct z_slice_map_t this_); - -ZENOHC_API -void z_slice_map_iterate(const struct z_slice_map_t *this_, - z_slice_map_iter_body_t body, - void *context); - -/** - * Returns number of key-value pairs in the map. - */ -ZENOHC_API size_t z_slice_map_len(struct z_slice_map_t this_); - -/** - * Constructs a new empty map. - */ -ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); - -/** - * Constructs the gravestone value for `z_owned_slice_map_t` - */ -ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); - -/** - * Deprecated in favor of `z_slice_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). - * - * `str == NULL` will cause this to return `z_slice_empty()` - */ -ZENOHC_API -struct z_slice_t z_slice_new(const char *str); - -/** - * Returns the gravestone value for `z_owned_slice_t` - */ -ZENOHC_API struct z_owned_slice_t z_slice_null(void); - -/** - * Constructs a `len` bytes long view starting at `start`. - */ -ZENOHC_API struct z_slice_t z_slice_wrap(const uint8_t *start, size_t len); - -/** - * Returns ``true`` if `strs` is valid. - */ -ZENOHC_API bool z_str_array_check(const struct z_owned_str_array_t *strs); - -/** - * Frees `strs` and invalidates it for double-drop safety. - */ -ZENOHC_API void z_str_array_drop(struct z_owned_str_array_t *strs); - -/** - * Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. - */ -ZENOHC_API struct z_str_array_t z_str_array_loan(const struct z_owned_str_array_t *strs); - -/** - * Returns ``true`` if `s` is a valid string - */ -ZENOHC_API bool z_str_check(const struct z_owned_str_t *s); - -/** - * Frees `z_owned_str_t`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_str_drop(struct z_owned_str_t *s); - -/** - * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. - */ -ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); - -/** - * Returns undefined `z_owned_str_t` - */ -ZENOHC_API struct z_owned_str_t z_str_null(void); - -/** - * Returns ``true`` if `sub` is valid. - */ -ZENOHC_API bool z_subscriber_check(const struct z_owned_subscriber_t *subscriber); - -/** - * Returns the key expression of the subscriber. - */ -ZENOHC_API struct z_keyexpr_t z_subscriber_keyexpr(struct z_subscriber_t subscriber); - -/** - * Returns a :c:type:`z_subscriber_t` loaned from `this`. - */ -ZENOHC_API struct z_subscriber_t z_subscriber_loan(const struct z_owned_subscriber_t *this_); - -/** - * Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type - */ -ZENOHC_API void z_subscriber_null(struct z_owned_subscriber_t *this_); - -/** - * Constructs the default value for :c:type:`z_subscriber_options_t`. - */ -ZENOHC_API struct z_subscriber_options_t z_subscriber_options_default(void); - -ZENOHC_API bool z_task_check(const struct z_owned_task_t *this_); - -/** - * Detaches the task and releases all allocated resources. - */ -ZENOHC_API void z_task_detach(struct z_owned_task_t *this_); - -ZENOHC_API -ZCError z_task_init(struct z_owned_task_t *this_, - const struct z_task_attr_t *_attr, - void (*fun)(void *arg), - void *arg); - -/** - * Joins the task and releases all allocated resources - */ -ZENOHC_API ZCError z_task_join(struct z_owned_task_t *this_); - -ZENOHC_API void z_task_null(struct z_owned_task_t *this_); - -ZENOHC_API uint64_t z_time_elapsed_ms(const struct z_time_t *time); - -ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); - -ZENOHC_API uint64_t z_time_elapsed_us(const struct z_time_t *time); - -ZENOHC_API struct z_time_t z_time_now(void); - -ZENOHC_API const char *z_time_now_as_str(const char *buf, size_t len); - -ZENOHC_API struct z_id_t z_timestamp_get_id(const struct z_timestamp_t *timestamp); - -ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp); - -/** - * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. - * The keyxpr is consumed. - */ -ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); - -/** - * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -ZCError z_undeclare_publisher(struct z_owned_publisher_t *publisher); - -/** - * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. - * - * Parameters: - * qable: The :c:type:`z_owned_queryable_t` to undeclare. - */ -ZENOHC_API ZCError z_undeclare_queryable(struct z_owned_queryable_t *qable); - -/** - * Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -ZCError z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); - -/** - * Converts the kind of zenoh entity into a string. - * - * Parameters: - * whatami: A whatami bitmask of zenoh entity kind. - * buf: Buffer to write a null-terminated string to. - * len: Maximum number of bytes that can be written to the `buf`. - * - * Returns 0 if successful, negative values if whatami contains an invalid bitmask or `buf` is null, - * or number of remaining bytes, if the null-terminated string size exceeds `len`. - */ -ZENOHC_API int8_t z_whatami_to_str(uint8_t whatami, char *buf, size_t len); - -/** - * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. - */ -ZENOHC_API -ZCError zc_config_from_file(const char *path, - struct z_owned_config_t *this_); - -/** - * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. - * - * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). - */ -ZENOHC_API -ZCError zc_config_from_str(const char *s, - struct z_owned_config_t *this_); - -/** - * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. - * Use `z_drop` to safely deallocate this string - */ -ZENOHC_API -struct z_owned_str_t zc_config_get(struct z_config_t config, - const char *key); - -/** - * Inserts a JSON-serialized `value` at the `key` position of the configuration. - * - * Returns 0 if successful, a negative value otherwise. - */ -ZENOHC_API -int8_t zc_config_insert_json(struct z_config_t config, - const char *key, - const char *value); - -/** - * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. - */ -ZENOHC_API -struct z_owned_str_t zc_config_to_string(struct z_config_t config); - -/** - * Initialises the zenoh runtime logger. - * - * Note that unless you built zenoh-c with the `logger-autoinit` feature disabled, - * this will be performed automatically by `z_open` and `z_scout`. - */ -ZENOHC_API void zc_init_logger(void); - -/** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. - */ -ZENOHC_API -ZCError zc_keyexpr_from_slice(struct z_owned_keyexpr_t *this_, - const char *name, - size_t len); - -/** - * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. - * The string is canonized in-place before being passed to keyexpr. - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -ZCError zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, - char *name, - size_t *len); - -/** - * Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: - * - `name` MUST be valid UTF8. - * - `name` MUST follow the Key Expression specification, ie: - * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. - * - any instance of ``**`` may only be lead or followed by ``/``. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -void zc_keyexpr_from_slice_unchecked(struct z_owned_keyexpr_t *this_, - const char *start, - size_t len); - -ZENOHC_API -struct zc_liveliness_declaration_options_t zc_liveliness_declaration_options_default(void); - -/** - * Declares a subscriber on liveliness tokens that intersect `key`. - * - * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t key_expr: The key expression to subscribe. - * z_owned_closure_sample_t callback: The callback function that will be called each time a - * liveliness token status changed. - * zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. - * - * Returns: - * A :c:type:`z_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the subscriber is still valid, - * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - */ -ZENOHC_API -ZCError zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_sample_t *callback, - struct zc_liveliness_declare_subscriber_options_t _options); - -/** - * Constructs and declares a liveliness token on the network. - * - * Liveliness token subscribers on an intersecting key expression will receive a PUT sample when connectivity - * is achieved, and a DELETE sample if it's lost. - * - * Passing `NULL` as options is valid and equivalent to a pointer to the default options. - */ -ZENOHC_API -ZCError zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct zc_liveliness_declaration_options_t _options); - -/** - * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. - * - * Note that the same "value stealing" tricks apply as with a normal :c:func:`z_get` - * - * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. - */ -ZENOHC_API -ZCError zc_liveliness_get(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_reply_t *callback, - struct zc_liveliness_get_options_t options); - -/** - * The gravestone value for `zc_liveliness_get_options_t` - */ -ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_default(void); - -ZENOHC_API -struct zc_liveliness_declare_subscriber_options_t zc_liveliness_subscriber_options_default(void); - -/** - * Returns `true` unless the token is at its gravestone value. - */ -ZENOHC_API bool zc_liveliness_token_check(const struct zc_owned_liveliness_token_t *this_); - -/** - * The gravestone value for liveliness tokens. - */ -ZENOHC_API void zc_liveliness_token_null(struct zc_owned_liveliness_token_t *this_); - -/** - * Destroys a liveliness token, notifying subscribers of its destruction. - */ -ZENOHC_API ZCError zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t *this_); - -/** - * Creates a new blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, - * which it will then return; or until the `send` closure is dropped and all queries have been consumed, - * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_query_channel_t zc_query_fifo_new(size_t bound); - -/** - * Creates a new non-blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, - * which it will then return; or until the `send` closure is dropped and all queries have been consumed, - * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_query_channel_t zc_query_non_blocking_fifo_new(size_t bound); - -/** - * Creates a new blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, - * which it will then return; or until the `send` closure is dropped and all replies have been consumed, - * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); - -/** - * Creates a new non-blocking fifo channel, returned as a pair of closures. - * - * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. - * - * The `send` end should be passed as callback to a `z_get` call. - * - * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, - * which it will then return; or until the `send` closure is dropped and all replies have been consumed, - * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. - */ -ZENOHC_API -struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); - -/** - * Returns `true` if `sample` is valid. - * - * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed - * unless the value has been dropped already. - */ -ZENOHC_API -bool zc_sample_check(const struct zc_owned_sample_t *sample); - -/** - * Clone a sample in the cheapest way available. - */ -ZENOHC_API void zc_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); - -/** - * Destroy the sample. - */ -ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); - -/** - * Borrow the sample, allowing calling its accessor methods. - * - * Calling this function using a dropped sample is undefined behaviour. - */ -ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); - -ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); - -/** - * Increments the session's reference count, returning a new owning handle. - */ -ZENOHC_API -int8_t zc_session_rcinc(struct z_owned_session_t *dst, - const struct z_owned_session_t *src); - -/** - * Calls the closure. Calling an uninitialized closure is a no-op. - */ -ZENOHC_API -void zcu_closure_matching_status_call(const struct zcu_owned_closure_matching_status_t *closure, - const struct zcu_matching_status_t *sample); - -/** - * Drops the closure. Droping an uninitialized closure is a no-op. - */ -ZENOHC_API -void zcu_closure_matching_status_drop(struct zcu_owned_closure_matching_status_t *closure); - -/** - * Constructs a null safe-to-drop value of 'zcu_owned_closure_matching_status_t' type - */ -ZENOHC_API struct zcu_owned_closure_matching_status_t zcu_closure_matching_status_null(void); - -ZENOHC_API enum zcu_locality_t zcu_locality_default(void); - -/** - * Register callback for notifying subscribers matching. - */ -ZENOHC_API -ZCError zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, - struct zcu_owned_closure_matching_status_t *callback, - struct zcu_owned_matching_listener_t *this_); - -ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); - -/** - * Declares a Publication Cache. - * - * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t key_expr: The key expression to publish. - * ze_publication_cache_options_t options: Additional options for the publication_cache. - * - * Returns: - * :c:type:`ze_owned_publication_cache_t`. - * - * - * Example: - * Declaring a publication cache `NULL` for the options: - * - * .. code-block:: C - * - * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), NULL); - * - * is equivalent to initializing and passing the default publication cache options: - * - * .. code-block:: C - * - * ze_publication_cache_options_t opts = ze_publication_cache_options_default(); - * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), &opts); - */ -ZENOHC_API -ZCError ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct ze_publication_cache_options_t options); - -/** - * Declares a Querying Subscriber for a given key expression. - * - * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t keyexpr: The key expression to subscribe. - * z_owned_closure_sample_t callback: The callback function that will be called each time a data matching the subscribed expression is received. - * ze_querying_subscriber_options_t options: Additional options for the querying subscriber. - * - * Returns: - * :c:type:`ze_owned_subscriber_t`. - * - * To check if the subscription succeeded and if the querying subscriber is still valid, - * you may use `ze_querying_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. - * - * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. - * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. - * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. - * - * Example: - * Declaring a subscriber passing ``NULL`` for the options: - * - * .. code-block:: C - * - * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); - * - * is equivalent to initializing and passing the default subscriber options: - * - * .. code-block:: C - * - * z_subscriber_options_t opts = z_subscriber_options_default(); - * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); - */ -ZENOHC_API -ZCError ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_sample_t *callback, - struct ze_querying_subscriber_options_t options); - -/** - * Returns ``true`` if `pub_cache` is valid. - */ -ZENOHC_API bool ze_publication_cache_check(const struct ze_owned_publication_cache_t *this_); - -/** - * Constructs a null safe-to-drop value of 'ze_owned_publication_cache_t' type - */ -ZENOHC_API void ze_publication_cache_null(struct ze_owned_publication_cache_t *this_); - -/** - * Constructs the default value for :c:type:`ze_publication_cache_options_t`. - */ -ZENOHC_API struct ze_publication_cache_options_t ze_publication_cache_options_default(void); - -/** - * Returns ``true`` if `this` is valid. - */ -ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subscriber_t *this_); - -/** - * Make a :c:type:`ze_owned_querying_subscriber_t` to perform an additional query on a specified selector. - * The queried samples will be merged with the received publications and made available in the subscriber callback. - */ -ZENOHC_API -ZCError ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, - struct z_keyexpr_t selector, - const struct z_get_options_t *options); - -/** - * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. - */ -ZENOHC_API -struct ze_querying_subscriber_t ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); - -/** - * Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type - */ -ZENOHC_API void ze_querying_subscriber_null(struct ze_owned_querying_subscriber_t *this_); - -/** - * Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. - */ -ZENOHC_API struct ze_querying_subscriber_options_t ze_querying_subscriber_options_default(void); - -/** - * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -ZCError ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *this_); - -/** - * Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. - */ -ZENOHC_API -ZCError ze_undeclare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 9ef5cb4e1..08906c0be 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -15,3 +15,2393 @@ #define ALIGN(n) #define ZENOHC_API #endif +/** + * The kind of congestion control. + * + * - **BLOCK** + * - **DROP** + */ +typedef enum z_congestion_control_t { + Z_CONGESTION_CONTROL_BLOCK, + Z_CONGESTION_CONTROL_DROP, +} z_congestion_control_t; +/** + * Consolidation mode values. + * + * - **Z_CONSOLIDATION_MODE_AUTO**: Let Zenoh decide the best consolidation mode depending on the query selector + * If the selector contains time range properties, consolidation mode `NONE` is used. + * Otherwise the `LATEST` consolidation mode is used. + * - **Z_CONSOLIDATION_MODE_NONE**: No consolidation is applied. Replies may come in any order and any number. + * - **Z_CONSOLIDATION_MODE_MONOTONIC**: It guarantees that any reply for a given key expression will be monotonic in time + * w.r.t. the previous received replies for the same key expression. I.e., for the same key expression multiple + * replies may be received. It is guaranteed that two replies received at t1 and t2 will have timestamp + * ts2 > ts1. It optimizes latency. + * - **Z_CONSOLIDATION_MODE_LATEST**: It guarantees unicity of replies for the same key expression. + * It optimizes bandwidth. + */ +typedef enum z_consolidation_mode_t { + Z_CONSOLIDATION_MODE_AUTO = -1, + Z_CONSOLIDATION_MODE_NONE = 0, + Z_CONSOLIDATION_MODE_MONOTONIC = 1, + Z_CONSOLIDATION_MODE_LATEST = 2, +} z_consolidation_mode_t; +/** + * A :c:type:`z_keyexpr_intersection_level_t`. + * + * - **Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES** + * - **Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS** + */ +typedef enum z_keyexpr_intersection_level_t { + Z_KEYEXPR_INTERSECTION_LEVEL_DISJOINT = 0, + Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS = 1, + Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES = 2, + Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS = 3, +} z_keyexpr_intersection_level_t; +/** + * The priority of zenoh messages. + * + * - **REAL_TIME** + * - **INTERACTIVE_HIGH** + * - **INTERACTIVE_LOW** + * - **DATA_HIGH** + * - **DATA** + * - **DATA_LOW** + * - **BACKGROUND** + */ +typedef enum z_priority_t { + Z_PRIORITY_REAL_TIME = 1, + Z_PRIORITY_INTERACTIVE_HIGH = 2, + Z_PRIORITY_INTERACTIVE_LOW = 3, + Z_PRIORITY_DATA_HIGH = 4, + Z_PRIORITY_DATA = 5, + Z_PRIORITY_DATA_LOW = 6, + Z_PRIORITY_BACKGROUND = 7, +} z_priority_t; +/** + * The Queryables that should be target of a :c:func:`z_get`. + * + * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. + * - **ALL_COMPLETE**: All complete queryables. + * - **ALL**: All matching queryables. + */ +typedef enum z_query_target_t { + Z_QUERY_TARGET_BEST_MATCHING, + Z_QUERY_TARGET_ALL, + Z_QUERY_TARGET_ALL_COMPLETE, +} z_query_target_t; +/** + * The subscription reliability. + * + * - **Z_RELIABILITY_BEST_EFFORT** + * - **Z_RELIABILITY_RELIABLE** + */ +typedef enum z_reliability_t { + Z_RELIABILITY_BEST_EFFORT, + Z_RELIABILITY_RELIABLE, +} z_reliability_t; +typedef enum z_sample_kind_t { + Z_SAMPLE_KIND_PUT = 0, + Z_SAMPLE_KIND_DELETE = 1, +} z_sample_kind_t; +typedef enum zcu_locality_t { + ZCU_LOCALITY_ANY = 0, + ZCU_LOCALITY_SESSION_LOCAL = 1, + ZCU_LOCALITY_REMOTE = 2, +} zcu_locality_t; +typedef enum zcu_reply_keyexpr_t { + ZCU_REPLY_KEYEXPR_ANY = 0, + ZCU_REPLY_KEYEXPR_MATCHING_QUERY = 1, +} zcu_reply_keyexpr_t; +/** + * A split buffer that owns all of its data. + * + * To minimize copies and reallocations, Zenoh may provide you data in split buffers. + */ +typedef struct ALIGN(8) z_owned_bytes_t { + uint8_t _0[40]; +} z_owned_bytes_t; +typedef int8_t ZCError; +/** + * A loaned payload. + */ +typedef struct ALIGN(8) z_bytes_t { + uint8_t _0[8]; +} z_bytes_t; +typedef struct z_owned_slice_t { + uint8_t *start; + size_t len; +} z_owned_slice_t; +/** + * A map of maybe-owned vector of bytes to maybe-owned vector of bytes. + * + * In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher + */ +typedef struct ALIGN(8) z_owned_slice_map_t { + uint8_t _0[48]; +} z_owned_slice_map_t; +/** + * The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` + * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with + * `z_check` and `z_str_check` correspondently + */ +typedef struct z_owned_str_t { + char *_cstr; +} z_owned_str_t; +/** + * A contiguous view of bytes owned by some other entity. + * + * `start` being `null` is considered a gravestone value, + * and empty slices are represented using a possibly dangling pointer for `start`. + */ +typedef struct z_slice_t { + const uint8_t *start; + size_t len; +} z_slice_t; +typedef struct ALIGN(8) z_slice_map_t { + uint8_t _0[8]; +} z_slice_map_t; +/** + * A reader for payload data. + */ +typedef struct ALIGN(8) z_owned_bytes_t_reader_t { + uint8_t _0[24]; +} z_owned_bytes_t_reader_t; +typedef struct ALIGN(8) z_bytes_reader_t { + uint8_t _0[8]; +} z_bytes_reader_t; +/** + * Clock + * Uses monotonic clock + */ +typedef struct z_clock_t { + uint64_t t; + const void *t_base; +} z_clock_t; +/** + * Represents a Zenoh ID. + * + * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. + */ +typedef struct ALIGN(1) z_id_t { + uint8_t _0[16]; +} z_id_t; +/** + * An owned array of owned, zenoh allocated, NULL terminated strings. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct z_owned_str_array_t { + char **val; + size_t len; +} z_owned_str_array_t; +/** + * A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. + * + * Members: + * unsigned int whatami: The kind of zenoh entity. + * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). + * z_owned_str_array_t locators: The locators of the scouted entity. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +typedef struct z_owned_hello_t { + unsigned int _whatami; + struct z_id_t _pid; + struct z_owned_str_array_t _locators; +} z_owned_hello_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_hello_t { + void *context; + void (*call)(struct z_owned_hello_t*, void*); + void (*drop)(void*); +} z_owned_closure_hello_t; +/** + * + * Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. + * `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. + */ +typedef struct ALIGN(8) z_owned_query_t { + uint8_t _0[16]; +} z_owned_query_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_owned_query_t { + void *context; + void (*call)(struct z_owned_query_t*, void *context); + void (*drop)(void*); +} z_owned_closure_owned_query_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(z_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_query_t { + void *context; + void (*call)(struct z_query_t, void *context); + void (*drop)(void*); +} z_owned_closure_query_t; +typedef struct ALIGN(8) z_reply_t { + uint8_t _0[8]; +} z_reply_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_reply_t { + void *context; + void (*call)(struct z_reply_t, void*); + void (*drop)(void*); +} z_owned_closure_reply_t; +typedef struct ALIGN(8) z_sample_t { + uint8_t _0[8]; +} z_sample_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(struct z_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_sample_t { + void *context; + void (*call)(struct z_sample_t, void *context); + void (*drop)(void*); +} z_owned_closure_sample_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_closure_zid_t { + void *context; + void (*call)(const struct z_id_t*, void*); + void (*drop)(void*); +} z_owned_closure_zid_t; +typedef struct ALIGN(8) z_owned_condvar_t { + uint8_t _0[24]; +} z_owned_condvar_t; +typedef struct ALIGN(8) z_condvar_t { + uint8_t _0[8]; +} z_condvar_t; +typedef struct ALIGN(8) z_mutex_t { + uint8_t _0[8]; +} z_mutex_t; +/** + * An owned zenoh configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_config_t { + uint8_t _0[8]; +} z_owned_config_t; +/** + * A loaned zenoh configuration. + */ +typedef struct ALIGN(8) z_config_t { + uint8_t _0[8]; +} z_config_t; +/** + * A zenoh-allocated key expression. + * + * Key expressions can identify a single key or a set of keys. + * + * Examples : + * - ``"key/expression"``. + * - ``"key/ex*"``. + * + * Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` + * for wire and computation efficiency. + * + * A `key expression `_ can be either: + * - A plain string expression. + * - A pure numerical id. + * - The combination of a numerical prefix and a string suffix. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_keyexpr_t { + uint8_t _0[32]; +} z_owned_keyexpr_t; +/** + * A loaned key expression. + * + * Key expressions can identify a single key or a set of keys. + * + * Examples : + * - ``"key/expression"``. + * - ``"key/ex*"``. + * + * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, + * both for local processing and network-wise. + */ +typedef struct ALIGN(8) z_keyexpr_t { + uint8_t _0[8]; +} z_keyexpr_t; +/** + * Options passed to the :c:func:`z_declare_publisher` function. + * + * Members: + * z_congestion_control_t congestion_control: The congestion control to apply when routing messages from this publisher. + * z_priority_t priority: The priority of messages from this publisher. + */ +typedef struct z_publisher_options_t { + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; +} z_publisher_options_t; +/** + * An owned zenoh publisher. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_publisher_t { + uint8_t _0[56]; +} z_owned_publisher_t; +/** + * Options passed to the :c:func:`z_declare_queryable` function. + * + * Members: + * bool complete: The completeness of the Queryable. + */ +typedef struct z_queryable_options_t { + bool complete; +} z_queryable_options_t; +/** + * Options passed to the :c:func:`z_declare_subscriber` or :c:func:`z_declare_pull_subscriber` function. + * + * Members: + * z_reliability_t reliability: The subscription reliability. + */ +typedef struct z_subscriber_options_t { + enum z_reliability_t reliability; +} z_subscriber_options_t; +/** + * Options passed to the :c:func:`z_delete` function. + */ +typedef struct z_delete_options_t { + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; +} z_delete_options_t; +typedef struct ALIGN(8) z_owned_encoding_t { + uint8_t _0[48]; +} z_owned_encoding_t; +/** + * The encoding of a payload, in a MIME-like format. + * + * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. + */ +typedef struct ALIGN(8) z_encoding_t { + uint8_t _0[8]; +} z_encoding_t; +/** + * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. + */ +typedef struct z_query_consolidation_t { + enum z_consolidation_mode_t mode; +} z_query_consolidation_t; +/** + * Options passed to the :c:func:`z_get` function. + * + * Members: + * z_query_target_t target: The Queryables that should be target of the query. + * z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. + * z_value_t value: An optional value to attach to the query. + * z_bytes_t attachment: The attachment to attach to the query. + * uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. + */ +typedef struct z_get_options_t { + enum z_query_target_t target; + struct z_query_consolidation_t consolidation; + struct z_owned_bytes_t *payload; + struct z_owned_encoding_t *encoding; + struct z_owned_bytes_t *attachment; + uint64_t timeout_ms; +} z_get_options_t; +/** + * An borrowed array of borrowed, zenoh allocated, NULL terminated strings. + */ +typedef struct z_str_array_t { + size_t len; + const char *const *val; +} z_str_array_t; +/** + * A reference-type hello message returned by a zenoh entity to a scout message sent with `z_scout`. + * + * Members: + * unsigned int whatami: The kind of zenoh entity. + * z_owned_bytes_t pid: The peer id of the scouted entity (empty if absent). + * z_owned_str_array_t locators: The locators of the scouted entity. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +typedef struct z_hello_t { + unsigned int whatami; + struct z_id_t pid; + struct z_str_array_t locators; +} z_hello_t; +typedef struct ALIGN(8) z_owned_mutex_t { + uint8_t _0[32]; +} z_owned_mutex_t; +typedef struct ALIGN(8) z_publisher_t { + uint8_t _0[8]; +} z_publisher_t; +/** + * Represents the set of options that can be applied to the delete operation by a previously declared publisher, + * whenever issued via :c:func:`z_publisher_delete`. + */ +typedef struct z_publisher_delete_options_t { + uint8_t __dummy; +} z_publisher_delete_options_t; +/** + * Options passed to the :c:func:`z_publisher_put` function. + * + * Members: + * z_owned_encoding_t encoding: The encoding of the payload. + * z_owned_bytes_t attachment: The attachment to attach to the publication. + */ +typedef struct z_publisher_put_options_t { + struct z_owned_encoding_t *encoding; + struct z_owned_bytes_t *attachment; +} z_publisher_put_options_t; +/** + * Options passed to the :c:func:`z_put` function. + * + * Members: + * z_encoding_t encoding: The encoding of the payload. + * z_congestion_control_t congestion_control: The congestion control to apply when routing this message. + * z_priority_t priority: The priority of this message. + * z_bytes_t attachment: The attachment to this message. + */ +typedef struct z_put_options_t { + struct z_owned_encoding_t *encoding; + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; + struct z_owned_bytes_t *attachment; +} z_put_options_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * - `this` is a pointer to an arbitrary state. + * - `call` is the typical callback function. `this` will be passed as its last argument. + * - `drop` allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * We guarantee that: + * - `call` will never be called once `drop` has started. + * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_query_channel_closure_t { + void *context; + bool (*call)(struct z_owned_query_t*, void*); + void (*drop)(void*); +} z_owned_query_channel_closure_t; +/** + * A pair of closures + */ +typedef struct z_owned_query_channel_t { + struct z_owned_closure_query_t send; + struct z_owned_query_channel_closure_t recv; +} z_owned_query_channel_t; +/** + * Represents the set of options that can be applied to a query reply, + * sent via :c:func:`z_query_reply`. + * + * Members: + * z_owned_encoding_t encoding: The encoding of the payload. + * z_owned_bytes_t attachment: The attachment to this reply. + */ +typedef struct z_query_reply_options_t { + struct z_owned_encoding_t *encoding; + struct z_owned_bytes_t *attachment; +} z_query_reply_options_t; +typedef struct ALIGN(8) z_value_t { + uint8_t _0[8]; +} z_value_t; +/** + * An owned reply to a :c:func:`z_get`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_reply_t { + uint8_t _0[256]; +} z_owned_reply_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * - `this` is a pointer to an arbitrary state. + * - `call` is the typical callback function. `this` will be passed as its last argument. + * - `drop` allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * We guarantee that: + * - `call` will never be called once `drop` has started. + * - `drop` will only be called ONCE, and AFTER EVERY `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct z_owned_reply_channel_closure_t { + void *context; + bool (*call)(struct z_owned_reply_t*, void*); + void (*drop)(void*); +} z_owned_reply_channel_closure_t; +/** + * A pair of closures, the `send` one accepting + */ +typedef struct z_owned_reply_channel_t { + struct z_owned_closure_reply_t send; + struct z_owned_reply_channel_closure_t recv; +} z_owned_reply_channel_t; +typedef struct ALIGN(8) z_timestamp_t { + uint8_t _0[24]; +} z_timestamp_t; +typedef struct z_owned_scouting_config_t { + struct z_owned_config_t _config; + unsigned long zc_timeout_ms; + uint8_t zc_what; +} z_owned_scouting_config_t; +/** + * The body of a loop over a z_slice_map's key-value pairs. + * + * `key` and `value` are loaned to the body for the duration of a single call. + * `context` is passed transparently through the iteration driver. + * + * Returning `true` is treated as `continue`. + */ +typedef bool (*z_slice_map_iter_body_t)(struct z_slice_t key, struct z_slice_t value, void *context); +typedef struct ALIGN(8) z_subscriber_t { + uint8_t _0[8]; +} z_subscriber_t; +typedef struct ALIGN(8) z_owned_task_t { + uint8_t _0[24]; +} z_owned_task_t; +typedef struct z_task_attr_t { + size_t _0; +} z_task_attr_t; +/** + * Time + * Uses system clock + */ +typedef struct z_time_t { + uint64_t t; +} z_time_t; +/** + * The options for `zc_liveliness_declare_token` + */ +typedef struct zc_liveliness_declaration_options_t { + uint8_t _dummy; +} zc_liveliness_declaration_options_t; +/** + * The options for :c:func:`zc_liveliness_declare_subscriber` + */ +typedef struct zc_liveliness_declare_subscriber_options_t { + uint8_t _dummy; +} zc_liveliness_declare_subscriber_options_t; +/** + * A liveliness token that can be used to provide the network with information about connectivity to its + * declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key + * expressions. + * + * A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. + */ +typedef struct ALIGN(8) zc_owned_liveliness_token_t { + uint8_t _0[32]; +} zc_owned_liveliness_token_t; +/** + * The options for :c:func:`zc_liveliness_declare_subscriber` + */ +typedef struct zc_liveliness_get_options_t { + uint32_t timeout_ms; +} zc_liveliness_get_options_t; +/** + * An owned sample. + * + * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + */ +typedef struct ALIGN(8) zc_owned_sample_t { + uint8_t _0[240]; +} zc_owned_sample_t; +/** + * A struct that indicates if there exist Subscribers matching the Publisher's key expression. + * + * Members: + * bool matching: true if there exist Subscribers matching the Publisher's key expression. + */ +typedef struct zcu_matching_status_t { + bool matching; +} zcu_matching_status_t; +/** + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: + * + * Members: + * void *context: a pointer to an arbitrary state. + * void *call(const struct z_owned_reply_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *drop(void*): allows the callback's state to be freed. + * + * Closures are not guaranteed not to be called concurrently. + * + * It is guaranteed that: + * + * - `call` will never be called once `drop` has started. + * - `drop` will only be called **once**, and **after every** `call` has ended. + * - The two previous guarantees imply that `call` and `drop` are never called concurrently. + */ +typedef struct zcu_owned_closure_matching_status_t { + void *context; + void (*call)(const struct zcu_matching_status_t*, void*); + void (*drop)(void*); +} zcu_owned_closure_matching_status_t; +/** + * An owned zenoh matching listener. Destroying the matching listener cancels the subscription. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) zcu_owned_matching_listener_t { + uint8_t _0[40]; +} zcu_owned_matching_listener_t; +/** + * An owned zenoh publication_cache. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) ze_owned_publication_cache_t { + uint8_t _0[96]; +} ze_owned_publication_cache_t; +/** + * Options passed to the :c:func:`ze_declare_publication_cache` function. + * + * Members: + * z_keyexpr_t queryable_prefix: The prefix used for queryable + * zcu_locality_t queryable_origin: The restriction for the matching queries that will be receive by this + * publication cache + * bool queryable_complete: the `complete` option for the queryable + * size_t history: The the history size + * size_t resources_limit: The limit number of cached resources + */ +typedef struct ze_publication_cache_options_t { + const struct z_keyexpr_t *queryable_prefix; + enum zcu_locality_t queryable_origin; + bool queryable_complete; + size_t history; + size_t resources_limit; +} ze_publication_cache_options_t; +/** + * An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. + * + * Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) ze_owned_querying_subscriber_t { + uint8_t _0[64]; +} ze_owned_querying_subscriber_t; +/** + * Represents the set of options that can be applied to a querying subscriber, + * upon its declaration via :c:func:`ze_declare_querying_subscriber`. + * + * Members: + * z_reliability_t reliability: The subscription reliability. + * zcu_locality_t allowed_origin: The restriction for the matching publications that will be + * receive by this subscriber. + * z_keyexpr_t query_selector: The selector to be used for queries. + * z_query_target_t query_target: The target to be used for queries. + * z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. + * zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. + * uint64_t query_timeout_ms: The timeout to be used for queries. + */ +typedef struct ze_querying_subscriber_options_t { + enum z_reliability_t reliability; + enum zcu_locality_t allowed_origin; + const struct z_keyexpr_t *query_selector; + enum z_query_target_t query_target; + struct z_query_consolidation_t query_consolidation; + enum zcu_reply_keyexpr_t query_accept_replies; + uint64_t query_timeout_ms; +} ze_querying_subscriber_options_t; +typedef struct ALIGN(8) ze_querying_subscriber_t { + uint8_t _0[8]; +} ze_querying_subscriber_t; +ZENOHC_API extern const unsigned int Z_ROUTER; +ZENOHC_API extern const unsigned int Z_PEER; +ZENOHC_API extern const unsigned int Z_CLIENT; +ZENOHC_API extern const char *Z_CONFIG_MODE_KEY; +ZENOHC_API extern const char *Z_CONFIG_CONNECT_KEY; +ZENOHC_API extern const char *Z_CONFIG_LISTEN_KEY; +ZENOHC_API extern const char *Z_CONFIG_USER_KEY; +ZENOHC_API extern const char *Z_CONFIG_PASSWORD_KEY; +ZENOHC_API extern const char *Z_CONFIG_MULTICAST_SCOUTING_KEY; +ZENOHC_API extern const char *Z_CONFIG_MULTICAST_INTERFACE_KEY; +ZENOHC_API extern const char *Z_CONFIG_MULTICAST_IPV4_ADDRESS_KEY; +ZENOHC_API extern const char *Z_CONFIG_SCOUTING_TIMEOUT_KEY; +ZENOHC_API extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; +ZENOHC_API extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; +/** + * Returns `true` if the payload is in a valid state. + */ +ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *payload); +/** + * Increments the payload's reference count, returning an owned version of it. + */ +ZENOHC_API void z_bytes_clone(const struct z_owned_bytes_t *src, struct z_owned_bytes_t *dst); +/** + * Decodes payload into owned bytes + */ +ZENOHC_API ZCError z_bytes_decode_into_bytes(struct z_bytes_t payload, struct z_owned_slice_t *dst); +/** + * Decodes payload into bytes map. + */ +ZENOHC_API +ZCError z_bytes_decode_into_bytes_map(struct z_bytes_t payload, + struct z_owned_slice_map_t *dst); +/** + * Decodes payload into null-terminated string. + */ +ZENOHC_API ZCError z_bytes_decode_into_string(struct z_bytes_t payload, struct z_owned_str_t *dst); +/** + * Decrements the payload's reference counter, destroying it if applicable. + * + * `this` will be reset to `z_buffer_null`, preventing UB on double-frees. + */ +ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); +/** + * Encodes byte sequence by aliasing. + */ +ZENOHC_API void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, struct z_slice_t bytes); +/** + * Encodes bytes map by copying. + */ +ZENOHC_API +void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, + struct z_slice_map_t bytes_map); +/** + * Encodes a null-terminated string by aliasing. + */ +ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const char *cstr); +/** + * Returns total number bytes in the payload. + */ +ZENOHC_API size_t z_bytes_len(struct z_bytes_t payload); +/** + * Loans the payload, allowing you to call functions that only need a loan of it. + */ +ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *payload); +/** + * The gravestone value for `z_owned_bytes_t`. + */ +ZENOHC_API void z_bytes_null(struct z_owned_bytes_t *this_); +ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_t_reader_t *this_); +ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_t_reader_t *this_); +ZENOHC_API +struct z_bytes_reader_t z_bytes_reader_loan(const struct z_owned_bytes_t_reader_t *reader); +/** + * Creates a reader for the specified `payload`. + * + * Returns 0 in case of success, -1 if `payload` is not valid. + */ +ZENOHC_API +void z_bytes_reader_new(struct z_bytes_t payload, + struct z_owned_bytes_t_reader_t *this_); +ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_t_reader_t *this_); +/** + * Reads data into specified destination. + * + * Will read at most `len` bytes. + * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. + */ +ZENOHC_API +size_t z_bytes_reader_read(struct z_bytes_reader_t this_, + uint8_t *dest, + size_t len); +/** + * Sets the `reader` position indicator for the payload to the value pointed to by offset. + * The new position is exactly offset bytes measured from the beginning of the payload if origin is SEEK_SET, + * from the current reader position if origin is SEEK_CUR, and from the end of the payload if origin is SEEK_END. + * Return ​0​ upon success, negative error code otherwise. + */ +ZENOHC_API +ZCError z_bytes_reader_seek(struct z_bytes_reader_t this_, + int64_t offset, + int origin); +/** + * Returns the read position indicator. + * Returns read position indicator on success or -1L if failure occurs. + */ +ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t this_); +ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); +ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); +ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); +ZENOHC_API struct z_clock_t z_clock_now(void); +/** + * Closes a zenoh session. This drops and invalidates `session` for double-drop safety. + * + * Returns a negative value if an error occured while closing the session. + * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. + */ +ZENOHC_API int8_t z_close(struct z_owned_session_t *session); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_hello_call(const struct z_owned_closure_hello_t *closure, + struct z_owned_hello_t *hello); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_hello_drop(struct z_owned_closure_hello_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_hello_t' type + */ +ZENOHC_API struct z_owned_closure_hello_t z_closure_hello_null(void); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_owned_query_call(const struct z_owned_closure_owned_query_t *closure, + struct z_owned_query_t *query); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_owned_query_drop(struct z_owned_closure_owned_query_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type + */ +ZENOHC_API struct z_owned_closure_owned_query_t z_closure_owned_query_null(void); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_query_call(const struct z_owned_closure_query_t *closure, + struct z_query_t query); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_query_drop(struct z_owned_closure_query_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_query_t' type + */ +ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_reply_call(const struct z_owned_closure_reply_t *closure, + struct z_reply_t reply); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_reply_drop(struct z_owned_closure_reply_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_reply_t' type + */ +ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, + struct z_sample_t sample); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_sample_drop(struct z_owned_closure_sample_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_sample_t' type + */ +ZENOHC_API struct z_owned_closure_sample_t z_closure_sample_null(void); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void z_closure_zid_call(const struct z_owned_closure_zid_t *closure, + const struct z_id_t *sample); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_closure_zid_drop(struct z_owned_closure_zid_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_closure_zid_t' type + */ +ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); +ZENOHC_API bool z_condvar_check(const struct z_owned_condvar_t *this_); +ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); +ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); +ZENOHC_API struct z_condvar_t z_condvar_loan(const struct z_owned_condvar_t *this_); +ZENOHC_API void z_condvar_null(struct z_owned_condvar_t *this_); +ZENOHC_API ZCError z_condvar_signal(struct z_condvar_t this_); +ZENOHC_API ZCError z_condvar_wait(struct z_condvar_t this_, struct z_mutex_t m); +/** + * Returns ``true`` if `config` is valid. + */ +ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); +/** + * Constructs a default, zenoh-allocated, client mode configuration. + * If `peer` is not null, it is added to the configuration as remote peer. + */ +ZENOHC_API +ZCError z_config_client(const char *const *peers, + size_t n_peers, + struct z_owned_config_t *this_); +/** + * Clones the config. + */ +ZENOHC_API void z_config_clone(const struct z_config_t *src, struct z_owned_config_t *dst); +/** + * Frees `config`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_config_drop(struct z_owned_config_t *config); +/** + * Returns a :c:type:`z_config_t` loaned from `s`. + */ +ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); +/** + * Return a new, zenoh-allocated, empty configuration. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +ZENOHC_API +void z_config_new(struct z_owned_config_t *this_); +/** + * Constructs a null safe-to-drop value of 'z_owned_config_t' type + */ +ZENOHC_API void z_config_null(struct z_owned_config_t *this_); +/** + * Constructs a default, zenoh-allocated, peer mode configuration. + */ +ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); +/** + * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. + * + * This numerical id will be used on the network to save bandwidth and + * ease the retrieval of the concerned resource in the routing tables. + */ +ZENOHC_API +ZCError z_declare_keyexpr(struct z_owned_keyexpr_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr); +/** + * Declares a publisher for the given key expression. + * + * Data can be put and deleted with this publisher with the help of the + * :c:func:`z_publisher_put` and :c:func:`z_publisher_delete` functions. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to publish. + * options: additional options for the publisher. + * + * Returns: + * A :c:type:`z_owned_publisherr_t`. + * + * To check if the publisher decalration succeeded and if the publisher is still valid, + * you may use `z_publisher_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * Example: + * Declaring a publisher passing `NULL` for the options: + * + * .. code-block:: C + * + * z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(expr), NULL); + * + * is equivalent to initializing and passing the default publisher options: + * + * .. code-block:: C + * + * z_publisher_options_t opts = z_publisher_options_default(); + * z_owned_publisher_t sub = z_declare_publisher(z_loan(s), z_keyexpr(expr), &opts); + */ +ZENOHC_API +ZCError z_declare_publisher(struct z_session_t session, + struct z_keyexpr_t key_expr, + const struct z_publisher_options_t *options, + struct z_owned_publisher_t *this_); +/** + * Creates a Queryable for the given key expression. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression the Queryable will reply to. + * callback: The callback function that will be called each time a matching query is received. + * options: Options for the queryable. + * + * Returns: + * The created :c:type:`z_owned_queryable_t` or ``null`` if the creation failed. + */ +ZENOHC_API +ZCError z_declare_queryable(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_query_t *callback, + const struct z_queryable_options_t *options, + struct z_owned_queryable_t *this_); +/** + * Declare a subscriber for a given key expression. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to subscribe. + * callback: The callback function that will be called each time a data matching the subscribed expression is received. + * opts: The options to be passed to describe the options to be passed to the subscriber declaration. + * + * Returns: + * A :c:type:`z_owned_subscriber_t`. + * + * To check if the subscription succeeded and if the subscriber is still valid, + * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * Example: + * Declaring a subscriber passing `NULL` for the options: + * + * .. code-block:: C + * + * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); + * + * is equivalent to initializing and passing the default subscriber options: + * + * .. code-block:: C + * + * z_subscriber_options_t opts = z_subscriber_options_default(); + * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); + */ +ZENOHC_API +ZCError z_declare_subscriber(struct z_owned_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct z_subscriber_options_t options); +/** + * Delete data. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to delete. + * options: The put options. + * Returns: + * ``0`` in case of success, negative values in case of failure. + */ +ZENOHC_API +ZCError z_delete(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_delete_options_t opts); +/** + * Constructs the default value for :c:type:`z_put_options_t`. + */ +ZENOHC_API struct z_delete_options_t z_delete_options_default(void); +/** + * Returns ``true`` if `encoding` is valid. + */ +ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); +/** + * Constructs a default :c:type:`z_encoding_t`. + */ +ZENOHC_API struct z_encoding_t z_encoding_default(void); +/** + * Frees `encoding`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); +/** + * Constructs a specific :c:type:`z_encoding_t`. + */ +ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); +/** + * Returns a :c:type:`z_encoding_t` loaned from `encoding`. + */ +ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); +/** + * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type + */ +ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); +/** + * Query data from the matching queryables in the system. + * Replies are provided through a callback function. + * + * Returns a negative value upon failure. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression matching resources to query. + * parameters: The query's parameters, similar to a url's query segment. + * callback: The callback function that will be called on reception of replies for this query. + * Note that the `reply` parameter of the callback is passed by mutable reference, + * but **will** be dropped once your callback exits to help you avoid memory leaks. + * If you'd rather take ownership, please refer to the documentation of :c:func:`z_reply_null` + * options: additional options for the get. + */ +ZENOHC_API +ZCError z_get(struct z_session_t session, + struct z_keyexpr_t key_expr, + const char *parameters, + struct z_owned_closure_reply_t *callback, + struct z_get_options_t options); +ZENOHC_API struct z_get_options_t z_get_options_default(void); +/** + * Returns ``true`` if `hello` is valid. + */ +ZENOHC_API bool z_hello_check(const struct z_owned_hello_t *hello); +/** + * Frees `hello`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_hello_drop(struct z_owned_hello_t *hello); +/** + * Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. + */ +ZENOHC_API struct z_hello_t z_hello_loan(const struct z_owned_hello_t *hello); +/** + * Constructs a gravestone value for hello, useful to steal one from a callback + */ +ZENOHC_API struct z_owned_hello_t z_hello_null(void); +/** + * Fetches the Zenoh IDs of all connected peers. + * + * `callback` will be called once for each ID, is guaranteed to never be called concurrently, + * and is guaranteed to be dropped before this function exits. + * + * Retuns 0 on success, negative values on failure + */ +ZENOHC_API +ZCError z_info_peers_zid(struct z_session_t session, + struct z_owned_closure_zid_t *callback); +/** + * Fetches the Zenoh IDs of all connected routers. + * + * `callback` will be called once for each ID, is guaranteed to never be called concurrently, + * and is guaranteed to be dropped before this function exits. + * + * Retuns 0 on success, negative values on failure. + */ +ZENOHC_API +ZCError z_info_routers_zid(struct z_session_t session, + struct z_owned_closure_zid_t *callback); +/** + * Returns the local Zenoh ID. + * + * Unless the `session` is invalid, that ID is guaranteed to be non-zero. + * In other words, this function returning an array of 16 zeros means you failed + * to pass it a valid session. + */ +ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API ZCError z_keyexpr(struct z_owned_keyexpr_t *this_, const char *name); +/** + * Returns the key expression's internal string by aliasing it. + * + * Currently exclusive to zenoh-c + */ +ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(struct z_keyexpr_t ke); +/** + * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. + * The string is canonized in-place before being passed to keyexpr. + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +ZCError z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, + char *name); +/** + * Canonizes the passed string in place, possibly shortening it by modifying `len`. + * + * Returns ``0`` upon success, negative values upon failure. + * Returns a negative value if canonization failed, which indicates that the passed string was an invalid + * key expression for reasons other than a non-canon form. + * + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +ZCError z_keyexpr_canonize(char *start, + size_t *len); +/** + * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. + * + * Returns ``0`` upon success, negative values upon failure. + * Returns a negative value if canonization failed, which indicates that the passed string was an invalid + * key expression for reasons other than a non-canon form. + * + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +ZCError z_keyexpr_canonize_null_terminated(char *start); +/** + * Returns ``true`` if `keyexpr` is valid. + */ +ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); +/** + * Performs string concatenation and returns the result as a `z_owned_keyexpr_t`. + * In case of error, the return value will be set to its invalidated state. + * + * You should probably prefer `z_keyexpr_join` as Zenoh may then take advantage of the hierachical separation it inserts. + * + * To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, + * as this would extremely likely cause bugs. + */ +ZENOHC_API +ZCError z_keyexpr_concat(struct z_keyexpr_t left, + const char *right_start, + size_t right_len, + struct z_owned_keyexpr_t *this_); +/** + * Frees `keyexpr` and invalidates it for double-drop safety. + */ +ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); +/** + * Returns ``0`` if both ``left`` and ``right`` are equal. + */ +ZENOHC_API bool z_keyexpr_equals(struct z_keyexpr_t left, struct z_keyexpr_t right); +/** + * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set + * defined by ``right``. + */ +ZENOHC_API +bool z_keyexpr_includes(struct z_keyexpr_t left, + struct z_keyexpr_t right); +/** + * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the + * sets defined by ``left`` and ``right``. + */ +ZENOHC_API +bool z_keyexpr_intersects(struct z_keyexpr_t left, + struct z_keyexpr_t right); +/** + * Returns ``0`` if the passed string is a valid (and canon) key expression. + * Otherwise returns error value + */ +ZENOHC_API ZCError z_keyexpr_is_canon(const char *start, size_t len); +/** + * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. + * In case of error, the return value will be set to its invalidated state. + */ +ZENOHC_API +ZCError z_keyexpr_join(struct z_keyexpr_t left, + struct z_keyexpr_t right, + struct z_owned_keyexpr_t *this_); +/** + * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + */ +ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); +/** + * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. + */ +ZENOHC_API ZCError z_keyexpr_new(const char *name, struct z_owned_keyexpr_t *this_); +/** + * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. + */ +ZENOHC_API +ZCError z_keyexpr_new_autocanonize(const char *name, + struct z_owned_keyexpr_t *this_); +/** + * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type + */ +ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); +/** + * Returns the relation between `left` and `right` from `left`'s point of view. + * + * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. + */ +ZENOHC_API +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, + struct z_keyexpr_t right); +/** + * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. + * The user is responsible of droping the returned string using `z_drop` + */ +ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t ke); +/** + * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * + * - MUST NOT contain `//`, MUST NOT start nor end with `/`, MUST NOT contain any of the characters `?#$`. + * - any instance of `**` may only be lead or followed by `/`. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API +void z_keyexpr_unchecked(struct z_owned_keyexpr_t *this_, + const char *name); +ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); +ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); +ZENOHC_API ZCError z_mutex_init(struct z_owned_mutex_t *this_); +ZENOHC_API struct z_mutex_t z_mutex_loan(const struct z_owned_mutex_t *this_); +ZENOHC_API ZCError z_mutex_lock(struct z_mutex_t this_); +ZENOHC_API ZCError z_mutex_try_lock(struct z_mutex_t this_); +ZENOHC_API ZCError z_mutex_unlock(struct z_mutex_t this_); +/** + * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. + * Config value is always consumed upon function return. + */ +ZENOHC_API +ZCError z_open(struct z_owned_session_t *this_, + struct z_owned_config_t *config); +/** + * Returns ``true`` if `pub` is valid. + */ +ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); +/** + * Sends a `DELETE` message onto the publisher's key expression. + * + * Returns: + * ``0`` in case of success, ``1`` in case of failure. + */ +ZENOHC_API +ZCError z_publisher_delete(struct z_publisher_t publisher, + struct z_publisher_delete_options_t _options); +/** + * Constructs the default values for the delete operation via a publisher entity. + * + * Returns: + * Returns the constructed :c:type:`z_publisher_delete_options_t`. + */ +ZENOHC_API struct z_publisher_delete_options_t z_publisher_delete_options_default(void); +/** + * Returns the key expression of the publisher + */ +ZENOHC_API struct z_keyexpr_t z_publisher_keyexpr(struct z_publisher_t publisher); +/** + * Returns a :c:type:`z_publisher_t` loaned from `p`. + */ +ZENOHC_API struct z_publisher_t z_publisher_loan(const struct z_owned_publisher_t *p); +/** + * Constructs a null safe-to-drop value of 'z_owned_publisher_t' type + */ +ZENOHC_API void z_publisher_null(struct z_owned_publisher_t *this_); +/** + * Constructs the default value for :c:type:`z_publisher_options_t`. + */ +ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); +/** + * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. + * + * This is avoids copies when transfering data that was either: + * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher + * - constructed from a `zc_owned_shmbuf_t` + * + * The payload and all owned options fields are consumed upon function return. + * + * Parameters: + * session: The zenoh session. + * payload: The value to put. + * options: The publisher put options. + * Returns: + * ``0`` in case of success, negative values in case of failure. + */ +ZENOHC_API +ZCError z_publisher_put(struct z_publisher_t publisher, + struct z_owned_bytes_t *payload, + struct z_publisher_put_options_t options); +/** + * Constructs the default value for :c:type:`z_publisher_put_options_t`. + */ +ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); +/** + * Put data, transfering its ownership. + * + * + * The payload's encoding and attachment can be sepcified through the options. These values are consumed upon function + * return. + * + * Parameters: + * session: The zenoh session. + * key_expr: The key expression to put. + * payload: The value to put (consumed upon function return). + * options: The put options. + * Returns: + * ``0`` in case of success, negative error values in case of failure. + */ +ZENOHC_API +ZCError z_put(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_bytes_t *payload, + struct z_put_options_t options); +/** + * Constructs the default value for :c:type:`z_put_options_t`. + */ +ZENOHC_API struct z_put_options_t z_put_options_default(void); +/** + * Gets the attachment to the query by aliasing. + * + * Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. + */ +ZENOHC_API struct z_bytes_t z_query_attachment(struct z_query_t query); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +bool z_query_channel_closure_call(const struct z_owned_query_channel_closure_t *closure, + struct z_owned_query_t *query); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_query_channel_closure_drop(struct z_owned_query_channel_closure_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_query_channel_closure_t' type + */ +ZENOHC_API struct z_owned_query_channel_closure_t z_query_channel_closure_null(void); +ZENOHC_API void z_query_channel_drop(struct z_owned_query_channel_t *channel); +/** + * Constructs a null safe-to-drop value of 'z_owned_query_channel_t' type + */ +ZENOHC_API struct z_owned_query_channel_t z_query_channel_null(void); +/** + * Returns `false` if `this` is in a gravestone state, `true` otherwise. + * + * This function may not be called with the null pointer, but can be called with the gravestone value. + */ +ZENOHC_API +bool z_query_check(const struct z_owned_query_t *query); +/** + * Clones the query, allowing to keep it in an "open" state past the callback's return. + * + * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). + */ +ZENOHC_API +void z_query_clone(struct z_owned_query_t *this_, + struct z_query_t query); +/** + * Automatic query consolidation strategy selection. + * + * A query consolidation strategy will automatically be selected depending the query selector. + * If the selector contains time range properties, no consolidation is performed. + * Otherwise the :c:func:`z_query_consolidation_latest` strategy is used. + * + * Returns: + * Returns the constructed :c:type:`z_query_consolidation_t`. + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_auto(void); +/** + * Creates a default :c:type:`z_query_consolidation_t` (consolidation mode AUTO). + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_default(void); +/** + * Latest value consolidation. + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_latest(void); +/** + * Monotonic consolidation. + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_monotonic(void); +/** + * Disable consolidation. + */ +ZENOHC_API struct z_query_consolidation_t z_query_consolidation_none(void); +/** + * Destroys the query, setting `this` to its gravestone value to prevent double-frees. + * + * This function may not be called with the null pointer, but can be called with the gravestone value. + */ +ZENOHC_API +void z_query_drop(struct z_owned_query_t *this_); +/** + * Get a query's key by aliasing it. + */ +ZENOHC_API struct z_keyexpr_t z_query_keyexpr(struct z_query_t query); +/** + * Aliases the query. + * + * This function may not be called with the null pointer, but can be called with the gravestone value. + */ +ZENOHC_API +struct z_query_t z_query_loan(const struct z_owned_query_t *this_); +/** + * The gravestone value of `z_owned_query_t`. + */ +ZENOHC_API void z_query_null(struct z_owned_query_t *this_); +/** + * Get a query's `value selector `_ by aliasing it. + */ +ZENOHC_API +struct z_slice_t z_query_parameters(struct z_query_t query); +/** + * Send a reply to a query. + * + * This function must be called inside of a Queryable callback passing the + * query received as parameters of the callback function. This function can + * be called multiple times to send multiple replies to a query. The reply + * will be considered complete when the Queryable callback returns. + * + * Parameters: + * query: The query to reply to. + * key_expr: The key of this reply. + * payload: The value of this reply. + * options: The options of this reply. + * + * The payload and all owned options fields are consumed upon function return. + */ +ZENOHC_API +ZCError z_query_reply(struct z_query_t query, + struct z_keyexpr_t key_expr, + struct z_owned_bytes_t *payload, + struct z_query_reply_options_t options); +/** + * Constructs the default value for :c:type:`z_query_reply_options_t`. + */ +ZENOHC_API struct z_query_reply_options_t z_query_reply_options_default(void); +/** + * Create a default :c:type:`z_query_target_t`. + */ +ZENOHC_API enum z_query_target_t z_query_target_default(void); +/** + * Gets a query's `payload value `_ by aliasing it. + * + * **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** + * Before calling this funciton, the user must ensure that `z_query_has_value` returns true. + */ +ZENOHC_API +struct z_value_t z_query_value(struct z_query_t query); +/** + * Returns ``true`` if `qable` is valid. + */ +ZENOHC_API bool z_queryable_check(const struct z_owned_queryable_t *qable); +/** + * Constructs a null safe-to-drop value of 'z_owned_queryable_t' type + */ +ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); +/** + * Constructs the default value for :c:type:`z_query_reply_options_t`. + */ +ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); +ZENOHC_API void z_random_fill(void *buf, size_t len); +ZENOHC_API uint16_t z_random_u16(void); +ZENOHC_API uint32_t z_random_u32(void); +ZENOHC_API uint64_t z_random_u64(void); +ZENOHC_API uint8_t z_random_u8(void); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +bool z_reply_channel_closure_call(const struct z_owned_reply_channel_closure_t *closure, + struct z_owned_reply_t *reply); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API void z_reply_channel_closure_drop(struct z_owned_reply_channel_closure_t *closure); +/** + * Constructs a null safe-to-drop value of 'z_owned_reply_channel_closure_t' type + */ +ZENOHC_API struct z_owned_reply_channel_closure_t z_reply_channel_closure_null(void); +ZENOHC_API void z_reply_channel_drop(struct z_owned_reply_channel_t *channel); +/** + * Constructs a null safe-to-drop value of 'z_owned_reply_channel_t' type + */ +ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); +/** + * Returns ``true`` if `reply` is valid. + */ +ZENOHC_API bool z_reply_check(const struct z_owned_reply_t *this_); +ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, struct z_reply_t reply); +/** + * Frees `reply`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_reply_drop(struct z_owned_reply_t *this_); +/** + * Yields the contents of the reply by asserting it indicates a failure. + * + * You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. + */ +ZENOHC_API +struct z_value_t z_reply_err(struct z_reply_t reply); +/** + * Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. + * + * If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. + */ +ZENOHC_API +bool z_reply_is_ok(struct z_reply_t reply); +/** + * Returns an invalidated :c:type:`z_owned_reply_t`. + * + * This is useful when you wish to take ownership of a value from a callback to :c:func:`z_get`: + * + * - copy the value of the callback's argument's pointee, + * - overwrite the pointee with this function's return value, + * - you are now responsible for dropping your copy of the reply. + */ +ZENOHC_API void z_reply_null(struct z_owned_reply_t *this_); +/** + * Yields the contents of the reply by asserting it indicates a success. + * + * You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. + */ +ZENOHC_API +struct z_sample_t z_reply_ok(struct z_reply_t reply); +/** + * Gets sample's attachment. + * + * Before calling this function, ensure that `zc_sample_has_attachment` returns true + */ +ZENOHC_API struct z_bytes_t z_sample_attachment(struct z_sample_t sample); +/** + * The encoding of the payload. + */ +ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); +/** + * The qos with which the sample was received. + * TODO: split to methods (priority, congestion_control, express) + * Checks if sample contains an attachment. + */ +ZENOHC_API bool z_sample_has_attachment(struct z_sample_t sample); +/** + * The Key Expression of the sample. + * + * `sample` is aliased by its return value. + */ +ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); +/** + * The sample's kind (put or delete). + */ +ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); +/** + * The sample's data, the return value aliases the sample. + * + */ +ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); +/** + * The samples timestamp + * + * Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. + */ +ZENOHC_API +bool z_sample_timestamp(const struct z_sample_t *sample, + struct z_timestamp_t *timestamp_out); +/** + * Scout for routers and/or peers. + * + * Parameters: + * what: A whatami bitmask of zenoh entities kind to scout for. + * config: A set of properties to configure the scouting. + * timeout: The time (in milliseconds) that should be spent scouting. + * + * Returns 0 if successful, negative values upon failure. + */ +ZENOHC_API +ZCError z_scout(struct z_owned_scouting_config_t *config, + struct z_owned_closure_hello_t *callback); +ZENOHC_API bool z_scouting_config_check(const struct z_owned_scouting_config_t *config); +ZENOHC_API void z_scouting_config_default(struct z_owned_scouting_config_t *this_); +ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); +ZENOHC_API +void z_scouting_config_from(struct z_config_t config, + struct z_owned_scouting_config_t *this_); +ZENOHC_API void z_scouting_config_null(struct z_owned_scouting_config_t *this_); +/** + * Returns ``true`` if `session` is valid. + */ +ZENOHC_API bool z_session_check(const struct z_owned_session_t *this_); +/** + * Returns a :c:type:`z_session_t` loaned from `s`. + * + * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. + * + * # Safety + * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, + * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) + * have been destroyed is UB (likely SEGFAULT) + */ +ZENOHC_API +struct z_session_t z_session_loan(const struct z_owned_session_t *this_); +/** + * Constructs a null safe-to-drop value of 'z_owned_session_t' type + */ +ZENOHC_API void z_session_null(struct z_owned_session_t *this_); +ZENOHC_API int8_t z_sleep_ms(size_t time); +ZENOHC_API int8_t z_sleep_s(size_t time); +ZENOHC_API int8_t z_sleep_us(size_t time); +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *b); +ZENOHC_API struct z_owned_slice_t z_slice_clone(const struct z_slice_t *b); +/** + * Returns the gravestone value for `z_slice_t` + */ +ZENOHC_API struct z_slice_t z_slice_empty(void); +/** + * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * `str == NULL` will cause this to return `z_slice_empty()` + */ +ZENOHC_API struct z_slice_t z_slice_from_str(const char *str); +/** + * Returns ``true`` if `b` is initialized. + */ +ZENOHC_API bool z_slice_is_initialized(const struct z_slice_t *b); +ZENOHC_API struct z_slice_t z_slice_loan(const struct z_owned_slice_t *b); +/** + * Returns `true` if the map is not in its gravestone state + */ +ZENOHC_API bool z_slice_map_check(const struct z_owned_slice_map_t *map); +/** + * Destroys the map, resetting `this` to its gravestone value. + * + * This function is double-free safe, passing a pointer to the gravestone value will have no effect. + */ +ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); +/** + * Returns the value associated with `key`, returning a gravestone value if: + * - `key` is in gravestone state. + */ +ZENOHC_API struct z_slice_t z_slice_map_get(struct z_slice_map_t this_, struct z_slice_t key); +/** + * Associates `value` to `key` in the map, aliasing them. + * + * Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. + * + * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. + */ +ZENOHC_API +ZCError z_slice_map_insert_by_alias(struct z_slice_map_t this_, + struct z_slice_t key, + struct z_slice_t value); +/** + * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. + * + * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. + */ +ZENOHC_API +ZCError z_slice_map_insert_by_copy(struct z_slice_map_t this_, + struct z_slice_t key, + struct z_slice_t value); +/** + * Returns true if the map is empty, false otherwise. + */ +ZENOHC_API bool z_slice_map_is_empty(struct z_slice_map_t this_); +ZENOHC_API +void z_slice_map_iterate(const struct z_slice_map_t *this_, + z_slice_map_iter_body_t body, + void *context); +/** + * Returns number of key-value pairs in the map. + */ +ZENOHC_API size_t z_slice_map_len(struct z_slice_map_t this_); +/** + * Constructs a new empty map. + */ +ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); +/** + * Constructs the gravestone value for `z_owned_slice_map_t` + */ +ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); +/** + * Deprecated in favor of `z_slice_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * `str == NULL` will cause this to return `z_slice_empty()` + */ +ZENOHC_API +struct z_slice_t z_slice_new(const char *str); +/** + * Returns the gravestone value for `z_owned_slice_t` + */ +ZENOHC_API struct z_owned_slice_t z_slice_null(void); +/** + * Constructs a `len` bytes long view starting at `start`. + */ +ZENOHC_API struct z_slice_t z_slice_wrap(const uint8_t *start, size_t len); +/** + * Returns ``true`` if `strs` is valid. + */ +ZENOHC_API bool z_str_array_check(const struct z_owned_str_array_t *strs); +/** + * Frees `strs` and invalidates it for double-drop safety. + */ +ZENOHC_API void z_str_array_drop(struct z_owned_str_array_t *strs); +/** + * Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. + */ +ZENOHC_API struct z_str_array_t z_str_array_loan(const struct z_owned_str_array_t *strs); +/** + * Returns ``true`` if `s` is a valid string + */ +ZENOHC_API bool z_str_check(const struct z_owned_str_t *s); +/** + * Frees `z_owned_str_t`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_str_drop(struct z_owned_str_t *s); +/** + * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. + */ +ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); +/** + * Returns undefined `z_owned_str_t` + */ +ZENOHC_API struct z_owned_str_t z_str_null(void); +/** + * Returns ``true`` if `sub` is valid. + */ +ZENOHC_API bool z_subscriber_check(const struct z_owned_subscriber_t *subscriber); +/** + * Returns the key expression of the subscriber. + */ +ZENOHC_API struct z_keyexpr_t z_subscriber_keyexpr(struct z_subscriber_t subscriber); +/** + * Returns a :c:type:`z_subscriber_t` loaned from `this`. + */ +ZENOHC_API struct z_subscriber_t z_subscriber_loan(const struct z_owned_subscriber_t *this_); +/** + * Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type + */ +ZENOHC_API void z_subscriber_null(struct z_owned_subscriber_t *this_); +/** + * Constructs the default value for :c:type:`z_subscriber_options_t`. + */ +ZENOHC_API struct z_subscriber_options_t z_subscriber_options_default(void); +ZENOHC_API bool z_task_check(const struct z_owned_task_t *this_); +/** + * Detaches the task and releases all allocated resources. + */ +ZENOHC_API void z_task_detach(struct z_owned_task_t *this_); +ZENOHC_API +ZCError z_task_init(struct z_owned_task_t *this_, + const struct z_task_attr_t *_attr, + void (*fun)(void *arg), + void *arg); +/** + * Joins the task and releases all allocated resources + */ +ZENOHC_API ZCError z_task_join(struct z_owned_task_t *this_); +ZENOHC_API void z_task_null(struct z_owned_task_t *this_); +ZENOHC_API uint64_t z_time_elapsed_ms(const struct z_time_t *time); +ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); +ZENOHC_API uint64_t z_time_elapsed_us(const struct z_time_t *time); +ZENOHC_API struct z_time_t z_time_now(void); +ZENOHC_API const char *z_time_now_as_str(const char *buf, size_t len); +ZENOHC_API struct z_id_t z_timestamp_get_id(const struct z_timestamp_t *timestamp); +ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp); +/** + * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. + * The keyxpr is consumed. + */ +ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); +/** + * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError z_undeclare_publisher(struct z_owned_publisher_t *publisher); +/** + * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. + * + * Parameters: + * qable: The :c:type:`z_owned_queryable_t` to undeclare. + */ +ZENOHC_API ZCError z_undeclare_queryable(struct z_owned_queryable_t *qable); +/** + * Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); +/** + * Converts the kind of zenoh entity into a string. + * + * Parameters: + * whatami: A whatami bitmask of zenoh entity kind. + * buf: Buffer to write a null-terminated string to. + * len: Maximum number of bytes that can be written to the `buf`. + * + * Returns 0 if successful, negative values if whatami contains an invalid bitmask or `buf` is null, + * or number of remaining bytes, if the null-terminated string size exceeds `len`. + */ +ZENOHC_API int8_t z_whatami_to_str(uint8_t whatami, char *buf, size_t len); +/** + * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. + */ +ZENOHC_API +ZCError zc_config_from_file(const char *path, + struct z_owned_config_t *this_); +/** + * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. + * + * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). + */ +ZENOHC_API +ZCError zc_config_from_str(const char *s, + struct z_owned_config_t *this_); +/** + * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. + * Use `z_drop` to safely deallocate this string + */ +ZENOHC_API +struct z_owned_str_t zc_config_get(struct z_config_t config, + const char *key); +/** + * Inserts a JSON-serialized `value` at the `key` position of the configuration. + * + * Returns 0 if successful, a negative value otherwise. + */ +ZENOHC_API +int8_t zc_config_insert_json(struct z_config_t config, + const char *key, + const char *value); +/** + * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. + */ +ZENOHC_API +struct z_owned_str_t zc_config_to_string(struct z_config_t config); +/** + * Initialises the zenoh runtime logger. + * + * Note that unless you built zenoh-c with the `logger-autoinit` feature disabled, + * this will be performed automatically by `z_open` and `z_scout`. + */ +ZENOHC_API void zc_init_logger(void); +/** + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + */ +ZENOHC_API +ZCError zc_keyexpr_from_slice(struct z_owned_keyexpr_t *this_, + const char *name, + size_t len); +/** + * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. + * The string is canonized in-place before being passed to keyexpr. + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +ZCError zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, + char *name, + size_t *len); +/** + * Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. + * - any instance of ``**`` may only be lead or followed by ``/``. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API +void zc_keyexpr_from_slice_unchecked(struct z_owned_keyexpr_t *this_, + const char *start, + size_t len); +ZENOHC_API +struct zc_liveliness_declaration_options_t zc_liveliness_declaration_options_default(void); +/** + * Declares a subscriber on liveliness tokens that intersect `key`. + * + * Parameters: + * z_session_t session: The zenoh session. + * z_keyexpr_t key_expr: The key expression to subscribe. + * z_owned_closure_sample_t callback: The callback function that will be called each time a + * liveliness token status changed. + * zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. + * + * Returns: + * A :c:type:`z_owned_subscriber_t`. + * + * To check if the subscription succeeded and if the subscriber is still valid, + * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +ZENOHC_API +ZCError zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct zc_liveliness_declare_subscriber_options_t _options); +/** + * Constructs and declares a liveliness token on the network. + * + * Liveliness token subscribers on an intersecting key expression will receive a PUT sample when connectivity + * is achieved, and a DELETE sample if it's lost. + * + * Passing `NULL` as options is valid and equivalent to a pointer to the default options. + */ +ZENOHC_API +ZCError zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct zc_liveliness_declaration_options_t _options); +/** + * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. + * + * Note that the same "value stealing" tricks apply as with a normal :c:func:`z_get` + * + * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. + */ +ZENOHC_API +ZCError zc_liveliness_get(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_reply_t *callback, + struct zc_liveliness_get_options_t options); +/** + * The gravestone value for `zc_liveliness_get_options_t` + */ +ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_default(void); +ZENOHC_API +struct zc_liveliness_declare_subscriber_options_t zc_liveliness_subscriber_options_default(void); +/** + * Returns `true` unless the token is at its gravestone value. + */ +ZENOHC_API bool zc_liveliness_token_check(const struct zc_owned_liveliness_token_t *this_); +/** + * The gravestone value for liveliness tokens. + */ +ZENOHC_API void zc_liveliness_token_null(struct zc_owned_liveliness_token_t *this_); +/** + * Destroys a liveliness token, notifying subscribers of its destruction. + */ +ZENOHC_API ZCError zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t *this_); +/** + * Creates a new blocking fifo channel, returned as a pair of closures. + * + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, + * which it will then return; or until the `send` closure is dropped and all queries have been consumed, + * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. + */ +ZENOHC_API +struct z_owned_query_channel_t zc_query_fifo_new(size_t bound); +/** + * Creates a new non-blocking fifo channel, returned as a pair of closures. + * + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_query_t` is available, + * which it will then return; or until the `send` closure is dropped and all queries have been consumed, + * at which point it will return an invalidated `z_owned_query_t`, and so will further calls. + */ +ZENOHC_API +struct z_owned_query_channel_t zc_query_non_blocking_fifo_new(size_t bound); +/** + * Creates a new blocking fifo channel, returned as a pair of closures. + * + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, + * which it will then return; or until the `send` closure is dropped and all replies have been consumed, + * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. + */ +ZENOHC_API +struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); +/** + * Creates a new non-blocking fifo channel, returned as a pair of closures. + * + * If `bound` is different from 0, that channel will be bound and apply back-pressure when full. + * + * The `send` end should be passed as callback to a `z_get` call. + * + * The `recv` end is a synchronous closure that will block until either a `z_owned_reply_t` is available, + * which it will then return; or until the `send` closure is dropped and all replies have been consumed, + * at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. + */ +ZENOHC_API +struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); +/** + * Returns `true` if `sample` is valid. + * + * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed + * unless the value has been dropped already. + */ +ZENOHC_API +bool zc_sample_check(const struct zc_owned_sample_t *sample); +/** + * Clone a sample in the cheapest way available. + */ +ZENOHC_API void zc_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); +/** + * Destroy the sample. + */ +ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); +/** + * Borrow the sample, allowing calling its accessor methods. + * + * Calling this function using a dropped sample is undefined behaviour. + */ +ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); +ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); +/** + * Increments the session's reference count, returning a new owning handle. + */ +ZENOHC_API +int8_t zc_session_rcinc(struct z_owned_session_t *dst, + const struct z_owned_session_t *src); +/** + * Calls the closure. Calling an uninitialized closure is a no-op. + */ +ZENOHC_API +void zcu_closure_matching_status_call(const struct zcu_owned_closure_matching_status_t *closure, + const struct zcu_matching_status_t *sample); +/** + * Drops the closure. Droping an uninitialized closure is a no-op. + */ +ZENOHC_API +void zcu_closure_matching_status_drop(struct zcu_owned_closure_matching_status_t *closure); +/** + * Constructs a null safe-to-drop value of 'zcu_owned_closure_matching_status_t' type + */ +ZENOHC_API struct zcu_owned_closure_matching_status_t zcu_closure_matching_status_null(void); +ZENOHC_API enum zcu_locality_t zcu_locality_default(void); +/** + * Register callback for notifying subscribers matching. + */ +ZENOHC_API +ZCError zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, + struct zcu_owned_closure_matching_status_t *callback, + struct zcu_owned_matching_listener_t *this_); +ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); +/** + * Declares a Publication Cache. + * + * Parameters: + * z_session_t session: The zenoh session. + * z_keyexpr_t key_expr: The key expression to publish. + * ze_publication_cache_options_t options: Additional options for the publication_cache. + * + * Returns: + * :c:type:`ze_owned_publication_cache_t`. + * + * + * Example: + * Declaring a publication cache `NULL` for the options: + * + * .. code-block:: C + * + * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), NULL); + * + * is equivalent to initializing and passing the default publication cache options: + * + * .. code-block:: C + * + * ze_publication_cache_options_t opts = ze_publication_cache_options_default(); + * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), &opts); + */ +ZENOHC_API +ZCError ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct ze_publication_cache_options_t options); +/** + * Declares a Querying Subscriber for a given key expression. + * + * Parameters: + * z_session_t session: The zenoh session. + * z_keyexpr_t keyexpr: The key expression to subscribe. + * z_owned_closure_sample_t callback: The callback function that will be called each time a data matching the subscribed expression is received. + * ze_querying_subscriber_options_t options: Additional options for the querying subscriber. + * + * Returns: + * :c:type:`ze_owned_subscriber_t`. + * + * To check if the subscription succeeded and if the querying subscriber is still valid, + * you may use `ze_querying_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + * + * Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * Example: + * Declaring a subscriber passing ``NULL`` for the options: + * + * .. code-block:: C + * + * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, NULL); + * + * is equivalent to initializing and passing the default subscriber options: + * + * .. code-block:: C + * + * z_subscriber_options_t opts = z_subscriber_options_default(); + * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); + */ +ZENOHC_API +ZCError ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct ze_querying_subscriber_options_t options); +/** + * Returns ``true`` if `pub_cache` is valid. + */ +ZENOHC_API bool ze_publication_cache_check(const struct ze_owned_publication_cache_t *this_); +/** + * Constructs a null safe-to-drop value of 'ze_owned_publication_cache_t' type + */ +ZENOHC_API void ze_publication_cache_null(struct ze_owned_publication_cache_t *this_); +/** + * Constructs the default value for :c:type:`ze_publication_cache_options_t`. + */ +ZENOHC_API struct ze_publication_cache_options_t ze_publication_cache_options_default(void); +/** + * Returns ``true`` if `this` is valid. + */ +ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subscriber_t *this_); +/** + * Make a :c:type:`ze_owned_querying_subscriber_t` to perform an additional query on a specified selector. + * The queried samples will be merged with the received publications and made available in the subscriber callback. + */ +ZENOHC_API +ZCError ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, + struct z_keyexpr_t selector, + const struct z_get_options_t *options); +/** + * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. + */ +ZENOHC_API +struct ze_querying_subscriber_t ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); +/** + * Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type + */ +ZENOHC_API void ze_querying_subscriber_null(struct ze_owned_querying_subscriber_t *this_); +/** + * Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. + */ +ZENOHC_API struct ze_querying_subscriber_options_t ze_querying_subscriber_options_default(void); +/** + * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *this_); +/** + * Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. + */ +ZENOHC_API +ZCError ze_undeclare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_); diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 9ef5cb4e1..764cf399a 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -15,3 +15,70 @@ #define ALIGN(n) #define ZENOHC_API #endif +#include +#include +#include +#include +#include +#define DEFAULT_SCOUTING_TIMEOUT 1000 +/** + * An owned zenoh session. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_session_t { + uint8_t _0[8]; +} z_owned_session_t; +typedef struct ALIGN(8) z_query_t { + uint8_t _0[8]; +} z_query_t; +typedef struct ALIGN(8) z_session_t { + uint8_t _0[8]; +} z_session_t; +/** + * An owned zenoh queryable. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_queryable_t { + uint8_t _0[32]; +} z_owned_queryable_t; +/** + * An owned zenoh subscriber. Destroying the subscriber cancels the subscription. + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +typedef struct ALIGN(8) z_owned_subscriber_t { + uint8_t _0[32]; +} z_owned_subscriber_t; +#define Z_OK 0 +#define Z_EINVAL -1 +#define Z_EPARSE -2 +#define Z_EIO -3 +#define Z_ENETWORK -4 +#define Z_EBUSY_MUTEX -16 +#define Z_EINVAL_MUTEX -22 +#define Z_EAGAIN_MUTEX -11 +#define Z_EPOISON_MUTEX -22 +#define Z_EGENERIC INT8_MIN diff --git a/src/commons.rs b/src/commons.rs index fb245e40b..9b8b17c86 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -102,7 +102,7 @@ pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { #[no_mangle] pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { let sample = sample.transmute_ref(); - sample.encoding().transmute_copy() + sample.encoding().transmute_handle() } /// The sample's data, the return value aliases the sample. /// @@ -192,7 +192,7 @@ pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { } pub use crate::opaque_types::z_encoding_t; -decl_transmute_copy!(&'static Encoding, z_encoding_t); +decl_transmute_handle!(Encoding, z_encoding_t); /// An owned payload encoding. /// @@ -233,7 +233,7 @@ pub unsafe extern "C" fn z_encoding_from_str( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - (&Encoding::ZENOH_BYTES).transmute_copy() + (&Encoding::ZENOH_BYTES).transmute_handle() } /// Frees `encoding`, invalidating it for double-drop safety. @@ -254,14 +254,14 @@ pub extern "C" fn z_encoding_check(encoding: &'static z_owned_encoding_t) -> boo #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_loan(encoding: &'static z_owned_encoding_t) -> z_encoding_t { - encoding.transmute_ref().transmute_copy() + encoding.transmute_ref().transmute_handle() } pub use crate::opaque_types::z_owned_value_t; decl_transmute_owned!(Value, z_owned_value_t); pub use crate::opaque_types::z_value_t; -decl_transmute_copy!(&'static Value, z_value_t); +decl_transmute_handle!(Value, z_value_t); #[repr(C)] #[derive(Clone, Copy, Debug)] diff --git a/src/get.rs b/src/get.rs index 9a6855559..c6e6f8b42 100644 --- a/src/get.rs +++ b/src/get.rs @@ -72,7 +72,7 @@ pub unsafe extern "C" fn z_reply_ok(reply: z_reply_t) -> z_sample_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_err(reply: z_reply_t) -> z_value_t { let reply = reply.transmute_ref(); - reply.result().expect_err("Reply does not contain error").transmute_copy() + reply.result().expect_err("Reply does not contain error").transmute_handle() } /// Returns an invalidated :c:type:`z_owned_reply_t`. @@ -151,7 +151,7 @@ pub unsafe extern "C" fn z_get( } else { CStr::from_ptr(parameters).to_str().unwrap() }; - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let mut get = session.get(key_expr.clone().with_parameters(p)); diff --git a/src/info.rs b/src/info.rs index 6a2558a66..c63fe91c0 100644 --- a/src/info.rs +++ b/src/info.rs @@ -1,4 +1,4 @@ -use crate::transmute::TransmuteCopy; +use crate::transmute::{TransmuteCopy, TransmuteFromHandle}; // // Copyright (c) 2017, 2022 ZettaScale Technology. // @@ -35,7 +35,7 @@ impl From<[u8;16]> for z_id_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_info_zid(session: z_session_t) -> z_id_t { - let session = session.transmute_copy(); + let session = session.transmute_ref(); session.info().zid().res_sync().transmute_copy() } @@ -53,7 +53,7 @@ pub unsafe extern "C" fn z_info_peers_zid( ) -> errors::ZCError { let mut closure = z_owned_closure_zid_t::empty(); std::mem::swap(&mut closure, callback); - let session = session.transmute_copy(); + let session = session.transmute_ref(); for id in session.info().peers_zid().res_sync() { z_closure_zid_call(&closure, &id.transmute_copy()); } @@ -74,7 +74,7 @@ pub unsafe extern "C" fn z_info_routers_zid( ) -> errors::ZCError { let mut closure = z_owned_closure_zid_t::empty(); std::mem::swap(&mut closure, callback); - let session = session.transmute_copy(); + let session = session.transmute_ref(); for id in session.info().routers_zid().res_sync() { z_closure_zid_call(&closure, &id.transmute_copy()); } diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 9d4cc194b..0d0c3fbdb 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -390,7 +390,7 @@ pub extern "C" fn z_declare_keyexpr( ) -> ZCError { let this = this.transmute_uninit_ptr(); let key_expr = key_expr.transmute_ref(); - let session = session.transmute_copy(); + let session = session.transmute_ref(); match session.declare_keyexpr(key_expr).res_sync() { Ok(id) => { Inplace::init(this, Some(id.into_owned())); @@ -413,7 +413,7 @@ pub extern "C" fn z_undeclare_keyexpr(session: z_session_t, kexpr: &mut z_owned_ log::debug!("Attempted to undeclare dropped keyexpr"); return i8::MIN; }; - let session = session.transmute_copy(); + let session = session.transmute_ref(); match session.undeclare(kexpr).res() { Ok(()) => errors::Z_OK, Err(e) => { diff --git a/src/liveliness.rs b/src/liveliness.rs index ec50a7798..256002c7c 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -66,7 +66,7 @@ pub extern "C" fn zc_liveliness_declare_token( _options: zc_liveliness_declaration_options_t, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); match session.liveliness().declare_token(key_expr).res() { Ok(token) => { @@ -129,7 +129,7 @@ pub extern "C" fn zc_liveliness_declare_subscriber( _options: zc_liveliness_declare_subscriber_options_t, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let callback = core::mem::replace(callback, z_owned_closure_sample_t::empty()); let key_expr = key_expr.transmute_ref(); match session @@ -177,7 +177,7 @@ pub extern "C" fn zc_liveliness_get( callback: &mut z_owned_closure_reply_t, options: zc_liveliness_get_options_t, ) -> errors::ZCError { - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let callback = core::mem::replace(callback, z_owned_closure_reply_t::empty()); let liveliness: Liveliness<'static> = session.liveliness(); diff --git a/src/payload.rs b/src/payload.rs index 2dd56c7d9..58db5c147 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -72,9 +72,14 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( let len = z_bytes_len(payload); let cstr = z_owned_str_t::preallocate(len); let payload = payload.transmute_ref(); - payload.reader().read(from_raw_parts_mut(cstr._cstr as *mut u8, len)); - Inplace::init(dst, cstr); - errors::Z_OK + if let Err(e) = payload.reader().read(from_raw_parts_mut(cstr._cstr as *mut u8, len)) { + log::error!("Failed to read the payload: {}", e); + Inplace::empty(dst); + errors::Z_EIO + } else { + Inplace::init(dst, cstr); + errors::Z_OK + } } /// Decodes payload into bytes map. @@ -105,9 +110,14 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes( let len = z_bytes_len(payload); let b = z_owned_slice_t::preallocate(len); let payload = payload.transmute_ref(); - payload.reader().read(from_raw_parts_mut(b.start, len)); - Inplace::init(dst, b); - errors::Z_OK + if let Err(e) = payload.reader().read(from_raw_parts_mut(b.start, len)) { + log::error!("Failed to read the payload: {}", e); + Inplace::empty(dst); + errors::Z_EIO + } else { + Inplace::init(dst, b); + errors::Z_OK + } } unsafe impl Send for z_slice_t {} @@ -194,9 +204,8 @@ pub unsafe extern "C" fn z_bytes_reader_null(this: *mut MaybeUninit bool { - let reader = reader.transmute_ref(); - reader.as_ref().is_some() +pub unsafe extern "C" fn z_bytes_reader_check(this: &z_owned_bytes_t_reader_t) -> bool { + this.transmute_ref().is_some() } #[no_mangle] @@ -219,11 +228,11 @@ extern "C" fn z_bytes_reader_loan(reader: &'static z_owned_bytes_t_reader_t) -> #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_read( - reader: z_bytes_reader_t, + this: z_bytes_reader_t, dest: *mut u8, len: usize, ) -> usize { - let reader = reader.transmute_mut(); + let reader = this.transmute_mut(); let buf = unsafe { from_raw_parts_mut(dest, len) }; reader.read(buf).unwrap_or(0) } @@ -234,8 +243,8 @@ pub unsafe extern "C" fn z_bytes_reader_read( /// Return ​0​ upon success, negative error code otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_seek(reader: z_bytes_reader_t, offset: i64, origin: libc::c_int) -> ZCError { - let reader = reader.transmute_mut(); +pub unsafe extern "C" fn z_bytes_reader_seek(this: z_bytes_reader_t, offset: i64, origin: libc::c_int) -> ZCError { + let reader = this.transmute_mut(); let pos = match origin { libc::SEEK_SET => offset.try_into().map(|r| SeekFrom::Start(r)), libc::SEEK_CUR => Ok(SeekFrom::Current(offset)), @@ -252,8 +261,8 @@ pub unsafe extern "C" fn z_bytes_reader_seek(reader: z_bytes_reader_t, offset: i /// Returns read position indicator on success or -1L if failure occurs. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_tell(reader: z_bytes_reader_t) -> i64 { - let reader = reader.transmute_mut(); +pub unsafe extern "C" fn z_bytes_reader_tell(this: z_bytes_reader_t) -> i64 { + let reader = this.transmute_mut(); reader.stream_position().map(|p| p as i64).unwrap_or(-1) } diff --git a/src/publication_cache.rs b/src/publication_cache.rs index dadc91cc3..0868b5ce1 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -91,7 +91,7 @@ pub extern "C" fn ze_declare_publication_cache( options: ze_publication_cache_options_t, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let mut p = session.declare_publication_cache(key_expr); p = p.history(options.history); diff --git a/src/publisher.rs b/src/publisher.rs index 2ebf4c410..274b5a52c 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -67,7 +67,7 @@ pub extern "C" fn z_publisher_options_default() -> z_publisher_options_t { pub use crate::opaque_types::z_owned_publisher_t; decl_transmute_owned!(Option>, z_owned_publisher_t); pub use crate::opaque_types::z_publisher_t; -decl_transmute_copy!(&'static Publisher<'static>, z_publisher_t); +decl_transmute_handle!(Publisher<'static>, z_publisher_t); /// Declares a publisher for the given key expression. /// @@ -111,7 +111,7 @@ pub extern "C" fn z_declare_publisher( this: *mut MaybeUninit, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref().clone().into_owned(); let mut p = session.declare_publisher(key_expr); if let Some(options) = options { @@ -152,7 +152,7 @@ pub extern "C" fn z_publisher_check(pbl: &'static z_owned_publisher_t) -> bool { pub extern "C" fn z_publisher_loan(p: &'static z_owned_publisher_t) -> z_publisher_t { let p = p.transmute_ref(); let p = unwrap_ref_unchecked(p); - p.transmute_copy() + p.transmute_handle() } /// Options passed to the :c:func:`z_publisher_put` function. @@ -197,7 +197,7 @@ pub unsafe extern "C" fn z_publisher_put( payload: &mut z_owned_bytes_t, options: z_publisher_put_options_t, ) -> errors::ZCError { - let publisher = publisher.transmute_copy(); + let publisher = publisher.transmute_ref(); let payload = match payload.transmute_mut().extract() { Some(p) => p, None => { @@ -251,8 +251,7 @@ pub extern "C" fn z_publisher_delete( publisher: z_publisher_t, _options: z_publisher_delete_options_t, ) -> errors::ZCError { - let publisher = publisher.transmute_copy(); - + let publisher = publisher.transmute_ref(); if let Err(e) = publisher.delete().res_sync() { log::error!("{}", e); errors::Z_EGENERIC @@ -265,7 +264,7 @@ pub extern "C" fn z_publisher_delete( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_keyexpr_t { - let publisher = publisher.transmute_copy(); + let publisher = publisher.transmute_ref(); publisher.key_expr().transmute_handle() } @@ -293,7 +292,7 @@ pub extern "C" fn zcu_publisher_matching_listener_callback( let this = this.transmute_uninit_ptr(); let mut closure = zcu_owned_closure_matching_status_t::empty(); std::mem::swap(callback, &mut closure); - let publisher = publisher.transmute_copy(); + let publisher = publisher.transmute_ref(); let listener = publisher .matching_listener() .callback_mut(move |matching_status| { diff --git a/src/put.rs b/src/put.rs index 5457dd522..d9b3a9165 100644 --- a/src/put.rs +++ b/src/put.rs @@ -82,7 +82,7 @@ pub extern "C" fn z_put( payload: &mut z_owned_bytes_t, options: z_put_options_t, ) -> errors::ZCError { - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let payload = match payload.transmute_mut().extract() { Some(p) => p, @@ -144,7 +144,7 @@ pub extern "C" fn z_delete( key_expr: z_keyexpr_t, opts: z_delete_options_t, ) -> errors::ZCError { - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let del = session.delete(key_expr) diff --git a/src/queryable.rs b/src/queryable.rs index 875918cab..f3f9aa6c5 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -146,7 +146,7 @@ pub extern "C" fn z_declare_queryable( let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_query_t::empty(); std::mem::swap(&mut closure, callback); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let keyexpr = key_expr.transmute_ref(); let mut builder = session.declare_queryable(keyexpr); if let Some(options) = options { @@ -275,7 +275,7 @@ pub extern "C" fn z_query_has_attachment(query: z_query_t) -> bool { /// Before calling this funciton, the user must ensure that `z_query_has_value` returns true. #[no_mangle] pub extern "C" fn z_query_value(query: z_query_t) -> z_value_t { - query.transmute_ref().value().expect("Query does not contain a value").transmute_copy() + query.transmute_ref().value().expect("Query does not contain a value").transmute_handle() } /// Gets the attachment to the query by aliasing. diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 4ab406708..ce8bba2f5 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -83,7 +83,7 @@ pub struct ze_querying_subscriber_options_t { #[no_mangle] pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscriber_options_t { ze_querying_subscriber_options_t { - reliability: Reliability::BestEffort.into(), + reliability: Reliability::DEFAULT.into(), allowed_origin: zcu_locality_default(), query_selector: null(), query_target: z_query_target_default(), @@ -136,7 +136,7 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let mut sub = session.declare_subscriber(key_expr.transmute_ref()).querying(); sub = sub .reliability(options.reliability.into()) diff --git a/src/session.rs b/src/session.rs index 86682da16..fb4903bb4 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,7 +12,7 @@ // ZettaScale Zenoh team, // -use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteRef, TransmuteUninitPtr}; +use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}; use crate::{errors, z_owned_config_t, zc_init_logger}; use std::mem::MaybeUninit; use std::sync::Arc; @@ -25,7 +25,7 @@ decl_transmute_owned!(Option>, z_owned_session_t); /// A loaned zenoh session. use crate::opaque_types::z_session_t; -decl_transmute_copy!(&'static Session, z_session_t); +decl_transmute_handle!(Session, z_session_t); /// Returns a :c:type:`z_session_t` loaned from `s`. /// @@ -36,18 +36,18 @@ decl_transmute_copy!(&'static Session, z_session_t); /// attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) /// have been destroyed is UB (likely SEGFAULT) #[no_mangle] -pub extern "C" fn z_session_loan(s: &'static z_owned_session_t) -> z_session_t { - let s = s.transmute_ref(); - let s = unwrap_ref_unchecked(s); - let s = s.as_ref(); - s.transmute_copy() +pub extern "C" fn z_session_loan(this: &'static z_owned_session_t) -> z_session_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + let this = this.as_ref(); + this.transmute_handle() } /// Constructs a null safe-to-drop value of 'z_owned_session_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_session_null(s: *mut MaybeUninit) { - Inplace::empty(s.transmute_uninit_ptr()); +pub extern "C" fn z_session_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); } /// Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. @@ -86,8 +86,8 @@ pub extern "C" fn z_open( /// Returns ``true`` if `session` is valid. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_session_check(session: &z_owned_session_t) -> bool { - session.transmute_ref().is_some() +pub extern "C" fn z_session_check(this: &z_owned_session_t) -> bool { + this.transmute_ref().is_some() } /// Closes a zenoh session. This drops and invalidates `session` for double-drop safety. diff --git a/src/subscriber.rs b/src/subscriber.rs index ceab769cf..f431fdb6c 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -98,7 +98,7 @@ pub struct z_subscriber_options_t { #[no_mangle] pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { z_subscriber_options_t { - reliability: Reliability::BestEffort.into() + reliability: Reliability::DEFAULT.into() } } @@ -145,7 +145,7 @@ pub extern "C" fn z_declare_subscriber( let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); - let session = session.transmute_copy(); + let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let subscriber = session.declare_subscriber(key_expr).callback(move |sample| { From e6497a83ee522ad9a728879bdeb8475c6c6056f9 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 23 Apr 2024 09:39:27 +0200 Subject: [PATCH 56/75] fmt --- src/closures/query_channel.rs | 19 +++++--- src/closures/reply_closure.rs | 10 +---- src/closures/response_channel.rs | 18 +++++--- src/collections.rs | 32 ++++++++----- src/commons.rs | 19 ++++---- src/config.rs | 3 +- src/errors.rs | 2 +- src/get.rs | 40 ++++++++++------- src/info.rs | 6 +-- src/keyexpr.rs | 77 ++++++++++++++++++++------------ src/lib.rs | 2 +- src/liveliness.rs | 25 +++++++---- src/payload.rs | 25 ++++++++--- src/platform/synchronization.rs | 29 +++++++----- src/publication_cache.rs | 13 +++--- src/publisher.rs | 28 +++++------- src/put.rs | 10 ++--- src/queryable.rs | 40 +++++++++++------ src/querying_subscriber.rs | 70 ++++++++++++++++------------- src/scouting.rs | 17 +++++-- src/session.rs | 5 ++- src/subscriber.rs | 23 +++++----- src/transmute.rs | 29 ++++++++---- 23 files changed, 329 insertions(+), 213 deletions(-) diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index 9860e926d..10ba68c0e 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -1,6 +1,12 @@ -use crate::{z_closure_query_drop, z_owned_closure_query_t, z_owned_query_t, z_query_clone, z_query_null, z_query_t}; +use crate::{ + z_closure_query_drop, z_owned_closure_query_t, z_owned_query_t, z_query_clone, z_query_null, + z_query_t, +}; use libc::c_void; -use std::{mem::MaybeUninit, sync::mpsc::{Receiver, TryRecvError}}; +use std::{ + mem::MaybeUninit, + sync::mpsc::{Receiver, TryRecvError}, +}; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// - `this` is a pointer to an arbitrary state. @@ -70,7 +76,6 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver } } - /// Creates a new blocking fifo channel, returned as a pair of closures. /// /// If `bound` is different from 0, that channel will be bound and apply back-pressure when full. @@ -110,8 +115,8 @@ pub unsafe extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned let (send, rx) = get_send_recv_ends(bound); z_owned_query_channel_t { send, - recv: From::from(move |this: *mut MaybeUninit| { - match rx.try_recv() { + recv: From::from( + move |this: *mut MaybeUninit| match rx.try_recv() { Ok(val) => { (*this).write(val); true @@ -124,8 +129,8 @@ pub unsafe extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned z_query_null(this); false } - } - }), + }, + ), } } diff --git a/src/closures/reply_closure.rs b/src/closures/reply_closure.rs index e7fdc721f..d05b63ab3 100644 --- a/src/closures/reply_closure.rs +++ b/src/closures/reply_closure.rs @@ -46,10 +46,7 @@ pub extern "C" fn z_closure_reply_null() -> z_owned_closure_reply_t { } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_reply_call( - closure: &z_owned_closure_reply_t, - reply: z_reply_t, -) { +pub extern "C" fn z_closure_reply_call(closure: &z_owned_closure_reply_t, reply: z_reply_t) { match closure.call { Some(call) => call(reply, closure.context), None => { @@ -66,10 +63,7 @@ pub extern "C" fn z_closure_reply_drop(closure: &mut z_owned_closure_reply_t) { impl From for z_owned_closure_reply_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call( - response: z_reply_t, - this: *mut c_void, - ) { + extern "C" fn call(response: z_reply_t, this: *mut c_void) { let this = unsafe { &*(this as *const F) }; this(response) } diff --git a/src/closures/response_channel.rs b/src/closures/response_channel.rs index 8375a7e5e..e89b509ba 100644 --- a/src/closures/response_channel.rs +++ b/src/closures/response_channel.rs @@ -1,6 +1,12 @@ -use crate::{ z_closure_reply_drop, z_owned_closure_reply_t, z_owned_reply_t, z_reply_clone, z_reply_null, z_reply_t}; +use crate::{ + z_closure_reply_drop, z_owned_closure_reply_t, z_owned_reply_t, z_reply_clone, z_reply_null, + z_reply_t, +}; use libc::c_void; -use std::{mem::MaybeUninit, sync::mpsc::{Receiver, TryRecvError}}; +use std::{ + mem::MaybeUninit, + sync::mpsc::{Receiver, TryRecvError}, +}; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// - `this` is a pointer to an arbitrary state. /// - `call` is the typical callback function. `this` will be passed as its last argument. @@ -107,8 +113,8 @@ pub unsafe extern "C" fn zc_reply_non_blocking_fifo_new(bound: usize) -> z_owned let (send, rx) = get_send_recv_ends(bound); z_owned_reply_channel_t { send, - recv: From::from(move |this: *mut MaybeUninit| { - match rx.try_recv() { + recv: From::from( + move |this: *mut MaybeUninit| match rx.try_recv() { Ok(val) => { (*this).write(val); true @@ -121,8 +127,8 @@ pub unsafe extern "C" fn zc_reply_non_blocking_fifo_new(bound: usize) -> z_owned z_reply_null(this); false } - } - }), + }, + ), } } diff --git a/src/collections.rs b/src/collections.rs index b75ca2d63..6bf5622b5 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -20,7 +20,9 @@ use libc::{c_char, c_void, size_t}; use zenoh::prelude::ZenohId; use crate::errors; -use crate::transmute::{Inplace, InplaceDefault, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}; +use crate::transmute::{ + Inplace, InplaceDefault, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr, +}; /// A contiguous view of bytes owned by some other entity. /// @@ -182,7 +184,7 @@ pub const extern "C" fn z_slice_loan(b: &z_owned_slice_t) -> z_slice_t { } #[no_mangle] -pub extern "C" fn z_slice_clone(b: &z_slice_t, ) -> z_owned_slice_t { +pub extern "C" fn z_slice_clone(b: &z_slice_t) -> z_owned_slice_t { if !z_slice_is_initialized(b) { z_slice_null() } else { @@ -244,7 +246,6 @@ impl From<&[u8]> for z_slice_t { impl InplaceDefault for z_owned_slice_t {} - /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` /// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with /// `z_check` and `z_str_check` correspondently @@ -331,7 +332,10 @@ pub use crate::opaque_types::z_slice_map_t; pub type ZHashMap = HashMap, Cow<'static, [u8]>>; pub use crate::opaque_types::z_config_t; -decl_transmute_handle!(HashMap, Cow<'static, [u8]>>, z_slice_map_t); +decl_transmute_handle!( + HashMap, Cow<'static, [u8]>>, + z_slice_map_t +); pub use crate::opaque_types::z_owned_config_t; decl_transmute_owned!(Option, z_owned_slice_map_t); @@ -390,7 +394,11 @@ pub type z_slice_map_iter_body_t = extern "C" fn(key: z_slice_t, value: z_slice_t, context: *mut c_void) -> bool; #[no_mangle] -pub extern "C" fn z_slice_map_iterate(this: &z_slice_map_t, body: z_slice_map_iter_body_t, context: *mut c_void) { +pub extern "C" fn z_slice_map_iterate( + this: &z_slice_map_t, + body: z_slice_map_iter_body_t, + context: *mut c_void, +) { let this = this.transmute_ref(); for (key, value) in this { if !body(key.as_ref().into(), value.as_ref().into(), context) { @@ -407,8 +415,10 @@ pub extern "C" fn z_slice_map_get(this: z_slice_map_t, key: z_slice_t) -> z_slic return z_slice_empty(); } let m = this.transmute_mut(); - let key = key.as_slice().unwrap(); - m.get(key).map(|s| s.as_ref().into()).unwrap_or( z_slice_empty()) + let key = key.as_slice().unwrap(); + m.get(key) + .map(|s| s.as_ref().into()) + .unwrap_or(z_slice_empty()) } /// Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. @@ -421,8 +431,7 @@ pub extern "C" fn z_slice_map_insert_by_copy( value: z_slice_t, ) -> errors::ZCError { let this = this.transmute_mut(); - if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) - { + if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())); errors::Z_OK } else { @@ -442,11 +451,10 @@ pub extern "C" fn z_slice_map_insert_by_alias( value: z_slice_t, ) -> errors::ZCError { let this = this.transmute_mut(); - if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) - { + if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { this.insert(Cow::Borrowed(key), Cow::Borrowed(value)); errors::Z_OK } else { errors::Z_EINVAL } -} \ No newline at end of file +} diff --git a/src/commons.rs b/src/commons.rs index 9b8b17c86..8e2b95cff 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -23,8 +23,8 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; -use crate::z_id_t; use crate::z_bytes_t; +use crate::z_id_t; use crate::z_keyexpr_t; use libc::{c_char, c_ulong}; use unwrap_infallible::UnwrapInfallible; @@ -83,7 +83,6 @@ pub unsafe extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t timestamp.transmute_copy().get_id().to_le_bytes().into() } - /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. @@ -119,10 +118,13 @@ pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { sample.kind().into() } /// The samples timestamp -/// +/// /// Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. #[no_mangle] -pub extern "C" fn z_sample_timestamp(sample: &z_sample_t, timestamp_out: &mut z_timestamp_t) -> bool { +pub extern "C" fn z_sample_timestamp( + sample: &z_sample_t, + timestamp_out: &mut z_timestamp_t, +) -> bool { let sample = sample.transmute_ref(); if let Some(t) = sample.timestamp() { *timestamp_out = t.transmute_copy(); @@ -147,7 +149,10 @@ pub extern "C" fn z_sample_has_attachment(sample: z_sample_t) -> bool { #[no_mangle] pub extern "C" fn z_sample_attachment(sample: z_sample_t) -> z_bytes_t { let sample = sample.transmute_ref(); - sample.attachment().expect("Sample does not have an attachment").transmute_handle() + sample + .attachment() + .expect("Sample does not have an attachment") + .transmute_handle() } pub use crate::opaque_types::zc_owned_sample_t; @@ -257,7 +262,6 @@ pub extern "C" fn z_encoding_loan(encoding: &'static z_owned_encoding_t) -> z_en encoding.transmute_ref().transmute_handle() } - pub use crate::opaque_types::z_owned_value_t; decl_transmute_owned!(Value, z_owned_value_t); pub use crate::opaque_types::z_value_t; @@ -326,7 +330,6 @@ pub extern "C" fn zcu_reply_keyexpr_default() -> zcu_reply_keyexpr_t { ReplyKeyExpr::default().into() } - /// The Queryables that should be target of a :c:func:`z_get`. /// /// - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. @@ -503,4 +506,4 @@ impl From for CongestionControl { z_congestion_control_t::DROP => CongestionControl::Drop, } } -} \ No newline at end of file +} diff --git a/src/config.rs b/src/config.rs index 23ef45a88..f30abd036 100644 --- a/src/config.rs +++ b/src/config.rs @@ -18,7 +18,8 @@ use zenoh::config::{Config, ValidatedMap, WhatAmI}; use crate::errors::{ZCError, Z_EPARSE}; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, + TransmuteUninitPtr, }; use crate::{errors, z_owned_str_t, z_str_null}; diff --git a/src/errors.rs b/src/errors.rs index 298752442..72448026a 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -9,4 +9,4 @@ pub const Z_EBUSY_MUTEX: ZCError = -16; pub const Z_EINVAL_MUTEX: ZCError = -22; pub const Z_EAGAIN_MUTEX: ZCError = -11; pub const Z_EPOISON_MUTEX: ZCError = -22; // same as Z_EINVAL_MUTEX -pub const Z_EGENERIC: ZCError = i8::MIN; \ No newline at end of file +pub const Z_EGENERIC: ZCError = i8::MIN; diff --git a/src/get.rs b/src/get.rs index c6e6f8b42..d72471e1b 100644 --- a/src/get.rs +++ b/src/get.rs @@ -13,13 +13,13 @@ // use libc::c_char; -use zenoh::sample::SampleBuilderTrait; -use zenoh::sample::ValueBuilderTrait; +use std::ffi::CStr; use std::mem::MaybeUninit; use std::ptr::null_mut; -use std::ffi::CStr; +use zenoh::sample::SampleBuilderTrait; +use zenoh::sample::ValueBuilderTrait; -use zenoh::prelude::{ConsolidationMode, QueryTarget, Mode, QueryConsolidation, Reply}; +use zenoh::prelude::{ConsolidationMode, Mode, QueryConsolidation, QueryTarget, Reply}; use crate::errors; use crate::transmute::Inplace; @@ -29,15 +29,12 @@ use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; use crate::z_consolidation_mode_t; +use crate::z_owned_bytes_t; use crate::z_owned_encoding_t; use crate::z_query_target_t; use crate::z_sample_t; -use crate::z_owned_bytes_t; use crate::z_value_t; -use crate::{ - z_closure_reply_call, z_keyexpr_t, - z_owned_closure_reply_t, z_session_t, -}; +use crate::{z_closure_reply_call, z_keyexpr_t, z_owned_closure_reply_t, z_session_t}; use zenoh::prelude::SyncResolve; pub use crate::opaque_types::z_owned_reply_t; @@ -62,7 +59,10 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: z_reply_t) -> bool { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_ok(reply: z_reply_t) -> z_sample_t { let reply = reply.transmute_ref(); - reply.result().expect("Reply does not contain a sample").transmute_handle() + reply + .result() + .expect("Reply does not contain a sample") + .transmute_handle() } /// Yields the contents of the reply by asserting it indicates a failure. @@ -72,7 +72,10 @@ pub unsafe extern "C" fn z_reply_ok(reply: z_reply_t) -> z_sample_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_reply_err(reply: z_reply_t) -> z_value_t { let reply = reply.transmute_ref(); - reply.result().expect_err("Reply does not contain error").transmute_handle() + reply + .result() + .expect_err("Reply does not contain error") + .transmute_handle() } /// Returns an invalidated :c:type:`z_owned_reply_t`. @@ -89,7 +92,10 @@ pub extern "C" fn z_reply_null(this: *mut MaybeUninit) { #[no_mangle] pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: z_reply_t) { - Inplace::init(this.transmute_uninit_ptr(), Some(reply.transmute_ref().clone())); + Inplace::init( + this.transmute_uninit_ptr(), + Some(reply.transmute_ref().clone()), + ); } /// Options passed to the :c:func:`z_get` function. @@ -169,12 +175,12 @@ pub unsafe extern "C" fn z_get( get = get.attachment(attachment); } - get = get.consolidation(options.consolidation) - .timeout(std::time::Duration::from_millis(options.timeout_ms)) - .target(options.target.into()); + get = get + .consolidation(options.consolidation) + .timeout(std::time::Duration::from_millis(options.timeout_ms)) + .target(options.target.into()); match get - .callback(move |response| { - z_closure_reply_call(&closure, response.transmute_handle()) }) + .callback(move |response| z_closure_reply_call(&closure, response.transmute_handle())) .res_sync() { Ok(()) => errors::Z_OK, diff --git a/src/info.rs b/src/info.rs index c63fe91c0..c2604d84a 100644 --- a/src/info.rs +++ b/src/info.rs @@ -12,8 +12,8 @@ use crate::transmute::{TransmuteCopy, TransmuteFromHandle}; // Contributors: // ZettaScale Zenoh team, // -use std::mem::MaybeUninit; use crate::{errors, z_closure_zid_call, z_owned_closure_zid_t, z_session_t}; +use std::mem::MaybeUninit; use zenoh::config::ZenohId; use zenoh::prelude::sync::SyncResolve; use zenoh::session::SessionDeclarations; @@ -21,8 +21,8 @@ use zenoh::session::SessionDeclarations; pub use crate::opaque_types::z_id_t; decl_transmute_copy!(ZenohId, z_id_t); -impl From<[u8;16]> for z_id_t { - fn from(value: [u8;16]) -> Self { +impl From<[u8; 16]> for z_id_t { + fn from(value: [u8; 16]) -> Self { unsafe { std::mem::transmute(value) } } } diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 0d0c3fbdb..e64933366 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -24,15 +24,15 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; -use crate::z_slice_t; use crate::z_owned_str_t; use crate::z_session_t; +use crate::z_slice_t; use libc::c_char; +use std::error::Error; use zenoh::core::SyncResolve; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::KeyExpr; -use std::error::Error; pub use crate::opaque_types::z_owned_keyexpr_t; decl_transmute_owned!(Option>, z_owned_keyexpr_t); @@ -44,7 +44,11 @@ pub extern "C" fn z_keyexpr_null(this: *mut MaybeUninit) { Inplace::empty(this.transmute_uninit_ptr()); } -fn keyexpr_create_inner(name: &'static mut str, should_auto_canonize: bool, should_copy: bool) -> Result, Box> { +fn keyexpr_create_inner( + name: &'static mut str, + should_auto_canonize: bool, + should_copy: bool, +) -> Result, Box> { if should_copy { let s = name.to_owned(); match should_auto_canonize { @@ -61,17 +65,17 @@ fn keyexpr_create_inner(name: &'static mut str, should_auto_canonize: bool, shou #[allow(clippy::missing_safety_doc)] #[no_mangle] -unsafe fn keyexpr_create(name: &'static mut [u8], should_auto_canonize: bool, should_copy: bool) -> Result, errors::ZCError> { +unsafe fn keyexpr_create( + name: &'static mut [u8], + should_auto_canonize: bool, + should_copy: bool, +) -> Result, errors::ZCError> { match std::str::from_utf8_mut(name) { - Ok(name) => { - match keyexpr_create_inner(name, should_auto_canonize, should_copy) { - Ok(v) => { - Ok(v) - } - Err(e) => { - log::error!("Couldn't construct a keyexpr: {}", e); - Err(errors::Z_EINVAL) - } + Ok(name) => match keyexpr_create_inner(name, should_auto_canonize, should_copy) { + Ok(v) => Ok(v), + Err(e) => { + log::error!("Couldn't construct a keyexpr: {}", e); + Err(errors::Z_EINVAL) } }, Err(e) => { @@ -80,8 +84,6 @@ unsafe fn keyexpr_create(name: &'static mut [u8], should_auto_canonize: bool, sh } } } - - /// Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. #[allow(clippy::missing_safety_doc)] @@ -99,7 +101,7 @@ pub unsafe extern "C" fn z_keyexpr_new( Ok(ke) => { Inplace::init(this, Some(ke)); errors::Z_OK - }, + } Err(e) => { Inplace::empty(this); e @@ -123,7 +125,7 @@ pub unsafe extern "C" fn z_keyexpr_new_autocanonize( Ok(ke) => { Inplace::init(this, Some(ke)); errors::Z_OK - }, + } Err(e) => { Inplace::empty(this); e @@ -219,7 +221,7 @@ pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) Ok(ke) => { *len = ke.len(); errors::Z_OK - }, + } Err(e) => e, } } @@ -227,19 +229,23 @@ pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) /// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn zc_keyexpr_from_slice(this: *mut MaybeUninit, name: *const c_char, len: usize) -> ZCError { +pub unsafe extern "C" fn zc_keyexpr_from_slice( + this: *mut MaybeUninit, + name: *const c_char, + len: usize, +) -> ZCError { let this = this.transmute_uninit_ptr(); if name.is_null() { Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, len); - + match keyexpr_create(name, false, false) { Ok(ke) => { Inplace::init(this, Some(ke)); errors::Z_OK - }, + } Err(e) => { Inplace::empty(this); e @@ -263,13 +269,13 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); - + match keyexpr_create(name, true, false) { Ok(ke) => { *len = ke.len(); Inplace::init(this, Some(ke)); errors::Z_OK - }, + } Err(e) => { Inplace::empty(this); e @@ -281,7 +287,10 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr(this: *mut MaybeUninit, name: *const c_char) -> ZCError { +pub unsafe extern "C" fn z_keyexpr( + this: *mut MaybeUninit, + name: *const c_char, +) -> ZCError { if name.is_null() { Inplace::empty(this.transmute_uninit_ptr()); return errors::Z_EINVAL; @@ -296,7 +305,10 @@ pub unsafe extern "C" fn z_keyexpr(this: *mut MaybeUninit, na /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_autocanonize(this: *mut MaybeUninit, name: *mut c_char) -> ZCError { +pub unsafe extern "C" fn z_keyexpr_autocanonize( + this: *mut MaybeUninit, + name: *mut c_char, +) -> ZCError { if name.is_null() { Inplace::empty(this.transmute_uninit_ptr()); return errors::Z_EINVAL; @@ -343,7 +355,10 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_unchecked(this: *mut MaybeUninit, name: *const c_char) { +pub unsafe extern "C" fn z_keyexpr_unchecked( + this: *mut MaybeUninit, + name: *const c_char, +) { zc_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) } @@ -364,7 +379,7 @@ pub extern "C" fn z_keyexpr_as_bytes(ke: z_keyexpr_t) -> z_slice_t { let ke = ke.transmute_ref(); z_slice_t { start: ke.as_ptr(), - len: ke.len() + len: ke.len(), } } @@ -465,7 +480,7 @@ pub unsafe extern "C" fn z_keyexpr_concat( left: z_keyexpr_t, right_start: *const c_char, right_len: usize, - this: *mut MaybeUninit + this: *mut MaybeUninit, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); let left = left.transmute_ref(); @@ -500,7 +515,11 @@ pub unsafe extern "C" fn z_keyexpr_concat( #[no_mangle] /// Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. /// In case of error, the return value will be set to its invalidated state. -pub extern "C" fn z_keyexpr_join(left: z_keyexpr_t, right: z_keyexpr_t, this: *mut MaybeUninit) -> errors::ZCError { +pub extern "C" fn z_keyexpr_join( + left: z_keyexpr_t, + right: z_keyexpr_t, + this: *mut MaybeUninit, +) -> errors::ZCError { let left = left.transmute_ref(); let right = right.transmute_ref(); let this = this.transmute_uninit_ptr(); diff --git a/src/lib.rs b/src/lib.rs index 6e6f5843e..ed883ca71 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,8 +59,8 @@ pub use liveliness::*; mod publication_cache; pub use publication_cache::*; mod querying_subscriber; -pub use querying_subscriber::*; pub use platform::*; +pub use querying_subscriber::*; pub mod platform; // #[cfg(feature = "shared-memory")] // mod shm; diff --git a/src/liveliness.rs b/src/liveliness.rs index 256002c7c..7e9342677 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -15,17 +15,24 @@ use std::mem::MaybeUninit; use zenoh::prelude::SyncResolve; use zenoh::{ - liveliness::{Liveliness, LivelinessToken}, prelude::SessionDeclarations + liveliness::{Liveliness, LivelinessToken}, + prelude::SessionDeclarations, }; use crate::transmute::TransmuteIntoHandle; use crate::{ - errors, transmute::{Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}, z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, z_owned_closure_reply_t, z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t + errors, + transmute::{Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}, + z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, z_owned_closure_reply_t, + z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t, }; -use crate::opaque_types::zc_owned_liveliness_token_t; use crate::opaque_types::zc_liveliness_token_t; -decl_transmute_owned!(Option>, zc_owned_liveliness_token_t); +use crate::opaque_types::zc_owned_liveliness_token_t; +decl_transmute_owned!( + Option>, + zc_owned_liveliness_token_t +); decl_transmute_handle!(LivelinessToken<'static>, zc_liveliness_token_t); /// The gravestone value for liveliness tokens. @@ -47,8 +54,8 @@ pub struct zc_liveliness_declaration_options_t { } #[no_mangle] -pub extern "C" fn zc_liveliness_declaration_options_default( -) -> zc_liveliness_declaration_options_t { +pub extern "C" fn zc_liveliness_declaration_options_default() -> zc_liveliness_declaration_options_t +{ zc_liveliness_declaration_options_t { _dummy: 0 } } @@ -72,7 +79,7 @@ pub extern "C" fn zc_liveliness_declare_token( Ok(token) => { Inplace::init(this, Some(token)); errors::Z_OK - }, + } Err(e) => { log::error!("Failed to undeclare token: {e}"); Inplace::empty(this); @@ -83,7 +90,9 @@ pub extern "C" fn zc_liveliness_declare_token( /// Destroys a liveliness token, notifying subscribers of its destruction. #[no_mangle] -pub extern "C" fn zc_liveliness_undeclare_token(this: &mut zc_owned_liveliness_token_t) -> errors::ZCError { +pub extern "C" fn zc_liveliness_undeclare_token( + this: &mut zc_owned_liveliness_token_t, +) -> errors::ZCError { let this = this.transmute_mut(); if let Some(token) = this.extract().take() { if let Err(e) = token.undeclare().res() { diff --git a/src/payload.rs b/src/payload.rs index 58db5c147..194d66cc8 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,8 +1,11 @@ use crate::errors::{self, ZCError}; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, + TransmuteUninitPtr, +}; +use crate::{ + z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, ZHashMap, }; -use crate::{z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, ZHashMap}; use core::slice; use std::any::Any; use std::io::{Read, Seek, SeekFrom}; @@ -72,7 +75,10 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( let len = z_bytes_len(payload); let cstr = z_owned_str_t::preallocate(len); let payload = payload.transmute_ref(); - if let Err(e) = payload.reader().read(from_raw_parts_mut(cstr._cstr as *mut u8, len)) { + if let Err(e) = payload + .reader() + .read(from_raw_parts_mut(cstr._cstr as *mut u8, len)) + { log::error!("Failed to read the payload: {}", e); Inplace::empty(dst); errors::Z_EIO @@ -243,17 +249,23 @@ pub unsafe extern "C" fn z_bytes_reader_read( /// Return ​0​ upon success, negative error code otherwise. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_seek(this: z_bytes_reader_t, offset: i64, origin: libc::c_int) -> ZCError { +pub unsafe extern "C" fn z_bytes_reader_seek( + this: z_bytes_reader_t, + offset: i64, + origin: libc::c_int, +) -> ZCError { let reader = this.transmute_mut(); let pos = match origin { libc::SEEK_SET => offset.try_into().map(|r| SeekFrom::Start(r)), libc::SEEK_CUR => Ok(SeekFrom::Current(offset)), libc::SEEK_END => Ok(SeekFrom::End(offset)), - _ => { return errors::Z_EINVAL; } + _ => { + return errors::Z_EINVAL; + } }; match pos.map(|p| reader.seek(p)) { Ok(_) => 0, - Err(_) => errors::Z_EINVAL + Err(_) => errors::Z_EINVAL, } } @@ -265,4 +277,3 @@ pub unsafe extern "C" fn z_bytes_reader_tell(this: z_bytes_reader_t) -> i64 { let reader = this.transmute_mut(); reader.stream_position().map(|p| p as i64).unwrap_or(-1) } - diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index fa6523128..e592c4166 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -1,17 +1,27 @@ use std::{ - mem::MaybeUninit, sync::{Condvar, Mutex, MutexGuard}, thread::{self, JoinHandle} + mem::MaybeUninit, + sync::{Condvar, Mutex, MutexGuard}, + thread::{self, JoinHandle}, }; use libc::c_void; -use crate::{errors, transmute::{unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}}; -pub use crate::opaque_types::z_owned_mutex_t; pub use crate::opaque_types::z_mutex_t; +pub use crate::opaque_types::z_owned_mutex_t; +use crate::{ + errors, + transmute::{ + unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, + TransmuteUninitPtr, + }, +}; -decl_transmute_owned!(Option<(Mutex<()>, Option>)>, z_owned_mutex_t); +decl_transmute_owned!( + Option<(Mutex<()>, Option>)>, + z_owned_mutex_t +); decl_transmute_handle!((Mutex<()>, Option>), z_mutex_t); - #[no_mangle] pub extern "C" fn z_mutex_init(this: *mut MaybeUninit) -> errors::ZCError { let this = this.transmute_uninit_ptr(); @@ -37,7 +47,6 @@ pub extern "C" fn z_mutex_loan(this: &z_owned_mutex_t) -> z_mutex_t { this.transmute_handle() } - #[no_mangle] pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::ZCError { let this = this.transmute_mut(); @@ -81,9 +90,8 @@ pub unsafe extern "C" fn z_mutex_try_lock(this: z_mutex_t) -> errors::ZCError { errors::Z_OK } - -pub use crate::opaque_types::z_owned_condvar_t; pub use crate::opaque_types::z_condvar_t; +pub use crate::opaque_types::z_owned_condvar_t; decl_transmute_owned!(Option, z_owned_condvar_t); decl_transmute_handle!(Condvar, z_condvar_t); @@ -181,7 +189,6 @@ pub extern "C" fn z_task_check(this: &z_owned_task_t) -> bool { this.transmute_ref().is_some() } - struct FunArgPair { fun: unsafe extern "C" fn(arg: *mut c_void), arg: *mut c_void, @@ -209,8 +216,8 @@ pub unsafe extern "C" fn z_task_init( match thread::Builder::new().spawn(move || fun_arg_pair.call()) { Ok(join_handle) => { Inplace::init(this, Some(join_handle)); - }, + } Err(_) => return errors::Z_EAGAIN_MUTEX, } errors::Z_OK -} \ No newline at end of file +} diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 0868b5ce1..2f6be1d73 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -13,15 +13,15 @@ // use std::mem::MaybeUninit; -use zenoh::prelude::SyncResolve; use std::ptr::null; +use zenoh::prelude::SyncResolve; use zenoh_ext::SessionExt; -use crate::transmute::{Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}; -use crate::{ - errors, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t +use crate::transmute::{ + Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr, }; +use crate::{errors, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t}; /// Options passed to the :c:func:`ze_declare_publication_cache` function. /// @@ -55,7 +55,10 @@ pub extern "C" fn ze_publication_cache_options_default() -> ze_publication_cache pub use crate::opaque_types::ze_owned_publication_cache_t; pub use crate::opaque_types::ze_publication_cache_t; -decl_transmute_owned!(Option>, ze_owned_publication_cache_t); +decl_transmute_owned!( + Option>, + ze_owned_publication_cache_t +); decl_transmute_handle!(zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); /// Declares a Publication Cache. diff --git a/src/publisher.rs b/src/publisher.rs index 274b5a52c..dd6012e51 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -31,18 +31,11 @@ use zenoh::publication::CongestionControl; use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; -use zenoh::{ - prelude::Priority, - publication::MatchingListener, - publication::Publisher, -}; +use zenoh::{prelude::Priority, publication::MatchingListener, publication::Publisher}; use zenoh::prelude::SyncResolve; -use crate::{ - z_congestion_control_t, z_keyexpr_t, - z_priority_t, z_session_t, z_owned_bytes_t -}; +use crate::{z_congestion_control_t, z_keyexpr_t, z_owned_bytes_t, z_priority_t, z_session_t}; /// Options passed to the :c:func:`z_declare_publisher` function. /// @@ -205,11 +198,11 @@ pub unsafe extern "C" fn z_publisher_put( return errors::Z_EINVAL; } }; - + let mut put = publisher.put(payload); if !options.encoding.is_null() { - let encoding = unsafe{ *options.encoding }.transmute_mut().extract(); + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); put = put.encoding(encoding); }; if !options.attachment.is_null() { @@ -252,7 +245,7 @@ pub extern "C" fn z_publisher_delete( _options: z_publisher_delete_options_t, ) -> errors::ZCError { let publisher = publisher.transmute_ref(); - if let Err(e) = publisher.delete().res_sync() { + if let Err(e) = publisher.delete().res_sync() { log::error!("{}", e); errors::Z_EGENERIC } else { @@ -269,7 +262,10 @@ pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_keyexpr_t { } pub use crate::opaque_types::zcu_owned_matching_listener_t; -decl_transmute_owned!(Option>, zcu_owned_matching_listener_t); +decl_transmute_owned!( + Option>, + zcu_owned_matching_listener_t +); /// A struct that indicates if there exist Subscribers matching the Publisher's key expression. /// @@ -287,7 +283,7 @@ pub struct zcu_matching_status_t { pub extern "C" fn zcu_publisher_matching_listener_callback( publisher: z_publisher_t, callback: &mut zcu_owned_closure_matching_status_t, - this: *mut MaybeUninit + this: *mut MaybeUninit, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); let mut closure = zcu_owned_closure_matching_status_t::empty(); @@ -306,11 +302,11 @@ pub extern "C" fn zcu_publisher_matching_listener_callback( Ok(_) => { Inplace::empty(this); errors::Z_OK - }, + } Err(e) => { log::error!("{}", e); errors::Z_EGENERIC - } + } } } diff --git a/src/put.rs b/src/put.rs index d9b3a9165..a4c93b9b9 100644 --- a/src/put.rs +++ b/src/put.rs @@ -91,11 +91,11 @@ pub extern "C" fn z_put( return errors::Z_EINVAL; } }; - + let mut put = session.put(key_expr, payload); if !options.encoding.is_null() { - let encoding = unsafe{ *options.encoding }.transmute_mut().extract(); + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); put = put.encoding(encoding); }; if !options.attachment.is_null() { @@ -146,11 +146,11 @@ pub extern "C" fn z_delete( ) -> errors::ZCError { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); - let del - = session.delete(key_expr) + let del = session + .delete(key_expr) .congestion_control(opts.congestion_control.into()) .priority(opts.priority.into()); - + match del.res_sync() { Err(e) => { log::error!("{}", e); diff --git a/src/queryable.rs b/src/queryable.rs index f3f9aa6c5..ecd052253 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -11,19 +11,23 @@ // Contributors: // ZettaScale Zenoh team, // -use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}; +use crate::transmute::{ + unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteIntoHandle, + TransmuteRef, TransmuteUninitPtr, +}; use crate::{ - errors, z_slice_t, z_closure_query_call, z_keyexpr_t,z_owned_bytes_t, z_owned_closure_query_t, z_owned_encoding_t, z_session_t, z_value_t, z_bytes_t + errors, z_bytes_t, z_closure_query_call, z_keyexpr_t, z_owned_bytes_t, z_owned_closure_query_t, + z_owned_encoding_t, z_session_t, z_slice_t, z_value_t, }; -use zenoh::sample::{SampleBuilderTrait, ValueBuilderTrait}; use std::mem::MaybeUninit; use std::ptr::null_mut; use zenoh::prelude::SessionDeclarations; -use zenoh::prelude::{Query, Queryable}; use zenoh::prelude::SyncResolve; +use zenoh::prelude::{Query, Queryable}; +use zenoh::sample::{SampleBuilderTrait, ValueBuilderTrait}; pub use crate::opaque_types::z_owned_queryable_t; -decl_transmute_owned!(Option>, z_owned_queryable_t); +decl_transmute_owned!(Option>, z_owned_queryable_t); /// Constructs a null safe-to-drop value of 'z_owned_queryable_t' type #[no_mangle] @@ -141,7 +145,7 @@ pub extern "C" fn z_declare_queryable( key_expr: z_keyexpr_t, callback: &mut z_owned_closure_query_t, options: Option<&z_queryable_options_t>, - this: *mut MaybeUninit + this: *mut MaybeUninit, ) -> errors::ZCError { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_query_t::empty(); @@ -163,7 +167,7 @@ pub extern "C" fn z_declare_queryable( Err(e) => { log::error!("{}", e); errors::Z_EGENERIC - } + } } } @@ -201,7 +205,7 @@ pub extern "C" fn z_queryable_check(qable: &z_owned_queryable_t) -> bool { /// key_expr: The key of this reply. /// payload: The value of this reply. /// options: The options of this reply. -/// +/// /// The payload and all owned options fields are consumed upon function return. #[allow(clippy::missing_safety_doc)] #[no_mangle] @@ -213,7 +217,7 @@ pub unsafe extern "C" fn z_query_reply( ) -> errors::ZCError { let query = query.transmute_ref(); let key_expr = key_expr.transmute_ref(); - + let payload = match payload.transmute_mut().extract() { Some(p) => p, None => { @@ -221,15 +225,15 @@ pub unsafe extern "C" fn z_query_reply( return errors::Z_EINVAL; } }; - + let mut reply = query.reply(key_expr, payload); if !options.encoding.is_null() { - let encoding = unsafe{ *options.encoding }.transmute_mut().extract(); + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); reply = reply.encoding(encoding); }; if !options.attachment.is_null() { - let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); reply = reply.attachment(attachment); } @@ -275,7 +279,11 @@ pub extern "C" fn z_query_has_attachment(query: z_query_t) -> bool { /// Before calling this funciton, the user must ensure that `z_query_has_value` returns true. #[no_mangle] pub extern "C" fn z_query_value(query: z_query_t) -> z_value_t { - query.transmute_ref().value().expect("Query does not contain a value").transmute_handle() + query + .transmute_ref() + .value() + .expect("Query does not contain a value") + .transmute_handle() } /// Gets the attachment to the query by aliasing. @@ -283,5 +291,9 @@ pub extern "C" fn z_query_value(query: z_query_t) -> z_value_t { /// Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. #[no_mangle] pub extern "C" fn z_query_attachment(query: z_query_t) -> z_bytes_t { - query.transmute_ref().attachment().expect("Query does not contain an attachment").transmute_handle() + query + .transmute_ref() + .attachment() + .expect("Query does not contain an attachment") + .transmute_handle() } diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index ce8bba2f5..e69f0e0f7 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -34,16 +34,22 @@ use crate::transmute::TransmuteUninitPtr; use crate::z_keyexpr_t; use crate::z_owned_closure_sample_t; use crate::z_reliability_t; -use crate::{z_closure_sample_call, z_get_options_t, - z_query_consolidation_none, z_query_consolidation_t, +use crate::{ + z_closure_sample_call, z_get_options_t, z_query_consolidation_none, z_query_consolidation_t, z_query_target_default, z_query_target_t, z_session_t, zcu_locality_default, zcu_locality_t, - zcu_reply_keyexpr_default, zcu_reply_keyexpr_t + zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, }; use crate::opaque_types::ze_owned_querying_subscriber_t; use crate::opaque_types::ze_querying_subscriber_t; -decl_transmute_owned!(Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t); -decl_transmute_handle!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_querying_subscriber_t); +decl_transmute_owned!( + Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, + ze_owned_querying_subscriber_t +); +decl_transmute_handle!( + (zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), + ze_querying_subscriber_t +); /// Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type #[no_mangle] @@ -137,7 +143,9 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); let session = session.transmute_ref(); - let mut sub = session.declare_subscriber(key_expr.transmute_ref()).querying(); + let mut sub = session + .declare_subscriber(key_expr.transmute_ref()) + .querying(); sub = sub .reliability(options.reliability.into()) .allowed_origin(options.allowed_origin.into()) @@ -149,16 +157,13 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( sub = sub.query_selector(query_selector) } if options.query_timeout_ms != 0 { - sub = sub - .query_timeout(std::time::Duration::from_millis(options.query_timeout_ms)); + sub = sub.query_timeout(std::time::Duration::from_millis(options.query_timeout_ms)); } - let sub = sub - .callback(move |sample| { + let sub = sub.callback(move |sample| { let sample = sample.transmute_handle(); z_closure_sample_call(&closure, sample); }); - match sub.res() - { + match sub.res() { Ok(sub) => { Inplace::init(this, Some((sub, session))); errors::Z_OK @@ -184,21 +189,22 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( let sub = sub.transmute_ref(); let session = sub.1; let selector = selector.transmute_ref().clone(); - if let Err(e) = sub.0 - .fetch({ - let selector = KeyExpr::try_from(selector).unwrap(); - move |cb| match options { - Some(options) => session - .get(selector) - .target(options.target.into()) - .consolidation(options.consolidation) - .timeout(std::time::Duration::from_millis(options.timeout_ms)) - .callback(cb) - .res_sync(), - None => session.get(selector).callback(cb).res_sync(), - } - }) - .res() + if let Err(e) = sub + .0 + .fetch({ + let selector = KeyExpr::try_from(selector).unwrap(); + move |cb| match options { + Some(options) => session + .get(selector) + .target(options.target.into()) + .consolidation(options.consolidation) + .timeout(std::time::Duration::from_millis(options.timeout_ms)) + .callback(cb) + .res_sync(), + None => session.get(selector).callback(cb).res_sync(), + } + }) + .res() { log::debug!("{}", e); return errors::Z_EGENERIC; @@ -209,11 +215,13 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( /// Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn ze_undeclare_querying_subscriber(this: &mut ze_owned_querying_subscriber_t) -> errors::ZCError { +pub extern "C" fn ze_undeclare_querying_subscriber( + this: &mut ze_owned_querying_subscriber_t, +) -> errors::ZCError { if let Some(s) = this.transmute_mut().extract().take() { if let Err(e) = s.0.close().res_sync() { log::error!("{}", e); - return errors::Z_EGENERIC + return errors::Z_EGENERIC; } } errors::Z_OK @@ -228,7 +236,9 @@ pub extern "C" fn ze_querying_subscriber_check(this: &ze_owned_querying_subscrib /// Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. #[no_mangle] -pub extern "C" fn ze_querying_subscriber_loan(this: &ze_owned_querying_subscriber_t,) -> ze_querying_subscriber_t { +pub extern "C" fn ze_querying_subscriber_loan( + this: &ze_owned_querying_subscriber_t, +) -> ze_querying_subscriber_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/scouting.rs b/src/scouting.rs index 61cba7426..f1f2939c9 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -12,7 +12,11 @@ // ZettaScale Zenoh team, // use crate::{ - errors::{self, Z_OK}, transmute::{Inplace, TransmuteRef}, z_closure_hello_call, z_config_check, z_config_clone, z_config_drop, z_config_new, z_config_null, z_config_t, z_id_t, z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, CopyableToCArray + errors::{self, Z_OK}, + transmute::{Inplace, TransmuteRef}, + z_closure_hello_call, z_config_check, z_config_clone, z_config_drop, z_config_new, + z_config_null, z_config_t, z_id_t, z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, + CopyableToCArray, }; use async_std::task; use libc::{c_char, c_uint, c_ulong, size_t}; @@ -203,7 +207,7 @@ pub extern "C" fn z_scouting_config_null(this: *mut MaybeUninit) { - let mut _config = MaybeUninit::::uninit(); + let mut _config = MaybeUninit::::uninit(); z_config_new(&mut _config as *mut MaybeUninit); let _config = unsafe { _config.assume_init() }; @@ -217,7 +221,10 @@ pub extern "C" fn z_scouting_config_default(this: *mut MaybeUninit) { +pub extern "C" fn z_scouting_config_from( + config: z_config_t, + this: *mut MaybeUninit, +) { let mut dst = MaybeUninit::uninit(); z_config_clone(&config, &mut dst as *mut _); let _config = unsafe { dst.assume_init() }; @@ -264,7 +271,9 @@ pub extern "C" fn z_scout( let timeout = config.zc_timeout_ms as u64; let config = match config._config.transmute_mut().extract().take() { Some(c) => c, - None => { return errors::Z_EINVAL ;} + None => { + return errors::Z_EINVAL; + } }; let mut closure = z_owned_closure_hello_t::empty(); std::mem::swap(&mut closure, callback); diff --git a/src/session.rs b/src/session.rs index fb4903bb4..87c6b46fd 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,7 +12,10 @@ // ZettaScale Zenoh team, // -use crate::transmute::{unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr}; +use crate::transmute::{ + unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteIntoHandle, TransmuteRef, + TransmuteUninitPtr, +}; use crate::{errors, z_owned_config_t, zc_init_logger}; use std::mem::MaybeUninit; use std::sync::Arc; diff --git a/src/subscriber.rs b/src/subscriber.rs index f431fdb6c..4356ce9d7 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -39,12 +39,12 @@ use zenoh::subscriber::Subscriber; #[repr(C)] #[derive(Clone, Copy)] pub enum z_reliability_t { - BEST_EFFORT, - RELIABLE, + BEST_EFFORT, + RELIABLE, } impl From for z_reliability_t { -#[inline] + #[inline] fn from(r: Reliability) -> Self { match r { Reliability::BestEffort => z_reliability_t::BEST_EFFORT, @@ -54,7 +54,7 @@ impl From for z_reliability_t { } impl From for Reliability { -#[inline] + #[inline] fn from(val: z_reliability_t) -> Self { match val { z_reliability_t::BEST_EFFORT => Reliability::BestEffort, @@ -98,7 +98,7 @@ pub struct z_subscriber_options_t { #[no_mangle] pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { z_subscriber_options_t { - reliability: Reliability::DEFAULT.into() + reliability: Reliability::DEFAULT.into(), } } @@ -147,18 +147,19 @@ pub extern "C" fn z_declare_subscriber( std::mem::swap(callback, &mut closure); let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); - let subscriber - = session.declare_subscriber(key_expr).callback(move |sample| { + let subscriber = session + .declare_subscriber(key_expr) + .callback(move |sample| { let sample = sample.transmute_handle(); z_closure_sample_call(&closure, sample) }); - + let subscriber = subscriber.reliability(options.reliability.into()); match subscriber.res() { Ok(sub) => { Inplace::init(this, Some(sub)); errors::Z_OK - }, + } Err(e) => { log::error!("{}", e); Inplace::empty(this); @@ -182,7 +183,7 @@ pub extern "C" fn z_undeclare_subscriber(subscriber: &mut z_owned_subscriber_t) if let Some(s) = subscriber.transmute_mut().extract().take() { if let Err(e) = s.undeclare().res_sync() { log::error!("{}", e); - return errors::Z_EGENERIC + return errors::Z_EGENERIC; } } errors::Z_OK @@ -192,5 +193,5 @@ pub extern "C" fn z_undeclare_subscriber(subscriber: &mut z_owned_subscriber_t) #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_subscriber_check(subscriber: &z_owned_subscriber_t) -> bool { - subscriber.transmute_ref().is_some() + subscriber.transmute_ref().is_some() } diff --git a/src/transmute.rs b/src/transmute.rs index cafe930ea..97f24b978 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -99,16 +99,30 @@ macro_rules! validate_equivalence { const ALIGN_B: usize = std::mem::align_of::<$type_b>(); if ALIGN_A != ALIGN_B { const ERR_MESSAGE: &str = concatcp!( - "Alingment mismatch: type ", TYPE_NAME_A, " has alignment ", ALIGN_A, - " while type ", TYPE_NAME_B, " has alignment ", ALIGN_B); + "Alingment mismatch: type ", + TYPE_NAME_A, + " has alignment ", + ALIGN_A, + " while type ", + TYPE_NAME_B, + " has alignment ", + ALIGN_B + ); panic!("{}", ERR_MESSAGE); } const SIZE_A: usize = std::mem::size_of::<$type_a>(); const SIZE_B: usize = std::mem::size_of::<$type_b>(); if SIZE_A != SIZE_B { const ERR_MESSAGE: &str = concatcp!( - "Size mismatch: type ", TYPE_NAME_A, " has size ", SIZE_A, - " while type ", TYPE_NAME_B, " has size ", SIZE_B); + "Size mismatch: type ", + TYPE_NAME_A, + " has size ", + SIZE_A, + " while type ", + TYPE_NAME_B, + " has size ", + SIZE_B + ); panic!("{}", ERR_MESSAGE); } }; @@ -183,7 +197,6 @@ macro_rules! impl_transmute_uninit_ptr { }; } - macro_rules! impl_transmute_handle { ($c_type:ty, $zenoh_type:ty) => { impl $crate::transmute::TransmuteFromHandle<$zenoh_type> for $c_type { @@ -195,9 +208,9 @@ macro_rules! impl_transmute_handle { } } impl $crate::transmute::TransmuteIntoHandle<$c_type> for $zenoh_type { - fn transmute_handle(& self) -> $c_type { - unsafe { std::mem::transmute::<& $zenoh_type, $c_type>(self) } + fn transmute_handle(&self) -> $c_type { + unsafe { std::mem::transmute::<&$zenoh_type, $c_type>(self) } } } }; -} \ No newline at end of file +} From 70ac887acd513ed19facafa788a328c1b7ee595f Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 23 Apr 2024 09:51:31 +0200 Subject: [PATCH 57/75] clippy --- build.rs | 9 ++++----- src/closures/query_channel.rs | 2 ++ src/closures/response_channel.rs | 2 ++ src/commons.rs | 4 ++-- src/config.rs | 2 +- src/get.rs | 1 - src/keyexpr.rs | 7 +++---- src/lib.rs | 2 -- src/liveliness.rs | 2 +- src/payload.rs | 2 +- src/publication_cache.rs | 4 +--- src/publisher.rs | 1 - src/put.rs | 8 +------- src/queryable.rs | 6 +++--- src/querying_subscriber.rs | 15 +++++---------- src/scouting.rs | 20 +++++++++++--------- src/session.rs | 3 +-- src/subscriber.rs | 1 - src/transmute.rs | 2 +- 19 files changed, 39 insertions(+), 54 deletions(-) diff --git a/build.rs b/build.rs index 83eabc4f8..50668d5a6 100644 --- a/build.rs +++ b/build.rs @@ -1,5 +1,4 @@ use fs2::FileExt; -use fs_extra::dir::remove; use regex::Regex; use std::env; use std::io::{Read, Write}; @@ -107,9 +106,9 @@ pub struct {type_name} {{ }} " ); - let doc = docs.remove(type_name).expect(&format!( - "Failed to extract docs for opaque type: {type_name}" - )); + let doc = docs + .remove(type_name) + .unwrap_or_else(|| panic!("Failed to extract docs for opaque type: {type_name}")); for d in doc { data_out += &d; data_out += "\r\n"; @@ -125,7 +124,7 @@ pub struct {type_name} {{ fn get_opaque_type_docs() -> HashMap> { let current_folder = get_build_rs_path(); let path_in = current_folder.join("./build-resources/opaque-types/src/lib.rs"); - let re = Regex::new(r#"(?m)^\s*get_opaque_type_data!\(\s*(.*)\s*,\s*(\w+)\)"#).unwrap(); + let re = Regex::new(r"(?m)^\s*get_opaque_type_data!\(\s*(.*)\s*,\s*(\w+)\)").unwrap(); let mut comments = std::vec::Vec::::new(); let mut res = HashMap::>::new(); diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index 10ba68c0e..15264a470 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -86,6 +86,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver /// which it will then return; or until the `send` closure is dropped and all queries have been consumed, /// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channel_t { let (send, rx) = get_send_recv_ends(bound); z_owned_query_channel_t { @@ -111,6 +112,7 @@ pub unsafe extern "C" fn zc_query_fifo_new(bound: usize) -> z_owned_query_channe /// which it will then return; or until the `send` closure is dropped and all queries have been consumed, /// at which point it will return an invalidated `z_owned_query_t`, and so will further calls. #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_query_non_blocking_fifo_new(bound: usize) -> z_owned_query_channel_t { let (send, rx) = get_send_recv_ends(bound); z_owned_query_channel_t { diff --git a/src/closures/response_channel.rs b/src/closures/response_channel.rs index e89b509ba..5cabdccdc 100644 --- a/src/closures/response_channel.rs +++ b/src/closures/response_channel.rs @@ -84,6 +84,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver /// which it will then return; or until the `send` closure is dropped and all replies have been consumed, /// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channel_t { let (send, rx) = get_send_recv_ends(bound); z_owned_reply_channel_t { @@ -109,6 +110,7 @@ pub unsafe extern "C" fn zc_reply_fifo_new(bound: usize) -> z_owned_reply_channe /// which it will then return; or until the `send` closure is dropped and all replies have been consumed, /// at which point it will return an invalidated `z_owned_reply_t`, and so will further calls. #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_reply_non_blocking_fifo_new(bound: usize) -> z_owned_reply_channel_t { let (send, rx) = get_send_recv_ends(bound); z_owned_reply_channel_t { diff --git a/src/commons.rs b/src/commons.rs index 8e2b95cff..650e230d6 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -79,7 +79,7 @@ pub extern "C" fn z_timestamp_npt64_time(timestamp: &z_timestamp_t) -> u64 { } #[no_mangle] -pub unsafe extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t { +pub extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t { timestamp.transmute_copy().get_id().to_le_bytes().into() } @@ -238,7 +238,7 @@ pub unsafe extern "C" fn z_encoding_from_str( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_encoding_default() -> z_encoding_t { - (&Encoding::ZENOH_BYTES).transmute_handle() + Encoding::ZENOH_BYTES.transmute_handle() } /// Frees `encoding`, invalidating it for double-drop safety. diff --git a/src/config.rs b/src/config.rs index f30abd036..12ab9e087 100644 --- a/src/config.rs +++ b/src/config.rs @@ -179,7 +179,7 @@ pub unsafe extern "C" fn zc_config_from_str( let conf_str = CStr::from_ptr(s); let props: Option> = json5::from_str(&conf_str.to_string_lossy()) .ok() - .map(|v| Box::new(v)); + .map(Box::new); if props.is_none() { res = Z_EPARSE; } diff --git a/src/get.rs b/src/get.rs index d72471e1b..97c17bc52 100644 --- a/src/get.rs +++ b/src/get.rs @@ -23,7 +23,6 @@ use zenoh::prelude::{ConsolidationMode, Mode, QueryConsolidation, QueryTarget, R use crate::errors; use crate::transmute::Inplace; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; diff --git a/src/keyexpr.rs b/src/keyexpr.rs index e64933366..b39eb6dfd 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -19,7 +19,6 @@ use crate::errors::ZCError; use crate::errors::Z_OK; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; @@ -293,7 +292,7 @@ pub unsafe extern "C" fn z_keyexpr( ) -> ZCError { if name.is_null() { Inplace::empty(this.transmute_uninit_ptr()); - return errors::Z_EINVAL; + errors::Z_EINVAL } else { let len = libc::strlen(name); zc_keyexpr_from_slice(this, name, len) @@ -311,7 +310,7 @@ pub unsafe extern "C" fn z_keyexpr_autocanonize( ) -> ZCError { if name.is_null() { Inplace::empty(this.transmute_uninit_ptr()); - return errors::Z_EINVAL; + errors::Z_EINVAL } else { let mut len = libc::strlen(name); let res = zc_keyexpr_from_slice_autocanonize(this, name, &mut len); @@ -383,7 +382,7 @@ pub extern "C" fn z_keyexpr_as_bytes(ke: z_keyexpr_t) -> z_slice_t { } } -impl<'a> From<&'static KeyExpr<'static>> for z_keyexpr_t { +impl From<&'static KeyExpr<'static>> for z_keyexpr_t { fn from(key: &'static KeyExpr<'static>) -> Self { key.transmute_handle() } diff --git a/src/lib.rs b/src/lib.rs index ed883ca71..b7565306b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,8 +65,6 @@ pub mod platform; // #[cfg(feature = "shared-memory")] // mod shm; -pub(crate) const LOG_INVALID_SESSION: &str = "Invalid session"; - /// Initialises the zenoh runtime logger. /// /// Note that unless you built zenoh-c with the `logger-autoinit` feature disabled, diff --git a/src/liveliness.rs b/src/liveliness.rs index 7e9342677..29fee985c 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -22,7 +22,7 @@ use zenoh::{ use crate::transmute::TransmuteIntoHandle; use crate::{ errors, - transmute::{Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}, + transmute::{Inplace, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}, z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, z_owned_closure_reply_t, z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t, }; diff --git a/src/payload.rs b/src/payload.rs index 194d66cc8..a6bfdc927 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -256,7 +256,7 @@ pub unsafe extern "C" fn z_bytes_reader_seek( ) -> ZCError { let reader = this.transmute_mut(); let pos = match origin { - libc::SEEK_SET => offset.try_into().map(|r| SeekFrom::Start(r)), + libc::SEEK_SET => offset.try_into().map(SeekFrom::Start), libc::SEEK_CUR => Ok(SeekFrom::Current(offset)), libc::SEEK_END => Ok(SeekFrom::End(offset)), _ => { diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 2f6be1d73..18e0ce407 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -18,9 +18,7 @@ use zenoh::prelude::SyncResolve; use zenoh_ext::SessionExt; -use crate::transmute::{ - Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr, -}; +use crate::transmute::{Inplace, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}; use crate::{errors, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t}; /// Options passed to the :c:func:`ze_declare_publication_cache` function. diff --git a/src/publisher.rs b/src/publisher.rs index dd6012e51..3ab7eb2d5 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -15,7 +15,6 @@ use crate::errors; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; diff --git a/src/put.rs b/src/put.rs index a4c93b9b9..8ba9c77c1 100644 --- a/src/put.rs +++ b/src/put.rs @@ -16,18 +16,12 @@ use std::ptr::null_mut; use crate::commons::*; use crate::errors; use crate::keyexpr::*; -use crate::session::*; use crate::transmute::Inplace; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteRef; use crate::z_owned_bytes_t; use crate::z_session_t; -use crate::LOG_INVALID_SESSION; -use libc::c_void; -use zenoh::encoding; -use zenoh::key_expr; -use zenoh::prelude::{sync::SyncResolve, Priority, SampleKind}; +use zenoh::prelude::{sync::SyncResolve, Priority}; use zenoh::publication::CongestionControl; use zenoh::sample::QoSBuilderTrait; use zenoh::sample::SampleBuilderTrait; diff --git a/src/queryable.rs b/src/queryable.rs index ecd052253..ea1b7905e 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -12,8 +12,8 @@ // ZettaScale Zenoh team, // use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteFromHandle, TransmuteIntoHandle, - TransmuteRef, TransmuteUninitPtr, + unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, + TransmuteUninitPtr, }; use crate::{ errors, z_bytes_t, z_closure_query_call, z_keyexpr_t, z_owned_bytes_t, z_owned_closure_query_t, @@ -241,7 +241,7 @@ pub unsafe extern "C" fn z_query_reply( log::error!("{}", e); return errors::Z_EGENERIC; } - return errors::Z_OK; + errors::Z_OK } /// Get a query's key by aliasing it. diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index e69f0e0f7..aea07e03a 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -15,18 +15,9 @@ use std::mem::MaybeUninit; use std::ptr::null; -use zenoh::prelude::sync::SyncResolve; -use zenoh::prelude::KeyExpr; -use zenoh::prelude::SessionDeclarations; -use zenoh::session; -use zenoh::session::Session; -use zenoh::subscriber::Reliability; -use zenoh_ext::*; - use crate::errors; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; @@ -39,6 +30,11 @@ use crate::{ z_query_target_default, z_query_target_t, z_session_t, zcu_locality_default, zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, }; +use zenoh::prelude::sync::SyncResolve; +use zenoh::prelude::SessionDeclarations; +use zenoh::session::Session; +use zenoh::subscriber::Reliability; +use zenoh_ext::*; use crate::opaque_types::ze_owned_querying_subscriber_t; use crate::opaque_types::ze_querying_subscriber_t; @@ -192,7 +188,6 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( if let Err(e) = sub .0 .fetch({ - let selector = KeyExpr::try_from(selector).unwrap(); move |cb| match options { Some(options) => session .get(selector) diff --git a/src/scouting.rs b/src/scouting.rs index f1f2939c9..22a61fb2e 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -191,50 +191,52 @@ pub const DEFAULT_SCOUTING_TIMEOUT: c_ulong = 1000; #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_scouting_config_null(this: *mut MaybeUninit) { +pub unsafe extern "C" fn z_scouting_config_null(this: *mut MaybeUninit) { let mut _config = MaybeUninit::::uninit(); z_config_null(&mut _config as *mut MaybeUninit); - let _config = unsafe { _config.assume_init() }; + let _config = _config.assume_init(); let config = z_owned_scouting_config_t { _config, zc_timeout_ms: DEFAULT_SCOUTING_TIMEOUT, zc_what: DEFAULT_SCOUTING_WHAT, }; - (unsafe { &mut *this }).write(config); + (*this).write(config); } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_scouting_config_default(this: *mut MaybeUninit) { +pub unsafe extern "C" fn z_scouting_config_default( + this: *mut MaybeUninit, +) { let mut _config = MaybeUninit::::uninit(); z_config_new(&mut _config as *mut MaybeUninit); - let _config = unsafe { _config.assume_init() }; + let _config = _config.assume_init(); let config = z_owned_scouting_config_t { _config, zc_timeout_ms: DEFAULT_SCOUTING_TIMEOUT, zc_what: DEFAULT_SCOUTING_WHAT, }; - (unsafe { &mut *this }).write(config); + (*this).write(config); } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_scouting_config_from( +pub unsafe extern "C" fn z_scouting_config_from( config: z_config_t, this: *mut MaybeUninit, ) { let mut dst = MaybeUninit::uninit(); z_config_clone(&config, &mut dst as *mut _); - let _config = unsafe { dst.assume_init() }; + let _config = dst.assume_init(); let config = z_owned_scouting_config_t { _config, zc_timeout_ms: DEFAULT_SCOUTING_TIMEOUT, zc_what: DEFAULT_SCOUTING_WHAT, }; - (unsafe { &mut *this }).write(config); + (*this).write(config); } #[no_mangle] diff --git a/src/session.rs b/src/session.rs index 87c6b46fd..c37d8b721 100644 --- a/src/session.rs +++ b/src/session.rs @@ -13,8 +13,7 @@ // use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteCopy, TransmuteIntoHandle, TransmuteRef, - TransmuteUninitPtr, + unwrap_ref_unchecked, Inplace, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; use crate::{errors, z_owned_config_t, zc_init_logger}; use std::mem::MaybeUninit; diff --git a/src/subscriber.rs b/src/subscriber.rs index 4356ce9d7..ea530d561 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -18,7 +18,6 @@ use crate::errors; use crate::keyexpr::*; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; -use crate::transmute::TransmuteCopy; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; diff --git a/src/transmute.rs b/src/transmute.rs index 97f24b978..5951a7137 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -63,7 +63,7 @@ pub(crate) trait Inplace: Sized { } // Move the object out of this, leaving it in empty state - fn extract(self: &mut Self) -> Self { + fn extract(&mut self) -> Self { let mut out: MaybeUninit = MaybeUninit::uninit(); Self::empty(&mut out); let mut out = unsafe { out.assume_init() }; From 35154cec042d978a8b3016e2a5ebc953863a8cfb Mon Sep 17 00:00:00 2001 From: yellowhatter Date: Tue, 23 Apr 2024 14:51:58 +0300 Subject: [PATCH 58/75] [skip ci] wip on shm api --- Cargo.lock | 503 ++++++++++++------ Cargo.toml | 10 +- Cargo.toml.in | 2 +- include/zenoh_commons.h | 423 +++++++++------ include/zenoh_macros.h | 14 +- src/lib.rs | 53 ++ src/session.rs | 2 +- src/shm/client/shared_memory_client.rs | 81 ++- src/shm/client_storage/mod.rs | 190 ++++--- .../posix/posix_shared_memory_client.rs | 17 +- src/shm/provider/alloc_layout.rs | 139 +++-- src/shm/provider/alloc_layout_threadsafe.rs | 179 ++++--- src/shm/provider/shared_memory_provider.rs | 18 +- .../provider/shared_memory_provider_impl.rs | 6 +- .../shared_memory_provider_threadsafe.rs | 30 +- src/shm/provider/types.rs | 30 +- src/shm/provider/zsliceshm.rs | 14 +- 17 files changed, 1124 insertions(+), 587 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59351f9ae..4869e7cf5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,6 +35,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -70,54 +71,6 @@ dependencies = [ "libc", ] -[[package]] -name = "anstream" -version = "0.6.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" - -[[package]] -name = "anstyle-parse" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" -dependencies = [ - "anstyle", - "windows-sys 0.52.0", -] - [[package]] name = "anyhow" version = "1.0.81" @@ -319,7 +272,7 @@ checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -392,6 +345,9 @@ name = "bitflags" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +dependencies = [ + "serde", +] [[package]] name = "block-buffer" @@ -521,12 +477,6 @@ dependencies = [ "os_str_bytes", ] -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - [[package]] name = "concurrent-queue" version = "2.4.0" @@ -626,9 +576,9 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -674,16 +624,6 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" -[[package]] -name = "env_filter" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" -dependencies = [ - "log", - "regex", -] - [[package]] name = "env_logger" version = "0.10.2" @@ -697,19 +637,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "env_logger" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "humantime", - "log", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -927,7 +854,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -1006,7 +933,7 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -1021,6 +948,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "half" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" + [[package]] name = "hashbrown" version = "0.12.3" @@ -1210,6 +1143,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "iter-read" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c397ca3ea05ad509c4ec451fea28b4771236a376ca1c69fd5143aae0cf8f93c4" + [[package]] name = "itoa" version = "1.0.11" @@ -1353,6 +1292,15 @@ dependencies = [ "twox-hash", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "memchr" version = "2.7.2" @@ -1427,6 +1375,27 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-bigint-dig" version = "0.8.4" @@ -1526,6 +1495,12 @@ version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "owned-alloc" version = "0.2.0" @@ -1561,9 +1536,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" dependencies = [ "memchr", "thiserror", @@ -1572,9 +1547,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" dependencies = [ "pest", "pest_generator", @@ -1582,22 +1557,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] name = "pest_meta" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" dependencies = [ "once_cell", "pest", @@ -1614,6 +1589,48 @@ dependencies = [ "indexmap 2.2.6", ] +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.58", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -1729,11 +1746,10 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "once_cell", "toml_edit", ] @@ -1852,8 +1868,17 @@ checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -1864,9 +1889,15 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.3", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.3" @@ -1913,6 +1944,18 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64", + "bitflags 2.5.0", + "serde", + "serde_derive", +] + [[package]] name = "rsa" version = "0.9.6" @@ -2187,6 +2230,29 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-pickle" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762ad136a26407c6a80825813600ceeab5e613660d93d79a41f0ec877171e71" +dependencies = [ + "byteorder", + "iter-read", + "num-bigint", + "num-traits", + "serde", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + [[package]] name = "serde_derive" version = "1.0.197" @@ -2195,7 +2261,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -2271,6 +2337,15 @@ dependencies = [ "keccak", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + [[package]] name = "shared_memory" version = "0.12.4" @@ -2312,6 +2387,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -2374,9 +2455,9 @@ dependencies = [ [[package]] name = "stabby" -version = "3.0.3" +version = "4.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad55eaa7e95bd8f952922221460336fd352bc6680fecabaf7d692205f2b56750" +checksum = "6ec04c5825384722310b6a1fd83023bee0bfdc838f7aa3069f0a59e10203836b" dependencies = [ "lazy_static", "rustversion", @@ -2385,9 +2466,9 @@ dependencies = [ [[package]] name = "stabby-abi" -version = "3.0.3" +version = "4.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a36348288e2ef8ba107386fdebee3238f54b3e709ecadd43ed5556137b456a7" +checksum = "976322da1deb6cc64a8406fd24378b840b1962acaac1978a993131c3838d81b3" dependencies = [ "libc", "rustversion", @@ -2397,9 +2478,9 @@ dependencies = [ [[package]] name = "stabby-macros" -version = "3.0.3" +version = "4.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6aa9f59e8bf047add442a0615d880a333d67eac517b1db9401bbc57983f82b0" +checksum = "736712a13ab37b1fa6e073831efca751bbcb31033af4d7308bd5d9d605939183" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -2451,9 +2532,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.57" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -2504,7 +2585,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -2521,6 +2602,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2570,7 +2661,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -2638,9 +2729,9 @@ checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap 2.2.6", "toml_datetime", @@ -2667,7 +2758,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] @@ -2677,6 +2768,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", ] [[package]] @@ -2779,6 +2913,12 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "unwrap-infallible" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151ac09978d3c2862c4e39b557f4eceee2cc72150bc4cb4f16abf061b6e381fb" + [[package]] name = "unzip-n" version = "0.1.2" @@ -2807,12 +2947,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - [[package]] name = "uuid" version = "1.8.0" @@ -2846,6 +2980,12 @@ dependencies = [ "unzip-n", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "value-bag" version = "1.8.1" @@ -2897,7 +3037,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", "wasm-bindgen-shared", ] @@ -2931,7 +3071,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3197,32 +3337,37 @@ dependencies = [ [[package]] name = "zenoh" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ + "ahash", "async-trait", "base64", "const_format", - "env_logger 0.11.3", "event-listener 4.0.3", "flume", "form_urlencoded", "futures", "git-version", "lazy_static", - "log", "ordered-float", "paste", "petgraph", + "phf", "rand", "regex", "rustc_version", "serde", + "serde-pickle", + "serde_cbor", "serde_json", + "serde_yaml", "socket2 0.5.6", "stop-token", "tokio", "tokio-util", + "tracing", "uhlc", + "unwrap-infallible", "uuid", "vec_map", "zenoh-buffers", @@ -3240,6 +3385,7 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", + "zenoh-task", "zenoh-transport", "zenoh-util", ] @@ -3247,7 +3393,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "zenoh-collections", ] @@ -3260,7 +3406,7 @@ dependencies = [ "async-trait", "cbindgen", "chrono", - "env_logger 0.10.2", + "env_logger", "fs2", "futures", "json5", @@ -3279,10 +3425,10 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ - "log", "serde", + "tracing", "uhlc", "zenoh-buffers", "zenoh-protocol", @@ -3292,21 +3438,21 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" [[package]] name = "zenoh-config" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "flume", "json5", - "log", "num_cpus", "secrecy", "serde", "serde_json", "serde_yaml", + "tracing", "validated_struct", "zenoh-core", "zenoh-protocol", @@ -3317,7 +3463,7 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "async-global-executor", "lazy_static", @@ -3329,7 +3475,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "aes", "hmac", @@ -3342,28 +3488,31 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "bincode", - "env_logger 0.11.3", "flume", "futures", - "log", + "phf", "serde", + "serde_cbor", + "serde_json", "tokio", + "tracing", "zenoh", "zenoh-core", "zenoh-macros", "zenoh-result", "zenoh-runtime", "zenoh-sync", + "zenoh-task", "zenoh-util", ] [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "hashbrown 0.14.3", "keyed-set", @@ -3377,7 +3526,7 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "async-trait", "zenoh-config", @@ -3395,17 +3544,17 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "async-trait", "flume", "futures", - "log", "rustls 0.22.3", "rustls-webpki 0.102.2", "serde", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-codec", "zenoh-core", @@ -3418,12 +3567,11 @@ dependencies = [ [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "async-trait", "base64", "futures", - "log", "quinn", "rustls 0.21.10", "rustls-native-certs 0.7.0", @@ -3433,6 +3581,8 @@ dependencies = [ "tokio", "tokio-rustls 0.24.1", "tokio-util", + "tracing", + "zenoh-collections", "zenoh-config", "zenoh-core", "zenoh-link-commons", @@ -3446,12 +3596,12 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "async-trait", - "log", "tokio", "tokio-util", + "tracing", "zenoh-core", "zenoh-link-commons", "zenoh-protocol", @@ -3464,12 +3614,11 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "async-trait", "base64", "futures", - "log", "rustls 0.22.3", "rustls-pemfile 2.1.1", "rustls-pki-types", @@ -3478,7 +3627,9 @@ dependencies = [ "tokio", "tokio-rustls 0.25.0", "tokio-util", + "tracing", "webpki-roots", + "zenoh-collections", "zenoh-config", "zenoh-core", "zenoh-link-commons", @@ -3492,13 +3643,13 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "async-trait", - "log", "socket2 0.5.6", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-collections", "zenoh-core", @@ -3513,14 +3664,14 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "async-trait", "futures", - "log", "nix 0.27.1", "tokio", "tokio-util", + "tracing", "uuid", "zenoh-core", "zenoh-link-commons", @@ -3533,14 +3684,14 @@ dependencies = [ [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "async-trait", "futures-util", - "log", "tokio", "tokio-tungstenite", "tokio-util", + "tracing", "url", "zenoh-core", "zenoh-link-commons", @@ -3554,24 +3705,24 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", "zenoh-keyexpr", ] [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "const_format", "libloading", - "log", "serde", "serde_json", + "tracing", "zenoh-keyexpr", "zenoh-macros", "zenoh-result", @@ -3581,13 +3732,14 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "const_format", "rand", "serde", "uhlc", "zenoh-buffers", + "zenoh-collections", "zenoh-keyexpr", "zenoh-result", ] @@ -3595,7 +3747,7 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "anyhow", ] @@ -3603,25 +3755,30 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ + "futures", "lazy_static", + "libc", + "ron", + "serde", "tokio", "zenoh-collections", + "zenoh-macros", + "zenoh-protocol", "zenoh-result", ] [[package]] name = "zenoh-shm" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "async-trait", "bincode", "crc", "lazy_static", "lockfree", - "log", "num-traits", "rand", "serde", @@ -3629,6 +3786,7 @@ dependencies = [ "stabby", "thread-priority", "tokio", + "tracing", "zenoh-buffers", "zenoh-core", "zenoh-macros", @@ -3638,7 +3796,7 @@ dependencies = [ [[package]] name = "zenoh-sync" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "event-listener 4.0.3", "futures", @@ -3649,14 +3807,26 @@ dependencies = [ "zenoh-runtime", ] +[[package]] +name = "zenoh-task" +version = "0.11.0-dev" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" +dependencies = [ + "futures", + "tokio", + "tokio-util", + "tracing", + "zenoh-core", + "zenoh-runtime", +] + [[package]] name = "zenoh-transport" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "async-trait", "flume", - "log", "lz4_flex", "paste", "rand", @@ -3666,6 +3836,7 @@ dependencies = [ "sha3", "tokio", "tokio-util", + "tracing", "zenoh-buffers", "zenoh-codec", "zenoh-collections", @@ -3678,13 +3849,14 @@ dependencies = [ "zenoh-runtime", "zenoh-shm", "zenoh-sync", + "zenoh-task", "zenoh-util", ] [[package]] name = "zenoh-util" version = "0.11.0-dev" -source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_watchdog_poc#b77d2a787b056e10e7e73728943d793283391eff" +source = "git+https://github.com/ZettaScaleLabs/zenoh.git?branch=shm_refine#f6c67fbb73552ec20c800c3d534cf54819b81a4d" dependencies = [ "async-std", "async-trait", @@ -3694,10 +3866,11 @@ dependencies = [ "lazy_static", "libc", "libloading", - "log", "pnet_datalink", "shellexpand", "tokio", + "tracing", + "tracing-subscriber", "winapi", "zenoh-core", "zenoh-result", @@ -3720,7 +3893,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.57", + "syn 2.0.58", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 03f7b6925..dc2335b00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ build = "build.rs" [features] logger-autoinit = [] shared-memory = ["zenoh/shared-memory"] -default = ["zenoh/default"] +default = ["zenoh/default", "shared-memory"] [badges] maintenance = { status = "actively-developed" } @@ -51,10 +51,10 @@ log = "0.4.17" rand = "0.8.5" spin = "0.9.5" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine", features = ["unstable"] } [build-dependencies] cbindgen = "0.26.0" diff --git a/Cargo.toml.in b/Cargo.toml.in index 8918983d2..08d528d53 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -33,7 +33,7 @@ build = "@CARGO_PROJECT_DIR@build.rs" [features] logger-autoinit = [] shared-memory = ["zenoh/shared-memory"] -default = ["zenoh/default"] +default = ["zenoh/default", "shared-memory"] [badges] maintenance = { status = "actively-developed" } diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index e0058f9e2..6522d44d7 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -189,57 +189,69 @@ typedef struct ALIGN(4) z_alloc_alignment_t { uint32_t _0[1]; } z_alloc_alignment_t; #endif -/** - * A non-thread-safe SharedMemoryProvider's AllocLayout - */ #if defined(TARGET_ARCH_X86_64) -typedef struct ALIGN(8) z_alloc_layout_t { - uint64_t _0[4]; -} z_alloc_layout_t; +typedef struct ALIGN(8) z_owned_buf_alloc_result_t { + uint64_t _0[11]; +} z_owned_buf_alloc_result_t; #endif #if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(16) z_alloc_layout_t { - uint64_t _0[14]; -} z_alloc_layout_t; +typedef struct ALIGN(16) z_owned_buf_alloc_result_t { + uint64_t _0[12]; +} z_owned_buf_alloc_result_t; #endif #if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_alloc_layout_t { - uint64_t _0[14]; -} z_alloc_layout_t; +typedef struct ALIGN(8) z_owned_buf_alloc_result_t { + uint64_t _0[11]; +} z_owned_buf_alloc_result_t; #endif +/** + * A non-thread-safe SharedMemoryProvider's AllocLayout + */ #if defined(TARGET_ARCH_X86_64) -typedef struct ALIGN(8) z_buf_alloc_result_t { - uint64_t _0[10]; -} z_buf_alloc_result_t; +typedef struct ALIGN(8) z_owned_alloc_layout_t { + uint64_t _0[4]; +} z_owned_alloc_layout_t; #endif #if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(16) z_buf_alloc_result_t { - uint64_t _0[10]; -} z_buf_alloc_result_t; +typedef struct ALIGN(16) z_owned_alloc_layout_t { + uint64_t _0[14]; +} z_owned_alloc_layout_t; #endif #if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_buf_alloc_result_t { - uint64_t _0[10]; -} z_buf_alloc_result_t; +typedef struct ALIGN(8) z_owned_alloc_layout_t { + uint64_t _0[14]; +} z_owned_alloc_layout_t; #endif +/** + * A loaned non-thread-safe SharedMemoryProvider's AllocLayout + */ +typedef struct z_alloc_layout_t { + const struct z_owned_alloc_layout_t *_0; +} z_alloc_layout_t; /** * A thread-safe SharedMemoryProvider's AllocLayout */ #if defined(TARGET_ARCH_X86_64) -typedef struct ALIGN(8) z_alloc_layout_threadsafe_t { +typedef struct ALIGN(8) z_owned_alloc_layout_threadsafe_t { uint64_t _0[4]; -} z_alloc_layout_threadsafe_t; +} z_owned_alloc_layout_threadsafe_t; #endif #if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(16) z_alloc_layout_threadsafe_t { - uint64_t _0[14]; -} z_alloc_layout_threadsafe_t; +typedef struct ALIGN(16) z_owned_alloc_layout_threadsafe_t { + uint64_t _0[4]; +} z_owned_alloc_layout_threadsafe_t; #endif #if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_alloc_layout_threadsafe_t { - uint64_t _0[14]; -} z_alloc_layout_threadsafe_t; +typedef struct ALIGN(8) z_owned_alloc_layout_threadsafe_t { + uint64_t _0[4]; +} z_owned_alloc_layout_threadsafe_t; #endif +/** + * A loaned thread-safe SharedMemoryProvider's AllocLayout + */ +typedef struct z_alloc_layout_threadsafe_t { + const struct z_owned_alloc_layout_threadsafe_t *_0; +} z_alloc_layout_threadsafe_t; typedef struct zc_threadsafe_context_data_t { void *ptr; } zc_threadsafe_context_data_t; @@ -339,21 +351,6 @@ typedef struct z_attachment_t { const void *data; z_attachment_iter_driver_t iteration_driver; } z_attachment_t; -#if defined(TARGET_ARCH_X86_64) -typedef struct ALIGN(8) z_slice_shm_t { - uint64_t _0[10]; -} z_slice_shm_t; -#endif -#if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(16) z_slice_shm_t { - uint64_t _0[10]; -} z_slice_shm_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_slice_shm_t { - uint64_t _0[10]; -} z_slice_shm_t; -#endif /** * A map of maybe-owned vector of bytes to owned vector of bytes. * @@ -909,30 +906,112 @@ typedef struct ALIGN(8) z_memory_layout_t { uint64_t _0[2]; } z_memory_layout_t; #endif +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) z_slice_shm_mut_t { + uint64_t _0[10]; +} z_slice_shm_mut_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) z_slice_shm_mut_t { + uint64_t _0[10]; +} z_slice_shm_mut_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) z_slice_shm_mut_t { + uint64_t _0[10]; +} z_slice_shm_mut_t; +#endif /** - * A SharedMemoryClientStorage. - */ -typedef struct z_shared_memory_client_storage_t { - size_t _0; -} z_shared_memory_client_storage_t; -/** - * A SharedMemoryClient + * An owned SharedMemoryClient + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. */ #if defined(TARGET_ARCH_X86_64) -typedef struct ALIGN(8) z_shared_memory_client_t { +typedef struct ALIGN(8) z_owned_shared_memory_client_t { uint64_t _0[2]; -} z_shared_memory_client_t; +} z_owned_shared_memory_client_t; #endif #if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(16) z_shared_memory_client_t { +typedef struct ALIGN(16) z_owned_shared_memory_client_t { uint64_t _0[2]; -} z_shared_memory_client_t; +} z_owned_shared_memory_client_t; #endif #if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_shared_memory_client_t { +typedef struct ALIGN(8) z_owned_shared_memory_client_t { uint64_t _0[2]; +} z_owned_shared_memory_client_t; +#endif +/** + * A loaned SharedMemoryClient + */ +typedef struct z_shared_memory_client_t { + const struct z_owned_shared_memory_client_t *_0; } z_shared_memory_client_t; +/** + * A callbacks for SharedMemorySegment + */ +typedef struct zc_shared_memory_segment_callbacks_t { + uint8_t *(*map_fn)(void*, z_chunk_id_t); +} zc_shared_memory_segment_callbacks_t; +/** + * A SharedMemorySegment + */ +typedef struct z_shared_memory_segment_t { + struct zc_threadsafe_context_t context; + struct zc_shared_memory_segment_callbacks_t callbacks; +} z_shared_memory_segment_t; +/** + * A callbacks for SharedMemoryClient + */ +typedef struct zc_shared_memory_client_callbacks_t { + bool (*attach_fn)(void*, z_segment_id_t, struct z_shared_memory_segment_t*); +} zc_shared_memory_client_callbacks_t; +/** + * A SharedMemoryClientStorage. + */ +typedef struct z_owned_shared_memory_client_storage_t { + size_t _0; +} z_owned_shared_memory_client_storage_t; +/** + * An owned list of SharedMemoryClients + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ +#if defined(TARGET_ARCH_X86_64) +typedef struct ALIGN(8) zc_owned_shared_memory_client_list_t { + uint64_t _0[3]; +} zc_owned_shared_memory_client_list_t; +#endif +#if defined(TARGET_ARCH_AARCH64) +typedef struct ALIGN(16) zc_owned_shared_memory_client_list_t { + uint64_t _0[4]; +} zc_owned_shared_memory_client_list_t; +#endif +#if defined(TARGET_ARCH_ARM) +typedef struct ALIGN(8) zc_owned_shared_memory_client_list_t { + uint64_t _0[3]; +} zc_owned_shared_memory_client_list_t; #endif +/** + * A loaned list of SharedMemoryClients + */ +typedef struct zc_shared_memory_client_list_t { + const struct zc_owned_shared_memory_client_list_t *_0; +} zc_shared_memory_client_list_t; /** * An owned SharedMemoryProvider with POSIX backend * @@ -1066,43 +1145,6 @@ typedef struct z_owned_scouting_config_t { unsigned long zc_timeout_ms; uint8_t zc_what; } z_owned_scouting_config_t; -/** - * A callbacks for SharedMemorySegment - */ -typedef struct zc_shared_memory_segment_callbacks_t { - uint8_t *(*map_fn)(void*, z_chunk_id_t); -} zc_shared_memory_segment_callbacks_t; -/** - * A SharedMemorySegment - */ -typedef struct z_shared_memory_segment_t { - struct zc_threadsafe_context_t context; - struct zc_shared_memory_segment_callbacks_t callbacks; -} z_shared_memory_segment_t; -/** - * A callbacks for SharedMemoryClient - */ -typedef struct zc_shared_memory_client_callbacks_t { - bool (*attach_fn)(void*, z_segment_id_t, struct z_shared_memory_segment_t*); -} zc_shared_memory_client_callbacks_t; -/** - * A list of SharedMemoryClients. - */ -#if defined(TARGET_ARCH_X86_64) -typedef struct ALIGN(8) zc_shared_memory_client_list_t { - uint64_t _0[3]; -} zc_shared_memory_client_list_t; -#endif -#if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(16) zc_shared_memory_client_list_t { - uint64_t _0[4]; -} zc_shared_memory_client_list_t; -#endif -#if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) zc_shared_memory_client_list_t { - uint64_t _0[3]; -} zc_shared_memory_client_list_t; -#endif /** * A non-thread-safe SharedMemoryProvider specialization */ @@ -1381,43 +1423,60 @@ ZENOHC_API extern const char *Z_CONFIG_SCOUTING_DELAY_KEY; ZENOHC_API extern const char *Z_CONFIG_ADD_TIMESTAMP_KEY; ZENOHC_API void z_alloc_alignment_delete(struct z_alloc_alignment_t alignment); ZENOHC_API -void z_alloc_layout_alloc(const struct z_alloc_layout_t *layout, - struct z_buf_alloc_result_t *out_buffer); +int32_t z_alloc_layout_alloc(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_alloc_layout_t layout); ZENOHC_API -void z_alloc_layout_alloc_gc(const struct z_alloc_layout_t *layout, - struct z_buf_alloc_result_t *out_buffer); +int32_t z_alloc_layout_alloc_gc(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_alloc_layout_t layout); ZENOHC_API -void z_alloc_layout_alloc_gc_defrag(const struct z_alloc_layout_t *layout, - struct z_buf_alloc_result_t *out_buffer); +int32_t z_alloc_layout_alloc_gc_defrag(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_alloc_layout_t layout); ZENOHC_API -void z_alloc_layout_alloc_gc_defrag_blocking(const struct z_alloc_layout_t *layout, - struct z_buf_alloc_result_t *out_buffer); +int32_t z_alloc_layout_alloc_gc_defrag_blocking(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_alloc_layout_t layout); ZENOHC_API -void z_alloc_layout_alloc_gc_defrag_dealloc(const struct z_alloc_layout_t *layout, - struct z_buf_alloc_result_t *out_buffer); -ZENOHC_API void z_alloc_layout_delete(struct z_alloc_layout_t layout); +int32_t z_alloc_layout_alloc_gc_defrag_dealloc(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_alloc_layout_t layout); +/** + * Returns ``true`` if `layout` is valid. + */ +ZENOHC_API bool z_alloc_layout_check(const struct z_owned_alloc_layout_t *layout); +ZENOHC_API void z_alloc_layout_delete(struct z_owned_alloc_layout_t *layout); +/** + * Initializes a null memory for safe-to-drop value of 'z_owned_alloc_layout_t' type + */ +ZENOHC_API void z_alloc_layout_null(struct z_owned_alloc_layout_t *out); ZENOHC_API -void z_alloc_layout_threadsafe_alloc(const struct z_alloc_layout_threadsafe_t *layout, - struct z_buf_alloc_result_t *out_buffer); +int32_t z_alloc_layout_threadsafe_alloc(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_alloc_layout_threadsafe_t layout); ZENOHC_API -void z_alloc_layout_threadsafe_alloc_gc(const struct z_alloc_layout_threadsafe_t *layout, - struct z_buf_alloc_result_t *out_buffer); +int32_t z_alloc_layout_threadsafe_alloc_gc(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_alloc_layout_threadsafe_t layout); ZENOHC_API -void z_alloc_layout_threadsafe_alloc_gc_defrag(const struct z_alloc_layout_threadsafe_t *layout, - struct z_buf_alloc_result_t *out_buffer); +int32_t z_alloc_layout_threadsafe_alloc_gc_defrag(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_alloc_layout_threadsafe_t layout); ZENOHC_API -void z_alloc_layout_threadsafe_alloc_gc_defrag_async(const struct z_alloc_layout_threadsafe_t *layout, - struct z_buf_alloc_result_t *out_buffer, - struct zc_threadsafe_context_t result_context, - void (*result_callback)(void*, - struct z_buf_alloc_result_t*)); +int32_t z_alloc_layout_threadsafe_alloc_gc_defrag_async(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_alloc_layout_threadsafe_t layout, + struct zc_threadsafe_context_t result_context, + void (*result_callback)(void*, + struct z_owned_buf_alloc_result_t*)); ZENOHC_API -void z_alloc_layout_threadsafe_alloc_gc_defrag_blocking(const struct z_alloc_layout_threadsafe_t *layout, - struct z_buf_alloc_result_t *out_buffer); +int32_t z_alloc_layout_threadsafe_alloc_gc_defrag_blocking(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_alloc_layout_threadsafe_t layout); ZENOHC_API -void z_alloc_layout_threadsafe_alloc_gc_defrag_dealloc(const struct z_alloc_layout_threadsafe_t *layout, - struct z_buf_alloc_result_t *out_buffer); -ZENOHC_API void z_alloc_layout_threadsafe_delete(struct z_alloc_layout_threadsafe_t layout); +int32_t z_alloc_layout_threadsafe_alloc_gc_defrag_dealloc(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_alloc_layout_threadsafe_t layout); +/** + * Returns ``true`` if `layout` is valid. + */ +ZENOHC_API +bool z_alloc_layout_threadsafe_check(const struct z_owned_alloc_layout_threadsafe_t *layout); +ZENOHC_API void z_alloc_layout_threadsafe_delete(struct z_owned_alloc_layout_threadsafe_t *layout); +/** + * Initializes a null memory for safe-to-drop value of 'z_owned_alloc_layout_threadsafe_t' type + */ +ZENOHC_API void z_alloc_layout_threadsafe_null(struct z_owned_alloc_layout_threadsafe_t *out); ZENOHC_API void z_allocated_chunk_delete(struct z_allocated_chunk_t val); ZENOHC_API void z_allocated_chunk_new(struct z_chunk_descriptor_t descriptor, @@ -1457,11 +1516,6 @@ ZENOHC_API size_t z_attachment_len(struct z_attachment_t this_); * Returns the gravestone value for `z_attachment_t`. */ ZENOHC_API struct z_attachment_t z_attachment_null(void); -ZENOHC_API void z_buf_alloc_result_delete(struct z_buf_alloc_result_t result); -ZENOHC_API -bool z_buf_alloc_result_unwrap(struct z_buf_alloc_result_t alloc_result, - struct z_slice_shm_t *out_buf, - enum z_alloc_error_t *out_error); /** * Returns ``true`` if `b` is initialized. */ @@ -2140,8 +2194,41 @@ struct z_owned_session_t z_open(struct z_owned_config_t *config); */ ZENOHC_API struct z_owned_session_t z_open_with_shm_clients(struct z_owned_config_t *config, - const struct z_shared_memory_client_storage_t *shm_clients); -ZENOHC_API struct z_shared_memory_client_t z_posix_shared_memory_client_new(void); + z_shared_memory_client_storage_t shm_clients); +ZENOHC_API void z_owned_buf_alloc_result_delete(struct z_owned_buf_alloc_result_t result); +ZENOHC_API +bool z_owned_buf_alloc_result_unwrap(struct z_owned_buf_alloc_result_t alloc_result, + struct z_slice_shm_mut_t *out_buf, + enum z_alloc_error_t *out_error); +/** + * Returns ``true`` if `client` is valid. + */ +ZENOHC_API +bool z_owned_shared_memory_client_check(const struct z_owned_shared_memory_client_t *client); +ZENOHC_API +void z_owned_shared_memory_client_delete(struct z_owned_shared_memory_client_t *out_client); +/** + * Returns a :c:type:`z_shared_memory_client_t` loaned from `client`. + */ +ZENOHC_API +struct z_shared_memory_client_t z_owned_shared_memory_client_loan(const struct z_owned_shared_memory_client_t *client); +ZENOHC_API +int32_t z_owned_shared_memory_client_new(struct z_owned_shared_memory_client_t *out_client, + struct zc_threadsafe_context_t context, + struct zc_shared_memory_client_callbacks_t callbacks); +/** + * Initializes a null memory for safe-to-drop value of 'z_owned_shared_memory_client_t' type + */ +ZENOHC_API +void z_owned_shared_memory_client_null(struct z_owned_shared_memory_client_t *out_client); +ZENOHC_API +int32_t z_owned_shared_memory_client_storage_new(struct z_owned_shared_memory_client_storage_t *out, + struct zc_shared_memory_client_list_t clients); +ZENOHC_API +int32_t z_owned_shared_memory_client_storage_new_with_default_client_set(struct z_owned_shared_memory_client_storage_t *out, + struct zc_shared_memory_client_list_t clients); +ZENOHC_API +int32_t z_posix_shared_memory_client_new(struct z_owned_shared_memory_client_t *out_client); ZENOHC_API bool z_posix_shared_memory_provider_new(const struct z_memory_layout_t *layout, struct z_posix_shared_memory_provider_t *out_provider); @@ -2502,45 +2589,45 @@ struct z_session_t z_session_loan(const struct z_owned_session_t *s); * Constructs a null safe-to-drop value of 'z_owned_session_t' type */ ZENOHC_API struct z_owned_session_t z_session_null(void); -ZENOHC_API void z_shared_memory_client_delete(struct z_shared_memory_client_t client); +/** + * Returns ``true`` if `storage` is valid. + */ ZENOHC_API -void z_shared_memory_client_new(struct zc_threadsafe_context_t context, - struct zc_shared_memory_client_callbacks_t callbacks, - struct z_shared_memory_client_t *out_client); +bool z_shared_memory_client_storage_check(const struct z_owned_shared_memory_client_storage_t *storage); ZENOHC_API -void z_shared_memory_client_storage_deref(struct z_shared_memory_client_storage_t storage); -ZENOHC_API struct z_shared_memory_client_storage_t z_shared_memory_client_storage_global(void); +void z_shared_memory_client_storage_deref(struct z_owned_shared_memory_client_storage_t *storage); ZENOHC_API -bool z_shared_memory_client_storage_new(struct zc_shared_memory_client_list_t clients, - struct z_shared_memory_client_storage_t *out_storage); +int32_t z_shared_memory_client_storage_global(struct z_owned_shared_memory_client_storage_t *out); +/** + * Initializes a null memory for safe-to-drop value of 'z_owned_shared_memory_client_storage_t' type + */ ZENOHC_API -bool z_shared_memory_client_storage_new_with_default_client_set(struct zc_shared_memory_client_list_t clients, - struct z_shared_memory_client_storage_t *out_storage); +void z_shared_memory_client_storage_null(struct z_owned_shared_memory_client_storage_t *out); ZENOHC_API bool z_shared_memory_provider_alloc(const struct z_shared_memory_provider_t *provider, size_t size, struct z_alloc_alignment_t alignment, - struct z_buf_alloc_result_t *out_buffer); + struct z_owned_buf_alloc_result_t *out_buffer); ZENOHC_API bool z_shared_memory_provider_alloc_gc(const struct z_shared_memory_provider_t *provider, size_t size, struct z_alloc_alignment_t alignment, - struct z_buf_alloc_result_t *out_buffer); + struct z_owned_buf_alloc_result_t *out_buffer); ZENOHC_API bool z_shared_memory_provider_alloc_gc_defrag(const struct z_shared_memory_provider_t *provider, size_t size, struct z_alloc_alignment_t alignment, - struct z_buf_alloc_result_t *out_buffer); + struct z_owned_buf_alloc_result_t *out_buffer); ZENOHC_API bool z_shared_memory_provider_alloc_gc_defrag_blocking(const struct z_shared_memory_provider_t *provider, size_t size, struct z_alloc_alignment_t alignment, - struct z_buf_alloc_result_t *out_buffer); + struct z_owned_buf_alloc_result_t *out_buffer); ZENOHC_API bool z_shared_memory_provider_alloc_gc_defrag_dealloc(const struct z_shared_memory_provider_t *provider, size_t size, struct z_alloc_alignment_t alignment, - struct z_buf_alloc_result_t *out_buffer); + struct z_owned_buf_alloc_result_t *out_buffer); ZENOHC_API size_t z_shared_memory_provider_available(const struct z_shared_memory_provider_t *provider); ZENOHC_API @@ -2552,7 +2639,7 @@ ZENOHC_API bool z_shared_memory_provider_map(const struct z_shared_memory_provider_t *provider, struct z_allocated_chunk_t allocated_chunk, size_t len, - struct z_slice_shm_t *out_buffer); + struct z_slice_shm_mut_t *out_buffer); ZENOHC_API void z_shared_memory_provider_new(z_protocol_id_t id, struct zc_context_t context, @@ -2562,41 +2649,41 @@ ZENOHC_API bool z_shared_memory_provider_threadsafe_alloc(const struct z_shared_memory_provider_threadsafe_t *provider, size_t size, struct z_alloc_alignment_t alignment, - struct z_buf_alloc_result_t *out_buffer); + struct z_owned_buf_alloc_result_t *out_buffer); ZENOHC_API bool z_shared_memory_provider_threadsafe_alloc_gc(const struct z_shared_memory_provider_threadsafe_t *provider, size_t size, struct z_alloc_alignment_t alignment, - struct z_buf_alloc_result_t *out_buffer); + struct z_owned_buf_alloc_result_t *out_buffer); ZENOHC_API bool z_shared_memory_provider_threadsafe_alloc_gc_defrag(const struct z_shared_memory_provider_threadsafe_t *provider, size_t size, struct z_alloc_alignment_t alignment, - struct z_buf_alloc_result_t *out_buffer); + struct z_owned_buf_alloc_result_t *out_buffer); ZENOHC_API void z_shared_memory_provider_threadsafe_alloc_gc_defrag_async(const struct z_shared_memory_provider_threadsafe_t *provider, size_t size, struct z_alloc_alignment_t alignment, - struct z_buf_alloc_result_t *out_buffer, + struct z_owned_buf_alloc_result_t *out_buffer, struct zc_threadsafe_context_t result_context, void (*result_callback)(void*, bool, - struct z_buf_alloc_result_t*)); + struct z_owned_buf_alloc_result_t*)); ZENOHC_API bool z_shared_memory_provider_threadsafe_alloc_gc_defrag_blocking(const struct z_shared_memory_provider_threadsafe_t *provider, size_t size, struct z_alloc_alignment_t alignment, - struct z_buf_alloc_result_t *out_buffer); + struct z_owned_buf_alloc_result_t *out_buffer); ZENOHC_API bool z_shared_memory_provider_threadsafe_alloc_gc_defrag_dealloc(const struct z_shared_memory_provider_threadsafe_t *provider, size_t size, struct z_alloc_alignment_t alignment, - struct z_buf_alloc_result_t *out_buffer); + struct z_owned_buf_alloc_result_t *out_buffer); ZENOHC_API -bool z_shared_memory_provider_threadsafe_alloc_layout(const struct z_shared_memory_provider_threadsafe_t *provider, +bool z_shared_memory_provider_threadsafe_alloc_layout(struct z_owned_alloc_layout_threadsafe_t *out_layout, + const struct z_shared_memory_provider_threadsafe_t *provider, size_t size, - struct z_alloc_alignment_t alignment, - struct z_alloc_layout_threadsafe_t *out_layout); + struct z_alloc_alignment_t alignment); ZENOHC_API size_t z_shared_memory_provider_threadsafe_available(const struct z_shared_memory_provider_threadsafe_t *provider); ZENOHC_API @@ -2609,7 +2696,7 @@ ZENOHC_API bool z_shared_memory_provider_threadsafe_map(const struct z_shared_memory_provider_threadsafe_t *provider, struct z_allocated_chunk_t allocated_chunk, size_t len, - struct z_slice_shm_t *out_buffer); + struct z_slice_shm_mut_t *out_buffer); ZENOHC_API void z_shared_memory_provider_threadsafe_new(z_protocol_id_t id, struct zc_threadsafe_context_t context, @@ -2618,7 +2705,7 @@ void z_shared_memory_provider_threadsafe_new(z_protocol_id_t id, ZENOHC_API int8_t z_sleep_ms(size_t time); ZENOHC_API int8_t z_sleep_s(size_t time); ZENOHC_API int8_t z_sleep_us(size_t time); -ZENOHC_API void z_slice_shm_delete(struct z_slice_shm_t slice); +ZENOHC_API void z_slice_shm_mut_delete(struct z_slice_shm_mut_t slice); /** * Returns ``true`` if `strs` is valid. */ @@ -3018,11 +3105,27 @@ ZENOHC_API struct zc_owned_payload_t zc_sample_payload_rcinc(const struct z_samp */ ZENOHC_API struct z_owned_session_t zc_session_rcinc(struct z_session_t session); ZENOHC_API -void zc_shared_memory_client_list_add_client(z_protocol_id_t id, - struct z_shared_memory_client_t client, - struct zc_shared_memory_client_list_t *list); -ZENOHC_API void zc_shared_memory_client_list_delete(struct zc_shared_memory_client_list_t list); -ZENOHC_API struct zc_shared_memory_client_list_t zc_shared_memory_client_list_new(void); +int32_t zc_shared_memory_client_list_add_client(z_protocol_id_t id, + struct z_owned_shared_memory_client_t *client, + struct zc_shared_memory_client_list_t list); +/** + * Returns ``true`` if `list` is valid. + */ +ZENOHC_API +bool zc_shared_memory_client_list_check(const struct zc_owned_shared_memory_client_list_t *list); +ZENOHC_API +void zc_shared_memory_client_list_delete(struct zc_owned_shared_memory_client_list_t *out_client); +/** + * Returns a :c:type:`zc_shared_memory_client_list_t` loaned from `list`. + */ +ZENOHC_API +struct zc_shared_memory_client_list_t zc_shared_memory_client_list_loan(const struct zc_owned_shared_memory_client_list_t *list); +ZENOHC_API +int32_t zc_shared_memory_client_list_new(struct zc_owned_shared_memory_client_list_t *out); +/** + * Initializes a null memory for safe-to-drop value of 'zc_owned_shared_memory_client_list_t' type + */ +ZENOHC_API void zc_shared_memory_client_list_null(struct zc_owned_shared_memory_client_list_t *out); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 726abef13..57d0885d7 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -47,11 +47,11 @@ ze_owned_publication_cache_t * : ze_undeclare_publication_cache, \ ze_owned_querying_subscriber_t * : ze_undeclare_querying_subscriber \ /* - z_shared_memory_client_t : z_shared_memory_client_delete, - z_shared_memory_client_storage_t : z_shared_memory_client_storage_deref, - zc_shared_memory_client_list_t : zc_shared_memory_client_list_delete, - z_alloc_layout_threadsafe_t : z_alloc_layout_threadsafe_delete, \ - z_alloc_layout_t : z_alloc_layout_delete, \ + z_owned_shared_memory_client_t : z_owned_shared_memory_client_delete, + z_owned_shared_memory_client_storage_t : z_owned_shared_memory_client_storage_deref, + zc_owned_shared_memory_client_list_t : zc_shared_memory_client_list_delete, + z_owned_alloc_layout_threadsafe_t : z_owned_alloc_layout_threadsafe_delete, \ + z_owned_alloc_layout_t : z_owned_alloc_layout_delete, \ z_chunk_descriptor_t : z_chunk_descriptor_delete, \ z_allocated_chunk_t : z_allocated_chunk_delete, \ z_shared_memory_provider_threadsafe_t : z_shared_memory_provider_threadsafe_delete, \ @@ -59,8 +59,8 @@ z_alloc_alignment_t : z_alloc_alignment_delete, \ z_memory_layout_t : z_memory_layout_delete, \ z_chunk_alloc_result_t : z_chunk_alloc_result_delete, \ - z_buf_alloc_result_t : z_buf_alloc_result_delete, \ - z_slice_shm_t : z_slice_shm_delete \ + z_owned_buf_alloc_result_t : z_owned_buf_alloc_result_delete, \ + z_slice_shm_mut_t : z_slice_shm_delete \ */ \ )(x) diff --git a/src/lib.rs b/src/lib.rs index 4d846550a..04a081ea4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,6 +78,59 @@ macro_rules! decl_rust_copy_type { }; } +#[macro_export] +macro_rules! decl_rust_new_owned_type { + (zenoh:($zenoh_type:ty), c:($c_type:ty)) => { + impl_guarded_transmute!(noderefs $zenoh_type, $c_type); + impl_guarded_transmute!(noderefs $c_type, $zenoh_type); + + impl $c_type { + pub fn check(&mut self) -> bool { + self.transmute_mut().is_some() + } + + pub fn make_null(&mut self) { + *self.transmute_mut() = None; + } + + pub fn delete(&mut self) { + let _ = self.transmute_mut().take(); + } + } + }; +} + +#[macro_export] +macro_rules! prepare_memory_to_init { + ($owned_c_type:ident) => {{ + let owned_zenoh_type = $owned_c_type.transmute_mut(); + if owned_zenoh_type.is_some() { + return -1; // todo: error type E_DOUBLE_INIT + } + owned_zenoh_type + }}; +} + +#[macro_export] +macro_rules! access_owned_memory { + ($owned_c_obj_mut:expr, $acess_expr:expr) => { + match $owned_c_obj_mut.transmute_mut() { + Some(val) => $acess_expr(val), + None => -2, // todo: error type E_ACCESS_NULL + } + }; +} + +#[macro_export] +macro_rules! move_owned_memory { + ($owned_c_obj_mut:expr, $acess_expr:expr) => { + match $owned_c_obj_mut.transmute_mut().take() { + Some(val) => $acess_expr(val), + None => -3, // todo: error type E_MOVE_NULL + } + }; +} + /// For internal use only. /// /// This macro is used to establish the equivalence between a Rust type (first parameter) and a C layout (second parameter). diff --git a/src/session.rs b/src/session.rs index 3caf63ea1..e7f0a19a3 100644 --- a/src/session.rs +++ b/src/session.rs @@ -126,7 +126,7 @@ pub extern "C" fn z_open(config: &mut z_owned_config_t) -> z_owned_session_t { #[cfg(feature = "shared-memory")] pub extern "C" fn z_open_with_shm_clients( config: &mut z_owned_config_t, - shm_clients: &z_shared_memory_client_storage_t, + shm_clients: z_shared_memory_client_storage_t, ) -> z_owned_session_t { use crate::GuardedTransmute; diff --git a/src/shm/client/shared_memory_client.rs b/src/shm/client/shared_memory_client.rs index da8456ceb..9cd84a00c 100644 --- a/src/shm/client/shared_memory_client.rs +++ b/src/shm/client/shared_memory_client.rs @@ -26,8 +26,9 @@ use zenoh::{ use zenoh_util::core::bail; use crate::{ - common::types::z_segment_id_t, decl_rust_copy_type, impl_guarded_transmute, - zc_threadsafe_context_t, DroppableContext, GuardedTransmute, ThreadsafeContext, + common::types::z_segment_id_t, decl_rust_new_owned_type, impl_guarded_transmute, + prepare_memory_to_init, zc_threadsafe_context_t, DroppableContext, GuardedTransmute, + ThreadsafeContext, }; use super::shared_memory_segment::{z_shared_memory_segment_t, DynamicSharedMemorySegment}; @@ -43,22 +44,37 @@ pub struct zc_shared_memory_client_callbacks_t { ) -> bool, } -/// A SharedMemoryClient +/// A loaned SharedMemoryClient +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(C)] +pub struct z_shared_memory_client_t<'a>(&'a z_owned_shared_memory_client_t); + +/// An owned SharedMemoryClient +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. #[cfg(target_arch = "x86_64")] #[repr(C, align(8))] -pub struct z_shared_memory_client_t([u64; 2]); +pub struct z_owned_shared_memory_client_t([u64; 2]); #[cfg(target_arch = "aarch64")] #[repr(C, align(16))] -pub struct z_shared_memory_client_t([u64; 2]); +pub struct z_owned_shared_memory_client_t([u64; 2]); #[cfg(target_arch = "arm")] #[repr(C, align(8))] -pub struct z_shared_memory_client_t([u64; 2]); +pub struct z_owned_shared_memory_client_t([u64; 2]); -decl_rust_copy_type!( - zenoh:(Box), - c:(z_shared_memory_client_t) +decl_rust_new_owned_type!( + zenoh:(Option>), + c:(z_owned_shared_memory_client_t) ); #[derive(Debug)] @@ -89,21 +105,52 @@ impl SharedMemoryClient for DynamicSharedMemoryClient { #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_shared_memory_client_new( +pub unsafe extern "C" fn z_owned_shared_memory_client_new( + out_client: &mut z_owned_shared_memory_client_t, context: zc_threadsafe_context_t, callbacks: zc_shared_memory_client_callbacks_t, - out_client: &mut MaybeUninit, -) { - let client = Box::new(DynamicSharedMemoryClient::new( +) -> i32 { + let out_client = prepare_memory_to_init!(out_client); + + let client = Arc::new(DynamicSharedMemoryClient::new( context.transmute(), callbacks, - )) as Box; + )) as Arc; - out_client.write(client.transmute()); + *out_client = Some(client); + 0 +} + +/// Initializes a null memory for safe-to-drop value of 'z_owned_shared_memory_client_t' type +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub extern "C" fn z_owned_shared_memory_client_null( + out_client: &mut z_owned_shared_memory_client_t, +) { + out_client.make_null(); } +/// Returns ``true`` if `client` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_shared_memory_client_delete(client: z_shared_memory_client_t) { - let _ = client.transmute(); +pub extern "C" fn z_owned_shared_memory_client_check( + client: &z_owned_shared_memory_client_t, +) -> bool { + client.check() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_owned_shared_memory_client_delete( + out_client: &mut z_owned_shared_memory_client_t, +) { + out_client.delete(); +} + +/// Returns a :c:type:`z_shared_memory_client_t` loaned from `client`. +#[no_mangle] +pub extern "C" fn z_owned_shared_memory_client_loan( + client: &z_owned_shared_memory_client_t, +) -> z_shared_memory_client_t { + z_shared_memory_client_t(client) } diff --git a/src/shm/client_storage/mod.rs b/src/shm/client_storage/mod.rs index 7fb5dc382..1181eeeca 100644 --- a/src/shm/client_storage/mod.rs +++ b/src/shm/client_storage/mod.rs @@ -21,115 +21,181 @@ use zenoh::{ }; use crate::{ - client::shared_memory_client::z_shared_memory_client_t, common::types::z_protocol_id_t, - decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute, + access_owned_memory, client::shared_memory_client::z_owned_shared_memory_client_t, + common::types::z_protocol_id_t, decl_rust_new_owned_type, impl_guarded_transmute, + move_owned_memory, prepare_memory_to_init, GuardedTransmute, }; -use std::{mem::MaybeUninit, sync::Arc}; +use std::sync::Arc; -/// A list of SharedMemoryClients. +/// A loaned list of SharedMemoryClients +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(C)] +pub struct zc_shared_memory_client_list_t<'a>(&'a zc_owned_shared_memory_client_list_t); + +/// An owned list of SharedMemoryClients +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. #[cfg(target_arch = "x86_64")] #[repr(C, align(8))] -pub struct zc_shared_memory_client_list_t([u64; 3]); +pub struct zc_owned_shared_memory_client_list_t([u64; 3]); #[cfg(target_arch = "aarch64")] #[repr(C, align(16))] -pub struct zc_shared_memory_client_list_t([u64; 4]); +pub struct zc_owned_shared_memory_client_list_t([u64; 4]); #[cfg(target_arch = "arm")] #[repr(C, align(8))] -pub struct zc_shared_memory_client_list_t([u64; 3]); +pub struct zc_owned_shared_memory_client_list_t([u64; 3]); -decl_rust_copy_type!( - zenoh:(Vec<(ProtocolID, Box)>), - c:(zc_shared_memory_client_list_t) +decl_rust_new_owned_type!( + zenoh:(Option)>>), + c:(zc_owned_shared_memory_client_list_t) ); #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_shared_memory_client_list_new() -> zc_shared_memory_client_list_t { - let result = Vec::default(); - result.transmute() +pub unsafe extern "C" fn zc_shared_memory_client_list_new( + out: &mut zc_owned_shared_memory_client_list_t, +) -> i32 { + let out = prepare_memory_to_init!(out); + *out = Some(Vec::default()); + 0 } +/// Initializes a null memory for safe-to-drop value of 'zc_owned_shared_memory_client_list_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_shared_memory_client_list_add_client( - id: z_protocol_id_t, - client: z_shared_memory_client_t, - list: &mut zc_shared_memory_client_list_t, +pub extern "C" fn zc_shared_memory_client_list_null( + out: &mut zc_owned_shared_memory_client_list_t, ) { - list.transmute_mut().push((id, client.transmute())); + out.make_null(); +} + +/// Returns ``true`` if `list` is valid. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub extern "C" fn zc_shared_memory_client_list_check( + list: &zc_owned_shared_memory_client_list_t, +) -> bool { + list.check() } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn zc_shared_memory_client_list_delete(list: zc_shared_memory_client_list_t) { - let _ = list.transmute(); +pub unsafe extern "C" fn zc_shared_memory_client_list_delete( + out_client: &mut zc_owned_shared_memory_client_list_t, +) { + out_client.delete(); +} + +/// Returns a :c:type:`zc_shared_memory_client_list_t` loaned from `list`. +#[no_mangle] +pub extern "C" fn zc_shared_memory_client_list_loan( + list: &zc_owned_shared_memory_client_list_t, +) -> zc_shared_memory_client_list_t { + zc_shared_memory_client_list_t(list) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn zc_shared_memory_client_list_add_client( + id: z_protocol_id_t, + client: &mut z_owned_shared_memory_client_t, + list: zc_shared_memory_client_list_t, +) -> i32 { + access_owned_memory!(list.0, |list: &mut Vec<_>| { + move_owned_memory!(client, |client| { + list.push((id, client)); + 0 + }) + }) } /// A SharedMemoryClientStorage. #[repr(C)] -pub struct z_shared_memory_client_storage_t(usize); +pub struct z_owned_shared_memory_client_storage_t(usize); -decl_rust_copy_type!( - zenoh:(Arc), - c:(z_shared_memory_client_storage_t) +decl_rust_new_owned_type!( + zenoh:(Option>), + c:(z_owned_shared_memory_client_storage_t) ); #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_shared_memory_client_storage_global() -> z_shared_memory_client_storage_t -{ - let result = GLOBAL_CLIENT_STORAGE.clone(); - result.transmute() +pub unsafe extern "C" fn z_shared_memory_client_storage_global( + out: &mut z_owned_shared_memory_client_storage_t, +) -> i32 { + let out = prepare_memory_to_init!(out); + *out = Some(GLOBAL_CLIENT_STORAGE.clone()); + 0 } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_shared_memory_client_storage_deref( - storage: z_shared_memory_client_storage_t, -) { - let _ = storage.transmute(); +pub unsafe extern "C" fn z_owned_shared_memory_client_storage_new( + out: &mut z_owned_shared_memory_client_storage_t, + clients: zc_shared_memory_client_list_t, +) -> i32 { + let out = prepare_memory_to_init!(out); + access_owned_memory!(clients.0, |list: &Vec<_>| { + if list.is_empty() { + return -5; // todo: E_ARGUMENT_INVALID + } + let builder = SharedMemoryClientStorage::builder().with_clients(list); + *out = Some(Arc::new(builder.build())); + 0 + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_shared_memory_client_storage_new( +pub unsafe extern "C" fn z_owned_shared_memory_client_storage_new_with_default_client_set( + out: &mut z_owned_shared_memory_client_storage_t, clients: zc_shared_memory_client_list_t, - out_storage: &mut MaybeUninit, -) -> bool { - let mut clients = clients.transmute(); - - if let Some((id, client)) = clients.pop() { - let mut builder = SharedMemoryClientStorage::builder().with_client(id, client); - - for (id, client) in clients.drain(0..) { - match builder.with_client(id, client) { - Ok(b) => builder = b, - Err(_) => return false, - } +) -> i32 { + let out = prepare_memory_to_init!(out); + access_owned_memory!(clients.0, |list: &Vec<_>| { + if list.is_empty() { + return -5; // todo: E_ARGUMENT_INVALID } - out_storage.write(Arc::new(builder.build()).transmute()); - return true; - } - false + let builder = SharedMemoryClientStorage::builder() + .with_default_client_set() + .with_clients(list); + *out = Some(Arc::new(builder.build())); + 0 + }) } +/// Initializes a null memory for safe-to-drop value of 'z_owned_shared_memory_client_storage_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_shared_memory_client_storage_new_with_default_client_set( - clients: zc_shared_memory_client_list_t, - out_storage: &mut MaybeUninit, +pub extern "C" fn z_shared_memory_client_storage_null( + out: &mut z_owned_shared_memory_client_storage_t, +) { + out.make_null(); +} + +/// Returns ``true`` if `storage` is valid. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub extern "C" fn z_shared_memory_client_storage_check( + storage: &z_owned_shared_memory_client_storage_t, ) -> bool { - let mut clients = clients.transmute(); - let mut builder = SharedMemoryClientStorage::builder().with_default_client_set(); + storage.check() +} - for (id, client) in clients.drain(0..) { - match builder.with_client(id, client) { - Ok(b) => builder = b, - Err(_) => return false, - } - } - out_storage.write(Arc::new(builder.build()).transmute()); - true +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_client_storage_deref( + storage: &mut z_owned_shared_memory_client_storage_t, +) { + storage.delete(); } diff --git a/src/shm/protocol_implementations/posix/posix_shared_memory_client.rs b/src/shm/protocol_implementations/posix/posix_shared_memory_client.rs index 2818c1742..debbc9420 100644 --- a/src/shm/protocol_implementations/posix/posix_shared_memory_client.rs +++ b/src/shm/protocol_implementations/posix/posix_shared_memory_client.rs @@ -12,16 +12,25 @@ // ZettaScale Zenoh Team, // +use std::sync::Arc; + use zenoh::shm::{ client::shared_memory_client::SharedMemoryClient, protocol_implementations::posix::posix_shared_memory_client::PosixSharedMemoryClient, }; -use crate::{client::shared_memory_client::z_shared_memory_client_t, GuardedTransmute}; +use crate::{ + client::shared_memory_client::z_owned_shared_memory_client_t, prepare_memory_to_init, + GuardedTransmute, +}; #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_posix_shared_memory_client_new() -> z_shared_memory_client_t { - let client = Box::new(PosixSharedMemoryClient) as Box; - client.transmute() +pub unsafe extern "C" fn z_posix_shared_memory_client_new( + out_client: &mut z_owned_shared_memory_client_t, +) -> i32 { + let out_client = prepare_memory_to_init!(out_client); + let client = Arc::new(PosixSharedMemoryClient) as Arc; + *out_client = Some(client); + 0 } diff --git a/src/shm/provider/alloc_layout.rs b/src/shm/provider/alloc_layout.rs index 68ffbc0a4..b6d1f88a8 100644 --- a/src/shm/provider/alloc_layout.rs +++ b/src/shm/provider/alloc_layout.rs @@ -12,102 +12,139 @@ // ZettaScale Zenoh Team, // -use std::mem::MaybeUninit; - use zenoh::shm::provider::shared_memory_provider::{ AllocLayout, BlockOn, Deallocate, Defragment, DynamicProtocolID, GarbageCollect, JustAlloc, }; -use crate::{decl_rust_copy_type, impl_guarded_transmute, Context, GuardedTransmute}; +use crate::{ + access_owned_memory, decl_rust_new_owned_type, impl_guarded_transmute, prepare_memory_to_init, + Context, GuardedTransmute, +}; use super::{ - shared_memory_provider_backend::DynamicSharedMemoryProviderBackend, types::z_buf_alloc_result_t, + shared_memory_provider_backend::DynamicSharedMemoryProviderBackend, + types::z_owned_buf_alloc_result_t, }; +/// A loaned non-thread-safe SharedMemoryProvider's AllocLayout +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(C)] +pub struct z_alloc_layout_t<'a>(&'a z_owned_alloc_layout_t); + /// A non-thread-safe SharedMemoryProvider's AllocLayout #[cfg(target_arch = "x86_64")] #[repr(C, align(8))] -pub struct z_alloc_layout_t([u64; 4]); +pub struct z_owned_alloc_layout_t([u64; 4]); #[cfg(target_arch = "aarch64")] #[repr(C, align(16))] -pub struct z_alloc_layout_t([u64; 14]); +pub struct z_owned_alloc_layout_t([u64; 14]); #[cfg(target_arch = "arm")] #[repr(C, align(8))] -pub struct z_alloc_layout_t([u64; 14]); +pub struct z_owned_alloc_layout_t([u64; 14]); -decl_rust_copy_type!( - zenoh:(AllocLayout<'static, DynamicProtocolID, DynamicSharedMemoryProviderBackend>), - c:(z_alloc_layout_t) +decl_rust_new_owned_type!( + zenoh:(Option>>), + c:(z_owned_alloc_layout_t) ); +/// Initializes a null memory for safe-to-drop value of 'z_owned_alloc_layout_t' type +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub extern "C" fn z_alloc_layout_null(out: &mut z_owned_alloc_layout_t) { + out.make_null(); +} + +/// Returns ``true`` if `layout` is valid. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub extern "C" fn z_alloc_layout_check(layout: &z_owned_alloc_layout_t) -> bool { + layout.check() +} + #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_alloc_layout_delete(layout: z_alloc_layout_t) { - let _ = layout.transmute(); +pub unsafe extern "C" fn z_alloc_layout_delete(layout: &mut z_owned_alloc_layout_t) { + layout.delete(); } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_alloc_layout_alloc( - layout: &z_alloc_layout_t, - out_buffer: &mut MaybeUninit, -) { - let layout = layout.transmute_ref(); - let buffer = layout.alloc().with_policy::().res(); - out_buffer.write(buffer.transmute()); + out_buffer: &mut z_owned_buf_alloc_result_t, + layout: z_alloc_layout_t, +) -> i32 { + access_owned_memory!(layout.0, |layout: &AllocLayout<_, _>| { + let out_buffer = prepare_memory_to_init!(out_buffer); + let buffer = layout.alloc().with_policy::().res(); + *out_buffer = Some(buffer); + 0 + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_alloc_layout_alloc_gc( - layout: &z_alloc_layout_t, - out_buffer: &mut MaybeUninit, -) { - let layout = layout.transmute_ref(); - let buffer = layout.alloc().with_policy::().res(); - out_buffer.write(buffer.transmute()); + out_buffer: &mut z_owned_buf_alloc_result_t, + layout: z_alloc_layout_t, +) -> i32 { + access_owned_memory!(layout.0, |layout: &AllocLayout<_, _>| { + let out_buffer = prepare_memory_to_init!(out_buffer); + let buffer = layout.alloc().with_policy::().res(); + *out_buffer = Some(buffer); + 0 + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_alloc_layout_alloc_gc_defrag( - layout: &z_alloc_layout_t, - out_buffer: &mut MaybeUninit, -) { - let layout = layout.transmute_ref(); - let buffer = layout - .alloc() - .with_policy::>() - .res(); - out_buffer.write(buffer.transmute()); + out_buffer: &mut z_owned_buf_alloc_result_t, + layout: z_alloc_layout_t, +) -> i32 { + access_owned_memory!(layout.0, |layout: &AllocLayout<_, _>| { + let out_buffer = prepare_memory_to_init!(out_buffer); + let buffer = layout + .alloc() + .with_policy::>() + .res(); + *out_buffer = Some(buffer); + 0 + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_alloc_layout_alloc_gc_defrag_dealloc( - layout: &z_alloc_layout_t, - out_buffer: &mut MaybeUninit, -) { - let layout = layout.transmute_ref(); - let buffer = layout - .alloc() - .with_policy::>>() - .res(); - out_buffer.write(buffer.transmute()); + out_buffer: &mut z_owned_buf_alloc_result_t, + layout: z_alloc_layout_t, +) -> i32 { + access_owned_memory!(layout.0, |layout: &AllocLayout<_, _>| { + let out_buffer = prepare_memory_to_init!(out_buffer); + let buffer = layout + .alloc() + .with_policy::>>() + .res(); + *out_buffer = Some(buffer); + 0 + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_alloc_layout_alloc_gc_defrag_blocking( - layout: &z_alloc_layout_t, - out_buffer: &mut MaybeUninit, -) { - let layout = layout.transmute_ref(); - let buffer = layout - .alloc() - .with_policy::>>() - .res(); - out_buffer.write(buffer.transmute()); + out_buffer: &mut z_owned_buf_alloc_result_t, + layout: z_alloc_layout_t, +) -> i32 { + access_owned_memory!(layout.0, |layout: &AllocLayout<_, _>| { + let out_buffer = prepare_memory_to_init!(out_buffer); + let buffer = layout + .alloc() + .with_policy::>>() + .res(); + *out_buffer = Some(buffer); + 0 + }) } diff --git a/src/shm/provider/alloc_layout_threadsafe.rs b/src/shm/provider/alloc_layout_threadsafe.rs index 3b1d42c02..0b41ab9f8 100644 --- a/src/shm/provider/alloc_layout_threadsafe.rs +++ b/src/shm/provider/alloc_layout_threadsafe.rs @@ -12,129 +12,172 @@ // ZettaScale Zenoh Team, // -use std::mem::MaybeUninit; - use libc::c_void; use zenoh::shm::provider::shared_memory_provider::{ AllocLayout, BlockOn, Deallocate, Defragment, DynamicProtocolID, GarbageCollect, JustAlloc, }; use crate::{ - decl_rust_copy_type, impl_guarded_transmute, zc_threadsafe_context_t, DroppableContext, - GuardedTransmute, ThreadsafeContext, + access_owned_memory, decl_rust_new_owned_type, impl_guarded_transmute, prepare_memory_to_init, + zc_threadsafe_context_t, DroppableContext, GuardedTransmute, ThreadsafeContext, }; use super::{ - shared_memory_provider_backend::DynamicSharedMemoryProviderBackend, types::z_buf_alloc_result_t, + shared_memory_provider_backend::DynamicSharedMemoryProviderBackend, + types::z_owned_buf_alloc_result_t, }; +/// A loaned thread-safe SharedMemoryProvider's AllocLayout +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(C)] +pub struct z_alloc_layout_threadsafe_t<'a>(&'a z_owned_alloc_layout_threadsafe_t); + /// A thread-safe SharedMemoryProvider's AllocLayout #[cfg(target_arch = "x86_64")] #[repr(C, align(8))] -pub struct z_alloc_layout_threadsafe_t([u64; 4]); +pub struct z_owned_alloc_layout_threadsafe_t([u64; 4]); #[cfg(target_arch = "aarch64")] #[repr(C, align(16))] -pub struct z_alloc_layout_threadsafe_t([u64; 14]); +pub struct z_owned_alloc_layout_threadsafe_t([u64; 4]); #[cfg(target_arch = "arm")] #[repr(C, align(8))] -pub struct z_alloc_layout_threadsafe_t([u64; 14]); +pub struct z_owned_alloc_layout_threadsafe_t([u64; 4]); -decl_rust_copy_type!( - zenoh:(AllocLayout<'static, DynamicProtocolID, DynamicSharedMemoryProviderBackend>), - c:(z_alloc_layout_threadsafe_t) +decl_rust_new_owned_type!( + zenoh:(Option>>), + c:(z_owned_alloc_layout_threadsafe_t) ); +/// Initializes a null memory for safe-to-drop value of 'z_owned_alloc_layout_threadsafe_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_alloc_layout_threadsafe_delete(layout: z_alloc_layout_threadsafe_t) { - let _ = layout.transmute(); +pub extern "C" fn z_alloc_layout_threadsafe_null( + out: &mut z_owned_alloc_layout_threadsafe_t, +) { + out.make_null(); } +/// Returns ``true`` if `layout` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc( - layout: &z_alloc_layout_threadsafe_t, - out_buffer: &mut MaybeUninit, +pub extern "C" fn z_alloc_layout_threadsafe_check( + layout: &z_owned_alloc_layout_threadsafe_t, +) -> bool { + layout.check() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_threadsafe_delete( + layout: &mut z_owned_alloc_layout_threadsafe_t, ) { - let layout = layout.transmute_ref(); - let buffer = layout.alloc().with_policy::().res(); - out_buffer.write(buffer.transmute()); + layout.delete(); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc( + out_buffer: &mut z_owned_buf_alloc_result_t, + layout: z_alloc_layout_threadsafe_t, +) -> i32 { + access_owned_memory!(layout.0, |layout: &AllocLayout<_, _>| { + let out_buffer = prepare_memory_to_init!(out_buffer); + let buffer = layout.alloc().with_policy::().res(); + *out_buffer = Some(buffer); + 0 + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc_gc( - layout: &z_alloc_layout_threadsafe_t, - out_buffer: &mut MaybeUninit, -) { - let layout = layout.transmute_ref(); - let buffer = layout.alloc().with_policy::().res(); - out_buffer.write(buffer.transmute()); + out_buffer: &mut z_owned_buf_alloc_result_t, + layout: z_alloc_layout_threadsafe_t, +) -> i32 { + access_owned_memory!(layout.0, |layout: &AllocLayout<_, _>| { + let out_buffer = prepare_memory_to_init!(out_buffer); + let buffer = layout.alloc().with_policy::().res(); + *out_buffer = Some(buffer); + 0 + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc_gc_defrag( - layout: &z_alloc_layout_threadsafe_t, - out_buffer: &mut MaybeUninit, -) { - let layout = layout.transmute_ref(); - let buffer = layout - .alloc() - .with_policy::>() - .res(); - out_buffer.write(buffer.transmute()); + out_buffer: &mut z_owned_buf_alloc_result_t, + layout: z_alloc_layout_threadsafe_t, +) -> i32 { + access_owned_memory!(layout.0, |layout: &AllocLayout<_, _>| { + let out_buffer = prepare_memory_to_init!(out_buffer); + let buffer = layout + .alloc() + .with_policy::>() + .res(); + *out_buffer = Some(buffer); + 0 + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc_gc_defrag_dealloc( - layout: &z_alloc_layout_threadsafe_t, - out_buffer: &mut MaybeUninit, -) { - let layout = layout.transmute_ref(); - let buffer = layout - .alloc() - .with_policy::>>() - .res(); - out_buffer.write(buffer.transmute()); + out_buffer: &mut z_owned_buf_alloc_result_t, + layout: z_alloc_layout_threadsafe_t, +) -> i32 { + access_owned_memory!(layout.0, |layout: &AllocLayout<_, _>| { + let out_buffer = prepare_memory_to_init!(out_buffer); + let buffer = layout + .alloc() + .with_policy::>>() + .res(); + *out_buffer = Some(buffer); + 0 + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc_gc_defrag_blocking( - layout: &z_alloc_layout_threadsafe_t, - out_buffer: &mut MaybeUninit, -) { - let layout = layout.transmute_ref(); - let buffer = layout - .alloc() - .with_policy::>>() - .res(); - out_buffer.write(buffer.transmute()); + out_buffer: &mut z_owned_buf_alloc_result_t, + layout: z_alloc_layout_threadsafe_t, +) -> i32 { + access_owned_memory!(layout.0, |layout: &AllocLayout<_, _>| { + let out_buffer = prepare_memory_to_init!(out_buffer); + let buffer = layout + .alloc() + .with_policy::>>() + .res(); + *out_buffer = Some(buffer); + 0 + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_alloc_layout_threadsafe_alloc_gc_defrag_async( - layout: &'static z_alloc_layout_threadsafe_t, - out_buffer: &'static mut MaybeUninit, + out_buffer: &mut z_owned_buf_alloc_result_t, + layout: z_alloc_layout_threadsafe_t, + result_context: zc_threadsafe_context_t, - result_callback: unsafe extern "C" fn(*mut c_void, &mut MaybeUninit), -) { - let result_context = result_context.transmute(); + result_callback: unsafe extern "C" fn(*mut c_void, &mut z_owned_buf_alloc_result_t), +) -> i32 { + let transmuted_out_buffer = prepare_memory_to_init!(out_buffer); //todo: this should be ported to tokio with executor argument support - async_std::task::block_on(async move { - let layout = layout.transmute_ref(); - let buffer = layout - .alloc() - .with_policy::>>() - .res_async() - .await; - out_buffer.write(buffer.transmute()); - - (result_callback)(result_context.get(), out_buffer); - }); + access_owned_memory!(layout.0, |layout: &AllocLayout<_, _>| { + async_std::task::spawn(async move { + let buffer = layout + .alloc() + .with_policy::>>() + .res_async() + .await; + *transmuted_out_buffer = Some(buffer); + let result_context = result_context.transmute(); + (result_callback)(result_context.get(), out_buffer); + }); + 0 + }) } diff --git a/src/shm/provider/shared_memory_provider.rs b/src/shm/provider/shared_memory_provider.rs index ae630f3e7..68ce03258 100644 --- a/src/shm/provider/shared_memory_provider.rs +++ b/src/shm/provider/shared_memory_provider.rs @@ -30,8 +30,8 @@ use super::{ zc_shared_memory_provider_backend_callbacks_t, DynamicSharedMemoryProviderBackend, }, shared_memory_provider_impl::alloc, - types::{z_alloc_alignment_t, z_buf_alloc_result_t}, - zsliceshm::z_slice_shm_t, + types::{z_alloc_alignment_t, z_owned_buf_alloc_result_t}, + zsliceshm::z_slice_shm_mut_t, }; /// A non-thread-safe SharedMemoryProvider specialization @@ -80,7 +80,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_alloc( provider: &z_shared_memory_provider_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { alloc_inner::(provider, size, alignment, out_buffer) } @@ -91,7 +91,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc( provider: &z_shared_memory_provider_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { alloc_inner::(provider, size, alignment, out_buffer) } @@ -102,7 +102,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc_defrag( provider: &z_shared_memory_provider_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { alloc_inner::>(provider, size, alignment, out_buffer) } @@ -113,7 +113,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc_defrag_dealloc( provider: &z_shared_memory_provider_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { alloc_inner::>>( provider, size, alignment, out_buffer, @@ -126,7 +126,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc_defrag_blocking( provider: &z_shared_memory_provider_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { alloc_inner::>>(provider, size, alignment, out_buffer) } @@ -136,7 +136,7 @@ unsafe fn alloc_inner( provider: &z_shared_memory_provider_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { alloc::(provider, size, alignment, out_buffer) } @@ -171,7 +171,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_map( provider: &z_shared_memory_provider_t, allocated_chunk: z_allocated_chunk_t, len: usize, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { let provider = provider.transmute_ref(); match provider.map(allocated_chunk.transmute(), len) { diff --git a/src/shm/provider/shared_memory_provider_impl.rs b/src/shm/provider/shared_memory_provider_impl.rs index 39d217036..407faddd4 100644 --- a/src/shm/provider/shared_memory_provider_impl.rs +++ b/src/shm/provider/shared_memory_provider_impl.rs @@ -22,7 +22,7 @@ use crate::{DroppableContext, GuardedTransmute, ThreadsafeContext}; use super::{ shared_memory_provider_backend::DynamicSharedMemoryProviderBackend, - types::{z_alloc_alignment_t, z_buf_alloc_result_t}, + types::{z_alloc_alignment_t, z_owned_buf_alloc_result_t}, }; #[allow(clippy::missing_safety_doc)] @@ -30,7 +30,7 @@ pub(crate) unsafe fn alloc( provider: &TAnyProvider, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool where TAnyContext: DroppableContext, @@ -62,7 +62,7 @@ pub(crate) async fn alloc_async( provider: &TThreadsafeProvider, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool where TThreadsafeProvider: GuardedTransmute< diff --git a/src/shm/provider/shared_memory_provider_threadsafe.rs b/src/shm/provider/shared_memory_provider_threadsafe.rs index ffd22010b..544a6e013 100644 --- a/src/shm/provider/shared_memory_provider_threadsafe.rs +++ b/src/shm/provider/shared_memory_provider_threadsafe.rs @@ -26,14 +26,14 @@ use crate::{ }; use super::{ - alloc_layout_threadsafe::z_alloc_layout_threadsafe_t, + alloc_layout_threadsafe::z_owned_alloc_layout_threadsafe_t, chunk::z_allocated_chunk_t, shared_memory_provider_backend::{ zc_shared_memory_provider_backend_callbacks_t, DynamicSharedMemoryProviderBackend, }, shared_memory_provider_impl::{alloc, alloc_async}, - types::{z_alloc_alignment_t, z_buf_alloc_result_t}, - zsliceshm::z_slice_shm_t, + types::{z_alloc_alignment_t, z_owned_buf_alloc_result_t}, + zsliceshm::z_slice_shm_mut_t, }; /// A thread-safe SharedMemoryProvider specialization @@ -80,11 +80,11 @@ pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_delete( #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_layout( - provider: &'static z_shared_memory_provider_threadsafe_t, +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_layout<'a>( + out_layout: &'a mut z_owned_alloc_layout_threadsafe_t, + provider: &'a z_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_layout: &mut MaybeUninit, ) -> bool { let provider = provider.transmute_ref(); match provider @@ -110,7 +110,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc( provider: &z_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { alloc_inner::(provider, size, alignment, out_buffer) } @@ -121,7 +121,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc( provider: &z_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { alloc_inner::(provider, size, alignment, out_buffer) } @@ -132,7 +132,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag( provider: &z_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { alloc_inner::>(provider, size, alignment, out_buffer) } @@ -143,7 +143,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag_dea provider: &z_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { alloc_inner::>>( provider, size, alignment, out_buffer, @@ -156,7 +156,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag_blo provider: &z_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { alloc_inner::>>(provider, size, alignment, out_buffer) } @@ -167,12 +167,12 @@ pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag_asy provider: &z_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, result_context: zc_threadsafe_context_t, result_callback: unsafe extern "C" fn( *mut c_void, bool, - &mut MaybeUninit, + &mut MaybeUninit, ), ) { let result_context = result_context.transmute(); @@ -192,7 +192,7 @@ unsafe fn alloc_inner( provider: &z_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { alloc::( provider, size, alignment, out_buffer, @@ -229,7 +229,7 @@ pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_map( provider: &z_shared_memory_provider_threadsafe_t, allocated_chunk: z_allocated_chunk_t, len: usize, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { let provider = provider.transmute_ref(); match provider.map(allocated_chunk.transmute(), len) { diff --git a/src/shm/provider/types.rs b/src/shm/provider/types.rs index 278449714..bc821d776 100644 --- a/src/shm/provider/types.rs +++ b/src/shm/provider/types.rs @@ -19,9 +19,9 @@ use zenoh::shm::provider::types::{ }; use zenoh_util::core::zerror; -use crate::{decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute}; +use crate::{decl_rust_new_owned_type, decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute}; -use super::{chunk::z_allocated_chunk_t, zsliceshm::z_slice_shm_t}; +use super::{chunk::z_allocated_chunk_t, zsliceshm::z_slice_shm_mut_t}; /// Allocation errors /// @@ -163,28 +163,34 @@ pub unsafe extern "C" fn z_chunk_alloc_result_delete(result: z_chunk_alloc_resul let _ = result.transmute(); } +/// A loaned BufAllocResult +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(C)] +pub struct z_buf_alloc_result_t<'a>(&'a z_owned_buf_alloc_result_t); + // A BufAllocResult #[cfg(target_arch = "x86_64")] #[repr(C, align(8))] -pub struct z_buf_alloc_result_t([u64; 10]); +pub struct z_owned_buf_alloc_result_t([u64; 11]); #[cfg(target_arch = "aarch64")] #[repr(C, align(16))] -pub struct z_buf_alloc_result_t([u64; 10]); +pub struct z_owned_buf_alloc_result_t([u64; 12]); #[cfg(target_arch = "arm")] #[repr(C, align(8))] -pub struct z_buf_alloc_result_t([u64; 10]); -decl_rust_copy_type!( - zenoh:(BufAllocResult), - c:(z_buf_alloc_result_t) +pub struct z_owned_buf_alloc_result_t([u64; 11]); +decl_rust_new_owned_type!( + zenoh:(Option), + c:(z_owned_buf_alloc_result_t) ); #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_buf_alloc_result_unwrap( - alloc_result: z_buf_alloc_result_t, - out_buf: &mut MaybeUninit, +pub unsafe extern "C" fn z_owned_buf_alloc_result_unwrap( + alloc_result: z_owned_buf_alloc_result_t, + out_buf: &mut MaybeUninit, out_error: &mut MaybeUninit, ) -> bool { match alloc_result.transmute() { @@ -201,6 +207,6 @@ pub unsafe extern "C" fn z_buf_alloc_result_unwrap( #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_buf_alloc_result_delete(result: z_buf_alloc_result_t) { +pub unsafe extern "C" fn z_owned_buf_alloc_result_delete(result: z_owned_buf_alloc_result_t) { let _ = result.transmute(); } diff --git a/src/shm/provider/zsliceshm.rs b/src/shm/provider/zsliceshm.rs index 376f87e59..90861d875 100644 --- a/src/shm/provider/zsliceshm.rs +++ b/src/shm/provider/zsliceshm.rs @@ -12,30 +12,30 @@ // ZettaScale Zenoh Team, // -use zenoh::shm::provider::zsliceshm::ZSliceShm; +use zenoh::shm::provider::zsliceshmmut::ZSliceShmMut; use crate::{decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute}; // A ZSliceSHM #[cfg(target_arch = "x86_64")] #[repr(C, align(8))] -pub struct z_slice_shm_t([u64; 10]); +pub struct z_slice_shm_mut_t([u64; 10]); #[cfg(target_arch = "aarch64")] #[repr(C, align(16))] -pub struct z_slice_shm_t([u64; 10]); +pub struct z_slice_shm_mut_t([u64; 10]); #[cfg(target_arch = "arm")] #[repr(C, align(8))] -pub struct z_slice_shm_t([u64; 10]); +pub struct z_slice_shm_mut_t([u64; 10]); decl_rust_copy_type!( - zenoh:(ZSliceShm), - c:(z_slice_shm_t) + zenoh:(ZSliceShmMut), + c:(z_slice_shm_mut_t) ); #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_shm_delete(slice: z_slice_shm_t) { +pub unsafe extern "C" fn z_slice_shm_mut_delete(slice: z_slice_shm_mut_t) { let _ = slice.transmute(); } From b6f05d56bbdc495fa01b67a7afa925b46455cfed Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 23 Apr 2024 14:22:01 +0200 Subject: [PATCH 59/75] removed shm / pull subscriber; updated macros --- Cargo.toml.in | 3 + examples/z_pub_shm.c | 94 ----------- examples/z_pull.c | 86 ---------- include/zenoh_commons.h | 275 ++++++++++++++++---------------- include/zenoh_macros.h | 103 +++++++----- src/collections.rs | 4 +- src/config.rs | 8 +- src/errors.rs | 22 +-- src/get.rs | 2 +- src/info.rs | 4 +- src/keyexpr.rs | 28 ++-- src/liveliness.rs | 8 +- src/payload.rs | 10 +- src/platform/synchronization.rs | 21 ++- src/publication_cache.rs | 4 +- src/publisher.rs | 10 +- src/put.rs | 4 +- src/queryable.rs | 6 +- src/querying_subscriber.rs | 6 +- src/scouting.rs | 2 +- src/session.rs | 2 +- src/subscriber.rs | 6 +- 22 files changed, 281 insertions(+), 427 deletions(-) delete mode 100644 examples/z_pub_shm.c delete mode 100644 examples/z_pull.c diff --git a/Cargo.toml.in b/Cargo.toml.in index af0cd4fa0..b2ef20aa5 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -60,6 +60,9 @@ const_format = "0.2.32" zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} +zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } +zenoh-util = { path = "../zenoh/commons/zenoh-util" } + [build-dependencies] cbindgen = "0.26.0" diff --git a/examples/z_pub_shm.c b/examples/z_pub_shm.c deleted file mode 100644 index c7bb1684d..000000000 --- a/examples/z_pub_shm.c +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -#include -#include -#include -#include - -#include "zenoh.h" - -#define N 10 - -int main(int argc, char **argv) { - char *keyexpr = "demo/example/zenoh-c-pub-shm"; - char *value = "Pub from C!"; - - if (argc > 1) keyexpr = argv[1]; - if (argc > 2) value = argv[2]; - - z_owned_config_t config = z_config_default(); - // Enable shared memory - if (zc_config_insert_json(z_loan(config), "transport/shared_memory/enabled", "true") < 0) { - printf("Error enabling Shared Memory"); - exit(-1); - } - if (argc > 3) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { - printf( - "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " - "JSON-serialized list of strings\n", - argv[3], Z_CONFIG_CONNECT_KEY, Z_CONFIG_CONNECT_KEY); - exit(-1); - } - } - - printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - z_id_t id = z_info_zid(z_loan(s)); - char idstr[33]; - for (int i = 0; i < 16; i++) { - sprintf(idstr + 2 * i, "%02x", id.id[i]); - } - idstr[32] = 0; - zc_owned_shm_manager_t manager = zc_shm_manager_new(z_loan(s), idstr, N * 1000000); - if (!z_check(s)) { - printf("Unable to open session!\n"); - exit(-1); - } - - printf("Declaring Publisher on '%s'...\n", keyexpr); - z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(keyexpr), NULL); - if (!z_check(pub)) { - printf("Unable to declare Publisher for key expression!\n"); - exit(-1); - } - - for (int idx = 0; true; ++idx) { - zc_owned_shmbuf_t shmbuf = zc_shm_alloc(&manager, 256); - if (!z_check(shmbuf)) { - zc_shm_gc(&manager); - shmbuf = zc_shm_alloc(&manager, 256); - if (!z_check(shmbuf)) { - printf("Failed to allocate a SHM buffer, even after GCing\n"); - exit(-1); - } - } - char *buf = (char *)zc_shmbuf_ptr(&shmbuf); - buf[256] = 0; - snprintf(buf, 255, "[%4d] %s", idx, value); - size_t len = strlen(buf); - zc_shmbuf_set_length(&shmbuf, len); - z_sleep_s(1); - printf("Putting Data ('%s': '%s')...\n", keyexpr, buf); - z_publisher_put_options_t options = z_publisher_put_options_default(); - options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); - z_owned_bytes_t payload = zc_shmbuf_into_payload(z_move(shmbuf)); - z_publisher_put(z_loan(pub), z_move(payload), &options); - } - - z_undeclare_publisher(z_move(pub)); - - z_close(z_move(s)); - return 0; -} diff --git a/examples/z_pull.c b/examples/z_pull.c deleted file mode 100644 index 8016da577..000000000 --- a/examples/z_pull.c +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -#include -#include "zenoh.h" - -const char *kind_to_str(z_sample_kind_t kind); - -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); - z_owned_str_t payload_value = z_str_null(); - z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); - printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), - z_loan(payload_value)); - z_drop(z_move(payload_value)); - z_drop(z_move(keystr)); -} - -int main(int argc, char **argv) { - char *expr = "demo/example/**"; - if (argc > 1) { - expr = argv[1]; - } - - z_owned_config_t config = z_config_default(); - if (argc > 2) { - if (zc_config_insert_json(z_loan(config), Z_CONFIG_LISTEN_KEY, argv[2]) < 0) { - printf( - "Couldn't insert value `%s` in configuration at `%s`. This is likely because `%s` expects a " - "JSON-serialized list of strings\n", - argv[2], Z_CONFIG_LISTEN_KEY, Z_CONFIG_LISTEN_KEY); - exit(-1); - } - } - - printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { - printf("Unable to open session!\n"); - exit(-1); - } - - z_owned_closure_sample_t callback = z_closure(data_handler); - printf("Declaring Subscriber on '%s'...\n", expr); - z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(expr), z_move(callback), NULL); - if (!z_check(sub)) { - printf("Unable to declare subscriber.\n"); - exit(-1); - } - - printf("Press to pull data...\n"); - char c = 0; - while (c != 'q') { - c = getchar(); - if (c == -1) { - z_sleep_s(1); - } else { - z_subscriber_pull(z_loan(sub)); - } - } - - z_undeclare_pull_subscriber(z_move(sub)); - z_close(z_move(s)); - return 0; -} - -const char *kind_to_str(z_sample_kind_t kind) { - switch (kind) { - case Z_SAMPLE_KIND_PUT: - return "PUT"; - case Z_SAMPLE_KIND_DELETE: - return "DELETE"; - default: - return "UNKNOWN"; - } -} \ No newline at end of file diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 08906c0be..fd817ec0b 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -122,7 +122,7 @@ typedef enum zcu_reply_keyexpr_t { typedef struct ALIGN(8) z_owned_bytes_t { uint8_t _0[40]; } z_owned_bytes_t; -typedef int8_t ZCError; +typedef int8_t z_error_t; /** * A loaned payload. */ @@ -875,17 +875,21 @@ ZENOHC_API void z_bytes_clone(const struct z_owned_bytes_t *src, struct z_owned_ /** * Decodes payload into owned bytes */ -ZENOHC_API ZCError z_bytes_decode_into_bytes(struct z_bytes_t payload, struct z_owned_slice_t *dst); +ZENOHC_API +z_error_t z_bytes_decode_into_bytes(struct z_bytes_t payload, + struct z_owned_slice_t *dst); /** * Decodes payload into bytes map. */ ZENOHC_API -ZCError z_bytes_decode_into_bytes_map(struct z_bytes_t payload, - struct z_owned_slice_map_t *dst); +z_error_t z_bytes_decode_into_bytes_map(struct z_bytes_t payload, + struct z_owned_slice_map_t *dst); /** * Decodes payload into null-terminated string. */ -ZENOHC_API ZCError z_bytes_decode_into_string(struct z_bytes_t payload, struct z_owned_str_t *dst); +ZENOHC_API +z_error_t z_bytes_decode_into_string(struct z_bytes_t payload, + struct z_owned_str_t *dst); /** * Decrements the payload's reference counter, destroying it if applicable. * @@ -948,9 +952,9 @@ size_t z_bytes_reader_read(struct z_bytes_reader_t this_, * Return ​0​ upon success, negative error code otherwise. */ ZENOHC_API -ZCError z_bytes_reader_seek(struct z_bytes_reader_t this_, - int64_t offset, - int origin); +z_error_t z_bytes_reader_seek(struct z_bytes_reader_t this_, + int64_t offset, + int origin); /** * Returns the read position indicator. * Returns read position indicator on success or -1L if failure occurs. @@ -1056,8 +1060,8 @@ ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); ZENOHC_API struct z_condvar_t z_condvar_loan(const struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_null(struct z_owned_condvar_t *this_); -ZENOHC_API ZCError z_condvar_signal(struct z_condvar_t this_); -ZENOHC_API ZCError z_condvar_wait(struct z_condvar_t this_, struct z_mutex_t m); +ZENOHC_API z_error_t z_condvar_signal(struct z_condvar_t this_); +ZENOHC_API z_error_t z_condvar_wait(struct z_condvar_t this_, struct z_mutex_t m); /** * Returns ``true`` if `config` is valid. */ @@ -1067,9 +1071,9 @@ ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); * If `peer` is not null, it is added to the configuration as remote peer. */ ZENOHC_API -ZCError z_config_client(const char *const *peers, - size_t n_peers, - struct z_owned_config_t *this_); +z_error_t z_config_client(const char *const *peers, + size_t n_peers, + struct z_owned_config_t *this_); /** * Clones the config. */ @@ -1111,9 +1115,9 @@ ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); * ease the retrieval of the concerned resource in the routing tables. */ ZENOHC_API -ZCError z_declare_keyexpr(struct z_owned_keyexpr_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr); +z_error_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr); /** * Declares a publisher for the given key expression. * @@ -1150,10 +1154,10 @@ ZCError z_declare_keyexpr(struct z_owned_keyexpr_t *this_, * z_owned_publisher_t sub = z_declare_publisher(z_loan(s), z_keyexpr(expr), &opts); */ ZENOHC_API -ZCError z_declare_publisher(struct z_session_t session, - struct z_keyexpr_t key_expr, - const struct z_publisher_options_t *options, - struct z_owned_publisher_t *this_); +z_error_t z_declare_publisher(struct z_session_t session, + struct z_keyexpr_t key_expr, + const struct z_publisher_options_t *options, + struct z_owned_publisher_t *this_); /** * Creates a Queryable for the given key expression. * @@ -1167,11 +1171,11 @@ ZCError z_declare_publisher(struct z_session_t session, * The created :c:type:`z_owned_queryable_t` or ``null`` if the creation failed. */ ZENOHC_API -ZCError z_declare_queryable(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_query_t *callback, - const struct z_queryable_options_t *options, - struct z_owned_queryable_t *this_); +z_error_t z_declare_queryable(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_query_t *callback, + const struct z_queryable_options_t *options, + struct z_owned_queryable_t *this_); /** * Declare a subscriber for a given key expression. * @@ -1206,11 +1210,11 @@ ZCError z_declare_queryable(struct z_session_t session, * z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); */ ZENOHC_API -ZCError z_declare_subscriber(struct z_owned_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_sample_t *callback, - struct z_subscriber_options_t options); +z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct z_subscriber_options_t options); /** * Delete data. * @@ -1222,9 +1226,9 @@ ZCError z_declare_subscriber(struct z_owned_subscriber_t *this_, * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API -ZCError z_delete(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_delete_options_t opts); +z_error_t z_delete(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_delete_options_t opts); /** * Constructs the default value for :c:type:`z_put_options_t`. */ @@ -1270,11 +1274,11 @@ ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); * options: additional options for the get. */ ZENOHC_API -ZCError z_get(struct z_session_t session, - struct z_keyexpr_t key_expr, - const char *parameters, - struct z_owned_closure_reply_t *callback, - struct z_get_options_t options); +z_error_t z_get(struct z_session_t session, + struct z_keyexpr_t key_expr, + const char *parameters, + struct z_owned_closure_reply_t *callback, + struct z_get_options_t options); ZENOHC_API struct z_get_options_t z_get_options_default(void); /** * Returns ``true`` if `hello` is valid. @@ -1301,8 +1305,8 @@ ZENOHC_API struct z_owned_hello_t z_hello_null(void); * Retuns 0 on success, negative values on failure */ ZENOHC_API -ZCError z_info_peers_zid(struct z_session_t session, - struct z_owned_closure_zid_t *callback); +z_error_t z_info_peers_zid(struct z_session_t session, + struct z_owned_closure_zid_t *callback); /** * Fetches the Zenoh IDs of all connected routers. * @@ -1312,8 +1316,8 @@ ZCError z_info_peers_zid(struct z_session_t session, * Retuns 0 on success, negative values on failure. */ ZENOHC_API -ZCError z_info_routers_zid(struct z_session_t session, - struct z_owned_closure_zid_t *callback); +z_error_t z_info_routers_zid(struct z_session_t session, + struct z_owned_closure_zid_t *callback); /** * Returns the local Zenoh ID. * @@ -1326,7 +1330,7 @@ ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); * Constructs a :c:type:`z_keyexpr_t` departing from a string. * It is a loaned key expression that aliases `name`. */ -ZENOHC_API ZCError z_keyexpr(struct z_owned_keyexpr_t *this_, const char *name); +ZENOHC_API z_error_t z_keyexpr(struct z_owned_keyexpr_t *this_, const char *name); /** * Returns the key expression's internal string by aliasing it. * @@ -1339,8 +1343,8 @@ ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(struct z_keyexpr_t ke); * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). */ ZENOHC_API -ZCError z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, - char *name); +z_error_t z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, + char *name); /** * Canonizes the passed string in place, possibly shortening it by modifying `len`. * @@ -1351,8 +1355,8 @@ ZCError z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). */ ZENOHC_API -ZCError z_keyexpr_canonize(char *start, - size_t *len); +z_error_t z_keyexpr_canonize(char *start, + size_t *len); /** * Canonizes the passed string in place, possibly shortening it by placing a new null-terminator. * @@ -1363,7 +1367,7 @@ ZCError z_keyexpr_canonize(char *start, * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). */ ZENOHC_API -ZCError z_keyexpr_canonize_null_terminated(char *start); +z_error_t z_keyexpr_canonize_null_terminated(char *start); /** * Returns ``true`` if `keyexpr` is valid. */ @@ -1378,10 +1382,10 @@ ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); * as this would extremely likely cause bugs. */ ZENOHC_API -ZCError z_keyexpr_concat(struct z_keyexpr_t left, - const char *right_start, - size_t right_len, - struct z_owned_keyexpr_t *this_); +z_error_t z_keyexpr_concat(struct z_keyexpr_t left, + const char *right_start, + size_t right_len, + struct z_owned_keyexpr_t *this_); /** * Frees `keyexpr` and invalidates it for double-drop safety. */ @@ -1408,15 +1412,15 @@ bool z_keyexpr_intersects(struct z_keyexpr_t left, * Returns ``0`` if the passed string is a valid (and canon) key expression. * Otherwise returns error value */ -ZENOHC_API ZCError z_keyexpr_is_canon(const char *start, size_t len); +ZENOHC_API z_error_t z_keyexpr_is_canon(const char *start, size_t len); /** * Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. * In case of error, the return value will be set to its invalidated state. */ ZENOHC_API -ZCError z_keyexpr_join(struct z_keyexpr_t left, - struct z_keyexpr_t right, - struct z_owned_keyexpr_t *this_); +z_error_t z_keyexpr_join(struct z_keyexpr_t left, + struct z_keyexpr_t right, + struct z_owned_keyexpr_t *this_); /** * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. */ @@ -1424,13 +1428,13 @@ ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *key /** * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. */ -ZENOHC_API ZCError z_keyexpr_new(const char *name, struct z_owned_keyexpr_t *this_); +ZENOHC_API z_error_t z_keyexpr_new(const char *name, struct z_owned_keyexpr_t *this_); /** * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. The copied string is canonized. */ ZENOHC_API -ZCError z_keyexpr_new_autocanonize(const char *name, - struct z_owned_keyexpr_t *this_); +z_error_t z_keyexpr_new_autocanonize(const char *name, + struct z_owned_keyexpr_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type */ @@ -1465,18 +1469,19 @@ void z_keyexpr_unchecked(struct z_owned_keyexpr_t *this_, const char *name); ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); -ZENOHC_API ZCError z_mutex_init(struct z_owned_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_init(struct z_owned_mutex_t *this_); ZENOHC_API struct z_mutex_t z_mutex_loan(const struct z_owned_mutex_t *this_); -ZENOHC_API ZCError z_mutex_lock(struct z_mutex_t this_); -ZENOHC_API ZCError z_mutex_try_lock(struct z_mutex_t this_); -ZENOHC_API ZCError z_mutex_unlock(struct z_mutex_t this_); +ZENOHC_API z_error_t z_mutex_lock(struct z_mutex_t this_); +ZENOHC_API void z_mutex_null(struct z_owned_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_try_lock(struct z_mutex_t this_); +ZENOHC_API z_error_t z_mutex_unlock(struct z_mutex_t this_); /** * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. * Config value is always consumed upon function return. */ ZENOHC_API -ZCError z_open(struct z_owned_session_t *this_, - struct z_owned_config_t *config); +z_error_t z_open(struct z_owned_session_t *this_, + struct z_owned_config_t *config); /** * Returns ``true`` if `pub` is valid. */ @@ -1488,8 +1493,8 @@ ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); * ``0`` in case of success, ``1`` in case of failure. */ ZENOHC_API -ZCError z_publisher_delete(struct z_publisher_t publisher, - struct z_publisher_delete_options_t _options); +z_error_t z_publisher_delete(struct z_publisher_t publisher, + struct z_publisher_delete_options_t _options); /** * Constructs the default values for the delete operation via a publisher entity. * @@ -1530,9 +1535,9 @@ ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API -ZCError z_publisher_put(struct z_publisher_t publisher, - struct z_owned_bytes_t *payload, - struct z_publisher_put_options_t options); +z_error_t z_publisher_put(struct z_publisher_t publisher, + struct z_owned_bytes_t *payload, + struct z_publisher_put_options_t options); /** * Constructs the default value for :c:type:`z_publisher_put_options_t`. */ @@ -1553,10 +1558,10 @@ ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void * ``0`` in case of success, negative error values in case of failure. */ ZENOHC_API -ZCError z_put(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_bytes_t *payload, - struct z_put_options_t options); +z_error_t z_put(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_bytes_t *payload, + struct z_put_options_t options); /** * Constructs the default value for :c:type:`z_put_options_t`. */ @@ -1672,10 +1677,10 @@ struct z_slice_t z_query_parameters(struct z_query_t query); * The payload and all owned options fields are consumed upon function return. */ ZENOHC_API -ZCError z_query_reply(struct z_query_t query, - struct z_keyexpr_t key_expr, - struct z_owned_bytes_t *payload, - struct z_query_reply_options_t options); +z_error_t z_query_reply(struct z_query_t query, + struct z_keyexpr_t key_expr, + struct z_owned_bytes_t *payload, + struct z_query_reply_options_t options); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. */ @@ -1818,8 +1823,8 @@ bool z_sample_timestamp(const struct z_sample_t *sample, * Returns 0 if successful, negative values upon failure. */ ZENOHC_API -ZCError z_scout(struct z_owned_scouting_config_t *config, - struct z_owned_closure_hello_t *callback); +z_error_t z_scout(struct z_owned_scouting_config_t *config, + struct z_owned_closure_hello_t *callback); ZENOHC_API bool z_scouting_config_check(const struct z_owned_scouting_config_t *config); ZENOHC_API void z_scouting_config_default(struct z_owned_scouting_config_t *this_); ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); @@ -1893,18 +1898,18 @@ ZENOHC_API struct z_slice_t z_slice_map_get(struct z_slice_map_t this_, struct z * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. */ ZENOHC_API -ZCError z_slice_map_insert_by_alias(struct z_slice_map_t this_, - struct z_slice_t key, - struct z_slice_t value); +z_error_t z_slice_map_insert_by_alias(struct z_slice_map_t this_, + struct z_slice_t key, + struct z_slice_t value); /** * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. * * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. */ ZENOHC_API -ZCError z_slice_map_insert_by_copy(struct z_slice_map_t this_, - struct z_slice_t key, - struct z_slice_t value); +z_error_t z_slice_map_insert_by_copy(struct z_slice_map_t this_, + struct z_slice_t key, + struct z_slice_t value); /** * Returns true if the map is empty, false otherwise. */ @@ -1994,14 +1999,14 @@ ZENOHC_API bool z_task_check(const struct z_owned_task_t *this_); */ ZENOHC_API void z_task_detach(struct z_owned_task_t *this_); ZENOHC_API -ZCError z_task_init(struct z_owned_task_t *this_, - const struct z_task_attr_t *_attr, - void (*fun)(void *arg), - void *arg); +z_error_t z_task_init(struct z_owned_task_t *this_, + const struct z_task_attr_t *_attr, + void (*fun)(void *arg), + void *arg); /** * Joins the task and releases all allocated resources */ -ZENOHC_API ZCError z_task_join(struct z_owned_task_t *this_); +ZENOHC_API z_error_t z_task_join(struct z_owned_task_t *this_); ZENOHC_API void z_task_null(struct z_owned_task_t *this_); ZENOHC_API uint64_t z_time_elapsed_ms(const struct z_time_t *time); ZENOHC_API uint64_t z_time_elapsed_s(const struct z_time_t *time); @@ -2019,19 +2024,19 @@ ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. */ ZENOHC_API -ZCError z_undeclare_publisher(struct z_owned_publisher_t *publisher); +z_error_t z_undeclare_publisher(struct z_owned_publisher_t *publisher); /** * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. * * Parameters: * qable: The :c:type:`z_owned_queryable_t` to undeclare. */ -ZENOHC_API ZCError z_undeclare_queryable(struct z_owned_queryable_t *qable); +ZENOHC_API z_error_t z_undeclare_queryable(struct z_owned_queryable_t *qable); /** * Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. */ ZENOHC_API -ZCError z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); +z_error_t z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); /** * Converts the kind of zenoh entity into a string. * @@ -2048,16 +2053,16 @@ ZENOHC_API int8_t z_whatami_to_str(uint8_t whatami, char *buf, size_t len); * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. */ ZENOHC_API -ZCError zc_config_from_file(const char *path, - struct z_owned_config_t *this_); +z_error_t zc_config_from_file(const char *path, + struct z_owned_config_t *this_); /** * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. * * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). */ ZENOHC_API -ZCError zc_config_from_str(const char *s, - struct z_owned_config_t *this_); +z_error_t zc_config_from_str(const char *s, + struct z_owned_config_t *this_); /** * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. * Use `z_drop` to safely deallocate this string @@ -2090,18 +2095,18 @@ ZENOHC_API void zc_init_logger(void); * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. */ ZENOHC_API -ZCError zc_keyexpr_from_slice(struct z_owned_keyexpr_t *this_, - const char *name, - size_t len); +z_error_t zc_keyexpr_from_slice(struct z_owned_keyexpr_t *this_, + const char *name, + size_t len); /** * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. * The string is canonized in-place before being passed to keyexpr. * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). */ ZENOHC_API -ZCError zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, - char *name, - size_t *len); +z_error_t zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, + char *name, + size_t *len); /** * Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: * - `name` MUST be valid UTF8. @@ -2135,11 +2140,11 @@ struct zc_liveliness_declaration_options_t zc_liveliness_declaration_options_def * you may use `z_subscriber_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. */ ZENOHC_API -ZCError zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_sample_t *callback, - struct zc_liveliness_declare_subscriber_options_t _options); +z_error_t zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct zc_liveliness_declare_subscriber_options_t _options); /** * Constructs and declares a liveliness token on the network. * @@ -2149,10 +2154,10 @@ ZCError zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, * Passing `NULL` as options is valid and equivalent to a pointer to the default options. */ ZENOHC_API -ZCError zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct zc_liveliness_declaration_options_t _options); +z_error_t zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct zc_liveliness_declaration_options_t _options); /** * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. * @@ -2161,10 +2166,10 @@ ZCError zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. */ ZENOHC_API -ZCError zc_liveliness_get(struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_reply_t *callback, - struct zc_liveliness_get_options_t options); +z_error_t zc_liveliness_get(struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_reply_t *callback, + struct zc_liveliness_get_options_t options); /** * The gravestone value for `zc_liveliness_get_options_t` */ @@ -2182,7 +2187,7 @@ ZENOHC_API void zc_liveliness_token_null(struct zc_owned_liveliness_token_t *thi /** * Destroys a liveliness token, notifying subscribers of its destruction. */ -ZENOHC_API ZCError zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t *this_); +ZENOHC_API z_error_t zc_liveliness_undeclare_token(struct zc_owned_liveliness_token_t *this_); /** * Creates a new blocking fifo channel, returned as a pair of closures. * @@ -2284,9 +2289,9 @@ ZENOHC_API enum zcu_locality_t zcu_locality_default(void); * Register callback for notifying subscribers matching. */ ZENOHC_API -ZCError zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, - struct zcu_owned_closure_matching_status_t *callback, - struct zcu_owned_matching_listener_t *this_); +z_error_t zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, + struct zcu_owned_closure_matching_status_t *callback, + struct zcu_owned_matching_listener_t *this_); ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); /** * Declares a Publication Cache. @@ -2315,10 +2320,10 @@ ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); * ze_owned_publication_cache_t pub_cache = ze_declare_publication_cache(z_loan(s), z_keyexpr(expr), &opts); */ ZENOHC_API -ZCError ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct ze_publication_cache_options_t options); +z_error_t ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct ze_publication_cache_options_t options); /** * Declares a Querying Subscriber for a given key expression. * @@ -2353,11 +2358,11 @@ ZCError ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, * ze_owned_subscriber_t sub = ze_declare_querying_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); */ ZENOHC_API -ZCError ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, - struct z_owned_closure_sample_t *callback, - struct ze_querying_subscriber_options_t options); +z_error_t ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, + struct z_session_t session, + struct z_keyexpr_t key_expr, + struct z_owned_closure_sample_t *callback, + struct ze_querying_subscriber_options_t options); /** * Returns ``true`` if `pub_cache` is valid. */ @@ -2379,9 +2384,9 @@ ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subs * The queried samples will be merged with the received publications and made available in the subscriber callback. */ ZENOHC_API -ZCError ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, - struct z_keyexpr_t selector, - const struct z_get_options_t *options); +z_error_t ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, + struct z_keyexpr_t selector, + const struct z_get_options_t *options); /** * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. */ @@ -2399,9 +2404,9 @@ ZENOHC_API struct ze_querying_subscriber_options_t ze_querying_subscriber_option * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. */ ZENOHC_API -ZCError ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *this_); +z_error_t ze_undeclare_publication_cache(struct ze_owned_publication_cache_t *this_); /** * Undeclares the given :c:type:`ze_owned_querying_subscriber_t`, droping it and invalidating it for double-drop safety. */ ZENOHC_API -ZCError ze_undeclare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_); +z_error_t ze_undeclare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_); diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index a2d0582b1..110f4871a 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -14,8 +14,13 @@ z_owned_hello_t : z_hello_loan, \ z_owned_str_t : z_str_loan, \ z_owned_query_t : z_query_loan, \ - z_owned_bytes_t : z_bytes_loan, \ - ze_owned_querying_subscriber_t : ze_querying_subscriber_loan \ + z_owned_slice_map_t : z_slice_map_loan \ + z_owned_slice_t : z_slice_loan, \ + z_owned_bytes_t : z_bytes_loan, \ + ze_owned_querying_subscriber_t : ze_querying_subscriber_loan,\ + z_owned_mutex_t : z_mutex_loan, \ + z_condvar_t : z_condvar_loan, \ + z_owned_bytes_reader_t : z_bytes_reader_loan, \ )(&x) #define z_drop(x) \ @@ -24,7 +29,6 @@ z_owned_keyexpr_t * : z_keyexpr_drop, \ z_owned_config_t * : z_config_drop, \ z_owned_scouting_config_t * : z_scouting_config_drop, \ - z_owned_pull_subscriber_t * : z_undeclare_pull_subscriber, \ z_owned_subscriber_t * : z_undeclare_subscriber, \ z_owned_queryable_t * : z_undeclare_queryable, \ z_owned_encoding_t * : z_encoding_drop, \ @@ -42,13 +46,16 @@ z_owned_query_channel_closure_t * : z_query_channel_closure_drop, \ z_owned_reply_channel_t * : z_reply_channel_drop, \ z_owned_query_channel_t * : z_query_channel_drop, \ - z_owned_bytes_map_t * : z_slice_map_drop, \ - z_owned_bytes_t * : z_bytes_drop, \ - zc_owned_shmbuf_t * : zc_shmbuf_drop, \ - zc_owned_shm_manager_t * : zc_shm_manager_drop, \ + z_owned_slice_map_t * : z_slice_map_drop, \ + z_owned_slice_t * : z_slice_drop, \ zc_owned_liveliness_token_t * : zc_liveliness_undeclare_token, \ ze_owned_publication_cache_t * : ze_undeclare_publication_cache, \ - ze_owned_querying_subscriber_t * : ze_undeclare_querying_subscriber \ + ze_owned_querying_subscriber_t * : ze_undeclare_querying_subscriber, \ + z_owned_bytes_t * : z_bytes_drop, \ + z_owned_bytes_reader_t * : z_bytes_reader_drop, \ + z_owned_mutex_t * : z_mutex_drop, \ + z_owned_condvar_t * : z_condvar_drop, \ + z_owned_bytes_reader_t * : z_bytes_reader_drop \ )(x) #define z_null(x) (*x = \ @@ -57,7 +64,6 @@ z_owned_keyexpr_t * : z_keyexpr_null, \ z_owned_config_t * : z_config_null, \ z_owned_scouting_config_t * : z_scouting_config_null, \ - z_owned_pull_subscriber_t * : z_pull_subscriber_null, \ z_owned_subscriber_t * : z_subscriber_null, \ z_owned_queryable_t * : z_queryable_null, \ z_owned_encoding_t * : z_encoding_null, \ @@ -73,13 +79,15 @@ zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_null, \ z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ z_owned_reply_channel_t * : z_reply_channel_null, \ - z_owned_bytes_map_t * : z_slice_map_null, \ - z_owned_bytes_t * : z_bytes_null, \ - z_bytes_t * : z_attachment_null, \ - zc_owned_shmbuf_t * : zc_shmbuf_null, \ - zc_owned_shm_manager_t * : zc_shm_manager_null, \ + z_owned_slice_map_t * : z_slice_map_null, \ + z_owned_bytes_t * : z_bytes_null, \ + z_owned_slice_t * : z_slice_null, \ ze_owned_publication_cache_t * : ze_publication_cache_null, \ - zc_owned_liveliness_token_t * : zc_liveliness_token_null \ + zc_owned_liveliness_token_t * : zc_liveliness_token_null, \ + z_owned_bytes_reader_t * : z_bytes_reader_null, \ + z_owned_mutex_t * : z_mutex_null, \ + z_owned_condvar_t * : z_condvar_null, \ + z_owned_task_t * : z_task_null \ )()) #define z_check(x) \ @@ -89,7 +97,6 @@ z_keyexpr_t : z_keyexpr_is_initialized, \ z_owned_config_t : z_config_check, \ z_owned_scouting_config_t : z_scouting_config_check, \ - z_owned_bytes_t : z_slice_check, \ z_owned_subscriber_t : z_subscriber_check, \ z_owned_pull_subscriber_t : z_pull_subscriber_check, \ z_owned_queryable_t : z_queryable_check, \ @@ -98,14 +105,15 @@ z_owned_hello_t : z_hello_check, \ z_owned_query_t : z_query_check, \ z_owned_str_t : z_str_check, \ - z_owned_bytes_map_t : z_slice_map_check, \ - z_owned_bytes_t: z_bytes_check, \ - z_bytes_t : z_attachment_check, \ - zc_owned_shmbuf_t : zc_shmbuf_check, \ - zc_owned_shm_manager_t : zc_shm_manager_check, \ + z_owned_slice_map_t : z_slice_map_check, \ + z_owned_slice_t: z_slice_check, \ + z_owned_bytes_t : z_bytes_check, \ zc_owned_liveliness_token_t : zc_liveliness_token_check, \ ze_owned_publication_cache_t : ze_publication_cache_check, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_check \ + z_owned_mutex_t : z_mutex_check, \ + z_owned_condvar_t : z_owned_condar_check, \ + z_owned_task_t : z_task_check \ )(&x) #define z_call(x, ...) \ @@ -138,12 +146,16 @@ template<> struct zenoh_loan_type{ typedef z_config_t type; }; template<> struct zenoh_loan_type{ typedef z_publisher_t type; }; template<> struct zenoh_loan_type{ typedef z_subscriber_t type; }; template<> struct zenoh_loan_type{ typedef z_query_t type; }; -template<> struct zenoh_loan_type{ typedef z_pull_subscriber_t type; }; template<> struct zenoh_loan_type{ typedef z_encoding_t type; }; template<> struct zenoh_loan_type{ typedef z_hello_t type; }; template<> struct zenoh_loan_type{ typedef const char* type; }; template<> struct zenoh_loan_type{ typedef z_bytes_t type; }; +template<> struct zenoh_loan_type{ typedef z_bytes_reader_t type; }; template<> struct zenoh_loan_type{ typedef ze_querying_subscriber_t type; }; +template<> struct zenoh_loan_type{ typedef z_slice_t type; }; +template<> struct zenoh_loan_type{ typedef z_slice_map_t type; }; +template<> struct zenoh_loan_type{ typedef z_mutex_t type; }; +template<> struct zenoh_loan_type{ typedef z_condvar_t type; }; template<> inline z_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } template<> inline z_keyexpr_t z_loan(const z_owned_keyexpr_t& x) { return z_keyexpr_loan(&x); } @@ -156,7 +168,12 @@ template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_lo template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } template<> inline z_bytes_t z_loan(const z_owned_bytes_t& x) { return z_bytes_loan(&x); } +template<> inline z_bytes_reader_t z_loan(const z_owned_bytes_reader_t& x) { return z_bytes_reader_loan(&x); } template<> inline ze_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } +template<> inline z_slice_t z_loan(const z_owned_slice_t& x) { return z_slice_loan(&x); } +template<> inline z_slice_map_t z_loan(const z_owned_slice_map_t& x) { return z_slice_map_loan(&x); } +template<> inline z_mutex_t z_loan(const z_owned_mutex_t& x) { return z_mutex_loan(&x); } +template<> inline z_condvar_t z_loan(const z_owned_condvar_t& x) { return z_condvar_loan(&x); } template struct zenoh_drop_type { typedef T type; }; template inline typename zenoh_drop_type::type z_drop(T*); @@ -166,7 +183,6 @@ template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -175,9 +191,7 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -186,10 +200,13 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef int8_t type; }; +template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> inline int8_t z_drop(z_owned_session_t* v) { return z_close(v); } template<> inline int8_t z_drop(z_owned_publisher_t* v) { return z_undeclare_publisher(v); } @@ -205,9 +222,7 @@ template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } template<> inline void z_drop(z_owned_query_t* v) { z_query_drop(v); } template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } template<> inline void z_drop(z_owned_bytes_t* v) { z_bytes_drop(v); } -template<> inline void z_drop(z_owned_bytes_t* v) { z_bytes_drop(v); } -template<> inline void z_drop(zc_owned_shmbuf_t* v) { zc_shmbuf_drop(v); } -template<> inline void z_drop(zc_owned_shm_manager_t* v) { zc_shm_manager_drop(v); } +template<> inline void z_drop(z_owned_bytes_reader_t* v) { z_bytes_reader_drop(v); } template<> inline void z_drop(z_owned_closure_sample_t* v) { z_closure_sample_drop(v); } template<> inline void z_drop(z_owned_closure_query_t* v) { z_closure_query_drop(v); } template<> inline void z_drop(z_owned_closure_reply_t* v) { z_closure_reply_drop(v); } @@ -216,17 +231,19 @@ template<> inline void z_drop(z_owned_closure_zid_t* v) { z_closure_zid_drop(v); template<> inline void z_drop(zcu_owned_closure_matching_status_t* v) { zcu_closure_matching_status_drop(v); } template<> inline void z_drop(z_owned_reply_channel_closure_t* v) { z_reply_channel_closure_drop(v); } template<> inline void z_drop(z_owned_reply_channel_t* v) { z_reply_channel_drop(v); } -template<> inline void z_drop(z_owned_bytes_map_t* v) { z_slice_map_drop(v); } +template<> inline void z_drop(z_owned_slice_t* v) { z_slice_drop(v); } +template<> inline void z_drop(z_owned_slice_map_t* v) { z_slice_map_drop(v); } template<> inline void z_drop(zc_owned_liveliness_token_t* v) { zc_liveliness_undeclare_token(v); } template<> inline int8_t z_drop(ze_owned_publication_cache_t* v) { return ze_undeclare_publication_cache(v); } template<> inline int8_t z_drop(ze_owned_querying_subscriber_t* v) { return ze_undeclare_querying_subscriber(v); } +template<> inline void z_drop(z_owned_mutex_t* v) { z_mutex_drop(v); } +template<> inline void z_drop(z_owned_condvar_t* v) { z_condvar_drop(v); } inline void z_null(z_owned_session_t& v) { v = z_session_null(); } inline void z_null(z_owned_publisher_t& v) { v = z_publisher_null(); } inline void z_null(z_owned_keyexpr_t& v) { v = z_keyexpr_null(); } inline void z_null(z_owned_config_t& v) { v = z_config_null(); } inline void z_null(z_owned_scouting_config_t& v) { v = z_scouting_config_null(); } -inline void z_null(z_owned_pull_subscriber_t& v) { v = z_pull_subscriber_null(); } inline void z_null(z_owned_subscriber_t& v) { v = z_subscriber_null(); } inline void z_null(z_owned_queryable_t& v) { v = z_queryable_null(); } inline void z_null(z_owned_encoding_t& v) { v = z_encoding_null(); } @@ -235,9 +252,7 @@ inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } inline void z_null(z_owned_query_t& v) { v = z_query_null(); } inline void z_null(z_owned_str_t& v) { v = z_str_null(); } inline void z_null(z_owned_bytes_t& v) { v = z_bytes_null(); } -inline void z_null(z_owned_bytes_t& v) { v = z_bytes_null(); } -inline void z_null(zc_owned_shmbuf_t& v) { v = zc_shmbuf_null(); } -inline void z_null(zc_owned_shm_manager_t& v) { v = zc_shm_manager_null(); } +inline void z_null(z_owned_bytes_reader_t& v) { v = z_bytes_reader_null(); } inline void z_null(z_owned_closure_sample_t& v) { v = z_closure_sample_null(); } inline void z_null(z_owned_closure_query_t& v) { v = z_closure_query_null(); } inline void z_null(z_owned_closure_reply_t& v) { v = z_closure_reply_null(); } @@ -246,10 +261,14 @@ inline void z_null(z_owned_closure_zid_t& v) { v = z_closure_zid_null(); } inline void z_null(zcu_owned_closure_matching_status_t& v) { v = zcu_closure_matching_status_null(); } inline void z_null(z_owned_reply_channel_closure_t& v) { v = z_reply_channel_closure_null(); } inline void z_null(z_owned_reply_channel_t& v) { v = z_reply_channel_null(); } -inline void z_null(z_owned_bytes_map_t& v) { v = z_slice_map_null(); } +inline void z_null(z_owned_slice_t& v) { v = z_slice_null(); } +inline void z_null(z_owned_slice_map_t& v) { v = z_slice_map_null(); } inline void z_null(zc_owned_liveliness_token_t& v) { v = zc_liveliness_token_null(); } inline void z_null(ze_owned_publication_cache_t& v) { v = ze_publication_cache_null(); } inline void z_null(ze_owned_querying_subscriber_t& v) { v = ze_querying_subscriber_null(); } +inline void z_null(z_owned_mutex_t& v) { v = z_mutex_null(); } +inline void z_null(z_owned_condvar_t& v) { v = z_condvar_null(); } +inline void z_null(z_owned_task_t& v) { v = z_task_null(); } inline bool z_check(const z_owned_session_t& v) { return z_session_check(&v); } inline bool z_check(const z_owned_publisher_t& v) { return z_publisher_check(&v); } @@ -258,9 +277,7 @@ inline bool z_check(const z_keyexpr_t& v) { return z_keyexpr_is_initialized(&v); inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } inline bool z_check(const z_owned_bytes_t& v) { return z_slice_check(&v); } -inline bool z_check(const z_owned_bytes_t& v) { return z_bytes_check(&v); } -inline bool z_check(const zc_owned_shmbuf_t& v) { return zc_shmbuf_check(&v); } -inline bool z_check(const zc_owned_shm_manager_t& v) { return zc_shm_manager_check(&v); } +inline bool z_check(const z_owned_bytes_reader_t& v) { return z_bytes_reader_check(&v); } inline bool z_check(const z_owned_subscriber_t& v) { return z_subscriber_check(&v); } inline bool z_check(const z_owned_pull_subscriber_t& v) { return z_pull_subscriber_check(&v); } inline bool z_check(const z_owned_queryable_t& v) { return z_queryable_check(&v); } @@ -269,12 +286,14 @@ inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } inline bool z_check(const z_owned_query_t& v) { return z_query_check(&v); } inline bool z_check(const z_owned_str_t& v) { return z_str_check(&v); } -inline bool z_check(const z_owned_bytes_t& v) { return z_bytes_check(&v); } -inline bool z_check(const z_owned_bytes_map_t& v) { return z_slice_map_check(&v); } -inline bool z_check(constz_bytes_t& v) { return z_attachment_check(&v); } +inline bool z_check(const z_owned_slice_t& v) { return z_slice_check(&v); } +inline bool z_check(const z_owned_slice_map_t& v) { return z_slice_map_check(&v); } inline bool z_check(const zc_owned_liveliness_token_t& v) { return zc_liveliness_token_check(&v); } inline bool z_check(const ze_owned_publication_cache_t& v) { return ze_publication_cache_check(&v); } inline bool z_check(const ze_owned_querying_subscriber_t& v) { return ze_querying_subscriber_check(&v); } +inline bool z_check(const z_owned_mutex_t& v) { return z_mutex_check(&v); } +inline bool z_check(const z_owned_condvar_t& v) { return z_condvar_check(&v); } +inline bool z_check(const z_owned_task_t& v) { return z_task_check(&v); } inline void z_call(const struct z_owned_closure_sample_t &closure, const struct z_sample_t *sample) { z_closure_sample_call(&closure, sample); } diff --git a/src/collections.rs b/src/collections.rs index 6bf5622b5..c07832d11 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -429,7 +429,7 @@ pub extern "C" fn z_slice_map_insert_by_copy( this: z_slice_map_t, key: z_slice_t, value: z_slice_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_mut(); if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())); @@ -449,7 +449,7 @@ pub extern "C" fn z_slice_map_insert_by_alias( this: z_slice_map_t, key: z_slice_t, value: z_slice_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_mut(); if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { this.insert(Cow::Borrowed(key), Cow::Borrowed(value)); diff --git a/src/config.rs b/src/config.rs index 12ab9e087..f8e3d7ced 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,7 +16,7 @@ use std::ffi::CStr; use std::mem::MaybeUninit; use zenoh::config::{Config, ValidatedMap, WhatAmI}; -use crate::errors::{ZCError, Z_EPARSE}; +use crate::errors::{z_error_t, Z_EPARSE}; use crate::transmute::{ unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, @@ -170,7 +170,7 @@ pub extern "C" fn z_config_check(config: &z_owned_config_t) -> bool { pub unsafe extern "C" fn zc_config_from_str( s: *const c_char, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let mut res = errors::Z_OK; if s.is_null() { z_config_null(this); @@ -205,7 +205,7 @@ pub extern "C" fn zc_config_to_string(config: z_config_t) -> z_owned_str_t { pub unsafe extern "C" fn zc_config_from_file( path: *const c_char, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let path_str = CStr::from_ptr(path); let mut res = errors::Z_OK; let config = match path_str.to_str() { @@ -245,7 +245,7 @@ pub unsafe extern "C" fn z_config_client( peers: *const *const c_char, n_peers: usize, this: *mut MaybeUninit, -) -> ZCError { +) -> z_error_t { let mut res = errors::Z_OK; let locators = if peers.is_null() { Vec::new() diff --git a/src/errors.rs b/src/errors.rs index 72448026a..7415ffb40 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,12 +1,12 @@ -pub type ZCError = i8; -pub const Z_OK: ZCError = 0; -pub const Z_EINVAL: ZCError = -1; -pub const Z_EPARSE: ZCError = -2; -pub const Z_EIO: ZCError = -3; -pub const Z_ENETWORK: ZCError = -4; +pub type z_error_t = i8; +pub const Z_OK: z_error_t = 0; +pub const Z_EINVAL: z_error_t = -1; +pub const Z_EPARSE: z_error_t = -2; +pub const Z_EIO: z_error_t = -3; +pub const Z_ENETWORK: z_error_t = -4; // negativ pthread error codes (due to convention to return negative values on error) -pub const Z_EBUSY_MUTEX: ZCError = -16; -pub const Z_EINVAL_MUTEX: ZCError = -22; -pub const Z_EAGAIN_MUTEX: ZCError = -11; -pub const Z_EPOISON_MUTEX: ZCError = -22; // same as Z_EINVAL_MUTEX -pub const Z_EGENERIC: ZCError = i8::MIN; +pub const Z_EBUSY_MUTEX: z_error_t = -16; +pub const Z_EINVAL_MUTEX: z_error_t = -22; +pub const Z_EAGAIN_MUTEX: z_error_t = -11; +pub const Z_EPOISON_MUTEX: z_error_t = -22; // same as Z_EINVAL_MUTEX +pub const Z_EGENERIC: z_error_t = i8::MIN; diff --git a/src/get.rs b/src/get.rs index 97c17bc52..67abe9db6 100644 --- a/src/get.rs +++ b/src/get.rs @@ -148,7 +148,7 @@ pub unsafe extern "C" fn z_get( parameters: *const c_char, callback: &mut z_owned_closure_reply_t, options: z_get_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let mut closure = z_owned_closure_reply_t::empty(); std::mem::swap(callback, &mut closure); let p = if parameters.is_null() { diff --git a/src/info.rs b/src/info.rs index c2604d84a..90afc28ca 100644 --- a/src/info.rs +++ b/src/info.rs @@ -50,7 +50,7 @@ pub unsafe extern "C" fn z_info_zid(session: z_session_t) -> z_id_t { pub unsafe extern "C" fn z_info_peers_zid( session: z_session_t, callback: &mut z_owned_closure_zid_t, -) -> errors::ZCError { +) -> errors::z_error_t { let mut closure = z_owned_closure_zid_t::empty(); std::mem::swap(&mut closure, callback); let session = session.transmute_ref(); @@ -71,7 +71,7 @@ pub unsafe extern "C" fn z_info_peers_zid( pub unsafe extern "C" fn z_info_routers_zid( session: z_session_t, callback: &mut z_owned_closure_zid_t, -) -> errors::ZCError { +) -> errors::z_error_t { let mut closure = z_owned_closure_zid_t::empty(); std::mem::swap(&mut closure, callback); let session = session.transmute_ref(); diff --git a/src/keyexpr.rs b/src/keyexpr.rs index b39eb6dfd..6f25b75c6 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -15,7 +15,7 @@ use std::mem::MaybeUninit; use crate::errors; -use crate::errors::ZCError; +use crate::errors::z_error_t; use crate::errors::Z_OK; use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; @@ -68,7 +68,7 @@ unsafe fn keyexpr_create( name: &'static mut [u8], should_auto_canonize: bool, should_copy: bool, -) -> Result, errors::ZCError> { +) -> Result, errors::z_error_t> { match std::str::from_utf8_mut(name) { Ok(name) => match keyexpr_create_inner(name, should_auto_canonize, should_copy) { Ok(v) => Ok(v), @@ -90,7 +90,7 @@ unsafe fn keyexpr_create( pub unsafe extern "C" fn z_keyexpr_new( name: *const c_char, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { if name.is_null() { return errors::Z_EINVAL; } @@ -114,7 +114,7 @@ pub unsafe extern "C" fn z_keyexpr_new( pub unsafe extern "C" fn z_keyexpr_new_autocanonize( name: *const c_char, this: *mut MaybeUninit, -) -> ZCError { +) -> z_error_t { if name.is_null() { return errors::Z_EINVAL; } @@ -178,7 +178,7 @@ impl std::error::Error for UninitializedKeyExprError {} /// Otherwise returns error value #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_is_canon(start: *const c_char, len: usize) -> ZCError { +pub unsafe extern "C" fn z_keyexpr_is_canon(start: *const c_char, len: usize) -> z_error_t { let name = std::slice::from_raw_parts_mut(start as _, len); match keyexpr_create(name, false, false) { Ok(_) => errors::Z_OK, @@ -195,7 +195,7 @@ pub unsafe extern "C" fn z_keyexpr_is_canon(start: *const c_char, len: usize) -> /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_canonize_null_terminated(start: *mut c_char) -> ZCError { +pub unsafe extern "C" fn z_keyexpr_canonize_null_terminated(start: *mut c_char) -> z_error_t { let mut len = libc::strlen(start); match z_keyexpr_canonize(start, &mut len) { Z_OK => { @@ -214,7 +214,7 @@ pub unsafe extern "C" fn z_keyexpr_canonize_null_terminated(start: *mut c_char) /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) -> ZCError { +pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) -> z_error_t { let name = std::slice::from_raw_parts_mut(start as _, *len); match keyexpr_create(name, true, false) { Ok(ke) => { @@ -232,7 +232,7 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice( this: *mut MaybeUninit, name: *const c_char, len: usize, -) -> ZCError { +) -> z_error_t { let this = this.transmute_uninit_ptr(); if name.is_null() { Inplace::empty(this); @@ -261,7 +261,7 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( this: *mut MaybeUninit, name: *mut c_char, len: &mut usize, -) -> ZCError { +) -> z_error_t { let this = this.transmute_uninit_ptr(); if name.is_null() { Inplace::empty(this); @@ -289,7 +289,7 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( pub unsafe extern "C" fn z_keyexpr( this: *mut MaybeUninit, name: *const c_char, -) -> ZCError { +) -> z_error_t { if name.is_null() { Inplace::empty(this.transmute_uninit_ptr()); errors::Z_EINVAL @@ -307,7 +307,7 @@ pub unsafe extern "C" fn z_keyexpr( pub unsafe extern "C" fn z_keyexpr_autocanonize( this: *mut MaybeUninit, name: *mut c_char, -) -> ZCError { +) -> z_error_t { if name.is_null() { Inplace::empty(this.transmute_uninit_ptr()); errors::Z_EINVAL @@ -401,7 +401,7 @@ pub extern "C" fn z_declare_keyexpr( this: *mut MaybeUninit, session: z_session_t, key_expr: z_keyexpr_t, -) -> ZCError { +) -> z_error_t { let this = this.transmute_uninit_ptr(); let key_expr = key_expr.transmute_ref(); let session = session.transmute_ref(); @@ -480,7 +480,7 @@ pub unsafe extern "C" fn z_keyexpr_concat( right_start: *const c_char, right_len: usize, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let left = left.transmute_ref(); let right = std::slice::from_raw_parts(right_start as _, right_len); @@ -518,7 +518,7 @@ pub extern "C" fn z_keyexpr_join( left: z_keyexpr_t, right: z_keyexpr_t, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let left = left.transmute_ref(); let right = right.transmute_ref(); let this = this.transmute_uninit_ptr(); diff --git a/src/liveliness.rs b/src/liveliness.rs index 29fee985c..e16a77727 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -71,7 +71,7 @@ pub extern "C" fn zc_liveliness_declare_token( session: z_session_t, key_expr: z_keyexpr_t, _options: zc_liveliness_declaration_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); @@ -92,7 +92,7 @@ pub extern "C" fn zc_liveliness_declare_token( #[no_mangle] pub extern "C" fn zc_liveliness_undeclare_token( this: &mut zc_owned_liveliness_token_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_mut(); if let Some(token) = this.extract().take() { if let Err(e) = token.undeclare().res() { @@ -136,7 +136,7 @@ pub extern "C" fn zc_liveliness_declare_subscriber( key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, _options: zc_liveliness_declare_subscriber_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); let callback = core::mem::replace(callback, z_owned_closure_sample_t::empty()); @@ -185,7 +185,7 @@ pub extern "C" fn zc_liveliness_get( key_expr: z_keyexpr_t, callback: &mut z_owned_closure_reply_t, options: zc_liveliness_get_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let callback = core::mem::replace(callback, z_owned_closure_reply_t::empty()); diff --git a/src/payload.rs b/src/payload.rs index a6bfdc927..d80d0f060 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,4 +1,4 @@ -use crate::errors::{self, ZCError}; +use crate::errors::{self, z_error_t}; use crate::transmute::{ unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, @@ -71,7 +71,7 @@ extern "C" fn z_bytes_len(payload: z_bytes_t) -> usize { pub unsafe extern "C" fn z_bytes_decode_into_string( payload: z_bytes_t, dst: *mut MaybeUninit, -) -> ZCError { +) -> z_error_t { let len = z_bytes_len(payload); let cstr = z_owned_str_t::preallocate(len); let payload = payload.transmute_ref(); @@ -94,7 +94,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( payload: z_bytes_t, dst: *mut MaybeUninit, -) -> ZCError { +) -> z_error_t { let dst = dst.transmute_uninit_ptr(); let payload = payload.transmute_ref(); let iter = payload.iter::<(Vec, Vec)>(); @@ -112,7 +112,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( pub unsafe extern "C" fn z_bytes_decode_into_bytes( payload: z_bytes_t, dst: *mut MaybeUninit, -) -> ZCError { +) -> z_error_t { let len = z_bytes_len(payload); let b = z_owned_slice_t::preallocate(len); let payload = payload.transmute_ref(); @@ -253,7 +253,7 @@ pub unsafe extern "C" fn z_bytes_reader_seek( this: z_bytes_reader_t, offset: i64, origin: libc::c_int, -) -> ZCError { +) -> z_error_t { let reader = this.transmute_mut(); let pos = match origin { libc::SEEK_SET => offset.try_into().map(SeekFrom::Start), diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index e592c4166..cd1c016e3 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -23,7 +23,7 @@ decl_transmute_owned!( decl_transmute_handle!((Mutex<()>, Option>), z_mutex_t); #[no_mangle] -pub extern "C" fn z_mutex_init(this: *mut MaybeUninit) -> errors::ZCError { +pub extern "C" fn z_mutex_init(this: *mut MaybeUninit) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let m = (Mutex::<()>::new(()), None::>); Inplace::init(this, Some(m)); @@ -40,6 +40,11 @@ pub extern "C" fn z_mutex_check(this: &z_owned_mutex_t) -> bool { this.transmute_ref().is_some() } +#[no_mangle] +pub extern "C" fn z_mutex_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); +} + #[no_mangle] pub extern "C" fn z_mutex_loan(this: &z_owned_mutex_t) -> z_mutex_t { let this = this.transmute_ref(); @@ -48,7 +53,7 @@ pub extern "C" fn z_mutex_loan(this: &z_owned_mutex_t) -> z_mutex_t { } #[no_mangle] -pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::ZCError { +pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.lock() { @@ -64,7 +69,7 @@ pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::ZCError { } #[no_mangle] -pub extern "C" fn z_mutex_unlock(this: z_mutex_t) -> errors::ZCError { +pub extern "C" fn z_mutex_unlock(this: z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); if this.1.is_none() { return errors::Z_EINVAL_MUTEX; @@ -76,7 +81,7 @@ pub extern "C" fn z_mutex_unlock(this: z_mutex_t) -> errors::ZCError { #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_try_lock(this: z_mutex_t) -> errors::ZCError { +pub unsafe extern "C" fn z_mutex_try_lock(this: z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.try_lock() { Ok(new_lock) => { @@ -126,7 +131,7 @@ pub extern "C" fn z_condvar_loan(this: &z_owned_condvar_t) -> z_condvar_t { } #[no_mangle] -pub extern "C" fn z_condvar_signal(this: z_condvar_t) -> errors::ZCError { +pub extern "C" fn z_condvar_signal(this: z_condvar_t) -> errors::z_error_t { let this = this.transmute_mut(); this.notify_one(); errors::Z_OK @@ -134,7 +139,7 @@ pub extern "C" fn z_condvar_signal(this: z_condvar_t) -> errors::ZCError { #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_wait(this: z_condvar_t, m: z_mutex_t) -> errors::ZCError { +pub unsafe extern "C" fn z_condvar_wait(this: z_condvar_t, m: z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); let m = m.transmute_mut(); if m.1.is_none() { @@ -172,7 +177,7 @@ pub extern "C" fn z_task_detach(this: &mut z_owned_task_t) { /// Joins the task and releases all allocated resources #[no_mangle] -pub extern "C" fn z_task_join(this: &mut z_owned_task_t) -> errors::ZCError { +pub extern "C" fn z_task_join(this: &mut z_owned_task_t) -> errors::z_error_t { let this = this.transmute_mut().extract().take(); if let Some(task) = this { match task.join() { @@ -209,7 +214,7 @@ pub unsafe extern "C" fn z_task_init( _attr: *const z_task_attr_t, fun: unsafe extern "C" fn(arg: *mut c_void), arg: *mut c_void, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let fun_arg_pair = FunArgPair { fun, arg }; diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 18e0ce407..25c4d4ffd 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -90,7 +90,7 @@ pub extern "C" fn ze_declare_publication_cache( session: z_session_t, key_expr: z_keyexpr_t, options: ze_publication_cache_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); @@ -138,7 +138,7 @@ pub extern "C" fn ze_publication_cache_check(this: &ze_owned_publication_cache_t #[allow(clippy::missing_safety_doc)] pub extern "C" fn ze_undeclare_publication_cache( this: &mut ze_owned_publication_cache_t, -) -> errors::ZCError { +) -> errors::z_error_t { if let Some(p) = this.transmute_mut().extract().take() { if let Err(e) = p.close().res_sync() { log::error!("{}", e); diff --git a/src/publisher.rs b/src/publisher.rs index 3ab7eb2d5..3d3c6a84d 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -101,7 +101,7 @@ pub extern "C" fn z_declare_publisher( key_expr: z_keyexpr_t, options: Option<&z_publisher_options_t>, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref().clone().into_owned(); @@ -188,7 +188,7 @@ pub unsafe extern "C" fn z_publisher_put( publisher: z_publisher_t, payload: &mut z_owned_bytes_t, options: z_publisher_put_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let publisher = publisher.transmute_ref(); let payload = match payload.transmute_mut().extract() { Some(p) => p, @@ -242,7 +242,7 @@ pub extern "C" fn z_publisher_delete_options_default() -> z_publisher_delete_opt pub extern "C" fn z_publisher_delete( publisher: z_publisher_t, _options: z_publisher_delete_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let publisher = publisher.transmute_ref(); if let Err(e) = publisher.delete().res_sync() { log::error!("{}", e); @@ -283,7 +283,7 @@ pub extern "C" fn zcu_publisher_matching_listener_callback( publisher: z_publisher_t, callback: &mut zcu_owned_closure_matching_status_t, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = zcu_owned_closure_matching_status_t::empty(); std::mem::swap(callback, &mut closure); @@ -312,7 +312,7 @@ pub extern "C" fn zcu_publisher_matching_listener_callback( /// Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_undeclare_publisher(publisher: &mut z_owned_publisher_t) -> errors::ZCError { +pub extern "C" fn z_undeclare_publisher(publisher: &mut z_owned_publisher_t) -> errors::z_error_t { if let Some(p) = publisher.transmute_mut().extract().take() { if let Err(e) = p.undeclare().res_sync() { log::error!("{}", e); diff --git a/src/put.rs b/src/put.rs index 8ba9c77c1..a59934106 100644 --- a/src/put.rs +++ b/src/put.rs @@ -75,7 +75,7 @@ pub extern "C" fn z_put( key_expr: z_keyexpr_t, payload: &mut z_owned_bytes_t, options: z_put_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let payload = match payload.transmute_mut().extract() { @@ -137,7 +137,7 @@ pub extern "C" fn z_delete( session: z_session_t, key_expr: z_keyexpr_t, opts: z_delete_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let del = session diff --git a/src/queryable.rs b/src/queryable.rs index ea1b7905e..279afba74 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -146,7 +146,7 @@ pub extern "C" fn z_declare_queryable( callback: &mut z_owned_closure_query_t, options: Option<&z_queryable_options_t>, this: *mut MaybeUninit, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_query_t::empty(); std::mem::swap(&mut closure, callback); @@ -177,7 +177,7 @@ pub extern "C" fn z_declare_queryable( /// qable: The :c:type:`z_owned_queryable_t` to undeclare. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_undeclare_queryable(qable: &mut z_owned_queryable_t) -> errors::ZCError { +pub extern "C" fn z_undeclare_queryable(qable: &mut z_owned_queryable_t) -> errors::z_error_t { if let Some(qable) = qable.transmute_mut().extract().take() { if let Err(e) = qable.undeclare().res_sync() { log::error!("{}", e); @@ -214,7 +214,7 @@ pub unsafe extern "C" fn z_query_reply( key_expr: z_keyexpr_t, payload: &mut z_owned_bytes_t, options: z_query_reply_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let query = query.transmute_ref(); let key_expr = key_expr.transmute_ref(); diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index aea07e03a..6afb0f9fe 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -134,7 +134,7 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: ze_querying_subscriber_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); @@ -180,7 +180,7 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( sub: ze_querying_subscriber_t, selector: z_keyexpr_t, options: Option<&z_get_options_t>, -) -> errors::ZCError { +) -> errors::z_error_t { unsafe impl Sync for z_get_options_t {} let sub = sub.transmute_ref(); let session = sub.1; @@ -212,7 +212,7 @@ pub unsafe extern "C" fn ze_querying_subscriber_get( #[no_mangle] pub extern "C" fn ze_undeclare_querying_subscriber( this: &mut ze_owned_querying_subscriber_t, -) -> errors::ZCError { +) -> errors::z_error_t { if let Some(s) = this.transmute_mut().extract().take() { if let Err(e) = s.0.close().res_sync() { log::error!("{}", e); diff --git a/src/scouting.rs b/src/scouting.rs index 22a61fb2e..113f11c70 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -264,7 +264,7 @@ pub extern "C" fn z_scouting_config_drop(config: &mut z_owned_scouting_config_t) pub extern "C" fn z_scout( config: &mut z_owned_scouting_config_t, callback: &mut z_owned_closure_hello_t, -) -> errors::ZCError { +) -> errors::z_error_t { if cfg!(feature = "logger-autoinit") { zc_init_logger(); } diff --git a/src/session.rs b/src/session.rs index c37d8b721..5079c50f0 100644 --- a/src/session.rs +++ b/src/session.rs @@ -59,7 +59,7 @@ pub extern "C" fn z_session_null(this: *mut MaybeUninit) { pub extern "C" fn z_open( this: *mut MaybeUninit, config: &mut z_owned_config_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); if cfg!(feature = "logger-autoinit") { zc_init_logger(); diff --git a/src/subscriber.rs b/src/subscriber.rs index ea530d561..4e0582ad4 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -140,7 +140,7 @@ pub extern "C" fn z_declare_subscriber( key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: z_subscriber_options_t, -) -> errors::ZCError { +) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); @@ -178,7 +178,9 @@ pub extern "C" fn z_subscriber_keyexpr(subscriber: z_subscriber_t) -> z_keyexpr_ /// Undeclares the given :c:type:`z_owned_subscriber_t`, droping it and invalidating it for double-drop safety. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_undeclare_subscriber(subscriber: &mut z_owned_subscriber_t) -> errors::ZCError { +pub extern "C" fn z_undeclare_subscriber( + subscriber: &mut z_owned_subscriber_t, +) -> errors::z_error_t { if let Some(s) = subscriber.transmute_mut().extract().take() { if let Err(e) = s.undeclare().res_sync() { log::error!("{}", e); From 630c3cbaccbfb97de33ab58f1d4f28569dca8009 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 23 Apr 2024 23:11:06 +0200 Subject: [PATCH 60/75] more fixes --- Cargo.toml | 1 + build-resources/opaque-types/src/lib.rs | 2 +- examples/z_sub_thr.c | 23 ++++++---- include/zenoh_commons.h | 60 ++++++++++++------------- include/zenoh_macros.h | 6 +-- src/collections.rs | 11 ++++- src/config.rs | 12 ++--- src/get.rs | 36 ++++++++------- src/liveliness.rs | 4 +- src/payload.rs | 14 +++--- src/publication_cache.rs | 22 ++++----- src/publisher.rs | 19 ++++---- src/pull_subscriber.rs | 4 +- src/put.rs | 19 ++++---- src/queryable.rs | 23 +++++----- src/querying_subscriber.rs | 28 ++++++------ src/scouting.rs | 4 +- src/subscriber.rs | 9 ++-- 18 files changed, 159 insertions(+), 138 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4e62df310..1d25448fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,6 +63,7 @@ zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } zenoh-util = { path = "../zenoh/commons/zenoh-util" } + [build-dependencies] cbindgen = "0.26.0" fs2 = "0.4.3" diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 846e887a3..9e9f7d434 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -60,7 +60,7 @@ get_opaque_type_data!(Option, zc_owned_sample_t); get_opaque_type_data!(&'static Sample, z_sample_t); /// A reader for payload data. -get_opaque_type_data!(Option>, z_owned_bytes_t_reader_t); +get_opaque_type_data!(Option>, z_owned_bytes_reader_t); get_opaque_type_data!(&'static ZBytesReader<'static>, z_bytes_reader_t); /// The encoding of a payload, in a MIME-like format. diff --git a/examples/z_sub_thr.c b/examples/z_sub_thr.c index 05ee709d3..3fdfe1e2a 100644 --- a/examples/z_sub_thr.c +++ b/examples/z_sub_thr.c @@ -14,6 +14,7 @@ #include #include "zenoh.h" +#include #define N 1000000 @@ -33,7 +34,7 @@ z_stats_t *z_stats_make() { return stats; } -void on_sample(const z_sample_t *sample, void *context) { +void on_sample(z_sample_t sample, void *context) { z_stats_t *stats = (z_stats_t *)context; if (stats->count == 0) { stats->start = z_clock_now(); @@ -60,7 +61,8 @@ void drop_stats(void *context) { } int main(int argc, char **argv) { - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 1) { if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[1]) < 0) { printf( @@ -71,18 +73,22 @@ int main(int argc, char **argv) { } } - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } - z_owned_keyexpr_t ke = z_declare_keyexpr(z_loan(s), z_keyexpr("test/thr")); + z_owned_keyexpr_t ke; + z_keyexpr(&ke, "test/thr"); + z_owned_keyexpr_t declared_ke; + z_declare_keyexpr(&ke, z_loan(s), z_loan(ke)); z_stats_t *context = z_stats_make(); z_owned_closure_sample_t callback = z_closure(on_sample, drop_stats, context); - z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_loan(ke), z_move(callback), NULL); - if (!z_check(sub)) { + z_owned_subscriber_t sub; + if (z_declare_subscriber(&sub, z_loan(s), z_loan(declared_ke), z_move(callback), NULL)) { printf("Unable to create subscriber.\n"); exit(-1); } @@ -93,7 +99,8 @@ int main(int argc, char **argv) { } z_undeclare_subscriber(z_move(sub)); - z_undeclare_keyexpr(z_loan(s), z_move(ke)); + z_keyexpr_drop(z_move(ke)); + z_undeclare_keyexpr(z_loan(s), z_move(declared_ke)); z_close(z_move(s)); return 0; } diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index fd817ec0b..88a84d4dd 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -165,9 +165,9 @@ typedef struct ALIGN(8) z_slice_map_t { /** * A reader for payload data. */ -typedef struct ALIGN(8) z_owned_bytes_t_reader_t { +typedef struct ALIGN(8) z_owned_bytes_reader_t { uint8_t _0[24]; -} z_owned_bytes_t_reader_t; +} z_owned_bytes_reader_t; typedef struct ALIGN(8) z_bytes_reader_t { uint8_t _0[8]; } z_bytes_reader_t; @@ -922,19 +922,16 @@ ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *payload); * The gravestone value for `z_owned_bytes_t`. */ ZENOHC_API void z_bytes_null(struct z_owned_bytes_t *this_); -ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_t_reader_t *this_); -ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_t_reader_t *this_); -ZENOHC_API -struct z_bytes_reader_t z_bytes_reader_loan(const struct z_owned_bytes_t_reader_t *reader); +ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_reader_t *this_); +ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_reader_t *this_); +ZENOHC_API struct z_bytes_reader_t z_bytes_reader_loan(const struct z_owned_bytes_reader_t *reader); /** * Creates a reader for the specified `payload`. * * Returns 0 in case of success, -1 if `payload` is not valid. */ -ZENOHC_API -void z_bytes_reader_new(struct z_bytes_t payload, - struct z_owned_bytes_t_reader_t *this_); -ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_t_reader_t *this_); +ZENOHC_API void z_bytes_reader_new(struct z_bytes_t payload, struct z_owned_bytes_reader_t *this_); +ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_reader_t *this_); /** * Reads data into specified destination. * @@ -1078,14 +1075,6 @@ z_error_t z_config_client(const char *const *peers, * Clones the config. */ ZENOHC_API void z_config_clone(const struct z_config_t *src, struct z_owned_config_t *dst); -/** - * Frees `config`, invalidating it for double-drop safety. - */ -ZENOHC_API void z_config_drop(struct z_owned_config_t *config); -/** - * Returns a :c:type:`z_config_t` loaned from `s`. - */ -ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); /** * Return a new, zenoh-allocated, empty configuration. * @@ -1099,7 +1088,15 @@ ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *s); * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. */ ZENOHC_API -void z_config_new(struct z_owned_config_t *this_); +void z_config_default(struct z_owned_config_t *this_); +/** + * Frees `config`, invalidating it for double-drop safety. + */ +ZENOHC_API void z_config_drop(struct z_owned_config_t *config); +/** + * Returns a :c:type:`z_config_t` loaned from `s`. + */ +ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_config_t' type */ @@ -1171,11 +1168,11 @@ z_error_t z_declare_publisher(struct z_session_t session, * The created :c:type:`z_owned_queryable_t` or ``null`` if the creation failed. */ ZENOHC_API -z_error_t z_declare_queryable(struct z_session_t session, +z_error_t z_declare_queryable(struct z_owned_queryable_t *this_, + struct z_session_t session, struct z_keyexpr_t key_expr, struct z_owned_closure_query_t *callback, - const struct z_queryable_options_t *options, - struct z_owned_queryable_t *this_); + struct z_queryable_options_t *options); /** * Declare a subscriber for a given key expression. * @@ -1214,7 +1211,7 @@ z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, struct z_session_t session, struct z_keyexpr_t key_expr, struct z_owned_closure_sample_t *callback, - struct z_subscriber_options_t options); + struct z_subscriber_options_t *options); /** * Delete data. * @@ -1278,7 +1275,7 @@ z_error_t z_get(struct z_session_t session, struct z_keyexpr_t key_expr, const char *parameters, struct z_owned_closure_reply_t *callback, - struct z_get_options_t options); + struct z_get_options_t *options); ZENOHC_API struct z_get_options_t z_get_options_default(void); /** * Returns ``true`` if `hello` is valid. @@ -1537,7 +1534,7 @@ ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); ZENOHC_API z_error_t z_publisher_put(struct z_publisher_t publisher, struct z_owned_bytes_t *payload, - struct z_publisher_put_options_t options); + struct z_publisher_put_options_t *options); /** * Constructs the default value for :c:type:`z_publisher_put_options_t`. */ @@ -1561,7 +1558,7 @@ ZENOHC_API z_error_t z_put(struct z_session_t session, struct z_keyexpr_t key_expr, struct z_owned_bytes_t *payload, - struct z_put_options_t options); + struct z_put_options_t *options); /** * Constructs the default value for :c:type:`z_put_options_t`. */ @@ -1680,7 +1677,7 @@ ZENOHC_API z_error_t z_query_reply(struct z_query_t query, struct z_keyexpr_t key_expr, struct z_owned_bytes_t *payload, - struct z_query_reply_options_t options); + struct z_query_reply_options_t *options); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. */ @@ -1922,6 +1919,7 @@ void z_slice_map_iterate(const struct z_slice_map_t *this_, * Returns number of key-value pairs in the map. */ ZENOHC_API size_t z_slice_map_len(struct z_slice_map_t this_); +ZENOHC_API struct z_slice_map_t z_slice_map_loan(const struct z_owned_slice_map_t *this_); /** * Constructs a new empty map. */ @@ -2144,7 +2142,7 @@ z_error_t zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, struct z_session_t session, struct z_keyexpr_t key_expr, struct z_owned_closure_sample_t *callback, - struct zc_liveliness_declare_subscriber_options_t _options); + struct zc_liveliness_declare_subscriber_options_t *_options); /** * Constructs and declares a liveliness token on the network. * @@ -2157,7 +2155,7 @@ ZENOHC_API z_error_t zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, struct z_session_t session, struct z_keyexpr_t key_expr, - struct zc_liveliness_declaration_options_t _options); + struct zc_liveliness_declaration_options_t *_options); /** * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. * @@ -2323,7 +2321,7 @@ ZENOHC_API z_error_t ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, struct z_session_t session, struct z_keyexpr_t key_expr, - struct ze_publication_cache_options_t options); + struct ze_publication_cache_options_t *options); /** * Declares a Querying Subscriber for a given key expression. * @@ -2362,7 +2360,7 @@ z_error_t ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t * struct z_session_t session, struct z_keyexpr_t key_expr, struct z_owned_closure_sample_t *callback, - struct ze_querying_subscriber_options_t options); + struct ze_querying_subscriber_options_t *options); /** * Returns ``true`` if `pub_cache` is valid. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 110f4871a..69f89de72 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -9,18 +9,17 @@ z_owned_config_t : z_config_loan, \ z_owned_publisher_t : z_publisher_loan, \ z_owned_subscriber_t : z_subscriber_loan, \ - z_owned_pull_subscriber_t : z_pull_subscriber_loan, \ z_owned_encoding_t : z_encoding_loan, \ z_owned_hello_t : z_hello_loan, \ z_owned_str_t : z_str_loan, \ z_owned_query_t : z_query_loan, \ - z_owned_slice_map_t : z_slice_map_loan \ + z_owned_slice_map_t : z_slice_map_loan, \ z_owned_slice_t : z_slice_loan, \ z_owned_bytes_t : z_bytes_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan,\ z_owned_mutex_t : z_mutex_loan, \ z_condvar_t : z_condvar_loan, \ - z_owned_bytes_reader_t : z_bytes_reader_loan, \ + z_owned_bytes_reader_t : z_bytes_reader_loan \ )(&x) #define z_drop(x) \ @@ -162,7 +161,6 @@ template<> inline z_keyexpr_t z_loan(const z_owned_keyexpr_t& x) { return z_keye template<> inline z_config_t z_loan(const z_owned_config_t& x) { return z_config_loan(&x); } template<> inline z_publisher_t z_loan(const z_owned_publisher_t& x) { return z_publisher_loan(&x); } template<> inline z_subscriber_t z_loan(const z_owned_subscriber_t& x) { return z_subscriber_loan(&x); } -template<> inline z_pull_subscriber_t z_loan(const z_owned_pull_subscriber_t& x) { return z_pull_subscriber_loan(&x); } template<> inline z_encoding_t z_loan(const z_owned_encoding_t& x) { return z_encoding_loan(&x); } template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } diff --git a/src/collections.rs b/src/collections.rs index c07832d11..38412ba29 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -21,7 +21,7 @@ use zenoh::prelude::ZenohId; use crate::errors; use crate::transmute::{ - Inplace, InplaceDefault, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr, + unwrap_ref_unchecked, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }; /// A contiguous view of bytes owned by some other entity. @@ -338,7 +338,7 @@ decl_transmute_handle!( ); pub use crate::opaque_types::z_owned_config_t; -decl_transmute_owned!(Option, z_owned_slice_map_t); +decl_transmute_owned!(Option, Cow<'static, [u8]>>>, z_owned_slice_map_t); /// Constructs a new empty map. #[no_mangle] @@ -371,6 +371,13 @@ pub extern "C" fn z_slice_map_drop(this: &mut z_owned_slice_map_t) { Inplace::drop(this); } +#[no_mangle] +pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) ->z_slice_map_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() +} + /// Returns number of key-value pairs in the map. #[no_mangle] pub extern "C" fn z_slice_map_len(this: z_slice_map_t) -> usize { diff --git a/src/config.rs b/src/config.rs index f8e3d7ced..e7e420474 100644 --- a/src/config.rs +++ b/src/config.rs @@ -71,11 +71,11 @@ decl_transmute_owned!(Option>, z_owned_config_t); /// Returns a :c:type:`z_config_t` loaned from `s`. #[no_mangle] -pub extern "C" fn z_config_loan(s: &'static z_owned_config_t) -> z_config_t { - let s = s.transmute_ref(); - let s = unwrap_ref_unchecked(s); - let s = s.as_ref(); - s.transmute_handle() +pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> z_config_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + let this = this.as_ref(); + this.transmute_handle() } /// Return a new, zenoh-allocated, empty configuration. @@ -89,7 +89,7 @@ pub extern "C" fn z_config_loan(s: &'static z_owned_config_t) -> z_config_t { /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. #[no_mangle] -pub extern "C" fn z_config_new(this: *mut MaybeUninit) { +pub extern "C" fn z_config_default(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); let config: Box = Box::default(); Inplace::init(this, Some(config)); diff --git a/src/get.rs b/src/get.rs index 67abe9db6..bdf8ddfa0 100644 --- a/src/get.rs +++ b/src/get.rs @@ -147,7 +147,7 @@ pub unsafe extern "C" fn z_get( key_expr: z_keyexpr_t, parameters: *const c_char, callback: &mut z_owned_closure_reply_t, - options: z_get_options_t, + options: Option<&mut z_get_options_t>, ) -> errors::z_error_t { let mut closure = z_owned_closure_reply_t::empty(); std::mem::swap(callback, &mut closure); @@ -160,24 +160,26 @@ pub unsafe extern "C" fn z_get( let key_expr = key_expr.transmute_ref(); let mut get = session.get(key_expr.clone().with_parameters(p)); - if !options.payload.is_null() { - if let Some(payload) = unsafe { *options.payload }.transmute_mut().extract() { - get = get.payload(payload); + if let Some(options) = options { + if !options.payload.is_null() { + if let Some(payload) = unsafe { *options.payload }.transmute_mut().extract() { + get = get.payload(payload); + } + } + if !options.encoding.is_null() { + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); + get = get.encoding(encoding); + } + if !options.attachment.is_null() { + let attachment = unsafe { *options.payload }.transmute_mut().extract(); + get = get.attachment(attachment); } - } - if !options.encoding.is_null() { - let encoding = unsafe { *options.encoding }.transmute_mut().extract(); - get = get.encoding(encoding); - } - if !options.attachment.is_null() { - let attachment = unsafe { *options.payload }.transmute_mut().extract(); - get = get.attachment(attachment); - } - get = get - .consolidation(options.consolidation) - .timeout(std::time::Duration::from_millis(options.timeout_ms)) - .target(options.target.into()); + get = get + .consolidation(options.consolidation) + .timeout(std::time::Duration::from_millis(options.timeout_ms)) + .target(options.target.into()); + } match get .callback(move |response| z_closure_reply_call(&closure, response.transmute_handle())) .res_sync() diff --git a/src/liveliness.rs b/src/liveliness.rs index e16a77727..f35c1ce22 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -70,7 +70,7 @@ pub extern "C" fn zc_liveliness_declare_token( this: *mut MaybeUninit, session: z_session_t, key_expr: z_keyexpr_t, - _options: zc_liveliness_declaration_options_t, + _options: Option<&mut zc_liveliness_declaration_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); @@ -135,7 +135,7 @@ pub extern "C" fn zc_liveliness_declare_subscriber( session: z_session_t, key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - _options: zc_liveliness_declare_subscriber_options_t, + _options: Option<&mut zc_liveliness_declare_subscriber_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); diff --git a/src/payload.rs b/src/payload.rs index d80d0f060..582f65408 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -180,8 +180,8 @@ pub unsafe extern "C" fn z_bytes_encode_from_string( z_bytes_encode_from_bytes(this, bytes); } -pub use crate::opaque_types::z_owned_bytes_t_reader_t; -decl_transmute_owned!(Option>, z_owned_bytes_t_reader_t); +pub use crate::opaque_types::z_owned_bytes_reader_t; +decl_transmute_owned!(Option>, z_owned_bytes_reader_t); pub use crate::opaque_types::z_bytes_reader_t; decl_transmute_handle!(ZBytesReader<'static>, z_bytes_reader_t); @@ -193,7 +193,7 @@ decl_transmute_handle!(ZBytesReader<'static>, z_bytes_reader_t); #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_new( payload: z_bytes_t, - this: *mut MaybeUninit, + this: *mut MaybeUninit, ) { let this = this.transmute_uninit_ptr(); let payload = payload.transmute_ref(); @@ -203,25 +203,25 @@ pub unsafe extern "C" fn z_bytes_reader_new( #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_null(this: *mut MaybeUninit) { +pub unsafe extern "C" fn z_bytes_reader_null(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); Inplace::empty(this); } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_check(this: &z_owned_bytes_t_reader_t) -> bool { +pub unsafe extern "C" fn z_bytes_reader_check(this: &z_owned_bytes_reader_t) -> bool { this.transmute_ref().is_some() } #[no_mangle] -extern "C" fn z_bytes_reader_drop(this: &mut z_owned_bytes_t_reader_t) { +extern "C" fn z_bytes_reader_drop(this: &mut z_owned_bytes_reader_t) { let reader = this.transmute_mut(); Inplace::drop(reader); } #[no_mangle] -extern "C" fn z_bytes_reader_loan(reader: &'static z_owned_bytes_t_reader_t) -> z_bytes_reader_t { +extern "C" fn z_bytes_reader_loan(reader: &'static z_owned_bytes_reader_t) -> z_bytes_reader_t { let reader = reader.transmute_ref(); let reader = unwrap_ref_unchecked(reader); reader.transmute_handle() diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 25c4d4ffd..7f8f9e9e6 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -89,21 +89,23 @@ pub extern "C" fn ze_declare_publication_cache( this: *mut MaybeUninit, session: z_session_t, key_expr: z_keyexpr_t, - options: ze_publication_cache_options_t, + options: Option<&mut ze_publication_cache_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); let mut p = session.declare_publication_cache(key_expr); - p = p.history(options.history); - p = p.queryable_allowed_origin(options.queryable_origin.into()); - p = p.queryable_complete(options.queryable_complete); - if options.resources_limit != 0 { - p = p.resources_limit(options.resources_limit) - } - if !options.queryable_prefix.is_null() { - let queryable_prefix = unsafe { *options.queryable_prefix }.transmute_ref(); - p = p.queryable_prefix(queryable_prefix.clone()); + if let Some(options) = options { + p = p.history(options.history); + p = p.queryable_allowed_origin(options.queryable_origin.into()); + p = p.queryable_complete(options.queryable_complete); + if options.resources_limit != 0 { + p = p.resources_limit(options.resources_limit) + } + if !options.queryable_prefix.is_null() { + let queryable_prefix = unsafe { *options.queryable_prefix }.transmute_ref(); + p = p.queryable_prefix(queryable_prefix.clone()); + } } match p.res_sync() { Ok(publication_cache) => { diff --git a/src/publisher.rs b/src/publisher.rs index 3d3c6a84d..30c033645 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -187,7 +187,7 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t pub unsafe extern "C" fn z_publisher_put( publisher: z_publisher_t, payload: &mut z_owned_bytes_t, - options: z_publisher_put_options_t, + options: Option<&mut z_publisher_put_options_t>, ) -> errors::z_error_t { let publisher = publisher.transmute_ref(); let payload = match payload.transmute_mut().extract() { @@ -199,14 +199,15 @@ pub unsafe extern "C" fn z_publisher_put( }; let mut put = publisher.put(payload); - - if !options.encoding.is_null() { - let encoding = unsafe { *options.encoding }.transmute_mut().extract(); - put = put.encoding(encoding); - }; - if !options.attachment.is_null() { - let attachment = unsafe { *options.attachment }.transmute_mut().extract(); - put = put.attachment(attachment); + if let Some(options) = options { + if !options.encoding.is_null() { + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); + put = put.encoding(encoding); + }; + if !options.attachment.is_null() { + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + put = put.attachment(attachment); + } } if let Err(e) = put.res_sync() { diff --git a/src/pull_subscriber.rs b/src/pull_subscriber.rs index ebef7064b..624be46cb 100644 --- a/src/pull_subscriber.rs +++ b/src/pull_subscriber.rs @@ -131,7 +131,7 @@ pub extern "C" fn z_pull_subscriber_options_default() -> z_pull_subscriber_optio /// /// .. code-block:: C /// -/// z_subscriber_options_t opts = z_subscriber_options_default(); +/// z_subscriber_options_t options = z_subscriber_options_default(); /// z_owned_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(expr), callback, &opts); #[no_mangle] #[allow(clippy::missing_safety_doc)] @@ -139,7 +139,7 @@ pub extern "C" fn z_declare_pull_subscriber( session: z_session_t, keyexpr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - opts: Option<&z_pull_subscriber_options_t>, + options: Option<&z_pull_subscriber_options_t>, ) -> z_owned_pull_subscriber_t { let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); diff --git a/src/put.rs b/src/put.rs index a59934106..8bc9505d1 100644 --- a/src/put.rs +++ b/src/put.rs @@ -74,7 +74,7 @@ pub extern "C" fn z_put( session: z_session_t, key_expr: z_keyexpr_t, payload: &mut z_owned_bytes_t, - options: z_put_options_t, + options: Option<&mut z_put_options_t>, ) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); @@ -87,14 +87,15 @@ pub extern "C" fn z_put( }; let mut put = session.put(key_expr, payload); - - if !options.encoding.is_null() { - let encoding = unsafe { *options.encoding }.transmute_mut().extract(); - put = put.encoding(encoding); - }; - if !options.attachment.is_null() { - let attachment = unsafe { *options.attachment }.transmute_mut().extract(); - put = put.attachment(attachment); + if let Some(options) = options { + if !options.encoding.is_null() { + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); + put = put.encoding(encoding); + }; + if !options.attachment.is_null() { + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + put = put.attachment(attachment); + } } if let Err(e) = put.res_sync() { diff --git a/src/queryable.rs b/src/queryable.rs index 279afba74..17b5a82bc 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -141,11 +141,11 @@ pub extern "C" fn z_query_reply_options_default() -> z_query_reply_options_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_declare_queryable( + this: *mut MaybeUninit, session: z_session_t, key_expr: z_keyexpr_t, callback: &mut z_owned_closure_query_t, - options: Option<&z_queryable_options_t>, - this: *mut MaybeUninit, + options: Option<&mut z_queryable_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_query_t::empty(); @@ -213,7 +213,7 @@ pub unsafe extern "C" fn z_query_reply( query: z_query_t, key_expr: z_keyexpr_t, payload: &mut z_owned_bytes_t, - options: z_query_reply_options_t, + options: Option<&mut z_query_reply_options_t>, ) -> errors::z_error_t { let query = query.transmute_ref(); let key_expr = key_expr.transmute_ref(); @@ -227,14 +227,15 @@ pub unsafe extern "C" fn z_query_reply( }; let mut reply = query.reply(key_expr, payload); - - if !options.encoding.is_null() { - let encoding = unsafe { *options.encoding }.transmute_mut().extract(); - reply = reply.encoding(encoding); - }; - if !options.attachment.is_null() { - let attachment = unsafe { *options.attachment }.transmute_mut().extract(); - reply = reply.attachment(attachment); + if let Some(options) = options { + if !options.encoding.is_null() { + let encoding = unsafe { *options.encoding }.transmute_mut().extract(); + reply = reply.encoding(encoding); + }; + if !options.attachment.is_null() { + let attachment = unsafe { *options.attachment }.transmute_mut().extract(); + reply = reply.attachment(attachment); + } } if let Err(e) = reply.res_sync() { diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 6afb0f9fe..9bc8e2459 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -133,7 +133,7 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( session: z_session_t, key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - options: ze_querying_subscriber_options_t, + options: Option<&mut ze_querying_subscriber_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); @@ -142,18 +142,20 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( let mut sub = session .declare_subscriber(key_expr.transmute_ref()) .querying(); - sub = sub - .reliability(options.reliability.into()) - .allowed_origin(options.allowed_origin.into()) - .query_target(options.query_target.into()) - .query_consolidation(options.query_consolidation) - .query_accept_replies(options.query_accept_replies.into()); - if !options.query_selector.is_null() { - let query_selector = unsafe { *options.query_selector }.transmute_ref().clone(); - sub = sub.query_selector(query_selector) - } - if options.query_timeout_ms != 0 { - sub = sub.query_timeout(std::time::Duration::from_millis(options.query_timeout_ms)); + if let Some(options) = options { + sub = sub + .reliability(options.reliability.into()) + .allowed_origin(options.allowed_origin.into()) + .query_target(options.query_target.into()) + .query_consolidation(options.query_consolidation) + .query_accept_replies(options.query_accept_replies.into()); + if !options.query_selector.is_null() { + let query_selector = unsafe { *options.query_selector }.transmute_ref().clone(); + sub = sub.query_selector(query_selector) + } + if options.query_timeout_ms != 0 { + sub = sub.query_timeout(std::time::Duration::from_millis(options.query_timeout_ms)); + } } let sub = sub.callback(move |sample| { let sample = sample.transmute_handle(); diff --git a/src/scouting.rs b/src/scouting.rs index 113f11c70..3d593852d 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -14,7 +14,7 @@ use crate::{ errors::{self, Z_OK}, transmute::{Inplace, TransmuteRef}, - z_closure_hello_call, z_config_check, z_config_clone, z_config_drop, z_config_new, + z_closure_hello_call, z_config_check, z_config_clone, z_config_default, z_config_drop, z_config_null, z_config_t, z_id_t, z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, CopyableToCArray, }; @@ -210,7 +210,7 @@ pub unsafe extern "C" fn z_scouting_config_default( this: *mut MaybeUninit, ) { let mut _config = MaybeUninit::::uninit(); - z_config_new(&mut _config as *mut MaybeUninit); + z_config_default(&mut _config as *mut MaybeUninit); let _config = _config.assume_init(); let config = z_owned_scouting_config_t { diff --git a/src/subscriber.rs b/src/subscriber.rs index 4e0582ad4..81b1a8c4c 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -139,21 +139,22 @@ pub extern "C" fn z_declare_subscriber( session: z_session_t, key_expr: z_keyexpr_t, callback: &mut z_owned_closure_sample_t, - options: z_subscriber_options_t, + options: Option<&mut z_subscriber_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = z_owned_closure_sample_t::empty(); std::mem::swap(callback, &mut closure); let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); - let subscriber = session + let mut subscriber = session .declare_subscriber(key_expr) .callback(move |sample| { let sample = sample.transmute_handle(); z_closure_sample_call(&closure, sample) }); - - let subscriber = subscriber.reliability(options.reliability.into()); + if let Some(options) = options { + subscriber = subscriber.reliability(options.reliability.into()); + } match subscriber.res() { Ok(sub) => { Inplace::init(this, Some(sub)); From 328c28f3cf7abde4dbcbe9c0b48388d7858d75f3 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Tue, 23 Apr 2024 23:19:06 +0200 Subject: [PATCH 61/75] removed ref to local zenoh --- Cargo.lock | 195 ++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 15 ++-- Cargo.toml.in | 15 ++-- src/collections.rs | 10 ++- src/payload.rs | 7 +- 5 files changed, 212 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ebd15726..3120c2703 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -285,6 +285,9 @@ name = "bitflags" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +dependencies = [ + "serde", +] [[package]] name = "block-buffer" @@ -370,9 +373,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -476,6 +479,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crossbeam-utils" version = "0.8.16" @@ -1135,6 +1153,15 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "lockfree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ee94b5ad113c7cb98c5a040f783d0952ee4fe100993881d1673c2cb002dd23" +dependencies = [ + "owned-alloc", +] + [[package]] name = "log" version = "0.4.21" @@ -1297,9 +1324,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -1363,6 +1390,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "owned-alloc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30fceb411f9a12ff9222c5f824026be368ff15dc2f13468d850c7d3f502205d6" + [[package]] name = "parking" version = "2.1.0" @@ -1574,6 +1607,15 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -1779,6 +1821,18 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64", + "bitflags 2.4.0", + "serde", + "serde_derive", +] + [[package]] name = "rsa" version = "0.9.2" @@ -1946,6 +2000,12 @@ dependencies = [ "untrusted 0.9.0", ] +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + [[package]] name = "ryu" version = "1.0.15" @@ -2140,6 +2200,12 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + [[package]] name = "sha3" version = "0.10.8" @@ -2276,6 +2342,42 @@ dependencies = [ "der", ] +[[package]] +name = "stabby" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ec04c5825384722310b6a1fd83023bee0bfdc838f7aa3069f0a59e10203836b" +dependencies = [ + "lazy_static", + "rustversion", + "stabby-abi", +] + +[[package]] +name = "stabby-abi" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976322da1deb6cc64a8406fd24378b840b1962acaac1978a993131c3838d81b3" +dependencies = [ + "libc", + "rustversion", + "sha2-const-stable", + "stabby-macros", +] + +[[package]] +name = "stabby-macros" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736712a13ab37b1fa6e073831efca751bbcb31033af4d7308bd5d9d605939183" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "rand", + "syn 1.0.109", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -2375,6 +2477,20 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "thread-priority" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72cb4958060ee2d9540cef68bb3871fd1e547037772c7fe7650d5d1cbec53b3" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "log", + "rustversion", + "winapi", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -2494,6 +2610,23 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.0.0", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" version = "0.1.37" @@ -3082,9 +3215,19 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "zenoh" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "ahash", "async-trait", @@ -3140,6 +3283,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "zenoh-collections", ] @@ -3175,6 +3319,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "serde", "tracing", @@ -3187,10 +3332,12 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" [[package]] name = "zenoh-config" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "flume", "json5", @@ -3210,6 +3357,7 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-global-executor", "lazy_static", @@ -3221,6 +3369,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "aes", "hmac", @@ -3233,6 +3382,7 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "bincode", "flume", @@ -3244,12 +3394,14 @@ dependencies = [ "tokio", "tracing", "zenoh", + "zenoh-macros", "zenoh-util", ] [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "hashbrown 0.14.0", "keyed-set", @@ -3263,6 +3415,7 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "zenoh-config", @@ -3280,6 +3433,7 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "flume", @@ -3302,6 +3456,7 @@ dependencies = [ [[package]] name = "zenoh-link-quic" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "base64", @@ -3330,6 +3485,7 @@ dependencies = [ [[package]] name = "zenoh-link-tcp" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "tokio", @@ -3347,6 +3503,7 @@ dependencies = [ [[package]] name = "zenoh-link-tls" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "base64", @@ -3375,6 +3532,7 @@ dependencies = [ [[package]] name = "zenoh-link-udp" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "socket2 0.5.6", @@ -3395,6 +3553,7 @@ dependencies = [ [[package]] name = "zenoh-link-unixsock_stream" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "futures", @@ -3414,6 +3573,7 @@ dependencies = [ [[package]] name = "zenoh-link-ws" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "futures-util", @@ -3434,6 +3594,7 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "proc-macro2", "quote", @@ -3444,6 +3605,7 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "const_format", "libloading", @@ -3459,6 +3621,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "const_format", "rand", @@ -3473,6 +3636,7 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "anyhow", ] @@ -3480,10 +3644,16 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "futures", "lazy_static", + "libc", + "ron", + "serde", "tokio", + "zenoh-collections", + "zenoh-macros", "zenoh-protocol", "zenoh-result", ] @@ -3491,17 +3661,31 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ + "async-trait", + "bincode", + "crc", + "lazy_static", + "lockfree", + "num-traits", + "rand", "serde", "shared_memory", + "stabby", + "thread-priority", + "tokio", "tracing", "zenoh-buffers", + "zenoh-core", + "zenoh-macros", "zenoh-result", ] [[package]] name = "zenoh-sync" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "event-listener 4.0.0", "futures", @@ -3515,6 +3699,7 @@ dependencies = [ [[package]] name = "zenoh-task" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "futures", "tokio", @@ -3527,6 +3712,7 @@ dependencies = [ [[package]] name = "zenoh-transport" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "flume", @@ -3559,6 +3745,7 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-std", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 1d25448fe..1b5582b26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ maintenance = { status = "actively-developed" } [dependencies] async-std = "=1.12.0" async-trait = "0.1.66" -chrono = "0.4.34" +chrono = "0.4.37" env_logger = "0.10.0" futures = "0.3.26" json5 = "0.4.1" @@ -53,15 +53,10 @@ spin = "0.9.5" unwrap-infallible = "0.1.5" const_format = "0.2.32" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -#zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } -#zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } -#zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } -#zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } - -zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } -zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} -zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } -zenoh-util = { path = "../zenoh/commons/zenoh-util" } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } [build-dependencies] diff --git a/Cargo.toml.in b/Cargo.toml.in index b2ef20aa5..80c4f40ec 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -41,7 +41,7 @@ maintenance = { status = "actively-developed" } [dependencies] async-std = "=1.12.0" async-trait = "0.1.66" -chrono = "0.4.34" +chrono = "0.4.37" env_logger = "0.10.0" futures = "0.3.26" json5 = "0.4.1" @@ -53,15 +53,10 @@ spin = "0.9.5" unwrap-infallible = "0.1.5" const_format = "0.2.32" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -#zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } -#zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } -#zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } -#zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } - -zenoh = { path="../zenoh/zenoh", features = ["shared-memory", "unstable"], default-features = false } -zenoh-ext = { path = "../zenoh/zenoh-ext", features = ["unstable"]} -zenoh-protocol = { path = "../zenoh/commons/zenoh-protocol", features = ["shared-memory"] } -zenoh-util = { path = "../zenoh/commons/zenoh-util" } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } [build-dependencies] diff --git a/src/collections.rs b/src/collections.rs index 38412ba29..2b0dc1898 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -21,7 +21,8 @@ use zenoh::prelude::ZenohId; use crate::errors; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, + TransmuteRef, TransmuteUninitPtr, }; /// A contiguous view of bytes owned by some other entity. @@ -338,7 +339,10 @@ decl_transmute_handle!( ); pub use crate::opaque_types::z_owned_config_t; -decl_transmute_owned!(Option, Cow<'static, [u8]>>>, z_owned_slice_map_t); +decl_transmute_owned!( + Option, Cow<'static, [u8]>>>, + z_owned_slice_map_t +); /// Constructs a new empty map. #[no_mangle] @@ -372,7 +376,7 @@ pub extern "C" fn z_slice_map_drop(this: &mut z_owned_slice_map_t) { } #[no_mangle] -pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) ->z_slice_map_t { +pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> z_slice_map_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/payload.rs b/src/payload.rs index 582f65408..530fbf358 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -133,12 +133,13 @@ impl ZSliceBuffer for z_slice_t { fn as_slice(&self) -> &[u8] { unsafe { slice::from_raw_parts(self.start, self.len) } } - fn as_mut_slice(&mut self) -> &mut [u8] { - unsafe { slice::from_raw_parts_mut(self.start as *mut u8, self.len) } - } fn as_any(&self) -> &dyn Any { self } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } } /// Encodes byte sequence by aliasing. From a0e26653bc9d3a2d6922f61e57eaf0c58e40e2ce Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Wed, 24 Apr 2024 01:21:37 +0200 Subject: [PATCH 62/75] removed ref to local zenoh in build-resources --- build-resources/opaque-types/Cargo.lock | 181 ++++++++++++++++++++++++ build-resources/opaque-types/Cargo.toml | 8 +- 2 files changed, 183 insertions(+), 6 deletions(-) diff --git a/build-resources/opaque-types/Cargo.lock b/build-resources/opaque-types/Cargo.lock index 87d494976..ec5cafe8e 100644 --- a/build-resources/opaque-types/Cargo.lock +++ b/build-resources/opaque-types/Cargo.lock @@ -313,6 +313,9 @@ name = "bitflags" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +dependencies = [ + "serde", +] [[package]] name = "block-buffer" @@ -423,6 +426,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crossbeam-utils" version = "0.8.19" @@ -989,6 +1007,15 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "lockfree" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74ee94b5ad113c7cb98c5a040f783d0952ee4fe100993881d1673c2cb002dd23" +dependencies = [ + "owned-alloc", +] + [[package]] name = "log" version = "0.4.21" @@ -1173,6 +1200,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "owned-alloc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30fceb411f9a12ff9222c5f824026be368ff15dc2f13468d850c7d3f502205d6" + [[package]] name = "parking" version = "2.2.0" @@ -1380,6 +1413,15 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.79" @@ -1517,6 +1559,18 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64", + "bitflags 2.5.0", + "serde", + "serde_derive", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -1590,6 +1644,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + [[package]] name = "ryu" version = "1.0.17" @@ -1731,6 +1791,12 @@ dependencies = [ "digest", ] +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + [[package]] name = "sha3" version = "0.10.8" @@ -1831,6 +1897,42 @@ dependencies = [ "lock_api", ] +[[package]] +name = "stabby" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ec04c5825384722310b6a1fd83023bee0bfdc838f7aa3069f0a59e10203836b" +dependencies = [ + "lazy_static", + "rustversion", + "stabby-abi", +] + +[[package]] +name = "stabby-abi" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976322da1deb6cc64a8406fd24378b840b1962acaac1978a993131c3838d81b3" +dependencies = [ + "libc", + "rustversion", + "sha2-const-stable", + "stabby-macros", +] + +[[package]] +name = "stabby-macros" +version = "4.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736712a13ab37b1fa6e073831efca751bbcb31033af4d7308bd5d9d605939183" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "rand", + "syn 1.0.109", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -1897,6 +1999,20 @@ dependencies = [ "syn 2.0.55", ] +[[package]] +name = "thread-priority" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72cb4958060ee2d9540cef68bb3871fd1e547037772c7fe7650d5d1cbec53b3" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "log", + "rustversion", + "winapi", +] + [[package]] name = "thread_local" version = "1.1.8" @@ -1959,6 +2075,23 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" version = "0.1.40" @@ -2461,9 +2594,19 @@ version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "zenoh" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "ahash", "async-trait", @@ -2519,6 +2662,7 @@ dependencies = [ [[package]] name = "zenoh-buffers" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "zenoh-collections", ] @@ -2526,6 +2670,7 @@ dependencies = [ [[package]] name = "zenoh-codec" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "serde", "tracing", @@ -2538,10 +2683,12 @@ dependencies = [ [[package]] name = "zenoh-collections" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" [[package]] name = "zenoh-config" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "flume", "json5", @@ -2561,6 +2708,7 @@ dependencies = [ [[package]] name = "zenoh-core" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-global-executor", "lazy_static", @@ -2572,6 +2720,7 @@ dependencies = [ [[package]] name = "zenoh-crypto" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "aes", "hmac", @@ -2584,6 +2733,7 @@ dependencies = [ [[package]] name = "zenoh-ext" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "bincode", "flume", @@ -2595,12 +2745,14 @@ dependencies = [ "tokio", "tracing", "zenoh", + "zenoh-macros", "zenoh-util", ] [[package]] name = "zenoh-keyexpr" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "hashbrown 0.14.3", "keyed-set", @@ -2614,6 +2766,7 @@ dependencies = [ [[package]] name = "zenoh-link" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "zenoh-config", @@ -2625,6 +2778,7 @@ dependencies = [ [[package]] name = "zenoh-link-commons" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "flume", @@ -2647,6 +2801,7 @@ dependencies = [ [[package]] name = "zenoh-macros" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "proc-macro2", "quote", @@ -2657,6 +2812,7 @@ dependencies = [ [[package]] name = "zenoh-plugin-trait" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "const_format", "libloading", @@ -2672,6 +2828,7 @@ dependencies = [ [[package]] name = "zenoh-protocol" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "const_format", "rand", @@ -2686,6 +2843,7 @@ dependencies = [ [[package]] name = "zenoh-result" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "anyhow", ] @@ -2693,10 +2851,16 @@ dependencies = [ [[package]] name = "zenoh-runtime" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "futures", "lazy_static", + "libc", + "ron", + "serde", "tokio", + "zenoh-collections", + "zenoh-macros", "zenoh-protocol", "zenoh-result", ] @@ -2704,17 +2868,31 @@ dependencies = [ [[package]] name = "zenoh-shm" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ + "async-trait", + "bincode", + "crc", + "lazy_static", + "lockfree", + "num-traits", + "rand", "serde", "shared_memory", + "stabby", + "thread-priority", + "tokio", "tracing", "zenoh-buffers", + "zenoh-core", + "zenoh-macros", "zenoh-result", ] [[package]] name = "zenoh-sync" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "event-listener 4.0.3", "futures", @@ -2728,6 +2906,7 @@ dependencies = [ [[package]] name = "zenoh-task" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "futures", "tokio", @@ -2740,6 +2919,7 @@ dependencies = [ [[package]] name = "zenoh-transport" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-trait", "flume", @@ -2771,6 +2951,7 @@ dependencies = [ [[package]] name = "zenoh-util" version = "0.11.0-dev" +source = "git+https://github.com/eclipse-zenoh/zenoh.git?branch=explicit_api2#d10308568c7fb0444ea3412259bf344cafd0f8dc" dependencies = [ "async-std", "async-trait", diff --git a/build-resources/opaque-types/Cargo.toml b/build-resources/opaque-types/Cargo.toml index a1c020ed4..4d976ea98 100644 --- a/build-resources/opaque-types/Cargo.toml +++ b/build-resources/opaque-types/Cargo.toml @@ -7,10 +7,6 @@ edition = "2021" [dependencies] # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -# zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "main", features = ["shared-memory", "unstable"], default-features = false } +zenoh = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["shared-memory", "unstable"], default-features = false } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/eclipse-zenoh/zenoh.git", branch = "explicit_api2", features = ["unstable"] } const_format = "0.2.32" -zenoh = { path = "../../../zenoh/zenoh", features = [ - "shared-memory", - "unstable", -], default-features = false } -zenoh-ext = { path = "../../../zenoh/zenoh-ext", features = ["unstable"] } From c9cedafea83068239ce0e806922f23253b412e26 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Wed, 24 Apr 2024 10:34:02 +0200 Subject: [PATCH 63/75] z_get/z_delete examples compile --- examples/z_delete.c | 12 ++++++++---- examples/z_get.c | 36 ++++++++++++++++++++---------------- include/zenoh_commons.h | 4 ++-- include/zenoh_macros.h | 10 +++------- src/put.rs | 14 ++++++++------ 5 files changed, 41 insertions(+), 35 deletions(-) diff --git a/examples/z_delete.c b/examples/z_delete.c index 5000444bc..6f364dc80 100644 --- a/examples/z_delete.c +++ b/examples/z_delete.c @@ -21,7 +21,8 @@ int main(int argc, char **argv) { if (argc > 1) keyexpr = argv[1]; - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 3) { if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { printf( @@ -33,19 +34,22 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } printf("Deleting resources matching '%s'...\n", keyexpr); z_delete_options_t options = z_delete_options_default(); - int res = z_delete(z_loan(s), z_keyexpr(keyexpr), &options); + z_owned_keyexpr_t ke; + z_keyexpr(&ke, keyexpr); + int res = z_delete(z_loan(s), z_loan(ke), &options); if (res < 0) { printf("Delete failed...\n"); } + z_keyexpr_drop(z_move(ke)); z_close(z_move(s)); return 0; } diff --git a/examples/z_get.c b/examples/z_get.c index d8f90b35e..90291189c 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -30,12 +30,13 @@ int main(int argc, char **argv) { // Do nothing break; } - z_keyexpr_t keyexpr = z_keyexpr(expr); - if (!z_check(keyexpr)) { + z_owned_keyexpr_t keyexpr; + if (z_keyexpr(&keyexpr, expr) < 0) { printf("%s is not a valid key expression", expr); exit(-1); } - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 3) { if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[3]) < 0) { printf( @@ -47,8 +48,8 @@ int main(int argc, char **argv) { } printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + z_owned_session_t s; + if (!z_open(&s, z_move(config))) { printf("Unable to open session!\n"); exit(-1); } @@ -56,25 +57,28 @@ int main(int argc, char **argv) { printf("Sending Query '%s'...\n", expr); z_owned_reply_channel_t channel = zc_reply_fifo_new(16); z_get_options_t opts = z_get_options_default(); + z_owned_bytes_t payload; if (value != NULL) { - opts.payload = z_bytes_encode_from_string(value); + z_bytes_encode_from_string(&payload, value); + opts.payload = &payload; } - z_get(z_loan(s), keyexpr, "", z_move(channel.send), + z_get(z_loan(s), z_loan(keyexpr), "", z_move(channel.send), z_move(opts)); // here, the send is moved and will be dropped by zenoh when adequate - z_owned_reply_t reply = z_reply_null(); - z_owned_str_t payload_value = z_str_null(); + z_owned_reply_t reply; + z_owned_str_t reply_str; for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { - if (z_reply_is_ok(&reply)) { - z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); - printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); - z_drop(z_move(payload_value)); - z_drop(z_move(keystr)); + if (z_reply_is_ok(z_loan(reply))) { + z_sample_t sample = z_reply_ok(z_loan(reply)); + z_owned_str_t key_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_bytes_decode_into_string(z_sample_payload(&sample), &reply_str); + printf(">> Received ('%s': '%s')\n", z_loan(key_str), z_loan(reply_str)); + z_drop(z_move(reply_str)); + z_drop(z_move(key_str)); } else { printf("Received an error\n"); } } + z_drop(z_move(keyexpr)); z_drop(z_move(reply)); z_drop(z_move(channel)); z_close(z_move(s)); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 88a84d4dd..88bf8cae1 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1218,14 +1218,14 @@ z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, * Parameters: * session: The zenoh session. * key_expr: The key expression to delete. - * options: The put options. + * options: The delete options. * Returns: * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API z_error_t z_delete(struct z_session_t session, struct z_keyexpr_t key_expr, - struct z_delete_options_t opts); + struct z_delete_options_t *options); /** * Constructs the default value for :c:type:`z_put_options_t`. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 69f89de72..531bf095c 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -17,6 +17,7 @@ z_owned_slice_t : z_slice_loan, \ z_owned_bytes_t : z_bytes_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan,\ + z_owned_reply_t : z_owned_reply_t, \ z_owned_mutex_t : z_mutex_loan, \ z_condvar_t : z_condvar_loan, \ z_owned_bytes_reader_t : z_bytes_reader_loan \ @@ -93,11 +94,9 @@ _Generic((x), z_owned_session_t : z_session_check, \ z_owned_publisher_t : z_publisher_check, \ z_owned_keyexpr_t : z_keyexpr_check, \ - z_keyexpr_t : z_keyexpr_is_initialized, \ z_owned_config_t : z_config_check, \ z_owned_scouting_config_t : z_scouting_config_check, \ z_owned_subscriber_t : z_subscriber_check, \ - z_owned_pull_subscriber_t : z_pull_subscriber_check, \ z_owned_queryable_t : z_queryable_check, \ z_owned_encoding_t : z_encoding_check, \ z_owned_reply_t : z_reply_check, \ @@ -109,9 +108,9 @@ z_owned_bytes_t : z_bytes_check, \ zc_owned_liveliness_token_t : zc_liveliness_token_check, \ ze_owned_publication_cache_t : ze_publication_cache_check, \ - ze_owned_querying_subscriber_t : ze_querying_subscriber_check \ + ze_owned_querying_subscriber_t : ze_querying_subscriber_check,\ z_owned_mutex_t : z_mutex_check, \ - z_owned_condvar_t : z_owned_condar_check, \ + z_owned_condvar_t : z_condvar_check, \ z_owned_task_t : z_task_check \ )(&x) @@ -211,7 +210,6 @@ template<> inline int8_t z_drop(z_owned_publisher_t* v) { return z_undeclare_pub template<> inline void z_drop(z_owned_keyexpr_t* v) { z_keyexpr_drop(v); } template<> inline void z_drop(z_owned_config_t* v) { z_config_drop(v); } template<> inline void z_drop(z_owned_scouting_config_t* v) { z_scouting_config_drop(v); } -template<> inline int8_t z_drop(z_owned_pull_subscriber_t* v) { return z_undeclare_pull_subscriber(v); } template<> inline int8_t z_drop(z_owned_subscriber_t* v) { return z_undeclare_subscriber(v); } template<> inline int8_t z_drop(z_owned_queryable_t* v) { return z_undeclare_queryable(v); } template<> inline void z_drop(z_owned_encoding_t* v) { z_encoding_drop(v); } @@ -271,13 +269,11 @@ inline void z_null(z_owned_task_t& v) { v = z_task_null(); } inline bool z_check(const z_owned_session_t& v) { return z_session_check(&v); } inline bool z_check(const z_owned_publisher_t& v) { return z_publisher_check(&v); } inline bool z_check(const z_owned_keyexpr_t& v) { return z_keyexpr_check(&v); } -inline bool z_check(const z_keyexpr_t& v) { return z_keyexpr_is_initialized(&v); } inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } inline bool z_check(const z_owned_bytes_t& v) { return z_slice_check(&v); } inline bool z_check(const z_owned_bytes_reader_t& v) { return z_bytes_reader_check(&v); } inline bool z_check(const z_owned_subscriber_t& v) { return z_subscriber_check(&v); } -inline bool z_check(const z_owned_pull_subscriber_t& v) { return z_pull_subscriber_check(&v); } inline bool z_check(const z_owned_queryable_t& v) { return z_queryable_check(&v); } inline bool z_check(const z_owned_encoding_t& v) { return z_encoding_check(&v); } inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } diff --git a/src/put.rs b/src/put.rs index 8bc9505d1..728499034 100644 --- a/src/put.rs +++ b/src/put.rs @@ -129,7 +129,7 @@ pub unsafe extern "C" fn z_delete_options_default() -> z_delete_options_t { /// Parameters: /// session: The zenoh session. /// key_expr: The key expression to delete. -/// options: The put options. +/// options: The delete options. /// Returns: /// ``0`` in case of success, negative values in case of failure. #[no_mangle] @@ -137,14 +137,16 @@ pub unsafe extern "C" fn z_delete_options_default() -> z_delete_options_t { pub extern "C" fn z_delete( session: z_session_t, key_expr: z_keyexpr_t, - opts: z_delete_options_t, + options: Option<&mut z_delete_options_t>, ) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); - let del = session - .delete(key_expr) - .congestion_control(opts.congestion_control.into()) - .priority(opts.priority.into()); + let mut del = session + .delete(key_expr); + if let Some(options) = options { + del = del.congestion_control(options.congestion_control.into()) + .priority(options.priority.into()); + } match del.res_sync() { Err(e) => { From 1b54f3f82c53b375e995e777c632b405508d8769 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Wed, 24 Apr 2024 11:10:39 +0200 Subject: [PATCH 64/75] z_get_liveliness example builds --- examples/z_get_liveliness.c | 27 +++++++++++++++------------ include/zenoh_commons.h | 7 ++++++- include/zenoh_macros.h | 5 ++--- src/collections.rs | 1 + src/get.rs | 14 ++++++++++---- src/liveliness.rs | 6 ++++-- 6 files changed, 38 insertions(+), 22 deletions(-) diff --git a/examples/z_get_liveliness.c b/examples/z_get_liveliness.c index 9a00f3ca3..08ed225f1 100644 --- a/examples/z_get_liveliness.c +++ b/examples/z_get_liveliness.c @@ -22,13 +22,14 @@ int main(int argc, char **argv) { expr = argv[1]; } - z_keyexpr_t keyexpr = z_keyexpr(expr); - if (!z_check(keyexpr)) { + z_owned_keyexpr_t keyexpr; + if (z_keyexpr(&keyexpr, expr) < 0) { printf("%s is not a valid key expression\n", expr); exit(-1); } - z_owned_config_t config = z_config_default(); + z_owned_config_t config; + z_config_default(&config); if (argc > 2) { if (zc_config_insert_json(z_loan(config), Z_CONFIG_CONNECT_KEY, argv[2]) < 0) { printf( @@ -39,27 +40,29 @@ int main(int argc, char **argv) { } } + z_owned_session_t s; printf("Opening session...\n"); - z_owned_session_t s = z_open(z_move(config)); - if (!z_check(s)) { + if (z_open(&s, z_move(config)) < 0) { printf("Unable to open session!\n"); exit(-1); } printf("Sending liveliness query '%s'...\n", expr); z_owned_reply_channel_t channel = zc_reply_fifo_new(16); - zc_liveliness_get(z_loan(s), keyexpr, z_move(channel.send), NULL); - z_owned_reply_t reply = z_reply_null(); + zc_liveliness_get(z_loan(s), z_loan(keyexpr), z_move(channel.send), NULL); + z_owned_reply_t reply; for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { - if (z_reply_is_ok(&reply)) { - z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); - printf(">> Alive token ('%s')\n", z_loan(keystr)); - z_drop(z_move(keystr)); + if (z_reply_is_ok(z_loan(reply))) { + z_sample_t sample = z_reply_ok(z_loan(reply)); + z_owned_str_t key_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + printf(">> Alive token ('%s')\n", z_loan(key_str)); + z_drop(z_move(key_str)); } else { printf("Received an error\n"); } } + + z_drop(z_move(keyexpr)); z_drop(z_move(reply)); z_drop(z_move(channel)); z_close(z_move(s)); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 88bf8cae1..08fe40b04 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -1753,6 +1753,7 @@ struct z_value_t z_reply_err(struct z_reply_t reply); */ ZENOHC_API bool z_reply_is_ok(struct z_reply_t reply); +ZENOHC_API struct z_reply_t z_reply_loan(struct z_owned_reply_t *this_); /** * Returns an invalidated :c:type:`z_owned_reply_t`. * @@ -1857,6 +1858,10 @@ ZENOHC_API int8_t z_sleep_us(size_t time); */ ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *b); ZENOHC_API struct z_owned_slice_t z_slice_clone(const struct z_slice_t *b); +/** + * Frees `b` and invalidates it for double-drop safety. + */ +ZENOHC_API void z_slice_drop(struct z_owned_slice_t *b); /** * Returns the gravestone value for `z_slice_t` */ @@ -2167,7 +2172,7 @@ ZENOHC_API z_error_t zc_liveliness_get(struct z_session_t session, struct z_keyexpr_t key_expr, struct z_owned_closure_reply_t *callback, - struct zc_liveliness_get_options_t options); + struct zc_liveliness_get_options_t *options); /** * The gravestone value for `zc_liveliness_get_options_t` */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 531bf095c..fbd60560b 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -17,7 +17,7 @@ z_owned_slice_t : z_slice_loan, \ z_owned_bytes_t : z_bytes_loan, \ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan,\ - z_owned_reply_t : z_owned_reply_t, \ + z_owned_reply_t : z_reply_loan, \ z_owned_mutex_t : z_mutex_loan, \ z_condvar_t : z_condvar_loan, \ z_owned_bytes_reader_t : z_bytes_reader_loan \ @@ -54,8 +54,7 @@ z_owned_bytes_t * : z_bytes_drop, \ z_owned_bytes_reader_t * : z_bytes_reader_drop, \ z_owned_mutex_t * : z_mutex_drop, \ - z_owned_condvar_t * : z_condvar_drop, \ - z_owned_bytes_reader_t * : z_bytes_reader_drop \ + z_owned_condvar_t * : z_condvar_drop \ )(x) #define z_null(x) (*x = \ diff --git a/src/collections.rs b/src/collections.rs index 2b0dc1898..740870321 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -156,6 +156,7 @@ pub unsafe extern "C" fn z_slice_wrap(start: *const u8, len: usize) -> z_slice_t } /// Frees `b` and invalidates it for double-drop safety. +#[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_slice_drop(b: &mut z_owned_slice_t) { if !b.start.is_null() { diff --git a/src/get.rs b/src/get.rs index bdf8ddfa0..8be10c18b 100644 --- a/src/get.rs +++ b/src/get.rs @@ -22,6 +22,7 @@ use zenoh::sample::ValueBuilderTrait; use zenoh::prelude::{ConsolidationMode, Mode, QueryConsolidation, QueryTarget, Reply}; use crate::errors; +use crate::transmute::unwrap_ref_unchecked; use crate::transmute::Inplace; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; @@ -194,17 +195,22 @@ pub unsafe extern "C" fn z_get( /// Frees `reply`, invalidating it for double-drop safety. #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_drop(this: &mut z_owned_reply_t) { +pub extern "C" fn z_reply_drop(this: &mut z_owned_reply_t) { Inplace::drop(this.transmute_mut()) } /// Returns ``true`` if `reply` is valid. #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { +pub extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { this.transmute_ref().is_some() } +#[no_mangle] +pub extern "C" fn z_reply_loan(this: &mut z_owned_reply_t) -> z_reply_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() +} + /// The replies consolidation strategy to apply on replies to a :c:func:`z_get`. #[repr(C)] #[derive(Clone, Copy)] diff --git a/src/liveliness.rs b/src/liveliness.rs index f35c1ce22..fed6a9bfc 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -184,7 +184,7 @@ pub extern "C" fn zc_liveliness_get( session: z_session_t, key_expr: z_keyexpr_t, callback: &mut z_owned_closure_reply_t, - options: zc_liveliness_get_options_t, + options: Option<&mut zc_liveliness_get_options_t>, ) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); @@ -193,7 +193,9 @@ pub extern "C" fn zc_liveliness_get( let mut builder = liveliness .get(key_expr) .callback(move |response| z_closure_reply_call(&callback, response.transmute_handle())); - builder = builder.timeout(core::time::Duration::from_millis(options.timeout_ms as u64)); + if let Some(options) = options { + builder = builder.timeout(core::time::Duration::from_millis(options.timeout_ms as u64)); + } match builder.res() { Ok(()) => errors::Z_OK, Err(e) => { From 504a81cdeb45dae780fb55ae65fa14823993869d Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Wed, 24 Apr 2024 23:10:53 +0200 Subject: [PATCH 65/75] fixed api to newly-agreed usage of handle pointers --- build-resources/opaque-types/src/lib.rs | 34 +- build.rs | 6 +- include/zenoh_commons.h | 444 ++++++++++++------------ include/zenoh_concrete.h | 5 +- src/closures/query_channel.rs | 8 +- src/closures/query_closure.rs | 10 +- src/closures/reply_closure.rs | 10 +- src/closures/response_channel.rs | 4 +- src/closures/sample_closure.rs | 10 +- src/collections.rs | 118 ++++--- src/commons.rs | 57 +-- src/config.rs | 46 ++- src/errors.rs | 1 + src/get.rs | 41 +-- src/keyexpr.rs | 88 ++--- src/liveliness.rs | 25 +- src/payload.rs | 30 +- src/publisher.rs | 46 +-- src/put.rs | 20 +- src/queryable.rs | 55 ++- src/querying_subscriber.rs | 16 +- src/scouting.rs | 36 +- src/session.rs | 20 +- src/subscriber.rs | 12 +- src/transmute.rs | 27 +- 25 files changed, 588 insertions(+), 581 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 9e9f7d434..3781c062c 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -44,29 +44,29 @@ macro_rules! get_opaque_type_data { /// To minimize copies and reallocations, Zenoh may provide you data in split buffers. get_opaque_type_data!(Option, z_owned_bytes_t); /// A loaned payload. -get_opaque_type_data!(&'static ZBytes, z_bytes_t); +get_opaque_type_data!(ZBytes, z_bytes_t); /// A map of maybe-owned vector of bytes to maybe-owned vector of bytes. /// /// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher get_opaque_type_data!(Option, Cow<'static, [u8]>>>, z_owned_slice_map_t); -get_opaque_type_data!(&'static HashMap, Cow<'static, [u8]>>, z_slice_map_t); +get_opaque_type_data!(HashMap, Cow<'static, [u8]>>, z_slice_map_t); /// An owned sample. /// /// This is a read only type that can only be constructed by cloning a `z_sample_t`. /// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. get_opaque_type_data!(Option, zc_owned_sample_t); -get_opaque_type_data!(&'static Sample, z_sample_t); +get_opaque_type_data!(Sample, z_sample_t); /// A reader for payload data. get_opaque_type_data!(Option>, z_owned_bytes_reader_t); -get_opaque_type_data!(&'static ZBytesReader<'static>, z_bytes_reader_t); +get_opaque_type_data!(ZBytesReader<'static>, z_bytes_reader_t); /// The encoding of a payload, in a MIME-like format. /// /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. -get_opaque_type_data!(&'static Encoding, z_encoding_t); +get_opaque_type_data!(Encoding, z_encoding_t); get_opaque_type_data!(Encoding, z_owned_encoding_t); /// An owned reply to a :c:func:`z_get`. @@ -77,18 +77,18 @@ get_opaque_type_data!(Encoding, z_owned_encoding_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. get_opaque_type_data!(Option, z_owned_reply_t); -get_opaque_type_data!(&'static Reply, z_reply_t); +get_opaque_type_data!(Reply, z_reply_t); /// A zenoh value. get_opaque_type_data!(Value, z_owned_value_t); -get_opaque_type_data!(&'static Value, z_value_t); +get_opaque_type_data!(Value, z_value_t); // Loaned variant of a Query received by a Queryable. /// /// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. /// `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. get_opaque_type_data!(Option, z_owned_query_t); -get_opaque_type_data!(&'static Query, z_query_t); +get_opaque_type_data!(Query, z_query_t); /// An owned zenoh queryable. /// @@ -101,7 +101,7 @@ get_opaque_type_data!(&'static Query, z_query_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_queryable_t); -get_opaque_type_data!(&'static Queryable<'static, ()>, z_queryable_t); +get_opaque_type_data!(Queryable<'static, ()>, z_queryable_t); /// An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. /// @@ -114,7 +114,7 @@ get_opaque_type_data!(&'static Queryable<'static, ()>, z_queryable_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t); -get_opaque_type_data!(&'static (zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_querying_subscriber_t); +get_opaque_type_data!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_querying_subscriber_t); /// A zenoh-allocated key expression. /// @@ -151,7 +151,7 @@ get_opaque_type_data!(Option>, z_owned_keyexpr_t); /// /// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, /// both for local processing and network-wise. -get_opaque_type_data!(&'static KeyExpr<'_>, z_keyexpr_t); +get_opaque_type_data!(KeyExpr<'_>, z_keyexpr_t); /// An owned zenoh session. /// @@ -164,7 +164,7 @@ get_opaque_type_data!(&'static KeyExpr<'_>, z_keyexpr_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_session_t); -get_opaque_type_data!(&'static Session, z_session_t); +get_opaque_type_data!(Session, z_session_t); /// An owned zenoh configuration. /// @@ -176,9 +176,9 @@ get_opaque_type_data!(&'static Session, z_session_t); /// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. -get_opaque_type_data!(Option>, z_owned_config_t); +get_opaque_type_data!(Option, z_owned_config_t); /// A loaned zenoh configuration. -get_opaque_type_data!(&'static Config, z_config_t); +get_opaque_type_data!(Config, z_config_t); /// Represents a Zenoh ID. /// @@ -198,7 +198,7 @@ get_opaque_type_data!(Timestamp, z_timestamp_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_publisher_t); -get_opaque_type_data!(&'static Publisher<'static>, z_publisher_t); +get_opaque_type_data!(Publisher<'static>, z_publisher_t); /// An owned zenoh matching listener. Destroying the matching listener cancels the subscription. /// @@ -224,7 +224,7 @@ get_opaque_type_data!(Option>, zcu_own /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_subscriber_t); -get_opaque_type_data!(&'static Subscriber<'static, ()>, z_subscriber_t); +get_opaque_type_data!(Subscriber<'static, ()>, z_subscriber_t); /// A liveliness token that can be used to provide the network with information about connectivity to its /// declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key @@ -232,7 +232,7 @@ get_opaque_type_data!(&'static Subscriber<'static, ()>, z_subscriber_t); /// /// A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. get_opaque_type_data!(Option>, zc_owned_liveliness_token_t); -get_opaque_type_data!(&'static LivelinessToken<'static>, zc_liveliness_token_t); +get_opaque_type_data!(LivelinessToken<'static>, zc_liveliness_token_t); /// An owned zenoh publication_cache. diff --git a/build.rs b/build.rs index 50668d5a6..01fc61a4a 100644 --- a/build.rs +++ b/build.rs @@ -85,6 +85,9 @@ fn produce_opaque_types_data() -> PathBuf { } fn generate_opaque_types() { + let type_to_inner_field_name = HashMap::from([ + ("z_id_t", "id"), + ]); let current_folder = get_build_rs_path(); let path_in = produce_opaque_types_data(); let path_out = current_folder.join("./src/opaque_types/mod.rs"); @@ -98,11 +101,12 @@ fn generate_opaque_types() { let re = Regex::new(r"type: (\w+), align: (\d+), size: (\d+)").unwrap(); for (_, [type_name, align, size]) in re.captures_iter(&data_in).map(|c| c.extract()) { + let inner_field_name = type_to_inner_field_name.get(type_name).unwrap_or(&"_0"); let s = format!( "#[derive(Copy, Clone)] #[repr(C, align({align}))] pub struct {type_name} {{ - _0: [u8; {size}], + {inner_field_name}: [u8; {size}], }} " ); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 08fe40b04..0a3a59df7 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -122,15 +122,15 @@ typedef enum zcu_reply_keyexpr_t { typedef struct ALIGN(8) z_owned_bytes_t { uint8_t _0[40]; } z_owned_bytes_t; -typedef int8_t z_error_t; /** * A loaned payload. */ typedef struct ALIGN(8) z_bytes_t { - uint8_t _0[8]; + uint8_t _0[40]; } z_bytes_t; +typedef int8_t z_error_t; typedef struct z_owned_slice_t { - uint8_t *start; + const uint8_t *start; size_t len; } z_owned_slice_t; /** @@ -160,7 +160,7 @@ typedef struct z_slice_t { size_t len; } z_slice_t; typedef struct ALIGN(8) z_slice_map_t { - uint8_t _0[8]; + uint8_t _0[48]; } z_slice_map_t; /** * A reader for payload data. @@ -169,7 +169,7 @@ typedef struct ALIGN(8) z_owned_bytes_reader_t { uint8_t _0[24]; } z_owned_bytes_reader_t; typedef struct ALIGN(8) z_bytes_reader_t { - uint8_t _0[8]; + uint8_t _0[24]; } z_bytes_reader_t; /** * Clock @@ -185,7 +185,7 @@ typedef struct z_clock_t { * In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. */ typedef struct ALIGN(1) z_id_t { - uint8_t _0[16]; + uint8_t id[16]; } z_id_t; /** * An owned array of owned, zenoh allocated, NULL terminated strings. @@ -287,11 +287,11 @@ typedef struct z_owned_closure_owned_query_t { */ typedef struct z_owned_closure_query_t { void *context; - void (*call)(struct z_query_t, void *context); + void (*call)(const struct z_query_t*, void *context); void (*drop)(void*); } z_owned_closure_query_t; typedef struct ALIGN(8) z_reply_t { - uint8_t _0[8]; + uint8_t _0[256]; } z_reply_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: @@ -311,11 +311,11 @@ typedef struct ALIGN(8) z_reply_t { */ typedef struct z_owned_closure_reply_t { void *context; - void (*call)(struct z_reply_t, void*); + void (*call)(const struct z_reply_t*, void*); void (*drop)(void*); } z_owned_closure_reply_t; typedef struct ALIGN(8) z_sample_t { - uint8_t _0[8]; + uint8_t _0[240]; } z_sample_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. @@ -335,7 +335,7 @@ typedef struct ALIGN(8) z_sample_t { */ typedef struct z_owned_closure_sample_t { void *context; - void (*call)(struct z_sample_t, void *context); + void (*call)(const struct z_sample_t*, void *context); void (*drop)(void*); } z_owned_closure_sample_t; /** @@ -381,13 +381,13 @@ typedef struct ALIGN(8) z_mutex_t { * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. */ typedef struct ALIGN(8) z_owned_config_t { - uint8_t _0[8]; + uint8_t _0[1544]; } z_owned_config_t; /** * A loaned zenoh configuration. */ typedef struct ALIGN(8) z_config_t { - uint8_t _0[8]; + uint8_t _0[1544]; } z_config_t; /** * A zenoh-allocated key expression. @@ -431,19 +431,8 @@ typedef struct ALIGN(8) z_owned_keyexpr_t { * both for local processing and network-wise. */ typedef struct ALIGN(8) z_keyexpr_t { - uint8_t _0[8]; + uint8_t _0[32]; } z_keyexpr_t; -/** - * Options passed to the :c:func:`z_declare_publisher` function. - * - * Members: - * z_congestion_control_t congestion_control: The congestion control to apply when routing messages from this publisher. - * z_priority_t priority: The priority of messages from this publisher. - */ -typedef struct z_publisher_options_t { - enum z_congestion_control_t congestion_control; - enum z_priority_t priority; -} z_publisher_options_t; /** * An owned zenoh publisher. * @@ -459,6 +448,17 @@ typedef struct z_publisher_options_t { typedef struct ALIGN(8) z_owned_publisher_t { uint8_t _0[56]; } z_owned_publisher_t; +/** + * Options passed to the :c:func:`z_declare_publisher` function. + * + * Members: + * z_congestion_control_t congestion_control: The congestion control to apply when routing messages from this publisher. + * z_priority_t priority: The priority of messages from this publisher. + */ +typedef struct z_publisher_options_t { + enum z_congestion_control_t congestion_control; + enum z_priority_t priority; +} z_publisher_options_t; /** * Options passed to the :c:func:`z_declare_queryable` function. * @@ -493,7 +493,7 @@ typedef struct ALIGN(8) z_owned_encoding_t { * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. */ typedef struct ALIGN(8) z_encoding_t { - uint8_t _0[8]; + uint8_t _0[48]; } z_encoding_t; /** * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. @@ -549,7 +549,7 @@ typedef struct ALIGN(8) z_owned_mutex_t { uint8_t _0[32]; } z_owned_mutex_t; typedef struct ALIGN(8) z_publisher_t { - uint8_t _0[8]; + uint8_t _0[56]; } z_publisher_t; /** * Represents the set of options that can be applied to the delete operation by a previously declared publisher, @@ -622,7 +622,7 @@ typedef struct z_query_reply_options_t { struct z_owned_bytes_t *attachment; } z_query_reply_options_t; typedef struct ALIGN(8) z_value_t { - uint8_t _0[8]; + uint8_t _0[88]; } z_value_t; /** * An owned reply to a :c:func:`z_get`. @@ -661,6 +661,15 @@ typedef struct z_owned_reply_channel_t { struct z_owned_closure_reply_t send; struct z_owned_reply_channel_closure_t recv; } z_owned_reply_channel_t; +/** + * An owned sample. + * + * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + */ +typedef struct ALIGN(8) zc_owned_sample_t { + uint8_t _0[240]; +} zc_owned_sample_t; typedef struct ALIGN(8) z_timestamp_t { uint8_t _0[24]; } z_timestamp_t; @@ -677,9 +686,11 @@ typedef struct z_owned_scouting_config_t { * * Returning `true` is treated as `continue`. */ -typedef bool (*z_slice_map_iter_body_t)(struct z_slice_t key, struct z_slice_t value, void *context); +typedef bool (*z_slice_map_iter_body_t)(const struct z_slice_t *key, + const struct z_slice_t *value, + void *context); typedef struct ALIGN(8) z_subscriber_t { - uint8_t _0[8]; + uint8_t _0[32]; } z_subscriber_t; typedef struct ALIGN(8) z_owned_task_t { uint8_t _0[24]; @@ -722,15 +733,6 @@ typedef struct ALIGN(8) zc_owned_liveliness_token_t { typedef struct zc_liveliness_get_options_t { uint32_t timeout_ms; } zc_liveliness_get_options_t; -/** - * An owned sample. - * - * This is a read only type that can only be constructed by cloning a `z_sample_t`. - * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. - */ -typedef struct ALIGN(8) zc_owned_sample_t { - uint8_t _0[240]; -} zc_owned_sample_t; /** * A struct that indicates if there exist Subscribers matching the Publisher's key expression. * @@ -848,7 +850,7 @@ typedef struct ze_querying_subscriber_options_t { uint64_t query_timeout_ms; } ze_querying_subscriber_options_t; typedef struct ALIGN(8) ze_querying_subscriber_t { - uint8_t _0[8]; + uint8_t _0[64]; } ze_querying_subscriber_t; ZENOHC_API extern const unsigned int Z_ROUTER; ZENOHC_API extern const unsigned int Z_PEER; @@ -871,12 +873,12 @@ ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *payload); /** * Increments the payload's reference count, returning an owned version of it. */ -ZENOHC_API void z_bytes_clone(const struct z_owned_bytes_t *src, struct z_owned_bytes_t *dst); +ZENOHC_API void z_bytes_clone(const struct z_bytes_t *src, struct z_owned_bytes_t *dst); /** * Decodes payload into owned bytes */ ZENOHC_API -z_error_t z_bytes_decode_into_bytes(struct z_bytes_t payload, +z_error_t z_bytes_decode_into_bytes(const struct z_bytes_t *payload, struct z_owned_slice_t *dst); /** * Decodes payload into bytes map. @@ -888,7 +890,7 @@ z_error_t z_bytes_decode_into_bytes_map(struct z_bytes_t payload, * Decodes payload into null-terminated string. */ ZENOHC_API -z_error_t z_bytes_decode_into_string(struct z_bytes_t payload, +z_error_t z_bytes_decode_into_string(const struct z_bytes_t *payload, struct z_owned_str_t *dst); /** * Decrements the payload's reference counter, destroying it if applicable. @@ -899,13 +901,15 @@ ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); /** * Encodes byte sequence by aliasing. */ -ZENOHC_API void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, struct z_slice_t bytes); +ZENOHC_API +void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, + const struct z_slice_t *bytes); /** * Encodes bytes map by copying. */ ZENOHC_API void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, - struct z_slice_map_t bytes_map); + const struct z_slice_map_t *bytes_map); /** * Encodes a null-terminated string by aliasing. */ @@ -913,18 +917,19 @@ ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const /** * Returns total number bytes in the payload. */ -ZENOHC_API size_t z_bytes_len(struct z_bytes_t payload); +ZENOHC_API size_t z_bytes_len(const struct z_bytes_t *payload); /** * Loans the payload, allowing you to call functions that only need a loan of it. */ -ZENOHC_API struct z_bytes_t z_bytes_loan(const struct z_owned_bytes_t *payload); +ZENOHC_API const struct z_bytes_t *z_bytes_loan(const struct z_owned_bytes_t *payload); /** * The gravestone value for `z_owned_bytes_t`. */ ZENOHC_API void z_bytes_null(struct z_owned_bytes_t *this_); ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_reader_t *this_); ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_reader_t *this_); -ZENOHC_API struct z_bytes_reader_t z_bytes_reader_loan(const struct z_owned_bytes_reader_t *reader); +ZENOHC_API +const struct z_bytes_reader_t *z_bytes_reader_loan(const struct z_owned_bytes_reader_t *reader); /** * Creates a reader for the specified `payload`. * @@ -939,7 +944,7 @@ ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_reader_t *this_); * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. */ ZENOHC_API -size_t z_bytes_reader_read(struct z_bytes_reader_t this_, +size_t z_bytes_reader_read(const struct z_bytes_reader_t *this_, uint8_t *dest, size_t len); /** @@ -949,14 +954,14 @@ size_t z_bytes_reader_read(struct z_bytes_reader_t this_, * Return ​0​ upon success, negative error code otherwise. */ ZENOHC_API -z_error_t z_bytes_reader_seek(struct z_bytes_reader_t this_, +z_error_t z_bytes_reader_seek(const struct z_bytes_reader_t *this_, int64_t offset, int origin); /** * Returns the read position indicator. * Returns read position indicator on success or -1L if failure occurs. */ -ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t this_); +ZENOHC_API int64_t z_bytes_reader_tell(const struct z_bytes_reader_t *this_); ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); @@ -967,7 +972,7 @@ ZENOHC_API struct z_clock_t z_clock_now(void); * Returns a negative value if an error occured while closing the session. * Returns the remaining reference count of the session otherwise, saturating at i8::MAX. */ -ZENOHC_API int8_t z_close(struct z_owned_session_t *session); +ZENOHC_API z_error_t z_close(struct z_owned_session_t *session); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1001,7 +1006,7 @@ ZENOHC_API struct z_owned_closure_owned_query_t z_closure_owned_query_null(void) */ ZENOHC_API void z_closure_query_call(const struct z_owned_closure_query_t *closure, - struct z_query_t query); + const struct z_query_t *query); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -1015,7 +1020,7 @@ ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); */ ZENOHC_API void z_closure_reply_call(const struct z_owned_closure_reply_t *closure, - struct z_reply_t reply); + const struct z_reply_t *reply); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -1029,7 +1034,7 @@ ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); */ ZENOHC_API void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, - struct z_sample_t sample); + const struct z_sample_t *sample); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -1068,9 +1073,9 @@ ZENOHC_API bool z_config_check(const struct z_owned_config_t *config); * If `peer` is not null, it is added to the configuration as remote peer. */ ZENOHC_API -z_error_t z_config_client(const char *const *peers, - size_t n_peers, - struct z_owned_config_t *this_); +z_error_t z_config_client(struct z_owned_config_t *this_, + const char *const *peers, + size_t n_peers); /** * Clones the config. */ @@ -1096,7 +1101,7 @@ ZENOHC_API void z_config_drop(struct z_owned_config_t *config); /** * Returns a :c:type:`z_config_t` loaned from `s`. */ -ZENOHC_API struct z_config_t z_config_loan(const struct z_owned_config_t *this_); +ZENOHC_API const struct z_config_t *z_config_loan(const struct z_owned_config_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_config_t' type */ @@ -1113,8 +1118,8 @@ ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); */ ZENOHC_API z_error_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr); + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr); /** * Declares a publisher for the given key expression. * @@ -1151,10 +1156,10 @@ z_error_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, * z_owned_publisher_t sub = z_declare_publisher(z_loan(s), z_keyexpr(expr), &opts); */ ZENOHC_API -z_error_t z_declare_publisher(struct z_session_t session, - struct z_keyexpr_t key_expr, - const struct z_publisher_options_t *options, - struct z_owned_publisher_t *this_); +z_error_t z_declare_publisher(struct z_owned_publisher_t *this_, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, + const struct z_publisher_options_t *options); /** * Creates a Queryable for the given key expression. * @@ -1169,8 +1174,8 @@ z_error_t z_declare_publisher(struct z_session_t session, */ ZENOHC_API z_error_t z_declare_queryable(struct z_owned_queryable_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_owned_closure_query_t *callback, struct z_queryable_options_t *options); /** @@ -1208,8 +1213,8 @@ z_error_t z_declare_queryable(struct z_owned_queryable_t *this_, */ ZENOHC_API z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_owned_closure_sample_t *callback, struct z_subscriber_options_t *options); /** @@ -1223,13 +1228,13 @@ z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API -z_error_t z_delete(struct z_session_t session, - struct z_keyexpr_t key_expr, +z_error_t z_delete(const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_delete_options_t *options); /** * Constructs the default value for :c:type:`z_put_options_t`. */ -ZENOHC_API struct z_delete_options_t z_delete_options_default(void); +ZENOHC_API void z_delete_options_default(struct z_delete_options_t *this_); /** * Returns ``true`` if `encoding` is valid. */ @@ -1237,7 +1242,7 @@ ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); /** * Constructs a default :c:type:`z_encoding_t`. */ -ZENOHC_API struct z_encoding_t z_encoding_default(void); +ZENOHC_API const struct z_encoding_t *z_encoding_default(void); /** * Frees `encoding`, invalidating it for double-drop safety. */ @@ -1249,7 +1254,7 @@ ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const /** * Returns a :c:type:`z_encoding_t` loaned from `encoding`. */ -ZENOHC_API struct z_encoding_t z_encoding_loan(const struct z_owned_encoding_t *encoding); +ZENOHC_API const struct z_encoding_t *z_encoding_loan(const struct z_owned_encoding_t *encoding); /** * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type */ @@ -1271,12 +1276,12 @@ ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); * options: additional options for the get. */ ZENOHC_API -z_error_t z_get(struct z_session_t session, - struct z_keyexpr_t key_expr, +z_error_t z_get(const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, const char *parameters, struct z_owned_closure_reply_t *callback, struct z_get_options_t *options); -ZENOHC_API struct z_get_options_t z_get_options_default(void); +ZENOHC_API void z_get_options_default(struct z_get_options_t *this_); /** * Returns ``true`` if `hello` is valid. */ @@ -1288,11 +1293,11 @@ ZENOHC_API void z_hello_drop(struct z_owned_hello_t *hello); /** * Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. */ -ZENOHC_API struct z_hello_t z_hello_loan(const struct z_owned_hello_t *hello); +ZENOHC_API const struct z_hello_t *z_hello_loan(const struct z_owned_hello_t *hello); /** * Constructs a gravestone value for hello, useful to steal one from a callback */ -ZENOHC_API struct z_owned_hello_t z_hello_null(void); +ZENOHC_API void z_hello_null(struct z_owned_hello_t *this_); /** * Fetches the Zenoh IDs of all connected peers. * @@ -1327,20 +1332,20 @@ ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); * Constructs a :c:type:`z_keyexpr_t` departing from a string. * It is a loaned key expression that aliases `name`. */ -ZENOHC_API z_error_t z_keyexpr(struct z_owned_keyexpr_t *this_, const char *name); +ZENOHC_API z_error_t z_keyexpr(struct z_keyexpr_t *this_, const char *name); /** * Returns the key expression's internal string by aliasing it. * * Currently exclusive to zenoh-c */ -ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(struct z_keyexpr_t ke); +ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(const struct z_keyexpr_t *ke); /** - * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. * The string is canonized in-place before being passed to keyexpr. * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). */ ZENOHC_API -z_error_t z_keyexpr_autocanonize(struct z_owned_keyexpr_t *this_, +z_error_t z_keyexpr_autocanonize(struct z_keyexpr_t *this_, char *name); /** * Canonizes the passed string in place, possibly shortening it by modifying `len`. @@ -1379,10 +1384,10 @@ ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); * as this would extremely likely cause bugs. */ ZENOHC_API -z_error_t z_keyexpr_concat(struct z_keyexpr_t left, +z_error_t z_keyexpr_concat(struct z_owned_keyexpr_t *this_, + const struct z_keyexpr_t *left, const char *right_start, - size_t right_len, - struct z_owned_keyexpr_t *this_); + size_t right_len); /** * Frees `keyexpr` and invalidates it for double-drop safety. */ @@ -1390,21 +1395,21 @@ ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); /** * Returns ``0`` if both ``left`` and ``right`` are equal. */ -ZENOHC_API bool z_keyexpr_equals(struct z_keyexpr_t left, struct z_keyexpr_t right); +ZENOHC_API bool z_keyexpr_equals(const struct z_keyexpr_t *left, const struct z_keyexpr_t *right); /** * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set * defined by ``right``. */ ZENOHC_API -bool z_keyexpr_includes(struct z_keyexpr_t left, - struct z_keyexpr_t right); +bool z_keyexpr_includes(const struct z_keyexpr_t *left, + const struct z_keyexpr_t *right); /** * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the * sets defined by ``left`` and ``right``. */ ZENOHC_API -bool z_keyexpr_intersects(struct z_keyexpr_t left, - struct z_keyexpr_t right); +bool z_keyexpr_intersects(const struct z_keyexpr_t *left, + const struct z_keyexpr_t *right); /** * Returns ``0`` if the passed string is a valid (and canon) key expression. * Otherwise returns error value @@ -1415,13 +1420,13 @@ ZENOHC_API z_error_t z_keyexpr_is_canon(const char *start, size_t len); * In case of error, the return value will be set to its invalidated state. */ ZENOHC_API -z_error_t z_keyexpr_join(struct z_keyexpr_t left, - struct z_keyexpr_t right, - struct z_owned_keyexpr_t *this_); +z_error_t z_keyexpr_join(struct z_owned_keyexpr_t *this_, + const struct z_keyexpr_t *left, + const struct z_keyexpr_t *right); /** * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. */ -ZENOHC_API struct z_keyexpr_t z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); +ZENOHC_API const struct z_keyexpr_t *z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); /** * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. */ @@ -1442,15 +1447,15 @@ ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. */ ZENOHC_API -enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(struct z_keyexpr_t left, - struct z_keyexpr_t right); +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_keyexpr_t *left, + const struct z_keyexpr_t *right); /** * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. * The user is responsible of droping the returned string using `z_drop` */ -ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t ke); +ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(const struct z_keyexpr_t *ke); /** - * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: * * - `name` MUST be valid UTF8. * - `name` MUST follow the Key Expression specification, ie: @@ -1462,7 +1467,7 @@ ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(struct z_keyexpr_t ke); * It is a loaned key expression that aliases `name`. */ ZENOHC_API -void z_keyexpr_unchecked(struct z_owned_keyexpr_t *this_, +void z_keyexpr_unchecked(struct z_keyexpr_t *this_, const char *name); ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); @@ -1482,7 +1487,7 @@ z_error_t z_open(struct z_owned_session_t *this_, /** * Returns ``true`` if `pub` is valid. */ -ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); +ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *this_); /** * Sends a `DELETE` message onto the publisher's key expression. * @@ -1490,7 +1495,7 @@ ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *pbl); * ``0`` in case of success, ``1`` in case of failure. */ ZENOHC_API -z_error_t z_publisher_delete(struct z_publisher_t publisher, +z_error_t z_publisher_delete(const struct z_publisher_t *publisher, struct z_publisher_delete_options_t _options); /** * Constructs the default values for the delete operation via a publisher entity. @@ -1498,15 +1503,15 @@ z_error_t z_publisher_delete(struct z_publisher_t publisher, * Returns: * Returns the constructed :c:type:`z_publisher_delete_options_t`. */ -ZENOHC_API struct z_publisher_delete_options_t z_publisher_delete_options_default(void); +ZENOHC_API void z_publisher_delete_options_default(struct z_publisher_delete_options_t *this_); /** * Returns the key expression of the publisher */ -ZENOHC_API struct z_keyexpr_t z_publisher_keyexpr(struct z_publisher_t publisher); +ZENOHC_API const struct z_keyexpr_t *z_publisher_keyexpr(const struct z_publisher_t *publisher); /** * Returns a :c:type:`z_publisher_t` loaned from `p`. */ -ZENOHC_API struct z_publisher_t z_publisher_loan(const struct z_owned_publisher_t *p); +ZENOHC_API const struct z_publisher_t *z_publisher_loan(const struct z_owned_publisher_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_publisher_t' type */ @@ -1514,7 +1519,7 @@ ZENOHC_API void z_publisher_null(struct z_owned_publisher_t *this_); /** * Constructs the default value for :c:type:`z_publisher_options_t`. */ -ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); +ZENOHC_API void z_publisher_options_default(struct z_publisher_options_t *this_); /** * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. * @@ -1532,13 +1537,13 @@ ZENOHC_API struct z_publisher_options_t z_publisher_options_default(void); * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API -z_error_t z_publisher_put(struct z_publisher_t publisher, +z_error_t z_publisher_put(const struct z_publisher_t *publisher, struct z_owned_bytes_t *payload, struct z_publisher_put_options_t *options); /** * Constructs the default value for :c:type:`z_publisher_put_options_t`. */ -ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void); +ZENOHC_API void z_publisher_put_options_default(struct z_publisher_put_options_t *this_); /** * Put data, transfering its ownership. * @@ -1555,20 +1560,20 @@ ZENOHC_API struct z_publisher_put_options_t z_publisher_put_options_default(void * ``0`` in case of success, negative error values in case of failure. */ ZENOHC_API -z_error_t z_put(struct z_session_t session, - struct z_keyexpr_t key_expr, +z_error_t z_put(const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_owned_bytes_t *payload, struct z_put_options_t *options); /** * Constructs the default value for :c:type:`z_put_options_t`. */ -ZENOHC_API struct z_put_options_t z_put_options_default(void); +ZENOHC_API void z_put_options_default(struct z_put_options_t *this_); /** * Gets the attachment to the query by aliasing. * - * Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. + * Returns NULL if query does not contain an attachment. */ -ZENOHC_API struct z_bytes_t z_query_attachment(struct z_query_t query); +ZENOHC_API const struct z_bytes_t *z_query_attachment(const struct z_query_t *query); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1601,8 +1606,8 @@ bool z_query_check(const struct z_owned_query_t *query); * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). */ ZENOHC_API -void z_query_clone(struct z_owned_query_t *this_, - struct z_query_t query); +void z_query_clone(const struct z_query_t *this_, + struct z_owned_query_t *dst); /** * Automatic query consolidation strategy selection. * @@ -1637,17 +1642,21 @@ ZENOHC_API struct z_query_consolidation_t z_query_consolidation_none(void); */ ZENOHC_API void z_query_drop(struct z_owned_query_t *this_); +/** + * Checks if query contains a payload value. + */ +ZENOHC_API bool z_query_has_value(const struct z_query_t *query); /** * Get a query's key by aliasing it. */ -ZENOHC_API struct z_keyexpr_t z_query_keyexpr(struct z_query_t query); +ZENOHC_API const struct z_keyexpr_t *z_query_keyexpr(const struct z_query_t *query); /** * Aliases the query. * * This function may not be called with the null pointer, but can be called with the gravestone value. */ ZENOHC_API -struct z_query_t z_query_loan(const struct z_owned_query_t *this_); +const struct z_query_t *z_query_loan(const struct z_owned_query_t *this_); /** * The gravestone value of `z_owned_query_t`. */ @@ -1656,7 +1665,7 @@ ZENOHC_API void z_query_null(struct z_owned_query_t *this_); * Get a query's `value selector `_ by aliasing it. */ ZENOHC_API -struct z_slice_t z_query_parameters(struct z_query_t query); +struct z_slice_t z_query_parameters(const struct z_query_t *query); /** * Send a reply to a query. * @@ -1681,7 +1690,7 @@ z_error_t z_query_reply(struct z_query_t query, /** * Constructs the default value for :c:type:`z_query_reply_options_t`. */ -ZENOHC_API struct z_query_reply_options_t z_query_reply_options_default(void); +ZENOHC_API void z_query_reply_options_default(struct z_query_reply_options_t *this_); /** * Create a default :c:type:`z_query_target_t`. */ @@ -1693,7 +1702,7 @@ ZENOHC_API enum z_query_target_t z_query_target_default(void); * Before calling this funciton, the user must ensure that `z_query_has_value` returns true. */ ZENOHC_API -struct z_value_t z_query_value(struct z_query_t query); +const struct z_value_t *z_query_value(const struct z_query_t *query); /** * Returns ``true`` if `qable` is valid. */ @@ -1705,7 +1714,7 @@ ZENOHC_API void z_queryable_null(struct z_owned_queryable_t *this_); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. */ -ZENOHC_API struct z_queryable_options_t z_queryable_options_default(void); +ZENOHC_API void z_queryable_options_default(struct z_queryable_options_t *this_); ZENOHC_API void z_random_fill(void *buf, size_t len); ZENOHC_API uint16_t z_random_u16(void); ZENOHC_API uint32_t z_random_u32(void); @@ -1734,7 +1743,7 @@ ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); * Returns ``true`` if `reply` is valid. */ ZENOHC_API bool z_reply_check(const struct z_owned_reply_t *this_); -ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, struct z_reply_t reply); +ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, const struct z_reply_t *reply); /** * Frees `reply`, invalidating it for double-drop safety. */ @@ -1742,18 +1751,18 @@ ZENOHC_API void z_reply_drop(struct z_owned_reply_t *this_); /** * Yields the contents of the reply by asserting it indicates a failure. * - * You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. + * Returns null if reply does not contain a error (i. e. if :c:func:`z_reply_is_ok` returns ``true``). */ ZENOHC_API -struct z_value_t z_reply_err(struct z_reply_t reply); +const struct z_value_t *z_reply_err(const struct z_reply_t *reply); /** * Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. * * If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. */ ZENOHC_API -bool z_reply_is_ok(struct z_reply_t reply); -ZENOHC_API struct z_reply_t z_reply_loan(struct z_owned_reply_t *this_); +bool z_reply_is_ok(const struct z_reply_t *reply); +ZENOHC_API const struct z_reply_t *z_reply_loan(struct z_owned_reply_t *this_); /** * Returns an invalidated :c:type:`z_owned_reply_t`. * @@ -1767,32 +1776,42 @@ ZENOHC_API void z_reply_null(struct z_owned_reply_t *this_); /** * Yields the contents of the reply by asserting it indicates a success. * - * You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. + * Returns null if reply does not contains a sample (i. e. if :c:func:`z_reply_is_ok` returns ``false``). */ ZENOHC_API -struct z_sample_t z_reply_ok(struct z_reply_t reply); +const struct z_sample_t *z_reply_ok(const struct z_reply_t *reply); /** + * The qos with which the sample was received. + * TODO: split to methods (priority, congestion_control, express) * Gets sample's attachment. * - * Before calling this function, ensure that `zc_sample_has_attachment` returns true + * Returns NULL if sample does not contain an attachement. */ -ZENOHC_API struct z_bytes_t z_sample_attachment(struct z_sample_t sample); +ZENOHC_API const struct z_bytes_t *z_sample_attachment(const struct z_sample_t *sample); /** - * The encoding of the payload. + * Returns `true` if `sample` is valid. + * + * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed + * unless the value has been dropped already. */ -ZENOHC_API struct z_encoding_t z_sample_encoding(struct z_sample_t sample); +ZENOHC_API +bool z_sample_check(const struct zc_owned_sample_t *sample); /** - * The qos with which the sample was received. - * TODO: split to methods (priority, congestion_control, express) - * Checks if sample contains an attachment. + * Clone a sample in the cheapest way available. */ -ZENOHC_API bool z_sample_has_attachment(struct z_sample_t sample); +ZENOHC_API void z_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); +ZENOHC_API enum z_congestion_control_t z_sample_congestion_control(const struct z_sample_t *sample); +/** + * The encoding of the payload. + */ +ZENOHC_API const struct z_encoding_t *z_sample_encoding(const struct z_sample_t *sample); +ZENOHC_API bool z_sample_express(const struct z_sample_t *sample); /** * The Key Expression of the sample. * * `sample` is aliased by its return value. */ -ZENOHC_API struct z_keyexpr_t z_sample_keyexpr(const struct z_sample_t *sample); +ZENOHC_API const struct z_keyexpr_t *z_sample_keyexpr(const struct z_sample_t *sample); /** * The sample's kind (put or delete). */ @@ -1801,7 +1820,8 @@ ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); * The sample's data, the return value aliases the sample. * */ -ZENOHC_API struct z_bytes_t z_sample_payload(const struct z_sample_t *sample); +ZENOHC_API const struct z_bytes_t *z_sample_payload(const struct z_sample_t *sample); +ZENOHC_API enum z_priority_t z_sample_priority(const struct z_sample_t *sample); /** * The samples timestamp * @@ -1827,8 +1847,8 @@ ZENOHC_API bool z_scouting_config_check(const struct z_owned_scouting_config_t * ZENOHC_API void z_scouting_config_default(struct z_owned_scouting_config_t *this_); ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); ZENOHC_API -void z_scouting_config_from(struct z_config_t config, - struct z_owned_scouting_config_t *this_); +void z_scouting_config_from(struct z_owned_scouting_config_t *this_, + const struct z_config_t *config); ZENOHC_API void z_scouting_config_null(struct z_owned_scouting_config_t *this_); /** * Returns ``true`` if `session` is valid. @@ -1845,7 +1865,7 @@ ZENOHC_API bool z_session_check(const struct z_owned_session_t *this_); * have been destroyed is UB (likely SEGFAULT) */ ZENOHC_API -struct z_session_t z_session_loan(const struct z_owned_session_t *this_); +const struct z_session_t *z_session_loan(const struct z_owned_session_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_session_t' type */ @@ -1857,11 +1877,11 @@ ZENOHC_API int8_t z_sleep_us(size_t time); * Returns ``true`` if `b` is initialized. */ ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *b); -ZENOHC_API struct z_owned_slice_t z_slice_clone(const struct z_slice_t *b); +ZENOHC_API void z_slice_clone(struct z_owned_slice_t *this_, const struct z_slice_t *s); /** - * Frees `b` and invalidates it for double-drop safety. + * Frees `this` and invalidates it for double-drop safety. */ -ZENOHC_API void z_slice_drop(struct z_owned_slice_t *b); +ZENOHC_API void z_slice_drop(struct z_owned_slice_t *this_); /** * Returns the gravestone value for `z_slice_t` */ @@ -1875,7 +1895,7 @@ ZENOHC_API struct z_slice_t z_slice_from_str(const char *str); /** * Returns ``true`` if `b` is initialized. */ -ZENOHC_API bool z_slice_is_initialized(const struct z_slice_t *b); +ZENOHC_API bool z_slice_is_initialized(const struct z_slice_t *this_); ZENOHC_API struct z_slice_t z_slice_loan(const struct z_owned_slice_t *b); /** * Returns `true` if the map is not in its gravestone state @@ -1891,7 +1911,9 @@ ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); * Returns the value associated with `key`, returning a gravestone value if: * - `key` is in gravestone state. */ -ZENOHC_API struct z_slice_t z_slice_map_get(struct z_slice_map_t this_, struct z_slice_t key); +ZENOHC_API +struct z_slice_t z_slice_map_get(const struct z_slice_map_t *this_, + const struct z_slice_t *key); /** * Associates `value` to `key` in the map, aliasing them. * @@ -1900,22 +1922,22 @@ ZENOHC_API struct z_slice_t z_slice_map_get(struct z_slice_map_t this_, struct z * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. */ ZENOHC_API -z_error_t z_slice_map_insert_by_alias(struct z_slice_map_t this_, - struct z_slice_t key, - struct z_slice_t value); +z_error_t z_slice_map_insert_by_alias(struct z_slice_map_t *this_, + const struct z_slice_t *key, + const struct z_slice_t *value); /** * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. * * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. */ ZENOHC_API -z_error_t z_slice_map_insert_by_copy(struct z_slice_map_t this_, - struct z_slice_t key, - struct z_slice_t value); +z_error_t z_slice_map_insert_by_copy(struct z_slice_map_t *this_, + const struct z_slice_t *key, + const struct z_slice_t *value); /** * Returns true if the map is empty, false otherwise. */ -ZENOHC_API bool z_slice_map_is_empty(struct z_slice_map_t this_); +ZENOHC_API bool z_slice_map_is_empty(const struct z_slice_map_t *this_); ZENOHC_API void z_slice_map_iterate(const struct z_slice_map_t *this_, z_slice_map_iter_body_t body, @@ -1923,8 +1945,9 @@ void z_slice_map_iterate(const struct z_slice_map_t *this_, /** * Returns number of key-value pairs in the map. */ -ZENOHC_API size_t z_slice_map_len(struct z_slice_map_t this_); -ZENOHC_API struct z_slice_map_t z_slice_map_loan(const struct z_owned_slice_map_t *this_); +ZENOHC_API size_t z_slice_map_len(const struct z_slice_map_t *this_); +ZENOHC_API const struct z_slice_map_t *z_slice_map_loan(const struct z_owned_slice_map_t *this_); +ZENOHC_API struct z_slice_map_t *z_slice_map_loan_mut(struct z_owned_slice_map_t *this_); /** * Constructs a new empty map. */ @@ -1933,21 +1956,14 @@ ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); * Constructs the gravestone value for `z_owned_slice_map_t` */ ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); -/** - * Deprecated in favor of `z_slice_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). - * - * `str == NULL` will cause this to return `z_slice_empty()` - */ -ZENOHC_API -struct z_slice_t z_slice_new(const char *str); /** * Returns the gravestone value for `z_owned_slice_t` */ -ZENOHC_API struct z_owned_slice_t z_slice_null(void); +ZENOHC_API void z_slice_null(struct z_owned_slice_t *this_); /** * Constructs a `len` bytes long view starting at `start`. */ -ZENOHC_API struct z_slice_t z_slice_wrap(const uint8_t *start, size_t len); +ZENOHC_API struct z_slice_t z_slice_wrap(uint8_t *start, size_t len); /** * Returns ``true`` if `strs` is valid. */ @@ -1959,7 +1975,7 @@ ZENOHC_API void z_str_array_drop(struct z_owned_str_array_t *strs); /** * Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. */ -ZENOHC_API struct z_str_array_t z_str_array_loan(const struct z_owned_str_array_t *strs); +ZENOHC_API const struct z_str_array_t *z_str_array_loan(const struct z_owned_str_array_t *strs); /** * Returns ``true`` if `s` is a valid string */ @@ -1975,7 +1991,7 @@ ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); /** * Returns undefined `z_owned_str_t` */ -ZENOHC_API struct z_owned_str_t z_str_null(void); +ZENOHC_API void z_str_null(struct z_owned_str_t *this_); /** * Returns ``true`` if `sub` is valid. */ @@ -1983,11 +1999,11 @@ ZENOHC_API bool z_subscriber_check(const struct z_owned_subscriber_t *subscriber /** * Returns the key expression of the subscriber. */ -ZENOHC_API struct z_keyexpr_t z_subscriber_keyexpr(struct z_subscriber_t subscriber); +ZENOHC_API const struct z_keyexpr_t *z_subscriber_keyexpr(const struct z_subscriber_t *subscriber); /** * Returns a :c:type:`z_subscriber_t` loaned from `this`. */ -ZENOHC_API struct z_subscriber_t z_subscriber_loan(const struct z_owned_subscriber_t *this_); +ZENOHC_API const struct z_subscriber_t *z_subscriber_loan(const struct z_owned_subscriber_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type */ @@ -1995,7 +2011,7 @@ ZENOHC_API void z_subscriber_null(struct z_owned_subscriber_t *this_); /** * Constructs the default value for :c:type:`z_subscriber_options_t`. */ -ZENOHC_API struct z_subscriber_options_t z_subscriber_options_default(void); +ZENOHC_API void z_subscriber_options_default(struct z_subscriber_options_t *this_); ZENOHC_API bool z_task_check(const struct z_owned_task_t *this_); /** * Detaches the task and releases all allocated resources. @@ -2022,12 +2038,14 @@ ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp * Undeclare the key expression generated by a call to :c:func:`z_declare_keyexpr`. * The keyxpr is consumed. */ -ZENOHC_API int8_t z_undeclare_keyexpr(struct z_session_t session, struct z_owned_keyexpr_t *kexpr); +ZENOHC_API +z_error_t z_undeclare_keyexpr(const struct z_session_t *session, + struct z_owned_keyexpr_t *kexpr); /** * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. */ ZENOHC_API -z_error_t z_undeclare_publisher(struct z_owned_publisher_t *publisher); +z_error_t z_undeclare_publisher(struct z_owned_publisher_t *this_); /** * Undeclares a `z_owned_queryable_t`, droping it and invalidating it for doube-drop safety. * @@ -2056,16 +2074,16 @@ ZENOHC_API int8_t z_whatami_to_str(uint8_t whatami, char *buf, size_t len); * Constructs a configuration by parsing a file at `path`. Currently supported format is JSON5, a superset of JSON. */ ZENOHC_API -z_error_t zc_config_from_file(const char *path, - struct z_owned_config_t *this_); +z_error_t zc_config_from_file(struct z_owned_config_t *this_, + const char *path); /** * Reads a configuration from a JSON-serialized string, such as '{mode:"client",connect:{endpoints:["tcp/127.0.0.1:7447"]}}'. * * Passing a null-ptr will result in a gravestone value (`z_check(x) == false`). */ ZENOHC_API -z_error_t zc_config_from_str(const char *s, - struct z_owned_config_t *this_); +z_error_t zc_config_from_str(struct z_owned_config_t *this_, + const char *s); /** * Gets the property with the given path key from the configuration, returning an owned, null-terminated, JSON serialized string. * Use `z_drop` to safely deallocate this string @@ -2079,14 +2097,14 @@ struct z_owned_str_t zc_config_get(struct z_config_t config, * Returns 0 if successful, a negative value otherwise. */ ZENOHC_API -int8_t zc_config_insert_json(struct z_config_t config, - const char *key, - const char *value); +z_error_t zc_config_insert_json(const struct z_config_t *config, + const char *key, + const char *value); /** * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. */ ZENOHC_API -struct z_owned_str_t zc_config_to_string(struct z_config_t config); +struct z_owned_str_t zc_config_to_string(const struct z_config_t *config); /** * Initialises the zenoh runtime logger. * @@ -2097,21 +2115,18 @@ ZENOHC_API void zc_init_logger(void); /** * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. */ -ZENOHC_API -z_error_t zc_keyexpr_from_slice(struct z_owned_keyexpr_t *this_, - const char *name, - size_t len); +ZENOHC_API z_error_t zc_keyexpr_from_slice(struct z_keyexpr_t *this_, const char *name, size_t len); /** - * Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. * The string is canonized in-place before being passed to keyexpr. * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). */ ZENOHC_API -z_error_t zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, +z_error_t zc_keyexpr_from_slice_autocanonize(struct z_keyexpr_t *this_, char *name, size_t *len); /** - * Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: * - `name` MUST be valid UTF8. * - `name` MUST follow the Key Expression specification, ie: * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. @@ -2121,11 +2136,11 @@ z_error_t zc_keyexpr_from_slice_autocanonize(struct z_owned_keyexpr_t *this_, * It is a loaned key expression that aliases `name`. */ ZENOHC_API -void zc_keyexpr_from_slice_unchecked(struct z_owned_keyexpr_t *this_, +void zc_keyexpr_from_slice_unchecked(struct z_keyexpr_t *this_, const char *start, size_t len); ZENOHC_API -struct zc_liveliness_declaration_options_t zc_liveliness_declaration_options_default(void); +void zc_liveliness_declaration_options_default(struct zc_liveliness_declaration_options_t *this_); /** * Declares a subscriber on liveliness tokens that intersect `key`. * @@ -2144,8 +2159,8 @@ struct zc_liveliness_declaration_options_t zc_liveliness_declaration_options_def */ ZENOHC_API z_error_t zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_owned_closure_sample_t *callback, struct zc_liveliness_declare_subscriber_options_t *_options); /** @@ -2158,8 +2173,8 @@ z_error_t zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, */ ZENOHC_API z_error_t zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct zc_liveliness_declaration_options_t *_options); /** * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. @@ -2169,16 +2184,16 @@ z_error_t zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. */ ZENOHC_API -z_error_t zc_liveliness_get(struct z_session_t session, - struct z_keyexpr_t key_expr, +z_error_t zc_liveliness_get(const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_owned_closure_reply_t *callback, struct zc_liveliness_get_options_t *options); /** * The gravestone value for `zc_liveliness_get_options_t` */ -ZENOHC_API struct zc_liveliness_get_options_t zc_liveliness_get_options_default(void); +ZENOHC_API void zc_liveliness_get_options_default(struct zc_liveliness_get_options_t *this_); ZENOHC_API -struct zc_liveliness_declare_subscriber_options_t zc_liveliness_subscriber_options_default(void); +void zc_liveliness_subscriber_options_default(struct zc_liveliness_declare_subscriber_options_t *this_); /** * Returns `true` unless the token is at its gravestone value. */ @@ -2243,18 +2258,6 @@ struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); */ ZENOHC_API struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); -/** - * Returns `true` if `sample` is valid. - * - * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed - * unless the value has been dropped already. - */ -ZENOHC_API -bool zc_sample_check(const struct zc_owned_sample_t *sample); -/** - * Clone a sample in the cheapest way available. - */ -ZENOHC_API void zc_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); /** * Destroy the sample. */ @@ -2264,14 +2267,14 @@ ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); * * Calling this function using a dropped sample is undefined behaviour. */ -ZENOHC_API struct z_sample_t zc_sample_loan(const struct zc_owned_sample_t *sample); +ZENOHC_API const struct z_sample_t *zc_sample_loan(const struct zc_owned_sample_t *sample); ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); /** * Increments the session's reference count, returning a new owning handle. */ ZENOHC_API -int8_t zc_session_rcinc(struct z_owned_session_t *dst, - const struct z_owned_session_t *src); +z_error_t zc_session_clone(struct z_owned_session_t *dst, + const struct z_owned_session_t *src); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -2292,9 +2295,9 @@ ZENOHC_API enum zcu_locality_t zcu_locality_default(void); * Register callback for notifying subscribers matching. */ ZENOHC_API -z_error_t zcu_publisher_matching_listener_callback(struct z_publisher_t publisher, - struct zcu_owned_closure_matching_status_t *callback, - struct zcu_owned_matching_listener_t *this_); +z_error_t zcu_publisher_matching_listener_callback(struct zcu_owned_matching_listener_t *this_, + const struct z_publisher_t *publisher, + struct zcu_owned_closure_matching_status_t *callback); ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); /** * Declares a Publication Cache. @@ -2362,8 +2365,8 @@ z_error_t ze_declare_publication_cache(struct ze_owned_publication_cache_t *this */ ZENOHC_API z_error_t ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct z_owned_closure_sample_t *callback, struct ze_querying_subscriber_options_t *options); /** @@ -2387,14 +2390,14 @@ ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subs * The queried samples will be merged with the received publications and made available in the subscriber callback. */ ZENOHC_API -z_error_t ze_querying_subscriber_get(struct ze_querying_subscriber_t sub, - struct z_keyexpr_t selector, +z_error_t ze_querying_subscriber_get(const struct ze_querying_subscriber_t *sub, + const struct z_keyexpr_t *selector, const struct z_get_options_t *options); /** * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. */ ZENOHC_API -struct ze_querying_subscriber_t ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); +const struct ze_querying_subscriber_t *ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); /** * Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type */ @@ -2402,7 +2405,8 @@ ZENOHC_API void ze_querying_subscriber_null(struct ze_owned_querying_subscriber_ /** * Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. */ -ZENOHC_API struct ze_querying_subscriber_options_t ze_querying_subscriber_options_default(void); +ZENOHC_API +void ze_querying_subscriber_options_default(struct ze_querying_subscriber_options_t *this_); /** * Closes the given :c:type:`ze_owned_publication_cache_t`, droping it and invalidating it for double-drop safety. */ diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 764cf399a..03f29535b 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -37,10 +37,10 @@ typedef struct ALIGN(8) z_owned_session_t { uint8_t _0[8]; } z_owned_session_t; typedef struct ALIGN(8) z_query_t { - uint8_t _0[8]; + uint8_t _0[16]; } z_query_t; typedef struct ALIGN(8) z_session_t { - uint8_t _0[8]; + uint8_t _0[40]; } z_session_t; /** * An owned zenoh queryable. @@ -77,6 +77,7 @@ typedef struct ALIGN(8) z_owned_subscriber_t { #define Z_EPARSE -2 #define Z_EIO -3 #define Z_ENETWORK -4 +#define Z_ENULL -5 #define Z_EBUSY_MUTEX -16 #define Z_EINVAL_MUTEX -22 #define Z_EAGAIN_MUTEX -11 diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index 15264a470..1cd1f063d 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -50,9 +50,9 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver if bound == 0 { let (tx, rx) = std::sync::mpsc::channel(); ( - From::from(move |query: z_query_t| { + From::from(move |query: &z_query_t| { let mut this = MaybeUninit::::uninit(); - z_query_clone(&mut this as *mut MaybeUninit, query); + z_query_clone(query, &mut this as *mut MaybeUninit); let this = this.assume_init(); if let Err(e) = tx.send(this) { log::error!("Attempted to push onto a closed reply_fifo: {}", e); @@ -63,9 +63,9 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver } else { let (tx, rx) = std::sync::mpsc::sync_channel(bound); ( - From::from(move |query: z_query_t| { + From::from(move |query: &z_query_t| { let mut this = MaybeUninit::::uninit(); - z_query_clone(&mut this as *mut MaybeUninit, query); + z_query_clone(query, &mut this as *mut MaybeUninit); let this = this.assume_init(); if let Err(e) = tx.send(this) { log::error!("Attempted to push onto a closed reply_fifo: {}", e); diff --git a/src/closures/query_closure.rs b/src/closures/query_closure.rs index f0387bc45..0512e28c8 100644 --- a/src/closures/query_closure.rs +++ b/src/closures/query_closure.rs @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_query_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } impl z_owned_closure_query_t { @@ -45,7 +45,7 @@ pub extern "C" fn z_closure_query_null() -> z_owned_closure_query_t { } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_query_call(closure: &z_owned_closure_query_t, query: z_query_t) { +pub extern "C" fn z_closure_query_call(closure: &z_owned_closure_query_t, query: &z_query_t) { match closure.call { Some(call) => call(query, closure.context), None => log::error!("Attempted to call an uninitialized closure!"), @@ -57,12 +57,12 @@ pub extern "C" fn z_closure_query_drop(closure: &mut z_owned_closure_query_t) { let mut empty_closure = z_owned_closure_query_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_query_t { +impl From for z_owned_closure_query_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(sample: z_query_t, this: *mut c_void) { + extern "C" fn call(query: *const z_query_t, this: *mut c_void) { let this = unsafe { &*(this as *const F) }; - this(sample) + unsafe { this(query.as_ref().unwrap()) } } extern "C" fn drop(this: *mut c_void) { std::mem::drop(unsafe { Box::from_raw(this as *mut F) }) diff --git a/src/closures/reply_closure.rs b/src/closures/reply_closure.rs index d05b63ab3..c070c4bd8 100644 --- a/src/closures/reply_closure.rs +++ b/src/closures/reply_closure.rs @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_reply_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } @@ -46,7 +46,7 @@ pub extern "C" fn z_closure_reply_null() -> z_owned_closure_reply_t { } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_reply_call(closure: &z_owned_closure_reply_t, reply: z_reply_t) { +pub extern "C" fn z_closure_reply_call(closure: &z_owned_closure_reply_t, reply: &z_reply_t) { match closure.call { Some(call) => call(reply, closure.context), None => { @@ -60,12 +60,12 @@ pub extern "C" fn z_closure_reply_drop(closure: &mut z_owned_closure_reply_t) { let mut empty_closure = z_owned_closure_reply_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_reply_t { +impl From for z_owned_closure_reply_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(response: z_reply_t, this: *mut c_void) { + extern "C" fn call(response: *const z_reply_t, this: *mut c_void) { let this = unsafe { &*(this as *const F) }; - this(response) + unsafe { this(response.as_ref().unwrap()) } } extern "C" fn drop(this: *mut c_void) { std::mem::drop(unsafe { Box::from_raw(this as *mut F) }) diff --git a/src/closures/response_channel.rs b/src/closures/response_channel.rs index 5cabdccdc..4ef56b760 100644 --- a/src/closures/response_channel.rs +++ b/src/closures/response_channel.rs @@ -49,7 +49,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver if bound == 0 { let (tx, rx) = std::sync::mpsc::channel(); ( - From::from(move |reply: z_reply_t| { + From::from(move |reply: &z_reply_t| { let mut this = MaybeUninit::::uninit(); z_reply_clone(&mut this as *mut MaybeUninit, reply); let this = this.assume_init(); @@ -62,7 +62,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver } else { let (tx, rx) = std::sync::mpsc::sync_channel(bound); ( - From::from(move |reply: z_reply_t| { + From::from(move |reply: &z_reply_t| { let mut this = MaybeUninit::::uninit(); z_reply_clone(&mut this as *mut MaybeUninit, reply); let this = this.assume_init(); diff --git a/src/closures/sample_closure.rs b/src/closures/sample_closure.rs index 4d95cf177..043b59fb8 100644 --- a/src/closures/sample_closure.rs +++ b/src/closures/sample_closure.rs @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_sample_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } impl z_owned_closure_sample_t { @@ -47,7 +47,7 @@ pub extern "C" fn z_closure_sample_null() -> z_owned_closure_sample_t { /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_sample_call(closure: &z_owned_closure_sample_t, sample: z_sample_t) { +pub extern "C" fn z_closure_sample_call(closure: &z_owned_closure_sample_t, sample: &z_sample_t) { match closure.call { Some(call) => call(sample, closure.context), None => log::error!("Attempted to call an uninitialized closure!"), @@ -60,12 +60,12 @@ pub extern "C" fn z_closure_sample_drop(closure: &mut z_owned_closure_sample_t) let mut empty_closure = z_owned_closure_sample_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_sample_t { +impl From for z_owned_closure_sample_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(sample: z_sample_t, this: *mut c_void) { + extern "C" fn call(sample: *const z_sample_t, this: *mut c_void) { let this = unsafe { &*(this as *const F) }; - this(sample) + unsafe { this(sample.as_ref().unwrap()) } } extern "C" fn drop(this: *mut c_void) { std::mem::drop(unsafe { Box::from_raw(this as *mut F) }) diff --git a/src/collections.rs b/src/collections.rs index 740870321..f24d7d075 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -15,6 +15,7 @@ use std::borrow::Cow; use std::collections::HashMap; use std::mem::MaybeUninit; +use std::ptr::{null, null_mut}; use libc::{c_char, c_void, size_t}; use zenoh::prelude::ZenohId; @@ -45,7 +46,7 @@ impl z_slice_t { } pub fn empty() -> Self { z_slice_t { - start: std::ptr::null(), + start: std::ptr::null_mut(), len: 0, } } @@ -60,7 +61,7 @@ impl Default for z_slice_t { #[repr(C)] #[derive(Clone, Debug)] pub struct z_owned_slice_t { - pub start: *mut u8, + pub start: *const u8, pub len: size_t, } @@ -71,9 +72,15 @@ impl Drop for z_owned_slice_t { } impl z_owned_slice_t { + pub fn null() -> z_owned_slice_t { + z_owned_slice_t { + start: null(), + len: 0 + } + } pub fn new(data: &[u8]) -> z_owned_slice_t { if data.is_empty() { - return z_slice_null(); + return Self::null(); } let data = data.to_vec().into_boxed_slice(); z_owned_slice_t { @@ -92,29 +99,26 @@ impl z_owned_slice_t { #[allow(clippy::missing_safety_doc)] pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { - std::ptr::copy_nonoverlapping(value.as_ptr(), self.start.add(start), value.len()); + std::ptr::copy_nonoverlapping(value.as_ptr(), self.start.add(start) as *mut u8, value.len()); } } impl Default for z_owned_slice_t { fn default() -> Self { - z_slice_null() + Self::null() } } /// Returns ``true`` if `b` is initialized. #[no_mangle] -pub extern "C" fn z_slice_is_initialized(b: &z_slice_t) -> bool { - !b.start.is_null() +pub extern "C" fn z_slice_is_initialized(this: &z_slice_t) -> bool { + !this.start.is_null() } /// Returns the gravestone value for `z_slice_t` #[no_mangle] pub const extern "C" fn z_slice_empty() -> z_slice_t { - z_slice_t { - len: 0, - start: core::ptr::null(), - } + z_slice_t::empty() } /// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). @@ -129,25 +133,15 @@ pub unsafe extern "C" fn z_slice_from_str(str: *const c_char) -> z_slice_t { let len = unsafe { libc::strlen(str) }; z_slice_t { len, - start: str.cast(), + start: str.cast_mut() as *mut u8, } } } -#[deprecated = "Renamed to z_slice_from_str"] -/// Deprecated in favor of `z_slice_from_str`: Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). -/// -/// `str == NULL` will cause this to return `z_slice_empty()` -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_new(str: *const c_char) -> z_slice_t { - z_slice_from_str(str) -} - /// Constructs a `len` bytes long view starting at `start`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_wrap(start: *const u8, len: usize) -> z_slice_t { +pub unsafe extern "C" fn z_slice_wrap(start: *mut u8, len: usize) -> z_slice_t { if start.is_null() { z_slice_empty() } else { @@ -155,26 +149,26 @@ pub unsafe extern "C" fn z_slice_wrap(start: *const u8, len: usize) -> z_slice_t } } -/// Frees `b` and invalidates it for double-drop safety. +/// Frees `this` and invalidates it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_drop(b: &mut z_owned_slice_t) { - if !b.start.is_null() { +pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { + if !this.start.is_null() { std::mem::drop(Box::from_raw( - core::ptr::slice_from_raw_parts(b.start, b.len).cast_mut(), + core::ptr::slice_from_raw_parts(this.start, this.len).cast_mut(), )); - b.start = std::ptr::null_mut(); - b.len = 0; + this.start = std::ptr::null_mut(); + this.len = 0; } } /// Returns the gravestone value for `z_owned_slice_t` #[no_mangle] -pub const extern "C" fn z_slice_null() -> z_owned_slice_t { - z_owned_slice_t { +pub unsafe extern "C" fn z_slice_null(this: *mut MaybeUninit) { + (*this).as_mut_ptr().write(z_owned_slice_t { len: 0, start: core::ptr::null_mut(), - } + }); } #[no_mangle] @@ -186,11 +180,11 @@ pub const extern "C" fn z_slice_loan(b: &z_owned_slice_t) -> z_slice_t { } #[no_mangle] -pub extern "C" fn z_slice_clone(b: &z_slice_t) -> z_owned_slice_t { - if !z_slice_is_initialized(b) { - z_slice_null() +pub unsafe extern "C" fn z_slice_clone(this: *mut MaybeUninit, s: &z_slice_t) { + if !z_slice_is_initialized(s) { + z_slice_null(this); } else { - z_owned_slice_t::new(unsafe { std::slice::from_raw_parts(b.start, b.len) }) + (*this).as_mut_ptr().write(z_owned_slice_t::new(unsafe { std::slice::from_raw_parts(s.start, s.len) })); } } @@ -257,6 +251,11 @@ pub struct z_owned_str_t { } impl z_owned_str_t { + pub fn null() -> z_owned_str_t { + z_owned_str_t { + _cstr: null_mut() + } + } #[allow(clippy::missing_safety_doc)] pub unsafe fn preallocate(len: usize) -> z_owned_str_t { let cstr = libc::malloc(len + 1) as *mut libc::c_char; @@ -292,7 +291,7 @@ impl Drop for z_owned_str_t { impl Default for z_owned_str_t { fn default() -> Self { - z_str_null() + Self::null() } } @@ -315,10 +314,12 @@ pub extern "C" fn z_str_check(s: &z_owned_str_t) -> bool { /// Returns undefined `z_owned_str_t` #[no_mangle] -pub extern "C" fn z_str_null() -> z_owned_str_t { - z_owned_str_t { - _cstr: std::ptr::null_mut(), - } +pub unsafe extern "C" fn z_str_null(this: *mut MaybeUninit) { + (*this).as_mut_ptr().write( + z_owned_str_t { + _cstr: std::ptr::null_mut(), + } + ); } /// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. @@ -377,21 +378,28 @@ pub extern "C" fn z_slice_map_drop(this: &mut z_owned_slice_map_t) { } #[no_mangle] -pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> z_slice_map_t { +pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> &z_slice_map_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() } +#[no_mangle] +pub extern "C" fn z_slice_map_loan_mut(this: &mut z_owned_slice_map_t) -> &mut z_slice_map_t { + let this = this.transmute_mut(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle_mut() +} + /// Returns number of key-value pairs in the map. #[no_mangle] -pub extern "C" fn z_slice_map_len(this: z_slice_map_t) -> usize { +pub extern "C" fn z_slice_map_len(this: &z_slice_map_t) -> usize { this.transmute_ref().len() } /// Returns true if the map is empty, false otherwise. #[no_mangle] -pub extern "C" fn z_slice_map_is_empty(this: z_slice_map_t) -> bool { +pub extern "C" fn z_slice_map_is_empty(this: &z_slice_map_t) -> bool { z_slice_map_len(this) == 0 } @@ -403,7 +411,7 @@ pub extern "C" fn z_slice_map_is_empty(this: z_slice_map_t) -> bool { /// Returning `true` is treated as `continue`. #[allow(non_camel_case_types)] pub type z_slice_map_iter_body_t = - extern "C" fn(key: z_slice_t, value: z_slice_t, context: *mut c_void) -> bool; + extern "C" fn(key: &z_slice_t, value: &z_slice_t, context: *mut c_void) -> bool; #[no_mangle] pub extern "C" fn z_slice_map_iterate( @@ -413,7 +421,9 @@ pub extern "C" fn z_slice_map_iterate( ) { let this = this.transmute_ref(); for (key, value) in this { - if !body(key.as_ref().into(), value.as_ref().into(), context) { + let key_slice = key.as_ref().into(); + let value_slice = value.as_ref().into(); + if !body(&key_slice, &value_slice, context) { break; } } @@ -422,11 +432,11 @@ pub extern "C" fn z_slice_map_iterate( /// Returns the value associated with `key`, returning a gravestone value if: /// - `key` is in gravestone state. #[no_mangle] -pub extern "C" fn z_slice_map_get(this: z_slice_map_t, key: z_slice_t) -> z_slice_t { +pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> z_slice_t { if !z_slice_is_initialized(&key) { return z_slice_empty(); } - let m = this.transmute_mut(); + let m = this.transmute_ref(); let key = key.as_slice().unwrap(); m.get(key) .map(|s| s.as_ref().into()) @@ -438,9 +448,9 @@ pub extern "C" fn z_slice_map_get(this: z_slice_map_t, key: z_slice_t) -> z_slic /// Returns 0 in case of success, -1 if one of the arguments were in gravestone state. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_copy( - this: z_slice_map_t, - key: z_slice_t, - value: z_slice_t, + this: &mut z_slice_map_t, + key: &z_slice_t, + value: &z_slice_t, ) -> errors::z_error_t { let this = this.transmute_mut(); if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { @@ -458,9 +468,9 @@ pub extern "C" fn z_slice_map_insert_by_copy( /// Returns 0 in case of success, -1 if one of the arguments were in gravestone state. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_alias( - this: z_slice_map_t, - key: z_slice_t, - value: z_slice_t, + this: &mut z_slice_map_t, + key: &z_slice_t, + value: &z_slice_t, ) -> errors::z_error_t { let this = this.transmute_mut(); if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { diff --git a/src/commons.rs b/src/commons.rs index 650e230d6..27eaafec8 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -14,6 +14,7 @@ use std::ffi::CStr; use std::mem::MaybeUninit; +use std::ptr::null; use std::str::FromStr; use crate::transmute::unwrap_ref_unchecked; @@ -93,20 +94,20 @@ decl_transmute_handle!(Sample, z_sample_t); /// /// `sample` is aliased by its return value. #[no_mangle] -pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> z_keyexpr_t { +pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> &z_keyexpr_t { let sample = sample.transmute_ref(); - sample.key_expr().into() + sample.key_expr().transmute_handle() } /// The encoding of the payload. #[no_mangle] -pub extern "C" fn z_sample_encoding(sample: z_sample_t) -> z_encoding_t { +pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> &z_encoding_t { let sample = sample.transmute_ref(); sample.encoding().transmute_handle() } /// The sample's data, the return value aliases the sample. /// #[no_mangle] -pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> z_bytes_t { +pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> &z_bytes_t { let sample = sample.transmute_ref(); sample.payload().transmute_handle() } @@ -136,23 +137,18 @@ pub extern "C" fn z_sample_timestamp( /// The qos with which the sample was received. /// TODO: split to methods (priority, congestion_control, express) -/// Checks if sample contains an attachment. -#[no_mangle] -pub extern "C" fn z_sample_has_attachment(sample: z_sample_t) -> bool { - let sample = sample.transmute_ref(); - sample.attachment().is_some() -} /// Gets sample's attachment. /// -/// Before calling this function, ensure that `zc_sample_has_attachment` returns true +/// Returns NULL if sample does not contain an attachement. #[no_mangle] -pub extern "C" fn z_sample_attachment(sample: z_sample_t) -> z_bytes_t { +pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> *const z_bytes_t { let sample = sample.transmute_ref(); - sample - .attachment() - .expect("Sample does not have an attachment") - .transmute_handle() + match sample.attachment() { + Some(attachment) => attachment.transmute_handle() as *const _, + None => null(), + } + } pub use crate::opaque_types::zc_owned_sample_t; @@ -160,19 +156,38 @@ decl_transmute_owned!(Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] -pub extern "C" fn zc_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { +pub extern "C" fn z_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { let src = src.transmute_ref(); let src = src.clone(); let dst = dst.transmute_uninit_ptr(); Inplace::init(dst, Some(src)); } + +#[no_mangle] +pub extern "C" fn z_sample_priority(sample: &z_sample_t) -> z_priority_t { + let sample = sample.transmute_ref(); + sample.priority().into() +} + +#[no_mangle] +pub extern "C" fn z_sample_express(sample: &z_sample_t) -> bool { + let sample = sample.transmute_ref(); + sample.express() +} + +#[no_mangle] +pub extern "C" fn z_sample_congestion_control(sample: &z_sample_t) -> z_congestion_control_t { + let sample = sample.transmute_ref(); + sample.congestion_control().into() +} + /// Returns `true` if `sample` is valid. /// /// Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed /// unless the value has been dropped already. #[no_mangle] -pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { +pub extern "C" fn z_sample_check(sample: &zc_owned_sample_t) -> bool { let sample = sample.transmute_ref(); sample.is_some() } @@ -181,7 +196,7 @@ pub extern "C" fn zc_sample_check(sample: &zc_owned_sample_t) -> bool { /// /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] -pub extern "C" fn zc_sample_loan(sample: &'static zc_owned_sample_t) -> z_sample_t { +pub extern "C" fn zc_sample_loan(sample: & zc_owned_sample_t) -> &z_sample_t { unwrap_ref_unchecked(sample.transmute_ref()).transmute_handle() } @@ -237,7 +252,7 @@ pub unsafe extern "C" fn z_encoding_from_str( /// Constructs a default :c:type:`z_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_default() -> z_encoding_t { +pub extern "C" fn z_encoding_default() -> &'static z_encoding_t { Encoding::ZENOH_BYTES.transmute_handle() } @@ -258,7 +273,7 @@ pub extern "C" fn z_encoding_check(encoding: &'static z_owned_encoding_t) -> boo /// Returns a :c:type:`z_encoding_t` loaned from `encoding`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_loan(encoding: &'static z_owned_encoding_t) -> z_encoding_t { +pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> &z_encoding_t { encoding.transmute_ref().transmute_handle() } diff --git a/src/config.rs b/src/config.rs index e7e420474..a837136ec 100644 --- a/src/config.rs +++ b/src/config.rs @@ -16,12 +16,12 @@ use std::ffi::CStr; use std::mem::MaybeUninit; use zenoh::config::{Config, ValidatedMap, WhatAmI}; -use crate::errors::{z_error_t, Z_EPARSE}; +use crate::errors::z_error_t; use crate::transmute::{ unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; -use crate::{errors, z_owned_str_t, z_str_null}; +use crate::{errors, z_owned_str_t}; #[no_mangle] pub static Z_ROUTER: c_uint = WhatAmI::Router as c_uint; @@ -67,14 +67,13 @@ pub use crate::opaque_types::z_config_t; decl_transmute_handle!(Config, z_config_t); pub use crate::opaque_types::z_owned_config_t; -decl_transmute_owned!(Option>, z_owned_config_t); +decl_transmute_owned!(Option, z_owned_config_t); /// Returns a :c:type:`z_config_t` loaned from `s`. #[no_mangle] -pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> z_config_t { +pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> &z_config_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); - let this = this.as_ref(); this.transmute_handle() } @@ -91,7 +90,7 @@ pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> z_config_t { #[no_mangle] pub extern "C" fn z_config_default(this: *mut MaybeUninit) { let this = this.transmute_uninit_ptr(); - let config: Box = Box::default(); + let config = Config::default(); Inplace::init(this, Some(config)); } @@ -106,7 +105,7 @@ pub extern "C" fn z_config_null(this: *mut MaybeUninit) { #[no_mangle] pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit) { let src = src.transmute_ref(); - let src = Box::new(src.clone()); + let src = src.clone(); let dst = dst.transmute_uninit_ptr(); Inplace::init(dst, Some(src)); } @@ -119,12 +118,12 @@ pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char) - let config = config.transmute_ref(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, - Err(_) => return z_str_null(), + Err(_) => return z_owned_str_t::null(), }; let val = config.get_json(key).ok(); match val { Some(val) => val.as_bytes().into(), - None => z_str_null(), + None => z_owned_str_t::null(), } } @@ -134,16 +133,16 @@ pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char) - #[no_mangle] #[allow(clippy::missing_safety_doc, unused_must_use)] pub unsafe extern "C" fn zc_config_insert_json( - config: z_config_t, + config: &z_config_t, key: *const c_char, value: *const c_char, -) -> i8 { +) -> errors::z_error_t { let config = config.transmute_mut(); let key = CStr::from_ptr(key); let value = CStr::from_ptr(value); match config.insert_json5(&key.to_string_lossy(), &value.to_string_lossy()) { Ok(_) => 0, - Err(_) => i8::MIN, + Err(_) => errors::Z_EGENERIC, } } @@ -168,8 +167,8 @@ pub extern "C" fn z_config_check(config: &z_owned_config_t) -> bool { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_config_from_str( - s: *const c_char, this: *mut MaybeUninit, + s: *const c_char, ) -> errors::z_error_t { let mut res = errors::Z_OK; if s.is_null() { @@ -177,11 +176,10 @@ pub unsafe extern "C" fn zc_config_from_str( res = errors::Z_EINVAL; } else { let conf_str = CStr::from_ptr(s); - let props: Option> = json5::from_str(&conf_str.to_string_lossy()) - .ok() - .map(Box::new); + let props: Option = json5::from_str(&conf_str.to_string_lossy()) + .ok(); if props.is_none() { - res = Z_EPARSE; + res = errors::Z_EPARSE; } Inplace::init(this.transmute_uninit_ptr(), props); } @@ -191,11 +189,11 @@ pub unsafe extern "C" fn zc_config_from_str( /// Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn zc_config_to_string(config: z_config_t) -> z_owned_str_t { +pub extern "C" fn zc_config_to_string(config: &z_config_t) -> z_owned_str_t { let config: &Config = config.transmute_ref(); match json5::to_string(config) { Ok(s) => s.as_bytes().into(), - Err(_) => z_str_null(), + Err(_) => z_owned_str_t::null(), } } @@ -203,14 +201,14 @@ pub extern "C" fn zc_config_to_string(config: z_config_t) -> z_owned_str_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_config_from_file( - path: *const c_char, this: *mut MaybeUninit, + path: *const c_char, ) -> errors::z_error_t { let path_str = CStr::from_ptr(path); let mut res = errors::Z_OK; let config = match path_str.to_str() { Ok(path) => match zenoh::config::Config::from_file(path) { - Ok(c) => Some(Box::new(c)), + Ok(c) => Some(c), Err(e) => { log::error!("Couldn't read config from {}: {}", path, e); res = errors::Z_EPARSE; @@ -233,7 +231,7 @@ pub unsafe extern "C" fn zc_config_from_file( pub extern "C" fn z_config_peer(this: *mut MaybeUninit) { Inplace::init( this.transmute_uninit_ptr(), - Some(Box::new(zenoh::config::peer())), + Some(zenoh::config::peer()), ); } @@ -242,9 +240,9 @@ pub extern "C" fn z_config_peer(this: *mut MaybeUninit) { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_config_client( + this: *mut MaybeUninit, peers: *const *const c_char, n_peers: usize, - this: *mut MaybeUninit, ) -> z_error_t { let mut res = errors::Z_OK; let locators = if peers.is_null() { @@ -274,7 +272,7 @@ pub unsafe extern "C" fn z_config_client( }; Inplace::init( this.transmute_uninit_ptr(), - Some(Box::new(zenoh::config::client(locators))), + Some(zenoh::config::client(locators)), ); res } diff --git a/src/errors.rs b/src/errors.rs index 7415ffb40..cf494f4e0 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -4,6 +4,7 @@ pub const Z_EINVAL: z_error_t = -1; pub const Z_EPARSE: z_error_t = -2; pub const Z_EIO: z_error_t = -3; pub const Z_ENETWORK: z_error_t = -4; +pub const Z_ENULL: z_error_t = -5; // negativ pthread error codes (due to convention to return negative values on error) pub const Z_EBUSY_MUTEX: z_error_t = -16; pub const Z_EINVAL_MUTEX: z_error_t = -22; diff --git a/src/get.rs b/src/get.rs index 8be10c18b..cba2370d1 100644 --- a/src/get.rs +++ b/src/get.rs @@ -15,6 +15,7 @@ use libc::c_char; use std::ffi::CStr; use std::mem::MaybeUninit; +use std::ptr::null; use std::ptr::null_mut; use zenoh::sample::SampleBuilderTrait; use zenoh::sample::ValueBuilderTrait; @@ -47,35 +48,35 @@ decl_transmute_handle!(Reply, z_reply_t); /// If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_is_ok(reply: z_reply_t) -> bool { +pub unsafe extern "C" fn z_reply_is_ok(reply: &z_reply_t) -> bool { let reply = reply.transmute_ref(); reply.result().is_ok() } /// Yields the contents of the reply by asserting it indicates a success. /// -/// You should always make sure that :c:func:`z_reply_is_ok` returns ``true`` before calling this function. +/// Returns null if reply does not contains a sample (i. e. if :c:func:`z_reply_is_ok` returns ``false``). #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_ok(reply: z_reply_t) -> z_sample_t { +pub unsafe extern "C" fn z_reply_ok(reply: &z_reply_t) -> *const z_sample_t { let reply = reply.transmute_ref(); - reply - .result() - .expect("Reply does not contain a sample") - .transmute_handle() + match reply.result() { + Ok(sample) => sample.transmute_handle(), + Err(_) => null(), + } } /// Yields the contents of the reply by asserting it indicates a failure. /// -/// You should always make sure that :c:func:`z_reply_is_ok` returns ``false`` before calling this function. +/// Returns null if reply does not contain a error (i. e. if :c:func:`z_reply_is_ok` returns ``true``). #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_err(reply: z_reply_t) -> z_value_t { +pub unsafe extern "C" fn z_reply_err(reply: &z_reply_t) -> *const z_value_t{ let reply = reply.transmute_ref(); - reply - .result() - .expect_err("Reply does not contain error") - .transmute_handle() + match reply.result() { + Ok(_) => null(), + Err(v) => v.transmute_handle(), + } } /// Returns an invalidated :c:type:`z_owned_reply_t`. @@ -91,7 +92,7 @@ pub extern "C" fn z_reply_null(this: *mut MaybeUninit) { } #[no_mangle] -pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: z_reply_t) { +pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: &z_reply_t) { Inplace::init( this.transmute_uninit_ptr(), Some(reply.transmute_ref().clone()), @@ -116,15 +117,15 @@ pub struct z_get_options_t { pub timeout_ms: u64, } #[no_mangle] -pub extern "C" fn z_get_options_default() -> z_get_options_t { - z_get_options_t { +pub extern "C" fn z_get_options_default(this: &mut z_get_options_t) { + *this = z_get_options_t { target: QueryTarget::default().into(), consolidation: QueryConsolidation::default().into(), timeout_ms: 0, payload: null_mut(), encoding: null_mut(), attachment: null_mut(), - } + }; } /// Query data from the matching queryables in the system. @@ -144,8 +145,8 @@ pub extern "C" fn z_get_options_default() -> z_get_options_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_get( - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, parameters: *const c_char, callback: &mut z_owned_closure_reply_t, options: Option<&mut z_get_options_t>, @@ -205,7 +206,7 @@ pub extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { } #[no_mangle] -pub extern "C" fn z_reply_loan(this: &mut z_owned_reply_t) -> z_reply_t { +pub extern "C" fn z_reply_loan(this: &mut z_owned_reply_t) -> &z_reply_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 6f25b75c6..4f07fd624 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -44,7 +44,7 @@ pub extern "C" fn z_keyexpr_null(this: *mut MaybeUninit) { } fn keyexpr_create_inner( - name: &'static mut str, + mut name: &'static mut str, should_auto_canonize: bool, should_copy: bool, ) -> Result, Box> { @@ -56,8 +56,8 @@ fn keyexpr_create_inner( } } else { match should_auto_canonize { - true => KeyExpr::<'static>::autocanonize(name), - false => KeyExpr::<'static>::try_from(name), + true => keyexpr::autocanonize(&mut name).map(|k| k.into()), + false => keyexpr::new(name).map(|k| k.into()) } } } @@ -134,7 +134,7 @@ pub unsafe extern "C" fn z_keyexpr_new_autocanonize( /// Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. #[no_mangle] -pub extern "C" fn z_keyexpr_loan(key_expr: &'static z_owned_keyexpr_t) -> z_keyexpr_t { +pub extern "C" fn z_keyexpr_loan(key_expr: &z_owned_keyexpr_t) -> &z_keyexpr_t { unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() } @@ -165,15 +165,6 @@ pub extern "C" fn z_keyexpr_check(keyexpr: &z_owned_keyexpr_t) -> bool { pub use crate::opaque_types::z_keyexpr_t; decl_transmute_handle!(KeyExpr<'static>, z_keyexpr_t); -#[derive(Debug, Clone, Copy)] -pub struct UninitializedKeyExprError; -impl std::fmt::Display for UninitializedKeyExprError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str("Uninitialized Key Expression detected, make sure you use `z_keyexpr_check` or `z_loaned_keyexpr_check` after constructing your key expressions") - } -} -impl std::error::Error for UninitializedKeyExprError {} - /// Returns ``0`` if the passed string is a valid (and canon) key expression. /// Otherwise returns error value #[allow(clippy::missing_safety_doc)] @@ -229,42 +220,36 @@ pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_keyexpr_from_slice( - this: *mut MaybeUninit, + this: *mut MaybeUninit, name: *const c_char, len: usize, ) -> z_error_t { - let this = this.transmute_uninit_ptr(); if name.is_null() { - Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, len); - match keyexpr_create(name, false, false) { Ok(ke) => { - Inplace::init(this, Some(ke)); + (*this).write(std::mem::transmute(ke)); errors::Z_OK } Err(e) => { - Inplace::empty(this); e } } } -/// Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. /// The string is canonized in-place before being passed to keyexpr. /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( - this: *mut MaybeUninit, + this: *mut MaybeUninit, name: *mut c_char, len: &mut usize, ) -> z_error_t { - let this = this.transmute_uninit_ptr(); if name.is_null() { - Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); @@ -272,11 +257,10 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( match keyexpr_create(name, true, false) { Ok(ke) => { *len = ke.len(); - Inplace::init(this, Some(ke)); + (*this).write(std::mem::transmute(ke)); errors::Z_OK } Err(e) => { - Inplace::empty(this); e } } @@ -287,11 +271,10 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_keyexpr( - this: *mut MaybeUninit, + this: *mut MaybeUninit, name: *const c_char, ) -> z_error_t { if name.is_null() { - Inplace::empty(this.transmute_uninit_ptr()); errors::Z_EINVAL } else { let len = libc::strlen(name); @@ -299,17 +282,16 @@ pub unsafe extern "C" fn z_keyexpr( } } -/// Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. /// The string is canonized in-place before being passed to keyexpr. /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_keyexpr_autocanonize( - this: *mut MaybeUninit, + this: *mut MaybeUninit, name: *mut c_char, ) -> z_error_t { if name.is_null() { - Inplace::empty(this.transmute_uninit_ptr()); errors::Z_EINVAL } else { let mut len = libc::strlen(name); @@ -321,7 +303,7 @@ pub unsafe extern "C" fn z_keyexpr_autocanonize( } } -/// Constructs a :c:type:`z_owned_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: /// - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. @@ -332,17 +314,17 @@ pub unsafe extern "C" fn z_keyexpr_autocanonize( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( - this: *mut MaybeUninit, + this: *mut MaybeUninit, start: *const c_char, len: usize, ) { let name = std::slice::from_raw_parts(start as _, len); let name = std::str::from_utf8_unchecked(name); let name: KeyExpr = keyexpr::from_str_unchecked(name).into(); - Inplace::init(this.transmute_uninit_ptr(), Some(name)); + (*this).write(std::mem::transmute(name)); } -/// Constructs a :c:type:`z_owned_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: /// /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: @@ -355,7 +337,7 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_keyexpr_unchecked( - this: *mut MaybeUninit, + this: *mut MaybeUninit, name: *const c_char, ) { zc_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) @@ -365,7 +347,7 @@ pub unsafe extern "C" fn z_keyexpr_unchecked( /// The user is responsible of droping the returned string using `z_drop` #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_to_string(ke: z_keyexpr_t) -> z_owned_str_t { +pub unsafe extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t) -> z_owned_str_t { ke.transmute_ref().as_bytes().into() } @@ -374,7 +356,7 @@ pub unsafe extern "C" fn z_keyexpr_to_string(ke: z_keyexpr_t) -> z_owned_str_t { /// Currently exclusive to zenoh-c #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_keyexpr_as_bytes(ke: z_keyexpr_t) -> z_slice_t { +pub extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t) -> z_slice_t { let ke = ke.transmute_ref(); z_slice_t { start: ke.as_ptr(), @@ -382,12 +364,6 @@ pub extern "C" fn z_keyexpr_as_bytes(ke: z_keyexpr_t) -> z_slice_t { } } -impl From<&'static KeyExpr<'static>> for z_keyexpr_t { - fn from(key: &'static KeyExpr<'static>) -> Self { - key.transmute_handle() - } -} - /**************************************/ /* DECLARATION */ /**************************************/ @@ -399,8 +375,8 @@ impl From<&'static KeyExpr<'static>> for z_keyexpr_t { #[no_mangle] pub extern "C" fn z_declare_keyexpr( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, ) -> z_error_t { let this = this.transmute_uninit_ptr(); let key_expr = key_expr.transmute_ref(); @@ -422,10 +398,10 @@ pub extern "C" fn z_declare_keyexpr( /// The keyxpr is consumed. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_undeclare_keyexpr(session: z_session_t, kexpr: &mut z_owned_keyexpr_t) -> i8 { +pub extern "C" fn z_undeclare_keyexpr(session: &z_session_t, kexpr: &mut z_owned_keyexpr_t) -> errors::z_error_t { let Some(kexpr) = kexpr.transmute_mut().take() else { log::debug!("Attempted to undeclare dropped keyexpr"); - return i8::MIN; + return errors::Z_EINVAL; }; let session = session.transmute_ref(); match session.undeclare(kexpr).res() { @@ -440,7 +416,7 @@ pub extern "C" fn z_undeclare_keyexpr(session: z_session_t, kexpr: &mut z_owned_ #[allow(clippy::missing_safety_doc)] #[no_mangle] /// Returns ``0`` if both ``left`` and ``right`` are equal. -pub extern "C" fn z_keyexpr_equals(left: z_keyexpr_t, right: z_keyexpr_t) -> bool { +pub extern "C" fn z_keyexpr_equals(left: &z_keyexpr_t, right: &z_keyexpr_t) -> bool { let l = left.transmute_ref(); let r = right.transmute_ref(); *l == *r @@ -450,7 +426,7 @@ pub extern "C" fn z_keyexpr_equals(left: z_keyexpr_t, right: z_keyexpr_t) -> boo #[no_mangle] /// Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the /// sets defined by ``left`` and ``right``. -pub extern "C" fn z_keyexpr_intersects(left: z_keyexpr_t, right: z_keyexpr_t) -> bool { +pub extern "C" fn z_keyexpr_intersects(left: &z_keyexpr_t, right: &z_keyexpr_t) -> bool { let l = left.transmute_ref(); let r = right.transmute_ref(); l.intersects(r) @@ -460,7 +436,7 @@ pub extern "C" fn z_keyexpr_intersects(left: z_keyexpr_t, right: z_keyexpr_t) -> #[no_mangle] /// Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set /// defined by ``right``. -pub extern "C" fn z_keyexpr_includes(left: z_keyexpr_t, right: z_keyexpr_t) -> bool { +pub extern "C" fn z_keyexpr_includes(left: &z_keyexpr_t, right: &z_keyexpr_t) -> bool { let l = left.transmute_ref(); let r = right.transmute_ref(); l.includes(r) @@ -476,10 +452,10 @@ pub extern "C" fn z_keyexpr_includes(left: z_keyexpr_t, right: z_keyexpr_t) -> b /// To avoid odd behaviors, concatenating a key expression starting with `*` to one ending with `*` is forbidden by this operation, /// as this would extremely likely cause bugs. pub unsafe extern "C" fn z_keyexpr_concat( - left: z_keyexpr_t, + this: *mut MaybeUninit, + left: &z_keyexpr_t, right_start: *const c_char, right_len: usize, - this: *mut MaybeUninit, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let left = left.transmute_ref(); @@ -515,9 +491,9 @@ pub unsafe extern "C" fn z_keyexpr_concat( /// Performs path-joining (automatically inserting) and returns the result as a `z_owned_keyexpr_t`. /// In case of error, the return value will be set to its invalidated state. pub extern "C" fn z_keyexpr_join( - left: z_keyexpr_t, - right: z_keyexpr_t, this: *mut MaybeUninit, + left: &z_keyexpr_t, + right: &z_keyexpr_t, ) -> errors::z_error_t { let left = left.transmute_ref(); let right = right.transmute_ref(); @@ -566,8 +542,8 @@ impl From for z_keyexpr_intersection_level_t { /// /// Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. pub extern "C" fn z_keyexpr_relation_to( - left: z_keyexpr_t, - right: z_keyexpr_t, + left: &z_keyexpr_t, + right: &z_keyexpr_t, ) -> z_keyexpr_intersection_level_t { let l = left.transmute_ref(); let r = right.transmute_ref(); diff --git a/src/liveliness.rs b/src/liveliness.rs index fed6a9bfc..88e0966b3 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -54,9 +54,9 @@ pub struct zc_liveliness_declaration_options_t { } #[no_mangle] -pub extern "C" fn zc_liveliness_declaration_options_default() -> zc_liveliness_declaration_options_t +pub extern "C" fn zc_liveliness_declaration_options_default(this: &mut zc_liveliness_declaration_options_t) { - zc_liveliness_declaration_options_t { _dummy: 0 } + *this = zc_liveliness_declaration_options_t { _dummy: 0 }; } /// Constructs and declares a liveliness token on the network. @@ -68,8 +68,8 @@ pub extern "C" fn zc_liveliness_declaration_options_default() -> zc_liveliness_d #[no_mangle] pub extern "C" fn zc_liveliness_declare_token( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, _options: Option<&mut zc_liveliness_declaration_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); @@ -110,9 +110,8 @@ pub struct zc_liveliness_declare_subscriber_options_t { } #[no_mangle] -pub extern "C" fn zc_liveliness_subscriber_options_default( -) -> zc_liveliness_declare_subscriber_options_t { - zc_liveliness_declare_subscriber_options_t { _dummy: 0 } +pub extern "C" fn zc_liveliness_subscriber_options_default(this: &mut zc_liveliness_declare_subscriber_options_t) { + *this = zc_liveliness_declare_subscriber_options_t { _dummy: 0 }; } /// Declares a subscriber on liveliness tokens that intersect `key`. @@ -132,8 +131,8 @@ pub extern "C" fn zc_liveliness_subscriber_options_default( #[no_mangle] pub extern "C" fn zc_liveliness_declare_subscriber( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, callback: &mut z_owned_closure_sample_t, _options: Option<&mut zc_liveliness_declare_subscriber_options_t>, ) -> errors::z_error_t { @@ -170,8 +169,8 @@ pub struct zc_liveliness_get_options_t { /// The gravestone value for `zc_liveliness_get_options_t` #[no_mangle] -pub extern "C" fn zc_liveliness_get_options_default() -> zc_liveliness_get_options_t { - zc_liveliness_get_options_t { timeout_ms: 10000 } +pub extern "C" fn zc_liveliness_get_options_default(this: &mut zc_liveliness_get_options_t) { + *this = zc_liveliness_get_options_t { timeout_ms: 10000 }; } /// Queries liveliness tokens currently on the network with a key expression intersecting with `key`. @@ -181,8 +180,8 @@ pub extern "C" fn zc_liveliness_get_options_default() -> zc_liveliness_get_optio /// Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. #[no_mangle] pub extern "C" fn zc_liveliness_get( - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, callback: &mut z_owned_closure_reply_t, options: Option<&mut zc_liveliness_get_options_t>, ) -> errors::z_error_t { diff --git a/src/payload.rs b/src/payload.rs index 530fbf358..7f3556b27 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -41,7 +41,7 @@ extern "C" fn z_bytes_check(payload: &z_owned_bytes_t) -> bool { /// Loans the payload, allowing you to call functions that only need a loan of it. #[no_mangle] -extern "C" fn z_bytes_loan(payload: &'static z_owned_bytes_t) -> z_bytes_t { +extern "C" fn z_bytes_loan(payload: & z_owned_bytes_t) -> &z_bytes_t { let payload = payload.transmute_ref(); let payload = unwrap_ref_unchecked(payload); payload.transmute_handle() @@ -52,16 +52,16 @@ decl_transmute_handle!(ZBytes, z_bytes_t); /// Increments the payload's reference count, returning an owned version of it. #[no_mangle] -extern "C" fn z_bytes_clone(src: &z_owned_bytes_t, dst: *mut MaybeUninit) { +extern "C" fn z_bytes_clone(src: &z_bytes_t, dst: *mut MaybeUninit) { let dst = dst.transmute_uninit_ptr(); let src = src.transmute_ref(); - let src = src.as_ref().map(Clone::clone); + let src = Some(src.clone()); Inplace::init(dst, src); } /// Returns total number bytes in the payload. #[no_mangle] -extern "C" fn z_bytes_len(payload: z_bytes_t) -> usize { +extern "C" fn z_bytes_len(payload: &z_bytes_t) -> usize { payload.transmute_ref().len() } @@ -69,7 +69,7 @@ extern "C" fn z_bytes_len(payload: z_bytes_t) -> usize { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_decode_into_string( - payload: z_bytes_t, + payload: &z_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { let len = z_bytes_len(payload); @@ -110,13 +110,13 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_decode_into_bytes( - payload: z_bytes_t, + payload: &z_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { let len = z_bytes_len(payload); let b = z_owned_slice_t::preallocate(len); let payload = payload.transmute_ref(); - if let Err(e) = payload.reader().read(from_raw_parts_mut(b.start, len)) { + if let Err(e) = payload.reader().read(from_raw_parts_mut(b.start as *mut _, len)) { log::error!("Failed to read the payload: {}", e); Inplace::empty(dst); errors::Z_EIO @@ -147,10 +147,10 @@ impl ZSliceBuffer for z_slice_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_bytes( this: *mut MaybeUninit, - bytes: z_slice_t, + bytes: &z_slice_t, ) { let this = this.transmute_uninit_ptr(); - let payload = ZBytes::from(ZSlice::from(bytes)); + let payload = ZBytes::from(ZSlice::from(bytes.clone())); Inplace::init(this, Some(payload)); } @@ -159,7 +159,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_bytes( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_bytes_map( this: *mut MaybeUninit, - bytes_map: z_slice_map_t, + bytes_map: &z_slice_map_t, ) { let dst = this.transmute_uninit_ptr(); let hm = bytes_map.transmute_ref(); @@ -178,7 +178,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_string( start: cstr as *const u8, len: libc::strlen(cstr), }; - z_bytes_encode_from_bytes(this, bytes); + z_bytes_encode_from_bytes(this, &bytes); } pub use crate::opaque_types::z_owned_bytes_reader_t; @@ -222,7 +222,7 @@ extern "C" fn z_bytes_reader_drop(this: &mut z_owned_bytes_reader_t) { } #[no_mangle] -extern "C" fn z_bytes_reader_loan(reader: &'static z_owned_bytes_reader_t) -> z_bytes_reader_t { +extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_bytes_reader_t { let reader = reader.transmute_ref(); let reader = unwrap_ref_unchecked(reader); reader.transmute_handle() @@ -235,7 +235,7 @@ extern "C" fn z_bytes_reader_loan(reader: &'static z_owned_bytes_reader_t) -> z_ #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_read( - this: z_bytes_reader_t, + this: &z_bytes_reader_t, dest: *mut u8, len: usize, ) -> usize { @@ -251,7 +251,7 @@ pub unsafe extern "C" fn z_bytes_reader_read( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_seek( - this: z_bytes_reader_t, + this: &z_bytes_reader_t, offset: i64, origin: libc::c_int, ) -> z_error_t { @@ -274,7 +274,7 @@ pub unsafe extern "C" fn z_bytes_reader_seek( /// Returns read position indicator on success or -1L if failure occurs. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_tell(this: z_bytes_reader_t) -> i64 { +pub unsafe extern "C" fn z_bytes_reader_tell(this: &z_bytes_reader_t) -> i64 { let reader = this.transmute_mut(); reader.stream_position().map(|p| p as i64).unwrap_or(-1) } diff --git a/src/publisher.rs b/src/publisher.rs index 30c033645..8b647dfd4 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -49,11 +49,11 @@ pub struct z_publisher_options_t { /// Constructs the default value for :c:type:`z_publisher_options_t`. #[no_mangle] -pub extern "C" fn z_publisher_options_default() -> z_publisher_options_t { - z_publisher_options_t { +pub extern "C" fn z_publisher_options_default(this: &mut z_publisher_options_t) { + *this = z_publisher_options_t { congestion_control: CongestionControl::default().into(), priority: Priority::default().into(), - } + }; } pub use crate::opaque_types::z_owned_publisher_t; @@ -97,10 +97,10 @@ decl_transmute_handle!(Publisher<'static>, z_publisher_t); #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_publisher( - session: z_session_t, - key_expr: z_keyexpr_t, - options: Option<&z_publisher_options_t>, this: *mut MaybeUninit, + session: &z_session_t, + key_expr: &z_keyexpr_t, + options: Option<&z_publisher_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let session = session.transmute_ref(); @@ -135,16 +135,16 @@ pub extern "C" fn z_publisher_null(this: *mut MaybeUninit) /// Returns ``true`` if `pub` is valid. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_publisher_check(pbl: &'static z_owned_publisher_t) -> bool { - pbl.transmute_ref().is_some() +pub extern "C" fn z_publisher_check(this: &z_owned_publisher_t) -> bool { + this.transmute_ref().is_some() } /// Returns a :c:type:`z_publisher_t` loaned from `p`. #[no_mangle] -pub extern "C" fn z_publisher_loan(p: &'static z_owned_publisher_t) -> z_publisher_t { - let p = p.transmute_ref(); - let p = unwrap_ref_unchecked(p); - p.transmute_handle() +pub extern "C" fn z_publisher_loan(this: &z_owned_publisher_t) -> &z_publisher_t { + let this = this.transmute_ref(); + let this = unwrap_ref_unchecked(this); + this.transmute_handle() } /// Options passed to the :c:func:`z_publisher_put` function. @@ -161,8 +161,8 @@ pub struct z_publisher_put_options_t { /// Constructs the default value for :c:type:`z_publisher_put_options_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t { - z_publisher_put_options_t { +pub extern "C" fn z_publisher_put_options_default(this: &mut z_publisher_put_options_t) { + *this = z_publisher_put_options_t { encoding: ptr::null_mut(), attachment: ptr::null_mut(), } @@ -185,7 +185,7 @@ pub extern "C" fn z_publisher_put_options_default() -> z_publisher_put_options_t #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_publisher_put( - publisher: z_publisher_t, + publisher: &z_publisher_t, payload: &mut z_owned_bytes_t, options: Option<&mut z_publisher_put_options_t>, ) -> errors::z_error_t { @@ -231,8 +231,8 @@ pub struct z_publisher_delete_options_t { /// Returns the constructed :c:type:`z_publisher_delete_options_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_publisher_delete_options_default() -> z_publisher_delete_options_t { - z_publisher_delete_options_t { __dummy: 0 } +pub extern "C" fn z_publisher_delete_options_default(this: &mut z_publisher_delete_options_t) { + *this = z_publisher_delete_options_t { __dummy: 0 } } /// Sends a `DELETE` message onto the publisher's key expression. /// @@ -241,7 +241,7 @@ pub extern "C" fn z_publisher_delete_options_default() -> z_publisher_delete_opt #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_publisher_delete( - publisher: z_publisher_t, + publisher: &z_publisher_t, _options: z_publisher_delete_options_t, ) -> errors::z_error_t { let publisher = publisher.transmute_ref(); @@ -256,7 +256,7 @@ pub extern "C" fn z_publisher_delete( /// Returns the key expression of the publisher #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_publisher_keyexpr(publisher: z_publisher_t) -> z_keyexpr_t { +pub extern "C" fn z_publisher_keyexpr(publisher: &z_publisher_t) -> &z_keyexpr_t { let publisher = publisher.transmute_ref(); publisher.key_expr().transmute_handle() } @@ -281,9 +281,9 @@ pub struct zcu_matching_status_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn zcu_publisher_matching_listener_callback( - publisher: z_publisher_t, - callback: &mut zcu_owned_closure_matching_status_t, this: *mut MaybeUninit, + publisher: &z_publisher_t, + callback: &mut zcu_owned_closure_matching_status_t, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); let mut closure = zcu_owned_closure_matching_status_t::empty(); @@ -313,8 +313,8 @@ pub extern "C" fn zcu_publisher_matching_listener_callback( /// Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_undeclare_publisher(publisher: &mut z_owned_publisher_t) -> errors::z_error_t { - if let Some(p) = publisher.transmute_mut().extract().take() { +pub extern "C" fn z_undeclare_publisher(this: &mut z_owned_publisher_t) -> errors::z_error_t { + if let Some(p) = this.transmute_mut().extract().take() { if let Err(e) = p.undeclare().res_sync() { log::error!("{}", e); return errors::Z_EGENERIC; diff --git a/src/put.rs b/src/put.rs index 728499034..2bb950087 100644 --- a/src/put.rs +++ b/src/put.rs @@ -46,13 +46,13 @@ pub struct z_put_options_t { /// Constructs the default value for :c:type:`z_put_options_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_put_options_default() -> z_put_options_t { - z_put_options_t { +pub extern "C" fn z_put_options_default(this: &mut z_put_options_t) { + *this = z_put_options_t { encoding: null_mut(), congestion_control: CongestionControl::default().into(), priority: Priority::default().into(), attachment: null_mut(), - } + }; } /// Put data, transfering its ownership. @@ -71,8 +71,8 @@ pub extern "C" fn z_put_options_default() -> z_put_options_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_put( - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, payload: &mut z_owned_bytes_t, options: Option<&mut z_put_options_t>, ) -> errors::z_error_t { @@ -117,11 +117,11 @@ pub struct z_delete_options_t { /// Constructs the default value for :c:type:`z_put_options_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_delete_options_default() -> z_delete_options_t { - z_delete_options_t { +pub unsafe extern "C" fn z_delete_options_default(this: *mut z_delete_options_t) { + *this = z_delete_options_t { congestion_control: CongestionControl::default().into(), priority: Priority::default().into(), - } + }; } /// Delete data. @@ -135,8 +135,8 @@ pub unsafe extern "C" fn z_delete_options_default() -> z_delete_options_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_delete( - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, options: Option<&mut z_delete_options_t>, ) -> errors::z_error_t { let session = session.transmute_ref(); diff --git a/src/queryable.rs b/src/queryable.rs index 17b5a82bc..e27178983 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -20,7 +20,7 @@ use crate::{ z_owned_encoding_t, z_session_t, z_slice_t, z_value_t, }; use std::mem::MaybeUninit; -use std::ptr::null_mut; +use std::ptr::{null, null_mut}; use zenoh::prelude::SessionDeclarations; use zenoh::prelude::SyncResolve; use zenoh::prelude::{Query, Queryable}; @@ -66,7 +66,7 @@ pub extern "C" fn z_query_check(query: &z_owned_query_t) -> bool { /// /// This function may not be called with the null pointer, but can be called with the gravestone value. #[no_mangle] -pub extern "C" fn z_query_loan(this: &'static z_owned_query_t) -> z_query_t { +pub extern "C" fn z_query_loan(this: &'static z_owned_query_t) -> &z_query_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() @@ -82,11 +82,11 @@ pub extern "C" fn z_query_drop(this: &mut z_owned_query_t) { /// /// This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). #[no_mangle] -pub extern "C" fn z_query_clone(this: *mut MaybeUninit, query: z_query_t) { - let query = query.transmute_ref(); - let query = query.clone(); - let this = this.transmute_uninit_ptr(); - Inplace::init(this, Some(query)); +pub extern "C" fn z_query_clone(this: &z_query_t, dst: *mut MaybeUninit) { + let this = this.transmute_ref(); + let this = this.clone(); + let dst = dst.transmute_uninit_ptr(); + Inplace::init(dst, Some(this)); } /// Options passed to the :c:func:`z_declare_queryable` function. @@ -101,8 +101,8 @@ pub struct z_queryable_options_t { /// Constructs the default value for :c:type:`z_query_reply_options_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_queryable_options_default() -> z_queryable_options_t { - z_queryable_options_t { complete: false } +pub extern "C" fn z_queryable_options_default(this: &mut z_queryable_options_t) { + *this = z_queryable_options_t { complete: false }; } /// Represents the set of options that can be applied to a query reply, @@ -121,11 +121,11 @@ pub struct z_query_reply_options_t { /// Constructs the default value for :c:type:`z_query_reply_options_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_query_reply_options_default() -> z_query_reply_options_t { - z_query_reply_options_t { +pub extern "C" fn z_query_reply_options_default(this: &mut z_query_reply_options_t) { + *this = z_query_reply_options_t { encoding: null_mut(), attachment: null_mut(), - } + }; } /// Creates a Queryable for the given key expression. @@ -142,8 +142,8 @@ pub extern "C" fn z_query_reply_options_default() -> z_query_reply_options_t { #[no_mangle] pub extern "C" fn z_declare_queryable( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, callback: &mut z_owned_closure_query_t, options: Option<&mut z_queryable_options_t>, ) -> errors::z_error_t { @@ -248,14 +248,14 @@ pub unsafe extern "C" fn z_query_reply( /// Get a query's key by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_keyexpr(query: z_query_t) -> z_keyexpr_t { +pub extern "C" fn z_query_keyexpr(query: &z_query_t) -> &z_keyexpr_t { query.transmute_ref().key_expr().transmute_handle() } /// Get a query's `value selector `_ by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_parameters(query: z_query_t) -> z_slice_t { +pub extern "C" fn z_query_parameters(query: &z_query_t) -> z_slice_t { let query = query.transmute_ref(); let params = query.parameters().as_str(); z_slice_t { @@ -265,21 +265,17 @@ pub extern "C" fn z_query_parameters(query: z_query_t) -> z_slice_t { } /// Checks if query contains a payload value. -pub extern "C" fn z_query_has_value(query: z_query_t) -> bool { +#[no_mangle] +pub extern "C" fn z_query_has_value(query: &z_query_t) -> bool { query.transmute_ref().value().is_some() } -/// Checks if query contains an attachment. -pub extern "C" fn z_query_has_attachment(query: z_query_t) -> bool { - query.transmute_ref().attachment().is_some() -} - /// Gets a query's `payload value `_ by aliasing it. /// /// **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** /// Before calling this funciton, the user must ensure that `z_query_has_value` returns true. #[no_mangle] -pub extern "C" fn z_query_value(query: z_query_t) -> z_value_t { +pub extern "C" fn z_query_value(query: &z_query_t) -> &z_value_t { query .transmute_ref() .value() @@ -289,12 +285,11 @@ pub extern "C" fn z_query_value(query: z_query_t) -> z_value_t { /// Gets the attachment to the query by aliasing. /// -/// Before calling this funciton, the user must ensure that `z_query_has_attachment` returns true. +/// Returns NULL if query does not contain an attachment. #[no_mangle] -pub extern "C" fn z_query_attachment(query: z_query_t) -> z_bytes_t { - query - .transmute_ref() - .attachment() - .expect("Query does not contain an attachment") - .transmute_handle() +pub extern "C" fn z_query_attachment(query: &z_query_t) -> *const z_bytes_t { + match query.transmute_ref().attachment() { + Some(attachment) => attachment.transmute_handle() as *const _, + None => null(), + } } diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 9bc8e2459..d6a5e3696 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -83,8 +83,8 @@ pub struct ze_querying_subscriber_options_t { /// Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. #[no_mangle] -pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscriber_options_t { - ze_querying_subscriber_options_t { +pub extern "C" fn ze_querying_subscriber_options_default(this: &mut ze_querying_subscriber_options_t) { + *this = ze_querying_subscriber_options_t { reliability: Reliability::DEFAULT.into(), allowed_origin: zcu_locality_default(), query_selector: null(), @@ -92,7 +92,7 @@ pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscr query_consolidation: z_query_consolidation_none(), query_accept_replies: zcu_reply_keyexpr_default(), query_timeout_ms: 0, - } + }; } /// Declares a Querying Subscriber for a given key expression. @@ -130,8 +130,8 @@ pub extern "C" fn ze_querying_subscriber_options_default() -> ze_querying_subscr #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn ze_declare_querying_subscriber( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: Option<&mut ze_querying_subscriber_options_t>, ) -> errors::z_error_t { @@ -179,8 +179,8 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn ze_querying_subscriber_get( - sub: ze_querying_subscriber_t, - selector: z_keyexpr_t, + sub: &ze_querying_subscriber_t, + selector: &z_keyexpr_t, options: Option<&z_get_options_t>, ) -> errors::z_error_t { unsafe impl Sync for z_get_options_t {} @@ -235,7 +235,7 @@ pub extern "C" fn ze_querying_subscriber_check(this: &ze_owned_querying_subscrib #[no_mangle] pub extern "C" fn ze_querying_subscriber_loan( this: &ze_owned_querying_subscriber_t, -) -> ze_querying_subscriber_t { +) -> &ze_querying_subscriber_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/scouting.rs b/src/scouting.rs index 3d593852d..0f2f29c34 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -42,9 +42,9 @@ pub struct z_owned_str_array_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_str_array_drop(strs: &mut z_owned_str_array_t) { - let locators = Vec::from_raw_parts(strs.val as *mut *const c_char, strs.len, strs.len); - for locator in locators { - std::mem::drop(CString::from_raw(locator as *mut c_char)); + let vals = Vec::from_raw_parts(strs.val as *mut *const c_char, strs.len, strs.len); + for val in vals { + std::mem::drop(CString::from_raw(val as *mut c_char)); } strs.val = std::ptr::null_mut(); strs.len = 0; @@ -67,11 +67,8 @@ pub struct z_str_array_t { /// Returns a :c:type:`z_str_array_t` loaned from :c:type:`z_owned_str_array_t`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_str_array_loan(strs: &z_owned_str_array_t) -> z_str_array_t { - z_str_array_t { - val: strs.val as *const _, - len: strs.len, - } +pub unsafe extern "C" fn z_str_array_loan(strs: &z_owned_str_array_t) -> &z_str_array_t { + std::mem::transmute(strs) } /// A zenoh-allocated hello message returned by a zenoh entity to a scout message sent with `z_scout`. /// @@ -146,26 +143,23 @@ pub unsafe extern "C" fn z_hello_drop(hello: &mut z_owned_hello_t) { /// Returns a :c:type:`z_hello_t` loaned from :c:type:`z_owned_hello_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_hello_loan(hello: &z_owned_hello_t) -> z_hello_t { - z_hello_t { - whatami: hello._whatami, - pid: hello._pid, - locators: z_str_array_loan(&hello._locators), - } +pub unsafe extern "C" fn z_hello_loan(hello: &z_owned_hello_t) -> &z_hello_t { + std::mem::transmute(hello) } /// Constructs a gravestone value for hello, useful to steal one from a callback #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_hello_null() -> z_owned_hello_t { - z_owned_hello_t { +pub unsafe extern "C" fn z_hello_null(this: *mut MaybeUninit) { + let h = z_owned_hello_t { _whatami: 0, _pid: [0; 16].into(), _locators: z_owned_str_array_t { val: std::ptr::null_mut(), len: 0, }, - } + }; + (*this).write(h); } impl Drop for z_owned_hello_t { fn drop(&mut self) { @@ -224,8 +218,8 @@ pub unsafe extern "C" fn z_scouting_config_default( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_scouting_config_from( - config: z_config_t, this: *mut MaybeUninit, + config: &z_config_t, ) { let mut dst = MaybeUninit::uninit(); z_config_clone(&config, &mut dst as *mut _); @@ -281,7 +275,7 @@ pub extern "C" fn z_scout( std::mem::swap(&mut closure, callback); task::block_on(async move { - let scout = zenoh::scout(what, *config) + let scout = zenoh::scout(what, config) .callback(move |h| { let mut hello = h.into(); z_closure_hello_call(&closure, &mut hello) @@ -307,10 +301,10 @@ pub extern "C" fn z_scout( #[no_mangle] pub extern "C" fn z_whatami_to_str(whatami: u8, buf: *mut c_char, len: usize) -> i8 { if buf.is_null() || len == 0 { - return -1; + return errors::Z_EINVAL; } match WhatAmIMatcher::try_from(whatami) { - Err(_) => -1, + Err(_) => errors::Z_EINVAL, Ok(w) => { let s = w.to_str(); let res = s.copy_to_c_array(buf as *mut c_void, len - 1); diff --git a/src/session.rs b/src/session.rs index 5079c50f0..194779201 100644 --- a/src/session.rs +++ b/src/session.rs @@ -38,7 +38,7 @@ decl_transmute_handle!(Session, z_session_t); /// attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) /// have been destroyed is UB (likely SEGFAULT) #[no_mangle] -pub extern "C" fn z_session_loan(this: &'static z_owned_session_t) -> z_session_t { +pub extern "C" fn z_session_loan(this: & z_owned_session_t) -> &z_session_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); let this = this.as_ref(); @@ -64,7 +64,7 @@ pub extern "C" fn z_open( if cfg!(feature = "logger-autoinit") { zc_init_logger(); } - let config = match config.transmute_mut().take() { + let config = match config.transmute_mut().extract() { Some(c) => c, None => { log::error!("Config not provided"); @@ -72,7 +72,7 @@ pub extern "C" fn z_open( return errors::Z_EINVAL; } }; - match zenoh::open(*config).res() { + match zenoh::open(config).res() { Ok(s) => { Inplace::init(this, Some(Arc::new(s))); errors::Z_OK @@ -98,10 +98,10 @@ pub extern "C" fn z_session_check(this: &z_owned_session_t) -> bool { /// Returns the remaining reference count of the session otherwise, saturating at i8::MAX. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_close(session: &mut z_owned_session_t) -> i8 { +pub extern "C" fn z_close(session: &mut z_owned_session_t) -> errors::z_error_t { let session = session.transmute_mut(); let Some(s) = session.take() else { - return 0; + return errors::Z_OK; }; let s = match Arc::try_unwrap(s) { Ok(s) => s, @@ -111,22 +111,22 @@ pub extern "C" fn z_close(session: &mut z_owned_session_t) -> i8 { }; match s.close().res() { Err(e) => e.errno().get(), - Ok(_) => 0, + Ok(_) => errors::Z_OK, } } /// Increments the session's reference count, returning a new owning handle. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn zc_session_rcinc( +pub extern "C" fn zc_session_clone( dst: *mut MaybeUninit, src: &z_owned_session_t, -) -> i8 { +) -> errors::z_error_t { // session.as_ref().as_ref().and_then(|s| s.upgrade()).into() let dst = dst.transmute_uninit_ptr(); let Some(src) = src.transmute_ref() else { - return -1; + return errors::Z_EINVAL; }; Inplace::init(dst, Some(src.clone())); - 0 + errors::Z_OK } diff --git a/src/subscriber.rs b/src/subscriber.rs index 81b1a8c4c..ad5d73e4d 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -77,7 +77,7 @@ pub extern "C" fn z_subscriber_null(this: *mut MaybeUninit /// Returns a :c:type:`z_subscriber_t` loaned from `this`. #[no_mangle] -pub extern "C" fn z_subscriber_loan(this: &z_owned_subscriber_t) -> z_subscriber_t { +pub extern "C" fn z_subscriber_loan(this: &z_owned_subscriber_t) -> &z_subscriber_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() @@ -95,8 +95,8 @@ pub struct z_subscriber_options_t { /// Constructs the default value for :c:type:`z_subscriber_options_t`. #[no_mangle] -pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { - z_subscriber_options_t { +pub extern "C" fn z_subscriber_options_default(this: &mut z_subscriber_options_t) { + *this = z_subscriber_options_t { reliability: Reliability::DEFAULT.into(), } } @@ -136,8 +136,8 @@ pub extern "C" fn z_subscriber_options_default() -> z_subscriber_options_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_subscriber( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: Option<&mut z_subscriber_options_t>, ) -> errors::z_error_t { @@ -171,7 +171,7 @@ pub extern "C" fn z_declare_subscriber( /// Returns the key expression of the subscriber. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_subscriber_keyexpr(subscriber: z_subscriber_t) -> z_keyexpr_t { +pub extern "C" fn z_subscriber_keyexpr(subscriber: &z_subscriber_t) -> &z_keyexpr_t { let subscriber = subscriber.transmute_ref(); subscriber.key_expr().transmute_handle() } diff --git a/src/transmute.rs b/src/transmute.rs index 5951a7137..b5d88a6dc 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -23,18 +23,24 @@ pub fn unwrap_ref_unchecked(value: &Option) -> &T { unsafe { value.as_ref().unwrap_unchecked() } } +pub fn unwrap_ref_unchecked_mut(value: &mut Option) -> &mut T { + debug_assert!(value.is_some()); + unsafe { value.as_mut().unwrap_unchecked() } +} + pub(crate) trait TransmuteRef: Sized { fn transmute_ref(&self) -> &T; fn transmute_mut(&mut self) -> &mut T; } pub(crate) trait TransmuteFromHandle: Sized { - fn transmute_ref(self) -> &'static T; - fn transmute_mut(self) -> &'static mut T; + fn transmute_ref(&self) -> &'static T; + fn transmute_mut(&mut self) -> &'static mut T; } pub(crate) trait TransmuteIntoHandle: Sized { - fn transmute_handle(&self) -> T; + fn transmute_handle(&self) -> &'static T; + fn transmute_handle_mut(&mut self) -> &'static mut T; } pub(crate) trait TransmuteCopy { @@ -200,16 +206,19 @@ macro_rules! impl_transmute_uninit_ptr { macro_rules! impl_transmute_handle { ($c_type:ty, $zenoh_type:ty) => { impl $crate::transmute::TransmuteFromHandle<$zenoh_type> for $c_type { - fn transmute_ref(self) -> &'static $zenoh_type { - unsafe { std::mem::transmute::<$c_type, &'static $zenoh_type>(self) } + fn transmute_ref(&self) -> &'static $zenoh_type { + unsafe { std::mem::transmute::<& $c_type, &'static $zenoh_type>(self) } } - fn transmute_mut(self) -> &'static mut $zenoh_type { - unsafe { std::mem::transmute::<$c_type, &'static mut $zenoh_type>(self) } + fn transmute_mut(&mut self) -> &'static mut $zenoh_type { + unsafe { std::mem::transmute::<&mut $c_type, &'static mut $zenoh_type>(self) } } } impl $crate::transmute::TransmuteIntoHandle<$c_type> for $zenoh_type { - fn transmute_handle(&self) -> $c_type { - unsafe { std::mem::transmute::<&$zenoh_type, $c_type>(self) } + fn transmute_handle(&self) -> &'static $c_type { + unsafe { std::mem::transmute::<&$zenoh_type, &'static $c_type>(self) } + } + fn transmute_handle_mut(&mut self) -> &'static mut $c_type { + unsafe { std::mem::transmute::<&mut $zenoh_type, &'static mut $c_type>(self) } } } }; From d0c513c7041dc1810e0d902696e0ec828e6b2bfe Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 25 Apr 2024 17:28:17 +0200 Subject: [PATCH 66/75] fixed api for view types --- build-resources/opaque-types/src/lib.rs | 17 + include/zenoh_commons.h | 262 ++++++++++----- include/zenoh_concrete.h | 1 + src/collections.rs | 429 ++++++++++-------------- src/config.rs | 31 +- src/errors.rs | 1 + src/keyexpr.rs | 87 +++-- src/payload.rs | 61 ++-- src/queryable.rs | 9 +- 9 files changed, 492 insertions(+), 406 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 3781c062c..4aba1525b 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -46,6 +46,21 @@ get_opaque_type_data!(Option, z_owned_bytes_t); /// A loaned payload. get_opaque_type_data!(ZBytes, z_bytes_t); +/// A contiguous view of bytes owned by some other entity. +/// +/// `start` being `null` is considered a gravestone value, +/// and empty slices are represented using a possibly dangling pointer for `start`. +get_opaque_type_data!(Option>, z_owned_slice_t); +get_opaque_type_data!(Option<&'static [u8]>, z_view_slice_t); +get_opaque_type_data!(&'static [u8], z_slice_t); + +/// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` +/// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with +/// `z_check` and `z_str_check` correspondently +get_opaque_type_data!(Option>, z_owned_str_t); +get_opaque_type_data!(Option<&'static [u8]>, z_view_str_t); +get_opaque_type_data!(&'static [u8], z_str_t); + /// A map of maybe-owned vector of bytes to maybe-owned vector of bytes. /// /// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher @@ -141,6 +156,8 @@ get_opaque_type_data!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Sess /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_keyexpr_t); +get_opaque_type_data!(Option>, z_view_keyexpr_t); + /// A loaned key expression. /// /// Key expressions can identify a single key or a set of keys. diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 0a3a59df7..7a3f071e8 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -129,9 +129,14 @@ typedef struct ALIGN(8) z_bytes_t { uint8_t _0[40]; } z_bytes_t; typedef int8_t z_error_t; -typedef struct z_owned_slice_t { - const uint8_t *start; - size_t len; +/** + * A contiguous view of bytes owned by some other entity. + * + * `start` being `null` is considered a gravestone value, + * and empty slices are represented using a possibly dangling pointer for `start`. + */ +typedef struct ALIGN(8) z_owned_slice_t { + uint8_t _0[16]; } z_owned_slice_t; /** * A map of maybe-owned vector of bytes to maybe-owned vector of bytes. @@ -146,22 +151,18 @@ typedef struct ALIGN(8) z_owned_slice_map_t { * should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with * `z_check` and `z_str_check` correspondently */ -typedef struct z_owned_str_t { - char *_cstr; +typedef struct ALIGN(8) z_owned_str_t { + uint8_t _0[16]; } z_owned_str_t; -/** - * A contiguous view of bytes owned by some other entity. - * - * `start` being `null` is considered a gravestone value, - * and empty slices are represented using a possibly dangling pointer for `start`. - */ -typedef struct z_slice_t { - const uint8_t *start; - size_t len; +typedef struct ALIGN(8) z_slice_t { + uint8_t _0[16]; } z_slice_t; typedef struct ALIGN(8) z_slice_map_t { uint8_t _0[48]; } z_slice_map_t; +typedef struct ALIGN(8) z_str_t { + uint8_t _0[16]; +} z_str_t; /** * A reader for payload data. */ @@ -545,6 +546,12 @@ typedef struct z_hello_t { struct z_id_t pid; struct z_str_array_t locators; } z_hello_t; +typedef struct ALIGN(8) z_view_slice_t { + uint8_t _0[16]; +} z_view_slice_t; +typedef struct ALIGN(8) z_view_keyexpr_t { + uint8_t _0[32]; +} z_view_keyexpr_t; typedef struct ALIGN(8) z_owned_mutex_t { uint8_t _0[32]; } z_owned_mutex_t; @@ -705,6 +712,9 @@ typedef struct z_task_attr_t { typedef struct z_time_t { uint64_t t; } z_time_t; +typedef struct ALIGN(8) z_view_str_t { + uint8_t _0[16]; +} z_view_str_t; /** * The options for `zc_liveliness_declare_token` */ @@ -913,7 +923,7 @@ void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, /** * Encodes a null-terminated string by aliasing. */ -ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const char *cstr); +ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const struct z_str_t *s); /** * Returns total number bytes in the payload. */ @@ -1328,25 +1338,12 @@ z_error_t z_info_routers_zid(struct z_session_t session, * to pass it a valid session. */ ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); -/** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API z_error_t z_keyexpr(struct z_keyexpr_t *this_, const char *name); /** * Returns the key expression's internal string by aliasing it. * * Currently exclusive to zenoh-c */ -ZENOHC_API struct z_slice_t z_keyexpr_as_bytes(const struct z_keyexpr_t *ke); -/** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. - * The string is canonized in-place before being passed to keyexpr. - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -z_error_t z_keyexpr_autocanonize(struct z_keyexpr_t *this_, - char *name); +ZENOHC_API void z_keyexpr_as_bytes(const struct z_keyexpr_t *ke, struct z_view_slice_t *b); /** * Canonizes the passed string in place, possibly shortening it by modifying `len`. * @@ -1453,7 +1450,7 @@ enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_keyexpr * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. * The user is responsible of droping the returned string using `z_drop` */ -ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(const struct z_keyexpr_t *ke); +ZENOHC_API void z_keyexpr_to_string(const struct z_keyexpr_t *ke, struct z_owned_str_t *s); /** * Constructs a :c:type:`z_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: * @@ -1467,7 +1464,7 @@ ZENOHC_API struct z_owned_str_t z_keyexpr_to_string(const struct z_keyexpr_t *ke * It is a loaned key expression that aliases `name`. */ ZENOHC_API -void z_keyexpr_unchecked(struct z_keyexpr_t *this_, +void z_keyexpr_unchecked(struct z_view_keyexpr_t *this_, const char *name); ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); @@ -1484,6 +1481,10 @@ ZENOHC_API z_error_t z_mutex_unlock(struct z_mutex_t this_); ZENOHC_API z_error_t z_open(struct z_owned_session_t *this_, struct z_owned_config_t *config); +/** + * Returns ``true`` if `this` is initialized. + */ +ZENOHC_API bool z_owned_slice_check(const struct z_owned_slice_t *this_); /** * Returns ``true`` if `pub` is valid. */ @@ -1665,7 +1666,8 @@ ZENOHC_API void z_query_null(struct z_owned_query_t *this_); * Get a query's `value selector `_ by aliasing it. */ ZENOHC_API -struct z_slice_t z_query_parameters(const struct z_query_t *query); +void z_query_parameters(const struct z_query_t *query, + struct z_view_slice_t *parameters); /** * Send a reply to a query. * @@ -1873,30 +1875,26 @@ ZENOHC_API void z_session_null(struct z_owned_session_t *this_); ZENOHC_API int8_t z_sleep_ms(size_t time); ZENOHC_API int8_t z_sleep_s(size_t time); ZENOHC_API int8_t z_sleep_us(size_t time); -/** - * Returns ``true`` if `b` is initialized. - */ -ZENOHC_API bool z_slice_check(const struct z_owned_slice_t *b); -ZENOHC_API void z_slice_clone(struct z_owned_slice_t *this_, const struct z_slice_t *s); +ZENOHC_API void z_slice_clone(const struct z_slice_t *this_, struct z_owned_slice_t *dst); +ZENOHC_API const uint8_t *z_slice_data(const struct z_slice_t *this_); /** * Frees `this` and invalidates it for double-drop safety. */ ZENOHC_API void z_slice_drop(struct z_owned_slice_t *this_); /** - * Returns the gravestone value for `z_slice_t` + * Returns an empty `z_owned_slice_t` */ -ZENOHC_API struct z_slice_t z_slice_empty(void); +ZENOHC_API void z_slice_empty(struct z_owned_slice_t *this_); /** - * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * Copies a string into `z_owned_slice_t` using `strlen` (this should therefore not be used with untrusted inputs). * - * `str == NULL` will cause this to return `z_slice_empty()` + * Calling this with `str == NULL` is equivalent to `z_slice_null`. */ -ZENOHC_API struct z_slice_t z_slice_from_str(const char *str); -/** - * Returns ``true`` if `b` is initialized. - */ -ZENOHC_API bool z_slice_is_initialized(const struct z_slice_t *this_); -ZENOHC_API struct z_slice_t z_slice_loan(const struct z_owned_slice_t *b); +ZENOHC_API +void z_slice_from_str(struct z_owned_slice_t *this_, + const char *str); +ZENOHC_API size_t z_slice_len(const struct z_slice_t *this_); +ZENOHC_API const struct z_slice_t *z_slice_loan(const struct z_owned_slice_t *this_); /** * Returns `true` if the map is not in its gravestone state */ @@ -1908,18 +1906,19 @@ ZENOHC_API bool z_slice_map_check(const struct z_owned_slice_map_t *map); */ ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); /** - * Returns the value associated with `key`, returning a gravestone value if: - * - `key` is in gravestone state. + * Returns the value associated with `key`. + * + * Will return NULL if the key is not present in the map. */ ZENOHC_API -struct z_slice_t z_slice_map_get(const struct z_slice_map_t *this_, - const struct z_slice_t *key); +const struct z_slice_t *z_slice_map_get(const struct z_slice_map_t *this_, + const struct z_slice_t *key); /** * Associates `value` to `key` in the map, aliasing them. * * Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. * - * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. + * Returns 1 if there was already an entry associated with the key, 0 otherwise. */ ZENOHC_API z_error_t z_slice_map_insert_by_alias(struct z_slice_map_t *this_, @@ -1928,12 +1927,12 @@ z_error_t z_slice_map_insert_by_alias(struct z_slice_map_t *this_, /** * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. * - * Returns 0 in case of success, -1 if one of the arguments were in gravestone state. + * Returns 1 if there was already an entry associated with the key, 0 otherwise. */ ZENOHC_API -z_error_t z_slice_map_insert_by_copy(struct z_slice_map_t *this_, - const struct z_slice_t *key, - const struct z_slice_t *value); +uint8_t z_slice_map_insert_by_copy(struct z_slice_map_t *this_, + const struct z_slice_t *key, + const struct z_slice_t *value); /** * Returns true if the map is empty, false otherwise. */ @@ -1956,14 +1955,11 @@ ZENOHC_API void z_slice_map_new(struct z_owned_slice_map_t *this_); * Constructs the gravestone value for `z_owned_slice_map_t` */ ZENOHC_API void z_slice_map_null(struct z_owned_slice_map_t *this_); -/** - * Returns the gravestone value for `z_owned_slice_t` - */ ZENOHC_API void z_slice_null(struct z_owned_slice_t *this_); /** * Constructs a `len` bytes long view starting at `start`. */ -ZENOHC_API struct z_slice_t z_slice_wrap(uint8_t *start, size_t len); +ZENOHC_API void z_slice_wrap(struct z_owned_slice_t *this_, const uint8_t *start, size_t len); /** * Returns ``true`` if `strs` is valid. */ @@ -1979,19 +1975,35 @@ ZENOHC_API const struct z_str_array_t *z_str_array_loan(const struct z_owned_str /** * Returns ``true`` if `s` is a valid string */ -ZENOHC_API bool z_str_check(const struct z_owned_str_t *s); +ZENOHC_API bool z_str_check(const struct z_owned_str_t *this_); +ZENOHC_API void z_str_clone(const struct z_str_t *this_, struct z_owned_str_t *dst); /** * Frees `z_owned_str_t`, invalidating it for double-drop safety. */ -ZENOHC_API void z_str_drop(struct z_owned_str_t *s); +ZENOHC_API void z_str_drop(struct z_owned_str_t *this_); +ZENOHC_API void z_str_empty(struct z_owned_str_t *this_); +/** + * Copies a a substring of length `len`into `z_owned_str_t`. + * + * Calling this with `str == NULL` is equivalent to `z_str_null`. + */ +ZENOHC_API void z_str_from_substring(struct z_owned_str_t *this_, const char *str, size_t len); /** * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. */ -ZENOHC_API const char *z_str_loan(const struct z_owned_str_t *s); +ZENOHC_API const struct z_str_t *z_str_loan(const struct z_owned_str_t *this_); /** * Returns undefined `z_owned_str_t` */ ZENOHC_API void z_str_null(struct z_owned_str_t *this_); +/** + * Copies a string into `z_owned_str_t` using `strlen` (this should therefore not be used with untrusted inputs). + * + * Calling this with `str == NULL` is equivalent to `z_str_null`. + */ +ZENOHC_API +void z_str_wrap(struct z_owned_slice_t *this_, + const char *str); /** * Returns ``true`` if `sub` is valid. */ @@ -2058,6 +2070,95 @@ ZENOHC_API z_error_t z_undeclare_queryable(struct z_owned_queryable_t *qable); */ ZENOHC_API z_error_t z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); +/** + * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API z_error_t z_view_keyexpr(struct z_view_keyexpr_t *this_, const char *name); +/** + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + * The string is canonized in-place before being passed to keyexpr. + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +z_error_t z_view_keyexpr_autocanonize(struct z_view_keyexpr_t *this_, + char *name); +/** + * Returns ``true`` if `keyexpr` is valid. + */ +ZENOHC_API bool z_view_keyexpr_check(const struct z_view_keyexpr_t *keyexpr); +/** + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + */ +ZENOHC_API +z_error_t z_view_keyexpr_from_slice(struct z_view_keyexpr_t *this_, + const char *name, + size_t len); +/** + * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + * The string is canonized in-place before being passed to keyexpr. + * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). + */ +ZENOHC_API +z_error_t z_view_keyexpr_from_slice_autocanonize(struct z_view_keyexpr_t *this_, + char *name, + size_t *len); +/** + * Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * - `name` MUST be valid UTF8. + * - `name` MUST follow the Key Expression specification, ie: + * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. + * - any instance of ``**`` may only be lead or followed by ``/``. + * - the key expression must have canon form. + * + * It is a loaned key expression that aliases `name`. + */ +ZENOHC_API +void z_view_keyexpr_from_slice_unchecked(struct z_view_keyexpr_t *this_, + const char *start, + size_t len); +/** + * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + */ +ZENOHC_API const struct z_keyexpr_t *z_view_keyexpr_loan(const struct z_view_keyexpr_t *key_expr); +ZENOHC_API void z_view_keyexpr_null(struct z_view_keyexpr_t *this_); +/** + * Returns ``true`` if `this` is initialized. + */ +ZENOHC_API bool z_view_slice_check(const struct z_view_slice_t *this_); +/** + * Returns an empty `z_view_slice_t` + */ +ZENOHC_API void z_view_slice_empty(struct z_view_slice_t *this_); +/** + * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * Calling this with `str == NULL` is equivalent to `z_view_slice_null`. + */ +ZENOHC_API void z_view_slice_from_str(struct z_view_slice_t *this_, const char *str); +ZENOHC_API const struct z_slice_t *z_view_slice_loan(const struct z_view_slice_t *this_); +ZENOHC_API void z_view_slice_null(struct z_view_slice_t *this_); +/** + * Constructs a `len` bytes long view starting at `start`. + */ +ZENOHC_API void z_view_slice_wrap(struct z_view_slice_t *this_, const uint8_t *start, size_t len); +ZENOHC_API const char *z_view_str_data(const struct z_str_t *this_); +ZENOHC_API void z_view_str_empty(struct z_view_str_t *this_); +ZENOHC_API size_t z_view_str_len(const struct z_str_t *this_); +/** + * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_view_str_t`. + */ +ZENOHC_API const struct z_str_t *z_view_str_loan(const struct z_view_str_t *this_); +/** + * Returns undefined `z_owned_str_t` + */ +ZENOHC_API void z_view_str_null(struct z_view_str_t *this_); +/** + * Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). + * + * Calling this with `str == NULL` is equivalent to `z_view_str_null`. + */ +ZENOHC_API void z_view_str_wrap(struct z_view_slice_t *this_, const char *str); /** * Converts the kind of zenoh entity into a string. * @@ -2089,8 +2190,9 @@ z_error_t zc_config_from_str(struct z_owned_config_t *this_, * Use `z_drop` to safely deallocate this string */ ZENOHC_API -struct z_owned_str_t zc_config_get(struct z_config_t config, - const char *key); +z_error_t zc_config_get(struct z_config_t config, + const char *key, + struct z_owned_str_t *value_string); /** * Inserts a JSON-serialized `value` at the `key` position of the configuration. * @@ -2104,7 +2206,8 @@ z_error_t zc_config_insert_json(const struct z_config_t *config, * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. */ ZENOHC_API -struct z_owned_str_t zc_config_to_string(const struct z_config_t *config); +z_error_t zc_config_to_string(const struct z_config_t *config, + struct z_owned_str_t *config_string); /** * Initialises the zenoh runtime logger. * @@ -2112,33 +2215,6 @@ struct z_owned_str_t zc_config_to_string(const struct z_config_t *config); * this will be performed automatically by `z_open` and `z_scout`. */ ZENOHC_API void zc_init_logger(void); -/** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. - */ -ZENOHC_API z_error_t zc_keyexpr_from_slice(struct z_keyexpr_t *this_, const char *name, size_t len); -/** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. - * The string is canonized in-place before being passed to keyexpr. - * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). - */ -ZENOHC_API -z_error_t zc_keyexpr_from_slice_autocanonize(struct z_keyexpr_t *this_, - char *name, - size_t *len); -/** - * Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: - * - `name` MUST be valid UTF8. - * - `name` MUST follow the Key Expression specification, ie: - * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. - * - any instance of ``**`` may only be lead or followed by ``/``. - * - the key expression must have canon form. - * - * It is a loaned key expression that aliases `name`. - */ -ZENOHC_API -void zc_keyexpr_from_slice_unchecked(struct z_keyexpr_t *this_, - const char *start, - size_t len); ZENOHC_API void zc_liveliness_declaration_options_default(struct zc_liveliness_declaration_options_t *this_); /** diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index 03f29535b..a7cc575ab 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -78,6 +78,7 @@ typedef struct ALIGN(8) z_owned_subscriber_t { #define Z_EIO -3 #define Z_ENETWORK -4 #define Z_ENULL -5 +#define Z_EUNAVAILABLE -6 #define Z_EBUSY_MUTEX -16 #define Z_EINVAL_MUTEX -22 #define Z_EAGAIN_MUTEX -11 diff --git a/src/collections.rs b/src/collections.rs index f24d7d075..e8c9039ee 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -16,136 +16,108 @@ use std::borrow::Cow; use std::collections::HashMap; use std::mem::MaybeUninit; use std::ptr::{null, null_mut}; +use std::slice::from_raw_parts; -use libc::{c_char, c_void, size_t}; +use libc::{c_char, c_void, size_t, strlen}; use zenoh::prelude::ZenohId; -use crate::errors; +use crate::{errors, transmute, z_owned_bytes_t}; use crate::transmute::{ unwrap_ref_unchecked, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; -/// A contiguous view of bytes owned by some other entity. -/// -/// `start` being `null` is considered a gravestone value, -/// and empty slices are represented using a possibly dangling pointer for `start`. -#[repr(C)] -#[derive(Clone, Copy, Debug)] -pub struct z_slice_t { - pub start: *const u8, - pub len: size_t, -} - -impl z_slice_t { - pub fn as_slice(&self) -> Option<&'static [u8]> { - if self.start.is_null() { - return None; - } - Some(unsafe { core::slice::from_raw_parts(self.start, self.len) }) - } - pub fn empty() -> Self { - z_slice_t { - start: std::ptr::null_mut(), - len: 0, - } - } -} +pub use crate::opaque_types::z_owned_slice_t; +pub use crate::opaque_types::z_view_slice_t; +pub use crate::opaque_types::z_slice_t; -impl Default for z_slice_t { - fn default() -> Self { - Self::empty() - } -} +decl_transmute_owned!(Option>, z_owned_slice_t); +decl_transmute_owned!(Option<&'static [u8]>, z_view_slice_t); +decl_transmute_handle!(&'static [u8], z_slice_t); -#[repr(C)] -#[derive(Clone, Debug)] -pub struct z_owned_slice_t { - pub start: *const u8, - pub len: size_t, +/// Returns an empty `z_view_slice_t` +#[no_mangle] +pub unsafe extern "C" fn z_view_slice_empty(this: *mut MaybeUninit) { + let slice: &'static [u8] = &[]; + Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } -impl Drop for z_owned_slice_t { - fn drop(&mut self) { - unsafe { z_slice_drop(self) } - } +#[no_mangle] +pub unsafe extern "C" fn z_view_slice_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); } -impl z_owned_slice_t { - pub fn null() -> z_owned_slice_t { - z_owned_slice_t { - start: null(), - len: 0 - } - } - pub fn new(data: &[u8]) -> z_owned_slice_t { - if data.is_empty() { - return Self::null(); - } - let data = data.to_vec().into_boxed_slice(); - z_owned_slice_t { - len: data.len(), - start: Box::leak(data).as_mut_ptr(), - } - } - - pub fn preallocate(len: usize) -> z_owned_slice_t { - let data = vec![0u8; len].into_boxed_slice(); - z_owned_slice_t { - len, - start: Box::leak(data).as_mut_ptr(), - } +/// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). +/// +/// Calling this with `str == NULL` is equivalent to `z_view_slice_null`. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_view_slice_from_str(this: *mut MaybeUninit, str: *const c_char) { + if str.is_null() { + z_view_slice_null(this) + } else { + z_view_slice_wrap(this, str as *const u8, libc::strlen(str)) } +} - #[allow(clippy::missing_safety_doc)] - pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { - std::ptr::copy_nonoverlapping(value.as_ptr(), self.start.add(start) as *mut u8, value.len()); +/// Constructs a `len` bytes long view starting at `start`. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_view_slice_wrap(this: *mut MaybeUninit, start: *const u8, len: usize) { + if len == 0 { + z_view_slice_empty(this) + } else if start.is_null() { + z_view_slice_null(this) + } else { + let slice: &'static [u8] = from_raw_parts(start, len).into(); + Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } } -impl Default for z_owned_slice_t { - fn default() -> Self { - Self::null() +#[no_mangle] +pub const extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> *const z_slice_t { + match this.transmute_ref() { + Some(s) => s.transmute_handle(), + None => null(), } } -/// Returns ``true`` if `b` is initialized. +/// Returns an empty `z_owned_slice_t` #[no_mangle] -pub extern "C" fn z_slice_is_initialized(this: &z_slice_t) -> bool { - !this.start.is_null() +pub unsafe extern "C" fn z_slice_empty(this: *mut MaybeUninit) { + let slice = Box::new([]); + Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } -/// Returns the gravestone value for `z_slice_t` #[no_mangle] -pub const extern "C" fn z_slice_empty() -> z_slice_t { - z_slice_t::empty() +pub extern "C" fn z_slice_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); } -/// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). +/// Copies a string into `z_owned_slice_t` using `strlen` (this should therefore not be used with untrusted inputs). /// -/// `str == NULL` will cause this to return `z_slice_empty()` +/// Calling this with `str == NULL` is equivalent to `z_slice_null`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_from_str(str: *const c_char) -> z_slice_t { +pub unsafe extern "C" fn z_slice_from_str(this: *mut MaybeUninit, str: *const c_char) { if str.is_null() { - z_slice_empty() + z_slice_null(this) } else { - let len = unsafe { libc::strlen(str) }; - z_slice_t { - len, - start: str.cast_mut() as *mut u8, - } + z_slice_wrap(this, str as *const u8, libc::strlen(str)) } } /// Constructs a `len` bytes long view starting at `start`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_wrap(start: *mut u8, len: usize) -> z_slice_t { - if start.is_null() { - z_slice_empty() +pub unsafe extern "C" fn z_slice_wrap(this: *mut MaybeUninit, start: *const u8, len: usize) { + if len == 0 { + z_slice_empty(this) + } else if start.is_null() { + z_slice_null(this) } else { - z_slice_t { len, start } + let slice = from_raw_parts(start, len).to_owned().into_boxed_slice(); + Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } } @@ -153,182 +125,146 @@ pub unsafe extern "C" fn z_slice_wrap(start: *mut u8, len: usize) -> z_slice_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { - if !this.start.is_null() { - std::mem::drop(Box::from_raw( - core::ptr::slice_from_raw_parts(this.start, this.len).cast_mut(), - )); - this.start = std::ptr::null_mut(); - this.len = 0; - } + let this = this.transmute_mut(); + Inplace::drop(this); } -/// Returns the gravestone value for `z_owned_slice_t` #[no_mangle] -pub unsafe extern "C" fn z_slice_null(this: *mut MaybeUninit) { - (*this).as_mut_ptr().write(z_owned_slice_t { - len: 0, - start: core::ptr::null_mut(), - }); +pub const extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_slice_t { + match this.transmute_ref() { + Some(s) => (&&*s.as_ref()) as *const &[u8] as *const z_slice_t, + None => null(), + } } #[no_mangle] -pub const extern "C" fn z_slice_loan(b: &z_owned_slice_t) -> z_slice_t { - z_slice_t { - len: b.len, - start: b.start, - } +pub unsafe extern "C" fn z_slice_clone(this: &z_slice_t, dst: *mut MaybeUninit) { + let slice = this.transmute_ref().to_vec().into_boxed_slice(); + Inplace::init(dst.transmute_uninit_ptr(), Some(slice)); } +/// Returns ``true`` if `this` is initialized. #[no_mangle] -pub unsafe extern "C" fn z_slice_clone(this: *mut MaybeUninit, s: &z_slice_t) { - if !z_slice_is_initialized(s) { - z_slice_null(this); - } else { - (*this).as_mut_ptr().write(z_owned_slice_t::new(unsafe { std::slice::from_raw_parts(s.start, s.len) })); - } +pub extern "C" fn z_owned_slice_check(this: &z_owned_slice_t) -> bool { + this.transmute_ref().is_some() } -/// Returns ``true`` if `b` is initialized. +/// Returns ``true`` if `this` is initialized. #[no_mangle] -pub extern "C" fn z_slice_check(b: &z_owned_slice_t) -> bool { - !b.start.is_null() +pub extern "C" fn z_view_slice_check(this: &z_view_slice_t) -> bool { + this.transmute_ref().is_some() } -impl From for z_slice_t { - #[inline] - fn from(pid: ZenohId) -> Self { - let pid = pid.to_le_bytes().to_vec().into_boxed_slice(); - let res = z_slice_t { - start: pid.as_ptr(), - len: pid.len() as size_t, - }; - std::mem::forget(pid); - res - } +#[no_mangle] +pub extern "C" fn z_slice_len(this: &z_slice_t) -> usize { + this.transmute_ref().len() } -impl From> for z_slice_t { - #[inline] - fn from(pid: Option) -> Self { - match pid { - Some(pid) => pid.into(), - None => z_slice_t { - start: std::ptr::null(), - len: 0, - }, - } - } +#[no_mangle] +pub extern "C" fn z_slice_data(this: &z_slice_t) -> *const u8 { + this.transmute_ref().as_ptr() } -impl From for String { - fn from(s: z_slice_t) -> Self { - unsafe { - String::from_utf8( - Box::from_raw(std::slice::from_raw_parts_mut(s.start as *mut u8, s.len)).into(), - ) - .unwrap() - } - } + +pub use crate::opaque_types::z_owned_str_t; +pub use crate::opaque_types::z_view_str_t; +pub use crate::opaque_types::z_str_t; + +decl_transmute_owned!(custom_inplace_init Option>, z_owned_str_t); +decl_transmute_owned!(custom_inplace_init Option<&'static [u8]>, z_view_str_t); +decl_transmute_handle!(&'static [u8], z_str_t); + + +/// Frees `z_owned_str_t`, invalidating it for double-drop safety. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_str_drop(this: &mut z_owned_str_t) { + z_slice_drop(this.transmute_mut().transmute_mut()); } -impl From<&[u8]> for z_slice_t { - fn from(s: &[u8]) -> Self { - z_slice_t { - start: s.as_ptr(), - len: s.len(), - } - } +/// Returns ``true`` if `s` is a valid string +#[no_mangle] +pub extern "C" fn z_str_check(this: &z_owned_str_t) -> bool { + z_owned_slice_check(this.transmute_ref().transmute_ref()) } -impl InplaceDefault for z_owned_slice_t {} +/// Returns undefined `z_owned_str_t` +#[no_mangle] +pub extern "C" fn z_str_null(this: *mut MaybeUninit) { + z_slice_null(this as *mut _) +} -/// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` -/// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with -/// `z_check` and `z_str_check` correspondently -#[repr(C)] -pub struct z_owned_str_t { - pub _cstr: *mut libc::c_char, +/// Returns undefined `z_owned_str_t` +#[no_mangle] +pub extern "C" fn z_view_str_null(this: *mut MaybeUninit) { + z_slice_null(this as *mut _) } -impl z_owned_str_t { - pub fn null() -> z_owned_str_t { - z_owned_str_t { - _cstr: null_mut() - } - } - #[allow(clippy::missing_safety_doc)] - pub unsafe fn preallocate(len: usize) -> z_owned_str_t { - let cstr = libc::malloc(len + 1) as *mut libc::c_char; - *cstr.add(len) = 0; - z_owned_str_t { _cstr: cstr } - } +#[no_mangle] +pub unsafe extern "C" fn z_str_empty(this: *mut MaybeUninit) { + z_slice_wrap(this as *mut _, [0u8].as_ptr(), 1) +} - #[allow(clippy::missing_safety_doc)] - pub unsafe fn insert_unchecked(&mut self, start: usize, value: &[u8]) { - std::ptr::copy_nonoverlapping( - value.as_ptr(), - (self._cstr as *mut u8).add(start), - value.len(), - ); - } +#[no_mangle] +pub unsafe extern "C" fn z_view_str_empty(this: *mut MaybeUninit) { + z_view_slice_wrap(this as *mut _, [0u8].as_ptr(), 1) } -impl From<&[u8]> for z_owned_str_t { - fn from(value: &[u8]) -> Self { - unsafe { - let mut cstr = Self::preallocate(value.len()); - cstr.insert_unchecked(0, value); - cstr - } - } +/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. +#[no_mangle] +pub extern "C" fn z_str_loan(this: &z_owned_str_t) -> *const z_str_t { + z_slice_loan(this.transmute_ref().transmute_ref()) as _ } -impl Drop for z_owned_str_t { - fn drop(&mut self) { - unsafe { z_str_drop(self) } - } +/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_view_str_t`. +#[no_mangle] +pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> *const z_str_t { + z_view_slice_loan(this.transmute_ref().transmute_ref()) as _ } -impl Default for z_owned_str_t { - fn default() -> Self { - Self::null() - } + +/// Copies a string into `z_owned_str_t` using `strlen` (this should therefore not be used with untrusted inputs). +/// +/// Calling this with `str == NULL` is equivalent to `z_str_null`. +#[no_mangle] +pub unsafe extern "C" fn z_str_wrap(this: *mut MaybeUninit, str: *const libc::c_char) { + z_slice_wrap(this as *mut _, str as _, strlen(str) + 1) } -/// Frees `z_owned_str_t`, invalidating it for double-drop safety. +/// Copies a a substring of length `len`into `z_owned_str_t`. +/// +/// Calling this with `str == NULL` is equivalent to `z_str_null`. #[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_str_drop(s: &mut z_owned_str_t) { - if s._cstr.is_null() { - return; - } - libc::free(std::mem::transmute(s._cstr)); - s._cstr = std::ptr::null_mut(); +pub unsafe extern "C" fn z_str_from_substring(this: *mut MaybeUninit, str: *const libc::c_char, len: usize) { + let mut v = vec![0u8; len + 1]; + v[0..len].copy_from_slice(from_raw_parts(str as *const u8, len)); + let b = v.into_boxed_slice(); + Inplace::init(this.transmute_uninit_ptr(), Some(b)); } -/// Returns ``true`` if `s` is a valid string +/// Returns a view of `str` using `strlen` (this should therefore not be used with untrusted inputs). +/// +/// Calling this with `str == NULL` is equivalent to `z_view_str_null`. #[no_mangle] -pub extern "C" fn z_str_check(s: &z_owned_str_t) -> bool { - !s._cstr.is_null() +pub unsafe extern "C" fn z_view_str_wrap(this: *mut MaybeUninit, str: *const libc::c_char) { + z_view_slice_wrap(this as *mut _, str as _, strlen(str) + 1) } -/// Returns undefined `z_owned_str_t` #[no_mangle] -pub unsafe extern "C" fn z_str_null(this: *mut MaybeUninit) { - (*this).as_mut_ptr().write( - z_owned_str_t { - _cstr: std::ptr::null_mut(), - } - ); +pub extern "C" fn z_view_str_len(this: &z_str_t) -> usize { + z_slice_len(this.transmute_ref().transmute_handle()) - 1 } -/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. #[no_mangle] -pub extern "C" fn z_str_loan(s: &z_owned_str_t) -> *const libc::c_char { - s._cstr +pub extern "C" fn z_view_str_data(this: &z_str_t) -> *const libc::c_char { + z_slice_data(&this.transmute_ref().transmute_handle()) as _ } -impl InplaceDefault for z_owned_str_t {} +#[no_mangle] +pub extern "C" fn z_str_clone(this: &z_str_t, dst: *mut MaybeUninit) { + let slice = this.transmute_ref().to_vec().into_boxed_slice(); + Inplace::init(dst.transmute_uninit_ptr(), Some(slice)); +} pub use crate::opaque_types::z_owned_slice_map_t; pub use crate::opaque_types::z_slice_map_t; @@ -421,43 +357,42 @@ pub extern "C" fn z_slice_map_iterate( ) { let this = this.transmute_ref(); for (key, value) in this { - let key_slice = key.as_ref().into(); - let value_slice = value.as_ref().into(); - if !body(&key_slice, &value_slice, context) { + let key_slice = key.as_ref(); + let value_slice = value.as_ref(); + if !body(key_slice.transmute_handle(), value_slice.transmute_handle(), context) { break; } } } -/// Returns the value associated with `key`, returning a gravestone value if: -/// - `key` is in gravestone state. +/// Returns the value associated with `key`. +/// +/// Will return NULL if the key is not present in the map. #[no_mangle] -pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> z_slice_t { - if !z_slice_is_initialized(&key) { - return z_slice_empty(); - } +pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> *const z_slice_t { let m = this.transmute_ref(); - let key = key.as_slice().unwrap(); - m.get(key) - .map(|s| s.as_ref().into()) - .unwrap_or(z_slice_empty()) + let key = *key.transmute_ref(); + let k = Cow::Borrowed(key); + m.get(&k) + .map(|s| s.as_ref().transmute_handle() as *const _) + .unwrap_or(null()) } /// Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. -/// -/// Returns 0 in case of success, -1 if one of the arguments were in gravestone state. +/// +/// Returns 1 if there was already an entry associated with the key, 0 otherwise. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_copy( this: &mut z_slice_map_t, key: &z_slice_t, value: &z_slice_t, -) -> errors::z_error_t { +) -> u8 { let this = this.transmute_mut(); - if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { - this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())); - errors::Z_OK - } else { - errors::Z_EINVAL + let key = *key.transmute_ref(); + let value = *value.transmute_ref(); + match this.insert(Cow::Owned(key.to_owned()), Cow::Owned(value.to_owned())) { + Some(_) => 1, + None => 0, } } @@ -465,7 +400,7 @@ pub extern "C" fn z_slice_map_insert_by_copy( /// /// Note that once `key` is aliased, reinserting at the same key may alias the previous instance, or the new instance of `key`. /// -/// Returns 0 in case of success, -1 if one of the arguments were in gravestone state. +/// Returns 1 if there was already an entry associated with the key, 0 otherwise. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_alias( this: &mut z_slice_map_t, @@ -473,10 +408,10 @@ pub extern "C" fn z_slice_map_insert_by_alias( value: &z_slice_t, ) -> errors::z_error_t { let this = this.transmute_mut(); - if let (Some(key), Some(value)) = (key.as_slice(), value.as_slice()) { - this.insert(Cow::Borrowed(key), Cow::Borrowed(value)); - errors::Z_OK - } else { - errors::Z_EINVAL + let key = key.transmute_ref(); + let value = value.transmute_ref(); + match this.insert(Cow::Borrowed(key), Cow::Borrowed(value)) { + Some(_) => 1, + None => 0, } } diff --git a/src/config.rs b/src/config.rs index a837136ec..73ac24b02 100644 --- a/src/config.rs +++ b/src/config.rs @@ -21,7 +21,7 @@ use crate::transmute::{ unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; -use crate::{errors, z_owned_str_t}; +use crate::{errors, z_owned_str_t, z_str_from_substring, z_str_null}; #[no_mangle] pub static Z_ROUTER: c_uint = WhatAmI::Router as c_uint; @@ -114,16 +114,25 @@ pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit z_owned_str_t { +pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char, value_string: *mut MaybeUninit) -> errors::z_error_t { let config = config.transmute_ref(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, - Err(_) => return z_owned_str_t::null(), + Err(_) => { + z_str_null(value_string); + return errors::Z_EINVAL; + } }; let val = config.get_json(key).ok(); match val { - Some(val) => val.as_bytes().into(), - None => z_owned_str_t::null(), + Some(val) => { + z_str_from_substring(value_string, val.as_ptr() as *const libc::c_char, val.len()); + errors::Z_OK + } + None => { + z_str_null(value_string); + errors::Z_EUNAVAILABLE + } } } @@ -189,11 +198,17 @@ pub unsafe extern "C" fn zc_config_from_str( /// Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn zc_config_to_string(config: &z_config_t) -> z_owned_str_t { +pub extern "C" fn zc_config_to_string(config: &z_config_t, config_string: *mut MaybeUninit) -> errors::z_error_t { let config: &Config = config.transmute_ref(); match json5::to_string(config) { - Ok(s) => s.as_bytes().into(), - Err(_) => z_owned_str_t::null(), + Ok(s) => { + unsafe { z_str_from_substring(config_string, s.as_ptr() as *const libc::c_char, s.len()) }; + errors::Z_OK + } + Err(_) => { + z_str_null(config_string); + errors::Z_EPARSE + }, } } diff --git a/src/errors.rs b/src/errors.rs index cf494f4e0..c2abfbff4 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -5,6 +5,7 @@ pub const Z_EPARSE: z_error_t = -2; pub const Z_EIO: z_error_t = -3; pub const Z_ENETWORK: z_error_t = -4; pub const Z_ENULL: z_error_t = -5; +pub const Z_EUNAVAILABLE: z_error_t = -6; // negativ pthread error codes (due to convention to return negative values on error) pub const Z_EBUSY_MUTEX: z_error_t = -16; pub const Z_EINVAL_MUTEX: z_error_t = -22; diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 4f07fd624..a930b8cc6 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -23,9 +23,14 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; +use crate::z_owned_slice_t; use crate::z_owned_str_t; use crate::z_session_t; use crate::z_slice_t; +use crate::z_str_from_substring; +use crate::z_view_slice_from_str; +use crate::z_view_slice_t; +use crate::z_view_slice_wrap; use libc::c_char; use std::error::Error; use zenoh::core::SyncResolve; @@ -34,15 +39,21 @@ use zenoh::prelude::keyexpr; use zenoh::prelude::KeyExpr; pub use crate::opaque_types::z_owned_keyexpr_t; +pub use crate::opaque_types::z_view_keyexpr_t; decl_transmute_owned!(Option>, z_owned_keyexpr_t); +decl_transmute_owned!(custom_inplace_init Option>, z_view_keyexpr_t); /// Constructs a null safe-to-drop value of 'z_owned_keyexpr_t' type #[no_mangle] -#[allow(clippy::missing_safety_doc)] pub extern "C" fn z_keyexpr_null(this: *mut MaybeUninit) { Inplace::empty(this.transmute_uninit_ptr()); } +#[no_mangle] +pub extern "C" fn z_view_keyexpr_null(this: *mut MaybeUninit) { + Inplace::empty(this.transmute_uninit_ptr()); +} + fn keyexpr_create_inner( mut name: &'static mut str, should_auto_canonize: bool, @@ -91,11 +102,12 @@ pub unsafe extern "C" fn z_keyexpr_new( name: *const c_char, this: *mut MaybeUninit, ) -> errors::z_error_t { + let this = this.transmute_uninit_ptr(); if name.is_null() { + Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); - let this = this.transmute_uninit_ptr(); match keyexpr_create(name, false, true) { Ok(ke) => { Inplace::init(this, Some(ke)); @@ -115,11 +127,12 @@ pub unsafe extern "C" fn z_keyexpr_new_autocanonize( name: *const c_char, this: *mut MaybeUninit, ) -> z_error_t { + let this = this.transmute_uninit_ptr(); if name.is_null() { + Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); - let this = this.transmute_uninit_ptr(); match keyexpr_create(name, true, true) { Ok(ke) => { Inplace::init(this, Some(ke)); @@ -138,20 +151,30 @@ pub extern "C" fn z_keyexpr_loan(key_expr: &z_owned_keyexpr_t) -> &z_keyexpr_t { unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() } +/// Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. +#[no_mangle] +pub extern "C" fn z_view_keyexpr_loan(key_expr: &z_view_keyexpr_t) -> &z_keyexpr_t { + unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() +} + /// Frees `keyexpr` and invalidates it for double-drop safety. #[no_mangle] -#[allow(clippy::missing_safety_doc)] pub extern "C" fn z_keyexpr_drop(keyexpr: &mut z_owned_keyexpr_t) { Inplace::drop(keyexpr.transmute_mut()); } /// Returns ``true`` if `keyexpr` is valid. #[no_mangle] -#[allow(clippy::missing_safety_doc)] pub extern "C" fn z_keyexpr_check(keyexpr: &z_owned_keyexpr_t) -> bool { keyexpr.transmute_ref().is_some() } +/// Returns ``true`` if `keyexpr` is valid. +#[no_mangle] +pub extern "C" fn z_view_keyexpr_check(keyexpr: &z_view_keyexpr_t) -> bool { + keyexpr.transmute_ref().is_some() +} + /// A loaned key expression. /// /// Key expressions can identify a single key or a set of keys. @@ -219,21 +242,24 @@ pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) /// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn zc_keyexpr_from_slice( - this: *mut MaybeUninit, +pub unsafe extern "C" fn z_view_keyexpr_from_slice( + this: *mut MaybeUninit, name: *const c_char, len: usize, ) -> z_error_t { + let this = this.transmute_uninit_ptr(); if name.is_null() { + Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, len); match keyexpr_create(name, false, false) { Ok(ke) => { - (*this).write(std::mem::transmute(ke)); + Inplace::init(this, Some(ke)); errors::Z_OK } Err(e) => { + Inplace::empty(this); e } } @@ -244,12 +270,14 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice( /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( - this: *mut MaybeUninit, +pub unsafe extern "C" fn z_view_keyexpr_from_slice_autocanonize( + this: *mut MaybeUninit, name: *mut c_char, len: &mut usize, ) -> z_error_t { + let this = this.transmute_uninit_ptr(); if name.is_null() { + Inplace::empty(this); return errors::Z_EINVAL; } let name = std::slice::from_raw_parts_mut(name as _, libc::strlen(name)); @@ -257,10 +285,11 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( match keyexpr_create(name, true, false) { Ok(ke) => { *len = ke.len(); - (*this).write(std::mem::transmute(ke)); + Inplace::init(this, Some(ke)); errors::Z_OK } Err(e) => { + Inplace::empty(this); e } } @@ -270,15 +299,16 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_autocanonize( /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr( - this: *mut MaybeUninit, +pub unsafe extern "C" fn z_view_keyexpr( + this: *mut MaybeUninit, name: *const c_char, ) -> z_error_t { if name.is_null() { + Inplace::empty(this.transmute_uninit_ptr()); errors::Z_EINVAL } else { let len = libc::strlen(name); - zc_keyexpr_from_slice(this, name, len) + z_view_keyexpr_from_slice(this, name, len) } } @@ -287,15 +317,16 @@ pub unsafe extern "C" fn z_keyexpr( /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_autocanonize( - this: *mut MaybeUninit, +pub unsafe extern "C" fn z_view_keyexpr_autocanonize( + this: *mut MaybeUninit, name: *mut c_char, ) -> z_error_t { if name.is_null() { + Inplace::empty(this.transmute_uninit_ptr()); errors::Z_EINVAL } else { let mut len = libc::strlen(name); - let res = zc_keyexpr_from_slice_autocanonize(this, name, &mut len); + let res = z_view_keyexpr_from_slice_autocanonize(this, name, &mut len); if res == errors::Z_OK { *name.add(len) = 0; } @@ -313,15 +344,15 @@ pub unsafe extern "C" fn z_keyexpr_autocanonize( /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( - this: *mut MaybeUninit, +pub unsafe extern "C" fn z_view_keyexpr_from_slice_unchecked( + this: *mut MaybeUninit, start: *const c_char, len: usize, ) { let name = std::slice::from_raw_parts(start as _, len); let name = std::str::from_utf8_unchecked(name); let name: KeyExpr = keyexpr::from_str_unchecked(name).into(); - (*this).write(std::mem::transmute(name)); + Inplace::init(this.transmute_uninit_ptr(), Some(name)) } /// Constructs a :c:type:`z_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: @@ -337,18 +368,19 @@ pub unsafe extern "C" fn zc_keyexpr_from_slice_unchecked( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_keyexpr_unchecked( - this: *mut MaybeUninit, + this: *mut MaybeUninit, name: *const c_char, ) { - zc_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) + z_view_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) } /// Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. /// The user is responsible of droping the returned string using `z_drop` #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t) -> z_owned_str_t { - ke.transmute_ref().as_bytes().into() +pub extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t, s: *mut MaybeUninit) { + let ke = ke.transmute_ref(); + unsafe { z_str_from_substring(s, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) } ; } /// Returns the key expression's internal string by aliasing it. @@ -356,12 +388,9 @@ pub unsafe extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t) -> z_owned_str_t /// Currently exclusive to zenoh-c #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t) -> z_slice_t { +pub extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t, b: *mut MaybeUninit) { let ke = ke.transmute_ref(); - z_slice_t { - start: ke.as_ptr(), - len: ke.len(), - } + unsafe { z_view_slice_wrap(b, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) } ; } /**************************************/ diff --git a/src/payload.rs b/src/payload.rs index 7f3556b27..59a09ad9f 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -4,9 +4,9 @@ use crate::transmute::{ TransmuteUninitPtr, }; use crate::{ - z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, ZHashMap, + z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, z_str_t, ZHashMap }; -use core::slice; +use core::{fmt, slice}; use std::any::Any; use std::io::{Read, Seek, SeekFrom}; use std::mem::MaybeUninit; @@ -73,18 +73,25 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( dst: *mut MaybeUninit, ) -> z_error_t { let len = z_bytes_len(payload); - let cstr = z_owned_str_t::preallocate(len); let payload = payload.transmute_ref(); + let mut out = vec![0u8; len + 1]; if let Err(e) = payload .reader() - .read(from_raw_parts_mut(cstr._cstr as *mut u8, len)) + .read(out.as_mut_slice()) { log::error!("Failed to read the payload: {}", e); - Inplace::empty(dst); + Inplace::empty(dst.transmute_uninit_ptr()); errors::Z_EIO } else { - Inplace::init(dst, cstr); - errors::Z_OK + if let Err(e) = std::str::from_utf8(out.as_slice()) { + log::error!("Payload is not a valid utf-8 string: {}", e); + Inplace::empty(dst.transmute_uninit_ptr()); + errors::Z_EPARSE + } else { + let b = out.into_boxed_slice(); + Inplace::init(dst.transmute_uninit_ptr(), Some(b)); + errors::Z_OK + } } } @@ -113,25 +120,34 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes( payload: &z_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { - let len = z_bytes_len(payload); - let b = z_owned_slice_t::preallocate(len); let payload = payload.transmute_ref(); - if let Err(e) = payload.reader().read(from_raw_parts_mut(b.start as *mut _, len)) { - log::error!("Failed to read the payload: {}", e); - Inplace::empty(dst); - errors::Z_EIO - } else { - Inplace::init(dst, b); - errors::Z_OK + match payload.deserialize::>() { + Ok(v) => { + let b = v.into_boxed_slice(); + Inplace::init(dst.transmute_uninit_ptr(), Some(b)); + errors::Z_OK + }, + Err(e) => { + log::error!("Failed to read the payload: {}", e); + Inplace::empty(dst.transmute_uninit_ptr()); + errors::Z_EIO + } } } unsafe impl Send for z_slice_t {} unsafe impl Sync for z_slice_t {} +impl fmt::Debug for z_slice_t { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let s = self.transmute_ref(); + f.debug_struct("z_slice_t").field("_0", s).finish() + } +} + impl ZSliceBuffer for z_slice_t { fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(self.start, self.len) } + self.transmute_ref() } fn as_any(&self) -> &dyn Any { self @@ -172,13 +188,12 @@ pub unsafe extern "C" fn z_bytes_encode_from_bytes_map( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_string( this: *mut MaybeUninit, - cstr: *const libc::c_char, + s: &z_str_t, ) { - let bytes = z_slice_t { - start: cstr as *const u8, - len: libc::strlen(cstr), - }; - z_bytes_encode_from_bytes(this, &bytes); + let s = s.transmute_ref(); + let ss = &s[0..s.len() - 1]; + let b = ss.transmute_handle(); + z_bytes_encode_from_bytes(this, &b); } pub use crate::opaque_types::z_owned_bytes_reader_t; diff --git a/src/queryable.rs b/src/queryable.rs index e27178983..e34927b40 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -17,7 +17,7 @@ use crate::transmute::{ }; use crate::{ errors, z_bytes_t, z_closure_query_call, z_keyexpr_t, z_owned_bytes_t, z_owned_closure_query_t, - z_owned_encoding_t, z_session_t, z_slice_t, z_value_t, + z_owned_encoding_t, z_session_t, z_slice_t, z_value_t, z_view_slice_t, z_view_slice_wrap, }; use std::mem::MaybeUninit; use std::ptr::{null, null_mut}; @@ -255,13 +255,10 @@ pub extern "C" fn z_query_keyexpr(query: &z_query_t) -> &z_keyexpr_t { /// Get a query's `value selector `_ by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_parameters(query: &z_query_t) -> z_slice_t { +pub extern "C" fn z_query_parameters(query: &z_query_t, parameters: *mut MaybeUninit) { let query = query.transmute_ref(); let params = query.parameters().as_str(); - z_slice_t { - start: params.as_ptr(), - len: params.len(), - } + unsafe { z_view_slice_wrap(parameters, params.as_ptr(), params.len()) }; } /// Checks if query contains a payload value. From 923c6f0ba6d3b2c4f65953a4a1121e90e6576844 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Thu, 25 Apr 2024 18:49:18 +0200 Subject: [PATCH 67/75] builds --- build-resources/opaque-types/src/lib.rs | 6 ++-- include/zenoh_commons.h | 40 ++++++++++++++----------- src/collections.rs | 9 +++--- src/config.rs | 15 +++++++--- src/keyexpr.rs | 12 ++++++-- src/payload.rs | 16 ++++++---- src/platform/synchronization.rs | 32 ++++++++++++-------- src/publication_cache.rs | 10 +++---- src/transmute.rs | 2 +- 9 files changed, 86 insertions(+), 56 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 4aba1525b..7797578d5 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -263,13 +263,13 @@ get_opaque_type_data!(LivelinessToken<'static>, zc_liveliness_token_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, ze_owned_publication_cache_t); -get_opaque_type_data!(&'static zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); +get_opaque_type_data!(zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); get_opaque_type_data!(Option<(Mutex<()>, Option>)>, z_owned_mutex_t); -get_opaque_type_data!(&'static (Mutex<()>, Option>), z_mutex_t); +get_opaque_type_data!((Mutex<()>, Option>), z_mutex_t); get_opaque_type_data!(Option, z_owned_condvar_t); -get_opaque_type_data!(&'static Condvar, z_condvar_t); +get_opaque_type_data!(Condvar, z_condvar_t); get_opaque_type_data!(Option>, z_owned_task_t); \ No newline at end of file diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 7a3f071e8..3944d26e1 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -364,10 +364,10 @@ typedef struct ALIGN(8) z_owned_condvar_t { uint8_t _0[24]; } z_owned_condvar_t; typedef struct ALIGN(8) z_condvar_t { - uint8_t _0[8]; + uint8_t _0[16]; } z_condvar_t; typedef struct ALIGN(8) z_mutex_t { - uint8_t _0[8]; + uint8_t _0[32]; } z_mutex_t; /** * An owned zenoh configuration. @@ -940,6 +940,7 @@ ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_reader_t *this_) ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_reader_t *this_); ZENOHC_API const struct z_bytes_reader_t *z_bytes_reader_loan(const struct z_owned_bytes_reader_t *reader); +ZENOHC_API struct z_bytes_reader_t *z_bytes_reader_loan_mut(struct z_owned_bytes_reader_t *reader); /** * Creates a reader for the specified `payload`. * @@ -954,7 +955,7 @@ ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_reader_t *this_); * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. */ ZENOHC_API -size_t z_bytes_reader_read(const struct z_bytes_reader_t *this_, +size_t z_bytes_reader_read(struct z_bytes_reader_t *this_, uint8_t *dest, size_t len); /** @@ -964,14 +965,14 @@ size_t z_bytes_reader_read(const struct z_bytes_reader_t *this_, * Return ​0​ upon success, negative error code otherwise. */ ZENOHC_API -z_error_t z_bytes_reader_seek(const struct z_bytes_reader_t *this_, +z_error_t z_bytes_reader_seek(struct z_bytes_reader_t *this_, int64_t offset, int origin); /** * Returns the read position indicator. * Returns read position indicator on success or -1L if failure occurs. */ -ZENOHC_API int64_t z_bytes_reader_tell(const struct z_bytes_reader_t *this_); +ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t *this_); ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); @@ -1070,10 +1071,11 @@ ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); ZENOHC_API bool z_condvar_check(const struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); -ZENOHC_API struct z_condvar_t z_condvar_loan(const struct z_owned_condvar_t *this_); +ZENOHC_API const struct z_condvar_t *z_condvar_loan(const struct z_owned_condvar_t *this_); +ZENOHC_API struct z_condvar_t *z_condvar_loan_mut(struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_null(struct z_owned_condvar_t *this_); -ZENOHC_API z_error_t z_condvar_signal(struct z_condvar_t this_); -ZENOHC_API z_error_t z_condvar_wait(struct z_condvar_t this_, struct z_mutex_t m); +ZENOHC_API z_error_t z_condvar_signal(const struct z_condvar_t *this_); +ZENOHC_API z_error_t z_condvar_wait(const struct z_condvar_t *this_, struct z_mutex_t *m); /** * Returns ``true`` if `config` is valid. */ @@ -1112,6 +1114,10 @@ ZENOHC_API void z_config_drop(struct z_owned_config_t *config); * Returns a :c:type:`z_config_t` loaned from `s`. */ ZENOHC_API const struct z_config_t *z_config_loan(const struct z_owned_config_t *this_); +/** + * Returns a :c:type:`z_config_t` loaned from `s`. + */ +ZENOHC_API struct z_config_t *z_config_loan_mut(struct z_owned_config_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_config_t' type */ @@ -1469,11 +1475,11 @@ void z_keyexpr_unchecked(struct z_view_keyexpr_t *this_, ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); ZENOHC_API z_error_t z_mutex_init(struct z_owned_mutex_t *this_); -ZENOHC_API struct z_mutex_t z_mutex_loan(const struct z_owned_mutex_t *this_); -ZENOHC_API z_error_t z_mutex_lock(struct z_mutex_t this_); +ZENOHC_API struct z_mutex_t *z_mutex_loan_mut(struct z_owned_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_lock(struct z_mutex_t *this_); ZENOHC_API void z_mutex_null(struct z_owned_mutex_t *this_); -ZENOHC_API z_error_t z_mutex_try_lock(struct z_mutex_t this_); -ZENOHC_API z_error_t z_mutex_unlock(struct z_mutex_t this_); +ZENOHC_API z_error_t z_mutex_try_lock(struct z_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_unlock(struct z_mutex_t *this_); /** * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. * Config value is always consumed upon function return. @@ -2190,7 +2196,7 @@ z_error_t zc_config_from_str(struct z_owned_config_t *this_, * Use `z_drop` to safely deallocate this string */ ZENOHC_API -z_error_t zc_config_get(struct z_config_t config, +z_error_t zc_config_get(const struct z_config_t *config, const char *key, struct z_owned_str_t *value_string); /** @@ -2199,7 +2205,7 @@ z_error_t zc_config_get(struct z_config_t config, * Returns 0 if successful, a negative value otherwise. */ ZENOHC_API -z_error_t zc_config_insert_json(const struct z_config_t *config, +z_error_t zc_config_insert_json(struct z_config_t *config, const char *key, const char *value); /** @@ -2403,8 +2409,8 @@ ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); */ ZENOHC_API z_error_t ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, - struct z_session_t session, - struct z_keyexpr_t key_expr, + const struct z_session_t *session, + const struct z_keyexpr_t *key_expr, struct ze_publication_cache_options_t *options); /** * Declares a Querying Subscriber for a given key expression. @@ -2456,7 +2462,7 @@ ZENOHC_API void ze_publication_cache_null(struct ze_owned_publication_cache_t *t /** * Constructs the default value for :c:type:`ze_publication_cache_options_t`. */ -ZENOHC_API struct ze_publication_cache_options_t ze_publication_cache_options_default(void); +ZENOHC_API void ze_publication_cache_options_default(struct ze_publication_cache_options_t *this_); /** * Returns ``true`` if `this` is valid. */ diff --git a/src/collections.rs b/src/collections.rs index e8c9039ee..ef47a8393 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -23,8 +23,7 @@ use zenoh::prelude::ZenohId; use crate::{errors, transmute, z_owned_bytes_t}; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, - TransmuteRef, TransmuteUninitPtr, + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }; pub use crate::opaque_types::z_owned_slice_t; @@ -75,7 +74,7 @@ pub unsafe extern "C" fn z_view_slice_wrap(this: *mut MaybeUninit *const z_slice_t { +pub extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> *const z_slice_t { match this.transmute_ref() { Some(s) => s.transmute_handle(), None => null(), @@ -130,7 +129,7 @@ pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { } #[no_mangle] -pub const extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_slice_t { +pub extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_slice_t { match this.transmute_ref() { Some(s) => (&&*s.as_ref()) as *const &[u8] as *const z_slice_t, None => null(), @@ -323,7 +322,7 @@ pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> &z_slice_map_t #[no_mangle] pub extern "C" fn z_slice_map_loan_mut(this: &mut z_owned_slice_map_t) -> &mut z_slice_map_t { let this = this.transmute_mut(); - let this = unwrap_ref_unchecked(this); + let this = unwrap_ref_unchecked_mut(this); this.transmute_handle_mut() } diff --git a/src/config.rs b/src/config.rs index 73ac24b02..77ef6bfd9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -18,8 +18,7 @@ use zenoh::config::{Config, ValidatedMap, WhatAmI}; use crate::errors::z_error_t; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, - TransmuteUninitPtr, + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }; use crate::{errors, z_owned_str_t, z_str_from_substring, z_str_null}; @@ -77,6 +76,14 @@ pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> &z_config_t this.transmute_handle() } +/// Returns a :c:type:`z_config_t` loaned from `s`. +#[no_mangle] +pub extern "C" fn z_config_loan_mut(this: &mut z_owned_config_t) -> &mut z_config_t { + let this = this.transmute_mut(); + let this = unwrap_ref_unchecked_mut(this); + this.transmute_handle_mut() +} + /// Return a new, zenoh-allocated, empty configuration. /// /// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. @@ -114,7 +121,7 @@ pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit) -> errors::z_error_t { +pub unsafe extern "C" fn zc_config_get(config: &z_config_t, key: *const c_char, value_string: *mut MaybeUninit) -> errors::z_error_t { let config = config.transmute_ref(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, @@ -142,7 +149,7 @@ pub unsafe extern "C" fn zc_config_get(config: z_config_t, key: *const c_char, v #[no_mangle] #[allow(clippy::missing_safety_doc, unused_must_use)] pub unsafe extern "C" fn zc_config_insert_json( - config: &z_config_t, + config: &mut z_config_t, key: *const c_char, value: *const c_char, ) -> errors::z_error_t { diff --git a/src/keyexpr.rs b/src/keyexpr.rs index a930b8cc6..fee889892 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -55,19 +55,25 @@ pub extern "C" fn z_view_keyexpr_null(this: *mut MaybeUninit) } fn keyexpr_create_inner( - mut name: &'static mut str, + name: &'static mut str, should_auto_canonize: bool, should_copy: bool, ) -> Result, Box> { if should_copy { - let s = name.to_owned(); + let s = name.to_string(); match should_auto_canonize { true => KeyExpr::<'static>::autocanonize(s), false => KeyExpr::<'static>::try_from(s), } } else { match should_auto_canonize { - true => keyexpr::autocanonize(&mut name).map(|k| k.into()), + true => { + // hack to fix issue with autocanonize requiring &&str instead of &str + // to be removed after this issue is resolved on zenoh-rust side + let n = &name as *const &'static mut str as *mut &'static mut str; + let n = unsafe { &mut *n }; + keyexpr::autocanonize(n).map(|k| k.into()) + }, false => keyexpr::new(name).map(|k| k.into()) } } diff --git a/src/payload.rs b/src/payload.rs index 59a09ad9f..96ef100ca 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,7 +1,6 @@ use crate::errors::{self, z_error_t}; use crate::transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, - TransmuteUninitPtr, + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }; use crate::{ z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, z_str_t, ZHashMap @@ -243,6 +242,13 @@ extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_bytes_r reader.transmute_handle() } +#[no_mangle] +extern "C" fn z_bytes_reader_loan_mut(reader: &mut z_owned_bytes_reader_t) -> &mut z_bytes_reader_t { + let reader = reader.transmute_mut(); + let reader = unwrap_ref_unchecked_mut(reader); + reader.transmute_handle_mut() +} + /// Reads data into specified destination. /// /// Will read at most `len` bytes. @@ -250,7 +256,7 @@ extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_bytes_r #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_read( - this: &z_bytes_reader_t, + this: &mut z_bytes_reader_t, dest: *mut u8, len: usize, ) -> usize { @@ -266,7 +272,7 @@ pub unsafe extern "C" fn z_bytes_reader_read( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_seek( - this: &z_bytes_reader_t, + this: &mut z_bytes_reader_t, offset: i64, origin: libc::c_int, ) -> z_error_t { @@ -289,7 +295,7 @@ pub unsafe extern "C" fn z_bytes_reader_seek( /// Returns read position indicator on success or -1L if failure occurs. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_tell(this: &z_bytes_reader_t) -> i64 { +pub unsafe extern "C" fn z_bytes_reader_tell(this: &mut z_bytes_reader_t) -> i64 { let reader = this.transmute_mut(); reader.stream_position().map(|p| p as i64).unwrap_or(-1) } diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index cd1c016e3..aa00c3090 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -11,8 +11,7 @@ pub use crate::opaque_types::z_owned_mutex_t; use crate::{ errors, transmute::{ - unwrap_ref_unchecked, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, - TransmuteUninitPtr, + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr }, }; @@ -46,14 +45,14 @@ pub extern "C" fn z_mutex_null(this: *mut MaybeUninit) { } #[no_mangle] -pub extern "C" fn z_mutex_loan(this: &z_owned_mutex_t) -> z_mutex_t { - let this = this.transmute_ref(); - let this = unwrap_ref_unchecked(this); - this.transmute_handle() +pub extern "C" fn z_mutex_loan_mut(this: &mut z_owned_mutex_t) -> &mut z_mutex_t { + let this = this.transmute_mut(); + let this = unwrap_ref_unchecked_mut(this); + this.transmute_handle_mut() } #[no_mangle] -pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::z_error_t { +pub extern "C" fn z_mutex_lock(this: &mut z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.lock() { @@ -69,7 +68,7 @@ pub extern "C" fn z_mutex_lock(this: z_mutex_t) -> errors::z_error_t { } #[no_mangle] -pub extern "C" fn z_mutex_unlock(this: z_mutex_t) -> errors::z_error_t { +pub extern "C" fn z_mutex_unlock(this: &mut z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); if this.1.is_none() { return errors::Z_EINVAL_MUTEX; @@ -81,7 +80,7 @@ pub extern "C" fn z_mutex_unlock(this: z_mutex_t) -> errors::z_error_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_try_lock(this: z_mutex_t) -> errors::z_error_t { +pub unsafe extern "C" fn z_mutex_try_lock(this: &mut z_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.try_lock() { Ok(new_lock) => { @@ -124,23 +123,30 @@ pub extern "C" fn z_condvar_check(this: &z_owned_condvar_t) -> bool { } #[no_mangle] -pub extern "C" fn z_condvar_loan(this: &z_owned_condvar_t) -> z_condvar_t { +pub extern "C" fn z_condvar_loan(this: &z_owned_condvar_t) -> &z_condvar_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() } #[no_mangle] -pub extern "C" fn z_condvar_signal(this: z_condvar_t) -> errors::z_error_t { +pub extern "C" fn z_condvar_loan_mut(this: &mut z_owned_condvar_t) -> &mut z_condvar_t { let this = this.transmute_mut(); + let this = unwrap_ref_unchecked_mut(this); + this.transmute_handle_mut() +} + +#[no_mangle] +pub extern "C" fn z_condvar_signal(this: &z_condvar_t) -> errors::z_error_t { + let this = this.transmute_ref(); this.notify_one(); errors::Z_OK } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_wait(this: z_condvar_t, m: z_mutex_t) -> errors::z_error_t { - let this = this.transmute_mut(); +pub unsafe extern "C" fn z_condvar_wait(this: &z_condvar_t, m: &mut z_mutex_t) -> errors::z_error_t { + let this = this.transmute_ref(); let m = m.transmute_mut(); if m.1.is_none() { return errors::Z_EINVAL_MUTEX; // lock was not aquired prior to wait call diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 7f8f9e9e6..84278e3d8 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -41,14 +41,14 @@ pub struct ze_publication_cache_options_t { /// Constructs the default value for :c:type:`ze_publication_cache_options_t`. #[no_mangle] -pub extern "C" fn ze_publication_cache_options_default() -> ze_publication_cache_options_t { - ze_publication_cache_options_t { +pub extern "C" fn ze_publication_cache_options_default(this: &mut ze_publication_cache_options_t) { + *this = ze_publication_cache_options_t { queryable_prefix: null(), queryable_origin: zcu_locality_default(), queryable_complete: false, history: 1, resources_limit: 0, - } + }; } pub use crate::opaque_types::ze_owned_publication_cache_t; @@ -87,8 +87,8 @@ decl_transmute_handle!(zenoh_ext::PublicationCache<'static>, ze_publication_cach #[allow(clippy::missing_safety_doc)] pub extern "C" fn ze_declare_publication_cache( this: *mut MaybeUninit, - session: z_session_t, - key_expr: z_keyexpr_t, + session: &z_session_t, + key_expr: &z_keyexpr_t, options: Option<&mut ze_publication_cache_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); diff --git a/src/transmute.rs b/src/transmute.rs index b5d88a6dc..92fb45f45 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -165,7 +165,7 @@ macro_rules! decl_transmute_copy { #[macro_export] macro_rules! decl_transmute_handle { ($zenoh_type:ty, $c_type:ty) => { - validate_equivalence!(&'static $zenoh_type, $c_type); + validate_equivalence!($zenoh_type, $c_type); impl_transmute_handle!($c_type, $zenoh_type); }; } From 6842d59feef28f1d7d11cda9efc1f53a2b2f604f Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 26 Apr 2024 09:45:41 +0200 Subject: [PATCH 68/75] fmt and clippy --- build.rs | 4 +- src/collections.rs | 93 ++++++++++++++++++++++----------- src/commons.rs | 5 +- src/config.rs | 28 ++++++---- src/get.rs | 2 +- src/keyexpr.rs | 31 +++++------ src/liveliness.rs | 9 ++-- src/payload.rs | 41 +++++++-------- src/platform/synchronization.rs | 8 ++- src/put.rs | 6 +-- src/queryable.rs | 7 ++- src/querying_subscriber.rs | 4 +- src/scouting.rs | 2 +- src/session.rs | 2 +- src/transmute.rs | 2 +- 15 files changed, 141 insertions(+), 103 deletions(-) diff --git a/build.rs b/build.rs index 01fc61a4a..72fd1ab4c 100644 --- a/build.rs +++ b/build.rs @@ -85,9 +85,7 @@ fn produce_opaque_types_data() -> PathBuf { } fn generate_opaque_types() { - let type_to_inner_field_name = HashMap::from([ - ("z_id_t", "id"), - ]); + let type_to_inner_field_name = HashMap::from([("z_id_t", "id")]); let current_folder = get_build_rs_path(); let path_in = produce_opaque_types_data(); let path_out = current_folder.join("./src/opaque_types/mod.rs"); diff --git a/src/collections.rs b/src/collections.rs index ef47a8393..0add96fff 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -15,20 +15,20 @@ use std::borrow::Cow; use std::collections::HashMap; use std::mem::MaybeUninit; -use std::ptr::{null, null_mut}; +use std::ptr::null; use std::slice::from_raw_parts; -use libc::{c_char, c_void, size_t, strlen}; -use zenoh::prelude::ZenohId; +use libc::{c_char, c_void, strlen}; -use crate::{errors, transmute, z_owned_bytes_t}; +use crate::errors; use crate::transmute::{ - unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, InplaceDefault, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, + TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; pub use crate::opaque_types::z_owned_slice_t; -pub use crate::opaque_types::z_view_slice_t; pub use crate::opaque_types::z_slice_t; +pub use crate::opaque_types::z_view_slice_t; decl_transmute_owned!(Option>, z_owned_slice_t); decl_transmute_owned!(Option<&'static [u8]>, z_view_slice_t); @@ -36,13 +36,13 @@ decl_transmute_handle!(&'static [u8], z_slice_t); /// Returns an empty `z_view_slice_t` #[no_mangle] -pub unsafe extern "C" fn z_view_slice_empty(this: *mut MaybeUninit) { +pub extern "C" fn z_view_slice_empty(this: *mut MaybeUninit) { let slice: &'static [u8] = &[]; Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } #[no_mangle] -pub unsafe extern "C" fn z_view_slice_null(this: *mut MaybeUninit) { +pub extern "C" fn z_view_slice_null(this: *mut MaybeUninit) { Inplace::empty(this.transmute_uninit_ptr()); } @@ -51,7 +51,10 @@ pub unsafe extern "C" fn z_view_slice_null(this: *mut MaybeUninit, str: *const c_char) { +pub unsafe extern "C" fn z_view_slice_from_str( + this: *mut MaybeUninit, + str: *const c_char, +) { if str.is_null() { z_view_slice_null(this) } else { @@ -62,13 +65,17 @@ pub unsafe extern "C" fn z_view_slice_from_str(this: *mut MaybeUninit, start: *const u8, len: usize) { +pub unsafe extern "C" fn z_view_slice_wrap( + this: *mut MaybeUninit, + start: *const u8, + len: usize, +) { if len == 0 { z_view_slice_empty(this) } else if start.is_null() { z_view_slice_null(this) } else { - let slice: &'static [u8] = from_raw_parts(start, len).into(); + let slice: &'static [u8] = from_raw_parts(start, len); Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } } @@ -83,7 +90,7 @@ pub extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> *const z_slice_t { /// Returns an empty `z_owned_slice_t` #[no_mangle] -pub unsafe extern "C" fn z_slice_empty(this: *mut MaybeUninit) { +pub extern "C" fn z_slice_empty(this: *mut MaybeUninit) { let slice = Box::new([]); Inplace::init(this.transmute_uninit_ptr(), Some(slice)) } @@ -98,7 +105,10 @@ pub extern "C" fn z_slice_null(this: *mut MaybeUninit) { /// Calling this with `str == NULL` is equivalent to `z_slice_null`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_from_str(this: *mut MaybeUninit, str: *const c_char) { +pub unsafe extern "C" fn z_slice_from_str( + this: *mut MaybeUninit, + str: *const c_char, +) { if str.is_null() { z_slice_null(this) } else { @@ -109,7 +119,11 @@ pub unsafe extern "C" fn z_slice_from_str(this: *mut MaybeUninit, start: *const u8, len: usize) { +pub unsafe extern "C" fn z_slice_wrap( + this: *mut MaybeUninit, + start: *const u8, + len: usize, +) { if len == 0 { z_slice_empty(this) } else if start.is_null() { @@ -131,14 +145,14 @@ pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { #[no_mangle] pub extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_slice_t { match this.transmute_ref() { - Some(s) => (&&*s.as_ref()) as *const &[u8] as *const z_slice_t, + Some(s) => (&s.as_ref()) as *const &[u8] as *const z_slice_t, None => null(), } } #[no_mangle] -pub unsafe extern "C" fn z_slice_clone(this: &z_slice_t, dst: *mut MaybeUninit) { - let slice = this.transmute_ref().to_vec().into_boxed_slice(); +pub extern "C" fn z_slice_clone(this: &z_slice_t, dst: *mut MaybeUninit) { + let slice = this.transmute_ref().to_vec().into_boxed_slice(); Inplace::init(dst.transmute_uninit_ptr(), Some(slice)); } @@ -164,16 +178,14 @@ pub extern "C" fn z_slice_data(this: &z_slice_t) -> *const u8 { this.transmute_ref().as_ptr() } - pub use crate::opaque_types::z_owned_str_t; -pub use crate::opaque_types::z_view_str_t; pub use crate::opaque_types::z_str_t; +pub use crate::opaque_types::z_view_str_t; decl_transmute_owned!(custom_inplace_init Option>, z_owned_str_t); decl_transmute_owned!(custom_inplace_init Option<&'static [u8]>, z_view_str_t); decl_transmute_handle!(&'static [u8], z_str_t); - /// Frees `z_owned_str_t`, invalidating it for double-drop safety. #[no_mangle] #[allow(clippy::missing_safety_doc)] @@ -200,11 +212,13 @@ pub extern "C" fn z_view_str_null(this: *mut MaybeUninit) { } #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_str_empty(this: *mut MaybeUninit) { z_slice_wrap(this as *mut _, [0u8].as_ptr(), 1) } #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_view_str_empty(this: *mut MaybeUninit) { z_view_slice_wrap(this as *mut _, [0u8].as_ptr(), 1) } @@ -221,20 +235,28 @@ pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> *const z_str_t { z_view_slice_loan(this.transmute_ref().transmute_ref()) as _ } - /// Copies a string into `z_owned_str_t` using `strlen` (this should therefore not be used with untrusted inputs). /// /// Calling this with `str == NULL` is equivalent to `z_str_null`. #[no_mangle] -pub unsafe extern "C" fn z_str_wrap(this: *mut MaybeUninit, str: *const libc::c_char) { - z_slice_wrap(this as *mut _, str as _, strlen(str) + 1) +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_str_wrap( + this: *mut MaybeUninit, + str: *const libc::c_char, +) { + z_slice_wrap(this as *mut _, str as _, strlen(str) + 1) } /// Copies a a substring of length `len`into `z_owned_str_t`. /// /// Calling this with `str == NULL` is equivalent to `z_str_null`. #[no_mangle] -pub unsafe extern "C" fn z_str_from_substring(this: *mut MaybeUninit, str: *const libc::c_char, len: usize) { +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_str_from_substring( + this: *mut MaybeUninit, + str: *const libc::c_char, + len: usize, +) { let mut v = vec![0u8; len + 1]; v[0..len].copy_from_slice(from_raw_parts(str as *const u8, len)); let b = v.into_boxed_slice(); @@ -245,8 +267,12 @@ pub unsafe extern "C" fn z_str_from_substring(this: *mut MaybeUninit, str: *const libc::c_char) { - z_view_slice_wrap(this as *mut _, str as _, strlen(str) + 1) +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_view_str_wrap( + this: *mut MaybeUninit, + str: *const libc::c_char, +) { + z_view_slice_wrap(this as *mut _, str as _, strlen(str) + 1) } #[no_mangle] @@ -255,8 +281,9 @@ pub extern "C" fn z_view_str_len(this: &z_str_t) -> usize { } #[no_mangle] +#[allow(clippy::missing_safety_doc)] pub extern "C" fn z_view_str_data(this: &z_str_t) -> *const libc::c_char { - z_slice_data(&this.transmute_ref().transmute_handle()) as _ + z_slice_data(this.transmute_ref().transmute_handle()) as _ } #[no_mangle] @@ -358,14 +385,18 @@ pub extern "C" fn z_slice_map_iterate( for (key, value) in this { let key_slice = key.as_ref(); let value_slice = value.as_ref(); - if !body(key_slice.transmute_handle(), value_slice.transmute_handle(), context) { + if !body( + key_slice.transmute_handle(), + value_slice.transmute_handle(), + context, + ) { break; } } } -/// Returns the value associated with `key`. -/// +/// Returns the value associated with `key`. +/// /// Will return NULL if the key is not present in the map. #[no_mangle] pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> *const z_slice_t { @@ -378,7 +409,7 @@ pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> *con } /// Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. -/// +/// /// Returns 1 if there was already an entry associated with the key, 0 otherwise. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_copy( diff --git a/src/commons.rs b/src/commons.rs index 27eaafec8..86f5bad69 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -137,7 +137,6 @@ pub extern "C" fn z_sample_timestamp( /// The qos with which the sample was received. /// TODO: split to methods (priority, congestion_control, express) - /// Gets sample's attachment. /// /// Returns NULL if sample does not contain an attachement. @@ -148,7 +147,6 @@ pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> *const z_bytes_t { Some(attachment) => attachment.transmute_handle() as *const _, None => null(), } - } pub use crate::opaque_types::zc_owned_sample_t; @@ -163,7 +161,6 @@ pub extern "C" fn z_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit z_priority_t { let sample = sample.transmute_ref(); @@ -196,7 +193,7 @@ pub extern "C" fn z_sample_check(sample: &zc_owned_sample_t) -> bool { /// /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] -pub extern "C" fn zc_sample_loan(sample: & zc_owned_sample_t) -> &z_sample_t { +pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> &z_sample_t { unwrap_ref_unchecked(sample.transmute_ref()).transmute_handle() } diff --git a/src/config.rs b/src/config.rs index 77ef6bfd9..9e207bbbe 100644 --- a/src/config.rs +++ b/src/config.rs @@ -18,7 +18,8 @@ use zenoh::config::{Config, ValidatedMap, WhatAmI}; use crate::errors::z_error_t; use crate::transmute::{ - unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, + TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; use crate::{errors, z_owned_str_t, z_str_from_substring, z_str_null}; @@ -121,7 +122,11 @@ pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit) -> errors::z_error_t { +pub unsafe extern "C" fn zc_config_get( + config: &z_config_t, + key: *const c_char, + value_string: *mut MaybeUninit, +) -> errors::z_error_t { let config = config.transmute_ref(); let key = match CStr::from_ptr(key).to_str() { Ok(s) => s, @@ -192,8 +197,7 @@ pub unsafe extern "C" fn zc_config_from_str( res = errors::Z_EINVAL; } else { let conf_str = CStr::from_ptr(s); - let props: Option = json5::from_str(&conf_str.to_string_lossy()) - .ok(); + let props: Option = json5::from_str(&conf_str.to_string_lossy()).ok(); if props.is_none() { res = errors::Z_EPARSE; } @@ -205,17 +209,22 @@ pub unsafe extern "C" fn zc_config_from_str( /// Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn zc_config_to_string(config: &z_config_t, config_string: *mut MaybeUninit) -> errors::z_error_t { +pub unsafe extern "C" fn zc_config_to_string( + config: &z_config_t, + config_string: *mut MaybeUninit, +) -> errors::z_error_t { let config: &Config = config.transmute_ref(); match json5::to_string(config) { Ok(s) => { - unsafe { z_str_from_substring(config_string, s.as_ptr() as *const libc::c_char, s.len()) }; + unsafe { + z_str_from_substring(config_string, s.as_ptr() as *const libc::c_char, s.len()) + }; errors::Z_OK } Err(_) => { z_str_null(config_string); errors::Z_EPARSE - }, + } } } @@ -251,10 +260,7 @@ pub unsafe extern "C" fn zc_config_from_file( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_config_peer(this: *mut MaybeUninit) { - Inplace::init( - this.transmute_uninit_ptr(), - Some(zenoh::config::peer()), - ); + Inplace::init(this.transmute_uninit_ptr(), Some(zenoh::config::peer())); } /// Constructs a default, zenoh-allocated, client mode configuration. diff --git a/src/get.rs b/src/get.rs index cba2370d1..3586e50a2 100644 --- a/src/get.rs +++ b/src/get.rs @@ -71,7 +71,7 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_reply_t) -> *const z_sample_t { /// Returns null if reply does not contain a error (i. e. if :c:func:`z_reply_is_ok` returns ``true``). #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_err(reply: &z_reply_t) -> *const z_value_t{ +pub unsafe extern "C" fn z_reply_err(reply: &z_reply_t) -> *const z_value_t { let reply = reply.transmute_ref(); match reply.result() { Ok(_) => null(), diff --git a/src/keyexpr.rs b/src/keyexpr.rs index fee889892..61fefacd5 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -23,12 +23,9 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; -use crate::z_owned_slice_t; use crate::z_owned_str_t; use crate::z_session_t; -use crate::z_slice_t; use crate::z_str_from_substring; -use crate::z_view_slice_from_str; use crate::z_view_slice_t; use crate::z_view_slice_wrap; use libc::c_char; @@ -37,6 +34,7 @@ use zenoh::core::SyncResolve; use zenoh::key_expr::SetIntersectionLevel; use zenoh::prelude::keyexpr; use zenoh::prelude::KeyExpr; +use zenoh_protocol::core::key_expr::canon::Canonizable; pub use crate::opaque_types::z_owned_keyexpr_t; pub use crate::opaque_types::z_view_keyexpr_t; @@ -55,7 +53,7 @@ pub extern "C" fn z_view_keyexpr_null(this: *mut MaybeUninit) } fn keyexpr_create_inner( - name: &'static mut str, + mut name: &'static mut str, should_auto_canonize: bool, should_copy: bool, ) -> Result, Box> { @@ -66,16 +64,10 @@ fn keyexpr_create_inner( false => KeyExpr::<'static>::try_from(s), } } else { - match should_auto_canonize { - true => { - // hack to fix issue with autocanonize requiring &&str instead of &str - // to be removed after this issue is resolved on zenoh-rust side - let n = &name as *const &'static mut str as *mut &'static mut str; - let n = unsafe { &mut *n }; - keyexpr::autocanonize(n).map(|k| k.into()) - }, - false => keyexpr::new(name).map(|k| k.into()) + if should_auto_canonize { + name.canonize(); } + return keyexpr::new(name).map(|k| k.into()); } } @@ -384,9 +376,9 @@ pub unsafe extern "C" fn z_keyexpr_unchecked( /// The user is responsible of droping the returned string using `z_drop` #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t, s: *mut MaybeUninit) { +pub unsafe extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t, s: *mut MaybeUninit) { let ke = ke.transmute_ref(); - unsafe { z_str_from_substring(s, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) } ; + unsafe { z_str_from_substring(s, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) }; } /// Returns the key expression's internal string by aliasing it. @@ -394,9 +386,9 @@ pub extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t, s: *mut MaybeUninit) { +pub unsafe extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t, b: *mut MaybeUninit) { let ke = ke.transmute_ref(); - unsafe { z_view_slice_wrap(b, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) } ; + unsafe { z_view_slice_wrap(b, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) }; } /**************************************/ @@ -433,7 +425,10 @@ pub extern "C" fn z_declare_keyexpr( /// The keyxpr is consumed. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_undeclare_keyexpr(session: &z_session_t, kexpr: &mut z_owned_keyexpr_t) -> errors::z_error_t { +pub extern "C" fn z_undeclare_keyexpr( + session: &z_session_t, + kexpr: &mut z_owned_keyexpr_t, +) -> errors::z_error_t { let Some(kexpr) = kexpr.transmute_mut().take() else { log::debug!("Attempted to undeclare dropped keyexpr"); return errors::Z_EINVAL; diff --git a/src/liveliness.rs b/src/liveliness.rs index 88e0966b3..8fefb253d 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -54,8 +54,9 @@ pub struct zc_liveliness_declaration_options_t { } #[no_mangle] -pub extern "C" fn zc_liveliness_declaration_options_default(this: &mut zc_liveliness_declaration_options_t) -{ +pub extern "C" fn zc_liveliness_declaration_options_default( + this: &mut zc_liveliness_declaration_options_t, +) { *this = zc_liveliness_declaration_options_t { _dummy: 0 }; } @@ -110,7 +111,9 @@ pub struct zc_liveliness_declare_subscriber_options_t { } #[no_mangle] -pub extern "C" fn zc_liveliness_subscriber_options_default(this: &mut zc_liveliness_declare_subscriber_options_t) { +pub extern "C" fn zc_liveliness_subscriber_options_default( + this: &mut zc_liveliness_declare_subscriber_options_t, +) { *this = zc_liveliness_declare_subscriber_options_t { _dummy: 0 }; } diff --git a/src/payload.rs b/src/payload.rs index 96ef100ca..665ae0d24 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -1,11 +1,13 @@ use crate::errors::{self, z_error_t}; use crate::transmute::{ - unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, + TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; use crate::{ - z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, z_str_t, ZHashMap + z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, z_str_t, + ZHashMap, }; -use core::{fmt, slice}; +use core::fmt; use std::any::Any; use std::io::{Read, Seek, SeekFrom}; use std::mem::MaybeUninit; @@ -40,7 +42,7 @@ extern "C" fn z_bytes_check(payload: &z_owned_bytes_t) -> bool { /// Loans the payload, allowing you to call functions that only need a loan of it. #[no_mangle] -extern "C" fn z_bytes_loan(payload: & z_owned_bytes_t) -> &z_bytes_t { +extern "C" fn z_bytes_loan(payload: &z_owned_bytes_t) -> &z_bytes_t { let payload = payload.transmute_ref(); let payload = unwrap_ref_unchecked(payload); payload.transmute_handle() @@ -74,23 +76,18 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( let len = z_bytes_len(payload); let payload = payload.transmute_ref(); let mut out = vec![0u8; len + 1]; - if let Err(e) = payload - .reader() - .read(out.as_mut_slice()) - { + if let Err(e) = payload.reader().read(out.as_mut_slice()) { log::error!("Failed to read the payload: {}", e); Inplace::empty(dst.transmute_uninit_ptr()); errors::Z_EIO + } else if let Err(e) = std::str::from_utf8(out.as_slice()) { + log::error!("Payload is not a valid utf-8 string: {}", e); + Inplace::empty(dst.transmute_uninit_ptr()); + errors::Z_EPARSE } else { - if let Err(e) = std::str::from_utf8(out.as_slice()) { - log::error!("Payload is not a valid utf-8 string: {}", e); - Inplace::empty(dst.transmute_uninit_ptr()); - errors::Z_EPARSE - } else { - let b = out.into_boxed_slice(); - Inplace::init(dst.transmute_uninit_ptr(), Some(b)); - errors::Z_OK - } + let b = out.into_boxed_slice(); + Inplace::init(dst.transmute_uninit_ptr(), Some(b)); + errors::Z_OK } } @@ -125,7 +122,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes( let b = v.into_boxed_slice(); Inplace::init(dst.transmute_uninit_ptr(), Some(b)); errors::Z_OK - }, + } Err(e) => { log::error!("Failed to read the payload: {}", e); Inplace::empty(dst.transmute_uninit_ptr()); @@ -165,7 +162,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_bytes( bytes: &z_slice_t, ) { let this = this.transmute_uninit_ptr(); - let payload = ZBytes::from(ZSlice::from(bytes.clone())); + let payload = ZBytes::from(ZSlice::from(*bytes)); Inplace::init(this, Some(payload)); } @@ -192,7 +189,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_string( let s = s.transmute_ref(); let ss = &s[0..s.len() - 1]; let b = ss.transmute_handle(); - z_bytes_encode_from_bytes(this, &b); + z_bytes_encode_from_bytes(this, b); } pub use crate::opaque_types::z_owned_bytes_reader_t; @@ -243,7 +240,9 @@ extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_bytes_r } #[no_mangle] -extern "C" fn z_bytes_reader_loan_mut(reader: &mut z_owned_bytes_reader_t) -> &mut z_bytes_reader_t { +extern "C" fn z_bytes_reader_loan_mut( + reader: &mut z_owned_bytes_reader_t, +) -> &mut z_bytes_reader_t { let reader = reader.transmute_mut(); let reader = unwrap_ref_unchecked_mut(reader); reader.transmute_handle_mut() diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index aa00c3090..9c2adf78f 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -11,7 +11,8 @@ pub use crate::opaque_types::z_owned_mutex_t; use crate::{ errors, transmute::{ - unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr + unwrap_ref_unchecked, unwrap_ref_unchecked_mut, Inplace, TransmuteFromHandle, + TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }, }; @@ -145,7 +146,10 @@ pub extern "C" fn z_condvar_signal(this: &z_condvar_t) -> errors::z_error_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_condvar_wait(this: &z_condvar_t, m: &mut z_mutex_t) -> errors::z_error_t { +pub unsafe extern "C" fn z_condvar_wait( + this: &z_condvar_t, + m: &mut z_mutex_t, +) -> errors::z_error_t { let this = this.transmute_ref(); let m = m.transmute_mut(); if m.1.is_none() { diff --git a/src/put.rs b/src/put.rs index 2bb950087..74b63b4b8 100644 --- a/src/put.rs +++ b/src/put.rs @@ -141,10 +141,10 @@ pub extern "C" fn z_delete( ) -> errors::z_error_t { let session = session.transmute_ref(); let key_expr = key_expr.transmute_ref(); - let mut del = session - .delete(key_expr); + let mut del = session.delete(key_expr); if let Some(options) = options { - del = del.congestion_control(options.congestion_control.into()) + del = del + .congestion_control(options.congestion_control.into()) .priority(options.priority.into()); } diff --git a/src/queryable.rs b/src/queryable.rs index e34927b40..0f2de51ce 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -17,7 +17,7 @@ use crate::transmute::{ }; use crate::{ errors, z_bytes_t, z_closure_query_call, z_keyexpr_t, z_owned_bytes_t, z_owned_closure_query_t, - z_owned_encoding_t, z_session_t, z_slice_t, z_value_t, z_view_slice_t, z_view_slice_wrap, + z_owned_encoding_t, z_session_t, z_value_t, z_view_slice_t, z_view_slice_wrap, }; use std::mem::MaybeUninit; use std::ptr::{null, null_mut}; @@ -255,7 +255,10 @@ pub extern "C" fn z_query_keyexpr(query: &z_query_t) -> &z_keyexpr_t { /// Get a query's `value selector `_ by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_parameters(query: &z_query_t, parameters: *mut MaybeUninit) { +pub unsafe extern "C" fn z_query_parameters( + query: &z_query_t, + parameters: *mut MaybeUninit, +) { let query = query.transmute_ref(); let params = query.parameters().as_str(); unsafe { z_view_slice_wrap(parameters, params.as_ptr(), params.len()) }; diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index d6a5e3696..0166314f1 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -83,7 +83,9 @@ pub struct ze_querying_subscriber_options_t { /// Constructs the default value for :c:type:`ze_querying_subscriber_options_t`. #[no_mangle] -pub extern "C" fn ze_querying_subscriber_options_default(this: &mut ze_querying_subscriber_options_t) { +pub extern "C" fn ze_querying_subscriber_options_default( + this: &mut ze_querying_subscriber_options_t, +) { *this = ze_querying_subscriber_options_t { reliability: Reliability::DEFAULT.into(), allowed_origin: zcu_locality_default(), diff --git a/src/scouting.rs b/src/scouting.rs index 0f2f29c34..7609c3a38 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -222,7 +222,7 @@ pub unsafe extern "C" fn z_scouting_config_from( config: &z_config_t, ) { let mut dst = MaybeUninit::uninit(); - z_config_clone(&config, &mut dst as *mut _); + z_config_clone(config, &mut dst as *mut _); let _config = dst.assume_init(); let config = z_owned_scouting_config_t { diff --git a/src/session.rs b/src/session.rs index 194779201..049fd7ca3 100644 --- a/src/session.rs +++ b/src/session.rs @@ -38,7 +38,7 @@ decl_transmute_handle!(Session, z_session_t); /// attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) /// have been destroyed is UB (likely SEGFAULT) #[no_mangle] -pub extern "C" fn z_session_loan(this: & z_owned_session_t) -> &z_session_t { +pub extern "C" fn z_session_loan(this: &z_owned_session_t) -> &z_session_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); let this = this.as_ref(); diff --git a/src/transmute.rs b/src/transmute.rs index 92fb45f45..136069535 100644 --- a/src/transmute.rs +++ b/src/transmute.rs @@ -207,7 +207,7 @@ macro_rules! impl_transmute_handle { ($c_type:ty, $zenoh_type:ty) => { impl $crate::transmute::TransmuteFromHandle<$zenoh_type> for $c_type { fn transmute_ref(&self) -> &'static $zenoh_type { - unsafe { std::mem::transmute::<& $c_type, &'static $zenoh_type>(self) } + unsafe { std::mem::transmute::<&$c_type, &'static $zenoh_type>(self) } } fn transmute_mut(&mut self) -> &'static mut $zenoh_type { unsafe { std::mem::transmute::<&mut $c_type, &'static mut $zenoh_type>(self) } From 155aa60036a20bf54a996ba2f5730618121dd108 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 26 Apr 2024 10:31:53 +0200 Subject: [PATCH 69/75] explicitely named loaned types --- build-resources/opaque-types/src/lib.rs | 46 +-- docs/api.rst | 18 +- docs/examples.rst | 8 +- examples/z_get.c | 4 +- examples/z_get_liveliness.c | 4 +- examples/z_liveliness.c | 2 +- examples/z_non_blocking_get.c | 6 +- examples/z_ping.c | 12 +- examples/z_pong.c | 8 +- examples/z_pub_thr.c | 2 +- examples/z_query_sub.c | 4 +- examples/z_queryable.c | 10 +- examples/z_queryable_with_channels.c | 12 +- examples/z_sub.c | 4 +- examples/z_sub_attachment.c | 10 +- examples/z_sub_liveliness.c | 6 +- examples/z_sub_thr.c | 2 +- include/zenoh_commons.h | 523 +++++++++++++----------- include/zenoh_concrete.h | 8 +- include/zenoh_macros.h | 62 +-- splitguide.yaml | 4 +- src/closures/query_channel.rs | 8 +- src/closures/query_closure.rs | 20 +- src/closures/reply_closure.rs | 16 +- src/closures/response_channel.rs | 8 +- src/closures/sample_closure.rs | 18 +- src/collections.rs | 71 ++-- src/commons.rs | 79 ++-- src/config.rs | 20 +- src/get.rs | 36 +- src/info.rs | 8 +- src/keyexpr.rs | 68 +-- src/liveliness.rs | 24 +- src/payload.rs | 52 +-- src/platform/synchronization.rs | 29 +- src/publication_cache.rs | 21 +- src/publisher.rs | 24 +- src/pull_subscriber.rs | 6 +- src/put.rs | 14 +- src/queryable.rs | 31 +- src/querying_subscriber.rs | 36 +- src/scouting.rs | 6 +- src/session.rs | 10 +- src/shm.rs | 4 +- src/subscriber.rs | 16 +- tests/z_api_alignment_test.c | 34 +- tests/z_api_attachment_test.c | 24 +- tests/z_api_double_drop_test.c | 4 +- tests/z_api_keyexpr_drop_test.c | 8 +- tests/z_api_keyexpr_test.c | 24 +- tests/z_api_payload_test.c | 2 +- tests/z_api_unitinialized_check.c | 2 +- tests/z_int_pub_cache_query_sub_test.c | 4 +- tests/z_int_pub_sub_attachment_test.c | 8 +- tests/z_int_pub_sub_test.c | 4 +- tests/z_int_queryable_attachment_test.c | 20 +- tests/z_int_queryable_test.c | 12 +- 57 files changed, 800 insertions(+), 726 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 7797578d5..512ea8b00 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -44,7 +44,7 @@ macro_rules! get_opaque_type_data { /// To minimize copies and reallocations, Zenoh may provide you data in split buffers. get_opaque_type_data!(Option, z_owned_bytes_t); /// A loaned payload. -get_opaque_type_data!(ZBytes, z_bytes_t); +get_opaque_type_data!(ZBytes, z_loaned_bytes_t); /// A contiguous view of bytes owned by some other entity. /// @@ -52,36 +52,36 @@ get_opaque_type_data!(ZBytes, z_bytes_t); /// and empty slices are represented using a possibly dangling pointer for `start`. get_opaque_type_data!(Option>, z_owned_slice_t); get_opaque_type_data!(Option<&'static [u8]>, z_view_slice_t); -get_opaque_type_data!(&'static [u8], z_slice_t); +get_opaque_type_data!(&'static [u8], z_loaned_slice_t); /// The wrapper type for null-terminated string values allocated by zenoh. The instances of `z_owned_str_t` /// should be released with `z_drop` macro or with `z_str_drop` function and checked to validity with /// `z_check` and `z_str_check` correspondently get_opaque_type_data!(Option>, z_owned_str_t); get_opaque_type_data!(Option<&'static [u8]>, z_view_str_t); -get_opaque_type_data!(&'static [u8], z_str_t); +get_opaque_type_data!(&'static [u8], z_loaned_str_t); /// A map of maybe-owned vector of bytes to maybe-owned vector of bytes. /// /// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher get_opaque_type_data!(Option, Cow<'static, [u8]>>>, z_owned_slice_map_t); -get_opaque_type_data!(HashMap, Cow<'static, [u8]>>, z_slice_map_t); +get_opaque_type_data!(HashMap, Cow<'static, [u8]>>, z_loaned_slice_map_t); /// An owned sample. /// -/// This is a read only type that can only be constructed by cloning a `z_sample_t`. +/// This is a read only type that can only be constructed by cloning a `z_loaned_sample_t`. /// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. get_opaque_type_data!(Option, zc_owned_sample_t); -get_opaque_type_data!(Sample, z_sample_t); +get_opaque_type_data!(Sample, z_loaned_sample_t); /// A reader for payload data. get_opaque_type_data!(Option>, z_owned_bytes_reader_t); -get_opaque_type_data!(ZBytesReader<'static>, z_bytes_reader_t); +get_opaque_type_data!(ZBytesReader<'static>, z_loaned_bytes_reader_t); /// The encoding of a payload, in a MIME-like format. /// /// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. -get_opaque_type_data!(Encoding, z_encoding_t); +get_opaque_type_data!(Encoding, z_loaned_encoding_t); get_opaque_type_data!(Encoding, z_owned_encoding_t); /// An owned reply to a :c:func:`z_get`. @@ -92,18 +92,18 @@ get_opaque_type_data!(Encoding, z_owned_encoding_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. get_opaque_type_data!(Option, z_owned_reply_t); -get_opaque_type_data!(Reply, z_reply_t); +get_opaque_type_data!(Reply, z_loaned_reply_t); /// A zenoh value. get_opaque_type_data!(Value, z_owned_value_t); -get_opaque_type_data!(Value, z_value_t); +get_opaque_type_data!(Value, z_loaned_value_t); // Loaned variant of a Query received by a Queryable. /// /// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. -/// `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. +/// `z_loaned_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. get_opaque_type_data!(Option, z_owned_query_t); -get_opaque_type_data!(Query, z_query_t); +get_opaque_type_data!(Query, z_loaned_query_t); /// An owned zenoh queryable. /// @@ -116,7 +116,7 @@ get_opaque_type_data!(Query, z_query_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_queryable_t); -get_opaque_type_data!(Queryable<'static, ()>, z_queryable_t); +get_opaque_type_data!(Queryable<'static, ()>, z_loaned_queryable_t); /// An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. /// @@ -129,7 +129,7 @@ get_opaque_type_data!(Queryable<'static, ()>, z_queryable_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t); -get_opaque_type_data!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_querying_subscriber_t); +get_opaque_type_data!((zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), ze_loaned_querying_subscriber_t); /// A zenoh-allocated key expression. /// @@ -168,7 +168,7 @@ get_opaque_type_data!(Option>, z_view_keyexpr_t); /// /// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, /// both for local processing and network-wise. -get_opaque_type_data!(KeyExpr<'_>, z_keyexpr_t); +get_opaque_type_data!(KeyExpr<'_>, z_loaned_keyexpr_t); /// An owned zenoh session. /// @@ -181,7 +181,7 @@ get_opaque_type_data!(KeyExpr<'_>, z_keyexpr_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_session_t); -get_opaque_type_data!(Session, z_session_t); +get_opaque_type_data!(Session, z_loaned_session_t); /// An owned zenoh configuration. /// @@ -195,7 +195,7 @@ get_opaque_type_data!(Session, z_session_t); /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option, z_owned_config_t); /// A loaned zenoh configuration. -get_opaque_type_data!(Config, z_config_t); +get_opaque_type_data!(Config, z_loaned_config_t); /// Represents a Zenoh ID. /// @@ -215,7 +215,7 @@ get_opaque_type_data!(Timestamp, z_timestamp_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_publisher_t); -get_opaque_type_data!(Publisher<'static>, z_publisher_t); +get_opaque_type_data!(Publisher<'static>, z_loaned_publisher_t); /// An owned zenoh matching listener. Destroying the matching listener cancels the subscription. /// @@ -241,7 +241,7 @@ get_opaque_type_data!(Option>, zcu_own /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, z_owned_subscriber_t); -get_opaque_type_data!(Subscriber<'static, ()>, z_subscriber_t); +get_opaque_type_data!(Subscriber<'static, ()>, z_loaned_subscriber_t); /// A liveliness token that can be used to provide the network with information about connectivity to its /// declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key @@ -249,7 +249,7 @@ get_opaque_type_data!(Subscriber<'static, ()>, z_subscriber_t); /// /// A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. get_opaque_type_data!(Option>, zc_owned_liveliness_token_t); -get_opaque_type_data!(LivelinessToken<'static>, zc_liveliness_token_t); +get_opaque_type_data!(LivelinessToken<'static>, zc_loaned_liveliness_token_t); /// An owned zenoh publication_cache. @@ -263,13 +263,13 @@ get_opaque_type_data!(LivelinessToken<'static>, zc_liveliness_token_t); /// /// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. get_opaque_type_data!(Option>, ze_owned_publication_cache_t); -get_opaque_type_data!(zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); +get_opaque_type_data!(zenoh_ext::PublicationCache<'static>, ze_loaned_publication_cache_t); get_opaque_type_data!(Option<(Mutex<()>, Option>)>, z_owned_mutex_t); -get_opaque_type_data!((Mutex<()>, Option>), z_mutex_t); +get_opaque_type_data!((Mutex<()>, Option>), z_loaned_mutex_t); get_opaque_type_data!(Option, z_owned_condvar_t); -get_opaque_type_data!(Condvar, z_condvar_t); +get_opaque_type_data!(Condvar, z_loaned_condvar_t); get_opaque_type_data!(Option>, z_owned_task_t); \ No newline at end of file diff --git a/docs/api.rst b/docs/api.rst index 046ede892..a5b0e1eea 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -22,7 +22,7 @@ Generic types Bytes ----- -.. autocstruct:: zenoh_commons.h::z_slice_t +.. autocstruct:: zenoh_commons.h::z_loaned_slice_t .. autocfunction:: zenoh_commons.h::z_slice_new .. autocfunction:: zenoh_commons.h::z_slice_check @@ -56,7 +56,7 @@ Session configuration --------------------- -.. autocstruct:: zenoh_commons.h::z_config_t +.. autocstruct:: zenoh_commons.h::z_loaned_config_t .. autocstruct:: zenoh_commons.h::z_owned_config_t .. autocstruct:: zenoh_commons.h::z_owned_scouting_config_t @@ -79,7 +79,7 @@ Session management Types ^^^^^ -.. autocstruct:: zenoh_concrete.h::z_session_t +.. autocstruct:: zenoh_concrete.h::z_loaned_session_t .. autocstruct:: zenoh_concrete.h::z_owned_session_t .. autocstruct:: zenoh_commons.h::z_owned_closure_zid_t @@ -104,13 +104,13 @@ Functions Key expression ============== -.. autocstruct:: zenoh_commons.h::z_keyexpr_t +.. autocstruct:: zenoh_commons.h::z_loaned_keyexpr_t .. autocstruct:: zenoh_commons.h::z_owned_keyexpr_t .. autocfunction:: zenoh_commons.h::z_keyexpr .. autocfunction:: zenoh_commons.h::z_keyexpr_autocanonize .. autocfunction:: zenoh_commons.h::z_keyexpr_unchecked -.. autocfunction:: zenoh_commons.h::z_keyexpr_to_string +.. autocfunction:: zenoh_commons.h::z_loaned_keyexpr_to_string .. autocfunction:: zenoh_commons.h::z_keyexpr_as_bytes .. autocfunction:: zenoh_commons.h::z_keyexpr_canonize .. autocfunction:: zenoh_commons.h::z_keyexpr_canonize_null_terminated @@ -133,7 +133,7 @@ Key expression Encoding ======== -.. autocstruct:: zenoh_commons.h::z_encoding_t +.. autocstruct:: zenoh_commons.h::z_loaned_encoding_t .. autocstruct:: zenoh_commons.h::z_owned_encoding_t .. autocfunction:: zenoh_commons.h::z_encoding_default @@ -147,12 +147,12 @@ Encoding Value ===== -.. autocstruct:: zenoh_commons.h::z_value_t +.. autocstruct:: zenoh_commons.h::z_loaned_value_t Sample ====== -.. autocstruct:: zenoh_commons.h::z_sample_t +.. autocstruct:: zenoh_commons.h::z_loaned_sample_t Attachment ========== @@ -237,7 +237,7 @@ Types .. autocstruct:: zenoh_commons.h::z_get_options_t -.. autocenum:: zenoh_commons.h::z_query_target_t +.. autocenum:: zenoh_commons.h::z_loaned_query_target_t .. autocenum:: zenoh_commons.h::z_consolidation_mode_t diff --git a/docs/examples.rst b/docs/examples.rst index bea19cbbe..1aab457a6 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -43,8 +43,8 @@ Subscribe #include #include "zenoh.h" - void data_handler(const z_sample_t *sample, const void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + void data_handler(const z_loaned_sample_t *sample, const void *arg) { + z_owned_str_t keystr = z_loaned_keyexpr_to_string(sample->keyexpr); printf(">> Received (%s, %.*s)\n", keystr, (int)sample->payload.len, sample->payload.start); z_drop(z_move(keystr)); @@ -86,8 +86,8 @@ Query { if (z_reply_is_ok(&reply)) { - z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(sample.keyexpr); + z_loaned_sample_t sample = z_reply_ok(&reply); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(sample.keyexpr); printf(">> Received ('%s': '%.*s')\n", keystr, (int)sample.payload.len, sample.payload.start); z_drop(z_move(keystr)); } diff --git a/examples/z_get.c b/examples/z_get.c index 90291189c..00eb2a524 100644 --- a/examples/z_get.c +++ b/examples/z_get.c @@ -68,8 +68,8 @@ int main(int argc, char **argv) { z_owned_str_t reply_str; for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(z_loan(reply))) { - z_sample_t sample = z_reply_ok(z_loan(reply)); - z_owned_str_t key_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_loaned_sample_t sample = z_reply_ok(z_loan(reply)); + z_owned_str_t key_str = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); z_bytes_decode_into_string(z_sample_payload(&sample), &reply_str); printf(">> Received ('%s': '%s')\n", z_loan(key_str), z_loan(reply_str)); z_drop(z_move(reply_str)); diff --git a/examples/z_get_liveliness.c b/examples/z_get_liveliness.c index 08ed225f1..025b09db3 100644 --- a/examples/z_get_liveliness.c +++ b/examples/z_get_liveliness.c @@ -53,8 +53,8 @@ int main(int argc, char **argv) { z_owned_reply_t reply; for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { if (z_reply_is_ok(z_loan(reply))) { - z_sample_t sample = z_reply_ok(z_loan(reply)); - z_owned_str_t key_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_loaned_sample_t sample = z_reply_ok(z_loan(reply)); + z_owned_str_t key_str = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); printf(">> Alive token ('%s')\n", z_loan(key_str)); z_drop(z_move(key_str)); } else { diff --git a/examples/z_liveliness.c b/examples/z_liveliness.c index 4191b0496..bc71da8eb 100644 --- a/examples/z_liveliness.c +++ b/examples/z_liveliness.c @@ -21,7 +21,7 @@ int main(int argc, char **argv) { expr = argv[1]; } - z_keyexpr_t keyexpr = z_keyexpr(expr); + z_loaned_keyexpr_t keyexpr = z_keyexpr(expr); if (!z_check(keyexpr)) { printf("%s is not a valid key expression\n", expr); exit(-1); diff --git a/examples/z_non_blocking_get.c b/examples/z_non_blocking_get.c index 30df45daf..c84074e67 100644 --- a/examples/z_non_blocking_get.c +++ b/examples/z_non_blocking_get.c @@ -21,7 +21,7 @@ int main(int argc, char **argv) { if (argc > 1) { expr = argv[1]; } - z_keyexpr_t keyexpr = z_keyexpr(expr); + z_loaned_keyexpr_t keyexpr = z_keyexpr(expr); if (!z_check(keyexpr)) { printf("%s is not a valid key expression", expr); exit(-1); @@ -58,8 +58,8 @@ int main(int argc, char **argv) { continue; } if (z_reply_is_ok(&reply)) { - z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_loaned_sample_t sample = z_reply_ok(&reply); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); printf(">> Received ('%s': '%s')\n", z_loan(keystr), z_loan(payload_value)); z_drop(z_move(payload_value)); diff --git a/examples/z_ping.c b/examples/z_ping.c index 8f8adb2f7..87dc697ab 100644 --- a/examples/z_ping.c +++ b/examples/z_ping.c @@ -13,10 +13,10 @@ #define handle_error_en(en, msg) \ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) -z_condvar_t cond; -z_mutex_t mutex; +z_loaned_condvar_t cond; +z_loaned_mutex_t mutex; -void callback(const z_sample_t* sample, void* context) { z_condvar_signal(&cond); } +void callback(const z_loaned_sample_t* sample, void* context) { z_condvar_signal(&cond); } void drop(void* context) { z_condvar_free(&cond); } struct args_t { @@ -45,8 +45,8 @@ int main(int argc, char** argv) { z_condvar_init(&cond); z_owned_config_t config = args.config_path ? zc_config_from_file(args.config_path) : z_config_default(); z_owned_session_t session = z_open(z_move(config)); - z_keyexpr_t ping = z_keyexpr_unchecked("test/ping"); - z_keyexpr_t pong = z_keyexpr_unchecked("test/pong"); + z_loaned_keyexpr_t ping = z_keyexpr_unchecked("test/ping"); + z_loaned_keyexpr_t pong = z_keyexpr_unchecked("test/pong"); z_owned_publisher_t pub = z_declare_publisher(z_loan(session), ping, NULL); z_owned_closure_sample_t respond = z_closure(callback, drop, (void*)(&pub)); z_owned_subscriber_t sub = z_declare_subscriber(z_loan(session), pong, z_move(respond), NULL); @@ -54,7 +54,7 @@ int main(int argc, char** argv) { for (int i = 0; i < args.size; i++) { data[i] = i % 10; } - z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_slice_t){.start = data, .len = args.size}); + z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_loaned_slice_t){.start = data, .len = args.size}); z_mutex_lock(&mutex); if (args.warmup_ms) { printf("Warming up for %dms...\n", args.warmup_ms); diff --git a/examples/z_pong.c b/examples/z_pong.c index 3da1150bb..b8920f70d 100644 --- a/examples/z_pong.c +++ b/examples/z_pong.c @@ -3,8 +3,8 @@ #include "zenoh.h" -void callback(const z_sample_t* sample, void* context) { - z_publisher_t pub = z_loan(*(z_owned_publisher_t*)context); +void callback(const z_loaned_sample_t* sample, void* context) { + z_loaned_publisher_t pub = z_loan(*(z_owned_publisher_t*)context); #ifdef ZENOH_C // The z_owned_bytes_t API is exclusive to zenoh-c, but allows avoiding some copies. z_owned_bytes_t payload = z_sample_owned_payload(sample); z_publisher_put(pub, z_move(payload), NULL); @@ -34,8 +34,8 @@ int main(int argc, char** argv) { } z_owned_config_t config = args.config_path ? zc_config_from_file(args.config_path) : z_config_default(); z_owned_session_t session = z_open(z_move(config)); - z_keyexpr_t ping = z_keyexpr_unchecked("test/ping"); - z_keyexpr_t pong = z_keyexpr_unchecked("test/pong"); + z_loaned_keyexpr_t ping = z_keyexpr_unchecked("test/ping"); + z_loaned_keyexpr_t pong = z_keyexpr_unchecked("test/pong"); z_owned_publisher_t pub = z_declare_publisher(z_loan(session), pong, NULL); z_owned_closure_sample_t respond = z_closure(callback, drop, (void*)z_move(pub)); z_owned_subscriber_t sub = z_declare_subscriber(z_loan(session), ping, z_move(respond), NULL); diff --git a/examples/z_pub_thr.c b/examples/z_pub_thr.c index 0298ceacf..c59f3f6c7 100644 --- a/examples/z_pub_thr.c +++ b/examples/z_pub_thr.c @@ -54,7 +54,7 @@ int main(int argc, char **argv) { } while (1) { - z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_slice_t){.start = value, .len = len}); + z_owned_bytes_t payload = z_bytes_encode_from_bytes((z_loaned_slice_t){.start = value, .len = len}); z_publisher_put(z_loan(pub), z_move(payload), NULL); } diff --git a/examples/z_query_sub.c b/examples/z_query_sub.c index a2f878019..4a2d72cc9 100644 --- a/examples/z_query_sub.c +++ b/examples/z_query_sub.c @@ -16,8 +16,8 @@ const char *kind_to_str(z_sample_kind_t kind); -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); +void data_handler(const z_loaned_sample_t *sample, void *arg) { + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), diff --git a/examples/z_queryable.c b/examples/z_queryable.c index 4342c6746..191daf413 100644 --- a/examples/z_queryable.c +++ b/examples/z_queryable.c @@ -17,12 +17,12 @@ const char *expr = "demo/example/zenoh-c-queryable"; const char *value = "Queryable from C!"; -z_keyexpr_t keyexpr; +z_loaned_keyexpr_t keyexpr; -void query_handler(const z_query_t *query, void *context) { - z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_slice_t pred = z_query_parameters(query); - z_bytes_t payload = z_query_value(query).payload; +void query_handler(const z_loaned_query_t *query, void *context) { + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_query_keyexpr(query)); + z_loaned_slice_t pred = z_query_parameters(query); + z_loaned_bytes_t payload = z_query_value(query).payload; if (z_bytes_len(payload) > 0) { z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(payload, &payload_value); diff --git a/examples/z_queryable_with_channels.c b/examples/z_queryable_with_channels.c index 422ad3971..0fec21120 100644 --- a/examples/z_queryable_with_channels.c +++ b/examples/z_queryable_with_channels.c @@ -18,9 +18,9 @@ const char *expr = "demo/example/zenoh-c-queryable"; const char *value = "Queryable from C!"; -z_keyexpr_t keyexpr; +z_loaned_keyexpr_t keyexpr; -void query_handler(const z_query_t *query, void *context) { +void query_handler(const z_loaned_query_t *query, void *context) { z_owned_closure_owned_query_t *channel = (z_owned_closure_owned_query_t *)context; z_owned_query_t oquery = z_query_clone(query); z_call(*channel, &oquery); @@ -65,10 +65,10 @@ int main(int argc, char **argv) { printf("^C to quit...\n"); z_owned_query_t oquery = z_query_null(); for (z_call(channel.recv, &oquery); z_check(oquery); z_call(channel.recv, &oquery)) { - z_query_t query = z_loan(oquery); - z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(&query)); - z_slice_t pred = z_query_parameters(&query); - z_bytes_t payload = z_query_value(&query).payload; + z_loaned_query_t query = z_loan(oquery); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_query_keyexpr(&query)); + z_loaned_slice_t pred = z_query_parameters(&query); + z_loaned_bytes_t payload = z_query_value(&query).payload; if (z_bytes_len(payload) > 0) { z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(payload, &payload_value); diff --git a/examples/z_sub.c b/examples/z_sub.c index f549d1561..f5b986634 100644 --- a/examples/z_sub.c +++ b/examples/z_sub.c @@ -16,8 +16,8 @@ const char *kind_to_str(z_sample_kind_t kind); -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); +void data_handler(const z_loaned_sample_t *sample, void *arg) { + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), diff --git a/examples/z_sub_attachment.c b/examples/z_sub_attachment.c index 6c1ea68be..13412321a 100644 --- a/examples/z_sub_attachment.c +++ b/examples/z_sub_attachment.c @@ -17,26 +17,26 @@ const char *kind_to_str(z_sample_kind_t kind); -int8_t attachment_reader(z_slice_t key, z_slice_t val, void *ctx) { +int8_t attachment_reader(z_loaned_slice_t key, z_loaned_slice_t val, void *ctx) { printf(" attachment: %.*s: '%.*s'\n", (int)key.len, key.start, (int)val.len, val.start); return 0; } -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); +void data_handler(const z_loaned_sample_t *sample, void *arg) { + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(z_sample_payload(sample), &payload_value); printf(">> [Subscriber] Received %s ('%s': '%s')\n", kind_to_str(z_sample_kind(sample)), z_loan(keystr), z_loan(payload_value)); - z_bytes_t attachment = z_sample_attachment(sample); + z_loaned_bytes_t attachment = z_sample_attachment(sample); // checks if attachment exists if (z_check(attachment)) { // reads full attachment z_attachment_iterate(attachment, attachment_reader, NULL); // reads particular attachment item - z_slice_t index = z_attachment_get(attachment, z_slice_from_str("index")); + z_loaned_slice_t index = z_attachment_get(attachment, z_slice_from_str("index")); if (z_slice_is_initialized(&index)) { printf(" message number: %.*s\n", (int)index.len, index.start); } diff --git a/examples/z_sub_liveliness.c b/examples/z_sub_liveliness.c index 5916200b2..5c6b49d6a 100644 --- a/examples/z_sub_liveliness.c +++ b/examples/z_sub_liveliness.c @@ -14,8 +14,8 @@ #include #include "zenoh.h" -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); +void data_handler(const z_loaned_sample_t *sample, void *arg) { + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); switch (z_sample_kind(sample)) { case Z_SAMPLE_KIND_PUT: printf(">> [LivelinessSubscriber] New alive token ('%s')\n", z_loan(keystr)); @@ -33,7 +33,7 @@ int main(int argc, char **argv) { expr = argv[1]; } - z_keyexpr_t keyexpr = z_keyexpr(expr); + z_loaned_keyexpr_t keyexpr = z_keyexpr(expr); if (!z_check(keyexpr)) { printf("%s is not a valid key expression\n", expr); exit(-1); diff --git a/examples/z_sub_thr.c b/examples/z_sub_thr.c index 3fdfe1e2a..d7e69a29f 100644 --- a/examples/z_sub_thr.c +++ b/examples/z_sub_thr.c @@ -34,7 +34,7 @@ z_stats_t *z_stats_make() { return stats; } -void on_sample(z_sample_t sample, void *context) { +void on_sample(z_loaned_sample_t sample, void *context) { z_stats_t *stats = (z_stats_t *)context; if (stats->count == 0) { stats->start = z_clock_now(); diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 3944d26e1..35429b0d6 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -59,6 +59,18 @@ typedef enum z_keyexpr_intersection_level_t { Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES = 2, Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS = 3, } z_keyexpr_intersection_level_t; +/** + * The Queryables that should be target of a :c:func:`z_get`. + * + * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. + * - **ALL_COMPLETE**: All complete queryables. + * - **ALL**: All matching queryables. + */ +typedef enum z_loaned_query_target_t { + Z_LOANED_QUERY_TARGET_BEST_MATCHING, + Z_LOANED_QUERY_TARGET_ALL, + Z_LOANED_QUERY_TARGET_ALL_COMPLETE, +} z_loaned_query_target_t; /** * The priority of zenoh messages. * @@ -79,18 +91,6 @@ typedef enum z_priority_t { Z_PRIORITY_DATA_LOW = 6, Z_PRIORITY_BACKGROUND = 7, } z_priority_t; -/** - * The Queryables that should be target of a :c:func:`z_get`. - * - * - **BEST_MATCHING**: The nearest complete queryable if any else all matching queryables. - * - **ALL_COMPLETE**: All complete queryables. - * - **ALL**: All matching queryables. - */ -typedef enum z_query_target_t { - Z_QUERY_TARGET_BEST_MATCHING, - Z_QUERY_TARGET_ALL, - Z_QUERY_TARGET_ALL_COMPLETE, -} z_query_target_t; /** * The subscription reliability. * @@ -125,9 +125,9 @@ typedef struct ALIGN(8) z_owned_bytes_t { /** * A loaned payload. */ -typedef struct ALIGN(8) z_bytes_t { +typedef struct ALIGN(8) z_loaned_bytes_t { uint8_t _0[40]; -} z_bytes_t; +} z_loaned_bytes_t; typedef int8_t z_error_t; /** * A contiguous view of bytes owned by some other entity. @@ -154,24 +154,24 @@ typedef struct ALIGN(8) z_owned_slice_map_t { typedef struct ALIGN(8) z_owned_str_t { uint8_t _0[16]; } z_owned_str_t; -typedef struct ALIGN(8) z_slice_t { +typedef struct ALIGN(8) z_loaned_slice_t { uint8_t _0[16]; -} z_slice_t; -typedef struct ALIGN(8) z_slice_map_t { +} z_loaned_slice_t; +typedef struct ALIGN(8) z_loaned_slice_map_t { uint8_t _0[48]; -} z_slice_map_t; -typedef struct ALIGN(8) z_str_t { +} z_loaned_slice_map_t; +typedef struct ALIGN(8) z_loaned_str_t { uint8_t _0[16]; -} z_str_t; +} z_loaned_str_t; /** * A reader for payload data. */ typedef struct ALIGN(8) z_owned_bytes_reader_t { uint8_t _0[24]; } z_owned_bytes_reader_t; -typedef struct ALIGN(8) z_bytes_reader_t { +typedef struct ALIGN(8) z_loaned_bytes_reader_t { uint8_t _0[24]; -} z_bytes_reader_t; +} z_loaned_bytes_reader_t; /** * Clock * Uses monotonic clock @@ -244,7 +244,7 @@ typedef struct z_owned_closure_hello_t { /** * * Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. - * `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. + * `z_loaned_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. */ typedef struct ALIGN(8) z_owned_query_t { uint8_t _0[16]; @@ -254,7 +254,7 @@ typedef struct ALIGN(8) z_owned_query_t { * * Members: * void *context: a pointer to an arbitrary state. - * void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *call(const struct z_loaned_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. * void *drop(void*): allows the callback's state to be freed. * * Closures are not guaranteed not to be called concurrently. @@ -275,7 +275,7 @@ typedef struct z_owned_closure_owned_query_t { * * Members: * void *context: a pointer to an arbitrary state. - * void *call(z_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *call(z_loaned_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. * void *drop(void*): allows the callback's state to be freed. * * Closures are not guaranteed not to be called concurrently. @@ -288,12 +288,12 @@ typedef struct z_owned_closure_owned_query_t { */ typedef struct z_owned_closure_query_t { void *context; - void (*call)(const struct z_query_t*, void *context); + void (*call)(const struct z_loaned_query_t*, void *context); void (*drop)(void*); } z_owned_closure_query_t; -typedef struct ALIGN(8) z_reply_t { +typedef struct ALIGN(8) z_loaned_reply_t { uint8_t _0[256]; -} z_reply_t; +} z_loaned_reply_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: * @@ -312,18 +312,18 @@ typedef struct ALIGN(8) z_reply_t { */ typedef struct z_owned_closure_reply_t { void *context; - void (*call)(const struct z_reply_t*, void*); + void (*call)(const struct z_loaned_reply_t*, void*); void (*drop)(void*); } z_owned_closure_reply_t; -typedef struct ALIGN(8) z_sample_t { +typedef struct ALIGN(8) z_loaned_sample_t { uint8_t _0[240]; -} z_sample_t; +} z_loaned_sample_t; /** * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. * * Members: * void *context: a pointer to an arbitrary state. - * void *call(struct z_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. + * void *call(struct z_loaned_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. * void *drop(void*): allows the callback's state to be freed. * * Closures are not guaranteed not to be called concurrently. @@ -336,7 +336,7 @@ typedef struct ALIGN(8) z_sample_t { */ typedef struct z_owned_closure_sample_t { void *context; - void (*call)(const struct z_sample_t*, void *context); + void (*call)(const struct z_loaned_sample_t*, void *context); void (*drop)(void*); } z_owned_closure_sample_t; /** @@ -363,12 +363,12 @@ typedef struct z_owned_closure_zid_t { typedef struct ALIGN(8) z_owned_condvar_t { uint8_t _0[24]; } z_owned_condvar_t; -typedef struct ALIGN(8) z_condvar_t { +typedef struct ALIGN(8) z_loaned_condvar_t { uint8_t _0[16]; -} z_condvar_t; -typedef struct ALIGN(8) z_mutex_t { +} z_loaned_condvar_t; +typedef struct ALIGN(8) z_loaned_mutex_t { uint8_t _0[32]; -} z_mutex_t; +} z_loaned_mutex_t; /** * An owned zenoh configuration. * @@ -387,9 +387,9 @@ typedef struct ALIGN(8) z_owned_config_t { /** * A loaned zenoh configuration. */ -typedef struct ALIGN(8) z_config_t { +typedef struct ALIGN(8) z_loaned_config_t { uint8_t _0[1544]; -} z_config_t; +} z_loaned_config_t; /** * A zenoh-allocated key expression. * @@ -431,9 +431,9 @@ typedef struct ALIGN(8) z_owned_keyexpr_t { * Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, * both for local processing and network-wise. */ -typedef struct ALIGN(8) z_keyexpr_t { +typedef struct ALIGN(8) z_loaned_keyexpr_t { uint8_t _0[32]; -} z_keyexpr_t; +} z_loaned_keyexpr_t; /** * An owned zenoh publisher. * @@ -493,9 +493,9 @@ typedef struct ALIGN(8) z_owned_encoding_t { * * For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. */ -typedef struct ALIGN(8) z_encoding_t { +typedef struct ALIGN(8) z_loaned_encoding_t { uint8_t _0[48]; -} z_encoding_t; +} z_loaned_encoding_t; /** * The replies consolidation strategy to apply on replies to a :c:func:`z_get`. */ @@ -506,14 +506,14 @@ typedef struct z_query_consolidation_t { * Options passed to the :c:func:`z_get` function. * * Members: - * z_query_target_t target: The Queryables that should be target of the query. + * z_loaned_query_target_t target: The Queryables that should be target of the query. * z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. - * z_value_t value: An optional value to attach to the query. - * z_bytes_t attachment: The attachment to attach to the query. + * z_loaned_value_t value: An optional value to attach to the query. + * z_loaned_bytes_t attachment: The attachment to attach to the query. * uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. */ typedef struct z_get_options_t { - enum z_query_target_t target; + enum z_loaned_query_target_t target; struct z_query_consolidation_t consolidation; struct z_owned_bytes_t *payload; struct z_owned_encoding_t *encoding; @@ -552,12 +552,15 @@ typedef struct ALIGN(8) z_view_slice_t { typedef struct ALIGN(8) z_view_keyexpr_t { uint8_t _0[32]; } z_view_keyexpr_t; +typedef struct ALIGN(8) z_timestamp_t { + uint8_t _0[24]; +} z_timestamp_t; typedef struct ALIGN(8) z_owned_mutex_t { uint8_t _0[32]; } z_owned_mutex_t; -typedef struct ALIGN(8) z_publisher_t { +typedef struct ALIGN(8) z_loaned_publisher_t { uint8_t _0[56]; -} z_publisher_t; +} z_loaned_publisher_t; /** * Represents the set of options that can be applied to the delete operation by a previously declared publisher, * whenever issued via :c:func:`z_publisher_delete`. @@ -580,10 +583,10 @@ typedef struct z_publisher_put_options_t { * Options passed to the :c:func:`z_put` function. * * Members: - * z_encoding_t encoding: The encoding of the payload. + * z_loaned_encoding_t encoding: The encoding of the payload. * z_congestion_control_t congestion_control: The congestion control to apply when routing this message. * z_priority_t priority: The priority of this message. - * z_bytes_t attachment: The attachment to this message. + * z_loaned_bytes_t attachment: The attachment to this message. */ typedef struct z_put_options_t { struct z_owned_encoding_t *encoding; @@ -628,9 +631,9 @@ typedef struct z_query_reply_options_t { struct z_owned_encoding_t *encoding; struct z_owned_bytes_t *attachment; } z_query_reply_options_t; -typedef struct ALIGN(8) z_value_t { +typedef struct ALIGN(8) z_loaned_value_t { uint8_t _0[88]; -} z_value_t; +} z_loaned_value_t; /** * An owned reply to a :c:func:`z_get`. * @@ -671,15 +674,12 @@ typedef struct z_owned_reply_channel_t { /** * An owned sample. * - * This is a read only type that can only be constructed by cloning a `z_sample_t`. + * This is a read only type that can only be constructed by cloning a `z_loaned_sample_t`. * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. */ typedef struct ALIGN(8) zc_owned_sample_t { uint8_t _0[240]; } zc_owned_sample_t; -typedef struct ALIGN(8) z_timestamp_t { - uint8_t _0[24]; -} z_timestamp_t; typedef struct z_owned_scouting_config_t { struct z_owned_config_t _config; unsigned long zc_timeout_ms; @@ -693,12 +693,12 @@ typedef struct z_owned_scouting_config_t { * * Returning `true` is treated as `continue`. */ -typedef bool (*z_slice_map_iter_body_t)(const struct z_slice_t *key, - const struct z_slice_t *value, +typedef bool (*z_slice_map_iter_body_t)(const struct z_loaned_slice_t *key, + const struct z_loaned_slice_t *value, void *context); -typedef struct ALIGN(8) z_subscriber_t { +typedef struct ALIGN(8) z_loaned_subscriber_t { uint8_t _0[32]; -} z_subscriber_t; +} z_loaned_subscriber_t; typedef struct ALIGN(8) z_owned_task_t { uint8_t _0[24]; } z_owned_task_t; @@ -807,7 +807,7 @@ typedef struct ALIGN(8) ze_owned_publication_cache_t { * Options passed to the :c:func:`ze_declare_publication_cache` function. * * Members: - * z_keyexpr_t queryable_prefix: The prefix used for queryable + * z_loaned_keyexpr_t queryable_prefix: The prefix used for queryable * zcu_locality_t queryable_origin: The restriction for the matching queries that will be receive by this * publication cache * bool queryable_complete: the `complete` option for the queryable @@ -815,7 +815,7 @@ typedef struct ALIGN(8) ze_owned_publication_cache_t { * size_t resources_limit: The limit number of cached resources */ typedef struct ze_publication_cache_options_t { - const struct z_keyexpr_t *queryable_prefix; + const struct z_loaned_keyexpr_t *queryable_prefix; enum zcu_locality_t queryable_origin; bool queryable_complete; size_t history; @@ -844,8 +844,8 @@ typedef struct ALIGN(8) ze_owned_querying_subscriber_t { * z_reliability_t reliability: The subscription reliability. * zcu_locality_t allowed_origin: The restriction for the matching publications that will be * receive by this subscriber. - * z_keyexpr_t query_selector: The selector to be used for queries. - * z_query_target_t query_target: The target to be used for queries. + * z_loaned_keyexpr_t query_selector: The selector to be used for queries. + * z_loaned_query_target_t query_target: The target to be used for queries. * z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. * zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. * uint64_t query_timeout_ms: The timeout to be used for queries. @@ -853,15 +853,15 @@ typedef struct ALIGN(8) ze_owned_querying_subscriber_t { typedef struct ze_querying_subscriber_options_t { enum z_reliability_t reliability; enum zcu_locality_t allowed_origin; - const struct z_keyexpr_t *query_selector; - enum z_query_target_t query_target; + const struct z_loaned_keyexpr_t *query_selector; + enum z_loaned_query_target_t query_target; struct z_query_consolidation_t query_consolidation; enum zcu_reply_keyexpr_t query_accept_replies; uint64_t query_timeout_ms; } ze_querying_subscriber_options_t; -typedef struct ALIGN(8) ze_querying_subscriber_t { +typedef struct ALIGN(8) ze_loaned_querying_subscriber_t { uint8_t _0[64]; -} ze_querying_subscriber_t; +} ze_loaned_querying_subscriber_t; ZENOHC_API extern const unsigned int Z_ROUTER; ZENOHC_API extern const unsigned int Z_PEER; ZENOHC_API extern const unsigned int Z_CLIENT; @@ -883,24 +883,24 @@ ZENOHC_API bool z_bytes_check(const struct z_owned_bytes_t *payload); /** * Increments the payload's reference count, returning an owned version of it. */ -ZENOHC_API void z_bytes_clone(const struct z_bytes_t *src, struct z_owned_bytes_t *dst); +ZENOHC_API void z_bytes_clone(const struct z_loaned_bytes_t *src, struct z_owned_bytes_t *dst); /** * Decodes payload into owned bytes */ ZENOHC_API -z_error_t z_bytes_decode_into_bytes(const struct z_bytes_t *payload, +z_error_t z_bytes_decode_into_bytes(const struct z_loaned_bytes_t *payload, struct z_owned_slice_t *dst); /** * Decodes payload into bytes map. */ ZENOHC_API -z_error_t z_bytes_decode_into_bytes_map(struct z_bytes_t payload, +z_error_t z_bytes_decode_into_bytes_map(struct z_loaned_bytes_t payload, struct z_owned_slice_map_t *dst); /** * Decodes payload into null-terminated string. */ ZENOHC_API -z_error_t z_bytes_decode_into_string(const struct z_bytes_t *payload, +z_error_t z_bytes_decode_into_string(const struct z_loaned_bytes_t *payload, struct z_owned_str_t *dst); /** * Decrements the payload's reference counter, destroying it if applicable. @@ -913,25 +913,27 @@ ZENOHC_API void z_bytes_drop(struct z_owned_bytes_t *this_); */ ZENOHC_API void z_bytes_encode_from_bytes(struct z_owned_bytes_t *this_, - const struct z_slice_t *bytes); + const struct z_loaned_slice_t *bytes); /** * Encodes bytes map by copying. */ ZENOHC_API void z_bytes_encode_from_bytes_map(struct z_owned_bytes_t *this_, - const struct z_slice_map_t *bytes_map); + const struct z_loaned_slice_map_t *bytes_map); /** * Encodes a null-terminated string by aliasing. */ -ZENOHC_API void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, const struct z_str_t *s); +ZENOHC_API +void z_bytes_encode_from_string(struct z_owned_bytes_t *this_, + const struct z_loaned_str_t *s); /** * Returns total number bytes in the payload. */ -ZENOHC_API size_t z_bytes_len(const struct z_bytes_t *payload); +ZENOHC_API size_t z_bytes_len(const struct z_loaned_bytes_t *payload); /** * Loans the payload, allowing you to call functions that only need a loan of it. */ -ZENOHC_API const struct z_bytes_t *z_bytes_loan(const struct z_owned_bytes_t *payload); +ZENOHC_API const struct z_loaned_bytes_t *z_bytes_loan(const struct z_owned_bytes_t *payload); /** * The gravestone value for `z_owned_bytes_t`. */ @@ -939,14 +941,17 @@ ZENOHC_API void z_bytes_null(struct z_owned_bytes_t *this_); ZENOHC_API bool z_bytes_reader_check(const struct z_owned_bytes_reader_t *this_); ZENOHC_API void z_bytes_reader_drop(struct z_owned_bytes_reader_t *this_); ZENOHC_API -const struct z_bytes_reader_t *z_bytes_reader_loan(const struct z_owned_bytes_reader_t *reader); -ZENOHC_API struct z_bytes_reader_t *z_bytes_reader_loan_mut(struct z_owned_bytes_reader_t *reader); +const struct z_loaned_bytes_reader_t *z_bytes_reader_loan(const struct z_owned_bytes_reader_t *reader); +ZENOHC_API +struct z_loaned_bytes_reader_t *z_bytes_reader_loan_mut(struct z_owned_bytes_reader_t *reader); /** * Creates a reader for the specified `payload`. * * Returns 0 in case of success, -1 if `payload` is not valid. */ -ZENOHC_API void z_bytes_reader_new(struct z_bytes_t payload, struct z_owned_bytes_reader_t *this_); +ZENOHC_API +void z_bytes_reader_new(struct z_loaned_bytes_t payload, + struct z_owned_bytes_reader_t *this_); ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_reader_t *this_); /** * Reads data into specified destination. @@ -955,7 +960,7 @@ ZENOHC_API void z_bytes_reader_null(struct z_owned_bytes_reader_t *this_); * Returns number of bytes read. If return value is smaller than `len`, it means that end of the payload was reached. */ ZENOHC_API -size_t z_bytes_reader_read(struct z_bytes_reader_t *this_, +size_t z_bytes_reader_read(struct z_loaned_bytes_reader_t *this_, uint8_t *dest, size_t len); /** @@ -965,14 +970,9 @@ size_t z_bytes_reader_read(struct z_bytes_reader_t *this_, * Return ​0​ upon success, negative error code otherwise. */ ZENOHC_API -z_error_t z_bytes_reader_seek(struct z_bytes_reader_t *this_, +z_error_t z_bytes_reader_seek(struct z_loaned_bytes_reader_t *this_, int64_t offset, int origin); -/** - * Returns the read position indicator. - * Returns read position indicator on success or -1L if failure occurs. - */ -ZENOHC_API int64_t z_bytes_reader_tell(struct z_bytes_reader_t *this_); ZENOHC_API uint64_t z_clock_elapsed_ms(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_s(const struct z_clock_t *time); ZENOHC_API uint64_t z_clock_elapsed_us(const struct z_clock_t *time); @@ -1017,7 +1017,7 @@ ZENOHC_API struct z_owned_closure_owned_query_t z_closure_owned_query_null(void) */ ZENOHC_API void z_closure_query_call(const struct z_owned_closure_query_t *closure, - const struct z_query_t *query); + const struct z_loaned_query_t *query); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -1031,7 +1031,7 @@ ZENOHC_API struct z_owned_closure_query_t z_closure_query_null(void); */ ZENOHC_API void z_closure_reply_call(const struct z_owned_closure_reply_t *closure, - const struct z_reply_t *reply); + const struct z_loaned_reply_t *reply); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -1045,7 +1045,7 @@ ZENOHC_API struct z_owned_closure_reply_t z_closure_reply_null(void); */ ZENOHC_API void z_closure_sample_call(const struct z_owned_closure_sample_t *closure, - const struct z_sample_t *sample); + const struct z_loaned_sample_t *sample); /** * Drops the closure. Droping an uninitialized closure is a no-op. */ @@ -1071,11 +1071,13 @@ ZENOHC_API struct z_owned_closure_zid_t z_closure_zid_null(void); ZENOHC_API bool z_condvar_check(const struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_drop(struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_init(struct z_owned_condvar_t *this_); -ZENOHC_API const struct z_condvar_t *z_condvar_loan(const struct z_owned_condvar_t *this_); -ZENOHC_API struct z_condvar_t *z_condvar_loan_mut(struct z_owned_condvar_t *this_); +ZENOHC_API const struct z_loaned_condvar_t *z_condvar_loan(const struct z_owned_condvar_t *this_); +ZENOHC_API struct z_loaned_condvar_t *z_condvar_loan_mut(struct z_owned_condvar_t *this_); ZENOHC_API void z_condvar_null(struct z_owned_condvar_t *this_); -ZENOHC_API z_error_t z_condvar_signal(const struct z_condvar_t *this_); -ZENOHC_API z_error_t z_condvar_wait(const struct z_condvar_t *this_, struct z_mutex_t *m); +ZENOHC_API z_error_t z_condvar_signal(const struct z_loaned_condvar_t *this_); +ZENOHC_API +z_error_t z_condvar_wait(const struct z_loaned_condvar_t *this_, + struct z_loaned_mutex_t *m); /** * Returns ``true`` if `config` is valid. */ @@ -1091,7 +1093,7 @@ z_error_t z_config_client(struct z_owned_config_t *this_, /** * Clones the config. */ -ZENOHC_API void z_config_clone(const struct z_config_t *src, struct z_owned_config_t *dst); +ZENOHC_API void z_config_clone(const struct z_loaned_config_t *src, struct z_owned_config_t *dst); /** * Return a new, zenoh-allocated, empty configuration. * @@ -1111,13 +1113,13 @@ void z_config_default(struct z_owned_config_t *this_); */ ZENOHC_API void z_config_drop(struct z_owned_config_t *config); /** - * Returns a :c:type:`z_config_t` loaned from `s`. + * Returns a :c:type:`z_loaned_config_t` loaned from `s`. */ -ZENOHC_API const struct z_config_t *z_config_loan(const struct z_owned_config_t *this_); +ZENOHC_API const struct z_loaned_config_t *z_config_loan(const struct z_owned_config_t *this_); /** - * Returns a :c:type:`z_config_t` loaned from `s`. + * Returns a :c:type:`z_loaned_config_t` loaned from `s`. */ -ZENOHC_API struct z_config_t *z_config_loan_mut(struct z_owned_config_t *this_); +ZENOHC_API struct z_loaned_config_t *z_config_loan_mut(struct z_owned_config_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_config_t' type */ @@ -1127,15 +1129,15 @@ ZENOHC_API void z_config_null(struct z_owned_config_t *this_); */ ZENOHC_API void z_config_peer(struct z_owned_config_t *this_); /** - * Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. + * Declare a key expression. The id is returned as a :c:type:`z_loaned_keyexpr_t` with a nullptr suffix. * * This numerical id will be used on the network to save bandwidth and * ease the retrieval of the concerned resource in the routing tables. */ ZENOHC_API z_error_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr); + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr); /** * Declares a publisher for the given key expression. * @@ -1173,8 +1175,8 @@ z_error_t z_declare_keyexpr(struct z_owned_keyexpr_t *this_, */ ZENOHC_API z_error_t z_declare_publisher(struct z_owned_publisher_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, const struct z_publisher_options_t *options); /** * Creates a Queryable for the given key expression. @@ -1190,8 +1192,8 @@ z_error_t z_declare_publisher(struct z_owned_publisher_t *this_, */ ZENOHC_API z_error_t z_declare_queryable(struct z_owned_queryable_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_closure_query_t *callback, struct z_queryable_options_t *options); /** @@ -1229,8 +1231,8 @@ z_error_t z_declare_queryable(struct z_owned_queryable_t *this_, */ ZENOHC_API z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_closure_sample_t *callback, struct z_subscriber_options_t *options); /** @@ -1244,8 +1246,8 @@ z_error_t z_declare_subscriber(struct z_owned_subscriber_t *this_, * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API -z_error_t z_delete(const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, +z_error_t z_delete(const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_delete_options_t *options); /** * Constructs the default value for :c:type:`z_put_options_t`. @@ -1256,21 +1258,22 @@ ZENOHC_API void z_delete_options_default(struct z_delete_options_t *this_); */ ZENOHC_API bool z_encoding_check(const struct z_owned_encoding_t *encoding); /** - * Constructs a default :c:type:`z_encoding_t`. + * Constructs a default :c:type:`z_loaned_encoding_t`. */ -ZENOHC_API const struct z_encoding_t *z_encoding_default(void); +ZENOHC_API const struct z_loaned_encoding_t *z_encoding_default(void); /** * Frees `encoding`, invalidating it for double-drop safety. */ ZENOHC_API void z_encoding_drop(struct z_owned_encoding_t *encoding); /** - * Constructs a specific :c:type:`z_encoding_t`. + * Constructs a specific :c:type:`z_loaned_encoding_t`. */ ZENOHC_API int8_t z_encoding_from_str(struct z_owned_encoding_t *encoding, const char *s); /** - * Returns a :c:type:`z_encoding_t` loaned from `encoding`. + * Returns a :c:type:`z_loaned_encoding_t` loaned from `encoding`. */ -ZENOHC_API const struct z_encoding_t *z_encoding_loan(const struct z_owned_encoding_t *encoding); +ZENOHC_API +const struct z_loaned_encoding_t *z_encoding_loan(const struct z_owned_encoding_t *encoding); /** * Constructs a null safe-to-drop value of 'z_owned_encoding_t' type */ @@ -1292,8 +1295,8 @@ ZENOHC_API void z_encoding_null(struct z_owned_encoding_t *encoding); * options: additional options for the get. */ ZENOHC_API -z_error_t z_get(const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, +z_error_t z_get(const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, const char *parameters, struct z_owned_closure_reply_t *callback, struct z_get_options_t *options); @@ -1323,7 +1326,7 @@ ZENOHC_API void z_hello_null(struct z_owned_hello_t *this_); * Retuns 0 on success, negative values on failure */ ZENOHC_API -z_error_t z_info_peers_zid(struct z_session_t session, +z_error_t z_info_peers_zid(struct z_loaned_session_t session, struct z_owned_closure_zid_t *callback); /** * Fetches the Zenoh IDs of all connected routers. @@ -1334,7 +1337,7 @@ z_error_t z_info_peers_zid(struct z_session_t session, * Retuns 0 on success, negative values on failure. */ ZENOHC_API -z_error_t z_info_routers_zid(struct z_session_t session, +z_error_t z_info_routers_zid(struct z_loaned_session_t session, struct z_owned_closure_zid_t *callback); /** * Returns the local Zenoh ID. @@ -1343,13 +1346,13 @@ z_error_t z_info_routers_zid(struct z_session_t session, * In other words, this function returning an array of 16 zeros means you failed * to pass it a valid session. */ -ZENOHC_API struct z_id_t z_info_zid(struct z_session_t session); +ZENOHC_API struct z_id_t z_info_zid(struct z_loaned_session_t session); /** * Returns the key expression's internal string by aliasing it. * * Currently exclusive to zenoh-c */ -ZENOHC_API void z_keyexpr_as_bytes(const struct z_keyexpr_t *ke, struct z_view_slice_t *b); +ZENOHC_API void z_keyexpr_as_bytes(const struct z_loaned_keyexpr_t *ke, struct z_view_slice_t *b); /** * Canonizes the passed string in place, possibly shortening it by modifying `len`. * @@ -1388,7 +1391,7 @@ ZENOHC_API bool z_keyexpr_check(const struct z_owned_keyexpr_t *keyexpr); */ ZENOHC_API z_error_t z_keyexpr_concat(struct z_owned_keyexpr_t *this_, - const struct z_keyexpr_t *left, + const struct z_loaned_keyexpr_t *left, const char *right_start, size_t right_len); /** @@ -1398,21 +1401,23 @@ ZENOHC_API void z_keyexpr_drop(struct z_owned_keyexpr_t *keyexpr); /** * Returns ``0`` if both ``left`` and ``right`` are equal. */ -ZENOHC_API bool z_keyexpr_equals(const struct z_keyexpr_t *left, const struct z_keyexpr_t *right); +ZENOHC_API +bool z_keyexpr_equals(const struct z_loaned_keyexpr_t *left, + const struct z_loaned_keyexpr_t *right); /** * Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set * defined by ``right``. */ ZENOHC_API -bool z_keyexpr_includes(const struct z_keyexpr_t *left, - const struct z_keyexpr_t *right); +bool z_keyexpr_includes(const struct z_loaned_keyexpr_t *left, + const struct z_loaned_keyexpr_t *right); /** * Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the * sets defined by ``left`` and ``right``. */ ZENOHC_API -bool z_keyexpr_intersects(const struct z_keyexpr_t *left, - const struct z_keyexpr_t *right); +bool z_keyexpr_intersects(const struct z_loaned_keyexpr_t *left, + const struct z_loaned_keyexpr_t *right); /** * Returns ``0`` if the passed string is a valid (and canon) key expression. * Otherwise returns error value @@ -1424,12 +1429,13 @@ ZENOHC_API z_error_t z_keyexpr_is_canon(const char *start, size_t len); */ ZENOHC_API z_error_t z_keyexpr_join(struct z_owned_keyexpr_t *this_, - const struct z_keyexpr_t *left, - const struct z_keyexpr_t *right); + const struct z_loaned_keyexpr_t *left, + const struct z_loaned_keyexpr_t *right); /** - * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + * Returns a :c:type:`z_loaned_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. */ -ZENOHC_API const struct z_keyexpr_t *z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); +ZENOHC_API +const struct z_loaned_keyexpr_t *z_keyexpr_loan(const struct z_owned_keyexpr_t *key_expr); /** * Constructs a :c:type:`z_owned_keyexpr_t` departing from a string, copying the passed string. */ @@ -1450,15 +1456,10 @@ ZENOHC_API void z_keyexpr_null(struct z_owned_keyexpr_t *this_); * Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. */ ZENOHC_API -enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_keyexpr_t *left, - const struct z_keyexpr_t *right); -/** - * Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. - * The user is responsible of droping the returned string using `z_drop` - */ -ZENOHC_API void z_keyexpr_to_string(const struct z_keyexpr_t *ke, struct z_owned_str_t *s); +enum z_keyexpr_intersection_level_t z_keyexpr_relation_to(const struct z_loaned_keyexpr_t *left, + const struct z_loaned_keyexpr_t *right); /** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string without checking any of `z_loaned_keyexpr_t`'s assertions: * * - `name` MUST be valid UTF8. * - `name` MUST follow the Key Expression specification, ie: @@ -1472,14 +1473,38 @@ ZENOHC_API void z_keyexpr_to_string(const struct z_keyexpr_t *ke, struct z_owned ZENOHC_API void z_keyexpr_unchecked(struct z_view_keyexpr_t *this_, const char *name); +/** + * Returns the read position indicator. + * Returns read position indicator on success or -1L if failure occurs. + */ +ZENOHC_API int64_t z_loaned_bytes_reader_tell(struct z_loaned_bytes_reader_t *this_); +/** + * Constructs a null-terminated string departing from a :c:type:`z_loaned_keyexpr_t`. + * The user is responsible of droping the returned string using `z_drop` + */ +ZENOHC_API +void z_loaned_keyexpr_to_string(const struct z_loaned_keyexpr_t *ke, + struct z_owned_str_t *s); +ZENOHC_API z_error_t z_loaned_mutex_try_lock(struct z_loaned_mutex_t *this_); +/** + * Create a default :c:type:`z_loaned_query_target_t`. + */ +ZENOHC_API enum z_loaned_query_target_t z_loaned_query_target_default(void); +/** + * The samples timestamp + * + * Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. + */ +ZENOHC_API +bool z_loaned_sample_timestamp(const struct z_loaned_sample_t *sample, + struct z_timestamp_t *timestamp_out); ZENOHC_API bool z_mutex_check(const struct z_owned_mutex_t *this_); ZENOHC_API void z_mutex_drop(struct z_owned_mutex_t *this_); ZENOHC_API z_error_t z_mutex_init(struct z_owned_mutex_t *this_); -ZENOHC_API struct z_mutex_t *z_mutex_loan_mut(struct z_owned_mutex_t *this_); -ZENOHC_API z_error_t z_mutex_lock(struct z_mutex_t *this_); +ZENOHC_API struct z_loaned_mutex_t *z_mutex_loan_mut(struct z_owned_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_lock(struct z_loaned_mutex_t *this_); ZENOHC_API void z_mutex_null(struct z_owned_mutex_t *this_); -ZENOHC_API z_error_t z_mutex_try_lock(struct z_mutex_t *this_); -ZENOHC_API z_error_t z_mutex_unlock(struct z_mutex_t *this_); +ZENOHC_API z_error_t z_mutex_unlock(struct z_loaned_mutex_t *this_); /** * Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. * Config value is always consumed upon function return. @@ -1502,7 +1527,7 @@ ZENOHC_API bool z_publisher_check(const struct z_owned_publisher_t *this_); * ``0`` in case of success, ``1`` in case of failure. */ ZENOHC_API -z_error_t z_publisher_delete(const struct z_publisher_t *publisher, +z_error_t z_publisher_delete(const struct z_loaned_publisher_t *publisher, struct z_publisher_delete_options_t _options); /** * Constructs the default values for the delete operation via a publisher entity. @@ -1514,11 +1539,13 @@ ZENOHC_API void z_publisher_delete_options_default(struct z_publisher_delete_opt /** * Returns the key expression of the publisher */ -ZENOHC_API const struct z_keyexpr_t *z_publisher_keyexpr(const struct z_publisher_t *publisher); +ZENOHC_API +const struct z_loaned_keyexpr_t *z_publisher_keyexpr(const struct z_loaned_publisher_t *publisher); /** - * Returns a :c:type:`z_publisher_t` loaned from `p`. + * Returns a :c:type:`z_loaned_publisher_t` loaned from `p`. */ -ZENOHC_API const struct z_publisher_t *z_publisher_loan(const struct z_owned_publisher_t *this_); +ZENOHC_API +const struct z_loaned_publisher_t *z_publisher_loan(const struct z_owned_publisher_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_publisher_t' type */ @@ -1544,7 +1571,7 @@ ZENOHC_API void z_publisher_options_default(struct z_publisher_options_t *this_) * ``0`` in case of success, negative values in case of failure. */ ZENOHC_API -z_error_t z_publisher_put(const struct z_publisher_t *publisher, +z_error_t z_publisher_put(const struct z_loaned_publisher_t *publisher, struct z_owned_bytes_t *payload, struct z_publisher_put_options_t *options); /** @@ -1567,8 +1594,8 @@ ZENOHC_API void z_publisher_put_options_default(struct z_publisher_put_options_t * ``0`` in case of success, negative error values in case of failure. */ ZENOHC_API -z_error_t z_put(const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, +z_error_t z_put(const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_bytes_t *payload, struct z_put_options_t *options); /** @@ -1580,7 +1607,7 @@ ZENOHC_API void z_put_options_default(struct z_put_options_t *this_); * * Returns NULL if query does not contain an attachment. */ -ZENOHC_API const struct z_bytes_t *z_query_attachment(const struct z_query_t *query); +ZENOHC_API const struct z_loaned_bytes_t *z_query_attachment(const struct z_loaned_query_t *query); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ @@ -1613,7 +1640,7 @@ bool z_query_check(const struct z_owned_query_t *query); * This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). */ ZENOHC_API -void z_query_clone(const struct z_query_t *this_, +void z_query_clone(const struct z_loaned_query_t *this_, struct z_owned_query_t *dst); /** * Automatic query consolidation strategy selection. @@ -1652,18 +1679,18 @@ void z_query_drop(struct z_owned_query_t *this_); /** * Checks if query contains a payload value. */ -ZENOHC_API bool z_query_has_value(const struct z_query_t *query); +ZENOHC_API bool z_query_has_value(const struct z_loaned_query_t *query); /** * Get a query's key by aliasing it. */ -ZENOHC_API const struct z_keyexpr_t *z_query_keyexpr(const struct z_query_t *query); +ZENOHC_API const struct z_loaned_keyexpr_t *z_query_keyexpr(const struct z_loaned_query_t *query); /** * Aliases the query. * * This function may not be called with the null pointer, but can be called with the gravestone value. */ ZENOHC_API -const struct z_query_t *z_query_loan(const struct z_owned_query_t *this_); +const struct z_loaned_query_t *z_query_loan(const struct z_owned_query_t *this_); /** * The gravestone value of `z_owned_query_t`. */ @@ -1672,7 +1699,7 @@ ZENOHC_API void z_query_null(struct z_owned_query_t *this_); * Get a query's `value selector `_ by aliasing it. */ ZENOHC_API -void z_query_parameters(const struct z_query_t *query, +void z_query_parameters(const struct z_loaned_query_t *query, struct z_view_slice_t *parameters); /** * Send a reply to a query. @@ -1691,18 +1718,14 @@ void z_query_parameters(const struct z_query_t *query, * The payload and all owned options fields are consumed upon function return. */ ZENOHC_API -z_error_t z_query_reply(struct z_query_t query, - struct z_keyexpr_t key_expr, +z_error_t z_query_reply(struct z_loaned_query_t query, + struct z_loaned_keyexpr_t key_expr, struct z_owned_bytes_t *payload, struct z_query_reply_options_t *options); /** * Constructs the default value for :c:type:`z_query_reply_options_t`. */ ZENOHC_API void z_query_reply_options_default(struct z_query_reply_options_t *this_); -/** - * Create a default :c:type:`z_query_target_t`. - */ -ZENOHC_API enum z_query_target_t z_query_target_default(void); /** * Gets a query's `payload value `_ by aliasing it. * @@ -1710,7 +1733,7 @@ ZENOHC_API enum z_query_target_t z_query_target_default(void); * Before calling this funciton, the user must ensure that `z_query_has_value` returns true. */ ZENOHC_API -const struct z_value_t *z_query_value(const struct z_query_t *query); +const struct z_loaned_value_t *z_query_value(const struct z_loaned_query_t *query); /** * Returns ``true`` if `qable` is valid. */ @@ -1751,7 +1774,7 @@ ZENOHC_API struct z_owned_reply_channel_t z_reply_channel_null(void); * Returns ``true`` if `reply` is valid. */ ZENOHC_API bool z_reply_check(const struct z_owned_reply_t *this_); -ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, const struct z_reply_t *reply); +ZENOHC_API void z_reply_clone(struct z_owned_reply_t *this_, const struct z_loaned_reply_t *reply); /** * Frees `reply`, invalidating it for double-drop safety. */ @@ -1762,15 +1785,15 @@ ZENOHC_API void z_reply_drop(struct z_owned_reply_t *this_); * Returns null if reply does not contain a error (i. e. if :c:func:`z_reply_is_ok` returns ``true``). */ ZENOHC_API -const struct z_value_t *z_reply_err(const struct z_reply_t *reply); +const struct z_loaned_value_t *z_reply_err(const struct z_loaned_reply_t *reply); /** * Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. * * If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. */ ZENOHC_API -bool z_reply_is_ok(const struct z_reply_t *reply); -ZENOHC_API const struct z_reply_t *z_reply_loan(struct z_owned_reply_t *this_); +bool z_reply_is_ok(const struct z_loaned_reply_t *reply); +ZENOHC_API const struct z_loaned_reply_t *z_reply_loan(struct z_owned_reply_t *this_); /** * Returns an invalidated :c:type:`z_owned_reply_t`. * @@ -1787,7 +1810,7 @@ ZENOHC_API void z_reply_null(struct z_owned_reply_t *this_); * Returns null if reply does not contains a sample (i. e. if :c:func:`z_reply_is_ok` returns ``false``). */ ZENOHC_API -const struct z_sample_t *z_reply_ok(const struct z_reply_t *reply); +const struct z_loaned_sample_t *z_reply_ok(const struct z_loaned_reply_t *reply); /** * The qos with which the sample was received. * TODO: split to methods (priority, congestion_control, express) @@ -1795,7 +1818,8 @@ const struct z_sample_t *z_reply_ok(const struct z_reply_t *reply); * * Returns NULL if sample does not contain an attachement. */ -ZENOHC_API const struct z_bytes_t *z_sample_attachment(const struct z_sample_t *sample); +ZENOHC_API +const struct z_loaned_bytes_t *z_sample_attachment(const struct z_loaned_sample_t *sample); /** * Returns `true` if `sample` is valid. * @@ -1807,37 +1831,32 @@ bool z_sample_check(const struct zc_owned_sample_t *sample); /** * Clone a sample in the cheapest way available. */ -ZENOHC_API void z_sample_clone(const struct z_sample_t *src, struct zc_owned_sample_t *dst); -ZENOHC_API enum z_congestion_control_t z_sample_congestion_control(const struct z_sample_t *sample); +ZENOHC_API void z_sample_clone(const struct z_loaned_sample_t *src, struct zc_owned_sample_t *dst); +ZENOHC_API +enum z_congestion_control_t z_sample_congestion_control(const struct z_loaned_sample_t *sample); /** * The encoding of the payload. */ -ZENOHC_API const struct z_encoding_t *z_sample_encoding(const struct z_sample_t *sample); -ZENOHC_API bool z_sample_express(const struct z_sample_t *sample); +ZENOHC_API +const struct z_loaned_encoding_t *z_sample_encoding(const struct z_loaned_sample_t *sample); +ZENOHC_API bool z_sample_express(const struct z_loaned_sample_t *sample); /** * The Key Expression of the sample. * * `sample` is aliased by its return value. */ -ZENOHC_API const struct z_keyexpr_t *z_sample_keyexpr(const struct z_sample_t *sample); +ZENOHC_API +const struct z_loaned_keyexpr_t *z_sample_keyexpr(const struct z_loaned_sample_t *sample); /** * The sample's kind (put or delete). */ -ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_sample_t *sample); +ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_loaned_sample_t *sample); /** * The sample's data, the return value aliases the sample. * */ -ZENOHC_API const struct z_bytes_t *z_sample_payload(const struct z_sample_t *sample); -ZENOHC_API enum z_priority_t z_sample_priority(const struct z_sample_t *sample); -/** - * The samples timestamp - * - * Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. - */ -ZENOHC_API -bool z_sample_timestamp(const struct z_sample_t *sample, - struct z_timestamp_t *timestamp_out); +ZENOHC_API const struct z_loaned_bytes_t *z_sample_payload(const struct z_loaned_sample_t *sample); +ZENOHC_API enum z_priority_t z_sample_priority(const struct z_loaned_sample_t *sample); /** * Scout for routers and/or peers. * @@ -1856,24 +1875,24 @@ ZENOHC_API void z_scouting_config_default(struct z_owned_scouting_config_t *this ZENOHC_API void z_scouting_config_drop(struct z_owned_scouting_config_t *config); ZENOHC_API void z_scouting_config_from(struct z_owned_scouting_config_t *this_, - const struct z_config_t *config); + const struct z_loaned_config_t *config); ZENOHC_API void z_scouting_config_null(struct z_owned_scouting_config_t *this_); /** * Returns ``true`` if `session` is valid. */ ZENOHC_API bool z_session_check(const struct z_owned_session_t *this_); /** - * Returns a :c:type:`z_session_t` loaned from `s`. + * Returns a :c:type:`z_loaned_session_t` loaned from `s`. * * This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. * * # Safety - * The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, + * The returned `z_loaned_session_t` aliases `z_owned_session_t`'s internal allocation, * attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) * have been destroyed is UB (likely SEGFAULT) */ ZENOHC_API -const struct z_session_t *z_session_loan(const struct z_owned_session_t *this_); +const struct z_loaned_session_t *z_session_loan(const struct z_owned_session_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_session_t' type */ @@ -1881,8 +1900,8 @@ ZENOHC_API void z_session_null(struct z_owned_session_t *this_); ZENOHC_API int8_t z_sleep_ms(size_t time); ZENOHC_API int8_t z_sleep_s(size_t time); ZENOHC_API int8_t z_sleep_us(size_t time); -ZENOHC_API void z_slice_clone(const struct z_slice_t *this_, struct z_owned_slice_t *dst); -ZENOHC_API const uint8_t *z_slice_data(const struct z_slice_t *this_); +ZENOHC_API void z_slice_clone(const struct z_loaned_slice_t *this_, struct z_owned_slice_t *dst); +ZENOHC_API const uint8_t *z_slice_data(const struct z_loaned_slice_t *this_); /** * Frees `this` and invalidates it for double-drop safety. */ @@ -1899,8 +1918,8 @@ ZENOHC_API void z_slice_empty(struct z_owned_slice_t *this_); ZENOHC_API void z_slice_from_str(struct z_owned_slice_t *this_, const char *str); -ZENOHC_API size_t z_slice_len(const struct z_slice_t *this_); -ZENOHC_API const struct z_slice_t *z_slice_loan(const struct z_owned_slice_t *this_); +ZENOHC_API size_t z_slice_len(const struct z_loaned_slice_t *this_); +ZENOHC_API const struct z_loaned_slice_t *z_slice_loan(const struct z_owned_slice_t *this_); /** * Returns `true` if the map is not in its gravestone state */ @@ -1917,8 +1936,8 @@ ZENOHC_API void z_slice_map_drop(struct z_owned_slice_map_t *this_); * Will return NULL if the key is not present in the map. */ ZENOHC_API -const struct z_slice_t *z_slice_map_get(const struct z_slice_map_t *this_, - const struct z_slice_t *key); +const struct z_loaned_slice_t *z_slice_map_get(const struct z_loaned_slice_map_t *this_, + const struct z_loaned_slice_t *key); /** * Associates `value` to `key` in the map, aliasing them. * @@ -1927,32 +1946,33 @@ const struct z_slice_t *z_slice_map_get(const struct z_slice_map_t *this_, * Returns 1 if there was already an entry associated with the key, 0 otherwise. */ ZENOHC_API -z_error_t z_slice_map_insert_by_alias(struct z_slice_map_t *this_, - const struct z_slice_t *key, - const struct z_slice_t *value); +z_error_t z_slice_map_insert_by_alias(struct z_loaned_slice_map_t *this_, + const struct z_loaned_slice_t *key, + const struct z_loaned_slice_t *value); /** * Associates `value` to `key` in the map, copying them to obtain ownership: `key` and `value` are not aliased past the function's return. * * Returns 1 if there was already an entry associated with the key, 0 otherwise. */ ZENOHC_API -uint8_t z_slice_map_insert_by_copy(struct z_slice_map_t *this_, - const struct z_slice_t *key, - const struct z_slice_t *value); +uint8_t z_slice_map_insert_by_copy(struct z_loaned_slice_map_t *this_, + const struct z_loaned_slice_t *key, + const struct z_loaned_slice_t *value); /** * Returns true if the map is empty, false otherwise. */ -ZENOHC_API bool z_slice_map_is_empty(const struct z_slice_map_t *this_); +ZENOHC_API bool z_slice_map_is_empty(const struct z_loaned_slice_map_t *this_); ZENOHC_API -void z_slice_map_iterate(const struct z_slice_map_t *this_, +void z_slice_map_iterate(const struct z_loaned_slice_map_t *this_, z_slice_map_iter_body_t body, void *context); /** * Returns number of key-value pairs in the map. */ -ZENOHC_API size_t z_slice_map_len(const struct z_slice_map_t *this_); -ZENOHC_API const struct z_slice_map_t *z_slice_map_loan(const struct z_owned_slice_map_t *this_); -ZENOHC_API struct z_slice_map_t *z_slice_map_loan_mut(struct z_owned_slice_map_t *this_); +ZENOHC_API size_t z_slice_map_len(const struct z_loaned_slice_map_t *this_); +ZENOHC_API +const struct z_loaned_slice_map_t *z_slice_map_loan(const struct z_owned_slice_map_t *this_); +ZENOHC_API struct z_loaned_slice_map_t *z_slice_map_loan_mut(struct z_owned_slice_map_t *this_); /** * Constructs a new empty map. */ @@ -1982,7 +2002,7 @@ ZENOHC_API const struct z_str_array_t *z_str_array_loan(const struct z_owned_str * Returns ``true`` if `s` is a valid string */ ZENOHC_API bool z_str_check(const struct z_owned_str_t *this_); -ZENOHC_API void z_str_clone(const struct z_str_t *this_, struct z_owned_str_t *dst); +ZENOHC_API void z_str_clone(const struct z_loaned_str_t *this_, struct z_owned_str_t *dst); /** * Frees `z_owned_str_t`, invalidating it for double-drop safety. */ @@ -1995,9 +2015,9 @@ ZENOHC_API void z_str_empty(struct z_owned_str_t *this_); */ ZENOHC_API void z_str_from_substring(struct z_owned_str_t *this_, const char *str, size_t len); /** - * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. + * Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_owned_str_t`. */ -ZENOHC_API const struct z_str_t *z_str_loan(const struct z_owned_str_t *this_); +ZENOHC_API const struct z_loaned_str_t *z_str_loan(const struct z_owned_str_t *this_); /** * Returns undefined `z_owned_str_t` */ @@ -2017,11 +2037,13 @@ ZENOHC_API bool z_subscriber_check(const struct z_owned_subscriber_t *subscriber /** * Returns the key expression of the subscriber. */ -ZENOHC_API const struct z_keyexpr_t *z_subscriber_keyexpr(const struct z_subscriber_t *subscriber); +ZENOHC_API +const struct z_loaned_keyexpr_t *z_subscriber_keyexpr(const struct z_loaned_subscriber_t *subscriber); /** - * Returns a :c:type:`z_subscriber_t` loaned from `this`. + * Returns a :c:type:`z_loaned_subscriber_t` loaned from `this`. */ -ZENOHC_API const struct z_subscriber_t *z_subscriber_loan(const struct z_owned_subscriber_t *this_); +ZENOHC_API +const struct z_loaned_subscriber_t *z_subscriber_loan(const struct z_owned_subscriber_t *this_); /** * Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type */ @@ -2057,7 +2079,7 @@ ZENOHC_API uint64_t z_timestamp_npt64_time(const struct z_timestamp_t *timestamp * The keyxpr is consumed. */ ZENOHC_API -z_error_t z_undeclare_keyexpr(const struct z_session_t *session, +z_error_t z_undeclare_keyexpr(const struct z_loaned_session_t *session, struct z_owned_keyexpr_t *kexpr); /** * Undeclares the given :c:type:`z_owned_publisher_t`, droping it and invalidating it for double-drop safety. @@ -2077,12 +2099,12 @@ ZENOHC_API z_error_t z_undeclare_queryable(struct z_owned_queryable_t *qable); ZENOHC_API z_error_t z_undeclare_subscriber(struct z_owned_subscriber_t *subscriber); /** - * Constructs a :c:type:`z_keyexpr_t` departing from a string. + * Constructs a :c:type:`z_loaned_keyexpr_t` departing from a string. * It is a loaned key expression that aliases `name`. */ ZENOHC_API z_error_t z_view_keyexpr(struct z_view_keyexpr_t *this_, const char *name); /** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. * The string is canonized in-place before being passed to keyexpr. * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). */ @@ -2094,14 +2116,14 @@ z_error_t z_view_keyexpr_autocanonize(struct z_view_keyexpr_t *this_, */ ZENOHC_API bool z_view_keyexpr_check(const struct z_view_keyexpr_t *keyexpr); /** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. */ ZENOHC_API z_error_t z_view_keyexpr_from_slice(struct z_view_keyexpr_t *this_, const char *name, size_t len); /** - * Constructs a :c:type:`z_keyexpr_t` by aliasing a string. + * Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. * The string is canonized in-place before being passed to keyexpr. * May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). */ @@ -2110,7 +2132,7 @@ z_error_t z_view_keyexpr_from_slice_autocanonize(struct z_view_keyexpr_t *this_, char *name, size_t *len); /** - * Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: + * Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_loaned_keyexpr_t`'s assertions: * - `name` MUST be valid UTF8. * - `name` MUST follow the Key Expression specification, ie: * - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. @@ -2124,9 +2146,10 @@ void z_view_keyexpr_from_slice_unchecked(struct z_view_keyexpr_t *this_, const char *start, size_t len); /** - * Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. + * Returns a :c:type:`z_loaned_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. */ -ZENOHC_API const struct z_keyexpr_t *z_view_keyexpr_loan(const struct z_view_keyexpr_t *key_expr); +ZENOHC_API +const struct z_loaned_keyexpr_t *z_view_keyexpr_loan(const struct z_view_keyexpr_t *key_expr); ZENOHC_API void z_view_keyexpr_null(struct z_view_keyexpr_t *this_); /** * Returns ``true`` if `this` is initialized. @@ -2142,19 +2165,19 @@ ZENOHC_API void z_view_slice_empty(struct z_view_slice_t *this_); * Calling this with `str == NULL` is equivalent to `z_view_slice_null`. */ ZENOHC_API void z_view_slice_from_str(struct z_view_slice_t *this_, const char *str); -ZENOHC_API const struct z_slice_t *z_view_slice_loan(const struct z_view_slice_t *this_); +ZENOHC_API const struct z_loaned_slice_t *z_view_slice_loan(const struct z_view_slice_t *this_); ZENOHC_API void z_view_slice_null(struct z_view_slice_t *this_); /** * Constructs a `len` bytes long view starting at `start`. */ ZENOHC_API void z_view_slice_wrap(struct z_view_slice_t *this_, const uint8_t *start, size_t len); -ZENOHC_API const char *z_view_str_data(const struct z_str_t *this_); +ZENOHC_API const char *z_view_str_data(const struct z_loaned_str_t *this_); ZENOHC_API void z_view_str_empty(struct z_view_str_t *this_); -ZENOHC_API size_t z_view_str_len(const struct z_str_t *this_); +ZENOHC_API size_t z_view_str_len(const struct z_loaned_str_t *this_); /** - * Returns :c:type:`z_str_t` structure loaned from :c:type:`z_view_str_t`. + * Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_view_str_t`. */ -ZENOHC_API const struct z_str_t *z_view_str_loan(const struct z_view_str_t *this_); +ZENOHC_API const struct z_loaned_str_t *z_view_str_loan(const struct z_view_str_t *this_); /** * Returns undefined `z_owned_str_t` */ @@ -2196,7 +2219,7 @@ z_error_t zc_config_from_str(struct z_owned_config_t *this_, * Use `z_drop` to safely deallocate this string */ ZENOHC_API -z_error_t zc_config_get(const struct z_config_t *config, +z_error_t zc_config_get(const struct z_loaned_config_t *config, const char *key, struct z_owned_str_t *value_string); /** @@ -2205,14 +2228,14 @@ z_error_t zc_config_get(const struct z_config_t *config, * Returns 0 if successful, a negative value otherwise. */ ZENOHC_API -z_error_t zc_config_insert_json(struct z_config_t *config, +z_error_t zc_config_insert_json(struct z_loaned_config_t *config, const char *key, const char *value); /** * Converts `config` into a JSON-serialized string, such as '{"mode":"client","connect":{"endpoints":["tcp/127.0.0.1:7447"]}}'. */ ZENOHC_API -z_error_t zc_config_to_string(const struct z_config_t *config, +z_error_t zc_config_to_string(const struct z_loaned_config_t *config, struct z_owned_str_t *config_string); /** * Initialises the zenoh runtime logger. @@ -2227,8 +2250,8 @@ void zc_liveliness_declaration_options_default(struct zc_liveliness_declaration_ * Declares a subscriber on liveliness tokens that intersect `key`. * * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t key_expr: The key expression to subscribe. + * z_loaned_session_t session: The zenoh session. + * z_loaned_keyexpr_t key_expr: The key expression to subscribe. * z_owned_closure_sample_t callback: The callback function that will be called each time a * liveliness token status changed. * zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. @@ -2241,8 +2264,8 @@ void zc_liveliness_declaration_options_default(struct zc_liveliness_declaration_ */ ZENOHC_API z_error_t zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_closure_sample_t *callback, struct zc_liveliness_declare_subscriber_options_t *_options); /** @@ -2255,8 +2278,8 @@ z_error_t zc_liveliness_declare_subscriber(struct z_owned_subscriber_t *this_, */ ZENOHC_API z_error_t zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct zc_liveliness_declaration_options_t *_options); /** * Queries liveliness tokens currently on the network with a key expression intersecting with `key`. @@ -2266,8 +2289,8 @@ z_error_t zc_liveliness_declare_token(struct zc_owned_liveliness_token_t *this_, * Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. */ ZENOHC_API -z_error_t zc_liveliness_get(const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, +z_error_t zc_liveliness_get(const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_closure_reply_t *callback, struct zc_liveliness_get_options_t *options); /** @@ -2349,7 +2372,7 @@ ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); * * Calling this function using a dropped sample is undefined behaviour. */ -ZENOHC_API const struct z_sample_t *zc_sample_loan(const struct zc_owned_sample_t *sample); +ZENOHC_API const struct z_loaned_sample_t *zc_sample_loan(const struct zc_owned_sample_t *sample); ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); /** * Increments the session's reference count, returning a new owning handle. @@ -2378,15 +2401,15 @@ ZENOHC_API enum zcu_locality_t zcu_locality_default(void); */ ZENOHC_API z_error_t zcu_publisher_matching_listener_callback(struct zcu_owned_matching_listener_t *this_, - const struct z_publisher_t *publisher, + const struct z_loaned_publisher_t *publisher, struct zcu_owned_closure_matching_status_t *callback); ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); /** * Declares a Publication Cache. * * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t key_expr: The key expression to publish. + * z_loaned_session_t session: The zenoh session. + * z_loaned_keyexpr_t key_expr: The key expression to publish. * ze_publication_cache_options_t options: Additional options for the publication_cache. * * Returns: @@ -2409,15 +2432,15 @@ ZENOHC_API enum zcu_reply_keyexpr_t zcu_reply_keyexpr_default(void); */ ZENOHC_API z_error_t ze_declare_publication_cache(struct ze_owned_publication_cache_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct ze_publication_cache_options_t *options); /** * Declares a Querying Subscriber for a given key expression. * * Parameters: - * z_session_t session: The zenoh session. - * z_keyexpr_t keyexpr: The key expression to subscribe. + * z_loaned_session_t session: The zenoh session. + * z_loaned_keyexpr_t keyexpr: The key expression to subscribe. * z_owned_closure_sample_t callback: The callback function that will be called each time a data matching the subscribed expression is received. * ze_querying_subscriber_options_t options: Additional options for the querying subscriber. * @@ -2447,8 +2470,8 @@ z_error_t ze_declare_publication_cache(struct ze_owned_publication_cache_t *this */ ZENOHC_API z_error_t ze_declare_querying_subscriber(struct ze_owned_querying_subscriber_t *this_, - const struct z_session_t *session, - const struct z_keyexpr_t *key_expr, + const struct z_loaned_session_t *session, + const struct z_loaned_keyexpr_t *key_expr, struct z_owned_closure_sample_t *callback, struct ze_querying_subscriber_options_t *options); /** @@ -2472,14 +2495,14 @@ ZENOHC_API bool ze_querying_subscriber_check(const struct ze_owned_querying_subs * The queried samples will be merged with the received publications and made available in the subscriber callback. */ ZENOHC_API -z_error_t ze_querying_subscriber_get(const struct ze_querying_subscriber_t *sub, - const struct z_keyexpr_t *selector, +z_error_t ze_querying_subscriber_get(const struct ze_loaned_querying_subscriber_t *sub, + const struct z_loaned_keyexpr_t *selector, const struct z_get_options_t *options); /** * Returns a :c:type:`ze_querying_subscriber_loan` loaned from `this`. */ ZENOHC_API -const struct ze_querying_subscriber_t *ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); +const struct ze_loaned_querying_subscriber_t *ze_querying_subscriber_loan(const struct ze_owned_querying_subscriber_t *this_); /** * Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type */ diff --git a/include/zenoh_concrete.h b/include/zenoh_concrete.h index a7cc575ab..f9f91304e 100644 --- a/include/zenoh_concrete.h +++ b/include/zenoh_concrete.h @@ -36,12 +36,12 @@ typedef struct ALIGN(8) z_owned_session_t { uint8_t _0[8]; } z_owned_session_t; -typedef struct ALIGN(8) z_query_t { +typedef struct ALIGN(8) z_loaned_query_t { uint8_t _0[16]; -} z_query_t; -typedef struct ALIGN(8) z_session_t { +} z_loaned_query_t; +typedef struct ALIGN(8) z_loaned_session_t { uint8_t _0[40]; -} z_session_t; +} z_loaned_session_t; /** * An owned zenoh queryable. * diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index fbd60560b..7b6bbe214 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -19,7 +19,7 @@ ze_owned_querying_subscriber_t : ze_querying_subscriber_loan,\ z_owned_reply_t : z_reply_loan, \ z_owned_mutex_t : z_mutex_loan, \ - z_condvar_t : z_condvar_loan, \ + z_loaned_condvar_t : z_condvar_loan, \ z_owned_bytes_reader_t : z_bytes_reader_loan \ )(&x) @@ -137,39 +137,39 @@ template struct zenoh_loan_type { typedef T type; }; template inline typename zenoh_loan_type::type z_loan(const T&); -template<> struct zenoh_loan_type{ typedef z_session_t type; }; -template<> struct zenoh_loan_type{ typedef z_keyexpr_t type; }; -template<> struct zenoh_loan_type{ typedef z_config_t type; }; -template<> struct zenoh_loan_type{ typedef z_publisher_t type; }; -template<> struct zenoh_loan_type{ typedef z_subscriber_t type; }; -template<> struct zenoh_loan_type{ typedef z_query_t type; }; -template<> struct zenoh_loan_type{ typedef z_encoding_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_session_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_keyexpr_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_config_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_publisher_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_subscriber_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_query_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_encoding_t type; }; template<> struct zenoh_loan_type{ typedef z_hello_t type; }; template<> struct zenoh_loan_type{ typedef const char* type; }; -template<> struct zenoh_loan_type{ typedef z_bytes_t type; }; -template<> struct zenoh_loan_type{ typedef z_bytes_reader_t type; }; -template<> struct zenoh_loan_type{ typedef ze_querying_subscriber_t type; }; -template<> struct zenoh_loan_type{ typedef z_slice_t type; }; -template<> struct zenoh_loan_type{ typedef z_slice_map_t type; }; -template<> struct zenoh_loan_type{ typedef z_mutex_t type; }; -template<> struct zenoh_loan_type{ typedef z_condvar_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_bytes_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_bytes_reader_t type; }; +template<> struct zenoh_loan_type{ typedef ze_loaned_querying_subscriber_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_slice_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_slice_map_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_mutex_t type; }; +template<> struct zenoh_loan_type{ typedef z_loaned_condvar_t type; }; -template<> inline z_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } -template<> inline z_keyexpr_t z_loan(const z_owned_keyexpr_t& x) { return z_keyexpr_loan(&x); } -template<> inline z_config_t z_loan(const z_owned_config_t& x) { return z_config_loan(&x); } -template<> inline z_publisher_t z_loan(const z_owned_publisher_t& x) { return z_publisher_loan(&x); } -template<> inline z_subscriber_t z_loan(const z_owned_subscriber_t& x) { return z_subscriber_loan(&x); } -template<> inline z_encoding_t z_loan(const z_owned_encoding_t& x) { return z_encoding_loan(&x); } +template<> inline z_loaned_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } +template<> inline z_loaned_keyexpr_t z_loan(const z_owned_keyexpr_t& x) { return z_keyexpr_loan(&x); } +template<> inline z_loaned_config_t z_loan(const z_owned_config_t& x) { return z_config_loan(&x); } +template<> inline z_loaned_publisher_t z_loan(const z_owned_publisher_t& x) { return z_publisher_loan(&x); } +template<> inline z_loaned_subscriber_t z_loan(const z_owned_subscriber_t& x) { return z_subscriber_loan(&x); } +template<> inline z_loaned_encoding_t z_loan(const z_owned_encoding_t& x) { return z_encoding_loan(&x); } template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } -template<> inline z_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } +template<> inline z_loaned_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } -template<> inline z_bytes_t z_loan(const z_owned_bytes_t& x) { return z_bytes_loan(&x); } -template<> inline z_bytes_reader_t z_loan(const z_owned_bytes_reader_t& x) { return z_bytes_reader_loan(&x); } -template<> inline ze_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } -template<> inline z_slice_t z_loan(const z_owned_slice_t& x) { return z_slice_loan(&x); } -template<> inline z_slice_map_t z_loan(const z_owned_slice_map_t& x) { return z_slice_map_loan(&x); } -template<> inline z_mutex_t z_loan(const z_owned_mutex_t& x) { return z_mutex_loan(&x); } -template<> inline z_condvar_t z_loan(const z_owned_condvar_t& x) { return z_condvar_loan(&x); } +template<> inline z_loaned_bytes_t z_loan(const z_owned_bytes_t& x) { return z_bytes_loan(&x); } +template<> inline z_loaned_bytes_reader_t z_loan(const z_owned_bytes_reader_t& x) { return z_bytes_reader_loan(&x); } +template<> inline ze_loaned_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } +template<> inline z_loaned_slice_t z_loan(const z_owned_slice_t& x) { return z_slice_loan(&x); } +template<> inline z_loaned_slice_map_t z_loan(const z_owned_slice_map_t& x) { return z_slice_map_loan(&x); } +template<> inline z_loaned_mutex_t z_loan(const z_owned_mutex_t& x) { return z_mutex_loan(&x); } +template<> inline z_loaned_condvar_t z_loan(const z_owned_condvar_t& x) { return z_condvar_loan(&x); } template struct zenoh_drop_type { typedef T type; }; template inline typename zenoh_drop_type::type z_drop(T*); @@ -288,9 +288,9 @@ inline bool z_check(const z_owned_mutex_t& v) { return z_mutex_check(&v); } inline bool z_check(const z_owned_condvar_t& v) { return z_condvar_check(&v); } inline bool z_check(const z_owned_task_t& v) { return z_task_check(&v); } -inline void z_call(const struct z_owned_closure_sample_t &closure, const struct z_sample_t *sample) +inline void z_call(const struct z_owned_closure_sample_t &closure, const struct z_loaned_sample_t *sample) { z_closure_sample_call(&closure, sample); } -inline void z_call(const struct z_owned_closure_query_t &closure, const struct z_query_t *query) +inline void z_call(const struct z_owned_closure_query_t &closure, const struct z_loaned_query_t *query) { z_closure_query_call(&closure, query); } inline void z_call(const struct z_owned_closure_reply_t &closure, struct z_owned_reply_t *sample) { z_closure_reply_call(&closure, sample); } diff --git a/splitguide.yaml b/splitguide.yaml index 5469f25de..6614c0356 100644 --- a/splitguide.yaml +++ b/splitguide.yaml @@ -7,7 +7,7 @@ zenoh_concrete.h: - :includes - :defines - z_owned_session_t! - - z_session_t! + - z_loaned_session_t! - z_owned_subscriber_t! - - z_query_t! + - z_loaned_query_t! - z_owned_queryable_t! diff --git a/src/closures/query_channel.rs b/src/closures/query_channel.rs index 1cd1f063d..c4bf36a2a 100644 --- a/src/closures/query_channel.rs +++ b/src/closures/query_channel.rs @@ -1,6 +1,6 @@ use crate::{ - z_closure_query_drop, z_owned_closure_query_t, z_owned_query_t, z_query_clone, z_query_null, - z_query_t, + z_closure_query_drop, z_loaned_query_t, z_owned_closure_query_t, z_owned_query_t, + z_query_clone, z_query_null, }; use libc::c_void; use std::{ @@ -50,7 +50,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver if bound == 0 { let (tx, rx) = std::sync::mpsc::channel(); ( - From::from(move |query: &z_query_t| { + From::from(move |query: &z_loaned_query_t| { let mut this = MaybeUninit::::uninit(); z_query_clone(query, &mut this as *mut MaybeUninit); let this = this.assume_init(); @@ -63,7 +63,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_query_t, Receiver } else { let (tx, rx) = std::sync::mpsc::sync_channel(bound); ( - From::from(move |query: &z_query_t| { + From::from(move |query: &z_loaned_query_t| { let mut this = MaybeUninit::::uninit(); z_query_clone(query, &mut this as *mut MaybeUninit); let this = this.assume_init(); diff --git a/src/closures/query_closure.rs b/src/closures/query_closure.rs index 0512e28c8..98f774cd8 100644 --- a/src/closures/query_closure.rs +++ b/src/closures/query_closure.rs @@ -1,10 +1,10 @@ -use crate::{z_owned_query_t, z_query_t}; +use crate::{z_loaned_query_t, z_owned_query_t}; use libc::c_void; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// /// Members: /// void *context: a pointer to an arbitrary state. -/// void *call(z_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. +/// void *call(z_loaned_query_t, const void *context): the typical callback function. `context` will be passed as its last argument. /// void *drop(void*): allows the callback's state to be freed. /// /// Closures are not guaranteed not to be called concurrently. @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_query_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } impl z_owned_closure_query_t { @@ -45,7 +45,10 @@ pub extern "C" fn z_closure_query_null() -> z_owned_closure_query_t { } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_query_call(closure: &z_owned_closure_query_t, query: &z_query_t) { +pub extern "C" fn z_closure_query_call( + closure: &z_owned_closure_query_t, + query: &z_loaned_query_t, +) { match closure.call { Some(call) => call(query, closure.context), None => log::error!("Attempted to call an uninitialized closure!"), @@ -57,10 +60,13 @@ pub extern "C" fn z_closure_query_drop(closure: &mut z_owned_closure_query_t) { let mut empty_closure = z_owned_closure_query_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_query_t { +impl From for z_owned_closure_query_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(query: *const z_query_t, this: *mut c_void) { + extern "C" fn call( + query: *const z_loaned_query_t, + this: *mut c_void, + ) { let this = unsafe { &*(this as *const F) }; unsafe { this(query.as_ref().unwrap()) } } @@ -79,7 +85,7 @@ impl From for z_owned_closure_query_t { /// /// Members: /// void *context: a pointer to an arbitrary state. -/// void *call(const struct z_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. +/// void *call(const struct z_loaned_query_t*, const void *context): the typical callback function. `context` will be passed as its last argument. /// void *drop(void*): allows the callback's state to be freed. /// /// Closures are not guaranteed not to be called concurrently. diff --git a/src/closures/reply_closure.rs b/src/closures/reply_closure.rs index c070c4bd8..d41c6580a 100644 --- a/src/closures/reply_closure.rs +++ b/src/closures/reply_closure.rs @@ -1,4 +1,4 @@ -use crate::z_reply_t; +use crate::z_loaned_reply_t; use libc::c_void; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks: /// @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_reply_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } @@ -46,7 +46,10 @@ pub extern "C" fn z_closure_reply_null() -> z_owned_closure_reply_t { } /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_reply_call(closure: &z_owned_closure_reply_t, reply: &z_reply_t) { +pub extern "C" fn z_closure_reply_call( + closure: &z_owned_closure_reply_t, + reply: &z_loaned_reply_t, +) { match closure.call { Some(call) => call(reply, closure.context), None => { @@ -60,10 +63,13 @@ pub extern "C" fn z_closure_reply_drop(closure: &mut z_owned_closure_reply_t) { let mut empty_closure = z_owned_closure_reply_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_reply_t { +impl From for z_owned_closure_reply_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(response: *const z_reply_t, this: *mut c_void) { + extern "C" fn call( + response: *const z_loaned_reply_t, + this: *mut c_void, + ) { let this = unsafe { &*(this as *const F) }; unsafe { this(response.as_ref().unwrap()) } } diff --git a/src/closures/response_channel.rs b/src/closures/response_channel.rs index 4ef56b760..4b0d52123 100644 --- a/src/closures/response_channel.rs +++ b/src/closures/response_channel.rs @@ -1,6 +1,6 @@ use crate::{ - z_closure_reply_drop, z_owned_closure_reply_t, z_owned_reply_t, z_reply_clone, z_reply_null, - z_reply_t, + z_closure_reply_drop, z_loaned_reply_t, z_owned_closure_reply_t, z_owned_reply_t, + z_reply_clone, z_reply_null, }; use libc::c_void; use std::{ @@ -49,7 +49,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver if bound == 0 { let (tx, rx) = std::sync::mpsc::channel(); ( - From::from(move |reply: &z_reply_t| { + From::from(move |reply: &z_loaned_reply_t| { let mut this = MaybeUninit::::uninit(); z_reply_clone(&mut this as *mut MaybeUninit, reply); let this = this.assume_init(); @@ -62,7 +62,7 @@ unsafe fn get_send_recv_ends(bound: usize) -> (z_owned_closure_reply_t, Receiver } else { let (tx, rx) = std::sync::mpsc::sync_channel(bound); ( - From::from(move |reply: &z_reply_t| { + From::from(move |reply: &z_loaned_reply_t| { let mut this = MaybeUninit::::uninit(); z_reply_clone(&mut this as *mut MaybeUninit, reply); let this = this.assume_init(); diff --git a/src/closures/sample_closure.rs b/src/closures/sample_closure.rs index 043b59fb8..e706b0b7a 100644 --- a/src/closures/sample_closure.rs +++ b/src/closures/sample_closure.rs @@ -1,10 +1,10 @@ -use crate::z_sample_t; +use crate::z_loaned_sample_t; use libc::c_void; /// A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. /// /// Members: /// void *context: a pointer to an arbitrary state. -/// void *call(struct z_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. +/// void *call(struct z_loaned_sample_t, const void *context): the typical callback function. `context` will be passed as its last argument. /// void *drop(void*): allows the callback's state to be freed. /// /// Closures are not guaranteed not to be called concurrently. @@ -17,7 +17,7 @@ use libc::c_void; #[repr(C)] pub struct z_owned_closure_sample_t { context: *mut c_void, - call: Option, + call: Option, drop: Option, } impl z_owned_closure_sample_t { @@ -47,7 +47,10 @@ pub extern "C" fn z_closure_sample_null() -> z_owned_closure_sample_t { /// Calls the closure. Calling an uninitialized closure is a no-op. #[no_mangle] -pub extern "C" fn z_closure_sample_call(closure: &z_owned_closure_sample_t, sample: &z_sample_t) { +pub extern "C" fn z_closure_sample_call( + closure: &z_owned_closure_sample_t, + sample: &z_loaned_sample_t, +) { match closure.call { Some(call) => call(sample, closure.context), None => log::error!("Attempted to call an uninitialized closure!"), @@ -60,10 +63,13 @@ pub extern "C" fn z_closure_sample_drop(closure: &mut z_owned_closure_sample_t) let mut empty_closure = z_owned_closure_sample_t::empty(); std::mem::swap(&mut empty_closure, closure); } -impl From for z_owned_closure_sample_t { +impl From for z_owned_closure_sample_t { fn from(f: F) -> Self { let this = Box::into_raw(Box::new(f)) as _; - extern "C" fn call(sample: *const z_sample_t, this: *mut c_void) { + extern "C" fn call( + sample: *const z_loaned_sample_t, + this: *mut c_void, + ) { let this = unsafe { &*(this as *const F) }; unsafe { this(sample.as_ref().unwrap()) } } diff --git a/src/collections.rs b/src/collections.rs index 0add96fff..395ee57e3 100644 --- a/src/collections.rs +++ b/src/collections.rs @@ -26,13 +26,13 @@ use crate::transmute::{ TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; +pub use crate::opaque_types::z_loaned_slice_t; pub use crate::opaque_types::z_owned_slice_t; -pub use crate::opaque_types::z_slice_t; pub use crate::opaque_types::z_view_slice_t; decl_transmute_owned!(Option>, z_owned_slice_t); decl_transmute_owned!(Option<&'static [u8]>, z_view_slice_t); -decl_transmute_handle!(&'static [u8], z_slice_t); +decl_transmute_handle!(&'static [u8], z_loaned_slice_t); /// Returns an empty `z_view_slice_t` #[no_mangle] @@ -81,7 +81,7 @@ pub unsafe extern "C" fn z_view_slice_wrap( } #[no_mangle] -pub extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> *const z_slice_t { +pub extern "C" fn z_view_slice_loan(this: &z_view_slice_t) -> *const z_loaned_slice_t { match this.transmute_ref() { Some(s) => s.transmute_handle(), None => null(), @@ -143,15 +143,15 @@ pub unsafe extern "C" fn z_slice_drop(this: &mut z_owned_slice_t) { } #[no_mangle] -pub extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_slice_t { +pub extern "C" fn z_slice_loan(this: &z_owned_slice_t) -> *const z_loaned_slice_t { match this.transmute_ref() { - Some(s) => (&s.as_ref()) as *const &[u8] as *const z_slice_t, + Some(s) => (&s.as_ref()) as *const &[u8] as *const z_loaned_slice_t, None => null(), } } #[no_mangle] -pub extern "C" fn z_slice_clone(this: &z_slice_t, dst: *mut MaybeUninit) { +pub extern "C" fn z_slice_clone(this: &z_loaned_slice_t, dst: *mut MaybeUninit) { let slice = this.transmute_ref().to_vec().into_boxed_slice(); Inplace::init(dst.transmute_uninit_ptr(), Some(slice)); } @@ -169,22 +169,22 @@ pub extern "C" fn z_view_slice_check(this: &z_view_slice_t) -> bool { } #[no_mangle] -pub extern "C" fn z_slice_len(this: &z_slice_t) -> usize { +pub extern "C" fn z_slice_len(this: &z_loaned_slice_t) -> usize { this.transmute_ref().len() } #[no_mangle] -pub extern "C" fn z_slice_data(this: &z_slice_t) -> *const u8 { +pub extern "C" fn z_slice_data(this: &z_loaned_slice_t) -> *const u8 { this.transmute_ref().as_ptr() } +pub use crate::opaque_types::z_loaned_str_t; pub use crate::opaque_types::z_owned_str_t; -pub use crate::opaque_types::z_str_t; pub use crate::opaque_types::z_view_str_t; decl_transmute_owned!(custom_inplace_init Option>, z_owned_str_t); decl_transmute_owned!(custom_inplace_init Option<&'static [u8]>, z_view_str_t); -decl_transmute_handle!(&'static [u8], z_str_t); +decl_transmute_handle!(&'static [u8], z_loaned_str_t); /// Frees `z_owned_str_t`, invalidating it for double-drop safety. #[no_mangle] @@ -223,15 +223,15 @@ pub unsafe extern "C" fn z_view_str_empty(this: *mut MaybeUninit) z_view_slice_wrap(this as *mut _, [0u8].as_ptr(), 1) } -/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_owned_str_t`. +/// Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_owned_str_t`. #[no_mangle] -pub extern "C" fn z_str_loan(this: &z_owned_str_t) -> *const z_str_t { +pub extern "C" fn z_str_loan(this: &z_owned_str_t) -> *const z_loaned_str_t { z_slice_loan(this.transmute_ref().transmute_ref()) as _ } -/// Returns :c:type:`z_str_t` structure loaned from :c:type:`z_view_str_t`. +/// Returns :c:type:`z_loaned_str_t` structure loaned from :c:type:`z_view_str_t`. #[no_mangle] -pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> *const z_str_t { +pub extern "C" fn z_view_str_loan(this: &z_view_str_t) -> *const z_loaned_str_t { z_view_slice_loan(this.transmute_ref().transmute_ref()) as _ } @@ -276,30 +276,30 @@ pub unsafe extern "C" fn z_view_str_wrap( } #[no_mangle] -pub extern "C" fn z_view_str_len(this: &z_str_t) -> usize { +pub extern "C" fn z_view_str_len(this: &z_loaned_str_t) -> usize { z_slice_len(this.transmute_ref().transmute_handle()) - 1 } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_view_str_data(this: &z_str_t) -> *const libc::c_char { +pub extern "C" fn z_view_str_data(this: &z_loaned_str_t) -> *const libc::c_char { z_slice_data(this.transmute_ref().transmute_handle()) as _ } #[no_mangle] -pub extern "C" fn z_str_clone(this: &z_str_t, dst: *mut MaybeUninit) { +pub extern "C" fn z_str_clone(this: &z_loaned_str_t, dst: *mut MaybeUninit) { let slice = this.transmute_ref().to_vec().into_boxed_slice(); Inplace::init(dst.transmute_uninit_ptr(), Some(slice)); } +pub use crate::opaque_types::z_loaned_slice_map_t; pub use crate::opaque_types::z_owned_slice_map_t; -pub use crate::opaque_types::z_slice_map_t; pub type ZHashMap = HashMap, Cow<'static, [u8]>>; -pub use crate::opaque_types::z_config_t; +pub use crate::opaque_types::z_loaned_config_t; decl_transmute_handle!( HashMap, Cow<'static, [u8]>>, - z_slice_map_t + z_loaned_slice_map_t ); pub use crate::opaque_types::z_owned_config_t; @@ -340,14 +340,16 @@ pub extern "C" fn z_slice_map_drop(this: &mut z_owned_slice_map_t) { } #[no_mangle] -pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> &z_slice_map_t { +pub extern "C" fn z_slice_map_loan(this: &z_owned_slice_map_t) -> &z_loaned_slice_map_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() } #[no_mangle] -pub extern "C" fn z_slice_map_loan_mut(this: &mut z_owned_slice_map_t) -> &mut z_slice_map_t { +pub extern "C" fn z_slice_map_loan_mut( + this: &mut z_owned_slice_map_t, +) -> &mut z_loaned_slice_map_t { let this = this.transmute_mut(); let this = unwrap_ref_unchecked_mut(this); this.transmute_handle_mut() @@ -355,13 +357,13 @@ pub extern "C" fn z_slice_map_loan_mut(this: &mut z_owned_slice_map_t) -> &mut z /// Returns number of key-value pairs in the map. #[no_mangle] -pub extern "C" fn z_slice_map_len(this: &z_slice_map_t) -> usize { +pub extern "C" fn z_slice_map_len(this: &z_loaned_slice_map_t) -> usize { this.transmute_ref().len() } /// Returns true if the map is empty, false otherwise. #[no_mangle] -pub extern "C" fn z_slice_map_is_empty(this: &z_slice_map_t) -> bool { +pub extern "C" fn z_slice_map_is_empty(this: &z_loaned_slice_map_t) -> bool { z_slice_map_len(this) == 0 } @@ -373,11 +375,11 @@ pub extern "C" fn z_slice_map_is_empty(this: &z_slice_map_t) -> bool { /// Returning `true` is treated as `continue`. #[allow(non_camel_case_types)] pub type z_slice_map_iter_body_t = - extern "C" fn(key: &z_slice_t, value: &z_slice_t, context: *mut c_void) -> bool; + extern "C" fn(key: &z_loaned_slice_t, value: &z_loaned_slice_t, context: *mut c_void) -> bool; #[no_mangle] pub extern "C" fn z_slice_map_iterate( - this: &z_slice_map_t, + this: &z_loaned_slice_map_t, body: z_slice_map_iter_body_t, context: *mut c_void, ) { @@ -399,7 +401,10 @@ pub extern "C" fn z_slice_map_iterate( /// /// Will return NULL if the key is not present in the map. #[no_mangle] -pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> *const z_slice_t { +pub extern "C" fn z_slice_map_get( + this: &z_loaned_slice_map_t, + key: &z_loaned_slice_t, +) -> *const z_loaned_slice_t { let m = this.transmute_ref(); let key = *key.transmute_ref(); let k = Cow::Borrowed(key); @@ -413,9 +418,9 @@ pub extern "C" fn z_slice_map_get(this: &z_slice_map_t, key: &z_slice_t) -> *con /// Returns 1 if there was already an entry associated with the key, 0 otherwise. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_copy( - this: &mut z_slice_map_t, - key: &z_slice_t, - value: &z_slice_t, + this: &mut z_loaned_slice_map_t, + key: &z_loaned_slice_t, + value: &z_loaned_slice_t, ) -> u8 { let this = this.transmute_mut(); let key = *key.transmute_ref(); @@ -433,9 +438,9 @@ pub extern "C" fn z_slice_map_insert_by_copy( /// Returns 1 if there was already an entry associated with the key, 0 otherwise. #[no_mangle] pub extern "C" fn z_slice_map_insert_by_alias( - this: &mut z_slice_map_t, - key: &z_slice_t, - value: &z_slice_t, + this: &mut z_loaned_slice_map_t, + key: &z_loaned_slice_t, + value: &z_loaned_slice_t, ) -> errors::z_error_t { let this = this.transmute_mut(); let key = key.transmute_ref(); diff --git a/src/commons.rs b/src/commons.rs index 86f5bad69..efc9fc9f0 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -24,9 +24,9 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; -use crate::z_bytes_t; use crate::z_id_t; -use crate::z_keyexpr_t; +use crate::z_loaned_bytes_t; +use crate::z_loaned_keyexpr_t; use libc::{c_char, c_ulong}; use unwrap_infallible::UnwrapInfallible; use zenoh::encoding::Encoding; @@ -87,34 +87,34 @@ pub extern "C" fn z_timestamp_get_id(timestamp: &z_timestamp_t) -> z_id_t { /// A data sample. /// /// A sample is the value associated to a given resource at a given point in time. -use crate::opaque_types::z_sample_t; -decl_transmute_handle!(Sample, z_sample_t); +use crate::opaque_types::z_loaned_sample_t; +decl_transmute_handle!(Sample, z_loaned_sample_t); /// The Key Expression of the sample. /// /// `sample` is aliased by its return value. #[no_mangle] -pub extern "C" fn z_sample_keyexpr(sample: &z_sample_t) -> &z_keyexpr_t { +pub extern "C" fn z_sample_keyexpr(sample: &z_loaned_sample_t) -> &z_loaned_keyexpr_t { let sample = sample.transmute_ref(); sample.key_expr().transmute_handle() } /// The encoding of the payload. #[no_mangle] -pub extern "C" fn z_sample_encoding(sample: &z_sample_t) -> &z_encoding_t { +pub extern "C" fn z_sample_encoding(sample: &z_loaned_sample_t) -> &z_loaned_encoding_t { let sample = sample.transmute_ref(); sample.encoding().transmute_handle() } /// The sample's data, the return value aliases the sample. /// #[no_mangle] -pub extern "C" fn z_sample_payload(sample: &z_sample_t) -> &z_bytes_t { +pub extern "C" fn z_sample_payload(sample: &z_loaned_sample_t) -> &z_loaned_bytes_t { let sample = sample.transmute_ref(); sample.payload().transmute_handle() } /// The sample's kind (put or delete). #[no_mangle] -pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { +pub extern "C" fn z_sample_kind(sample: &z_loaned_sample_t) -> z_sample_kind_t { let sample = sample.transmute_ref(); sample.kind().into() } @@ -122,8 +122,8 @@ pub extern "C" fn z_sample_kind(sample: &z_sample_t) -> z_sample_kind_t { /// /// Returns true if Sample contains timestamp, false otherwise. In the latter case the timestamp_out value is not altered. #[no_mangle] -pub extern "C" fn z_sample_timestamp( - sample: &z_sample_t, +pub extern "C" fn z_loaned_sample_timestamp( + sample: &z_loaned_sample_t, timestamp_out: &mut z_timestamp_t, ) -> bool { let sample = sample.transmute_ref(); @@ -141,7 +141,7 @@ pub extern "C" fn z_sample_timestamp( /// /// Returns NULL if sample does not contain an attachement. #[no_mangle] -pub extern "C" fn z_sample_attachment(sample: &z_sample_t) -> *const z_bytes_t { +pub extern "C" fn z_sample_attachment(sample: &z_loaned_sample_t) -> *const z_loaned_bytes_t { let sample = sample.transmute_ref(); match sample.attachment() { Some(attachment) => attachment.transmute_handle() as *const _, @@ -154,7 +154,10 @@ decl_transmute_owned!(Option, zc_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] -pub extern "C" fn z_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit) { +pub extern "C" fn z_sample_clone( + src: &z_loaned_sample_t, + dst: *mut MaybeUninit, +) { let src = src.transmute_ref(); let src = src.clone(); let dst = dst.transmute_uninit_ptr(); @@ -162,19 +165,21 @@ pub extern "C" fn z_sample_clone(src: &z_sample_t, dst: *mut MaybeUninit z_priority_t { +pub extern "C" fn z_sample_priority(sample: &z_loaned_sample_t) -> z_priority_t { let sample = sample.transmute_ref(); sample.priority().into() } #[no_mangle] -pub extern "C" fn z_sample_express(sample: &z_sample_t) -> bool { +pub extern "C" fn z_sample_express(sample: &z_loaned_sample_t) -> bool { let sample = sample.transmute_ref(); sample.express() } #[no_mangle] -pub extern "C" fn z_sample_congestion_control(sample: &z_sample_t) -> z_congestion_control_t { +pub extern "C" fn z_sample_congestion_control( + sample: &z_loaned_sample_t, +) -> z_congestion_control_t { let sample = sample.transmute_ref(); sample.congestion_control().into() } @@ -193,7 +198,7 @@ pub extern "C" fn z_sample_check(sample: &zc_owned_sample_t) -> bool { /// /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] -pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> &z_sample_t { +pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> &z_loaned_sample_t { unwrap_ref_unchecked(sample.transmute_ref()).transmute_handle() } @@ -208,8 +213,8 @@ pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { Inplace::empty(sample.transmute_uninit_ptr()); } -pub use crate::opaque_types::z_encoding_t; -decl_transmute_handle!(Encoding, z_encoding_t); +pub use crate::opaque_types::z_loaned_encoding_t; +decl_transmute_handle!(Encoding, z_loaned_encoding_t); /// An owned payload encoding. /// @@ -227,7 +232,7 @@ pub extern "C" fn z_encoding_null(encoding: *mut MaybeUninit Inplace::empty(encoding.transmute_uninit_ptr()); } -/// Constructs a specific :c:type:`z_encoding_t`. +/// Constructs a specific :c:type:`z_loaned_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_encoding_from_str( @@ -246,10 +251,10 @@ pub unsafe extern "C" fn z_encoding_from_str( } } -/// Constructs a default :c:type:`z_encoding_t`. +/// Constructs a default :c:type:`z_loaned_encoding_t`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_default() -> &'static z_encoding_t { +pub extern "C" fn z_encoding_default() -> &'static z_loaned_encoding_t { Encoding::ZENOH_BYTES.transmute_handle() } @@ -267,17 +272,17 @@ pub extern "C" fn z_encoding_check(encoding: &'static z_owned_encoding_t) -> boo *encoding.transmute_ref() != Encoding::default() } -/// Returns a :c:type:`z_encoding_t` loaned from `encoding`. +/// Returns a :c:type:`z_loaned_encoding_t` loaned from `encoding`. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> &z_encoding_t { +pub extern "C" fn z_encoding_loan(encoding: &z_owned_encoding_t) -> &z_loaned_encoding_t { encoding.transmute_ref().transmute_handle() } pub use crate::opaque_types::z_owned_value_t; decl_transmute_owned!(Value, z_owned_value_t); -pub use crate::opaque_types::z_value_t; -decl_transmute_handle!(Value, z_value_t); +pub use crate::opaque_types::z_loaned_value_t; +decl_transmute_handle!(Value, z_loaned_value_t); #[repr(C)] #[derive(Clone, Copy, Debug)] @@ -350,37 +355,37 @@ pub extern "C" fn zcu_reply_keyexpr_default() -> zcu_reply_keyexpr_t { #[allow(non_camel_case_types)] #[repr(C)] #[derive(Clone, Copy)] -pub enum z_query_target_t { +pub enum z_loaned_query_target_t { BEST_MATCHING, ALL, ALL_COMPLETE, } -impl From for z_query_target_t { +impl From for z_loaned_query_target_t { #[inline] fn from(t: QueryTarget) -> Self { match t { - QueryTarget::BestMatching => z_query_target_t::BEST_MATCHING, - QueryTarget::All => z_query_target_t::ALL, - QueryTarget::AllComplete => z_query_target_t::ALL_COMPLETE, + QueryTarget::BestMatching => z_loaned_query_target_t::BEST_MATCHING, + QueryTarget::All => z_loaned_query_target_t::ALL, + QueryTarget::AllComplete => z_loaned_query_target_t::ALL_COMPLETE, } } } -impl From for QueryTarget { +impl From for QueryTarget { #[inline] - fn from(val: z_query_target_t) -> Self { + fn from(val: z_loaned_query_target_t) -> Self { match val { - z_query_target_t::BEST_MATCHING => QueryTarget::BestMatching, - z_query_target_t::ALL => QueryTarget::All, - z_query_target_t::ALL_COMPLETE => QueryTarget::AllComplete, + z_loaned_query_target_t::BEST_MATCHING => QueryTarget::BestMatching, + z_loaned_query_target_t::ALL => QueryTarget::All, + z_loaned_query_target_t::ALL_COMPLETE => QueryTarget::AllComplete, } } } -/// Create a default :c:type:`z_query_target_t`. +/// Create a default :c:type:`z_loaned_query_target_t`. #[no_mangle] -pub extern "C" fn z_query_target_default() -> z_query_target_t { +pub extern "C" fn z_loaned_query_target_default() -> z_loaned_query_target_t { QueryTarget::default().into() } diff --git a/src/config.rs b/src/config.rs index 9e207bbbe..2514d7f3d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -63,23 +63,23 @@ pub static Z_CONFIG_SCOUTING_DELAY_KEY: &c_char = pub static Z_CONFIG_ADD_TIMESTAMP_KEY: &c_char = unsafe { &*(b"timestamping/enabled\0".as_ptr() as *const c_char) }; -pub use crate::opaque_types::z_config_t; -decl_transmute_handle!(Config, z_config_t); +pub use crate::opaque_types::z_loaned_config_t; +decl_transmute_handle!(Config, z_loaned_config_t); pub use crate::opaque_types::z_owned_config_t; decl_transmute_owned!(Option, z_owned_config_t); -/// Returns a :c:type:`z_config_t` loaned from `s`. +/// Returns a :c:type:`z_loaned_config_t` loaned from `s`. #[no_mangle] -pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> &z_config_t { +pub extern "C" fn z_config_loan(this: &'static z_owned_config_t) -> &z_loaned_config_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() } -/// Returns a :c:type:`z_config_t` loaned from `s`. +/// Returns a :c:type:`z_loaned_config_t` loaned from `s`. #[no_mangle] -pub extern "C" fn z_config_loan_mut(this: &mut z_owned_config_t) -> &mut z_config_t { +pub extern "C" fn z_config_loan_mut(this: &mut z_owned_config_t) -> &mut z_loaned_config_t { let this = this.transmute_mut(); let this = unwrap_ref_unchecked_mut(this); this.transmute_handle_mut() @@ -111,7 +111,7 @@ pub extern "C" fn z_config_null(this: *mut MaybeUninit) { /// Clones the config. #[no_mangle] -pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit) { +pub extern "C" fn z_config_clone(src: &z_loaned_config_t, dst: *mut MaybeUninit) { let src = src.transmute_ref(); let src = src.clone(); let dst = dst.transmute_uninit_ptr(); @@ -123,7 +123,7 @@ pub extern "C" fn z_config_clone(src: &z_config_t, dst: *mut MaybeUninit, ) -> errors::z_error_t { @@ -154,7 +154,7 @@ pub unsafe extern "C" fn zc_config_get( #[no_mangle] #[allow(clippy::missing_safety_doc, unused_must_use)] pub unsafe extern "C" fn zc_config_insert_json( - config: &mut z_config_t, + config: &mut z_loaned_config_t, key: *const c_char, value: *const c_char, ) -> errors::z_error_t { @@ -210,7 +210,7 @@ pub unsafe extern "C" fn zc_config_from_str( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn zc_config_to_string( - config: &z_config_t, + config: &z_loaned_config_t, config_string: *mut MaybeUninit, ) -> errors::z_error_t { let config: &Config = config.transmute_ref(); diff --git a/src/get.rs b/src/get.rs index 3586e50a2..d627a9075 100644 --- a/src/get.rs +++ b/src/get.rs @@ -30,25 +30,27 @@ use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; use crate::z_consolidation_mode_t; +use crate::z_loaned_query_target_t; +use crate::z_loaned_sample_t; +use crate::z_loaned_value_t; use crate::z_owned_bytes_t; use crate::z_owned_encoding_t; -use crate::z_query_target_t; -use crate::z_sample_t; -use crate::z_value_t; -use crate::{z_closure_reply_call, z_keyexpr_t, z_owned_closure_reply_t, z_session_t}; +use crate::{ + z_closure_reply_call, z_loaned_keyexpr_t, z_loaned_session_t, z_owned_closure_reply_t, +}; use zenoh::prelude::SyncResolve; pub use crate::opaque_types::z_owned_reply_t; decl_transmute_owned!(Option, z_owned_reply_t); -pub use crate::opaque_types::z_reply_t; -decl_transmute_handle!(Reply, z_reply_t); +pub use crate::opaque_types::z_loaned_reply_t; +decl_transmute_handle!(Reply, z_loaned_reply_t); /// Returns ``true`` if the queryable answered with an OK, which allows this value to be treated as a sample. /// /// If this returns ``false``, you should use :c:func:`z_check` before trying to use :c:func:`z_reply_err` if you want to process the error that may be here. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_is_ok(reply: &z_reply_t) -> bool { +pub unsafe extern "C" fn z_reply_is_ok(reply: &z_loaned_reply_t) -> bool { let reply = reply.transmute_ref(); reply.result().is_ok() } @@ -58,7 +60,7 @@ pub unsafe extern "C" fn z_reply_is_ok(reply: &z_reply_t) -> bool { /// Returns null if reply does not contains a sample (i. e. if :c:func:`z_reply_is_ok` returns ``false``). #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_ok(reply: &z_reply_t) -> *const z_sample_t { +pub unsafe extern "C" fn z_reply_ok(reply: &z_loaned_reply_t) -> *const z_loaned_sample_t { let reply = reply.transmute_ref(); match reply.result() { Ok(sample) => sample.transmute_handle(), @@ -71,7 +73,7 @@ pub unsafe extern "C" fn z_reply_ok(reply: &z_reply_t) -> *const z_sample_t { /// Returns null if reply does not contain a error (i. e. if :c:func:`z_reply_is_ok` returns ``true``). #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_reply_err(reply: &z_reply_t) -> *const z_value_t { +pub unsafe extern "C" fn z_reply_err(reply: &z_loaned_reply_t) -> *const z_loaned_value_t { let reply = reply.transmute_ref(); match reply.result() { Ok(_) => null(), @@ -92,7 +94,7 @@ pub extern "C" fn z_reply_null(this: *mut MaybeUninit) { } #[no_mangle] -pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: &z_reply_t) { +pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: &z_loaned_reply_t) { Inplace::init( this.transmute_uninit_ptr(), Some(reply.transmute_ref().clone()), @@ -102,14 +104,14 @@ pub extern "C" fn z_reply_clone(this: *mut MaybeUninit, reply: /// Options passed to the :c:func:`z_get` function. /// /// Members: -/// z_query_target_t target: The Queryables that should be target of the query. +/// z_loaned_query_target_t target: The Queryables that should be target of the query. /// z_query_consolidation_t consolidation: The replies consolidation strategy to apply on replies to the query. -/// z_value_t value: An optional value to attach to the query. -/// z_bytes_t attachment: The attachment to attach to the query. +/// z_loaned_value_t value: An optional value to attach to the query. +/// z_loaned_bytes_t attachment: The attachment to attach to the query. /// uint64_t timeout: The timeout for the query in milliseconds. 0 means default query timeout from zenoh configuration. #[repr(C)] pub struct z_get_options_t { - pub target: z_query_target_t, + pub target: z_loaned_query_target_t, pub consolidation: z_query_consolidation_t, pub payload: *mut z_owned_bytes_t, pub encoding: *mut z_owned_encoding_t, @@ -145,8 +147,8 @@ pub extern "C" fn z_get_options_default(this: &mut z_get_options_t) { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_get( - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, parameters: *const c_char, callback: &mut z_owned_closure_reply_t, options: Option<&mut z_get_options_t>, @@ -206,7 +208,7 @@ pub extern "C" fn z_reply_check(this: &z_owned_reply_t) -> bool { } #[no_mangle] -pub extern "C" fn z_reply_loan(this: &mut z_owned_reply_t) -> &z_reply_t { +pub extern "C" fn z_reply_loan(this: &mut z_owned_reply_t) -> &z_loaned_reply_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/info.rs b/src/info.rs index 90afc28ca..a7a23131e 100644 --- a/src/info.rs +++ b/src/info.rs @@ -12,7 +12,7 @@ use crate::transmute::{TransmuteCopy, TransmuteFromHandle}; // Contributors: // ZettaScale Zenoh team, // -use crate::{errors, z_closure_zid_call, z_owned_closure_zid_t, z_session_t}; +use crate::{errors, z_closure_zid_call, z_loaned_session_t, z_owned_closure_zid_t}; use std::mem::MaybeUninit; use zenoh::config::ZenohId; use zenoh::prelude::sync::SyncResolve; @@ -34,7 +34,7 @@ impl From<[u8; 16]> for z_id_t { /// to pass it a valid session. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_info_zid(session: z_session_t) -> z_id_t { +pub unsafe extern "C" fn z_info_zid(session: z_loaned_session_t) -> z_id_t { let session = session.transmute_ref(); session.info().zid().res_sync().transmute_copy() } @@ -48,7 +48,7 @@ pub unsafe extern "C" fn z_info_zid(session: z_session_t) -> z_id_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_info_peers_zid( - session: z_session_t, + session: z_loaned_session_t, callback: &mut z_owned_closure_zid_t, ) -> errors::z_error_t { let mut closure = z_owned_closure_zid_t::empty(); @@ -69,7 +69,7 @@ pub unsafe extern "C" fn z_info_peers_zid( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_info_routers_zid( - session: z_session_t, + session: z_loaned_session_t, callback: &mut z_owned_closure_zid_t, ) -> errors::z_error_t { let mut closure = z_owned_closure_zid_t::empty(); diff --git a/src/keyexpr.rs b/src/keyexpr.rs index 61fefacd5..4c2e75494 100644 --- a/src/keyexpr.rs +++ b/src/keyexpr.rs @@ -23,8 +23,8 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; +use crate::z_loaned_session_t; use crate::z_owned_str_t; -use crate::z_session_t; use crate::z_str_from_substring; use crate::z_view_slice_t; use crate::z_view_slice_wrap; @@ -143,15 +143,15 @@ pub unsafe extern "C" fn z_keyexpr_new_autocanonize( } } -/// Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. +/// Returns a :c:type:`z_loaned_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. #[no_mangle] -pub extern "C" fn z_keyexpr_loan(key_expr: &z_owned_keyexpr_t) -> &z_keyexpr_t { +pub extern "C" fn z_keyexpr_loan(key_expr: &z_owned_keyexpr_t) -> &z_loaned_keyexpr_t { unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() } -/// Returns a :c:type:`z_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. +/// Returns a :c:type:`z_loaned_keyexpr_t` loaned from :c:type:`z_owned_keyexpr_t`. #[no_mangle] -pub extern "C" fn z_view_keyexpr_loan(key_expr: &z_view_keyexpr_t) -> &z_keyexpr_t { +pub extern "C" fn z_view_keyexpr_loan(key_expr: &z_view_keyexpr_t) -> &z_loaned_keyexpr_t { unwrap_ref_unchecked(key_expr.transmute_ref()).transmute_handle() } @@ -183,8 +183,8 @@ pub extern "C" fn z_view_keyexpr_check(keyexpr: &z_view_keyexpr_t) -> bool { /// /// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, /// both for local processing and network-wise. -pub use crate::opaque_types::z_keyexpr_t; -decl_transmute_handle!(KeyExpr<'static>, z_keyexpr_t); +pub use crate::opaque_types::z_loaned_keyexpr_t; +decl_transmute_handle!(KeyExpr<'static>, z_loaned_keyexpr_t); /// Returns ``0`` if the passed string is a valid (and canon) key expression. /// Otherwise returns error value @@ -237,7 +237,7 @@ pub unsafe extern "C" fn z_keyexpr_canonize(start: *mut c_char, len: &mut usize) } } -/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_view_keyexpr_from_slice( @@ -263,7 +263,7 @@ pub unsafe extern "C" fn z_view_keyexpr_from_slice( } } -/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. /// The string is canonized in-place before being passed to keyexpr. /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] @@ -293,7 +293,7 @@ pub unsafe extern "C" fn z_view_keyexpr_from_slice_autocanonize( } } -/// Constructs a :c:type:`z_keyexpr_t` departing from a string. +/// Constructs a :c:type:`z_loaned_keyexpr_t` departing from a string. /// It is a loaned key expression that aliases `name`. #[allow(clippy::missing_safety_doc)] #[no_mangle] @@ -310,7 +310,7 @@ pub unsafe extern "C" fn z_view_keyexpr( } } -/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string. +/// Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string. /// The string is canonized in-place before being passed to keyexpr. /// May SEGFAULT if `start` is NULL or lies in read-only memory (as values initialized with string litterals do). #[allow(clippy::missing_safety_doc)] @@ -332,7 +332,7 @@ pub unsafe extern "C" fn z_view_keyexpr_autocanonize( } } -/// Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_eyexpr_t` by aliasing a string without checking any of `z_loaned_keyexpr_t`'s assertions: /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: /// - MUST NOT contain ``//``, MUST NOT start nor end with ``/``, MUST NOT contain any of the characters ``?#$``. @@ -353,7 +353,7 @@ pub unsafe extern "C" fn z_view_keyexpr_from_slice_unchecked( Inplace::init(this.transmute_uninit_ptr(), Some(name)) } -/// Constructs a :c:type:`z_keyexpr_t` by aliasing a string without checking any of `z_keyexpr_t`'s assertions: +/// Constructs a :c:type:`z_loaned_keyexpr_t` by aliasing a string without checking any of `z_loaned_keyexpr_t`'s assertions: /// /// - `name` MUST be valid UTF8. /// - `name` MUST follow the Key Expression specification, ie: @@ -372,11 +372,14 @@ pub unsafe extern "C" fn z_keyexpr_unchecked( z_view_keyexpr_from_slice_unchecked(this, name, libc::strlen(name)) } -/// Constructs a null-terminated string departing from a :c:type:`z_keyexpr_t`. +/// Constructs a null-terminated string departing from a :c:type:`z_loaned_keyexpr_t`. /// The user is responsible of droping the returned string using `z_drop` #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t, s: *mut MaybeUninit) { +pub unsafe extern "C" fn z_loaned_keyexpr_to_string( + ke: &z_loaned_keyexpr_t, + s: *mut MaybeUninit, +) { let ke = ke.transmute_ref(); unsafe { z_str_from_substring(s, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) }; } @@ -386,7 +389,10 @@ pub unsafe extern "C" fn z_keyexpr_to_string(ke: &z_keyexpr_t, s: *mut MaybeUnin /// Currently exclusive to zenoh-c #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub unsafe extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t, b: *mut MaybeUninit) { +pub unsafe extern "C" fn z_keyexpr_as_bytes( + ke: &z_loaned_keyexpr_t, + b: *mut MaybeUninit, +) { let ke = ke.transmute_ref(); unsafe { z_view_slice_wrap(b, ke.as_bytes().as_ptr() as *const _, ke.as_bytes().len()) }; } @@ -394,7 +400,7 @@ pub unsafe extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t, b: *mut MaybeUnini /**************************************/ /* DECLARATION */ /**************************************/ -/// Declare a key expression. The id is returned as a :c:type:`z_keyexpr_t` with a nullptr suffix. +/// Declare a key expression. The id is returned as a :c:type:`z_loaned_keyexpr_t` with a nullptr suffix. /// /// This numerical id will be used on the network to save bandwidth and /// ease the retrieval of the concerned resource in the routing tables. @@ -402,8 +408,8 @@ pub unsafe extern "C" fn z_keyexpr_as_bytes(ke: &z_keyexpr_t, b: *mut MaybeUnini #[no_mangle] pub extern "C" fn z_declare_keyexpr( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, ) -> z_error_t { let this = this.transmute_uninit_ptr(); let key_expr = key_expr.transmute_ref(); @@ -426,7 +432,7 @@ pub extern "C" fn z_declare_keyexpr( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub extern "C" fn z_undeclare_keyexpr( - session: &z_session_t, + session: &z_loaned_session_t, kexpr: &mut z_owned_keyexpr_t, ) -> errors::z_error_t { let Some(kexpr) = kexpr.transmute_mut().take() else { @@ -446,7 +452,7 @@ pub extern "C" fn z_undeclare_keyexpr( #[allow(clippy::missing_safety_doc)] #[no_mangle] /// Returns ``0`` if both ``left`` and ``right`` are equal. -pub extern "C" fn z_keyexpr_equals(left: &z_keyexpr_t, right: &z_keyexpr_t) -> bool { +pub extern "C" fn z_keyexpr_equals(left: &z_loaned_keyexpr_t, right: &z_loaned_keyexpr_t) -> bool { let l = left.transmute_ref(); let r = right.transmute_ref(); *l == *r @@ -456,7 +462,10 @@ pub extern "C" fn z_keyexpr_equals(left: &z_keyexpr_t, right: &z_keyexpr_t) -> b #[no_mangle] /// Returns ``0`` if the keyexprs intersect, i.e. there exists at least one key which is contained in both of the /// sets defined by ``left`` and ``right``. -pub extern "C" fn z_keyexpr_intersects(left: &z_keyexpr_t, right: &z_keyexpr_t) -> bool { +pub extern "C" fn z_keyexpr_intersects( + left: &z_loaned_keyexpr_t, + right: &z_loaned_keyexpr_t, +) -> bool { let l = left.transmute_ref(); let r = right.transmute_ref(); l.intersects(r) @@ -466,7 +475,10 @@ pub extern "C" fn z_keyexpr_intersects(left: &z_keyexpr_t, right: &z_keyexpr_t) #[no_mangle] /// Returns ``0`` if ``left`` includes ``right``, i.e. the set defined by ``left`` contains every key belonging to the set /// defined by ``right``. -pub extern "C" fn z_keyexpr_includes(left: &z_keyexpr_t, right: &z_keyexpr_t) -> bool { +pub extern "C" fn z_keyexpr_includes( + left: &z_loaned_keyexpr_t, + right: &z_loaned_keyexpr_t, +) -> bool { let l = left.transmute_ref(); let r = right.transmute_ref(); l.includes(r) @@ -483,7 +495,7 @@ pub extern "C" fn z_keyexpr_includes(left: &z_keyexpr_t, right: &z_keyexpr_t) -> /// as this would extremely likely cause bugs. pub unsafe extern "C" fn z_keyexpr_concat( this: *mut MaybeUninit, - left: &z_keyexpr_t, + left: &z_loaned_keyexpr_t, right_start: *const c_char, right_len: usize, ) -> errors::z_error_t { @@ -522,8 +534,8 @@ pub unsafe extern "C" fn z_keyexpr_concat( /// In case of error, the return value will be set to its invalidated state. pub extern "C" fn z_keyexpr_join( this: *mut MaybeUninit, - left: &z_keyexpr_t, - right: &z_keyexpr_t, + left: &z_loaned_keyexpr_t, + right: &z_loaned_keyexpr_t, ) -> errors::z_error_t { let left = left.transmute_ref(); let right = right.transmute_ref(); @@ -572,8 +584,8 @@ impl From for z_keyexpr_intersection_level_t { /// /// Note that this is slower than `z_keyexpr_intersects` and `keyexpr_includes`, so you should favor these methods for most applications. pub extern "C" fn z_keyexpr_relation_to( - left: &z_keyexpr_t, - right: &z_keyexpr_t, + left: &z_loaned_keyexpr_t, + right: &z_loaned_keyexpr_t, ) -> z_keyexpr_intersection_level_t { let l = left.transmute_ref(); let r = right.transmute_ref(); diff --git a/src/liveliness.rs b/src/liveliness.rs index 8fefb253d..ae48097e7 100644 --- a/src/liveliness.rs +++ b/src/liveliness.rs @@ -23,17 +23,17 @@ use crate::transmute::TransmuteIntoHandle; use crate::{ errors, transmute::{Inplace, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}, - z_closure_reply_call, z_closure_sample_call, z_keyexpr_t, z_owned_closure_reply_t, - z_owned_closure_sample_t, z_owned_subscriber_t, z_session_t, + z_closure_reply_call, z_closure_sample_call, z_loaned_keyexpr_t, z_loaned_session_t, + z_owned_closure_reply_t, z_owned_closure_sample_t, z_owned_subscriber_t, }; -use crate::opaque_types::zc_liveliness_token_t; +use crate::opaque_types::zc_loaned_liveliness_token_t; use crate::opaque_types::zc_owned_liveliness_token_t; decl_transmute_owned!( Option>, zc_owned_liveliness_token_t ); -decl_transmute_handle!(LivelinessToken<'static>, zc_liveliness_token_t); +decl_transmute_handle!(LivelinessToken<'static>, zc_loaned_liveliness_token_t); /// The gravestone value for liveliness tokens. #[no_mangle] @@ -69,8 +69,8 @@ pub extern "C" fn zc_liveliness_declaration_options_default( #[no_mangle] pub extern "C" fn zc_liveliness_declare_token( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, _options: Option<&mut zc_liveliness_declaration_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); @@ -120,8 +120,8 @@ pub extern "C" fn zc_liveliness_subscriber_options_default( /// Declares a subscriber on liveliness tokens that intersect `key`. /// /// Parameters: -/// z_session_t session: The zenoh session. -/// z_keyexpr_t key_expr: The key expression to subscribe. +/// z_loaned_session_t session: The zenoh session. +/// z_loaned_keyexpr_t key_expr: The key expression to subscribe. /// z_owned_closure_sample_t callback: The callback function that will be called each time a /// liveliness token status changed. /// zc_owned_liveliness_declare_subscriber_options_t _options: The options to be passed to describe the options to be passed to the liveliness subscriber declaration. @@ -134,8 +134,8 @@ pub extern "C" fn zc_liveliness_subscriber_options_default( #[no_mangle] pub extern "C" fn zc_liveliness_declare_subscriber( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, callback: &mut z_owned_closure_sample_t, _options: Option<&mut zc_liveliness_declare_subscriber_options_t>, ) -> errors::z_error_t { @@ -183,8 +183,8 @@ pub extern "C" fn zc_liveliness_get_options_default(this: &mut zc_liveliness_get /// Passing `NULL` as options is valid and equivalent to passing a pointer to the default options. #[no_mangle] pub extern "C" fn zc_liveliness_get( - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, callback: &mut z_owned_closure_reply_t, options: Option<&mut zc_liveliness_get_options_t>, ) -> errors::z_error_t { diff --git a/src/payload.rs b/src/payload.rs index 665ae0d24..1283f28a6 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -4,8 +4,8 @@ use crate::transmute::{ TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; use crate::{ - z_owned_slice_map_t, z_owned_slice_t, z_owned_str_t, z_slice_map_t, z_slice_t, z_str_t, - ZHashMap, + z_loaned_slice_map_t, z_loaned_slice_t, z_loaned_str_t, z_owned_slice_map_t, z_owned_slice_t, + z_owned_str_t, ZHashMap, }; use core::fmt; use std::any::Any; @@ -42,18 +42,18 @@ extern "C" fn z_bytes_check(payload: &z_owned_bytes_t) -> bool { /// Loans the payload, allowing you to call functions that only need a loan of it. #[no_mangle] -extern "C" fn z_bytes_loan(payload: &z_owned_bytes_t) -> &z_bytes_t { +extern "C" fn z_bytes_loan(payload: &z_owned_bytes_t) -> &z_loaned_bytes_t { let payload = payload.transmute_ref(); let payload = unwrap_ref_unchecked(payload); payload.transmute_handle() } -pub use crate::opaque_types::z_bytes_t; -decl_transmute_handle!(ZBytes, z_bytes_t); +pub use crate::opaque_types::z_loaned_bytes_t; +decl_transmute_handle!(ZBytes, z_loaned_bytes_t); /// Increments the payload's reference count, returning an owned version of it. #[no_mangle] -extern "C" fn z_bytes_clone(src: &z_bytes_t, dst: *mut MaybeUninit) { +extern "C" fn z_bytes_clone(src: &z_loaned_bytes_t, dst: *mut MaybeUninit) { let dst = dst.transmute_uninit_ptr(); let src = src.transmute_ref(); let src = Some(src.clone()); @@ -62,7 +62,7 @@ extern "C" fn z_bytes_clone(src: &z_bytes_t, dst: *mut MaybeUninit usize { +extern "C" fn z_bytes_len(payload: &z_loaned_bytes_t) -> usize { payload.transmute_ref().len() } @@ -70,7 +70,7 @@ extern "C" fn z_bytes_len(payload: &z_bytes_t) -> usize { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_decode_into_string( - payload: &z_bytes_t, + payload: &z_loaned_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { let len = z_bytes_len(payload); @@ -95,7 +95,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_string( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( - payload: z_bytes_t, + payload: z_loaned_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { let dst = dst.transmute_uninit_ptr(); @@ -113,7 +113,7 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes_map( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_decode_into_bytes( - payload: &z_bytes_t, + payload: &z_loaned_bytes_t, dst: *mut MaybeUninit, ) -> z_error_t { let payload = payload.transmute_ref(); @@ -131,17 +131,17 @@ pub unsafe extern "C" fn z_bytes_decode_into_bytes( } } -unsafe impl Send for z_slice_t {} -unsafe impl Sync for z_slice_t {} +unsafe impl Send for z_loaned_slice_t {} +unsafe impl Sync for z_loaned_slice_t {} -impl fmt::Debug for z_slice_t { +impl fmt::Debug for z_loaned_slice_t { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let s = self.transmute_ref(); - f.debug_struct("z_slice_t").field("_0", s).finish() + f.debug_struct("z_loaned_slice_t").field("_0", s).finish() } } -impl ZSliceBuffer for z_slice_t { +impl ZSliceBuffer for z_loaned_slice_t { fn as_slice(&self) -> &[u8] { self.transmute_ref() } @@ -159,7 +159,7 @@ impl ZSliceBuffer for z_slice_t { #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_bytes( this: *mut MaybeUninit, - bytes: &z_slice_t, + bytes: &z_loaned_slice_t, ) { let this = this.transmute_uninit_ptr(); let payload = ZBytes::from(ZSlice::from(*bytes)); @@ -171,7 +171,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_bytes( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_bytes_map( this: *mut MaybeUninit, - bytes_map: &z_slice_map_t, + bytes_map: &z_loaned_slice_map_t, ) { let dst = this.transmute_uninit_ptr(); let hm = bytes_map.transmute_ref(); @@ -184,7 +184,7 @@ pub unsafe extern "C" fn z_bytes_encode_from_bytes_map( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_encode_from_string( this: *mut MaybeUninit, - s: &z_str_t, + s: &z_loaned_str_t, ) { let s = s.transmute_ref(); let ss = &s[0..s.len() - 1]; @@ -195,8 +195,8 @@ pub unsafe extern "C" fn z_bytes_encode_from_string( pub use crate::opaque_types::z_owned_bytes_reader_t; decl_transmute_owned!(Option>, z_owned_bytes_reader_t); -pub use crate::opaque_types::z_bytes_reader_t; -decl_transmute_handle!(ZBytesReader<'static>, z_bytes_reader_t); +pub use crate::opaque_types::z_loaned_bytes_reader_t; +decl_transmute_handle!(ZBytesReader<'static>, z_loaned_bytes_reader_t); /// Creates a reader for the specified `payload`. /// @@ -204,7 +204,7 @@ decl_transmute_handle!(ZBytesReader<'static>, z_bytes_reader_t); #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_new( - payload: z_bytes_t, + payload: z_loaned_bytes_t, this: *mut MaybeUninit, ) { let this = this.transmute_uninit_ptr(); @@ -233,7 +233,7 @@ extern "C" fn z_bytes_reader_drop(this: &mut z_owned_bytes_reader_t) { } #[no_mangle] -extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_bytes_reader_t { +extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_loaned_bytes_reader_t { let reader = reader.transmute_ref(); let reader = unwrap_ref_unchecked(reader); reader.transmute_handle() @@ -242,7 +242,7 @@ extern "C" fn z_bytes_reader_loan(reader: &z_owned_bytes_reader_t) -> &z_bytes_r #[no_mangle] extern "C" fn z_bytes_reader_loan_mut( reader: &mut z_owned_bytes_reader_t, -) -> &mut z_bytes_reader_t { +) -> &mut z_loaned_bytes_reader_t { let reader = reader.transmute_mut(); let reader = unwrap_ref_unchecked_mut(reader); reader.transmute_handle_mut() @@ -255,7 +255,7 @@ extern "C" fn z_bytes_reader_loan_mut( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_read( - this: &mut z_bytes_reader_t, + this: &mut z_loaned_bytes_reader_t, dest: *mut u8, len: usize, ) -> usize { @@ -271,7 +271,7 @@ pub unsafe extern "C" fn z_bytes_reader_read( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_bytes_reader_seek( - this: &mut z_bytes_reader_t, + this: &mut z_loaned_bytes_reader_t, offset: i64, origin: libc::c_int, ) -> z_error_t { @@ -294,7 +294,7 @@ pub unsafe extern "C" fn z_bytes_reader_seek( /// Returns read position indicator on success or -1L if failure occurs. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_bytes_reader_tell(this: &mut z_bytes_reader_t) -> i64 { +pub unsafe extern "C" fn z_loaned_bytes_reader_tell(this: &mut z_loaned_bytes_reader_t) -> i64 { let reader = this.transmute_mut(); reader.stream_position().map(|p| p as i64).unwrap_or(-1) } diff --git a/src/platform/synchronization.rs b/src/platform/synchronization.rs index 9c2adf78f..52032c8aa 100644 --- a/src/platform/synchronization.rs +++ b/src/platform/synchronization.rs @@ -6,7 +6,7 @@ use std::{ use libc::c_void; -pub use crate::opaque_types::z_mutex_t; +pub use crate::opaque_types::z_loaned_mutex_t; pub use crate::opaque_types::z_owned_mutex_t; use crate::{ errors, @@ -20,7 +20,10 @@ decl_transmute_owned!( Option<(Mutex<()>, Option>)>, z_owned_mutex_t ); -decl_transmute_handle!((Mutex<()>, Option>), z_mutex_t); +decl_transmute_handle!( + (Mutex<()>, Option>), + z_loaned_mutex_t +); #[no_mangle] pub extern "C" fn z_mutex_init(this: *mut MaybeUninit) -> errors::z_error_t { @@ -46,14 +49,14 @@ pub extern "C" fn z_mutex_null(this: *mut MaybeUninit) { } #[no_mangle] -pub extern "C" fn z_mutex_loan_mut(this: &mut z_owned_mutex_t) -> &mut z_mutex_t { +pub extern "C" fn z_mutex_loan_mut(this: &mut z_owned_mutex_t) -> &mut z_loaned_mutex_t { let this = this.transmute_mut(); let this = unwrap_ref_unchecked_mut(this); this.transmute_handle_mut() } #[no_mangle] -pub extern "C" fn z_mutex_lock(this: &mut z_mutex_t) -> errors::z_error_t { +pub extern "C" fn z_mutex_lock(this: &mut z_loaned_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.lock() { @@ -69,7 +72,7 @@ pub extern "C" fn z_mutex_lock(this: &mut z_mutex_t) -> errors::z_error_t { } #[no_mangle] -pub extern "C" fn z_mutex_unlock(this: &mut z_mutex_t) -> errors::z_error_t { +pub extern "C" fn z_mutex_unlock(this: &mut z_loaned_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); if this.1.is_none() { return errors::Z_EINVAL_MUTEX; @@ -81,7 +84,7 @@ pub extern "C" fn z_mutex_unlock(this: &mut z_mutex_t) -> errors::z_error_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_mutex_try_lock(this: &mut z_mutex_t) -> errors::z_error_t { +pub unsafe extern "C" fn z_loaned_mutex_try_lock(this: &mut z_loaned_mutex_t) -> errors::z_error_t { let this = this.transmute_mut(); match this.0.try_lock() { Ok(new_lock) => { @@ -95,11 +98,11 @@ pub unsafe extern "C" fn z_mutex_try_lock(this: &mut z_mutex_t) -> errors::z_err errors::Z_OK } -pub use crate::opaque_types::z_condvar_t; +pub use crate::opaque_types::z_loaned_condvar_t; pub use crate::opaque_types::z_owned_condvar_t; decl_transmute_owned!(Option, z_owned_condvar_t); -decl_transmute_handle!(Condvar, z_condvar_t); +decl_transmute_handle!(Condvar, z_loaned_condvar_t); #[no_mangle] pub extern "C" fn z_condvar_init(this: *mut MaybeUninit) { @@ -124,21 +127,21 @@ pub extern "C" fn z_condvar_check(this: &z_owned_condvar_t) -> bool { } #[no_mangle] -pub extern "C" fn z_condvar_loan(this: &z_owned_condvar_t) -> &z_condvar_t { +pub extern "C" fn z_condvar_loan(this: &z_owned_condvar_t) -> &z_loaned_condvar_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() } #[no_mangle] -pub extern "C" fn z_condvar_loan_mut(this: &mut z_owned_condvar_t) -> &mut z_condvar_t { +pub extern "C" fn z_condvar_loan_mut(this: &mut z_owned_condvar_t) -> &mut z_loaned_condvar_t { let this = this.transmute_mut(); let this = unwrap_ref_unchecked_mut(this); this.transmute_handle_mut() } #[no_mangle] -pub extern "C" fn z_condvar_signal(this: &z_condvar_t) -> errors::z_error_t { +pub extern "C" fn z_condvar_signal(this: &z_loaned_condvar_t) -> errors::z_error_t { let this = this.transmute_ref(); this.notify_one(); errors::Z_OK @@ -147,8 +150,8 @@ pub extern "C" fn z_condvar_signal(this: &z_condvar_t) -> errors::z_error_t { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_condvar_wait( - this: &z_condvar_t, - m: &mut z_mutex_t, + this: &z_loaned_condvar_t, + m: &mut z_loaned_mutex_t, ) -> errors::z_error_t { let this = this.transmute_ref(); let m = m.transmute_mut(); diff --git a/src/publication_cache.rs b/src/publication_cache.rs index 84278e3d8..49cc9f1f1 100644 --- a/src/publication_cache.rs +++ b/src/publication_cache.rs @@ -19,12 +19,12 @@ use zenoh::prelude::SyncResolve; use zenoh_ext::SessionExt; use crate::transmute::{Inplace, TransmuteFromHandle, TransmuteRef, TransmuteUninitPtr}; -use crate::{errors, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality_t}; +use crate::{errors, z_loaned_keyexpr_t, z_loaned_session_t, zcu_locality_default, zcu_locality_t}; /// Options passed to the :c:func:`ze_declare_publication_cache` function. /// /// Members: -/// z_keyexpr_t queryable_prefix: The prefix used for queryable +/// z_loaned_keyexpr_t queryable_prefix: The prefix used for queryable /// zcu_locality_t queryable_origin: The restriction for the matching queries that will be receive by this /// publication cache /// bool queryable_complete: the `complete` option for the queryable @@ -32,7 +32,7 @@ use crate::{errors, z_keyexpr_t, z_session_t, zcu_locality_default, zcu_locality /// size_t resources_limit: The limit number of cached resources #[repr(C)] pub struct ze_publication_cache_options_t { - pub queryable_prefix: *const z_keyexpr_t, + pub queryable_prefix: *const z_loaned_keyexpr_t, pub queryable_origin: zcu_locality_t, pub queryable_complete: bool, pub history: usize, @@ -51,19 +51,22 @@ pub extern "C" fn ze_publication_cache_options_default(this: &mut ze_publication }; } +pub use crate::opaque_types::ze_loaned_publication_cache_t; pub use crate::opaque_types::ze_owned_publication_cache_t; -pub use crate::opaque_types::ze_publication_cache_t; decl_transmute_owned!( Option>, ze_owned_publication_cache_t ); -decl_transmute_handle!(zenoh_ext::PublicationCache<'static>, ze_publication_cache_t); +decl_transmute_handle!( + zenoh_ext::PublicationCache<'static>, + ze_loaned_publication_cache_t +); /// Declares a Publication Cache. /// /// Parameters: -/// z_session_t session: The zenoh session. -/// z_keyexpr_t key_expr: The key expression to publish. +/// z_loaned_session_t session: The zenoh session. +/// z_loaned_keyexpr_t key_expr: The key expression to publish. /// ze_publication_cache_options_t options: Additional options for the publication_cache. /// /// Returns: @@ -87,8 +90,8 @@ decl_transmute_handle!(zenoh_ext::PublicationCache<'static>, ze_publication_cach #[allow(clippy::missing_safety_doc)] pub extern "C" fn ze_declare_publication_cache( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, options: Option<&mut ze_publication_cache_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); diff --git a/src/publisher.rs b/src/publisher.rs index 8b647dfd4..f4d6b8cbf 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -34,7 +34,9 @@ use zenoh::{prelude::Priority, publication::MatchingListener, publication::Publi use zenoh::prelude::SyncResolve; -use crate::{z_congestion_control_t, z_keyexpr_t, z_owned_bytes_t, z_priority_t, z_session_t}; +use crate::{ + z_congestion_control_t, z_loaned_keyexpr_t, z_loaned_session_t, z_owned_bytes_t, z_priority_t, +}; /// Options passed to the :c:func:`z_declare_publisher` function. /// @@ -58,8 +60,8 @@ pub extern "C" fn z_publisher_options_default(this: &mut z_publisher_options_t) pub use crate::opaque_types::z_owned_publisher_t; decl_transmute_owned!(Option>, z_owned_publisher_t); -pub use crate::opaque_types::z_publisher_t; -decl_transmute_handle!(Publisher<'static>, z_publisher_t); +pub use crate::opaque_types::z_loaned_publisher_t; +decl_transmute_handle!(Publisher<'static>, z_loaned_publisher_t); /// Declares a publisher for the given key expression. /// @@ -98,8 +100,8 @@ decl_transmute_handle!(Publisher<'static>, z_publisher_t); #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_publisher( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, options: Option<&z_publisher_options_t>, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); @@ -139,9 +141,9 @@ pub extern "C" fn z_publisher_check(this: &z_owned_publisher_t) -> bool { this.transmute_ref().is_some() } -/// Returns a :c:type:`z_publisher_t` loaned from `p`. +/// Returns a :c:type:`z_loaned_publisher_t` loaned from `p`. #[no_mangle] -pub extern "C" fn z_publisher_loan(this: &z_owned_publisher_t) -> &z_publisher_t { +pub extern "C" fn z_publisher_loan(this: &z_owned_publisher_t) -> &z_loaned_publisher_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() @@ -185,7 +187,7 @@ pub extern "C" fn z_publisher_put_options_default(this: &mut z_publisher_put_opt #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_publisher_put( - publisher: &z_publisher_t, + publisher: &z_loaned_publisher_t, payload: &mut z_owned_bytes_t, options: Option<&mut z_publisher_put_options_t>, ) -> errors::z_error_t { @@ -241,7 +243,7 @@ pub extern "C" fn z_publisher_delete_options_default(this: &mut z_publisher_dele #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_publisher_delete( - publisher: &z_publisher_t, + publisher: &z_loaned_publisher_t, _options: z_publisher_delete_options_t, ) -> errors::z_error_t { let publisher = publisher.transmute_ref(); @@ -256,7 +258,7 @@ pub extern "C" fn z_publisher_delete( /// Returns the key expression of the publisher #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_publisher_keyexpr(publisher: &z_publisher_t) -> &z_keyexpr_t { +pub extern "C" fn z_publisher_keyexpr(publisher: &z_loaned_publisher_t) -> &z_loaned_keyexpr_t { let publisher = publisher.transmute_ref(); publisher.key_expr().transmute_handle() } @@ -282,7 +284,7 @@ pub struct zcu_matching_status_t { #[allow(clippy::missing_safety_doc)] pub extern "C" fn zcu_publisher_matching_listener_callback( this: *mut MaybeUninit, - publisher: &z_publisher_t, + publisher: &z_loaned_publisher_t, callback: &mut zcu_owned_closure_matching_status_t, ) -> errors::z_error_t { let this = this.transmute_uninit_ptr(); diff --git a/src/pull_subscriber.rs b/src/pull_subscriber.rs index 624be46cb..79ba96eb3 100644 --- a/src/pull_subscriber.rs +++ b/src/pull_subscriber.rs @@ -136,8 +136,8 @@ pub extern "C" fn z_pull_subscriber_options_default() -> z_pull_subscriber_optio #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_pull_subscriber( - session: z_session_t, - keyexpr: z_keyexpr_t, + session: z_loaned_session_t, + keyexpr: z_loaned_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: Option<&z_pull_subscriber_options_t>, ) -> z_owned_pull_subscriber_t { @@ -149,7 +149,7 @@ pub extern "C" fn z_declare_pull_subscriber( let mut res = s .declare_subscriber(keyexpr) .callback(move |sample| { - let sample = z_sample_t::new(&sample); + let sample = z_loaned_sample_t::new(&sample); z_closure_sample_call(&closure, &sample) }) .pull_mode(); diff --git a/src/put.rs b/src/put.rs index 74b63b4b8..ef5f99801 100644 --- a/src/put.rs +++ b/src/put.rs @@ -19,8 +19,8 @@ use crate::keyexpr::*; use crate::transmute::Inplace; use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteRef; +use crate::z_loaned_session_t; use crate::z_owned_bytes_t; -use crate::z_session_t; use zenoh::prelude::{sync::SyncResolve, Priority}; use zenoh::publication::CongestionControl; use zenoh::sample::QoSBuilderTrait; @@ -30,10 +30,10 @@ use zenoh::sample::ValueBuilderTrait; /// Options passed to the :c:func:`z_put` function. /// /// Members: -/// z_encoding_t encoding: The encoding of the payload. +/// z_loaned_encoding_t encoding: The encoding of the payload. /// z_congestion_control_t congestion_control: The congestion control to apply when routing this message. /// z_priority_t priority: The priority of this message. -/// z_bytes_t attachment: The attachment to this message. +/// z_loaned_bytes_t attachment: The attachment to this message. #[repr(C)] #[allow(non_camel_case_types)] pub struct z_put_options_t { @@ -71,8 +71,8 @@ pub extern "C" fn z_put_options_default(this: &mut z_put_options_t) { #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_put( - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, payload: &mut z_owned_bytes_t, options: Option<&mut z_put_options_t>, ) -> errors::z_error_t { @@ -135,8 +135,8 @@ pub unsafe extern "C" fn z_delete_options_default(this: *mut z_delete_options_t) #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_delete( - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, options: Option<&mut z_delete_options_t>, ) -> errors::z_error_t { let session = session.transmute_ref(); diff --git a/src/queryable.rs b/src/queryable.rs index 0f2de51ce..03da4edbe 100644 --- a/src/queryable.rs +++ b/src/queryable.rs @@ -16,8 +16,9 @@ use crate::transmute::{ TransmuteUninitPtr, }; use crate::{ - errors, z_bytes_t, z_closure_query_call, z_keyexpr_t, z_owned_bytes_t, z_owned_closure_query_t, - z_owned_encoding_t, z_session_t, z_value_t, z_view_slice_t, z_view_slice_wrap, + errors, z_closure_query_call, z_loaned_bytes_t, z_loaned_keyexpr_t, z_loaned_session_t, + z_loaned_value_t, z_owned_bytes_t, z_owned_closure_query_t, z_owned_encoding_t, z_view_slice_t, + z_view_slice_wrap, }; use std::mem::MaybeUninit; use std::ptr::{null, null_mut}; @@ -36,8 +37,8 @@ pub extern "C" fn z_queryable_null(this: *mut MaybeUninit) Inplace::empty(this.transmute_uninit_ptr()); } -pub use crate::opaque_types::z_query_t; -decl_transmute_handle!(Query, z_query_t); +pub use crate::opaque_types::z_loaned_query_t; +decl_transmute_handle!(Query, z_loaned_query_t); /// Owned variant of a Query received by a Queryable. /// @@ -66,7 +67,7 @@ pub extern "C" fn z_query_check(query: &z_owned_query_t) -> bool { /// /// This function may not be called with the null pointer, but can be called with the gravestone value. #[no_mangle] -pub extern "C" fn z_query_loan(this: &'static z_owned_query_t) -> &z_query_t { +pub extern "C" fn z_query_loan(this: &'static z_owned_query_t) -> &z_loaned_query_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() @@ -82,7 +83,7 @@ pub extern "C" fn z_query_drop(this: &mut z_owned_query_t) { /// /// This operation is infallible, but may return a gravestone value if `query` itself was a gravestone value (which cannot be the case in a callback). #[no_mangle] -pub extern "C" fn z_query_clone(this: &z_query_t, dst: *mut MaybeUninit) { +pub extern "C" fn z_query_clone(this: &z_loaned_query_t, dst: *mut MaybeUninit) { let this = this.transmute_ref(); let this = this.clone(); let dst = dst.transmute_uninit_ptr(); @@ -142,8 +143,8 @@ pub extern "C" fn z_query_reply_options_default(this: &mut z_query_reply_options #[no_mangle] pub extern "C" fn z_declare_queryable( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, callback: &mut z_owned_closure_query_t, options: Option<&mut z_queryable_options_t>, ) -> errors::z_error_t { @@ -210,8 +211,8 @@ pub extern "C" fn z_queryable_check(qable: &z_owned_queryable_t) -> bool { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_query_reply( - query: z_query_t, - key_expr: z_keyexpr_t, + query: z_loaned_query_t, + key_expr: z_loaned_keyexpr_t, payload: &mut z_owned_bytes_t, options: Option<&mut z_query_reply_options_t>, ) -> errors::z_error_t { @@ -248,7 +249,7 @@ pub unsafe extern "C" fn z_query_reply( /// Get a query's key by aliasing it. #[allow(clippy::missing_safety_doc)] #[no_mangle] -pub extern "C" fn z_query_keyexpr(query: &z_query_t) -> &z_keyexpr_t { +pub extern "C" fn z_query_keyexpr(query: &z_loaned_query_t) -> &z_loaned_keyexpr_t { query.transmute_ref().key_expr().transmute_handle() } @@ -256,7 +257,7 @@ pub extern "C" fn z_query_keyexpr(query: &z_query_t) -> &z_keyexpr_t { #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn z_query_parameters( - query: &z_query_t, + query: &z_loaned_query_t, parameters: *mut MaybeUninit, ) { let query = query.transmute_ref(); @@ -266,7 +267,7 @@ pub unsafe extern "C" fn z_query_parameters( /// Checks if query contains a payload value. #[no_mangle] -pub extern "C" fn z_query_has_value(query: &z_query_t) -> bool { +pub extern "C" fn z_query_has_value(query: &z_loaned_query_t) -> bool { query.transmute_ref().value().is_some() } @@ -275,7 +276,7 @@ pub extern "C" fn z_query_has_value(query: &z_query_t) -> bool { /// **WARNING: This API has been marked as unstable: it works as advertised, but it may change in a future release.** /// Before calling this funciton, the user must ensure that `z_query_has_value` returns true. #[no_mangle] -pub extern "C" fn z_query_value(query: &z_query_t) -> &z_value_t { +pub extern "C" fn z_query_value(query: &z_loaned_query_t) -> &z_loaned_value_t { query .transmute_ref() .value() @@ -287,7 +288,7 @@ pub extern "C" fn z_query_value(query: &z_query_t) -> &z_value_t { /// /// Returns NULL if query does not contain an attachment. #[no_mangle] -pub extern "C" fn z_query_attachment(query: &z_query_t) -> *const z_bytes_t { +pub extern "C" fn z_query_attachment(query: &z_loaned_query_t) -> *const z_loaned_bytes_t { match query.transmute_ref().attachment() { Some(attachment) => attachment.transmute_handle() as *const _, None => null(), diff --git a/src/querying_subscriber.rs b/src/querying_subscriber.rs index 0166314f1..c1d180ecc 100644 --- a/src/querying_subscriber.rs +++ b/src/querying_subscriber.rs @@ -22,13 +22,13 @@ use crate::transmute::TransmuteFromHandle; use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; -use crate::z_keyexpr_t; +use crate::z_loaned_keyexpr_t; use crate::z_owned_closure_sample_t; use crate::z_reliability_t; use crate::{ - z_closure_sample_call, z_get_options_t, z_query_consolidation_none, z_query_consolidation_t, - z_query_target_default, z_query_target_t, z_session_t, zcu_locality_default, zcu_locality_t, - zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, + z_closure_sample_call, z_get_options_t, z_loaned_query_target_default, z_loaned_query_target_t, + z_loaned_session_t, z_query_consolidation_none, z_query_consolidation_t, zcu_locality_default, + zcu_locality_t, zcu_reply_keyexpr_default, zcu_reply_keyexpr_t, }; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; @@ -36,15 +36,15 @@ use zenoh::session::Session; use zenoh::subscriber::Reliability; use zenoh_ext::*; +use crate::opaque_types::ze_loaned_querying_subscriber_t; use crate::opaque_types::ze_owned_querying_subscriber_t; -use crate::opaque_types::ze_querying_subscriber_t; decl_transmute_owned!( Option<(zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session)>, ze_owned_querying_subscriber_t ); decl_transmute_handle!( (zenoh_ext::FetchingSubscriber<'static, ()>, &'static Session), - ze_querying_subscriber_t + ze_loaned_querying_subscriber_t ); /// Constructs a null safe-to-drop value of 'ze_owned_querying_subscriber_t' type @@ -64,8 +64,8 @@ pub extern "C" fn ze_querying_subscriber_null( /// z_reliability_t reliability: The subscription reliability. /// zcu_locality_t allowed_origin: The restriction for the matching publications that will be /// receive by this subscriber. -/// z_keyexpr_t query_selector: The selector to be used for queries. -/// z_query_target_t query_target: The target to be used for queries. +/// z_loaned_keyexpr_t query_selector: The selector to be used for queries. +/// z_loaned_query_target_t query_target: The target to be used for queries. /// z_query_consolidation_t query_consolidation: The consolidation mode to be used for queries. /// zcu_reply_keyexpr_t query_accept_replies: The accepted replies for queries. /// uint64_t query_timeout_ms: The timeout to be used for queries. @@ -74,8 +74,8 @@ pub extern "C" fn ze_querying_subscriber_null( pub struct ze_querying_subscriber_options_t { reliability: z_reliability_t, allowed_origin: zcu_locality_t, - query_selector: *const z_keyexpr_t, - query_target: z_query_target_t, + query_selector: *const z_loaned_keyexpr_t, + query_target: z_loaned_query_target_t, query_consolidation: z_query_consolidation_t, query_accept_replies: zcu_reply_keyexpr_t, query_timeout_ms: u64, @@ -90,7 +90,7 @@ pub extern "C" fn ze_querying_subscriber_options_default( reliability: Reliability::DEFAULT.into(), allowed_origin: zcu_locality_default(), query_selector: null(), - query_target: z_query_target_default(), + query_target: z_loaned_query_target_default(), query_consolidation: z_query_consolidation_none(), query_accept_replies: zcu_reply_keyexpr_default(), query_timeout_ms: 0, @@ -100,8 +100,8 @@ pub extern "C" fn ze_querying_subscriber_options_default( /// Declares a Querying Subscriber for a given key expression. /// /// Parameters: -/// z_session_t session: The zenoh session. -/// z_keyexpr_t keyexpr: The key expression to subscribe. +/// z_loaned_session_t session: The zenoh session. +/// z_loaned_keyexpr_t keyexpr: The key expression to subscribe. /// z_owned_closure_sample_t callback: The callback function that will be called each time a data matching the subscribed expression is received. /// ze_querying_subscriber_options_t options: Additional options for the querying subscriber. /// @@ -132,8 +132,8 @@ pub extern "C" fn ze_querying_subscriber_options_default( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn ze_declare_querying_subscriber( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: Option<&mut ze_querying_subscriber_options_t>, ) -> errors::z_error_t { @@ -181,8 +181,8 @@ pub unsafe extern "C" fn ze_declare_querying_subscriber( #[allow(clippy::missing_safety_doc)] #[no_mangle] pub unsafe extern "C" fn ze_querying_subscriber_get( - sub: &ze_querying_subscriber_t, - selector: &z_keyexpr_t, + sub: &ze_loaned_querying_subscriber_t, + selector: &z_loaned_keyexpr_t, options: Option<&z_get_options_t>, ) -> errors::z_error_t { unsafe impl Sync for z_get_options_t {} @@ -237,7 +237,7 @@ pub extern "C" fn ze_querying_subscriber_check(this: &ze_owned_querying_subscrib #[no_mangle] pub extern "C" fn ze_querying_subscriber_loan( this: &ze_owned_querying_subscriber_t, -) -> &ze_querying_subscriber_t { +) -> &ze_loaned_querying_subscriber_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() diff --git a/src/scouting.rs b/src/scouting.rs index 7609c3a38..7a7931301 100644 --- a/src/scouting.rs +++ b/src/scouting.rs @@ -15,8 +15,8 @@ use crate::{ errors::{self, Z_OK}, transmute::{Inplace, TransmuteRef}, z_closure_hello_call, z_config_check, z_config_clone, z_config_default, z_config_drop, - z_config_null, z_config_t, z_id_t, z_owned_closure_hello_t, z_owned_config_t, zc_init_logger, - CopyableToCArray, + z_config_null, z_id_t, z_loaned_config_t, z_owned_closure_hello_t, z_owned_config_t, + zc_init_logger, CopyableToCArray, }; use async_std::task; use libc::{c_char, c_uint, c_ulong, size_t}; @@ -219,7 +219,7 @@ pub unsafe extern "C" fn z_scouting_config_default( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_scouting_config_from( this: *mut MaybeUninit, - config: &z_config_t, + config: &z_loaned_config_t, ) { let mut dst = MaybeUninit::uninit(); z_config_clone(config, &mut dst as *mut _); diff --git a/src/session.rs b/src/session.rs index 049fd7ca3..768bdf720 100644 --- a/src/session.rs +++ b/src/session.rs @@ -26,19 +26,19 @@ use crate::opaque_types::z_owned_session_t; decl_transmute_owned!(Option>, z_owned_session_t); /// A loaned zenoh session. -use crate::opaque_types::z_session_t; -decl_transmute_handle!(Session, z_session_t); +use crate::opaque_types::z_loaned_session_t; +decl_transmute_handle!(Session, z_loaned_session_t); -/// Returns a :c:type:`z_session_t` loaned from `s`. +/// Returns a :c:type:`z_loaned_session_t` loaned from `s`. /// /// This handle doesn't increase the refcount of the session, but does allow to do so with `zc_session_rcinc`. /// /// # Safety -/// The returned `z_session_t` aliases `z_owned_session_t`'s internal allocation, +/// The returned `z_loaned_session_t` aliases `z_owned_session_t`'s internal allocation, /// attempting to use it after all owned handles to the session (including publishers, queryables and subscribers) /// have been destroyed is UB (likely SEGFAULT) #[no_mangle] -pub extern "C" fn z_session_loan(this: &z_owned_session_t) -> &z_session_t { +pub extern "C" fn z_session_loan(this: &z_owned_session_t) -> &z_loaned_session_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); let this = this.as_ref(); diff --git a/src/shm.rs b/src/shm.rs index 52f9d51cd..cb90ed65f 100644 --- a/src/shm.rs +++ b/src/shm.rs @@ -23,7 +23,7 @@ use zenoh::{ shm::{SharedMemoryBuf, SharedMemoryManager}, }; -use crate::{z_session_t, z_owned_bytes_t, z_bytes_null}; +use crate::{z_loaned_session_t, z_owned_bytes_t, z_bytes_null}; #[repr(C)] pub struct zc_owned_shm_manager_t(usize); @@ -51,7 +51,7 @@ impl zc_owned_shm_manager_t { #[no_mangle] pub extern "C" fn zc_shm_manager_new( - session: z_session_t, + session: z_loaned_session_t, id: *const c_char, size: usize, ) -> zc_owned_shm_manager_t { diff --git a/src/subscriber.rs b/src/subscriber.rs index ad5d73e4d..f1cb26beb 100644 --- a/src/subscriber.rs +++ b/src/subscriber.rs @@ -23,8 +23,8 @@ use crate::transmute::TransmuteIntoHandle; use crate::transmute::TransmuteRef; use crate::transmute::TransmuteUninitPtr; use crate::z_closure_sample_call; +use crate::z_loaned_session_t; use crate::z_owned_closure_sample_t; -use crate::z_session_t; use zenoh::prelude::sync::SyncResolve; use zenoh::prelude::SessionDeclarations; use zenoh::subscriber::Reliability; @@ -62,11 +62,11 @@ impl From for Reliability { } } +pub use crate::opaque_types::z_loaned_subscriber_t; pub use crate::opaque_types::z_owned_subscriber_t; -pub use crate::opaque_types::z_subscriber_t; decl_transmute_owned!(Option>, z_owned_subscriber_t); -decl_transmute_handle!(Subscriber<'static, ()>, z_subscriber_t); +decl_transmute_handle!(Subscriber<'static, ()>, z_loaned_subscriber_t); /// Constructs a null safe-to-drop value of 'z_owned_subscriber_t' type #[no_mangle] @@ -75,9 +75,9 @@ pub extern "C" fn z_subscriber_null(this: *mut MaybeUninit Inplace::empty(this); } -/// Returns a :c:type:`z_subscriber_t` loaned from `this`. +/// Returns a :c:type:`z_loaned_subscriber_t` loaned from `this`. #[no_mangle] -pub extern "C" fn z_subscriber_loan(this: &z_owned_subscriber_t) -> &z_subscriber_t { +pub extern "C" fn z_subscriber_loan(this: &z_owned_subscriber_t) -> &z_loaned_subscriber_t { let this = this.transmute_ref(); let this = unwrap_ref_unchecked(this); this.transmute_handle() @@ -136,8 +136,8 @@ pub extern "C" fn z_subscriber_options_default(this: &mut z_subscriber_options_t #[allow(clippy::missing_safety_doc)] pub extern "C" fn z_declare_subscriber( this: *mut MaybeUninit, - session: &z_session_t, - key_expr: &z_keyexpr_t, + session: &z_loaned_session_t, + key_expr: &z_loaned_keyexpr_t, callback: &mut z_owned_closure_sample_t, options: Option<&mut z_subscriber_options_t>, ) -> errors::z_error_t { @@ -171,7 +171,7 @@ pub extern "C" fn z_declare_subscriber( /// Returns the key expression of the subscriber. #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub extern "C" fn z_subscriber_keyexpr(subscriber: &z_subscriber_t) -> &z_keyexpr_t { +pub extern "C" fn z_subscriber_keyexpr(subscriber: &z_loaned_subscriber_t) -> &z_loaned_keyexpr_t { let subscriber = subscriber.transmute_ref(); subscriber.key_expr().transmute_handle() } diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index 062c7c7ad..57bb31fd9 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -41,19 +41,19 @@ void hello_handler(z_owned_hello_t *hello, void *arg) { } volatile unsigned int queries = 0; -void query_handler(const z_query_t *query, void *arg) { +void query_handler(const z_loaned_query_t *query, void *arg) { queries++; - z_owned_str_t k_str = z_keyexpr_to_string(z_query_keyexpr(query)); + z_owned_str_t k_str = z_loaned_keyexpr_to_string(z_query_keyexpr(query)); #ifdef ZENOH_PICO if (k_str == NULL) { - k_str = zp_keyexpr_resolve(*(z_session_t *)arg, z_query_keyexpr(query)); + k_str = zp_keyexpr_resolve(*(z_loaned_session_t *)arg, z_query_keyexpr(query)); } #endif - z_slice_t pred = z_query_parameters(query); + z_loaned_slice_t pred = z_query_parameters(query); (void)(pred); - z_value_t payload_value = z_query_value(query); + z_loaned_value_t payload_value = z_query_value(query); (void)(payload_value); z_query_reply_options_t _ret_qreply_opt = z_query_reply_options_default(); z_owned_bytes_t payload = z_bytes_encode_from_string(value); @@ -67,17 +67,17 @@ void reply_handler(z_owned_reply_t *reply, void *arg) { replies++; if (z_reply_is_ok(reply)) { - z_sample_t sample = z_reply_ok(reply); + z_loaned_sample_t sample = z_reply_ok(reply); - z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_owned_str_t k_str = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); #ifdef ZENOH_PICO if (k_str == NULL) { - k_str = zp_keyexpr_resolve(*(z_session_t *)arg, sample.keyexpr); + k_str = zp_keyexpr_resolve(*(z_loaned_session_t *)arg, sample.keyexpr); } #endif z_drop(z_move(k_str)); } else { - z_value_t _ret_zvalue = z_reply_err(reply); + z_loaned_value_t _ret_zvalue = z_reply_err(reply); (void)(_ret_zvalue); } @@ -85,13 +85,13 @@ void reply_handler(z_owned_reply_t *reply, void *arg) { } volatile unsigned int datas = 0; -void data_handler(const z_sample_t *sample, void *arg) { +void data_handler(const z_loaned_sample_t *sample, void *arg) { datas++; - z_owned_str_t k_str = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t k_str = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); #ifdef ZENOH_PICO if (k_str == NULL) { - k_str = zp_keyexpr_resolve(*(z_session_t *)arg, sample->keyexpr); + k_str = zp_keyexpr_resolve(*(z_loaned_session_t *)arg, sample->keyexpr); } #endif z_drop(z_move(k_str)); @@ -104,7 +104,7 @@ int main(int argc, char **argv) { zc_init_logger(); #endif - z_keyexpr_t key = z_keyexpr("demo/example"); + z_loaned_keyexpr_t key = z_keyexpr("demo/example"); _Bool _ret_bool = z_keyexpr_is_initialized(&key); assert(_ret_bool == true); @@ -243,7 +243,7 @@ int main(int argc, char **argv) { z_sleep_s(SLEEP); - z_session_t ls1 = z_loan(s1); + z_loaned_session_t ls1 = z_loan(s1); z_owned_closure_sample_t _ret_closure_sample = z_closure(data_handler, NULL, &ls1); z_subscriber_options_t _ret_sub_opt = z_subscriber_options_default(); z_owned_subscriber_t _ret_sub = @@ -258,7 +258,7 @@ int main(int argc, char **argv) { assert(z_check(_ret_expr)); z_put_options_t _ret_put_opt = z_put_options_default(); _ret_put_opt.congestion_control = Z_CONGESTION_CONTROL_BLOCK; - z_encoding_t _ret_encoding = z_encoding_default(); + z_loaned_encoding_t _ret_encoding = z_encoding_default(); _ret_encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); _ret_put_opt.encoding = _ret_encoding; z_owned_bytes_t payload = z_bytes_encode_from_string(value); @@ -333,10 +333,10 @@ int main(int argc, char **argv) { z_sleep_s(SLEEP); - z_session_t ls2 = z_loan(s2); + z_loaned_session_t ls2 = z_loan(s2); z_owned_closure_reply_t _ret_closure_reply = z_closure(reply_handler, NULL, &ls2); z_get_options_t _ret_get_opt = z_get_options_default(); - _ret_get_opt.target = z_query_target_default(); + _ret_get_opt.target = z_loaned_query_target_default(); _ret_get_opt.consolidation = z_query_consolidation_auto(); _ret_get_opt.consolidation = z_query_consolidation_default(); _ret_get_opt.consolidation = z_query_consolidation_latest(); diff --git a/tests/z_api_attachment_test.c b/tests/z_api_attachment_test.c index 7669a3605..ebcdc6993 100644 --- a/tests/z_api_attachment_test.c +++ b/tests/z_api_attachment_test.c @@ -26,7 +26,7 @@ void writting_through_map_by_alias_read_by_get() { z_owned_bytes_map_t map = z_slice_map_new(); z_slice_map_insert_by_alias(&map, z_slice_from_str("k1"), z_slice_from_str("v1")); z_slice_map_insert_by_alias(&map, z_slice_from_str("k2"), z_slice_from_str("v2")); - z_bytes_t attachment = z_slice_map_as_attachment(&map); + z_loaned_bytes_t attachment = z_slice_map_as_attachment(&map); // Elements check @@ -34,20 +34,20 @@ void writting_through_map_by_alias_read_by_get() { assert(z_attachment_len(attachment) == 2); assert(!z_attachment_is_empty(attachment)); - z_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); + z_loaned_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); ASSERT_STR_BYTES_EQUAL("v1", a1); - z_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); + z_loaned_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); ASSERT_STR_BYTES_EQUAL("v2", a2); - z_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); + z_loaned_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); assert(a_non.start == NULL); assert(a_non.len == 0); z_drop(z_move(map)); } -int8_t _attachment_reader(z_slice_t key, z_slice_t value, void* ctx) { +int8_t _attachment_reader(z_loaned_slice_t key, z_loaned_slice_t value, void* ctx) { assert((size_t)ctx == 42); if (!strncmp(key.start, "k1", key.len)) { assert(!strncmp(value.start, "v1", value.len)); @@ -63,7 +63,7 @@ void writting_through_map_by_copy_read_by_iter() { z_owned_bytes_map_t map = z_slice_map_new(); z_slice_map_insert_by_copy(&map, z_slice_from_str("k1"), z_slice_from_str("v1")); z_slice_map_insert_by_copy(&map, z_slice_from_str("k2"), z_slice_from_str("v2")); - z_bytes_t attachment = z_slice_map_as_attachment(&map); + z_loaned_bytes_t attachment = z_slice_map_as_attachment(&map); // Elements check assert(z_slice_map_len(&map) == 2); @@ -87,29 +87,29 @@ int8_t _iteration_driver(const void* data, z_attachment_iter_body_t body, void* } void writting_no_map_read_by_get() { - z_bytes_t attachment = {.data = NULL, .iteration_driver = &_iteration_driver}; + z_loaned_bytes_t attachment = {.data = NULL, .iteration_driver = &_iteration_driver}; // Elements check assert(z_attachment_len(attachment) == 2); assert(!z_attachment_is_empty(attachment)); - z_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); + z_loaned_slice_t a1 = z_attachment_get(attachment, z_slice_from_str("k1")); ASSERT_STR_BYTES_EQUAL("v1", a1); - z_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); + z_loaned_slice_t a2 = z_attachment_get(attachment, z_slice_from_str("k2")); ASSERT_STR_BYTES_EQUAL("v2", a2); - z_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); + z_loaned_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); assert(a_non.start == NULL); assert(a_non.len == 0); } void invalid_attachment_safety() { - z_bytes_t attachment = z_attachment_null(); + z_loaned_bytes_t attachment = z_attachment_null(); assert(z_attachment_is_empty(attachment)); assert(z_attachment_len(attachment) == 0); - z_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); + z_loaned_slice_t a_non = z_attachment_get(attachment, z_slice_from_str("k_non")); assert(a_non.start == NULL); assert(a_non.len == 0); diff --git a/tests/z_api_double_drop_test.c b/tests/z_api_double_drop_test.c index 3fd158f12..48b5927f6 100644 --- a/tests/z_api_double_drop_test.c +++ b/tests/z_api_double_drop_test.c @@ -71,7 +71,7 @@ void test_scouting_config() { assert(!z_check(config)); } -void data_handler(const z_sample_t *sample, void *arg) {} +void data_handler(const z_loaned_sample_t *sample, void *arg) {} void test_pull_subscriber() { z_owned_config_t config = z_config_default(); @@ -99,7 +99,7 @@ void test_subscriber() { z_drop(z_move(s)); } -void query_handler(const z_query_t *query, void *context) {} +void query_handler(const z_loaned_query_t *query, void *context) {} void test_queryable() { z_owned_config_t config = z_config_default(); diff --git a/tests/z_api_keyexpr_drop_test.c b/tests/z_api_keyexpr_drop_test.c index ac81be4cd..08b77038d 100644 --- a/tests/z_api_keyexpr_drop_test.c +++ b/tests/z_api_keyexpr_drop_test.c @@ -29,14 +29,14 @@ void test_publisher() { z_owned_publisher_t pub = z_declare_publisher(z_loan(s), z_keyexpr(keyexpr), NULL); strncpy(keyexpr, "baz/quax", 256); // Update source string to ensure that the correct keyexpr z_owned_keyexpr_t pub_keyexpr = z_publisher_keyexpr(z_loan(pub)); - z_owned_str_t pub_keyexpr_str = z_keyexpr_to_string(z_loan(pub_keyexpr)); + z_owned_str_t pub_keyexpr_str = z_loaned_keyexpr_to_string(z_loan(pub_keyexpr)); assert(strcmp(z_loan(pub_keyexpr_str), "foo/bar") == 0); // Check that publisher keeps the correct keyexpr z_drop(z_move(pub_keyexpr_str)); z_drop(z_move(pub)); z_drop(z_move(s)); } -void data_handler(const z_sample_t *sample, void *arg) {} +void data_handler(const z_loaned_sample_t *sample, void *arg) {} // void test_pull_subscriber() { // z_owned_config_t config = z_config_default(); @@ -59,14 +59,14 @@ void test_subscriber() { z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); strncpy(keyexpr, "baz/quax", 256); // Update source string to ensure that the keyexpr is copied into the subscriber z_owned_keyexpr_t sub_keyexpr = z_subscriber_keyexpr(z_loan(sub)); - z_owned_str_t sub_keyexpr_str = z_keyexpr_to_string(z_loan(sub_keyexpr)); + z_owned_str_t sub_keyexpr_str = z_loaned_keyexpr_to_string(z_loan(sub_keyexpr)); assert(strcmp(z_loan(sub_keyexpr_str), "foo/bar") == 0); // Check that subscriber keeps the correct keyexpr z_drop(z_move(sub_keyexpr_str)); z_drop(z_move(sub)); z_drop(z_move(s)); } -// void query_handler(const z_query_t *query, void *context) {} +// void query_handler(const z_loaned_query_t *query, void *context) {} // void test_queryable() { // z_owned_config_t config = z_config_default(); diff --git a/tests/z_api_keyexpr_test.c b/tests/z_api_keyexpr_test.c index cb3c234b3..e62e27d09 100644 --- a/tests/z_api_keyexpr_test.c +++ b/tests/z_api_keyexpr_test.c @@ -43,7 +43,7 @@ void canonize() { assert(strcmp(keyexpr, "a/**/c") == 0); strcpy(keyexpr, "a/**/**/c"); - z_keyexpr_t key_expr_canonized = z_keyexpr_autocanonize(keyexpr); + z_loaned_keyexpr_t key_expr_canonized = z_keyexpr_autocanonize(keyexpr); assert(z_keyexpr_check(keyexpr) == true); assert(strcmp(keyexpr, "a/**/c") == 0); assert(z_keyexpr_as_bytes(key_expr_canonized).len == len_new); @@ -60,9 +60,9 @@ void canonize() { } void includes() { - z_keyexpr_t nul = z_keyexpr(NULL); - z_keyexpr_t foobar = z_keyexpr("foo/bar"); - z_keyexpr_t foostar = z_keyexpr("foo/*"); + z_loaned_keyexpr_t nul = z_keyexpr(NULL); + z_loaned_keyexpr_t foobar = z_keyexpr("foo/bar"); + z_loaned_keyexpr_t foostar = z_keyexpr("foo/*"); assert(z_keyexpr_includes(foostar, foobar) == 0); assert(z_keyexpr_includes(foobar, foostar) == -1); assert(z_keyexpr_includes(nul, foobar) < -1); @@ -70,10 +70,10 @@ void includes() { } void intersects() { - z_keyexpr_t nul = z_keyexpr(NULL); - z_keyexpr_t foobar = z_keyexpr("foo/bar"); - z_keyexpr_t foostar = z_keyexpr("foo/*"); - z_keyexpr_t barstar = z_keyexpr("bar/*"); + z_loaned_keyexpr_t nul = z_keyexpr(NULL); + z_loaned_keyexpr_t foobar = z_keyexpr("foo/bar"); + z_loaned_keyexpr_t foostar = z_keyexpr("foo/*"); + z_loaned_keyexpr_t barstar = z_keyexpr("bar/*"); assert(z_keyexpr_intersects(foostar, foobar) == 0); assert(z_keyexpr_intersects(barstar, foobar) == -1); assert(z_keyexpr_intersects(nul, foobar) < -1); @@ -90,10 +90,10 @@ void undeclare() { } void relation_to() { - z_keyexpr_t nul = z_keyexpr(NULL); - z_keyexpr_t foobar = z_keyexpr("foo/bar"); - z_keyexpr_t foostar = z_keyexpr("foo/*"); - z_keyexpr_t barstar = z_keyexpr("bar/*"); + z_loaned_keyexpr_t nul = z_keyexpr(NULL); + z_loaned_keyexpr_t foobar = z_keyexpr("foo/bar"); + z_loaned_keyexpr_t foostar = z_keyexpr("foo/*"); + z_loaned_keyexpr_t barstar = z_keyexpr("bar/*"); assert(z_keyexpr_relation_to(foostar, foobar) == Z_KEYEXPR_INTERSECTION_LEVEL_INCLUDES); assert(z_keyexpr_relation_to(foobar, foostar) == Z_KEYEXPR_INTERSECTION_LEVEL_INTERSECTS); assert(z_keyexpr_relation_to(foostar, foostar) == Z_KEYEXPR_INTERSECTION_LEVEL_EQUALS); diff --git a/tests/z_api_payload_test.c b/tests/z_api_payload_test.c index 9d8df0076..3e2fed1b2 100644 --- a/tests/z_api_payload_test.c +++ b/tests/z_api_payload_test.c @@ -24,7 +24,7 @@ void test_reader() { uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; uint8_t data_out[10] = {0}; - z_slice_t bytes = {.start = data, .len = 10 }; + z_loaned_slice_t bytes = {.start = data, .len = 10 }; z_owned_bytes_t payload = z_bytes_encode_from_bytes(bytes); z_bytes_reader reader; diff --git a/tests/z_api_unitinialized_check.c b/tests/z_api_unitinialized_check.c index 5a4df764e..3b6f95da0 100644 --- a/tests/z_api_unitinialized_check.c +++ b/tests/z_api_unitinialized_check.c @@ -25,6 +25,6 @@ int main(int argc, char **argv) { z_owned_keyexpr_t owned_keyexpr = z_keyexpr_new(NULL); assert(!z_check(owned_keyexpr)); - z_keyexpr_t keyexpr = z_keyexpr(NULL); + z_loaned_keyexpr_t keyexpr = z_keyexpr(NULL); assert(!z_check(keyexpr)); } diff --git a/tests/z_int_pub_cache_query_sub_test.c b/tests/z_int_pub_cache_query_sub_test.c index e0246ad01..742f2d656 100644 --- a/tests/z_int_pub_cache_query_sub_test.c +++ b/tests/z_int_pub_cache_query_sub_test.c @@ -85,9 +85,9 @@ int run_publisher() { return 0; } -void data_handler(const z_sample_t *sample, void *arg) { +void data_handler(const z_loaned_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); diff --git a/tests/z_int_pub_sub_attachment_test.c b/tests/z_int_pub_sub_attachment_test.c index 63bb54f4a..a2dba9b6b 100644 --- a/tests/z_int_pub_sub_attachment_test.c +++ b/tests/z_int_pub_sub_attachment_test.c @@ -65,9 +65,9 @@ int run_publisher() { return 0; } -void data_handler(const z_sample_t *sample, void *arg) { +void data_handler(const z_loaned_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); @@ -83,10 +83,10 @@ void data_handler(const z_sample_t *sample, void *arg) { } z_drop(z_move(payload_value)); - z_slice_t v_const = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_CONST)); + z_loaned_slice_t v_const = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); - z_slice_t v_var = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_VAR)); + z_loaned_slice_t v_var = z_attachment_get(z_sample_attachment(sample), z_slice_from_str(K_VAR)); ASSERT_STR_BYTES_EQUAL(values[val_num], v_var); if (++val_num == values_count) { diff --git a/tests/z_int_pub_sub_test.c b/tests/z_int_pub_sub_test.c index 6d681bb49..4907af56e 100644 --- a/tests/z_int_pub_sub_test.c +++ b/tests/z_int_pub_sub_test.c @@ -58,9 +58,9 @@ int run_publisher() { return 0; } -void data_handler(const z_sample_t *sample, void *arg) { +void data_handler(const z_loaned_sample_t *sample, void *arg) { static int val_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(sample)); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(sample)); if (strcmp(keyexpr, z_loan(keystr))) { perror("Unexpected key received"); exit(-1); diff --git a/tests/z_int_queryable_attachment_test.c b/tests/z_int_queryable_attachment_test.c index 9ea97fe8f..7582a9e92 100644 --- a/tests/z_int_queryable_attachment_test.c +++ b/tests/z_int_queryable_attachment_test.c @@ -29,19 +29,19 @@ const char *const K_VAR = "k_var"; const char *const K_CONST = "k_const"; const char *const V_CONST = "v const"; -void query_handler(const z_query_t *query, void *context) { +void query_handler(const z_loaned_query_t *query, void *context) { static int value_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_slice_t pred = z_query_parameters(query); - z_value_t payload_value = z_query_value(query); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_query_keyexpr(query)); + z_loaned_slice_t pred = z_query_parameters(query); + z_loaned_value_t payload_value = z_query_value(query); - z_bytes_t attachment = z_query_attachment(query); + z_loaned_bytes_t attachment = z_query_attachment(query); - z_slice_t v_const = z_attachment_get(attachment, z_slice_from_str(K_CONST)); + z_loaned_slice_t v_const = z_attachment_get(attachment, z_slice_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); - z_slice_t v_var = z_attachment_get(attachment, z_slice_from_str(K_VAR)); + z_loaned_slice_t v_var = z_attachment_get(attachment, z_slice_from_str(K_VAR)); ASSERT_STR_BYTES_EQUAL(values[value_num], v_var); z_owned_bytes_map_t map = z_slice_map_new(); @@ -108,8 +108,8 @@ int run_get() { for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { assert(z_reply_is_ok(&reply)); - z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_loaned_sample_t sample = z_reply_ok(&reply); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { @@ -118,7 +118,7 @@ int run_get() { exit(-1); } - z_slice_t v_const = z_attachment_get(z_sample_attachment(&sample), z_slice_from_str(K_CONST)); + z_loaned_slice_t v_const = z_attachment_get(z_sample_attachment(&sample), z_slice_from_str(K_CONST)); ASSERT_STR_BYTES_EQUAL(V_CONST, v_const); z_drop(z_move(keystr)); diff --git a/tests/z_int_queryable_test.c b/tests/z_int_queryable_test.c index b63686ecb..d22d5b6ab 100644 --- a/tests/z_int_queryable_test.c +++ b/tests/z_int_queryable_test.c @@ -25,12 +25,12 @@ const char *const keyexpr = "test/key"; const char *const values[] = {"test_value_1", "test_value_2", "test_value_3"}; const size_t values_count = sizeof(values) / sizeof(values[0]); -void query_handler(const z_query_t *query, void *context) { +void query_handler(const z_loaned_query_t *query, void *context) { static int value_num = 0; - z_owned_str_t keystr = z_keyexpr_to_string(z_query_keyexpr(query)); - z_slice_t pred = z_query_parameters(query); - z_value_t payload_value = z_query_value(query); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_query_keyexpr(query)); + z_loaned_slice_t pred = z_query_parameters(query); + z_loaned_value_t payload_value = z_query_value(query); z_query_reply_options_t options = z_query_reply_options_default(); options.encoding = z_encoding(Z_ENCODING_PREFIX_TEXT_PLAIN, NULL); @@ -84,8 +84,8 @@ int run_get() { for (z_call(channel.recv, &reply); z_check(reply); z_call(channel.recv, &reply)) { assert(z_reply_is_ok(&reply)); - z_sample_t sample = z_reply_ok(&reply); - z_owned_str_t keystr = z_keyexpr_to_string(z_sample_keyexpr(&sample)); + z_loaned_sample_t sample = z_reply_ok(&reply); + z_owned_str_t keystr = z_loaned_keyexpr_to_string(z_sample_keyexpr(&sample)); z_owned_str_t payload_value = z_str_null(); z_bytes_decode_into_string(z_sample_payload(&sample), &payload_value); if (strcmp(values[val_num], z_loan(payload_value))) { From 044757ad66773390247f90c045f500e54f850fc8 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 26 Apr 2024 16:50:08 +0200 Subject: [PATCH 70/75] automated macro-function generation --- build-resources/opaque-types/src/lib.rs | 4 +- build.rs | 456 +++++++++++++++++ include/zenoh_commons.h | 36 +- include/zenoh_macros.h | 646 +++++++++++++----------- src/commons.rs | 19 +- src/publisher.rs | 2 +- 6 files changed, 843 insertions(+), 320 deletions(-) diff --git a/build-resources/opaque-types/src/lib.rs b/build-resources/opaque-types/src/lib.rs index 512ea8b00..0d870a510 100644 --- a/build-resources/opaque-types/src/lib.rs +++ b/build-resources/opaque-types/src/lib.rs @@ -70,8 +70,8 @@ get_opaque_type_data!(HashMap, Cow<'static, [u8]>>, z_loaned_ /// An owned sample. /// /// This is a read only type that can only be constructed by cloning a `z_loaned_sample_t`. -/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. -get_opaque_type_data!(Option, zc_owned_sample_t); +/// Like all owned types, its memory must be freed by passing a mutable reference to it to `z_sample_drop`. +get_opaque_type_data!(Option, z_owned_sample_t); get_opaque_type_data!(Sample, z_loaned_sample_t); /// A reader for payload data. diff --git a/build.rs b/build.rs index 72fd1ab4c..4d06c44e3 100644 --- a/build.rs +++ b/build.rs @@ -37,6 +37,7 @@ fn main() { .expect("Unable to generate bindings") .write_to_file(GENERATION_PATH); + create_generics_header(GENERATION_PATH, "include/zenoh_macros.h"); configure(); let split_guide = SplitGuide::from_yaml(SPLITGUIDE_PATH); split_bindings(&split_guide).unwrap(); @@ -732,3 +733,458 @@ impl<'a> Iterator for Tokenizer<'a> { } } } + +#[derive(Clone, Debug)] +pub struct FuncArg { + typename: String, + cv: String, + name: String, +} + +impl FuncArg { + pub fn new(typename: &str, cv: &str, name: &str) -> Self { + FuncArg { + typename: typename.to_owned(), + cv: cv.to_owned(), + name: name.to_owned(), + } + } +} +#[derive(Clone, Debug)] +pub struct FunctionSignature { + return_type: String, + func_name: String, + arg_type_and_name: Vec, +} + +pub fn create_generics_header(path_in: &str, path_out: &str) { + let mut file_out = std::fs::File::options() + .read(false) + .create(false) + .write(true) + .truncate(true) + .open(path_out) + .unwrap(); + + let header = "#pragma once +// clang-format off +#ifndef __cplusplus + +"; + file_out.write(header.as_bytes()).unwrap(); + + let type_name_to_loan_func = find_loan_functions(path_in); + let out = generate_generic_loan_c(&type_name_to_loan_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let type_name_to_loan_mut_func = find_loan_mut_functions(path_in); + let out = generate_generic_loan_mut_c(&type_name_to_loan_mut_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let type_name_to_drop_func = find_drop_functions(path_in); + let out = generate_generic_drop_c(&type_name_to_drop_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let type_name_to_null_func = find_null_functions(path_in); + let out = generate_generic_null_c(&type_name_to_null_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let type_name_to_check_func = find_check_functions(path_in); + let out = generate_generic_check_c(&type_name_to_check_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let type_name_to_call_func = find_call_functions(path_in); + let out = generate_generic_call_c(&type_name_to_call_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_closure_c(&type_name_to_call_func); + file_out.write(out.as_bytes()).unwrap(); + + file_out + .write("\n#else // #ifndef __cplusplus\n".as_bytes()) + .unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_loan_cpp(&type_name_to_loan_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_loan_mut_cpp(&type_name_to_loan_mut_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_drop_cpp(&type_name_to_drop_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_null_cpp(&type_name_to_null_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_check_cpp(&type_name_to_check_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_call_cpp(&type_name_to_call_func); + file_out.write(out.as_bytes()).unwrap(); + file_out.write("\n\n".as_bytes()).unwrap(); + + let out = generate_generic_closure_cpp(&type_name_to_call_func); + file_out.write(out.as_bytes()).unwrap(); + + file_out + .write("\n#endif // #ifndef __cplusplus".as_bytes()) + .unwrap(); +} + +pub fn find_loan_functions(path_in: &str) -> HashMap { + let bindings = std::fs::read_to_string(path_in).unwrap(); + let re = Regex::new(r"const struct (\w+) \*(\w+)_loan\(const struct (\w+) \*(\w+)\);").unwrap(); + let mut res = HashMap::::new(); + + for (_, [return_type, func_name, arg_type, arg_name]) in + re.captures_iter(&bindings).map(|c| c.extract()) + { + let f = FunctionSignature { + return_type: return_type.to_string(), + func_name: func_name.to_string() + "_loan", + arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), + }; + res.insert(arg_type.to_string(), f); + } + res +} + +pub fn find_loan_mut_functions(path_in: &str) -> HashMap { + let bindings = std::fs::read_to_string(path_in).unwrap(); + let re = Regex::new(r"struct (\w+) \*(\w+)_loan_mut\(struct (\w+) \*(\w+)\);").unwrap(); + let mut res = HashMap::::new(); + + for (_, [return_type, func_name, arg_type, arg_name]) in + re.captures_iter(&bindings).map(|c| c.extract()) + { + let f = FunctionSignature { + return_type: return_type.to_string(), + func_name: func_name.to_string() + "_loan_mut", + arg_type_and_name: [FuncArg::new(arg_type, "", arg_name)].to_vec(), + }; + res.insert(arg_type.to_string(), f); + } + res +} + +pub fn find_drop_functions(path_in: &str) -> HashMap { + let bindings = std::fs::read_to_string(path_in).unwrap(); + let re = Regex::new(r"(\w+)_drop\(struct (\w+) \*(\w+)\);").unwrap(); + let mut res = HashMap::::new(); + + for (_, [func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { + let f = FunctionSignature { + return_type: "void".to_string(), + func_name: func_name.to_string() + "_drop", + arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), + }; + res.insert(arg_type.to_string(), f); + } + res +} + +pub fn find_null_functions(path_in: &str) -> HashMap { + let bindings = std::fs::read_to_string(path_in).unwrap(); + let re = Regex::new(r"(\w+)_null\(struct (\w+) \*(\w+)\);").unwrap(); + let mut res = HashMap::::new(); + + for (_, [func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { + let f = FunctionSignature { + return_type: "void".to_string(), + func_name: func_name.to_string() + "_null", + arg_type_and_name: [FuncArg::new(arg_type, "", arg_name)].to_vec(), + }; + res.insert(arg_type.to_string(), f); + } + res +} + +pub fn find_check_functions(path_in: &str) -> HashMap { + let bindings = std::fs::read_to_string(path_in).unwrap(); + let re = Regex::new(r"bool (\w+)_check\(const struct (\w+) \*(\w+)\);").unwrap(); + let mut res = HashMap::::new(); + + for (_, [func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { + let f = FunctionSignature { + return_type: "bool".to_string(), + func_name: func_name.to_string() + "_check", + arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), + }; + res.insert(arg_type.to_string(), f); + } + res +} + +pub fn find_call_functions(path_in: &str) -> HashMap { + let bindings = std::fs::read_to_string(path_in).unwrap(); + let re = Regex::new( + r"(\w+) (\w+)_call\(const struct (\w+) \*(\w+),\s+(\w*)\s*struct (\w+) \*(\w+)\);", + ) + .unwrap(); + let mut res = HashMap::::new(); + + for (_, [return_type, func_name, closure_type, closure_name, arg_cv, arg_type, arg_name]) in + re.captures_iter(&bindings).map(|c| c.extract()) + { + let f = FunctionSignature { + return_type: return_type.to_string(), + func_name: func_name.to_string() + "_call", + arg_type_and_name: [ + FuncArg::new(closure_type, "const", closure_name), + FuncArg::new(arg_type, arg_cv, arg_name), + ] + .to_vec(), + }; + res.insert(closure_type.to_string(), f); + } + res +} + +pub fn generate_generic_loan_c(owned_type_to_fun: &HashMap) -> String { + let mut out = "#define z_loan(x) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, func) in owned_type_to_fun { + let func_name = &func.func_name; + out += ", \\\n"; + out += &format!(" {owned_type} : {func_name}"); + } + out += " \\\n"; + out += " )(&x)"; + out +} + +pub fn generate_generic_loan_mut_c( + owned_type_to_fun: &HashMap, +) -> String { + let mut out = "#define z_loan_mut(x) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, func) in owned_type_to_fun { + let func_name = &func.func_name; + out += ", \\\n"; + out += &format!(" {owned_type} : {func_name}"); + } + out += " \\\n"; + out += " )(&x)"; + out +} + +pub fn generate_generic_drop_c(owned_type_to_fun: &HashMap) -> String { + let mut out = "#define z_drop(x) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, func) in owned_type_to_fun { + let func_name = &func.func_name; + out += ",\\\n"; + out += &format!(" {owned_type} * : {func_name}"); + } + out += " \\\n"; + out += " )(x)"; + out +} + +pub fn generate_generic_null_c(owned_type_to_fun: &HashMap) -> String { + let mut out = "#define z_null(x) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, func) in owned_type_to_fun { + let func_name = &func.func_name; + out += ", \\\n"; + out += &format!(" {owned_type} * : {func_name}"); + } + out += " \\\n"; + out += " )(x)"; + out +} + +pub fn generate_generic_check_c(owned_type_to_fun: &HashMap) -> String { + let mut out = "#define z_check(x) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, func) in owned_type_to_fun { + let func_name = &func.func_name; + out += ", \\\n"; + out += &format!(" {owned_type} : {func_name}"); + } + out += " \\\n"; + out += " )(&x)"; + out +} + +pub fn generate_generic_call_c(owned_type_to_fun: &HashMap) -> String { + let mut out = "#define z_call(x, ...) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, func) in owned_type_to_fun { + let func_name = &func.func_name; + out += ", \\\n"; + out += &format!(" {owned_type} : {func_name}"); + } + out += " \\\n"; + out += " )(&x, __VA_ARGS__)"; + + out +} + +pub fn generate_generic_closure_c( + owned_type_to_fun: &HashMap, +) -> String { + let mut out = "#define z_closure(x, callback, dropper, ctx) \\ + _Generic((x)" + .to_owned(); + + for (owned_type, _func) in owned_type_to_fun { + out += ", \\\n"; + out += &format!( +" {owned_type} * : {{ x->context = (void*)ctx; x->call = callback; x->drop = droper; }}"); + } + out += " \\\n"; + out += " )"; + + out +} + +pub fn generate_generic_loan_cpp(owned_type_to_fun: &HashMap) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let func_name = &func.func_name; + let return_type = &func.return_type; + let cv = &func.arg_type_and_name[0].cv; + let arg_name = &func.arg_type_and_name[0].name; + let arg_type = &func.arg_type_and_name[0].typename; + out += "\n"; + out += &format!("inline const {return_type}* z_loan({cv} {arg_type}* {arg_name}) {{ return {func_name}({arg_name}); }};"); + } + out +} + +pub fn generate_generic_loan_mut_cpp( + owned_type_to_fun: &HashMap, +) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let func_name = &func.func_name; + let return_type = &func.return_type; + let cv = &func.arg_type_and_name[0].cv; + let arg_name = &func.arg_type_and_name[0].name; + let arg_type = &func.arg_type_and_name[0].typename; + out += "\n"; + out += &format!("inline {return_type}* z_loan_mut({cv} {arg_type}& {arg_name}) {{ return {func_name}(&{arg_name}); }};"); + } + out +} + +pub fn generate_generic_drop_cpp(owned_type_to_fun: &HashMap) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let func_name = &func.func_name; + let return_type = &func.return_type; + let cv = &func.arg_type_and_name[0].cv; + let arg_name = &func.arg_type_and_name[0].name; + let arg_type = &func.arg_type_and_name[0].typename; + out += "\n"; + out += &format!("inline {return_type} z_drop({cv} {arg_type}* {arg_name}) {{ return {func_name}({arg_name}); }};"); + } + out +} + +pub fn generate_generic_null_cpp(owned_type_to_fun: &HashMap) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let func_name = &func.func_name; + let return_type = &func.return_type; + let cv = &func.arg_type_and_name[0].cv; + let arg_name = &func.arg_type_and_name[0].name; + let arg_type = &func.arg_type_and_name[0].typename; + out += "\n"; + out += &format!("inline {return_type} z_null({cv} {arg_type}* {arg_name}) {{ return {func_name}({arg_name}); }};"); + } + out +} + +pub fn generate_generic_check_cpp( + owned_type_to_fun: &HashMap, +) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let func_name = &func.func_name; + let return_type = &func.return_type; + let cv = &func.arg_type_and_name[0].cv; + let arg_name = &func.arg_type_and_name[0].name; + let arg_type = &func.arg_type_and_name[0].typename; + out += "\n"; + out += &format!("inline {return_type} z_check({cv} {arg_type}& {arg_name}) {{ return {func_name}(&{arg_name}); }};"); + } + out +} + +pub fn generate_generic_call_cpp(owned_type_to_fun: &HashMap) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let func_name = &func.func_name; + let return_type = &func.return_type; + let closure_cv = &func.arg_type_and_name[0].cv; + let closure_name = &func.arg_type_and_name[0].name; + let closure_type = &func.arg_type_and_name[0].typename; + let arg_cv = &func.arg_type_and_name[1].cv; + let arg_name = &func.arg_type_and_name[1].name; + let arg_type = &func.arg_type_and_name[1].typename; + out += "\n"; + out += &format!("inline {return_type} z_call({closure_cv} {closure_type}& {closure_name}, {arg_cv} {arg_type}* {arg_name}) {{ + return {func_name}(&{closure_name}, {arg_name}); +}};"); + } + out +} + +pub fn generate_generic_closure_cpp( + owned_type_to_fun: &HashMap, +) -> String { + let mut out = "".to_owned(); + + for (_, func) in owned_type_to_fun { + let return_type = &func.return_type; + let closure_name = &func.arg_type_and_name[0].name; + let closure_type = &func.arg_type_and_name[0].typename; + let arg_cv = &func.arg_type_and_name[1].cv; + let arg_type = &func.arg_type_and_name[1].typename; + out += "\n"; + out += &format!( + "inline void z_closure( + {closure_type}* {closure_name}, + {return_type} (*call)({arg_cv} {arg_type}*, void*), + void (*drop)(void*), + void *context) {{ + {closure_name}->context = context; + {closure_name}->drop = drop; + {closure_name}->call = call; +}};" + ); + } + out +} diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 35429b0d6..463f37575 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -675,11 +675,11 @@ typedef struct z_owned_reply_channel_t { * An owned sample. * * This is a read only type that can only be constructed by cloning a `z_loaned_sample_t`. - * Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. + * Like all owned types, its memory must be freed by passing a mutable reference to it to `z_sample_drop`. */ -typedef struct ALIGN(8) zc_owned_sample_t { +typedef struct ALIGN(8) z_owned_sample_t { uint8_t _0[240]; -} zc_owned_sample_t; +} z_owned_sample_t; typedef struct z_owned_scouting_config_t { struct z_owned_config_t _config; unsigned long zc_timeout_ms; @@ -1558,7 +1558,7 @@ ZENOHC_API void z_publisher_options_default(struct z_publisher_options_t *this_) * Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. * * This is avoids copies when transfering data that was either: - * - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher + * - `z_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher * - constructed from a `zc_owned_shmbuf_t` * * The payload and all owned options fields are consumed upon function return. @@ -1823,17 +1823,21 @@ const struct z_loaned_bytes_t *z_sample_attachment(const struct z_loaned_sample_ /** * Returns `true` if `sample` is valid. * - * Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed + * Note that there exist no fallinle constructors for `z_owned_sample_t`, so validity is always guaranteed * unless the value has been dropped already. */ ZENOHC_API -bool z_sample_check(const struct zc_owned_sample_t *sample); +bool z_sample_check(const struct z_owned_sample_t *sample); /** * Clone a sample in the cheapest way available. */ -ZENOHC_API void z_sample_clone(const struct z_loaned_sample_t *src, struct zc_owned_sample_t *dst); +ZENOHC_API void z_sample_clone(const struct z_loaned_sample_t *src, struct z_owned_sample_t *dst); ZENOHC_API enum z_congestion_control_t z_sample_congestion_control(const struct z_loaned_sample_t *sample); +/** + * Destroy the sample. + */ +ZENOHC_API void z_sample_drop(struct z_owned_sample_t *sample); /** * The encoding of the payload. */ @@ -1851,6 +1855,13 @@ const struct z_loaned_keyexpr_t *z_sample_keyexpr(const struct z_loaned_sample_t * The sample's kind (put or delete). */ ZENOHC_API enum z_sample_kind_t z_sample_kind(const struct z_loaned_sample_t *sample); +/** + * Borrow the sample, allowing calling its accessor methods. + * + * Calling this function using a dropped sample is undefined behaviour. + */ +ZENOHC_API const struct z_loaned_sample_t *z_sample_loan(const struct z_owned_sample_t *sample); +ZENOHC_API void z_sample_null(struct z_owned_sample_t *sample); /** * The sample's data, the return value aliases the sample. * @@ -2363,17 +2374,6 @@ struct z_owned_reply_channel_t zc_reply_fifo_new(size_t bound); */ ZENOHC_API struct z_owned_reply_channel_t zc_reply_non_blocking_fifo_new(size_t bound); -/** - * Destroy the sample. - */ -ZENOHC_API void zc_sample_drop(struct zc_owned_sample_t *sample); -/** - * Borrow the sample, allowing calling its accessor methods. - * - * Calling this function using a dropped sample is undefined behaviour. - */ -ZENOHC_API const struct z_loaned_sample_t *zc_sample_loan(const struct zc_owned_sample_t *sample); -ZENOHC_API void zc_sample_null(struct zc_owned_sample_t *sample); /** * Increments the session's reference count, returning a new owning handle. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 7b6bbe214..c4229023b 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -1,312 +1,382 @@ #pragma once - +// clang-format off #ifndef __cplusplus -// clang-format off #define z_loan(x) \ - _Generic((x), z_owned_session_t : z_session_loan, \ - z_owned_keyexpr_t : z_keyexpr_loan, \ - z_owned_config_t : z_config_loan, \ - z_owned_publisher_t : z_publisher_loan, \ - z_owned_subscriber_t : z_subscriber_loan, \ - z_owned_encoding_t : z_encoding_loan, \ - z_owned_hello_t : z_hello_loan, \ - z_owned_str_t : z_str_loan, \ - z_owned_query_t : z_query_loan, \ - z_owned_slice_map_t : z_slice_map_loan, \ - z_owned_slice_t : z_slice_loan, \ - z_owned_bytes_t : z_bytes_loan, \ - ze_owned_querying_subscriber_t : ze_querying_subscriber_loan,\ - z_owned_reply_t : z_reply_loan, \ - z_owned_mutex_t : z_mutex_loan, \ - z_loaned_condvar_t : z_condvar_loan, \ - z_owned_bytes_reader_t : z_bytes_reader_loan \ - )(&x) + _Generic((x), \ + ze_owned_querying_subscriber_t : ze_querying_subscriber_loan, \ + z_owned_sample_t : z_sample_loan, \ + z_view_slice_t : z_view_slice_loan, \ + z_owned_bytes_t : z_bytes_loan, \ + z_owned_publisher_t : z_publisher_loan, \ + z_owned_slice_t : z_slice_loan, \ + z_owned_slice_map_t : z_slice_map_loan, \ + z_owned_keyexpr_t : z_keyexpr_loan, \ + z_owned_encoding_t : z_encoding_loan, \ + z_owned_str_t : z_str_loan, \ + z_owned_session_t : z_session_loan, \ + z_owned_hello_t : z_hello_loan, \ + z_view_str_t : z_view_str_loan, \ + z_owned_query_t : z_query_loan, \ + z_owned_subscriber_t : z_subscriber_loan, \ + z_view_keyexpr_t : z_view_keyexpr_loan, \ + z_owned_str_array_t : z_str_array_loan, \ + z_owned_condvar_t : z_condvar_loan, \ + z_owned_config_t : z_config_loan, \ + z_owned_bytes_reader_t : z_bytes_reader_loan \ + )(&x) + +#define z_loan_mut(x) \ + _Generic((x), \ + z_owned_condvar_t : z_condvar_loan_mut, \ + z_owned_bytes_reader_t : z_bytes_reader_loan_mut, \ + z_owned_config_t : z_config_loan_mut, \ + z_owned_slice_map_t : z_slice_map_loan_mut, \ + z_owned_mutex_t : z_mutex_loan_mut \ + )(&x) #define z_drop(x) \ - _Generic((x), z_owned_session_t * : z_close, \ - z_owned_publisher_t * : z_undeclare_publisher, \ - z_owned_keyexpr_t * : z_keyexpr_drop, \ - z_owned_config_t * : z_config_drop, \ - z_owned_scouting_config_t * : z_scouting_config_drop, \ - z_owned_subscriber_t * : z_undeclare_subscriber, \ - z_owned_queryable_t * : z_undeclare_queryable, \ - z_owned_encoding_t * : z_encoding_drop, \ - z_owned_reply_t * : z_reply_drop, \ - z_owned_hello_t * : z_hello_drop, \ - z_owned_str_t * : z_str_drop, \ - z_owned_query_t * : z_query_drop, \ - z_owned_closure_sample_t * : z_closure_sample_drop, \ - z_owned_closure_query_t * : z_closure_query_drop, \ - z_owned_closure_reply_t * : z_closure_reply_drop, \ - z_owned_closure_hello_t * : z_closure_hello_drop, \ - z_owned_closure_zid_t * : z_closure_zid_drop, \ - zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_drop, \ - z_owned_reply_channel_closure_t * : z_reply_channel_closure_drop, \ - z_owned_query_channel_closure_t * : z_query_channel_closure_drop, \ - z_owned_reply_channel_t * : z_reply_channel_drop, \ - z_owned_query_channel_t * : z_query_channel_drop, \ - z_owned_slice_map_t * : z_slice_map_drop, \ - z_owned_slice_t * : z_slice_drop, \ - zc_owned_liveliness_token_t * : zc_liveliness_undeclare_token, \ - ze_owned_publication_cache_t * : ze_undeclare_publication_cache, \ - ze_owned_querying_subscriber_t * : ze_undeclare_querying_subscriber, \ - z_owned_bytes_t * : z_bytes_drop, \ - z_owned_bytes_reader_t * : z_bytes_reader_drop, \ - z_owned_mutex_t * : z_mutex_drop, \ - z_owned_condvar_t * : z_condvar_drop \ - )(x) + _Generic((x),\ + z_owned_closure_query_t * : z_closure_query_drop,\ + z_owned_closure_zid_t * : z_closure_zid_drop,\ + z_owned_slice_map_t * : z_slice_map_drop,\ + zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_drop,\ + z_owned_reply_t * : z_reply_drop,\ + z_owned_slice_t * : z_slice_drop,\ + z_owned_closure_sample_t * : z_closure_sample_drop,\ + z_owned_bytes_t * : z_bytes_drop,\ + z_owned_condvar_t * : z_condvar_drop,\ + z_owned_sample_t * : z_sample_drop,\ + z_owned_query_channel_t * : z_query_channel_drop,\ + z_owned_query_channel_closure_t * : z_query_channel_closure_drop,\ + z_owned_closure_reply_t * : z_closure_reply_drop,\ + z_owned_reply_channel_t * : z_reply_channel_drop,\ + z_owned_str_t * : z_str_drop,\ + z_owned_closure_owned_query_t * : z_closure_owned_query_drop,\ + z_owned_config_t * : z_config_drop,\ + z_owned_mutex_t * : z_mutex_drop,\ + z_owned_bytes_reader_t * : z_bytes_reader_drop,\ + z_owned_str_array_t * : z_str_array_drop,\ + z_owned_keyexpr_t * : z_keyexpr_drop,\ + z_owned_scouting_config_t * : z_scouting_config_drop,\ + z_owned_closure_hello_t * : z_closure_hello_drop,\ + z_owned_encoding_t * : z_encoding_drop,\ + z_owned_hello_t * : z_hello_drop,\ + z_owned_query_t * : z_query_drop,\ + z_owned_reply_channel_closure_t * : z_reply_channel_closure_drop \ + )(x) -#define z_null(x) (*x = \ - _Generic((x), z_owned_session_t * : z_session_null, \ - z_owned_publisher_t * : z_publisher_null, \ - z_owned_keyexpr_t * : z_keyexpr_null, \ - z_owned_config_t * : z_config_null, \ - z_owned_scouting_config_t * : z_scouting_config_null, \ - z_owned_subscriber_t * : z_subscriber_null, \ - z_owned_queryable_t * : z_queryable_null, \ - z_owned_encoding_t * : z_encoding_null, \ - z_owned_reply_t * : z_reply_null, \ - z_owned_hello_t * : z_hello_null, \ - z_owned_str_t * : z_str_null, \ - z_owned_query_t * : z_query_null, \ - z_owned_closure_sample_t * : z_closure_sample_null, \ - z_owned_closure_query_t * : z_closure_query_null, \ - z_owned_closure_reply_t * : z_closure_reply_null, \ - z_owned_closure_hello_t * : z_closure_hello_null, \ - z_owned_closure_zid_t * : z_closure_zid_null, \ - zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_null, \ - z_owned_reply_channel_closure_t * : z_reply_channel_closure_null, \ - z_owned_reply_channel_t * : z_reply_channel_null, \ - z_owned_slice_map_t * : z_slice_map_null, \ - z_owned_bytes_t * : z_bytes_null, \ - z_owned_slice_t * : z_slice_null, \ - ze_owned_publication_cache_t * : ze_publication_cache_null, \ - zc_owned_liveliness_token_t * : zc_liveliness_token_null, \ - z_owned_bytes_reader_t * : z_bytes_reader_null, \ - z_owned_mutex_t * : z_mutex_null, \ - z_owned_condvar_t * : z_condvar_null, \ - z_owned_task_t * : z_task_null \ - )()) +#define z_null(x) \ + _Generic((x), \ + z_owned_slice_map_t * : z_slice_map_null, \ + z_owned_query_t * : z_query_null, \ + z_owned_keyexpr_t * : z_keyexpr_null, \ + z_view_str_t * : z_view_str_null, \ + z_view_slice_t * : z_view_slice_null, \ + z_owned_str_t * : z_str_null, \ + z_owned_scouting_config_t * : z_scouting_config_null, \ + z_owned_condvar_t * : z_condvar_null, \ + z_owned_encoding_t * : z_encoding_null, \ + z_owned_queryable_t * : z_queryable_null, \ + z_owned_reply_t * : z_reply_null, \ + z_owned_mutex_t * : z_mutex_null, \ + z_owned_config_t * : z_config_null, \ + z_owned_bytes_reader_t * : z_bytes_reader_null, \ + z_owned_hello_t * : z_hello_null, \ + z_owned_sample_t * : z_sample_null, \ + z_owned_subscriber_t * : z_subscriber_null, \ + z_owned_bytes_t * : z_bytes_null, \ + z_owned_publisher_t * : z_publisher_null, \ + z_owned_session_t * : z_session_null, \ + z_owned_task_t * : z_task_null, \ + z_owned_slice_t * : z_slice_null, \ + z_view_keyexpr_t * : z_view_keyexpr_null, \ + zc_owned_liveliness_token_t * : zc_liveliness_token_null, \ + ze_owned_querying_subscriber_t * : ze_querying_subscriber_null, \ + ze_owned_publication_cache_t * : ze_publication_cache_null \ + )(x) #define z_check(x) \ - _Generic((x), z_owned_session_t : z_session_check, \ - z_owned_publisher_t : z_publisher_check, \ - z_owned_keyexpr_t : z_keyexpr_check, \ - z_owned_config_t : z_config_check, \ - z_owned_scouting_config_t : z_scouting_config_check, \ - z_owned_subscriber_t : z_subscriber_check, \ - z_owned_queryable_t : z_queryable_check, \ - z_owned_encoding_t : z_encoding_check, \ - z_owned_reply_t : z_reply_check, \ - z_owned_hello_t : z_hello_check, \ - z_owned_query_t : z_query_check, \ - z_owned_str_t : z_str_check, \ - z_owned_slice_map_t : z_slice_map_check, \ - z_owned_slice_t: z_slice_check, \ - z_owned_bytes_t : z_bytes_check, \ - zc_owned_liveliness_token_t : zc_liveliness_token_check, \ - ze_owned_publication_cache_t : ze_publication_cache_check, \ - ze_owned_querying_subscriber_t : ze_querying_subscriber_check,\ - z_owned_mutex_t : z_mutex_check, \ - z_owned_condvar_t : z_condvar_check, \ - z_owned_task_t : z_task_check \ - )(&x) + _Generic((x), \ + z_view_keyexpr_t : z_view_keyexpr_check, \ + z_owned_bytes_t : z_bytes_check, \ + z_owned_query_t : z_query_check, \ + z_owned_scouting_config_t : z_scouting_config_check, \ + ze_owned_querying_subscriber_t : ze_querying_subscriber_check, \ + z_owned_sample_t : z_sample_check, \ + z_owned_keyexpr_t : z_keyexpr_check, \ + z_owned_str_array_t : z_str_array_check, \ + z_owned_hello_t : z_hello_check, \ + z_owned_task_t : z_task_check, \ + z_owned_reply_t : z_reply_check, \ + z_view_slice_t : z_view_slice_check, \ + ze_owned_publication_cache_t : ze_publication_cache_check, \ + zc_owned_liveliness_token_t : zc_liveliness_token_check, \ + z_owned_queryable_t : z_queryable_check, \ + z_owned_condvar_t : z_condvar_check, \ + z_owned_str_t : z_str_check, \ + z_owned_config_t : z_config_check, \ + z_owned_bytes_reader_t : z_bytes_reader_check, \ + z_owned_mutex_t : z_mutex_check, \ + z_owned_publisher_t : z_publisher_check, \ + z_owned_slice_t : z_owned_slice_check, \ + z_owned_session_t : z_session_check, \ + z_owned_encoding_t : z_encoding_check, \ + z_owned_slice_map_t : z_slice_map_check, \ + z_owned_subscriber_t : z_subscriber_check \ + )(&x) #define z_call(x, ...) \ - _Generic((x), z_owned_closure_sample_t : z_closure_sample_call, \ - z_owned_closure_query_t : z_closure_query_call, \ - z_owned_closure_owned_query_t : z_closure_owned_query_call, \ - z_owned_closure_reply_t : z_closure_reply_call, \ - z_owned_closure_hello_t : z_closure_hello_call, \ - z_owned_closure_zid_t : z_closure_zid_call, \ - zcu_owned_closure_matching_status_t : zcu_closure_matching_status_call, \ - z_owned_reply_channel_closure_t : z_reply_channel_closure_call, \ - z_owned_query_channel_closure_t : z_query_channel_closure_call \ - ) (&x, __VA_ARGS__) -// clang-format on - -#define _z_closure_overloader(callback, droper, ctx, ...) \ - { .context = (void*)ctx, .call = callback, .drop = droper } -#define z_closure(...) _z_closure_overloader(__VA_ARGS__, NULL, NULL) -#define z_move(x) (&x) + _Generic((x), \ + z_owned_closure_query_t : z_closure_query_call, \ + z_owned_closure_hello_t : z_closure_hello_call, \ + z_owned_closure_reply_t : z_closure_reply_call, \ + z_owned_closure_sample_t : z_closure_sample_call, \ + z_owned_closure_owned_query_t : z_closure_owned_query_call, \ + z_owned_closure_zid_t : z_closure_zid_call, \ + zcu_owned_closure_matching_status_t : zcu_closure_matching_status_call, \ + z_owned_query_channel_closure_t : z_query_channel_closure_call, \ + z_owned_reply_channel_closure_t : z_reply_channel_closure_call \ + )(&x, __VA_ARGS__) +#define z_closure(x, callback, dropper, ctx) \ + _Generic((x), \ + z_owned_closure_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_hello_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_reply_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_sample_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_owned_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_zid_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + zcu_owned_closure_matching_status_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_query_channel_closure_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_reply_channel_closure_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; } \ + ) #else // #ifndef __cplusplus -// clang-format off -template struct zenoh_loan_type { typedef T type; }; -template inline typename zenoh_loan_type::type z_loan(const T&); -template<> struct zenoh_loan_type{ typedef z_loaned_session_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_keyexpr_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_config_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_publisher_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_subscriber_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_query_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_encoding_t type; }; -template<> struct zenoh_loan_type{ typedef z_hello_t type; }; -template<> struct zenoh_loan_type{ typedef const char* type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_bytes_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_bytes_reader_t type; }; -template<> struct zenoh_loan_type{ typedef ze_loaned_querying_subscriber_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_slice_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_slice_map_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_mutex_t type; }; -template<> struct zenoh_loan_type{ typedef z_loaned_condvar_t type; }; -template<> inline z_loaned_session_t z_loan(const z_owned_session_t& x) { return z_session_loan(&x); } -template<> inline z_loaned_keyexpr_t z_loan(const z_owned_keyexpr_t& x) { return z_keyexpr_loan(&x); } -template<> inline z_loaned_config_t z_loan(const z_owned_config_t& x) { return z_config_loan(&x); } -template<> inline z_loaned_publisher_t z_loan(const z_owned_publisher_t& x) { return z_publisher_loan(&x); } -template<> inline z_loaned_subscriber_t z_loan(const z_owned_subscriber_t& x) { return z_subscriber_loan(&x); } -template<> inline z_loaned_encoding_t z_loan(const z_owned_encoding_t& x) { return z_encoding_loan(&x); } -template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } -template<> inline z_loaned_query_t z_loan(const z_owned_query_t& x) { return z_query_loan(&x); } -template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } -template<> inline z_loaned_bytes_t z_loan(const z_owned_bytes_t& x) { return z_bytes_loan(&x); } -template<> inline z_loaned_bytes_reader_t z_loan(const z_owned_bytes_reader_t& x) { return z_bytes_reader_loan(&x); } -template<> inline ze_loaned_querying_subscriber_t z_loan(const ze_owned_querying_subscriber_t& x) { return ze_querying_subscriber_loan(&x); } -template<> inline z_loaned_slice_t z_loan(const z_owned_slice_t& x) { return z_slice_loan(&x); } -template<> inline z_loaned_slice_map_t z_loan(const z_owned_slice_map_t& x) { return z_slice_map_loan(&x); } -template<> inline z_loaned_mutex_t z_loan(const z_owned_mutex_t& x) { return z_mutex_loan(&x); } -template<> inline z_loaned_condvar_t z_loan(const z_owned_condvar_t& x) { return z_condvar_loan(&x); } +inline const ze_loaned_querying_subscriber_t* z_loan(const ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_loan(this_); }; +inline const z_loaned_sample_t* z_loan(const z_owned_sample_t* sample) { return z_sample_loan(sample); }; +inline const z_loaned_slice_t* z_loan(const z_view_slice_t* this_) { return z_view_slice_loan(this_); }; +inline const z_loaned_bytes_t* z_loan(const z_owned_bytes_t* payload) { return z_bytes_loan(payload); }; +inline const z_loaned_publisher_t* z_loan(const z_owned_publisher_t* this_) { return z_publisher_loan(this_); }; +inline const z_loaned_slice_t* z_loan(const z_owned_slice_t* this_) { return z_slice_loan(this_); }; +inline const z_loaned_slice_map_t* z_loan(const z_owned_slice_map_t* this_) { return z_slice_map_loan(this_); }; +inline const z_loaned_keyexpr_t* z_loan(const z_owned_keyexpr_t* key_expr) { return z_keyexpr_loan(key_expr); }; +inline const z_loaned_encoding_t* z_loan(const z_owned_encoding_t* encoding) { return z_encoding_loan(encoding); }; +inline const z_loaned_str_t* z_loan(const z_owned_str_t* this_) { return z_str_loan(this_); }; +inline const z_loaned_session_t* z_loan(const z_owned_session_t* this_) { return z_session_loan(this_); }; +inline const z_hello_t* z_loan(const z_owned_hello_t* hello) { return z_hello_loan(hello); }; +inline const z_loaned_str_t* z_loan(const z_view_str_t* this_) { return z_view_str_loan(this_); }; +inline const z_loaned_query_t* z_loan(const z_owned_query_t* this_) { return z_query_loan(this_); }; +inline const z_loaned_subscriber_t* z_loan(const z_owned_subscriber_t* this_) { return z_subscriber_loan(this_); }; +inline const z_loaned_keyexpr_t* z_loan(const z_view_keyexpr_t* key_expr) { return z_view_keyexpr_loan(key_expr); }; +inline const z_str_array_t* z_loan(const z_owned_str_array_t* strs) { return z_str_array_loan(strs); }; +inline const z_loaned_condvar_t* z_loan(const z_owned_condvar_t* this_) { return z_condvar_loan(this_); }; +inline const z_loaned_config_t* z_loan(const z_owned_config_t* this_) { return z_config_loan(this_); }; +inline const z_loaned_bytes_reader_t* z_loan(const z_owned_bytes_reader_t* reader) { return z_bytes_reader_loan(reader); }; + + +inline z_loaned_condvar_t* z_loan_mut( z_owned_condvar_t& this_) { return z_condvar_loan_mut(&this_); }; +inline z_loaned_bytes_reader_t* z_loan_mut( z_owned_bytes_reader_t& reader) { return z_bytes_reader_loan_mut(&reader); }; +inline z_loaned_config_t* z_loan_mut( z_owned_config_t& this_) { return z_config_loan_mut(&this_); }; +inline z_loaned_slice_map_t* z_loan_mut( z_owned_slice_map_t& this_) { return z_slice_map_loan_mut(&this_); }; +inline z_loaned_mutex_t* z_loan_mut( z_owned_mutex_t& this_) { return z_mutex_loan_mut(&this_); }; + + +inline void z_drop(const z_owned_closure_query_t* closure) { return z_closure_query_drop(closure); }; +inline void z_drop(const z_owned_closure_zid_t* closure) { return z_closure_zid_drop(closure); }; +inline void z_drop(const z_owned_slice_map_t* this_) { return z_slice_map_drop(this_); }; +inline void z_drop(const zcu_owned_closure_matching_status_t* closure) { return zcu_closure_matching_status_drop(closure); }; +inline void z_drop(const z_owned_reply_t* this_) { return z_reply_drop(this_); }; +inline void z_drop(const z_owned_slice_t* this_) { return z_slice_drop(this_); }; +inline void z_drop(const z_owned_closure_sample_t* closure) { return z_closure_sample_drop(closure); }; +inline void z_drop(const z_owned_bytes_t* this_) { return z_bytes_drop(this_); }; +inline void z_drop(const z_owned_condvar_t* this_) { return z_condvar_drop(this_); }; +inline void z_drop(const z_owned_sample_t* sample) { return z_sample_drop(sample); }; +inline void z_drop(const z_owned_query_channel_t* channel) { return z_query_channel_drop(channel); }; +inline void z_drop(const z_owned_query_channel_closure_t* closure) { return z_query_channel_closure_drop(closure); }; +inline void z_drop(const z_owned_closure_reply_t* closure) { return z_closure_reply_drop(closure); }; +inline void z_drop(const z_owned_reply_channel_t* channel) { return z_reply_channel_drop(channel); }; +inline void z_drop(const z_owned_str_t* this_) { return z_str_drop(this_); }; +inline void z_drop(const z_owned_closure_owned_query_t* closure) { return z_closure_owned_query_drop(closure); }; +inline void z_drop(const z_owned_config_t* config) { return z_config_drop(config); }; +inline void z_drop(const z_owned_mutex_t* this_) { return z_mutex_drop(this_); }; +inline void z_drop(const z_owned_bytes_reader_t* this_) { return z_bytes_reader_drop(this_); }; +inline void z_drop(const z_owned_str_array_t* strs) { return z_str_array_drop(strs); }; +inline void z_drop(const z_owned_keyexpr_t* keyexpr) { return z_keyexpr_drop(keyexpr); }; +inline void z_drop(const z_owned_scouting_config_t* config) { return z_scouting_config_drop(config); }; +inline void z_drop(const z_owned_closure_hello_t* closure) { return z_closure_hello_drop(closure); }; +inline void z_drop(const z_owned_encoding_t* encoding) { return z_encoding_drop(encoding); }; +inline void z_drop(const z_owned_hello_t* hello) { return z_hello_drop(hello); }; +inline void z_drop(const z_owned_query_t* this_) { return z_query_drop(this_); }; +inline void z_drop(const z_owned_reply_channel_closure_t* closure) { return z_reply_channel_closure_drop(closure); }; -template struct zenoh_drop_type { typedef T type; }; -template inline typename zenoh_drop_type::type z_drop(T*); -template<> struct zenoh_drop_type { typedef int8_t type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; -template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef void type; }; +inline void z_null( z_owned_slice_map_t* this_) { return z_slice_map_null(this_); }; +inline void z_null( z_owned_query_t* this_) { return z_query_null(this_); }; +inline void z_null( z_owned_keyexpr_t* this_) { return z_keyexpr_null(this_); }; +inline void z_null( z_view_str_t* this_) { return z_view_str_null(this_); }; +inline void z_null( z_view_slice_t* this_) { return z_view_slice_null(this_); }; +inline void z_null( z_owned_str_t* this_) { return z_str_null(this_); }; +inline void z_null( z_owned_scouting_config_t* this_) { return z_scouting_config_null(this_); }; +inline void z_null( z_owned_condvar_t* this_) { return z_condvar_null(this_); }; +inline void z_null( z_owned_encoding_t* encoding) { return z_encoding_null(encoding); }; +inline void z_null( z_owned_queryable_t* this_) { return z_queryable_null(this_); }; +inline void z_null( z_owned_reply_t* this_) { return z_reply_null(this_); }; +inline void z_null( z_owned_mutex_t* this_) { return z_mutex_null(this_); }; +inline void z_null( z_owned_config_t* this_) { return z_config_null(this_); }; +inline void z_null( z_owned_bytes_reader_t* this_) { return z_bytes_reader_null(this_); }; +inline void z_null( z_owned_hello_t* this_) { return z_hello_null(this_); }; +inline void z_null( z_owned_sample_t* sample) { return z_sample_null(sample); }; +inline void z_null( z_owned_subscriber_t* this_) { return z_subscriber_null(this_); }; +inline void z_null( z_owned_bytes_t* this_) { return z_bytes_null(this_); }; +inline void z_null( z_owned_publisher_t* this_) { return z_publisher_null(this_); }; +inline void z_null( z_owned_session_t* this_) { return z_session_null(this_); }; +inline void z_null( z_owned_task_t* this_) { return z_task_null(this_); }; +inline void z_null( z_owned_slice_t* this_) { return z_slice_null(this_); }; +inline void z_null( z_view_keyexpr_t* this_) { return z_view_keyexpr_null(this_); }; +inline void z_null( zc_owned_liveliness_token_t* this_) { return zc_liveliness_token_null(this_); }; +inline void z_null( ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_null(this_); }; +inline void z_null( ze_owned_publication_cache_t* this_) { return ze_publication_cache_null(this_); }; -template<> inline int8_t z_drop(z_owned_session_t* v) { return z_close(v); } -template<> inline int8_t z_drop(z_owned_publisher_t* v) { return z_undeclare_publisher(v); } -template<> inline void z_drop(z_owned_keyexpr_t* v) { z_keyexpr_drop(v); } -template<> inline void z_drop(z_owned_config_t* v) { z_config_drop(v); } -template<> inline void z_drop(z_owned_scouting_config_t* v) { z_scouting_config_drop(v); } -template<> inline int8_t z_drop(z_owned_subscriber_t* v) { return z_undeclare_subscriber(v); } -template<> inline int8_t z_drop(z_owned_queryable_t* v) { return z_undeclare_queryable(v); } -template<> inline void z_drop(z_owned_encoding_t* v) { z_encoding_drop(v); } -template<> inline void z_drop(z_owned_reply_t* v) { z_reply_drop(v); } -template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } -template<> inline void z_drop(z_owned_query_t* v) { z_query_drop(v); } -template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } -template<> inline void z_drop(z_owned_bytes_t* v) { z_bytes_drop(v); } -template<> inline void z_drop(z_owned_bytes_reader_t* v) { z_bytes_reader_drop(v); } -template<> inline void z_drop(z_owned_closure_sample_t* v) { z_closure_sample_drop(v); } -template<> inline void z_drop(z_owned_closure_query_t* v) { z_closure_query_drop(v); } -template<> inline void z_drop(z_owned_closure_reply_t* v) { z_closure_reply_drop(v); } -template<> inline void z_drop(z_owned_closure_hello_t* v) { z_closure_hello_drop(v); } -template<> inline void z_drop(z_owned_closure_zid_t* v) { z_closure_zid_drop(v); } -template<> inline void z_drop(zcu_owned_closure_matching_status_t* v) { zcu_closure_matching_status_drop(v); } -template<> inline void z_drop(z_owned_reply_channel_closure_t* v) { z_reply_channel_closure_drop(v); } -template<> inline void z_drop(z_owned_reply_channel_t* v) { z_reply_channel_drop(v); } -template<> inline void z_drop(z_owned_slice_t* v) { z_slice_drop(v); } -template<> inline void z_drop(z_owned_slice_map_t* v) { z_slice_map_drop(v); } -template<> inline void z_drop(zc_owned_liveliness_token_t* v) { zc_liveliness_undeclare_token(v); } -template<> inline int8_t z_drop(ze_owned_publication_cache_t* v) { return ze_undeclare_publication_cache(v); } -template<> inline int8_t z_drop(ze_owned_querying_subscriber_t* v) { return ze_undeclare_querying_subscriber(v); } -template<> inline void z_drop(z_owned_mutex_t* v) { z_mutex_drop(v); } -template<> inline void z_drop(z_owned_condvar_t* v) { z_condvar_drop(v); } -inline void z_null(z_owned_session_t& v) { v = z_session_null(); } -inline void z_null(z_owned_publisher_t& v) { v = z_publisher_null(); } -inline void z_null(z_owned_keyexpr_t& v) { v = z_keyexpr_null(); } -inline void z_null(z_owned_config_t& v) { v = z_config_null(); } -inline void z_null(z_owned_scouting_config_t& v) { v = z_scouting_config_null(); } -inline void z_null(z_owned_subscriber_t& v) { v = z_subscriber_null(); } -inline void z_null(z_owned_queryable_t& v) { v = z_queryable_null(); } -inline void z_null(z_owned_encoding_t& v) { v = z_encoding_null(); } -inline void z_null(z_owned_reply_t& v) { v = z_reply_null(); } -inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } -inline void z_null(z_owned_query_t& v) { v = z_query_null(); } -inline void z_null(z_owned_str_t& v) { v = z_str_null(); } -inline void z_null(z_owned_bytes_t& v) { v = z_bytes_null(); } -inline void z_null(z_owned_bytes_reader_t& v) { v = z_bytes_reader_null(); } -inline void z_null(z_owned_closure_sample_t& v) { v = z_closure_sample_null(); } -inline void z_null(z_owned_closure_query_t& v) { v = z_closure_query_null(); } -inline void z_null(z_owned_closure_reply_t& v) { v = z_closure_reply_null(); } -inline void z_null(z_owned_closure_hello_t& v) { v = z_closure_hello_null(); } -inline void z_null(z_owned_closure_zid_t& v) { v = z_closure_zid_null(); } -inline void z_null(zcu_owned_closure_matching_status_t& v) { v = zcu_closure_matching_status_null(); } -inline void z_null(z_owned_reply_channel_closure_t& v) { v = z_reply_channel_closure_null(); } -inline void z_null(z_owned_reply_channel_t& v) { v = z_reply_channel_null(); } -inline void z_null(z_owned_slice_t& v) { v = z_slice_null(); } -inline void z_null(z_owned_slice_map_t& v) { v = z_slice_map_null(); } -inline void z_null(zc_owned_liveliness_token_t& v) { v = zc_liveliness_token_null(); } -inline void z_null(ze_owned_publication_cache_t& v) { v = ze_publication_cache_null(); } -inline void z_null(ze_owned_querying_subscriber_t& v) { v = ze_querying_subscriber_null(); } -inline void z_null(z_owned_mutex_t& v) { v = z_mutex_null(); } -inline void z_null(z_owned_condvar_t& v) { v = z_condvar_null(); } -inline void z_null(z_owned_task_t& v) { v = z_task_null(); } +inline bool z_check(const z_view_keyexpr_t& keyexpr) { return z_view_keyexpr_check(&keyexpr); }; +inline bool z_check(const z_owned_bytes_t& payload) { return z_bytes_check(&payload); }; +inline bool z_check(const z_owned_query_t& query) { return z_query_check(&query); }; +inline bool z_check(const z_owned_scouting_config_t& config) { return z_scouting_config_check(&config); }; +inline bool z_check(const ze_owned_querying_subscriber_t& this_) { return ze_querying_subscriber_check(&this_); }; +inline bool z_check(const z_owned_sample_t& sample) { return z_sample_check(&sample); }; +inline bool z_check(const z_owned_keyexpr_t& keyexpr) { return z_keyexpr_check(&keyexpr); }; +inline bool z_check(const z_owned_str_array_t& strs) { return z_str_array_check(&strs); }; +inline bool z_check(const z_owned_hello_t& hello) { return z_hello_check(&hello); }; +inline bool z_check(const z_owned_task_t& this_) { return z_task_check(&this_); }; +inline bool z_check(const z_owned_reply_t& this_) { return z_reply_check(&this_); }; +inline bool z_check(const z_view_slice_t& this_) { return z_view_slice_check(&this_); }; +inline bool z_check(const ze_owned_publication_cache_t& this_) { return ze_publication_cache_check(&this_); }; +inline bool z_check(const zc_owned_liveliness_token_t& this_) { return zc_liveliness_token_check(&this_); }; +inline bool z_check(const z_owned_queryable_t& qable) { return z_queryable_check(&qable); }; +inline bool z_check(const z_owned_condvar_t& this_) { return z_condvar_check(&this_); }; +inline bool z_check(const z_owned_str_t& this_) { return z_str_check(&this_); }; +inline bool z_check(const z_owned_config_t& config) { return z_config_check(&config); }; +inline bool z_check(const z_owned_bytes_reader_t& this_) { return z_bytes_reader_check(&this_); }; +inline bool z_check(const z_owned_mutex_t& this_) { return z_mutex_check(&this_); }; +inline bool z_check(const z_owned_publisher_t& this_) { return z_publisher_check(&this_); }; +inline bool z_check(const z_owned_slice_t& this_) { return z_owned_slice_check(&this_); }; +inline bool z_check(const z_owned_session_t& this_) { return z_session_check(&this_); }; +inline bool z_check(const z_owned_encoding_t& encoding) { return z_encoding_check(&encoding); }; +inline bool z_check(const z_owned_slice_map_t& map) { return z_slice_map_check(&map); }; +inline bool z_check(const z_owned_subscriber_t& subscriber) { return z_subscriber_check(&subscriber); }; -inline bool z_check(const z_owned_session_t& v) { return z_session_check(&v); } -inline bool z_check(const z_owned_publisher_t& v) { return z_publisher_check(&v); } -inline bool z_check(const z_owned_keyexpr_t& v) { return z_keyexpr_check(&v); } -inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } -inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } -inline bool z_check(const z_owned_bytes_t& v) { return z_slice_check(&v); } -inline bool z_check(const z_owned_bytes_reader_t& v) { return z_bytes_reader_check(&v); } -inline bool z_check(const z_owned_subscriber_t& v) { return z_subscriber_check(&v); } -inline bool z_check(const z_owned_queryable_t& v) { return z_queryable_check(&v); } -inline bool z_check(const z_owned_encoding_t& v) { return z_encoding_check(&v); } -inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } -inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } -inline bool z_check(const z_owned_query_t& v) { return z_query_check(&v); } -inline bool z_check(const z_owned_str_t& v) { return z_str_check(&v); } -inline bool z_check(const z_owned_slice_t& v) { return z_slice_check(&v); } -inline bool z_check(const z_owned_slice_map_t& v) { return z_slice_map_check(&v); } -inline bool z_check(const zc_owned_liveliness_token_t& v) { return zc_liveliness_token_check(&v); } -inline bool z_check(const ze_owned_publication_cache_t& v) { return ze_publication_cache_check(&v); } -inline bool z_check(const ze_owned_querying_subscriber_t& v) { return ze_querying_subscriber_check(&v); } -inline bool z_check(const z_owned_mutex_t& v) { return z_mutex_check(&v); } -inline bool z_check(const z_owned_condvar_t& v) { return z_condvar_check(&v); } -inline bool z_check(const z_owned_task_t& v) { return z_task_check(&v); } -inline void z_call(const struct z_owned_closure_sample_t &closure, const struct z_loaned_sample_t *sample) - { z_closure_sample_call(&closure, sample); } -inline void z_call(const struct z_owned_closure_query_t &closure, const struct z_loaned_query_t *query) - { z_closure_query_call(&closure, query); } -inline void z_call(const struct z_owned_closure_reply_t &closure, struct z_owned_reply_t *sample) - { z_closure_reply_call(&closure, sample); } -inline void z_call(const struct z_owned_closure_hello_t &closure, struct z_owned_hello_t *hello) - { z_closure_hello_call(&closure, hello); } -inline void z_call(const struct z_owned_closure_zid_t &closure, const struct z_id_t *zid) - { z_closure_zid_call(&closure, zid); } -inline void z_call(const struct zcu_owned_closure_matching_status_t &closure, const struct zcu_matching_status_t *matching_status) - { zcu_closure_matching_status_call(&closure, matching_status); } -inline bool z_call(const struct z_owned_reply_channel_closure_t &closure, struct z_owned_reply_t *sample) - { return z_reply_channel_closure_call(&closure, sample); } -// clang-format on +inline void z_call(const z_owned_closure_query_t& closure, const z_loaned_query_t* query) { + return z_closure_query_call(&closure, query); +}; +inline void z_call(const z_owned_closure_hello_t& closure, z_owned_hello_t* hello) { + return z_closure_hello_call(&closure, hello); +}; +inline void z_call(const z_owned_closure_reply_t& closure, const z_loaned_reply_t* reply) { + return z_closure_reply_call(&closure, reply); +}; +inline void z_call(const z_owned_closure_sample_t& closure, const z_loaned_sample_t* sample) { + return z_closure_sample_call(&closure, sample); +}; +inline void z_call(const z_owned_closure_owned_query_t& closure, z_owned_query_t* query) { + return z_closure_owned_query_call(&closure, query); +}; +inline void z_call(const z_owned_closure_zid_t& closure, const z_id_t* sample) { + return z_closure_zid_call(&closure, sample); +}; +inline void z_call(const zcu_owned_closure_matching_status_t& closure, const zcu_matching_status_t* sample) { + return zcu_closure_matching_status_call(&closure, sample); +}; +inline bool z_call(const z_owned_query_channel_closure_t& closure, z_owned_query_t* query) { + return z_query_channel_closure_call(&closure, query); +}; +inline bool z_call(const z_owned_reply_channel_closure_t& closure, z_owned_reply_t* reply) { + return z_reply_channel_closure_call(&closure, reply); +}; -#define _z_closure_overloader(callback, droper, ctx, ...) \ - { .context = const_cast(static_cast(ctx)), .call = callback, .drop = droper } -#define z_closure(...) _z_closure_overloader(__VA_ARGS__, NULL, NULL) -#define z_move(x) (&x) -#endif // #ifndef __cplusplus +inline void z_closure( + z_owned_closure_query_t* closure, + void (*call)(const z_loaned_query_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_closure_hello_t* closure, + void (*call)( z_owned_hello_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_closure_reply_t* closure, + void (*call)(const z_loaned_reply_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_closure_sample_t* closure, + void (*call)(const z_loaned_sample_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_closure_owned_query_t* closure, + void (*call)( z_owned_query_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_closure_zid_t* closure, + void (*call)(const z_id_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + zcu_owned_closure_matching_status_t* closure, + void (*call)(const zcu_matching_status_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_query_channel_closure_t* closure, + bool (*call)( z_owned_query_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +inline void z_closure( + z_owned_reply_channel_closure_t* closure, + bool (*call)( z_owned_reply_t*, void*), + void (*drop)(void*), + void *context) { + closure->context = context; + closure->drop = drop; + closure->call = call; +}; +#endif // #ifndef __cplusplus \ No newline at end of file diff --git a/src/commons.rs b/src/commons.rs index efc9fc9f0..11a6a28b3 100644 --- a/src/commons.rs +++ b/src/commons.rs @@ -149,15 +149,12 @@ pub extern "C" fn z_sample_attachment(sample: &z_loaned_sample_t) -> *const z_lo } } -pub use crate::opaque_types::zc_owned_sample_t; -decl_transmute_owned!(Option, zc_owned_sample_t); +pub use crate::opaque_types::z_owned_sample_t; +decl_transmute_owned!(Option, z_owned_sample_t); /// Clone a sample in the cheapest way available. #[no_mangle] -pub extern "C" fn z_sample_clone( - src: &z_loaned_sample_t, - dst: *mut MaybeUninit, -) { +pub extern "C" fn z_sample_clone(src: &z_loaned_sample_t, dst: *mut MaybeUninit) { let src = src.transmute_ref(); let src = src.clone(); let dst = dst.transmute_uninit_ptr(); @@ -186,10 +183,10 @@ pub extern "C" fn z_sample_congestion_control( /// Returns `true` if `sample` is valid. /// -/// Note that there exist no fallinle constructors for `zc_owned_sample_t`, so validity is always guaranteed +/// Note that there exist no fallinle constructors for `z_owned_sample_t`, so validity is always guaranteed /// unless the value has been dropped already. #[no_mangle] -pub extern "C" fn z_sample_check(sample: &zc_owned_sample_t) -> bool { +pub extern "C" fn z_sample_check(sample: &z_owned_sample_t) -> bool { let sample = sample.transmute_ref(); sample.is_some() } @@ -198,18 +195,18 @@ pub extern "C" fn z_sample_check(sample: &zc_owned_sample_t) -> bool { /// /// Calling this function using a dropped sample is undefined behaviour. #[no_mangle] -pub extern "C" fn zc_sample_loan(sample: &zc_owned_sample_t) -> &z_loaned_sample_t { +pub extern "C" fn z_sample_loan(sample: &z_owned_sample_t) -> &z_loaned_sample_t { unwrap_ref_unchecked(sample.transmute_ref()).transmute_handle() } /// Destroy the sample. #[no_mangle] -pub extern "C" fn zc_sample_drop(sample: &mut zc_owned_sample_t) { +pub extern "C" fn z_sample_drop(sample: &mut z_owned_sample_t) { Inplace::drop(sample.transmute_mut()); } #[no_mangle] -pub extern "C" fn zc_sample_null(sample: *mut MaybeUninit) { +pub extern "C" fn z_sample_null(sample: *mut MaybeUninit) { Inplace::empty(sample.transmute_uninit_ptr()); } diff --git a/src/publisher.rs b/src/publisher.rs index f4d6b8cbf..acc473008 100644 --- a/src/publisher.rs +++ b/src/publisher.rs @@ -173,7 +173,7 @@ pub extern "C" fn z_publisher_put_options_default(this: &mut z_publisher_put_opt /// Sends a `PUT` message onto the publisher's key expression, transfering the payload ownership. /// /// This is avoids copies when transfering data that was either: -/// - `zc_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher +/// - `z_sample_payload_rcinc`'d from a sample, when forwarding samples from a subscriber/query to a publisher /// - constructed from a `zc_owned_shmbuf_t` /// /// The payload and all owned options fields are consumed upon function return. From cff75b0ec9994d6543740bab6b116c7fba451749 Mon Sep 17 00:00:00 2001 From: Denis Biryukov Date: Fri, 26 Apr 2024 16:50:33 +0200 Subject: [PATCH 71/75] automated macro-function generation --- build.rs | 159 ++++++++++--------- include/zenoh_macros.h | 346 ++++++++++++++++++++--------------------- 2 files changed, 256 insertions(+), 249 deletions(-) diff --git a/build.rs b/build.rs index 4d06c44e3..2a1c263bf 100644 --- a/build.rs +++ b/build.rs @@ -771,82 +771,82 @@ pub fn create_generics_header(path_in: &str, path_out: &str) { #ifndef __cplusplus "; - file_out.write(header.as_bytes()).unwrap(); + file_out.write_all(header.as_bytes()).unwrap(); let type_name_to_loan_func = find_loan_functions(path_in); let out = generate_generic_loan_c(&type_name_to_loan_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let type_name_to_loan_mut_func = find_loan_mut_functions(path_in); let out = generate_generic_loan_mut_c(&type_name_to_loan_mut_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let type_name_to_drop_func = find_drop_functions(path_in); let out = generate_generic_drop_c(&type_name_to_drop_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let type_name_to_null_func = find_null_functions(path_in); let out = generate_generic_null_c(&type_name_to_null_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let type_name_to_check_func = find_check_functions(path_in); let out = generate_generic_check_c(&type_name_to_check_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let type_name_to_call_func = find_call_functions(path_in); let out = generate_generic_call_c(&type_name_to_call_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_closure_c(&type_name_to_call_func); - file_out.write(out.as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); file_out - .write("\n#else // #ifndef __cplusplus\n".as_bytes()) + .write_all("\n#else // #ifndef __cplusplus\n".as_bytes()) .unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_loan_cpp(&type_name_to_loan_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_loan_mut_cpp(&type_name_to_loan_mut_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_drop_cpp(&type_name_to_drop_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_null_cpp(&type_name_to_null_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_check_cpp(&type_name_to_check_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_call_cpp(&type_name_to_call_func); - file_out.write(out.as_bytes()).unwrap(); - file_out.write("\n\n".as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); + file_out.write_all("\n\n".as_bytes()).unwrap(); let out = generate_generic_closure_cpp(&type_name_to_call_func); - file_out.write(out.as_bytes()).unwrap(); + file_out.write_all(out.as_bytes()).unwrap(); file_out - .write("\n#endif // #ifndef __cplusplus".as_bytes()) + .write_all("\n#endif // #ifndef __cplusplus".as_bytes()) .unwrap(); } -pub fn find_loan_functions(path_in: &str) -> HashMap { +pub fn find_loan_functions(path_in: &str) -> Vec { let bindings = std::fs::read_to_string(path_in).unwrap(); let re = Regex::new(r"const struct (\w+) \*(\w+)_loan\(const struct (\w+) \*(\w+)\);").unwrap(); - let mut res = HashMap::::new(); + let mut res = Vec::::new(); for (_, [return_type, func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) @@ -856,15 +856,15 @@ pub fn find_loan_functions(path_in: &str) -> HashMap func_name: func_name.to_string() + "_loan", arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), }; - res.insert(arg_type.to_string(), f); + res.push(f); } res } -pub fn find_loan_mut_functions(path_in: &str) -> HashMap { +pub fn find_loan_mut_functions(path_in: &str) -> Vec { let bindings = std::fs::read_to_string(path_in).unwrap(); let re = Regex::new(r"struct (\w+) \*(\w+)_loan_mut\(struct (\w+) \*(\w+)\);").unwrap(); - let mut res = HashMap::::new(); + let mut res = Vec::::new(); for (_, [return_type, func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) @@ -874,15 +874,15 @@ pub fn find_loan_mut_functions(path_in: &str) -> HashMap HashMap { +pub fn find_drop_functions(path_in: &str) -> Vec { let bindings = std::fs::read_to_string(path_in).unwrap(); let re = Regex::new(r"(\w+)_drop\(struct (\w+) \*(\w+)\);").unwrap(); - let mut res = HashMap::::new(); + let mut res = Vec::::new(); for (_, [func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { let f = FunctionSignature { @@ -890,15 +890,15 @@ pub fn find_drop_functions(path_in: &str) -> HashMap func_name: func_name.to_string() + "_drop", arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), }; - res.insert(arg_type.to_string(), f); + res.push(f); } res } -pub fn find_null_functions(path_in: &str) -> HashMap { +pub fn find_null_functions(path_in: &str) -> Vec { let bindings = std::fs::read_to_string(path_in).unwrap(); let re = Regex::new(r"(\w+)_null\(struct (\w+) \*(\w+)\);").unwrap(); - let mut res = HashMap::::new(); + let mut res = Vec::::new(); for (_, [func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { let f = FunctionSignature { @@ -906,15 +906,15 @@ pub fn find_null_functions(path_in: &str) -> HashMap func_name: func_name.to_string() + "_null", arg_type_and_name: [FuncArg::new(arg_type, "", arg_name)].to_vec(), }; - res.insert(arg_type.to_string(), f); + res.push(f); } res } -pub fn find_check_functions(path_in: &str) -> HashMap { +pub fn find_check_functions(path_in: &str) -> Vec { let bindings = std::fs::read_to_string(path_in).unwrap(); let re = Regex::new(r"bool (\w+)_check\(const struct (\w+) \*(\w+)\);").unwrap(); - let mut res = HashMap::::new(); + let mut res = Vec::::new(); for (_, [func_name, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) { let f = FunctionSignature { @@ -922,18 +922,18 @@ pub fn find_check_functions(path_in: &str) -> HashMap func_name: func_name.to_string() + "_check", arg_type_and_name: [FuncArg::new(arg_type, "const", arg_name)].to_vec(), }; - res.insert(arg_type.to_string(), f); + res.push(f); } res } -pub fn find_call_functions(path_in: &str) -> HashMap { +pub fn find_call_functions(path_in: &str) -> Vec { let bindings = std::fs::read_to_string(path_in).unwrap(); let re = Regex::new( r"(\w+) (\w+)_call\(const struct (\w+) \*(\w+),\s+(\w*)\s*struct (\w+) \*(\w+)\);", ) .unwrap(); - let mut res = HashMap::::new(); + let mut res = Vec::::new(); for (_, [return_type, func_name, closure_type, closure_name, arg_cv, arg_type, arg_name]) in re.captures_iter(&bindings).map(|c| c.extract()) @@ -947,17 +947,18 @@ pub fn find_call_functions(path_in: &str) -> HashMap ] .to_vec(), }; - res.insert(closure_type.to_string(), f); + res.push(f); } res } -pub fn generate_generic_loan_c(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_loan_c(macro_func: &Vec) -> String { let mut out = "#define z_loan(x) \\ _Generic((x)" .to_owned(); - for (owned_type, func) in owned_type_to_fun { + for func in macro_func { + let owned_type = &func.arg_type_and_name[0].typename; let func_name = &func.func_name; out += ", \\\n"; out += &format!(" {owned_type} : {func_name}"); @@ -968,13 +969,14 @@ pub fn generate_generic_loan_c(owned_type_to_fun: &HashMap, + macro_func: &Vec ) -> String { let mut out = "#define z_loan_mut(x) \\ _Generic((x)" .to_owned(); - for (owned_type, func) in owned_type_to_fun { + for func in macro_func { + let owned_type = &func.arg_type_and_name[0].typename; let func_name = &func.func_name; out += ", \\\n"; out += &format!(" {owned_type} : {func_name}"); @@ -984,12 +986,13 @@ pub fn generate_generic_loan_mut_c( out } -pub fn generate_generic_drop_c(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_drop_c(macro_func: &Vec) -> String { let mut out = "#define z_drop(x) \\ _Generic((x)" .to_owned(); - for (owned_type, func) in owned_type_to_fun { + for func in macro_func { + let owned_type = &func.arg_type_and_name[0].typename; let func_name = &func.func_name; out += ",\\\n"; out += &format!(" {owned_type} * : {func_name}"); @@ -999,12 +1002,13 @@ pub fn generate_generic_drop_c(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_null_c(macro_func: &Vec) -> String { let mut out = "#define z_null(x) \\ _Generic((x)" .to_owned(); - for (owned_type, func) in owned_type_to_fun { + for func in macro_func { + let owned_type = &func.arg_type_and_name[0].typename; let func_name = &func.func_name; out += ", \\\n"; out += &format!(" {owned_type} * : {func_name}"); @@ -1014,12 +1018,13 @@ pub fn generate_generic_null_c(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_check_c(macro_func: &Vec) -> String { let mut out = "#define z_check(x) \\ _Generic((x)" .to_owned(); - for (owned_type, func) in owned_type_to_fun { + for func in macro_func { + let owned_type = &func.arg_type_and_name[0].typename; let func_name = &func.func_name; out += ", \\\n"; out += &format!(" {owned_type} : {func_name}"); @@ -1029,13 +1034,14 @@ pub fn generate_generic_check_c(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_call_c(macro_func: &Vec) -> String { let mut out = "#define z_call(x, ...) \\ _Generic((x)" .to_owned(); - for (owned_type, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; + let owned_type = &func.arg_type_and_name[0].typename; out += ", \\\n"; out += &format!(" {owned_type} : {func_name}"); } @@ -1046,13 +1052,14 @@ pub fn generate_generic_call_c(owned_type_to_fun: &HashMap, + macro_func: &Vec ) -> String { let mut out = "#define z_closure(x, callback, dropper, ctx) \\ _Generic((x)" .to_owned(); - for (owned_type, _func) in owned_type_to_fun { + for func in macro_func { + let owned_type = &func.arg_type_and_name[0].typename; out += ", \\\n"; out += &format!( " {owned_type} * : {{ x->context = (void*)ctx; x->call = callback; x->drop = droper; }}"); @@ -1063,10 +1070,10 @@ pub fn generate_generic_closure_c( out } -pub fn generate_generic_loan_cpp(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_loan_cpp(macro_func: &Vec) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; let cv = &func.arg_type_and_name[0].cv; @@ -1079,11 +1086,11 @@ pub fn generate_generic_loan_cpp(owned_type_to_fun: &HashMap, + macro_func: &Vec ) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; let cv = &func.arg_type_and_name[0].cv; @@ -1095,10 +1102,10 @@ pub fn generate_generic_loan_mut_cpp( out } -pub fn generate_generic_drop_cpp(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_drop_cpp(macro_func: &Vec) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; let cv = &func.arg_type_and_name[0].cv; @@ -1110,10 +1117,10 @@ pub fn generate_generic_drop_cpp(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_null_cpp(macro_func: &Vec) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; let cv = &func.arg_type_and_name[0].cv; @@ -1126,11 +1133,11 @@ pub fn generate_generic_null_cpp(owned_type_to_fun: &HashMap, + macro_func: &Vec ) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; let cv = &func.arg_type_and_name[0].cv; @@ -1142,10 +1149,10 @@ pub fn generate_generic_check_cpp( out } -pub fn generate_generic_call_cpp(owned_type_to_fun: &HashMap) -> String { +pub fn generate_generic_call_cpp(macro_func: &Vec) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let func_name = &func.func_name; let return_type = &func.return_type; let closure_cv = &func.arg_type_and_name[0].cv; @@ -1163,11 +1170,11 @@ pub fn generate_generic_call_cpp(owned_type_to_fun: &HashMap, + macro_func: &Vec ) -> String { let mut out = "".to_owned(); - for (_, func) in owned_type_to_fun { + for func in macro_func { let return_type = &func.return_type; let closure_name = &func.arg_type_and_name[0].name; let closure_type = &func.arg_type_and_name[0].typename; diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index c4229023b..d432f0650 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -4,303 +4,303 @@ #define z_loan(x) \ _Generic((x), \ - ze_owned_querying_subscriber_t : ze_querying_subscriber_loan, \ - z_owned_sample_t : z_sample_loan, \ - z_view_slice_t : z_view_slice_loan, \ z_owned_bytes_t : z_bytes_loan, \ + z_owned_bytes_reader_t : z_bytes_reader_loan, \ + z_owned_condvar_t : z_condvar_loan, \ + z_owned_config_t : z_config_loan, \ + z_owned_encoding_t : z_encoding_loan, \ + z_owned_hello_t : z_hello_loan, \ + z_owned_keyexpr_t : z_keyexpr_loan, \ z_owned_publisher_t : z_publisher_loan, \ + z_owned_query_t : z_query_loan, \ + z_owned_sample_t : z_sample_loan, \ + z_owned_session_t : z_session_loan, \ z_owned_slice_t : z_slice_loan, \ z_owned_slice_map_t : z_slice_map_loan, \ - z_owned_keyexpr_t : z_keyexpr_loan, \ - z_owned_encoding_t : z_encoding_loan, \ + z_owned_str_array_t : z_str_array_loan, \ z_owned_str_t : z_str_loan, \ - z_owned_session_t : z_session_loan, \ - z_owned_hello_t : z_hello_loan, \ - z_view_str_t : z_view_str_loan, \ - z_owned_query_t : z_query_loan, \ z_owned_subscriber_t : z_subscriber_loan, \ z_view_keyexpr_t : z_view_keyexpr_loan, \ - z_owned_str_array_t : z_str_array_loan, \ - z_owned_condvar_t : z_condvar_loan, \ - z_owned_config_t : z_config_loan, \ - z_owned_bytes_reader_t : z_bytes_reader_loan \ + z_view_slice_t : z_view_slice_loan, \ + z_view_str_t : z_view_str_loan, \ + ze_owned_querying_subscriber_t : ze_querying_subscriber_loan \ )(&x) #define z_loan_mut(x) \ _Generic((x), \ - z_owned_condvar_t : z_condvar_loan_mut, \ z_owned_bytes_reader_t : z_bytes_reader_loan_mut, \ + z_owned_condvar_t : z_condvar_loan_mut, \ z_owned_config_t : z_config_loan_mut, \ - z_owned_slice_map_t : z_slice_map_loan_mut, \ - z_owned_mutex_t : z_mutex_loan_mut \ + z_owned_mutex_t : z_mutex_loan_mut, \ + z_owned_slice_map_t : z_slice_map_loan_mut \ )(&x) #define z_drop(x) \ _Generic((x),\ + z_owned_bytes_t * : z_bytes_drop,\ + z_owned_bytes_reader_t * : z_bytes_reader_drop,\ + z_owned_closure_hello_t * : z_closure_hello_drop,\ + z_owned_closure_owned_query_t * : z_closure_owned_query_drop,\ z_owned_closure_query_t * : z_closure_query_drop,\ - z_owned_closure_zid_t * : z_closure_zid_drop,\ - z_owned_slice_map_t * : z_slice_map_drop,\ - zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_drop,\ - z_owned_reply_t * : z_reply_drop,\ - z_owned_slice_t * : z_slice_drop,\ + z_owned_closure_reply_t * : z_closure_reply_drop,\ z_owned_closure_sample_t * : z_closure_sample_drop,\ - z_owned_bytes_t * : z_bytes_drop,\ + z_owned_closure_zid_t * : z_closure_zid_drop,\ z_owned_condvar_t * : z_condvar_drop,\ - z_owned_sample_t * : z_sample_drop,\ - z_owned_query_channel_t * : z_query_channel_drop,\ - z_owned_query_channel_closure_t * : z_query_channel_closure_drop,\ - z_owned_closure_reply_t * : z_closure_reply_drop,\ - z_owned_reply_channel_t * : z_reply_channel_drop,\ - z_owned_str_t * : z_str_drop,\ - z_owned_closure_owned_query_t * : z_closure_owned_query_drop,\ z_owned_config_t * : z_config_drop,\ - z_owned_mutex_t * : z_mutex_drop,\ - z_owned_bytes_reader_t * : z_bytes_reader_drop,\ - z_owned_str_array_t * : z_str_array_drop,\ - z_owned_keyexpr_t * : z_keyexpr_drop,\ - z_owned_scouting_config_t * : z_scouting_config_drop,\ - z_owned_closure_hello_t * : z_closure_hello_drop,\ z_owned_encoding_t * : z_encoding_drop,\ z_owned_hello_t * : z_hello_drop,\ + z_owned_keyexpr_t * : z_keyexpr_drop,\ + z_owned_mutex_t * : z_mutex_drop,\ + z_owned_query_channel_closure_t * : z_query_channel_closure_drop,\ + z_owned_query_channel_t * : z_query_channel_drop,\ z_owned_query_t * : z_query_drop,\ - z_owned_reply_channel_closure_t * : z_reply_channel_closure_drop \ + z_owned_reply_channel_closure_t * : z_reply_channel_closure_drop,\ + z_owned_reply_channel_t * : z_reply_channel_drop,\ + z_owned_reply_t * : z_reply_drop,\ + z_owned_sample_t * : z_sample_drop,\ + z_owned_scouting_config_t * : z_scouting_config_drop,\ + z_owned_slice_t * : z_slice_drop,\ + z_owned_slice_map_t * : z_slice_map_drop,\ + z_owned_str_array_t * : z_str_array_drop,\ + z_owned_str_t * : z_str_drop,\ + zcu_owned_closure_matching_status_t * : zcu_closure_matching_status_drop \ )(x) #define z_null(x) \ _Generic((x), \ - z_owned_slice_map_t * : z_slice_map_null, \ - z_owned_query_t * : z_query_null, \ - z_owned_keyexpr_t * : z_keyexpr_null, \ - z_view_str_t * : z_view_str_null, \ - z_view_slice_t * : z_view_slice_null, \ - z_owned_str_t * : z_str_null, \ - z_owned_scouting_config_t * : z_scouting_config_null, \ + z_owned_bytes_t * : z_bytes_null, \ + z_owned_bytes_reader_t * : z_bytes_reader_null, \ z_owned_condvar_t * : z_condvar_null, \ + z_owned_config_t * : z_config_null, \ z_owned_encoding_t * : z_encoding_null, \ + z_owned_hello_t * : z_hello_null, \ + z_owned_keyexpr_t * : z_keyexpr_null, \ + z_owned_mutex_t * : z_mutex_null, \ + z_owned_publisher_t * : z_publisher_null, \ + z_owned_query_t * : z_query_null, \ z_owned_queryable_t * : z_queryable_null, \ z_owned_reply_t * : z_reply_null, \ - z_owned_mutex_t * : z_mutex_null, \ - z_owned_config_t * : z_config_null, \ - z_owned_bytes_reader_t * : z_bytes_reader_null, \ - z_owned_hello_t * : z_hello_null, \ z_owned_sample_t * : z_sample_null, \ - z_owned_subscriber_t * : z_subscriber_null, \ - z_owned_bytes_t * : z_bytes_null, \ - z_owned_publisher_t * : z_publisher_null, \ + z_owned_scouting_config_t * : z_scouting_config_null, \ z_owned_session_t * : z_session_null, \ - z_owned_task_t * : z_task_null, \ + z_owned_slice_map_t * : z_slice_map_null, \ z_owned_slice_t * : z_slice_null, \ + z_owned_str_t * : z_str_null, \ + z_owned_subscriber_t * : z_subscriber_null, \ + z_owned_task_t * : z_task_null, \ z_view_keyexpr_t * : z_view_keyexpr_null, \ + z_view_slice_t * : z_view_slice_null, \ + z_view_str_t * : z_view_str_null, \ zc_owned_liveliness_token_t * : zc_liveliness_token_null, \ - ze_owned_querying_subscriber_t * : ze_querying_subscriber_null, \ - ze_owned_publication_cache_t * : ze_publication_cache_null \ + ze_owned_publication_cache_t * : ze_publication_cache_null, \ + ze_owned_querying_subscriber_t * : ze_querying_subscriber_null \ )(x) #define z_check(x) \ _Generic((x), \ - z_view_keyexpr_t : z_view_keyexpr_check, \ z_owned_bytes_t : z_bytes_check, \ - z_owned_query_t : z_query_check, \ - z_owned_scouting_config_t : z_scouting_config_check, \ - ze_owned_querying_subscriber_t : ze_querying_subscriber_check, \ - z_owned_sample_t : z_sample_check, \ - z_owned_keyexpr_t : z_keyexpr_check, \ - z_owned_str_array_t : z_str_array_check, \ - z_owned_hello_t : z_hello_check, \ - z_owned_task_t : z_task_check, \ - z_owned_reply_t : z_reply_check, \ - z_view_slice_t : z_view_slice_check, \ - ze_owned_publication_cache_t : ze_publication_cache_check, \ - zc_owned_liveliness_token_t : zc_liveliness_token_check, \ - z_owned_queryable_t : z_queryable_check, \ + z_owned_bytes_reader_t : z_bytes_reader_check, \ z_owned_condvar_t : z_condvar_check, \ - z_owned_str_t : z_str_check, \ z_owned_config_t : z_config_check, \ - z_owned_bytes_reader_t : z_bytes_reader_check, \ + z_owned_encoding_t : z_encoding_check, \ + z_owned_hello_t : z_hello_check, \ + z_owned_keyexpr_t : z_keyexpr_check, \ z_owned_mutex_t : z_mutex_check, \ - z_owned_publisher_t : z_publisher_check, \ z_owned_slice_t : z_owned_slice_check, \ + z_owned_publisher_t : z_publisher_check, \ + z_owned_query_t : z_query_check, \ + z_owned_queryable_t : z_queryable_check, \ + z_owned_reply_t : z_reply_check, \ + z_owned_sample_t : z_sample_check, \ + z_owned_scouting_config_t : z_scouting_config_check, \ z_owned_session_t : z_session_check, \ - z_owned_encoding_t : z_encoding_check, \ z_owned_slice_map_t : z_slice_map_check, \ - z_owned_subscriber_t : z_subscriber_check \ + z_owned_str_array_t : z_str_array_check, \ + z_owned_str_t : z_str_check, \ + z_owned_subscriber_t : z_subscriber_check, \ + z_owned_task_t : z_task_check, \ + z_view_keyexpr_t : z_view_keyexpr_check, \ + z_view_slice_t : z_view_slice_check, \ + zc_owned_liveliness_token_t : zc_liveliness_token_check, \ + ze_owned_publication_cache_t : ze_publication_cache_check, \ + ze_owned_querying_subscriber_t : ze_querying_subscriber_check \ )(&x) #define z_call(x, ...) \ _Generic((x), \ - z_owned_closure_query_t : z_closure_query_call, \ z_owned_closure_hello_t : z_closure_hello_call, \ + z_owned_closure_owned_query_t : z_closure_owned_query_call, \ + z_owned_closure_query_t : z_closure_query_call, \ z_owned_closure_reply_t : z_closure_reply_call, \ z_owned_closure_sample_t : z_closure_sample_call, \ - z_owned_closure_owned_query_t : z_closure_owned_query_call, \ z_owned_closure_zid_t : z_closure_zid_call, \ - zcu_owned_closure_matching_status_t : zcu_closure_matching_status_call, \ z_owned_query_channel_closure_t : z_query_channel_closure_call, \ - z_owned_reply_channel_closure_t : z_reply_channel_closure_call \ + z_owned_reply_channel_closure_t : z_reply_channel_closure_call, \ + zcu_owned_closure_matching_status_t : zcu_closure_matching_status_call \ )(&x, __VA_ARGS__) #define z_closure(x, callback, dropper, ctx) \ _Generic((x), \ - z_owned_closure_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ z_owned_closure_hello_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_owned_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + z_owned_closure_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ z_owned_closure_reply_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ z_owned_closure_sample_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - z_owned_closure_owned_query_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ z_owned_closure_zid_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - zcu_owned_closure_matching_status_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ z_owned_query_channel_closure_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ - z_owned_reply_channel_closure_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; } \ + z_owned_reply_channel_closure_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; }, \ + zcu_owned_closure_matching_status_t * : { x->context = (void*)ctx; x->call = callback; x->drop = droper; } \ ) #else // #ifndef __cplusplus -inline const ze_loaned_querying_subscriber_t* z_loan(const ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_loan(this_); }; -inline const z_loaned_sample_t* z_loan(const z_owned_sample_t* sample) { return z_sample_loan(sample); }; -inline const z_loaned_slice_t* z_loan(const z_view_slice_t* this_) { return z_view_slice_loan(this_); }; inline const z_loaned_bytes_t* z_loan(const z_owned_bytes_t* payload) { return z_bytes_loan(payload); }; +inline const z_loaned_bytes_reader_t* z_loan(const z_owned_bytes_reader_t* reader) { return z_bytes_reader_loan(reader); }; +inline const z_loaned_condvar_t* z_loan(const z_owned_condvar_t* this_) { return z_condvar_loan(this_); }; +inline const z_loaned_config_t* z_loan(const z_owned_config_t* this_) { return z_config_loan(this_); }; +inline const z_loaned_encoding_t* z_loan(const z_owned_encoding_t* encoding) { return z_encoding_loan(encoding); }; +inline const z_hello_t* z_loan(const z_owned_hello_t* hello) { return z_hello_loan(hello); }; +inline const z_loaned_keyexpr_t* z_loan(const z_owned_keyexpr_t* key_expr) { return z_keyexpr_loan(key_expr); }; inline const z_loaned_publisher_t* z_loan(const z_owned_publisher_t* this_) { return z_publisher_loan(this_); }; +inline const z_loaned_query_t* z_loan(const z_owned_query_t* this_) { return z_query_loan(this_); }; +inline const z_loaned_sample_t* z_loan(const z_owned_sample_t* sample) { return z_sample_loan(sample); }; +inline const z_loaned_session_t* z_loan(const z_owned_session_t* this_) { return z_session_loan(this_); }; inline const z_loaned_slice_t* z_loan(const z_owned_slice_t* this_) { return z_slice_loan(this_); }; inline const z_loaned_slice_map_t* z_loan(const z_owned_slice_map_t* this_) { return z_slice_map_loan(this_); }; -inline const z_loaned_keyexpr_t* z_loan(const z_owned_keyexpr_t* key_expr) { return z_keyexpr_loan(key_expr); }; -inline const z_loaned_encoding_t* z_loan(const z_owned_encoding_t* encoding) { return z_encoding_loan(encoding); }; +inline const z_str_array_t* z_loan(const z_owned_str_array_t* strs) { return z_str_array_loan(strs); }; inline const z_loaned_str_t* z_loan(const z_owned_str_t* this_) { return z_str_loan(this_); }; -inline const z_loaned_session_t* z_loan(const z_owned_session_t* this_) { return z_session_loan(this_); }; -inline const z_hello_t* z_loan(const z_owned_hello_t* hello) { return z_hello_loan(hello); }; -inline const z_loaned_str_t* z_loan(const z_view_str_t* this_) { return z_view_str_loan(this_); }; -inline const z_loaned_query_t* z_loan(const z_owned_query_t* this_) { return z_query_loan(this_); }; inline const z_loaned_subscriber_t* z_loan(const z_owned_subscriber_t* this_) { return z_subscriber_loan(this_); }; inline const z_loaned_keyexpr_t* z_loan(const z_view_keyexpr_t* key_expr) { return z_view_keyexpr_loan(key_expr); }; -inline const z_str_array_t* z_loan(const z_owned_str_array_t* strs) { return z_str_array_loan(strs); }; -inline const z_loaned_condvar_t* z_loan(const z_owned_condvar_t* this_) { return z_condvar_loan(this_); }; -inline const z_loaned_config_t* z_loan(const z_owned_config_t* this_) { return z_config_loan(this_); }; -inline const z_loaned_bytes_reader_t* z_loan(const z_owned_bytes_reader_t* reader) { return z_bytes_reader_loan(reader); }; +inline const z_loaned_slice_t* z_loan(const z_view_slice_t* this_) { return z_view_slice_loan(this_); }; +inline const z_loaned_str_t* z_loan(const z_view_str_t* this_) { return z_view_str_loan(this_); }; +inline const ze_loaned_querying_subscriber_t* z_loan(const ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_loan(this_); }; -inline z_loaned_condvar_t* z_loan_mut( z_owned_condvar_t& this_) { return z_condvar_loan_mut(&this_); }; inline z_loaned_bytes_reader_t* z_loan_mut( z_owned_bytes_reader_t& reader) { return z_bytes_reader_loan_mut(&reader); }; +inline z_loaned_condvar_t* z_loan_mut( z_owned_condvar_t& this_) { return z_condvar_loan_mut(&this_); }; inline z_loaned_config_t* z_loan_mut( z_owned_config_t& this_) { return z_config_loan_mut(&this_); }; -inline z_loaned_slice_map_t* z_loan_mut( z_owned_slice_map_t& this_) { return z_slice_map_loan_mut(&this_); }; inline z_loaned_mutex_t* z_loan_mut( z_owned_mutex_t& this_) { return z_mutex_loan_mut(&this_); }; +inline z_loaned_slice_map_t* z_loan_mut( z_owned_slice_map_t& this_) { return z_slice_map_loan_mut(&this_); }; +inline void z_drop(const z_owned_bytes_t* this_) { return z_bytes_drop(this_); }; +inline void z_drop(const z_owned_bytes_reader_t* this_) { return z_bytes_reader_drop(this_); }; +inline void z_drop(const z_owned_closure_hello_t* closure) { return z_closure_hello_drop(closure); }; +inline void z_drop(const z_owned_closure_owned_query_t* closure) { return z_closure_owned_query_drop(closure); }; inline void z_drop(const z_owned_closure_query_t* closure) { return z_closure_query_drop(closure); }; -inline void z_drop(const z_owned_closure_zid_t* closure) { return z_closure_zid_drop(closure); }; -inline void z_drop(const z_owned_slice_map_t* this_) { return z_slice_map_drop(this_); }; -inline void z_drop(const zcu_owned_closure_matching_status_t* closure) { return zcu_closure_matching_status_drop(closure); }; -inline void z_drop(const z_owned_reply_t* this_) { return z_reply_drop(this_); }; -inline void z_drop(const z_owned_slice_t* this_) { return z_slice_drop(this_); }; +inline void z_drop(const z_owned_closure_reply_t* closure) { return z_closure_reply_drop(closure); }; inline void z_drop(const z_owned_closure_sample_t* closure) { return z_closure_sample_drop(closure); }; -inline void z_drop(const z_owned_bytes_t* this_) { return z_bytes_drop(this_); }; +inline void z_drop(const z_owned_closure_zid_t* closure) { return z_closure_zid_drop(closure); }; inline void z_drop(const z_owned_condvar_t* this_) { return z_condvar_drop(this_); }; -inline void z_drop(const z_owned_sample_t* sample) { return z_sample_drop(sample); }; -inline void z_drop(const z_owned_query_channel_t* channel) { return z_query_channel_drop(channel); }; -inline void z_drop(const z_owned_query_channel_closure_t* closure) { return z_query_channel_closure_drop(closure); }; -inline void z_drop(const z_owned_closure_reply_t* closure) { return z_closure_reply_drop(closure); }; -inline void z_drop(const z_owned_reply_channel_t* channel) { return z_reply_channel_drop(channel); }; -inline void z_drop(const z_owned_str_t* this_) { return z_str_drop(this_); }; -inline void z_drop(const z_owned_closure_owned_query_t* closure) { return z_closure_owned_query_drop(closure); }; inline void z_drop(const z_owned_config_t* config) { return z_config_drop(config); }; -inline void z_drop(const z_owned_mutex_t* this_) { return z_mutex_drop(this_); }; -inline void z_drop(const z_owned_bytes_reader_t* this_) { return z_bytes_reader_drop(this_); }; -inline void z_drop(const z_owned_str_array_t* strs) { return z_str_array_drop(strs); }; -inline void z_drop(const z_owned_keyexpr_t* keyexpr) { return z_keyexpr_drop(keyexpr); }; -inline void z_drop(const z_owned_scouting_config_t* config) { return z_scouting_config_drop(config); }; -inline void z_drop(const z_owned_closure_hello_t* closure) { return z_closure_hello_drop(closure); }; inline void z_drop(const z_owned_encoding_t* encoding) { return z_encoding_drop(encoding); }; inline void z_drop(const z_owned_hello_t* hello) { return z_hello_drop(hello); }; +inline void z_drop(const z_owned_keyexpr_t* keyexpr) { return z_keyexpr_drop(keyexpr); }; +inline void z_drop(const z_owned_mutex_t* this_) { return z_mutex_drop(this_); }; +inline void z_drop(const z_owned_query_channel_closure_t* closure) { return z_query_channel_closure_drop(closure); }; +inline void z_drop(const z_owned_query_channel_t* channel) { return z_query_channel_drop(channel); }; inline void z_drop(const z_owned_query_t* this_) { return z_query_drop(this_); }; inline void z_drop(const z_owned_reply_channel_closure_t* closure) { return z_reply_channel_closure_drop(closure); }; +inline void z_drop(const z_owned_reply_channel_t* channel) { return z_reply_channel_drop(channel); }; +inline void z_drop(const z_owned_reply_t* this_) { return z_reply_drop(this_); }; +inline void z_drop(const z_owned_sample_t* sample) { return z_sample_drop(sample); }; +inline void z_drop(const z_owned_scouting_config_t* config) { return z_scouting_config_drop(config); }; +inline void z_drop(const z_owned_slice_t* this_) { return z_slice_drop(this_); }; +inline void z_drop(const z_owned_slice_map_t* this_) { return z_slice_map_drop(this_); }; +inline void z_drop(const z_owned_str_array_t* strs) { return z_str_array_drop(strs); }; +inline void z_drop(const z_owned_str_t* this_) { return z_str_drop(this_); }; +inline void z_drop(const zcu_owned_closure_matching_status_t* closure) { return zcu_closure_matching_status_drop(closure); }; -inline void z_null( z_owned_slice_map_t* this_) { return z_slice_map_null(this_); }; -inline void z_null( z_owned_query_t* this_) { return z_query_null(this_); }; -inline void z_null( z_owned_keyexpr_t* this_) { return z_keyexpr_null(this_); }; -inline void z_null( z_view_str_t* this_) { return z_view_str_null(this_); }; -inline void z_null( z_view_slice_t* this_) { return z_view_slice_null(this_); }; -inline void z_null( z_owned_str_t* this_) { return z_str_null(this_); }; -inline void z_null( z_owned_scouting_config_t* this_) { return z_scouting_config_null(this_); }; +inline void z_null( z_owned_bytes_t* this_) { return z_bytes_null(this_); }; +inline void z_null( z_owned_bytes_reader_t* this_) { return z_bytes_reader_null(this_); }; inline void z_null( z_owned_condvar_t* this_) { return z_condvar_null(this_); }; +inline void z_null( z_owned_config_t* this_) { return z_config_null(this_); }; inline void z_null( z_owned_encoding_t* encoding) { return z_encoding_null(encoding); }; +inline void z_null( z_owned_hello_t* this_) { return z_hello_null(this_); }; +inline void z_null( z_owned_keyexpr_t* this_) { return z_keyexpr_null(this_); }; +inline void z_null( z_owned_mutex_t* this_) { return z_mutex_null(this_); }; +inline void z_null( z_owned_publisher_t* this_) { return z_publisher_null(this_); }; +inline void z_null( z_owned_query_t* this_) { return z_query_null(this_); }; inline void z_null( z_owned_queryable_t* this_) { return z_queryable_null(this_); }; inline void z_null( z_owned_reply_t* this_) { return z_reply_null(this_); }; -inline void z_null( z_owned_mutex_t* this_) { return z_mutex_null(this_); }; -inline void z_null( z_owned_config_t* this_) { return z_config_null(this_); }; -inline void z_null( z_owned_bytes_reader_t* this_) { return z_bytes_reader_null(this_); }; -inline void z_null( z_owned_hello_t* this_) { return z_hello_null(this_); }; inline void z_null( z_owned_sample_t* sample) { return z_sample_null(sample); }; -inline void z_null( z_owned_subscriber_t* this_) { return z_subscriber_null(this_); }; -inline void z_null( z_owned_bytes_t* this_) { return z_bytes_null(this_); }; -inline void z_null( z_owned_publisher_t* this_) { return z_publisher_null(this_); }; +inline void z_null( z_owned_scouting_config_t* this_) { return z_scouting_config_null(this_); }; inline void z_null( z_owned_session_t* this_) { return z_session_null(this_); }; -inline void z_null( z_owned_task_t* this_) { return z_task_null(this_); }; +inline void z_null( z_owned_slice_map_t* this_) { return z_slice_map_null(this_); }; inline void z_null( z_owned_slice_t* this_) { return z_slice_null(this_); }; +inline void z_null( z_owned_str_t* this_) { return z_str_null(this_); }; +inline void z_null( z_owned_subscriber_t* this_) { return z_subscriber_null(this_); }; +inline void z_null( z_owned_task_t* this_) { return z_task_null(this_); }; inline void z_null( z_view_keyexpr_t* this_) { return z_view_keyexpr_null(this_); }; +inline void z_null( z_view_slice_t* this_) { return z_view_slice_null(this_); }; +inline void z_null( z_view_str_t* this_) { return z_view_str_null(this_); }; inline void z_null( zc_owned_liveliness_token_t* this_) { return zc_liveliness_token_null(this_); }; -inline void z_null( ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_null(this_); }; inline void z_null( ze_owned_publication_cache_t* this_) { return ze_publication_cache_null(this_); }; +inline void z_null( ze_owned_querying_subscriber_t* this_) { return ze_querying_subscriber_null(this_); }; -inline bool z_check(const z_view_keyexpr_t& keyexpr) { return z_view_keyexpr_check(&keyexpr); }; inline bool z_check(const z_owned_bytes_t& payload) { return z_bytes_check(&payload); }; -inline bool z_check(const z_owned_query_t& query) { return z_query_check(&query); }; -inline bool z_check(const z_owned_scouting_config_t& config) { return z_scouting_config_check(&config); }; -inline bool z_check(const ze_owned_querying_subscriber_t& this_) { return ze_querying_subscriber_check(&this_); }; -inline bool z_check(const z_owned_sample_t& sample) { return z_sample_check(&sample); }; -inline bool z_check(const z_owned_keyexpr_t& keyexpr) { return z_keyexpr_check(&keyexpr); }; -inline bool z_check(const z_owned_str_array_t& strs) { return z_str_array_check(&strs); }; -inline bool z_check(const z_owned_hello_t& hello) { return z_hello_check(&hello); }; -inline bool z_check(const z_owned_task_t& this_) { return z_task_check(&this_); }; -inline bool z_check(const z_owned_reply_t& this_) { return z_reply_check(&this_); }; -inline bool z_check(const z_view_slice_t& this_) { return z_view_slice_check(&this_); }; -inline bool z_check(const ze_owned_publication_cache_t& this_) { return ze_publication_cache_check(&this_); }; -inline bool z_check(const zc_owned_liveliness_token_t& this_) { return zc_liveliness_token_check(&this_); }; -inline bool z_check(const z_owned_queryable_t& qable) { return z_queryable_check(&qable); }; +inline bool z_check(const z_owned_bytes_reader_t& this_) { return z_bytes_reader_check(&this_); }; inline bool z_check(const z_owned_condvar_t& this_) { return z_condvar_check(&this_); }; -inline bool z_check(const z_owned_str_t& this_) { return z_str_check(&this_); }; inline bool z_check(const z_owned_config_t& config) { return z_config_check(&config); }; -inline bool z_check(const z_owned_bytes_reader_t& this_) { return z_bytes_reader_check(&this_); }; +inline bool z_check(const z_owned_encoding_t& encoding) { return z_encoding_check(&encoding); }; +inline bool z_check(const z_owned_hello_t& hello) { return z_hello_check(&hello); }; +inline bool z_check(const z_owned_keyexpr_t& keyexpr) { return z_keyexpr_check(&keyexpr); }; inline bool z_check(const z_owned_mutex_t& this_) { return z_mutex_check(&this_); }; -inline bool z_check(const z_owned_publisher_t& this_) { return z_publisher_check(&this_); }; inline bool z_check(const z_owned_slice_t& this_) { return z_owned_slice_check(&this_); }; +inline bool z_check(const z_owned_publisher_t& this_) { return z_publisher_check(&this_); }; +inline bool z_check(const z_owned_query_t& query) { return z_query_check(&query); }; +inline bool z_check(const z_owned_queryable_t& qable) { return z_queryable_check(&qable); }; +inline bool z_check(const z_owned_reply_t& this_) { return z_reply_check(&this_); }; +inline bool z_check(const z_owned_sample_t& sample) { return z_sample_check(&sample); }; +inline bool z_check(const z_owned_scouting_config_t& config) { return z_scouting_config_check(&config); }; inline bool z_check(const z_owned_session_t& this_) { return z_session_check(&this_); }; -inline bool z_check(const z_owned_encoding_t& encoding) { return z_encoding_check(&encoding); }; inline bool z_check(const z_owned_slice_map_t& map) { return z_slice_map_check(&map); }; +inline bool z_check(const z_owned_str_array_t& strs) { return z_str_array_check(&strs); }; +inline bool z_check(const z_owned_str_t& this_) { return z_str_check(&this_); }; inline bool z_check(const z_owned_subscriber_t& subscriber) { return z_subscriber_check(&subscriber); }; +inline bool z_check(const z_owned_task_t& this_) { return z_task_check(&this_); }; +inline bool z_check(const z_view_keyexpr_t& keyexpr) { return z_view_keyexpr_check(&keyexpr); }; +inline bool z_check(const z_view_slice_t& this_) { return z_view_slice_check(&this_); }; +inline bool z_check(const zc_owned_liveliness_token_t& this_) { return zc_liveliness_token_check(&this_); }; +inline bool z_check(const ze_owned_publication_cache_t& this_) { return ze_publication_cache_check(&this_); }; +inline bool z_check(const ze_owned_querying_subscriber_t& this_) { return ze_querying_subscriber_check(&this_); }; -inline void z_call(const z_owned_closure_query_t& closure, const z_loaned_query_t* query) { - return z_closure_query_call(&closure, query); -}; inline void z_call(const z_owned_closure_hello_t& closure, z_owned_hello_t* hello) { return z_closure_hello_call(&closure, hello); }; +inline void z_call(const z_owned_closure_owned_query_t& closure, z_owned_query_t* query) { + return z_closure_owned_query_call(&closure, query); +}; +inline void z_call(const z_owned_closure_query_t& closure, const z_loaned_query_t* query) { + return z_closure_query_call(&closure, query); +}; inline void z_call(const z_owned_closure_reply_t& closure, const z_loaned_reply_t* reply) { return z_closure_reply_call(&closure, reply); }; inline void z_call(const z_owned_closure_sample_t& closure, const z_loaned_sample_t* sample) { return z_closure_sample_call(&closure, sample); }; -inline void z_call(const z_owned_closure_owned_query_t& closure, z_owned_query_t* query) { - return z_closure_owned_query_call(&closure, query); -}; inline void z_call(const z_owned_closure_zid_t& closure, const z_id_t* sample) { return z_closure_zid_call(&closure, sample); }; -inline void z_call(const zcu_owned_closure_matching_status_t& closure, const zcu_matching_status_t* sample) { - return zcu_closure_matching_status_call(&closure, sample); -}; inline bool z_call(const z_owned_query_channel_closure_t& closure, z_owned_query_t* query) { return z_query_channel_closure_call(&closure, query); }; inline bool z_call(const z_owned_reply_channel_closure_t& closure, z_owned_reply_t* reply) { return z_reply_channel_closure_call(&closure, reply); }; +inline void z_call(const zcu_owned_closure_matching_status_t& closure, const zcu_matching_status_t* sample) { + return zcu_closure_matching_status_call(&closure, sample); +}; inline void z_closure( - z_owned_closure_query_t* closure, - void (*call)(const z_loaned_query_t*, void*), + z_owned_closure_hello_t* closure, + void (*call)( z_owned_hello_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -308,8 +308,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - z_owned_closure_hello_t* closure, - void (*call)( z_owned_hello_t*, void*), + z_owned_closure_owned_query_t* closure, + void (*call)( z_owned_query_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -317,8 +317,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - z_owned_closure_reply_t* closure, - void (*call)(const z_loaned_reply_t*, void*), + z_owned_closure_query_t* closure, + void (*call)(const z_loaned_query_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -326,8 +326,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - z_owned_closure_sample_t* closure, - void (*call)(const z_loaned_sample_t*, void*), + z_owned_closure_reply_t* closure, + void (*call)(const z_loaned_reply_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -335,8 +335,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - z_owned_closure_owned_query_t* closure, - void (*call)( z_owned_query_t*, void*), + z_owned_closure_sample_t* closure, + void (*call)(const z_loaned_sample_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -353,8 +353,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - zcu_owned_closure_matching_status_t* closure, - void (*call)(const zcu_matching_status_t*, void*), + z_owned_query_channel_closure_t* closure, + bool (*call)( z_owned_query_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -362,8 +362,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - z_owned_query_channel_closure_t* closure, - bool (*call)( z_owned_query_t*, void*), + z_owned_reply_channel_closure_t* closure, + bool (*call)( z_owned_reply_t*, void*), void (*drop)(void*), void *context) { closure->context = context; @@ -371,8 +371,8 @@ inline void z_closure( closure->call = call; }; inline void z_closure( - z_owned_reply_channel_closure_t* closure, - bool (*call)( z_owned_reply_t*, void*), + zcu_owned_closure_matching_status_t* closure, + void (*call)(const zcu_matching_status_t*, void*), void (*drop)(void*), void *context) { closure->context = context; From 58412cd94ad2fa0f15bc02d54ea4dbee8f694526 Mon Sep 17 00:00:00 2001 From: yellowhatter Date: Sat, 27 Apr 2024 11:30:41 +0300 Subject: [PATCH 72/75] WIP on SHM API --- Cargo.toml | 8 +- include/zenoh_commons.h | 187 +++++---- include/zenoh_macros.h | 2 +- rust-toolchain.toml | 2 +- src/context.rs | 2 + src/lib.rs | 7 + src/opaque_types/mod.rs | 361 ++++++++++++++++++ src/shm/client_storage/mod.rs | 28 +- src/shm/provider/shared_memory_provider.rs | 10 +- .../provider/shared_memory_provider_impl.rs | 59 ++- .../shared_memory_provider_threadsafe.rs | 210 ++++++---- src/shm/provider/types.rs | 30 +- src/shm/provider/zsliceshm.rs | 67 +++- 13 files changed, 741 insertions(+), 232 deletions(-) create mode 100644 src/opaque_types/mod.rs diff --git a/Cargo.toml b/Cargo.toml index dc2335b00..b540b6b45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,10 +51,10 @@ log = "0.4.17" rand = "0.8.5" spin = "0.9.5" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["unstable"] } [build-dependencies] cbindgen = "0.26.0" diff --git a/include/zenoh_commons.h b/include/zenoh_commons.h index 6522d44d7..fb144a9d1 100644 --- a/include/zenoh_commons.h +++ b/include/zenoh_commons.h @@ -906,20 +906,32 @@ typedef struct ALIGN(8) z_memory_layout_t { uint64_t _0[2]; } z_memory_layout_t; #endif +/** + * An owned ZSliceShmMut + * + * Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. + * The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. + */ #if defined(TARGET_ARCH_X86_64) -typedef struct ALIGN(8) z_slice_shm_mut_t { +typedef struct ALIGN(8) z_owned_slice_shm_mut_t { uint64_t _0[10]; -} z_slice_shm_mut_t; +} z_owned_slice_shm_mut_t; #endif #if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(16) z_slice_shm_mut_t { +typedef struct ALIGN(16) z_owned_slice_shm_mut_t { uint64_t _0[10]; -} z_slice_shm_mut_t; +} z_owned_slice_shm_mut_t; #endif #if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_slice_shm_mut_t { +typedef struct ALIGN(8) z_owned_slice_shm_mut_t { uint64_t _0[10]; -} z_slice_shm_mut_t; +} z_owned_slice_shm_mut_t; #endif /** * An owned SharedMemoryClient @@ -1009,9 +1021,9 @@ typedef struct ALIGN(8) zc_owned_shared_memory_client_list_t { /** * A loaned list of SharedMemoryClients */ -typedef struct zc_shared_memory_client_list_t { +typedef struct zc_loaned_shared_memory_client_list_t { const struct zc_owned_shared_memory_client_list_t *_0; -} zc_shared_memory_client_list_t; +} zc_loaned_shared_memory_client_list_t; /** * An owned SharedMemoryProvider with POSIX backend * @@ -1204,23 +1216,41 @@ typedef struct zc_shared_memory_provider_backend_callbacks_t { void (*drop_fn)(void*); } zc_shared_memory_provider_backend_callbacks_t; /** - * A thread-safe SharedMemoryProvider specialization + * An owned SharedMemoryProvider thread-safe specialization + * + * Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. + * To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. + * After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. + * + * To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. */ #if defined(TARGET_ARCH_X86_64) -typedef struct ALIGN(8) z_shared_memory_provider_threadsafe_t { +typedef struct ALIGN(8) z_owned_shared_memory_provider_threadsafe_t { uint64_t _0[14]; -} z_shared_memory_provider_threadsafe_t; +} z_owned_shared_memory_provider_threadsafe_t; #endif #if defined(TARGET_ARCH_AARCH64) -typedef struct ALIGN(16) z_shared_memory_provider_threadsafe_t { +typedef struct ALIGN(16) z_owned_shared_memory_provider_threadsafe_t { uint64_t _0[14]; -} z_shared_memory_provider_threadsafe_t; +} z_owned_shared_memory_provider_threadsafe_t; #endif #if defined(TARGET_ARCH_ARM) -typedef struct ALIGN(8) z_shared_memory_provider_threadsafe_t { +typedef struct ALIGN(8) z_owned_shared_memory_provider_threadsafe_t { uint64_t _0[14]; -} z_shared_memory_provider_threadsafe_t; +} z_owned_shared_memory_provider_threadsafe_t; #endif +/** + * A loaned SharedMemoryProvider thread-safe specialization + */ +typedef struct z_loaned_shared_memory_provider_threadsafe_t { + const struct z_owned_shared_memory_provider_threadsafe_t *_0; +} z_loaned_shared_memory_provider_threadsafe_t; +/** + * A loaned ZSliceShmMut + */ +typedef struct z_loaned_slice_shm_mut_t { + const struct z_owned_slice_shm_mut_t *_0; +} z_loaned_slice_shm_mut_t; /** * A loaned zenoh subscriber. */ @@ -2197,9 +2227,9 @@ struct z_owned_session_t z_open_with_shm_clients(struct z_owned_config_t *config z_shared_memory_client_storage_t shm_clients); ZENOHC_API void z_owned_buf_alloc_result_delete(struct z_owned_buf_alloc_result_t result); ZENOHC_API -bool z_owned_buf_alloc_result_unwrap(struct z_owned_buf_alloc_result_t alloc_result, - struct z_slice_shm_mut_t *out_buf, - enum z_alloc_error_t *out_error); +int32_t z_owned_buf_alloc_result_unwrap(struct z_owned_buf_alloc_result_t *alloc_result, + struct z_owned_slice_shm_mut_t *out_buf, + enum z_alloc_error_t *out_error); /** * Returns ``true`` if `client` is valid. */ @@ -2223,10 +2253,10 @@ ZENOHC_API void z_owned_shared_memory_client_null(struct z_owned_shared_memory_client_t *out_client); ZENOHC_API int32_t z_owned_shared_memory_client_storage_new(struct z_owned_shared_memory_client_storage_t *out, - struct zc_shared_memory_client_list_t clients); + struct zc_loaned_shared_memory_client_list_t clients); ZENOHC_API int32_t z_owned_shared_memory_client_storage_new_with_default_client_set(struct z_owned_shared_memory_client_storage_t *out, - struct zc_shared_memory_client_list_t clients); + struct zc_loaned_shared_memory_client_list_t clients); ZENOHC_API int32_t z_posix_shared_memory_client_new(struct z_owned_shared_memory_client_t *out_client); ZENOHC_API @@ -2639,73 +2669,98 @@ ZENOHC_API bool z_shared_memory_provider_map(const struct z_shared_memory_provider_t *provider, struct z_allocated_chunk_t allocated_chunk, size_t len, - struct z_slice_shm_mut_t *out_buffer); + struct z_owned_slice_shm_mut_t *out_buffer); ZENOHC_API void z_shared_memory_provider_new(z_protocol_id_t id, struct zc_context_t context, struct zc_shared_memory_provider_backend_callbacks_t callbacks, struct z_shared_memory_provider_t *out_provider); ZENOHC_API -bool z_shared_memory_provider_threadsafe_alloc(const struct z_shared_memory_provider_threadsafe_t *provider, - size_t size, - struct z_alloc_alignment_t alignment, - struct z_owned_buf_alloc_result_t *out_buffer); -ZENOHC_API -bool z_shared_memory_provider_threadsafe_alloc_gc(const struct z_shared_memory_provider_threadsafe_t *provider, +int32_t z_shared_memory_provider_threadsafe_alloc(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_loaned_shared_memory_provider_threadsafe_t provider, size_t size, - struct z_alloc_alignment_t alignment, - struct z_owned_buf_alloc_result_t *out_buffer); + struct z_alloc_alignment_t alignment); ZENOHC_API -bool z_shared_memory_provider_threadsafe_alloc_gc_defrag(const struct z_shared_memory_provider_threadsafe_t *provider, - size_t size, - struct z_alloc_alignment_t alignment, - struct z_owned_buf_alloc_result_t *out_buffer); +int32_t z_shared_memory_provider_threadsafe_alloc_gc(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_loaned_shared_memory_provider_threadsafe_t provider, + size_t size, + struct z_alloc_alignment_t alignment); ZENOHC_API -void z_shared_memory_provider_threadsafe_alloc_gc_defrag_async(const struct z_shared_memory_provider_threadsafe_t *provider, +int32_t z_shared_memory_provider_threadsafe_alloc_gc_defrag(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_loaned_shared_memory_provider_threadsafe_t provider, + size_t size, + struct z_alloc_alignment_t alignment); +ZENOHC_API +void z_shared_memory_provider_threadsafe_alloc_gc_defrag_async(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_loaned_shared_memory_provider_threadsafe_t provider, size_t size, struct z_alloc_alignment_t alignment, - struct z_owned_buf_alloc_result_t *out_buffer, struct zc_threadsafe_context_t result_context, void (*result_callback)(void*, - bool, - struct z_owned_buf_alloc_result_t*)); + struct z_owned_buf_alloc_result_t*, + int32_t)); ZENOHC_API -bool z_shared_memory_provider_threadsafe_alloc_gc_defrag_blocking(const struct z_shared_memory_provider_threadsafe_t *provider, - size_t size, - struct z_alloc_alignment_t alignment, - struct z_owned_buf_alloc_result_t *out_buffer); +int32_t z_shared_memory_provider_threadsafe_alloc_gc_defrag_blocking(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_loaned_shared_memory_provider_threadsafe_t provider, + size_t size, + struct z_alloc_alignment_t alignment); ZENOHC_API -bool z_shared_memory_provider_threadsafe_alloc_gc_defrag_dealloc(const struct z_shared_memory_provider_threadsafe_t *provider, - size_t size, - struct z_alloc_alignment_t alignment, - struct z_owned_buf_alloc_result_t *out_buffer); +int32_t z_shared_memory_provider_threadsafe_alloc_gc_defrag_dealloc(struct z_owned_buf_alloc_result_t *out_buffer, + struct z_loaned_shared_memory_provider_threadsafe_t provider, + size_t size, + struct z_alloc_alignment_t alignment); ZENOHC_API -bool z_shared_memory_provider_threadsafe_alloc_layout(struct z_owned_alloc_layout_threadsafe_t *out_layout, - const struct z_shared_memory_provider_threadsafe_t *provider, - size_t size, - struct z_alloc_alignment_t alignment); +int32_t z_shared_memory_provider_threadsafe_alloc_layout_new(struct z_owned_alloc_layout_threadsafe_t *out_layout, + struct z_loaned_shared_memory_provider_threadsafe_t provider, + size_t size, + struct z_alloc_alignment_t alignment); +/** + * Returns ``true`` if `val` is valid. + */ ZENOHC_API -size_t z_shared_memory_provider_threadsafe_available(const struct z_shared_memory_provider_threadsafe_t *provider); +bool z_shared_memory_provider_threadsafe_check(const struct z_owned_shared_memory_provider_threadsafe_t *val); ZENOHC_API -size_t z_shared_memory_provider_threadsafe_defragment(const struct z_shared_memory_provider_threadsafe_t *provider); +int32_t z_shared_memory_provider_threadsafe_defragment(struct z_loaned_shared_memory_provider_threadsafe_t provider); ZENOHC_API -void z_shared_memory_provider_threadsafe_delete(struct z_shared_memory_provider_threadsafe_t provider); +int32_t z_shared_memory_provider_threadsafe_garbage_collect(struct z_loaned_shared_memory_provider_threadsafe_t provider); +/** + * Returns a :c:type:`z_loaned_shared_memory_provider_threadsafe_t` loaned from `val`. + */ ZENOHC_API -size_t z_shared_memory_provider_threadsafe_garbage_collect(const struct z_shared_memory_provider_threadsafe_t *provider); +struct z_loaned_shared_memory_provider_threadsafe_t z_shared_memory_provider_threadsafe_loan(const struct z_owned_shared_memory_provider_threadsafe_t *val); ZENOHC_API -bool z_shared_memory_provider_threadsafe_map(const struct z_shared_memory_provider_threadsafe_t *provider, +bool z_shared_memory_provider_threadsafe_map(const struct z_owned_shared_memory_provider_threadsafe_t *provider, struct z_allocated_chunk_t allocated_chunk, size_t len, - struct z_slice_shm_mut_t *out_buffer); + struct z_owned_slice_shm_mut_t *out_buffer); ZENOHC_API -void z_shared_memory_provider_threadsafe_new(z_protocol_id_t id, +void z_shared_memory_provider_threadsafe_new(struct z_owned_shared_memory_provider_threadsafe_t *out_provider, + z_protocol_id_t id, struct zc_threadsafe_context_t context, - struct zc_shared_memory_provider_backend_callbacks_t callbacks, - struct z_shared_memory_provider_threadsafe_t *out_provider); + struct zc_shared_memory_provider_backend_callbacks_t callbacks); +/** + * Initializes a null memory for safe-to-drop value of 'z_shared_memory_provider_threadsafe_' type + */ +ZENOHC_API +void z_shared_memory_provider_threadsafe_null(struct z_owned_shared_memory_provider_threadsafe_t *val); ZENOHC_API int8_t z_sleep_ms(size_t time); ZENOHC_API int8_t z_sleep_s(size_t time); ZENOHC_API int8_t z_sleep_us(size_t time); -ZENOHC_API void z_slice_shm_mut_delete(struct z_slice_shm_mut_t slice); +/** + * Returns ``true`` if `val` is valid. + */ +ZENOHC_API bool z_slice_shm_mut_check(const struct z_owned_slice_shm_mut_t *val); +ZENOHC_API void z_slice_shm_mut_delete(struct z_owned_slice_shm_mut_t *val); +ZENOHC_API void z_slice_shm_mut_delete(struct z_owned_slice_shm_mut_t *val); +/** + * Returns a :c:type:`z_loaned_slice_shm_mut_t` loaned from `val`. + */ +ZENOHC_API +struct z_loaned_slice_shm_mut_t z_slice_shm_mut_loan(const struct z_owned_slice_shm_mut_t *val); +/** + * Initializes a null memory for safe-to-drop value of 'z_owned_slice_shm_mut_t' type + */ +ZENOHC_API void z_slice_shm_mut_null(struct z_owned_slice_shm_mut_t *val); /** * Returns ``true`` if `strs` is valid. */ @@ -3107,25 +3162,25 @@ ZENOHC_API struct z_owned_session_t zc_session_rcinc(struct z_session_t session) ZENOHC_API int32_t zc_shared_memory_client_list_add_client(z_protocol_id_t id, struct z_owned_shared_memory_client_t *client, - struct zc_shared_memory_client_list_t list); + struct zc_loaned_shared_memory_client_list_t list); /** - * Returns ``true`` if `list` is valid. + * Returns ``true`` if `val` is valid. */ ZENOHC_API -bool zc_shared_memory_client_list_check(const struct zc_owned_shared_memory_client_list_t *list); +bool zc_shared_memory_client_list_check(const struct zc_owned_shared_memory_client_list_t *val); ZENOHC_API -void zc_shared_memory_client_list_delete(struct zc_owned_shared_memory_client_list_t *out_client); +void zc_shared_memory_client_list_delete(struct zc_owned_shared_memory_client_list_t *val); /** - * Returns a :c:type:`zc_shared_memory_client_list_t` loaned from `list`. + * Returns a :c:type:`zc_loaned_shared_memory_client_list_t` loaned from `list`. */ ZENOHC_API -struct zc_shared_memory_client_list_t zc_shared_memory_client_list_loan(const struct zc_owned_shared_memory_client_list_t *list); +struct zc_loaned_shared_memory_client_list_t zc_shared_memory_client_list_loan(const struct zc_owned_shared_memory_client_list_t *list); ZENOHC_API int32_t zc_shared_memory_client_list_new(struct zc_owned_shared_memory_client_list_t *out); /** * Initializes a null memory for safe-to-drop value of 'zc_owned_shared_memory_client_list_t' type */ -ZENOHC_API void zc_shared_memory_client_list_null(struct zc_owned_shared_memory_client_list_t *out); +ZENOHC_API void zc_shared_memory_client_list_null(struct zc_owned_shared_memory_client_list_t *val); /** * Calls the closure. Calling an uninitialized closure is a no-op. */ diff --git a/include/zenoh_macros.h b/include/zenoh_macros.h index 57d0885d7..9f4b2d616 100644 --- a/include/zenoh_macros.h +++ b/include/zenoh_macros.h @@ -54,7 +54,7 @@ z_owned_alloc_layout_t : z_owned_alloc_layout_delete, \ z_chunk_descriptor_t : z_chunk_descriptor_delete, \ z_allocated_chunk_t : z_allocated_chunk_delete, \ - z_shared_memory_provider_threadsafe_t : z_shared_memory_provider_threadsafe_delete, \ + z_owned_shared_memory_provider_threadsafe_t : z_shared_memory_provider_threadsafe_delete, \ z_shared_memory_provider_t : z_shared_memory_provider_delete, \ z_alloc_alignment_t : z_alloc_alignment_delete, \ z_memory_layout_t : z_memory_layout_delete, \ diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 8142c3012..743f7cd99 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.73.0" +channel = "1.72.0" diff --git a/src/context.rs b/src/context.rs index 6bc5cd96f..2397b947e 100644 --- a/src/context.rs +++ b/src/context.rs @@ -53,6 +53,7 @@ decl_rust_copy_type!( ); #[derive(Debug)] +#[repr(transparent)] pub struct Context(zc_context_t); impl DroppableContext for Context { fn get(&self) -> *mut c_void { @@ -100,6 +101,7 @@ decl_rust_copy_type!( ); #[derive(Debug)] +#[repr(transparent)] pub struct ThreadsafeContext(zc_threadsafe_context_t); impl DroppableContext for ThreadsafeContext { fn get(&self) -> *mut c_void { diff --git a/src/lib.rs b/src/lib.rs index 04a081ea4..653750b38 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -111,6 +111,13 @@ macro_rules! prepare_memory_to_init { }}; } +#[macro_export] +macro_rules! access_loaned_memory { + ($loaned_c_obj_mut:expr, $acess_expr:expr) => { + access_owned_memory!($loaned_c_obj_mut.0, $acess_expr) + }; +} + #[macro_export] macro_rules! access_owned_memory { ($owned_c_obj_mut:expr, $acess_expr:expr) => { diff --git a/src/opaque_types/mod.rs b/src/opaque_types/mod.rs new file mode 100644 index 000000000..b2b2812d9 --- /dev/null +++ b/src/opaque_types/mod.rs @@ -0,0 +1,361 @@ +#[rustfmt::skip] +#[allow(clippy::all)] +/// A split buffer that owns all of its data. +/// +/// To minimize copies and reallocations, Zenoh may provide you data in split buffers. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_bytes_t { + _0: [u8; 40], +} +/// A loaned payload. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_bytes_t { + _0: [u8; 8], +} +/// A map of maybe-owned vector of bytes to maybe-owned vector of bytes. +/// +/// In Zenoh C, this map is backed by Rust's standard HashMap, with a DoS-resistant hasher +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_slice_map_t { + _0: [u8; 48], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_slice_map_t { + _0: [u8; 8], +} +/// An owned sample. +/// +/// This is a read only type that can only be constructed by cloning a `z_sample_t`. +/// Like all owned types, its memory must be freed by passing a mutable reference to it to `zc_sample_drop`. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct zc_owned_sample_t { + _0: [u8; 240], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_sample_t { + _0: [u8; 8], +} +/// A reader for payload data. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_bytes_reader_t { + _0: [u8; 24], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_bytes_reader_t { + _0: [u8; 8], +} +/// The encoding of a payload, in a MIME-like format. +/// +/// For wire and matching efficiency, common MIME types are represented using an integer as `prefix`, and a `suffix` may be used to either provide more detail, or in combination with the `Empty` prefix to write arbitrary MIME types. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_encoding_t { + _0: [u8; 8], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_encoding_t { + _0: [u8; 48], +} +/// An owned reply to a :c:func:`z_get`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_reply_t { + _0: [u8; 256], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_reply_t { + _0: [u8; 8], +} +/// A zenoh value. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_value_t { + _0: [u8; 88], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_value_t { + _0: [u8; 8], +} +/// +/// Queries are atomically reference-counted, letting you extract them from the callback that handed them to you by cloning. +/// `z_query_t`'s are valid as long as at least one corresponding `z_owned_query_t` exists, including the one owned by Zenoh until the callback returns. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_query_t { + _0: [u8; 16], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_query_t { + _0: [u8; 8], +} +/// An owned zenoh queryable. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_queryable_t { + _0: [u8; 32], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_queryable_t { + _0: [u8; 8], +} +/// An owned zenoh querying subscriber. Destroying the subscriber cancels the subscription. +/// +/// Like most `ze_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `ze_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct ze_owned_querying_subscriber_t { + _0: [u8; 64], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct ze_querying_subscriber_t { + _0: [u8; 8], +} +/// A zenoh-allocated key expression. +/// +/// Key expressions can identify a single key or a set of keys. +/// +/// Examples : +/// - ``"key/expression"``. +/// - ``"key/ex*"``. +/// +/// Key expressions can be mapped to numerical ids through :c:func:`z_declare_expr` +/// for wire and computation efficiency. +/// +/// A `key expression `_ can be either: +/// - A plain string expression. +/// - A pure numerical id. +/// - The combination of a numerical prefix and a string suffix. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_keyexpr_t { + _0: [u8; 32], +} +/// A loaned key expression. +/// +/// Key expressions can identify a single key or a set of keys. +/// +/// Examples : +/// - ``"key/expression"``. +/// - ``"key/ex*"``. +/// +/// Using :c:func:`z_declare_keyexpr` allows zenoh to optimize a key expression, +/// both for local processing and network-wise. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_keyexpr_t { + _0: [u8; 8], +} +/// An owned zenoh session. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_session_t { + _0: [u8; 8], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_session_t { + _0: [u8; 8], +} +/// An owned zenoh configuration. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_config_t { + _0: [u8; 8], +} +/// A loaned zenoh configuration. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_config_t { + _0: [u8; 8], +} +/// Represents a Zenoh ID. +/// +/// In general, valid Zenoh IDs are LSB-first 128bit unsigned and non-zero integers. +#[derive(Copy, Clone)] +#[repr(C, align(1))] +pub struct z_id_t { + _0: [u8; 16], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_timestamp_t { + _0: [u8; 24], +} +/// An owned zenoh publisher. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_publisher_t { + _0: [u8; 56], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_publisher_t { + _0: [u8; 8], +} +/// An owned zenoh matching listener. Destroying the matching listener cancels the subscription. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct zcu_owned_matching_listener_t { + _0: [u8; 40], +} +/// An owned zenoh subscriber. Destroying the subscriber cancels the subscription. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_subscriber_t { + _0: [u8; 32], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_subscriber_t { + _0: [u8; 8], +} +/// A liveliness token that can be used to provide the network with information about connectivity to its +/// declarer: when constructed, a PUT sample will be received by liveliness subscribers on intersecting key +/// expressions. +/// +/// A DELETE on the token's key expression will be received by subscribers if the token is destroyed, or if connectivity between the subscriber and the token's creator is lost. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct zc_owned_liveliness_token_t { + _0: [u8; 32], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct zc_liveliness_token_t { + _0: [u8; 8], +} +/// An owned zenoh publication_cache. +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct ze_owned_publication_cache_t { + _0: [u8; 96], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct ze_publication_cache_t { + _0: [u8; 8], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_mutex_t { + _0: [u8; 24], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_mutex_t { + _0: [u8; 8], +} +#[derive(Copy, Clone)] +#[repr(C, align(4))] +pub struct z_owned_condvar_t { + _0: [u8; 8], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_condvar_t { + _0: [u8; 8], +} +#[derive(Copy, Clone)] +#[repr(C, align(8))] +pub struct z_owned_task_t { + _0: [u8; 24], +} diff --git a/src/shm/client_storage/mod.rs b/src/shm/client_storage/mod.rs index 1181eeeca..f01452632 100644 --- a/src/shm/client_storage/mod.rs +++ b/src/shm/client_storage/mod.rs @@ -31,7 +31,7 @@ use std::sync::Arc; #[allow(non_camel_case_types)] #[derive(Clone, Copy)] #[repr(C)] -pub struct zc_shared_memory_client_list_t<'a>(&'a zc_owned_shared_memory_client_list_t); +pub struct zc_loaned_shared_memory_client_list_t<'a>(&'a zc_owned_shared_memory_client_list_t); /// An owned list of SharedMemoryClients /// @@ -74,34 +74,34 @@ pub unsafe extern "C" fn zc_shared_memory_client_list_new( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn zc_shared_memory_client_list_null( - out: &mut zc_owned_shared_memory_client_list_t, + val: &mut zc_owned_shared_memory_client_list_t, ) { - out.make_null(); + val.make_null(); } -/// Returns ``true`` if `list` is valid. +/// Returns ``true`` if `val` is valid. #[no_mangle] #[allow(clippy::missing_safety_doc)] pub extern "C" fn zc_shared_memory_client_list_check( - list: &zc_owned_shared_memory_client_list_t, + val: &zc_owned_shared_memory_client_list_t, ) -> bool { - list.check() + val.check() } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn zc_shared_memory_client_list_delete( - out_client: &mut zc_owned_shared_memory_client_list_t, + val: &mut zc_owned_shared_memory_client_list_t, ) { - out_client.delete(); + val.delete(); } -/// Returns a :c:type:`zc_shared_memory_client_list_t` loaned from `list`. +/// Returns a :c:type:`zc_loaned_shared_memory_client_list_t` loaned from `list`. #[no_mangle] pub extern "C" fn zc_shared_memory_client_list_loan( list: &zc_owned_shared_memory_client_list_t, -) -> zc_shared_memory_client_list_t { - zc_shared_memory_client_list_t(list) +) -> zc_loaned_shared_memory_client_list_t { + zc_loaned_shared_memory_client_list_t(list) } #[no_mangle] @@ -109,7 +109,7 @@ pub extern "C" fn zc_shared_memory_client_list_loan( pub unsafe extern "C" fn zc_shared_memory_client_list_add_client( id: z_protocol_id_t, client: &mut z_owned_shared_memory_client_t, - list: zc_shared_memory_client_list_t, + list: zc_loaned_shared_memory_client_list_t, ) -> i32 { access_owned_memory!(list.0, |list: &mut Vec<_>| { move_owned_memory!(client, |client| { @@ -142,7 +142,7 @@ pub unsafe extern "C" fn z_shared_memory_client_storage_global( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_owned_shared_memory_client_storage_new( out: &mut z_owned_shared_memory_client_storage_t, - clients: zc_shared_memory_client_list_t, + clients: zc_loaned_shared_memory_client_list_t, ) -> i32 { let out = prepare_memory_to_init!(out); access_owned_memory!(clients.0, |list: &Vec<_>| { @@ -159,7 +159,7 @@ pub unsafe extern "C" fn z_owned_shared_memory_client_storage_new( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_owned_shared_memory_client_storage_new_with_default_client_set( out: &mut z_owned_shared_memory_client_storage_t, - clients: zc_shared_memory_client_list_t, + clients: zc_loaned_shared_memory_client_list_t, ) -> i32 { let out = prepare_memory_to_init!(out); access_owned_memory!(clients.0, |list: &Vec<_>| { diff --git a/src/shm/provider/shared_memory_provider.rs b/src/shm/provider/shared_memory_provider.rs index 68ce03258..13efc559c 100644 --- a/src/shm/provider/shared_memory_provider.rs +++ b/src/shm/provider/shared_memory_provider.rs @@ -31,7 +31,7 @@ use super::{ }, shared_memory_provider_impl::alloc, types::{z_alloc_alignment_t, z_owned_buf_alloc_result_t}, - zsliceshm::z_slice_shm_mut_t, + zsliceshm::z_owned_slice_shm_mut_t, }; /// A non-thread-safe SharedMemoryProvider specialization @@ -133,12 +133,12 @@ pub unsafe extern "C" fn z_shared_memory_provider_alloc_gc_defrag_blocking( #[allow(clippy::missing_safety_doc)] unsafe fn alloc_inner( - provider: &z_shared_memory_provider_t, + provider: &z_loaned_shared_memory_provider_t, size: usize, alignment: z_alloc_alignment_t, out_buffer: &mut MaybeUninit, ) -> bool { - alloc::(provider, size, alignment, out_buffer) + alloc::(provider, size, alignment, out_buffer) } #[no_mangle] @@ -171,12 +171,12 @@ pub unsafe extern "C" fn z_shared_memory_provider_map( provider: &z_shared_memory_provider_t, allocated_chunk: z_allocated_chunk_t, len: usize, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { let provider = provider.transmute_ref(); match provider.map(allocated_chunk.transmute(), len) { Ok(buffer) => { - out_buffer.write(buffer.transmute()); + out_buffer.write(Some(buffer).transmute()); true } Err(e) => { diff --git a/src/shm/provider/shared_memory_provider_impl.rs b/src/shm/provider/shared_memory_provider_impl.rs index 407faddd4..90d981752 100644 --- a/src/shm/provider/shared_memory_provider_impl.rs +++ b/src/shm/provider/shared_memory_provider_impl.rs @@ -26,19 +26,15 @@ use super::{ }; #[allow(clippy::missing_safety_doc)] -pub(crate) unsafe fn alloc( - provider: &TAnyProvider, +pub(crate) unsafe fn alloc( + provider: &SharedMemoryProvider< + DynamicProtocolID, + DynamicSharedMemoryProviderBackend, + >, size: usize, alignment: z_alloc_alignment_t, out_buffer: &mut MaybeUninit, -) -> bool -where - TAnyContext: DroppableContext, - TAnyProvider: GuardedTransmute< - SharedMemoryProvider>, - >, -{ - let provider = provider.transmute_ref(); +) -> i32 { match provider .alloc_layout() .size(size) @@ -46,33 +42,27 @@ where .res() { Ok(layout) => { - let result = layout.alloc().with_policy::().res().transmute(); - out_buffer.write(result); - return true; + let result = layout.alloc().with_policy::().res(); + out_buffer.write(Some(result).transmute()); + 0 } Err(e) => { log::error!("{e}"); + -5 // todo: E_ARGUMENT_INVALID } - }; - false + } } #[allow(clippy::missing_safety_doc)] -pub(crate) async fn alloc_async( - provider: &TThreadsafeProvider, +pub(crate) async fn alloc_async( + provider: &SharedMemoryProvider< + DynamicProtocolID, + DynamicSharedMemoryProviderBackend, + >, size: usize, alignment: z_alloc_alignment_t, out_buffer: &mut MaybeUninit, -) -> bool -where - TThreadsafeProvider: GuardedTransmute< - SharedMemoryProvider< - DynamicProtocolID, - DynamicSharedMemoryProviderBackend, - >, - >, -{ - let provider = provider.transmute_ref(); +) -> i32 { match provider .alloc_layout() .size(size) @@ -80,18 +70,13 @@ where .res() { Ok(layout) => { - let result = layout - .alloc() - .with_policy::() - .res_async() - .await - .transmute(); - out_buffer.write(result); - return true; + let result = layout.alloc().with_policy::().res_async().await; + out_buffer.write(Some(result).transmute()); + 0 } Err(e) => { log::error!("{e}"); + -5 // todo: E_ARGUMENT_INVALID } - }; - false + } } diff --git a/src/shm/provider/shared_memory_provider_threadsafe.rs b/src/shm/provider/shared_memory_provider_threadsafe.rs index 544a6e013..e00c677c4 100644 --- a/src/shm/provider/shared_memory_provider_threadsafe.rs +++ b/src/shm/provider/shared_memory_provider_threadsafe.rs @@ -21,8 +21,9 @@ use zenoh::shm::provider::shared_memory_provider::{ }; use crate::{ - common::types::z_protocol_id_t, decl_rust_copy_type, impl_guarded_transmute, - zc_threadsafe_context_t, DroppableContext, GuardedTransmute, ThreadsafeContext, + access_loaned_memory, access_owned_memory, common::types::z_protocol_id_t, + decl_rust_new_owned_type, impl_guarded_transmute, zc_threadsafe_context_t, DroppableContext, + GuardedTransmute, ThreadsafeContext, }; use super::{ @@ -33,118 +34,158 @@ use super::{ }, shared_memory_provider_impl::{alloc, alloc_async}, types::{z_alloc_alignment_t, z_owned_buf_alloc_result_t}, - zsliceshm::z_slice_shm_mut_t, + zsliceshm::z_owned_slice_shm_mut_t, }; -/// A thread-safe SharedMemoryProvider specialization +/// A loaned SharedMemoryProvider thread-safe specialization +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(C)] +pub struct z_loaned_shared_memory_provider_threadsafe_t<'a>( + &'a z_owned_shared_memory_provider_threadsafe_t, +); + +/// An owned SharedMemoryProvider thread-safe specialization +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` (or `z_check(val)` if your compiler supports `_Generic`), which will return `true` if `val` is valid. #[cfg(target_arch = "x86_64")] #[repr(C, align(8))] -pub struct z_shared_memory_provider_threadsafe_t([u64; 14]); +pub struct z_owned_shared_memory_provider_threadsafe_t([u64; 14]); #[cfg(target_arch = "aarch64")] #[repr(C, align(16))] -pub struct z_shared_memory_provider_threadsafe_t([u64; 14]); +pub struct z_owned_shared_memory_provider_threadsafe_t([u64; 14]); #[cfg(target_arch = "arm")] #[repr(C, align(8))] -pub struct z_shared_memory_provider_threadsafe_t([u64; 14]); +pub struct z_owned_shared_memory_provider_threadsafe_t([u64; 14]); -decl_rust_copy_type!( - zenoh:(SharedMemoryProvider>), - c:(z_shared_memory_provider_threadsafe_t) +decl_rust_new_owned_type!( + zenoh:(Option>>), + c:(z_owned_shared_memory_provider_threadsafe_t) ); #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_new( + out_provider: &mut MaybeUninit, id: z_protocol_id_t, context: zc_threadsafe_context_t, callbacks: zc_shared_memory_provider_backend_callbacks_t, - out_provider: &mut MaybeUninit, ) { let backend = DynamicSharedMemoryProviderBackend::new(context.transmute(), callbacks); let provider = SharedMemoryProviderBuilder::builder() .dynamic_protocol_id(id) .backend(backend) .res(); - out_provider.write(provider.transmute()); + out_provider.write(Some(provider).transmute()); } +/// Initializes a null memory for safe-to-drop value of 'z_shared_memory_provider_threadsafe_' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_delete( - provider: z_shared_memory_provider_threadsafe_t, +pub extern "C" fn z_shared_memory_provider_threadsafe_null( + val: &mut z_owned_shared_memory_provider_threadsafe_t, ) { - let _ = provider.transmute(); + val.make_null(); +} + +/// Returns ``true`` if `val` is valid. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub extern "C" fn z_shared_memory_provider_threadsafe_check( + val: &z_owned_shared_memory_provider_threadsafe_t, +) -> bool { + val.check() +} + +/// Returns a :c:type:`z_loaned_shared_memory_provider_threadsafe_t` loaned from `val`. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub extern "C" fn z_shared_memory_provider_threadsafe_loan( + val: &z_owned_shared_memory_provider_threadsafe_t, +) -> z_loaned_shared_memory_provider_threadsafe_t { + z_loaned_shared_memory_provider_threadsafe_t(val) } #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_layout<'a>( - out_layout: &'a mut z_owned_alloc_layout_threadsafe_t, - provider: &'a z_shared_memory_provider_threadsafe_t, +pub unsafe extern "C" fn z_slice_shm_mut_delete(val: &mut z_owned_slice_shm_mut_t) { + val.delete(); +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_layout_new( + out_layout: &mut MaybeUninit, + provider: z_loaned_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, -) -> bool { - let provider = provider.transmute_ref(); - match provider - .alloc_layout() - .size(size) - .alignment(alignment.transmute()) - .res() - { - Ok(layout) => { - out_layout.write(layout.transmute()); - return true; +) -> i32 { + access_loaned_memory!(provider, |val: &mut SharedMemoryProvider<_, _>| { + match val + .alloc_layout() + .size(size) + .alignment(alignment.transmute()) + .res() + { + Ok(layout) => { + out_layout.write(Some(layout).transmute()); + 0 + } + Err(e) => { + log::error!("{e}"); + return -5; // todo: E_ARGUMENT_INVALID + } } - Err(e) => { - log::error!("{e}"); - } - }; - false + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc( - provider: &z_shared_memory_provider_threadsafe_t, + out_buffer: &mut MaybeUninit, + provider: z_loaned_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, -) -> bool { +) -> i32 { alloc_inner::(provider, size, alignment, out_buffer) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc( - provider: &z_shared_memory_provider_threadsafe_t, + out_buffer: &mut MaybeUninit, + provider: z_loaned_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, -) -> bool { +) -> i32 { alloc_inner::(provider, size, alignment, out_buffer) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag( - provider: &z_shared_memory_provider_threadsafe_t, + out_buffer: &mut MaybeUninit, + provider: z_loaned_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, -) -> bool { +) -> i32 { alloc_inner::>(provider, size, alignment, out_buffer) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag_dealloc( - provider: &z_shared_memory_provider_threadsafe_t, + out_buffer: &mut MaybeUninit, + provider: z_loaned_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, -) -> bool { +) -> i32 { alloc_inner::>>( provider, size, alignment, out_buffer, ) @@ -153,83 +194,94 @@ pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag_dea #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag_blocking( - provider: &z_shared_memory_provider_threadsafe_t, + out_buffer: &mut MaybeUninit, + provider: z_loaned_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, -) -> bool { +) -> i32 { alloc_inner::>>(provider, size, alignment, out_buffer) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_alloc_gc_defrag_async( - provider: &z_shared_memory_provider_threadsafe_t, + out_buffer: &mut MaybeUninit, + provider: z_loaned_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, - out_buffer: &mut MaybeUninit, result_context: zc_threadsafe_context_t, result_callback: unsafe extern "C" fn( *mut c_void, - bool, &mut MaybeUninit, + i32, ), ) { let result_context = result_context.transmute(); //todo: this should be ported to tokio with executor argument support - async_std::task::block_on(async move { - let result = alloc_async::< - BlockOn>, - z_shared_memory_provider_threadsafe_t, - >(provider, size, alignment, out_buffer) - .await; - (result_callback)(result_context.get(), result, out_buffer); + async_std::task::spawn(async move { + let result = match provider.0.transmute_ref() { + Some(val) => { + alloc_async::>>(val, size, alignment, out_buffer) + .await + } + None => -2, // todo: error type E_ACCESS_NULL + }; + + (result_callback)(result_context.get(), out_buffer, result); }); } #[allow(clippy::missing_safety_doc)] unsafe fn alloc_inner( - provider: &z_shared_memory_provider_threadsafe_t, + provider: z_loaned_shared_memory_provider_threadsafe_t, size: usize, alignment: z_alloc_alignment_t, out_buffer: &mut MaybeUninit, -) -> bool { - alloc::( - provider, size, alignment, out_buffer, - ) +) -> i32 { + access_loaned_memory!(provider, |val| { + alloc::(val, size, alignment, out_buffer) + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_defragment( - provider: &z_shared_memory_provider_threadsafe_t, -) -> usize { - provider.transmute_ref().defragment() + provider: z_loaned_shared_memory_provider_threadsafe_t, +) -> i32 { + access_loaned_memory!(provider, |val: &mut SharedMemoryProvider<_, _>| { + let _ = val.defragment(); + 0 + }) } #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_garbage_collect( - provider: &z_shared_memory_provider_threadsafe_t, -) -> usize { - provider.transmute_ref().garbage_collect() + provider: z_loaned_shared_memory_provider_threadsafe_t, +) -> i32 { + access_loaned_memory!(provider, |val: &mut SharedMemoryProvider<_, _>| { + let _ = val.garbage_collect(); + 0 + }) } -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_available( - provider: &z_shared_memory_provider_threadsafe_t, -) -> usize { - provider.transmute_ref().available() -} +//#[no_mangle] +//#[allow(clippy::missing_safety_doc)] +//pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_available( +// provider: z_loaned_shared_memory_provider_threadsafe_t, +//) -> i32 { +// access_loaned_memory!(provider, |val: &mut SharedMemoryProvider<_, _>| { +// val.available() +// }) +//} #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_shared_memory_provider_threadsafe_map( - provider: &z_shared_memory_provider_threadsafe_t, + provider: &z_owned_shared_memory_provider_threadsafe_t, allocated_chunk: z_allocated_chunk_t, len: usize, - out_buffer: &mut MaybeUninit, + out_buffer: &mut MaybeUninit, ) -> bool { let provider = provider.transmute_ref(); match provider.map(allocated_chunk.transmute(), len) { diff --git a/src/shm/provider/types.rs b/src/shm/provider/types.rs index bc821d776..dfaf2ed9e 100644 --- a/src/shm/provider/types.rs +++ b/src/shm/provider/types.rs @@ -19,9 +19,9 @@ use zenoh::shm::provider::types::{ }; use zenoh_util::core::zerror; -use crate::{decl_rust_new_owned_type, decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute}; +use crate::{decl_rust_copy_type, decl_rust_new_owned_type, impl_guarded_transmute, move_owned_memory, GuardedTransmute}; -use super::{chunk::z_allocated_chunk_t, zsliceshm::z_slice_shm_mut_t}; +use super::{chunk::z_allocated_chunk_t, zsliceshm::z_owned_slice_shm_mut_t}; /// Allocation errors /// @@ -189,20 +189,22 @@ decl_rust_new_owned_type!( #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn z_owned_buf_alloc_result_unwrap( - alloc_result: z_owned_buf_alloc_result_t, - out_buf: &mut MaybeUninit, + alloc_result: &mut z_owned_buf_alloc_result_t, + out_buf: &mut MaybeUninit, out_error: &mut MaybeUninit, -) -> bool { - match alloc_result.transmute() { - Ok(val) => { - out_buf.write(val.transmute()); - true +) -> i32 { + move_owned_memory!(alloc_result, |result: BufAllocResult| { + match result { + Ok(val) => { + out_buf.write(Some(val).transmute()); + 0 + } + Err(e) => { + out_error.write(e.into()); + -5 // todo: E_ARGUMENT_INVALID + } } - Err(e) => { - out_error.write(e.into()); - false - } - } + }) } #[no_mangle] diff --git a/src/shm/provider/zsliceshm.rs b/src/shm/provider/zsliceshm.rs index 90861d875..afeac5d6b 100644 --- a/src/shm/provider/zsliceshm.rs +++ b/src/shm/provider/zsliceshm.rs @@ -12,30 +12,75 @@ // ZettaScale Zenoh Team, // -use zenoh::shm::provider::zsliceshmmut::ZSliceShmMut; +use zenoh::shm::slice::zsliceshmmut::ZSliceShmMut; -use crate::{decl_rust_copy_type, impl_guarded_transmute, GuardedTransmute}; +use crate::{decl_rust_new_owned_type, impl_guarded_transmute, GuardedTransmute}; -// A ZSliceSHM + +/// A loaned ZSliceShmMut +#[allow(non_camel_case_types)] +#[derive(Clone, Copy)] +#[repr(C)] +pub struct z_loaned_slice_shm_mut_t<'a>(&'a z_owned_slice_shm_mut_t); + +/// An owned ZSliceShmMut +/// +/// Like most `z_owned_X_t` types, you may obtain an instance of `z_X_t` by loaning it using `z_X_loan(&val)`. +/// The `z_loan(val)` macro, available if your compiler supports C11's `_Generic`, is equivalent to writing `z_X_loan(&val)`. +/// +/// Like all `z_owned_X_t`, an instance will be destroyed by any function which takes a mutable pointer to said instance, as this implies the instance's inners were moved. +/// To make this fact more obvious when reading your code, consider using `z_move(val)` instead of `&val` as the argument. +/// After a move, `val` will still exist, but will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your `val` is valid. +/// +/// To check if `val` is still valid, you may use `z_X_check(&val)` or `z_check(val)` if your compiler supports `_Generic`, which will return `true` if `val` is valid. #[cfg(target_arch = "x86_64")] #[repr(C, align(8))] -pub struct z_slice_shm_mut_t([u64; 10]); +pub struct z_owned_slice_shm_mut_t([u64; 10]); #[cfg(target_arch = "aarch64")] #[repr(C, align(16))] -pub struct z_slice_shm_mut_t([u64; 10]); +pub struct z_owned_slice_shm_mut_t([u64; 10]); #[cfg(target_arch = "arm")] #[repr(C, align(8))] -pub struct z_slice_shm_mut_t([u64; 10]); +pub struct z_owned_slice_shm_mut_t([u64; 10]); -decl_rust_copy_type!( - zenoh:(ZSliceShmMut), - c:(z_slice_shm_mut_t) +decl_rust_new_owned_type!( + zenoh:(Option), + c:(z_owned_slice_shm_mut_t) ); +/// Initializes a null memory for safe-to-drop value of 'z_owned_slice_shm_mut_t' type #[no_mangle] #[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn z_slice_shm_mut_delete(slice: z_slice_shm_mut_t) { - let _ = slice.transmute(); +pub extern "C" fn z_slice_shm_mut_null( + val: &mut z_owned_slice_shm_mut_t, +) { + val.make_null(); } + +/// Returns ``true`` if `val` is valid. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub extern "C" fn z_slice_shm_mut_check( + val: &z_owned_slice_shm_mut_t, +) -> bool { + val.check() +} + +/// Returns a :c:type:`z_loaned_slice_shm_mut_t` loaned from `val`. +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub extern "C" fn z_slice_shm_mut_loan( + val: &z_owned_slice_shm_mut_t, +) -> z_loaned_slice_shm_mut_t { + z_loaned_slice_shm_mut_t(val) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn z_slice_shm_mut_delete( + val: &mut z_owned_slice_shm_mut_t, +) { + val.delete(); +} \ No newline at end of file From 246ce9530b0f95305a72c6329223ca2ba3d87cf5 Mon Sep 17 00:00:00 2001 From: yellowhatter Date: Sat, 27 Apr 2024 12:31:05 +0300 Subject: [PATCH 73/75] Use shm_refine zenoh branch --- Cargo.toml | 8 ++++---- Cargo.toml.in | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f6c36910f..aab94730b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,10 +53,10 @@ spin = "0.9.5" unwrap-infallible = "0.1.5" const_format = "0.2.32" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine", features = ["unstable"] } [build-dependencies] cbindgen = "0.26.0" diff --git a/Cargo.toml.in b/Cargo.toml.in index 7a403db69..eb3b0e902 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -53,10 +53,10 @@ spin = "0.9.5" unwrap-infallible = "0.1.5" const_format = "0.2.32" # shared-memory enabled for zenoh even if zenoh-c "shared-memory" feature is disabled. This is to make "std::mem::transmute" work for `ZSLice` -zenoh = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["shared-memory", "unstable"], default-features = false } -zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["shared-memory"] } -zenoh-util = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc" } -zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_watchdog_poc", features = ["unstable"] } +zenoh = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine", features = ["shared-memory", "unstable"], default-features = false } +zenoh-protocol = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine", features = ["shared-memory"] } +zenoh-util = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine" } +zenoh-ext = { version = "0.11.0-dev", git = "https://github.com/ZettaScaleLabs/zenoh.git", branch = "shm_refine", features = ["unstable"] } [build-dependencies] cbindgen = "0.26.0" From 30cd123711c0d4b414ae02651b8a501445ab402f Mon Sep 17 00:00:00 2001 From: yellowhatter Date: Sat, 27 Apr 2024 12:38:16 +0300 Subject: [PATCH 74/75] fix feature set after merge --- src/lib.rs | 4 ++-- src/session.rs | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 205638257..0d87cbc43 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,9 +62,9 @@ mod querying_subscriber; pub use platform::*; pub use querying_subscriber::*; pub mod platform; -#[cfg(feature = "shared-memory")] +#[cfg(all(feature = "unstable", feature = "shared-memory"))] pub mod shm; -#[cfg(feature = "shared-memory")] +#[cfg(all(feature = "unstable", feature = "shared-memory"))] pub use crate::shm::*; /// Initialises the zenoh runtime logger. diff --git a/src/session.rs b/src/session.rs index 9276017b8..68a182e36 100644 --- a/src/session.rs +++ b/src/session.rs @@ -12,16 +12,14 @@ // ZettaScale Zenoh team, // -#[cfg(feature = "shared-memory")] +#[cfg(all(feature = "unstable", feature = "shared-memory"))] use crate::client_storage::z_shared_memory_client_storage_t; use crate::transmute::{ unwrap_ref_unchecked, Inplace, TransmuteIntoHandle, TransmuteRef, TransmuteUninitPtr, }; -use crate::{config::*, impl_guarded_transmute, zc_init_logger}; use crate::{errors, z_owned_config_t, zc_init_logger}; use std::mem::MaybeUninit; use std::sync::Arc; -use std::sync::{Arc, Weak}; use zenoh::core::ErrNo; use zenoh::prelude::sync::SyncResolve; use zenoh::session::Session; @@ -92,7 +90,7 @@ pub extern "C" fn z_open( /// Opens a zenoh session. Should the session opening fail, `z_check` ing the returned value will return `false`. #[allow(clippy::missing_safety_doc)] #[no_mangle] -#[cfg(feature = "shared-memory")] +#[cfg(all(feature = "unstable", feature = "shared-memory"))] pub extern "C" fn z_open_with_shm_clients( config: &mut z_owned_config_t, shm_clients: z_shared_memory_client_storage_t, From c98a23c16c173e10b67830f396db30df7de8b948 Mon Sep 17 00:00:00 2001 From: yellowhatter Date: Sat, 27 Apr 2024 12:40:39 +0300 Subject: [PATCH 75/75] Add unstable feature to use shared-memory api --- Cargo.toml | 3 ++- Cargo.toml.in | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index aab94730b..f7a9c7b0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,8 @@ build = "build.rs" [features] logger-autoinit = [] shared-memory = ["zenoh/shared-memory"] -default = ["zenoh/default", "shared-memory"] +unstable = ["zenoh/unstable"] +default = ["zenoh/default"] [badges] maintenance = { status = "actively-developed" } diff --git a/Cargo.toml.in b/Cargo.toml.in index eb3b0e902..60889e77b 100644 --- a/Cargo.toml.in +++ b/Cargo.toml.in @@ -33,7 +33,8 @@ build = "@CARGO_PROJECT_DIR@build.rs" [features] logger-autoinit = [] shared-memory = ["zenoh/shared-memory"] -default = ["zenoh/default", "shared-memory"] +unstable = ["zenoh/unstable"] +default = ["zenoh/default"] [badges] maintenance = { status = "actively-developed" }