From 403bfe9877a23bfe9e5c537a4c308d505d0d6a5e Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Wed, 6 Nov 2024 17:28:55 +0100 Subject: [PATCH 01/30] fix: remove superfluous rc init --- include/zenoh-pico/collections/refcount.h | 27 +++++++++-------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/include/zenoh-pico/collections/refcount.h b/include/zenoh-pico/collections/refcount.h index bcbd8f411..f1ad023f0 100644 --- a/include/zenoh-pico/collections/refcount.h +++ b/include/zenoh-pico/collections/refcount.h @@ -76,11 +76,10 @@ size_t _z_simple_rc_strong_count(void *cnt); return p; \ } \ static inline name##_rc_t name##_rc_clone(const name##_rc_t *p) { \ - name##_rc_t c = name##_rc_null(); \ if (_z_rc_increase_strong(p->_cnt) == _Z_RES_OK) { \ - c = *p; \ + return *p; \ } \ - return c; \ + return name##_rc_null(); \ } \ static inline name##_rc_t *name##_rc_clone_as_ptr(const name##_rc_t *p) { \ name##_rc_t *c = (name##_rc_t *)z_malloc(sizeof(name##_rc_t)); \ @@ -93,12 +92,10 @@ size_t _z_simple_rc_strong_count(void *cnt); return c; \ } \ static inline name##_weak_t name##_rc_clone_as_weak(const name##_rc_t *p) { \ - name##_weak_t c = name##_weak_null(); \ if (_z_rc_increase_weak(p->_cnt) == _Z_RES_OK) { \ - c._val = p->_val; \ - c._cnt = p->_cnt; \ + return (name##_weak_t){._val = p->_val, ._cnt = p->_cnt}; \ } \ - return c; \ + return name##_weak_null(); \ } \ static inline name##_weak_t *name##_rc_clone_as_weak_ptr(const name##_rc_t *p) { \ name##_weak_t *c = (name##_weak_t *)z_malloc(sizeof(name##_weak_t)); \ @@ -137,20 +134,17 @@ size_t _z_simple_rc_strong_count(void *cnt); return res; \ } \ static inline name##_weak_t name##_weak_clone(const name##_weak_t *p) { \ - name##_weak_t c = name##_weak_null(); \ if (_z_rc_increase_weak(p->_cnt) == _Z_RES_OK) { \ - c = *p; \ + return *p; \ } \ - return c; \ + return name##_weak_null(); \ } \ static inline void name##_weak_copy(name##_weak_t *dst, const name##_weak_t *p) { *dst = name##_weak_clone(p); } \ static inline name##_rc_t name##_weak_upgrade(const name##_weak_t *p) { \ - name##_rc_t c = name##_rc_null(); \ if (_z_rc_weak_upgrade(p->_cnt) == _Z_RES_OK) { \ - c._val = p->_val; \ - c._cnt = p->_cnt; \ + return (name##_rc_t){._val = p->_val, ._cnt = p->_cnt}; \ } \ - return c; \ + return name##_rc_null(); \ } \ static inline bool name##_weak_eq(const name##_weak_t *left, const name##_weak_t *right) { \ return (left->_val == right->_val); \ @@ -200,11 +194,10 @@ size_t _z_simple_rc_strong_count(void *cnt); return p; \ } \ static inline name##_simple_rc_t name##_simple_rc_clone(const name##_simple_rc_t *p) { \ - name##_simple_rc_t c = name##_simple_rc_null(); \ if (_z_simple_rc_increase(p->_cnt) == _Z_RES_OK) { \ - c = *p; \ + return *p; \ } \ - return c; \ + return name##_simple_rc_null(); \ } \ static inline name##_simple_rc_t *name##_simple_rc_clone_as_ptr(const name##_simple_rc_t *p) { \ name##_simple_rc_t *c = (name##_simple_rc_t *)z_malloc(sizeof(name##_simple_rc_t)); \ From a1a739790dfb69bee77bdef16ee99b1c9bfbe55c Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Wed, 6 Nov 2024 17:29:23 +0100 Subject: [PATCH 02/30] feat: lazify svec release --- src/collections/vec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/collections/vec.c b/src/collections/vec.c index 60ee8f4a1..d7e9b37c2 100644 --- a/src/collections/vec.c +++ b/src/collections/vec.c @@ -206,7 +206,7 @@ void _z_svec_clear(_z_svec_t *v, z_element_clear_f clear_f, size_t element_size) void _z_svec_release(_z_svec_t *v) { z_free(v->_val); - *v = _z_svec_null(); + v->_capacity = 0; } void _z_svec_free(_z_svec_t **v, z_element_clear_f clear, size_t element_size) { From c0c1127454934d27e7ecb3d0e051348e5b9a8303 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Wed, 6 Nov 2024 17:48:14 +0100 Subject: [PATCH 03/30] refactor: rename slice_empty as slice_null --- include/zenoh-pico/collections/slice.h | 4 ++-- src/api/api.c | 8 ++++---- src/collections/bytes.c | 2 +- src/collections/slice.c | 4 ++-- src/protocol/codec/transport.c | 6 +++--- src/protocol/definitions/transport.c | 2 +- src/transport/unicast/transport.c | 2 +- tests/z_msgcodec_test.c | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/zenoh-pico/collections/slice.h b/include/zenoh-pico/collections/slice.h index 00101c185..58bc8d610 100644 --- a/include/zenoh-pico/collections/slice.h +++ b/include/zenoh-pico/collections/slice.h @@ -51,8 +51,8 @@ typedef struct { _z_delete_context_t _delete_context; } _z_slice_t; -static inline _z_slice_t _z_slice_empty(void) { return (_z_slice_t){0}; } -static inline void _z_slice_reset(_z_slice_t *bs) { *bs = _z_slice_empty(); } +static inline _z_slice_t _z_slice_null(void) { return (_z_slice_t){0}; } +static inline void _z_slice_reset(_z_slice_t *bs) { *bs = _z_slice_null(); } static inline bool _z_slice_is_empty(const _z_slice_t *bs) { return bs->len == 0; } static inline bool _z_slice_check(const _z_slice_t *slice) { return slice->start != NULL; } static inline _z_slice_t _z_slice_alias(const _z_slice_t bs) { diff --git a/src/api/api.c b/src/api/api.c index d74130335..59b5b4476 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -244,12 +244,12 @@ const uint8_t *z_slice_data(const z_loaned_slice_t *slice) { return slice->start size_t z_slice_len(const z_loaned_slice_t *slice) { return slice->len; } -void z_slice_empty(z_owned_slice_t *slice) { slice->_val = _z_slice_empty(); } +void z_slice_empty(z_owned_slice_t *slice) { slice->_val = _z_slice_null(); } bool z_slice_is_empty(const z_loaned_slice_t *slice) { return _z_slice_is_empty(slice); } z_result_t z_bytes_to_slice(const z_loaned_bytes_t *bytes, z_owned_slice_t *dst) { - dst->_val = _z_slice_empty(); + dst->_val = _z_slice_null(); return _z_bytes_to_slice(bytes, &dst->_val); } @@ -479,7 +479,7 @@ _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_keyexpr_t, keyexpr, _z_keyexpr_check, _z_keyexp _z_keyexpr_clear) _Z_VIEW_FUNCTIONS_IMPL(_z_keyexpr_t, keyexpr, _z_keyexpr_check, _z_keyexpr_null) _Z_VIEW_FUNCTIONS_IMPL(_z_string_t, string, _z_string_check, _z_string_null) -_Z_VIEW_FUNCTIONS_IMPL(_z_slice_t, slice, _z_slice_check, _z_slice_empty) +_Z_VIEW_FUNCTIONS_IMPL(_z_slice_t, slice, _z_slice_check, _z_slice_null) _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_hello_t, hello, _z_hello_check, _z_hello_null, _z_hello_copy, _z_hello_clear) @@ -521,7 +521,7 @@ z_result_t _z_string_array_copy(_z_string_svec_t *dst, const _z_string_svec_t *s } _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_string_svec_t, string_array, _z_string_array_check, _z_string_array_null, _z_string_array_copy, _z_string_svec_clear) -_Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_slice_t, slice, _z_slice_check, _z_slice_empty, _z_slice_copy, _z_slice_clear) +_Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_slice_t, slice, _z_slice_check, _z_slice_null, _z_slice_copy, _z_slice_clear) _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_bytes_t, bytes, _z_bytes_check, _z_bytes_null, _z_bytes_copy, _z_bytes_drop) _Z_OWNED_FUNCTIONS_VALUE_NO_COPY_IMPL(_z_bytes_writer_t, bytes_writer, _z_bytes_writer_check, _z_bytes_writer_empty, _z_bytes_writer_clear) diff --git a/src/collections/bytes.c b/src/collections/bytes.c index deb3f8252..46c8b7fef 100644 --- a/src/collections/bytes.c +++ b/src/collections/bytes.c @@ -149,7 +149,7 @@ _z_slice_t _z_bytes_try_get_contiguous(const _z_bytes_t *bs) { _z_arc_slice_t *arc_s = _z_bytes_get_slice(bs, 0); return _z_slice_alias_buf(_z_arc_slice_data(arc_s), _z_arc_slice_len(arc_s)); } - return _z_slice_empty(); + return _z_slice_null(); } void _z_bytes_move(_z_bytes_t *dst, _z_bytes_t *src) { diff --git a/src/collections/slice.c b/src/collections/slice.c index 5c9116ea7..7cfe786f1 100644 --- a/src/collections/slice.c +++ b/src/collections/slice.c @@ -119,14 +119,14 @@ void _z_slice_move(_z_slice_t *dst, _z_slice_t *src) { } _z_slice_t _z_slice_duplicate(const _z_slice_t *src) { - _z_slice_t dst = _z_slice_empty(); + _z_slice_t dst = _z_slice_null(); _z_slice_copy(&dst, src); return dst; } _z_slice_t _z_slice_steal(_z_slice_t *b) { _z_slice_t ret = *b; - *b = _z_slice_empty(); + *b = _z_slice_null(); return ret; } bool _z_slice_eq(const _z_slice_t *left, const _z_slice_t *right) { diff --git a/src/protocol/codec/transport.c b/src/protocol/codec/transport.c index f09b5460f..4c0e01bd9 100644 --- a/src/protocol/codec/transport.c +++ b/src/protocol/codec/transport.c @@ -225,7 +225,7 @@ z_result_t _z_init_decode(_z_t_msg_init_t *msg, _z_zbuf_t *zbf, uint8_t header) if ((ret == _Z_RES_OK) && (_Z_HAS_FLAG(header, _Z_FLAG_T_INIT_A) == true)) { ret |= _z_slice_decode(&msg->_cookie, zbf); } else { - msg->_cookie = _z_slice_empty(); + msg->_cookie = _z_slice_null(); } if ((ret == _Z_RES_OK) && (_Z_HAS_FLAG(header, _Z_FLAG_T_Z) == true)) { @@ -270,10 +270,10 @@ z_result_t _z_open_decode(_z_t_msg_open_t *msg, _z_zbuf_t *zbf, uint8_t header) if ((ret == _Z_RES_OK) && (_Z_HAS_FLAG(header, _Z_FLAG_T_OPEN_A) == false)) { ret |= _z_slice_decode(&msg->_cookie, zbf); if (ret != _Z_RES_OK) { - msg->_cookie = _z_slice_empty(); + msg->_cookie = _z_slice_null(); } } else { - msg->_cookie = _z_slice_empty(); + msg->_cookie = _z_slice_null(); } if ((ret == _Z_RES_OK) && (_Z_HAS_FLAG(header, _Z_FLAG_T_Z) == true)) { ret |= _z_msg_ext_skip_non_mandatories(zbf, 0x02); diff --git a/src/protocol/definitions/transport.c b/src/protocol/definitions/transport.c index 448951e46..2a86d95da 100644 --- a/src/protocol/definitions/transport.c +++ b/src/protocol/definitions/transport.c @@ -248,7 +248,7 @@ _z_transport_message_t _z_t_msg_make_frame_header(_z_zint_t sn, z_reliability_t /*------------------ Fragment Message ------------------*/ _z_transport_message_t _z_t_msg_make_fragment_header(_z_zint_t sn, z_reliability_t reliability, bool is_last) { - return _z_t_msg_make_fragment(sn, _z_slice_empty(), reliability, is_last); + return _z_t_msg_make_fragment(sn, _z_slice_null(), reliability, is_last); } _z_transport_message_t _z_t_msg_make_fragment(_z_zint_t sn, _z_slice_t payload, z_reliability_t reliability, bool is_last) { diff --git a/src/transport/unicast/transport.c b/src/transport/unicast/transport.c index fe48e3f24..251eee96f 100644 --- a/src/transport/unicast/transport.c +++ b/src/transport/unicast/transport.c @@ -227,7 +227,7 @@ static z_result_t _z_unicast_handshake_listener(_z_transport_unicast_establish_p } _Z_DEBUG("Received Z_INIT(Syn)"); // Encode InitAck - _z_slice_t cookie = _z_slice_empty(); + _z_slice_t cookie = _z_slice_null(); _z_transport_message_t iam = _z_t_msg_make_init_ack(whatami, *local_zid, cookie); // Any of the size parameters in the InitAck must be less or equal than the one in the InitSyn, if (iam._body._init._seq_num_res > tmsg._body._init._seq_num_res) { diff --git a/tests/z_msgcodec_test.c b/tests/z_msgcodec_test.c index f3a92a77a..d717b0bfb 100644 --- a/tests/z_msgcodec_test.c +++ b/tests/z_msgcodec_test.c @@ -172,7 +172,7 @@ _z_wbuf_t gen_wbuf(size_t len) { _z_slice_t gen_slice(size_t len) { if (len == 0) { - return _z_slice_empty(); + return _z_slice_null(); } uint8_t *p = (uint8_t *)z_malloc(sizeof(uint8_t) * len); From f4183a96e2a440cf7ee21458d313e1a9bcca6610 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Wed, 6 Nov 2024 18:22:08 +0100 Subject: [PATCH 04/30] feat: rework svec expand --- src/collections/vec.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/collections/vec.c b/src/collections/vec.c index d7e9b37c2..b05113404 100644 --- a/src/collections/vec.c +++ b/src/collections/vec.c @@ -135,7 +135,7 @@ void _z_vec_remove(_z_vec_t *v, size_t pos, z_element_free_f free_f) { /*-------- svec --------*/ _z_svec_t _z_svec_make(size_t capacity, size_t element_size) { - _z_svec_t v = {._capacity = 0, ._len = 0, ._val = NULL}; + _z_svec_t v = _z_svec_null(); if (capacity != 0) { v._val = z_malloc(element_size * capacity); } @@ -226,13 +226,13 @@ bool _z_svec_is_empty(const _z_svec_t *v) { return v->_len == 0; } z_result_t _z_svec_expand(_z_svec_t *v, z_element_move_f move, size_t element_size, bool use_elem_f) { // Allocate a new vector - size_t _capacity = v->_capacity == 0 ? 1 : (v->_capacity << 1); + size_t _capacity = v->_capacity << 1; void *_val = (void *)z_malloc(_capacity * element_size); if (_val == NULL) { return _Z_ERR_SYSTEM_OUT_OF_MEMORY; } + // Move and clear old data __z_svec_move_inner(_val, v->_val, move, v->_len, element_size, use_elem_f); - // Free the old data z_free(v->_val); // Update the current vector v->_val = _val; @@ -241,7 +241,9 @@ z_result_t _z_svec_expand(_z_svec_t *v, z_element_move_f move, size_t element_si } z_result_t _z_svec_append(_z_svec_t *v, const void *e, z_element_move_f move, size_t element_size, bool use_elem_f) { - if (v->_len == v->_capacity) { + if (v->_capacity == 0) { + *v = _z_svec_make(1, element_size); + } else if (v->_len == v->_capacity) { _Z_RETURN_IF_ERR(_z_svec_expand(v, move, element_size, use_elem_f)); } // Append element From 7c63b6d05501161b283763332b26aae98da9426c Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Wed, 6 Nov 2024 18:23:12 +0100 Subject: [PATCH 05/30] refactor: z_bytes_append_slice --- src/collections/bytes.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/collections/bytes.c b/src/collections/bytes.c index 46c8b7fef..e4ad5c298 100644 --- a/src/collections/bytes.c +++ b/src/collections/bytes.c @@ -125,8 +125,12 @@ z_result_t _z_bytes_to_slice(const _z_bytes_t *bytes, _z_slice_t *s) { } z_result_t _z_bytes_append_slice(_z_bytes_t *dst, _z_arc_slice_t *s) { - _Z_CLEAN_RETURN_IF_ERR(_z_arc_slice_svec_append(&dst->_slices, s), _z_arc_slice_drop(s)); - return _Z_RES_OK; + z_result_t ret = _Z_RES_OK; + ret = _z_arc_slice_svec_append(&dst->_slices, s); + if (ret != _Z_RES_OK) { + _z_arc_slice_drop(s); + } + return ret; } z_result_t _z_bytes_append_bytes(_z_bytes_t *dst, _z_bytes_t *src) { From e5f88a435ab76956a2c6c7e3e8e1bb30a9bb83df Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Wed, 6 Nov 2024 18:23:32 +0100 Subject: [PATCH 06/30] feat: lazify arc slice --- src/collections/arc_slice.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/collections/arc_slice.c b/src/collections/arc_slice.c index 17d17a8eb..28603aff9 100644 --- a/src/collections/arc_slice.c +++ b/src/collections/arc_slice.c @@ -36,9 +36,6 @@ _z_arc_slice_t _z_arc_slice_wrap_slice_rc(_z_slice_simple_rc_t* slice_rc, size_t assert(offset + len <= _Z_RC_IN_VAL(slice_rc)->len); _z_arc_slice_t arc_s; arc_s.slice = _z_slice_simple_rc_clone(slice_rc); - if (_Z_RC_IS_NULL(&arc_s.slice)) { - return _z_arc_slice_empty(); - } arc_s.len = len; arc_s.start = offset; return arc_s; @@ -79,6 +76,6 @@ z_result_t _z_arc_slice_move(_z_arc_slice_t* dst, _z_arc_slice_t* src) { z_result_t _z_arc_slice_drop(_z_arc_slice_t* s) { _z_slice_simple_rc_drop(&s->slice); - *s = _z_arc_slice_empty(); + s->len = 0; return _Z_RES_OK; } From 7ac84dd1f97e5c231cef72246e6f91fe79189274 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Wed, 6 Nov 2024 18:24:42 +0100 Subject: [PATCH 07/30] feat: improve stirng/slice move --- src/collections/slice.c | 5 +---- src/collections/string.c | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/collections/slice.c b/src/collections/slice.c index 7cfe786f1..049721a8a 100644 --- a/src/collections/slice.c +++ b/src/collections/slice.c @@ -111,10 +111,7 @@ z_result_t _z_slice_n_copy(_z_slice_t *dst, const _z_slice_t *src, size_t offset } void _z_slice_move(_z_slice_t *dst, _z_slice_t *src) { - dst->start = src->start; - dst->len = src->len; - dst->_delete_context = src->_delete_context; - + *dst = *src; _z_slice_reset(src); } diff --git a/src/collections/string.c b/src/collections/string.c index a2545e767..d15d1438e 100644 --- a/src/collections/string.c +++ b/src/collections/string.c @@ -71,7 +71,7 @@ z_result_t _z_string_copy_substring(_z_string_t *dst, const _z_string_t *src, si return _z_slice_n_copy(&dst->_slice, &src->_slice, offset, len); } -void _z_string_move(_z_string_t *dst, _z_string_t *src) { *dst = _z_string_steal(src); } +void _z_string_move(_z_string_t *dst, _z_string_t *src) { _z_slice_move(&dst->_slice, &src->_slice); } _z_string_t _z_string_steal(_z_string_t *str) { _z_string_t ret; From 48be0d9fb85bc670de147a95126762d045f63af2 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Wed, 6 Nov 2024 19:15:56 +0100 Subject: [PATCH 08/30] feat: lazify sample timestamp set --- include/zenoh-pico/protocol/core.h | 4 +++- src/net/sample.c | 6 +++++- src/session/utils.c | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/zenoh-pico/protocol/core.h b/include/zenoh-pico/protocol/core.h index e66e3745e..d7ff3ec2f 100644 --- a/include/zenoh-pico/protocol/core.h +++ b/include/zenoh-pico/protocol/core.h @@ -70,7 +70,9 @@ typedef struct { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_timestamp_t _z_timestamp_null(void) { return (_z_timestamp_t){0}; } -static inline bool _z_timestamp_check(const _z_timestamp_t *stamp) { return stamp->valid; } +static inline void _z_timestamp_invalid(_z_timestamp_t *tstamp) { tstamp->valid = false; } +static inline bool _z_timestamp_check(const _z_timestamp_t *tstamp) { return tstamp->valid; } +void _z_timestamp_copy(_z_timestamp_t *dst, const _z_timestamp_t *src); _z_timestamp_t _z_timestamp_duplicate(const _z_timestamp_t *tstamp); void _z_timestamp_clear(_z_timestamp_t *tstamp); void _z_timestamp_move(_z_timestamp_t *dst, _z_timestamp_t *src); diff --git a/src/net/sample.c b/src/net/sample.c index d158398c6..eeec068e3 100644 --- a/src/net/sample.c +++ b/src/net/sample.c @@ -65,10 +65,14 @@ void _z_sample_create(_z_sample_t *s, _z_keyexpr_t *key, _z_bytes_t *payload, co s->qos = qos; s->reliability = reliability; s->keyexpr = _z_keyexpr_steal(key); - s->timestamp = _z_timestamp_check(timestamp) ? _z_timestamp_duplicate(timestamp) : _z_timestamp_null(); _z_encoding_move(&s->encoding, encoding); _z_bytes_move(&s->attachment, attachment); _z_bytes_move(&s->payload, payload); + if (_z_timestamp_check(timestamp)) { + _z_timestamp_copy(&s->timestamp, timestamp); + } else { + _z_timestamp_invalid(&s->timestamp); + } } #else void _z_sample_create(_z_sample_t *s, _z_keyexpr_t *key, _z_bytes_t *payload, const _z_timestamp_t *timestamp, diff --git a/src/session/utils.c b/src/session/utils.c index dde52129c..4c2ae96f6 100644 --- a/src/session/utils.c +++ b/src/session/utils.c @@ -26,6 +26,8 @@ #include "zenoh-pico/utils/logging.h" /*------------------ clone helpers ------------------*/ +void _z_timestamp_copy(_z_timestamp_t *dst, const _z_timestamp_t *src) { *dst = *src; } + _z_timestamp_t _z_timestamp_duplicate(const _z_timestamp_t *tstamp) { return *tstamp; } void _z_timestamp_move(_z_timestamp_t *dst, _z_timestamp_t *src) { From 1c888adb679a429c035e7d923bfc5c7fb6168347 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Thu, 7 Nov 2024 18:04:33 +0100 Subject: [PATCH 09/30] feat: add non-reader decode functions --- src/protocol/codec.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/protocol/codec.c b/src/protocol/codec.c index 64f22cade..ed903d676 100644 --- a/src/protocol/codec.c +++ b/src/protocol/codec.c @@ -194,37 +194,51 @@ z_result_t _z_zsize_decode_with_reader(_z_zint_t *zint, __z_single_byte_reader_t z_result_t _z_uint8_decode_reader(uint8_t *zint, void *context) { return _z_uint8_decode(zint, (_z_zbuf_t *)context); } z_result_t _z_zint64_decode(uint64_t *zint, _z_zbuf_t *zbf) { - return _z_zint64_decode_with_reader(zint, _z_uint8_decode_reader, (void *)zbf); + *zint = 0; + uint8_t b = 0; + _Z_RETURN_IF_ERR(_z_uint8_decode(&b, zbf)); + + uint8_t i = 0; + while (((b & 0x80) != 0) && (i != 7 * (VLE_LEN - 1))) { + *zint = *zint | ((uint64_t)(b & 0x7f)) << i; + _Z_RETURN_IF_ERR(_z_uint8_decode(&b, zbf)); + i = i + (uint8_t)7; + } + *zint = *zint | ((uint64_t)b << i); + return _Z_RES_OK; } z_result_t _z_zint16_decode(uint16_t *zint, _z_zbuf_t *zbf) { - z_result_t ret = _Z_RES_OK; uint64_t buf; _Z_RETURN_IF_ERR(_z_zint64_decode(&buf, zbf)); - if (buf <= UINT16_MAX) { - *zint = (uint16_t)buf; - } else { + if (buf > UINT16_MAX) { _Z_INFO("Invalid zint16 value decoded"); - ret = _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; + return _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; } - return ret; + *zint = (uint16_t)buf; + return _Z_RES_OK; } z_result_t _z_zint32_decode(uint32_t *zint, _z_zbuf_t *zbf) { - z_result_t ret = _Z_RES_OK; uint64_t buf; _Z_RETURN_IF_ERR(_z_zint64_decode(&buf, zbf)); - if (buf <= UINT32_MAX) { - *zint = (uint32_t)buf; - } else { + if (buf > UINT32_MAX) { _Z_INFO("Invalid zint32 value decoded"); - ret = _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; + return _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; } - return ret; + *zint = (uint32_t)buf; + return _Z_RES_OK; } z_result_t _z_zsize_decode(_z_zint_t *zint, _z_zbuf_t *zbf) { - return _z_zsize_decode_with_reader(zint, _z_uint8_decode_reader, (void *)zbf); + uint64_t buf; + _Z_RETURN_IF_ERR(_z_zint64_decode(&buf, zbf)); + if (buf > SIZE_MAX) { + _Z_INFO("Invalide zsize value decoded"); + return _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; + } + *zint = (_z_zint_t)buf; + return _Z_RES_OK; } /*------------------ uint8_array ------------------*/ From 49c299548653818ff40419c342a7a2e6bc14af19 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Fri, 8 Nov 2024 00:30:24 +0100 Subject: [PATCH 10/30] feat: remove superfluous keyexpr clear --- src/protocol/keyexpr.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/protocol/keyexpr.c b/src/protocol/keyexpr.c index f71e38875..7b7102228 100644 --- a/src/protocol/keyexpr.c +++ b/src/protocol/keyexpr.c @@ -82,7 +82,6 @@ void _z_keyexpr_clear(_z_keyexpr_t *rk) { if (_z_keyexpr_has_suffix(rk)) { _z_string_clear(&rk->_suffix); } - rk->_suffix = _z_string_null(); } void _z_keyexpr_free(_z_keyexpr_t **rk) { From f870c1ec0d3b388e334a37d9ea627bc3399e251a Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Fri, 8 Nov 2024 00:32:08 +0100 Subject: [PATCH 11/30] feat: add bytes alias arc --- include/zenoh-pico/collections/bytes.h | 4 ++++ include/zenoh-pico/collections/vec.h | 4 ++++ src/collections/bytes.c | 2 ++ src/protocol/definitions/message.c | 1 - 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/zenoh-pico/collections/bytes.h b/include/zenoh-pico/collections/bytes.h index 9f3ad16ef..9c227e3d1 100644 --- a/include/zenoh-pico/collections/bytes.h +++ b/include/zenoh-pico/collections/bytes.h @@ -44,6 +44,9 @@ typedef struct { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_bytes_t _z_bytes_null(void) { return (_z_bytes_t){0}; } +static inline void _z_bytes_alias_arc_slice(_z_bytes_t *dst, _z_arc_slice_t *s) { + dst->_slices = _z_arc_slice_svec_alias_element(s); +} bool _z_bytes_check(const _z_bytes_t *bytes); z_result_t _z_bytes_append_bytes(_z_bytes_t *dst, _z_bytes_t *src); z_result_t _z_bytes_append_slice(_z_bytes_t *dst, _z_arc_slice_t *s); @@ -51,6 +54,7 @@ z_result_t _z_bytes_copy(_z_bytes_t *dst, const _z_bytes_t *src); _z_bytes_t _z_bytes_duplicate(const _z_bytes_t *src); void _z_bytes_move(_z_bytes_t *dst, _z_bytes_t *src); void _z_bytes_drop(_z_bytes_t *bytes); +void _z_bytes_aliased_drop(_z_bytes_t *bytes); void _z_bytes_free(_z_bytes_t **bs); size_t _z_bytes_num_slices(const _z_bytes_t *bs); _z_arc_slice_t *_z_bytes_get_slice(const _z_bytes_t *bs, size_t i); diff --git a/include/zenoh-pico/collections/vec.h b/include/zenoh-pico/collections/vec.h index 3d5e48605..c65401e25 100644 --- a/include/zenoh-pico/collections/vec.h +++ b/include/zenoh-pico/collections/vec.h @@ -81,6 +81,9 @@ typedef struct { static inline _z_svec_t _z_svec_null(void) { return (_z_svec_t){0}; } static inline _z_svec_t _z_svec_alias(const _z_svec_t *src) { return *src; } +static inline _z_svec_t _z_svec_alias_element(void *element) { + return (_z_svec_t){._capacity = 1, ._len = 1, ._val = element}; +} void _z_svec_init(_z_svec_t *dst, size_t element_size); _z_svec_t _z_svec_make(size_t capacity, size_t element_size); z_result_t _z_svec_copy(_z_svec_t *dst, const _z_svec_t *src, z_element_copy_f copy, size_t element_size, @@ -132,6 +135,7 @@ void _z_svec_release(_z_svec_t *v); return _z_svec_copy(dst, src, name##_elem_copy, sizeof(type), use_elem_f); \ } \ static inline name##_svec_t name##_svec_alias(const name##_svec_t *v) { return _z_svec_alias(v); } \ + static inline name##_svec_t name##_svec_alias_element(type *e) { return _z_svec_alias_element((void *)e); } \ static inline void name##_svec_move(name##_svec_t *dst, name##_svec_t *src) { _z_svec_move(dst, src); } \ static inline void name##_svec_reset(name##_svec_t *v) { _z_svec_reset(v, name##_elem_clear, sizeof(type)); } \ static inline void name##_svec_clear(name##_svec_t *v) { _z_svec_clear(v, name##_elem_clear, sizeof(type)); } \ diff --git a/src/collections/bytes.c b/src/collections/bytes.c index e4ad5c298..190b41275 100644 --- a/src/collections/bytes.c +++ b/src/collections/bytes.c @@ -63,6 +63,8 @@ _z_arc_slice_t *_z_bytes_get_slice(const _z_bytes_t *bs, size_t i) { void _z_bytes_drop(_z_bytes_t *bytes) { _z_arc_slice_svec_clear(&bytes->_slices); } +void _z_bytes_aliased_drop(_z_bytes_t *bytes) { _z_arc_slice_svec_reset(&bytes->_slices); } + void _z_bytes_free(_z_bytes_t **bs) { _z_bytes_t *ptr = *bs; diff --git a/src/protocol/definitions/message.c b/src/protocol/definitions/message.c index 0c3058e0a..3001b3372 100644 --- a/src/protocol/definitions/message.c +++ b/src/protocol/definitions/message.c @@ -23,7 +23,6 @@ void _z_msg_reply_clear(_z_msg_reply_t *msg) { _z_push_body_clear(&msg->_body); } void _z_msg_put_clear(_z_msg_put_t *msg) { - // TODO: systematically move everything so there's nothing to clear _z_bytes_drop(&msg->_payload); _z_bytes_drop(&msg->_attachment); _z_encoding_clear(&msg->_encoding); From f68e8d3bc9b0cfb336a6bfd56f50abe26633e1a9 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Fri, 8 Nov 2024 00:35:21 +0100 Subject: [PATCH 12/30] feat: add rx pool size config option --- include/zenoh-pico/config.h | 5 +++++ include/zenoh-pico/config.h.in | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/include/zenoh-pico/config.h b/include/zenoh-pico/config.h index 2449535fe..1f89b4f05 100644 --- a/include/zenoh-pico/config.h +++ b/include/zenoh-pico/config.h @@ -182,6 +182,11 @@ */ #define Z_CONFIG_FRAME_AVG_MSG_SIZE 32 +/** + * Size of the rx pool. Size according to expected number of messages per frame for best batching performance. + */ +#define Z_CONFIG_RX_POOL_SIZE 8 + /** * Default "nop" instruction */ diff --git a/include/zenoh-pico/config.h.in b/include/zenoh-pico/config.h.in index d6f43e3d3..df0a0579f 100644 --- a/include/zenoh-pico/config.h.in +++ b/include/zenoh-pico/config.h.in @@ -182,6 +182,11 @@ */ #define Z_CONFIG_FRAME_AVG_MSG_SIZE 32 +/** + * Size of the rx pool. Size according to expected number of messages per frame for best batching performance. + */ +#define Z_CONFIG_RX_POOL_SIZE 8 + /** * Default "nop" instruction */ From 4dc26c7f4a5f353659397864098754a460e2d3e1 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Fri, 8 Nov 2024 17:29:00 +0100 Subject: [PATCH 13/30] feat: use transport arc slice pool for payload decode --- include/zenoh-pico/config.h | 5 --- include/zenoh-pico/config.h.in | 5 --- include/zenoh-pico/protocol/codec/core.h | 2 +- include/zenoh-pico/protocol/codec/message.h | 8 ++--- include/zenoh-pico/protocol/codec/network.h | 8 ++--- include/zenoh-pico/protocol/codec/transport.h | 6 ++-- include/zenoh-pico/transport/transport.h | 3 ++ src/net/sample.c | 2 +- src/protocol/codec.c | 7 ++-- src/protocol/codec/message.c | 18 +++++------ src/protocol/codec/network.c | 22 ++++++------- src/protocol/codec/transport.c | 15 ++++++--- src/protocol/definitions/message.c | 4 +-- src/transport/common/rx.c | 4 ++- src/transport/multicast/read.c | 2 +- src/transport/multicast/rx.c | 6 ++-- src/transport/multicast/transport.c | 6 +++- src/transport/raweth/rx.c | 2 +- src/transport/unicast/read.c | 2 +- src/transport/unicast/rx.c | 6 ++-- src/transport/unicast/transport.c | 6 +++- tests/z_msgcodec_test.c | 32 ++++++++++++------- 22 files changed, 97 insertions(+), 74 deletions(-) diff --git a/include/zenoh-pico/config.h b/include/zenoh-pico/config.h index 1f89b4f05..2449535fe 100644 --- a/include/zenoh-pico/config.h +++ b/include/zenoh-pico/config.h @@ -182,11 +182,6 @@ */ #define Z_CONFIG_FRAME_AVG_MSG_SIZE 32 -/** - * Size of the rx pool. Size according to expected number of messages per frame for best batching performance. - */ -#define Z_CONFIG_RX_POOL_SIZE 8 - /** * Default "nop" instruction */ diff --git a/include/zenoh-pico/config.h.in b/include/zenoh-pico/config.h.in index df0a0579f..d6f43e3d3 100644 --- a/include/zenoh-pico/config.h.in +++ b/include/zenoh-pico/config.h.in @@ -182,11 +182,6 @@ */ #define Z_CONFIG_FRAME_AVG_MSG_SIZE 32 -/** - * Size of the rx pool. Size according to expected number of messages per frame for best batching performance. - */ -#define Z_CONFIG_RX_POOL_SIZE 8 - /** * Default "nop" instruction */ diff --git a/include/zenoh-pico/protocol/codec/core.h b/include/zenoh-pico/protocol/codec/core.h index c86d1b18c..16cdef966 100644 --- a/include/zenoh-pico/protocol/codec/core.h +++ b/include/zenoh-pico/protocol/codec/core.h @@ -61,7 +61,7 @@ z_result_t _z_slice_val_decode_na(_z_slice_t *bs, _z_zbuf_t *zbf); z_result_t _z_slice_encode(_z_wbuf_t *buf, const _z_slice_t *bs); z_result_t _z_slice_decode(_z_slice_t *bs, _z_zbuf_t *buf); -z_result_t _z_bytes_decode(_z_bytes_t *bs, _z_zbuf_t *zbf); +z_result_t _z_bytes_decode(_z_bytes_t *bs, _z_zbuf_t *zbf, _z_arc_slice_t *arcs); z_result_t _z_bytes_encode(_z_wbuf_t *wbf, const _z_bytes_t *bs); z_result_t _z_zbuf_read_exact(_z_zbuf_t *zbf, uint8_t *dest, size_t length); diff --git a/include/zenoh-pico/protocol/codec/message.h b/include/zenoh-pico/protocol/codec/message.h index c9bd9c039..b2d5c625c 100644 --- a/include/zenoh-pico/protocol/codec/message.h +++ b/include/zenoh-pico/protocol/codec/message.h @@ -19,19 +19,19 @@ #include "zenoh-pico/protocol/iobuf.h" z_result_t _z_push_body_encode(_z_wbuf_t *wbf, const _z_push_body_t *pshb); -z_result_t _z_push_body_decode(_z_push_body_t *body, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_push_body_decode(_z_push_body_t *body, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_query_encode(_z_wbuf_t *wbf, const _z_msg_query_t *query); z_result_t _z_query_decode(_z_msg_query_t *query, _z_zbuf_t *zbf, uint8_t header); z_result_t _z_reply_encode(_z_wbuf_t *wbf, const _z_msg_reply_t *reply); -z_result_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_err_encode(_z_wbuf_t *wbf, const _z_msg_err_t *err); -z_result_t _z_err_decode(_z_msg_err_t *err, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_err_decode(_z_msg_err_t *err, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_put_encode(_z_wbuf_t *wbf, const _z_msg_put_t *put); -z_result_t _z_put_decode(_z_msg_put_t *put, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_put_decode(_z_msg_put_t *put, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_del_encode(_z_wbuf_t *wbf, const _z_msg_del_t *del); z_result_t _z_del_decode(_z_msg_del_t *del, _z_zbuf_t *zbf, uint8_t header); diff --git a/include/zenoh-pico/protocol/codec/network.h b/include/zenoh-pico/protocol/codec/network.h index 64a5229c8..e3bce1f14 100644 --- a/include/zenoh-pico/protocol/codec/network.h +++ b/include/zenoh-pico/protocol/codec/network.h @@ -20,11 +20,11 @@ #include "zenoh-pico/protocol/definitions/network.h" #include "zenoh-pico/protocol/iobuf.h" z_result_t _z_push_encode(_z_wbuf_t *wbf, const _z_n_msg_push_t *msg); -z_result_t _z_push_decode(_z_n_msg_push_t *msg, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_push_decode(_z_n_msg_push_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_request_encode(_z_wbuf_t *wbf, const _z_n_msg_request_t *msg); -z_result_t _z_request_decode(_z_n_msg_request_t *msg, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_request_decode(_z_n_msg_request_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_response_encode(_z_wbuf_t *wbf, const _z_n_msg_response_t *msg); -z_result_t _z_response_decode(_z_n_msg_response_t *msg, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_response_decode(_z_n_msg_response_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs); z_result_t _z_response_final_encode(_z_wbuf_t *wbf, const _z_n_msg_response_final_t *msg); z_result_t _z_response_final_decode(_z_n_msg_response_final_t *msg, _z_zbuf_t *zbf, uint8_t header); z_result_t _z_declare_encode(_z_wbuf_t *wbf, const _z_n_msg_declare_t *decl); @@ -33,6 +33,6 @@ z_result_t _z_n_interest_encode(_z_wbuf_t *wbf, const _z_n_msg_interest_t *inter z_result_t _z_n_interest_decode(_z_n_msg_interest_t *interest, _z_zbuf_t *zbf, uint8_t header); z_result_t _z_network_message_encode(_z_wbuf_t *wbf, const _z_network_message_t *msg); -z_result_t _z_network_message_decode(_z_network_message_t *msg, _z_zbuf_t *zbf); +z_result_t _z_network_message_decode(_z_network_message_t *msg, _z_zbuf_t *zbf, _z_arc_slice_t *arcs); #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_CODEC_NETWORK_H */ diff --git a/include/zenoh-pico/protocol/codec/transport.h b/include/zenoh-pico/protocol/codec/transport.h index 06bb26327..490227f72 100644 --- a/include/zenoh-pico/protocol/codec/transport.h +++ b/include/zenoh-pico/protocol/codec/transport.h @@ -22,7 +22,7 @@ z_result_t _z_scouting_message_encode(_z_wbuf_t *buf, const _z_scouting_message_ z_result_t _z_scouting_message_decode(_z_scouting_message_t *msg, _z_zbuf_t *buf); z_result_t _z_transport_message_encode(_z_wbuf_t *buf, const _z_transport_message_t *msg); -z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *buf); +z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *buf, _z_arc_slice_svec_t *arc_pool); z_result_t _z_join_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_join_t *msg); z_result_t _z_join_decode(_z_t_msg_join_t *msg, _z_zbuf_t *zbf, uint8_t header); @@ -40,11 +40,9 @@ z_result_t _z_keep_alive_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_k z_result_t _z_keep_alive_decode(_z_t_msg_keep_alive_t *msg, _z_zbuf_t *zbf, uint8_t header); z_result_t _z_frame_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_frame_t *msg); -z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header); +z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_svec_t *arc_pool); z_result_t _z_fragment_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_fragment_t *msg); z_result_t _z_fragment_decode(_z_t_msg_fragment_t *msg, _z_zbuf_t *zbf, uint8_t header); -z_result_t _z_transport_message_encode(_z_wbuf_t *wbf, const _z_transport_message_t *msg); -z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *zbf); #endif /* INCLUDE_ZENOH_PICO_PROTOCOL_CODEC_TRANSPORT_H */ diff --git a/include/zenoh-pico/transport/transport.h b/include/zenoh-pico/transport/transport.h index 678bf2022..91291a06d 100644 --- a/include/zenoh-pico/transport/transport.h +++ b/include/zenoh-pico/transport/transport.h @@ -69,6 +69,8 @@ _z_transport_peer_entry_list_t *_z_transport_peer_entry_list_insert(_z_transport // Forward type declaration to avoid cyclical include typedef struct _z_session_rc_t _z_session_rc_ref_t; +#define _Z_RES_POOL_INIT_SIZE 8 // Arbitrary small value + typedef struct { _z_session_rc_ref_t *_session; _z_link_t _link; @@ -79,6 +81,7 @@ typedef struct { _z_zint_t _sn_res; _z_zint_t _sn_tx_reliable; _z_zint_t _sn_tx_best_effort; + _z_arc_slice_svec_t _arc_pool; volatile _z_zint_t _lease; volatile bool _transmitted; #if Z_FEATURE_MULTI_THREAD == 1 diff --git a/src/net/sample.c b/src/net/sample.c index eeec068e3..2cfac75d0 100644 --- a/src/net/sample.c +++ b/src/net/sample.c @@ -26,8 +26,8 @@ void _z_sample_move(_z_sample_t *dst, _z_sample_t *src) { void _z_sample_clear(_z_sample_t *sample) { _z_keyexpr_clear(&sample->keyexpr); - _z_bytes_drop(&sample->payload); _z_encoding_clear(&sample->encoding); + _z_bytes_aliased_drop(&sample->payload); _z_bytes_drop(&sample->attachment); } diff --git a/src/protocol/codec.c b/src/protocol/codec.c index ed903d676..eea67422e 100644 --- a/src/protocol/codec.c +++ b/src/protocol/codec.c @@ -295,15 +295,16 @@ z_result_t _z_slice_val_decode(_z_slice_t *bs, _z_zbuf_t *zbf) { return _z_slice z_result_t _z_slice_decode(_z_slice_t *bs, _z_zbuf_t *zbf) { return _z_slice_decode_na(bs, zbf); } -z_result_t _z_bytes_decode(_z_bytes_t *bs, _z_zbuf_t *zbf) { +z_result_t _z_bytes_decode(_z_bytes_t *bs, _z_zbuf_t *zbf, _z_arc_slice_t *arcs) { // Decode slice _z_slice_t s; _Z_RETURN_IF_ERR(_z_slice_decode(&s, zbf)); // Calc offset size_t offset = _z_ptr_u8_diff(s.start, _Z_RC_IN_VAL(&zbf->_slice)->start); // Get ownership of subslice - _z_arc_slice_t arcs = _z_arc_slice_wrap_slice_rc(&zbf->_slice, offset, s.len); - return _z_bytes_append_slice(bs, &arcs); + *arcs = _z_arc_slice_wrap_slice_rc(&zbf->_slice, offset, s.len); + _z_bytes_alias_arc_slice(bs, arcs); + return _Z_RES_OK; } z_result_t _z_bytes_encode_val(_z_wbuf_t *wbf, const _z_bytes_t *bs) { diff --git a/src/protocol/codec/message.c b/src/protocol/codec/message.c index 35c8fa826..c11c62e46 100644 --- a/src/protocol/codec/message.c +++ b/src/protocol/codec/message.c @@ -327,7 +327,7 @@ z_result_t _z_push_body_decode_extensions(_z_msg_ext_t *extension, void *ctx) { return ret; } -z_result_t _z_push_body_decode(_z_push_body_t *pshb, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_push_body_decode(_z_push_body_t *pshb, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs) { z_result_t ret = _Z_RES_OK; switch (_Z_MID(header)) { case _Z_MID_Z_PUT: { @@ -342,7 +342,7 @@ z_result_t _z_push_body_decode(_z_push_body_t *pshb, _z_zbuf_t *zbf, uint8_t hea _Z_RETURN_IF_ERR(_z_msg_ext_decode_iter(zbf, _z_push_body_decode_extensions, pshb)); } if (ret == _Z_RES_OK) { - _Z_RETURN_IF_ERR(_z_bytes_decode(&pshb->_body._put._payload, zbf)); + _Z_RETURN_IF_ERR(_z_bytes_decode(&pshb->_body._put._payload, zbf, arcs)); } break; } @@ -367,10 +367,10 @@ z_result_t _z_put_encode(_z_wbuf_t *wbf, const _z_msg_put_t *put) { _z_push_body_t body = {._is_put = true, ._body = {._put = *put}}; return _z_push_body_encode(wbf, &body); } -z_result_t _z_put_decode(_z_msg_put_t *put, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_put_decode(_z_msg_put_t *put, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs) { assert(_Z_MID(header) == _Z_MID_Z_PUT); _z_push_body_t body = {._is_put = true, ._body = {._put = *put}}; - z_result_t ret = _z_push_body_decode(&body, zbf, header); + z_result_t ret = _z_push_body_decode(&body, zbf, header, arcs); *put = body._body._put; return ret; } @@ -382,7 +382,7 @@ z_result_t _z_del_encode(_z_wbuf_t *wbf, const _z_msg_del_t *del) { z_result_t _z_del_decode(_z_msg_del_t *del, _z_zbuf_t *zbf, uint8_t header) { assert(_Z_MID(header) == _Z_MID_Z_DEL); _z_push_body_t body = {._is_put = false, ._body = {._del = *del}}; - z_result_t ret = _z_push_body_decode(&body, zbf, header); + z_result_t ret = _z_push_body_decode(&body, zbf, header, NULL); *del = body._body._del; return ret; } @@ -509,7 +509,7 @@ z_result_t _z_reply_decode_extension(_z_msg_ext_t *extension, void *ctx) { } return ret; } -z_result_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs) { if (_Z_HAS_FLAG(header, _Z_FLAG_Z_R_C)) { _Z_RETURN_IF_ERR(_z_uint8_decode((uint8_t *)&reply->_consolidation, zbf)); } else { @@ -520,7 +520,7 @@ z_result_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header } uint8_t put_header = 0; _Z_RETURN_IF_ERR(_z_uint8_decode(&put_header, zbf)); - _Z_RETURN_IF_ERR(_z_push_body_decode(&reply->_body, zbf, put_header)); + _Z_RETURN_IF_ERR(_z_push_body_decode(&reply->_body, zbf, put_header, arcs)); return _Z_RES_OK; } @@ -569,14 +569,14 @@ z_result_t _z_err_decode_extension(_z_msg_ext_t *extension, void *ctx) { } return ret; } -z_result_t _z_err_decode(_z_msg_err_t *err, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_err_decode(_z_msg_err_t *err, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs) { if (_Z_HAS_FLAG(header, _Z_FLAG_Z_E_E)) { _Z_RETURN_IF_ERR(_z_encoding_decode(&err->_encoding, zbf)); } if (_Z_HAS_FLAG(header, _Z_FLAG_Z_Z)) { _Z_RETURN_IF_ERR(_z_msg_ext_decode_iter(zbf, _z_err_decode_extension, err)); } - _Z_RETURN_IF_ERR(_z_bytes_decode(&err->_payload, zbf)); + _Z_RETURN_IF_ERR(_z_bytes_decode(&err->_payload, zbf, arcs)); return _Z_RES_OK; } diff --git a/src/protocol/codec/network.c b/src/protocol/codec/network.c index de453c9ae..44cf9cde9 100644 --- a/src/protocol/codec/network.c +++ b/src/protocol/codec/network.c @@ -92,7 +92,7 @@ z_result_t _z_push_decode_ext_cb(_z_msg_ext_t *extension, void *ctx) { return ret; } -z_result_t _z_push_decode(_z_n_msg_push_t *msg, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_push_decode(_z_n_msg_push_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs) { z_result_t ret = _Z_RES_OK; msg->_qos = _Z_N_QOS_DEFAULT; ret |= _z_keyexpr_decode(&msg->_key, zbf, _Z_HAS_FLAG(header, _Z_FLAG_N_PUSH_N)); @@ -104,7 +104,7 @@ z_result_t _z_push_decode(_z_n_msg_push_t *msg, _z_zbuf_t *zbf, uint8_t header) if (ret == _Z_RES_OK) { uint8_t msgheader; _Z_RETURN_IF_ERR(_z_uint8_decode(&msgheader, zbf)); - _Z_RETURN_IF_ERR(_z_push_body_decode(&msg->_body, zbf, msgheader)); + _Z_RETURN_IF_ERR(_z_push_body_decode(&msg->_body, zbf, msgheader, arcs)); } return ret; @@ -206,7 +206,7 @@ z_result_t _z_request_decode_extensions(_z_msg_ext_t *extension, void *ctx) { } return _Z_RES_OK; } -z_result_t _z_request_decode(_z_n_msg_request_t *msg, _z_zbuf_t *zbf, const uint8_t header) { +z_result_t _z_request_decode(_z_n_msg_request_t *msg, _z_zbuf_t *zbf, const uint8_t header, _z_arc_slice_t *arcs) { msg->_ext_qos = _Z_N_QOS_DEFAULT; _Z_RETURN_IF_ERR(_z_zsize_decode(&msg->_rid, zbf)); _Z_RETURN_IF_ERR(_z_keyexpr_decode(&msg->_key, zbf, _Z_HAS_FLAG(header, _Z_FLAG_N_REQUEST_N))); @@ -224,7 +224,7 @@ z_result_t _z_request_decode(_z_n_msg_request_t *msg, _z_zbuf_t *zbf, const uint } break; case _Z_MID_Z_PUT: { msg->_tag = _Z_REQUEST_PUT; - _Z_RETURN_IF_ERR(_z_put_decode(&msg->_body._put, zbf, zheader)); + _Z_RETURN_IF_ERR(_z_put_decode(&msg->_body._put, zbf, zheader, arcs)); } break; case _Z_MID_Z_DEL: { msg->_tag = _Z_REQUEST_DEL; @@ -334,7 +334,7 @@ z_result_t _z_response_decode_extension(_z_msg_ext_t *extension, void *ctx) { return ret; } -z_result_t _z_response_decode(_z_n_msg_response_t *msg, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_response_decode(_z_n_msg_response_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_t *arcs) { _Z_DEBUG("Decoding _Z_MID_N_RESPONSE"); msg->_ext_qos = _Z_N_QOS_DEFAULT; z_result_t ret = _Z_RES_OK; @@ -352,12 +352,12 @@ z_result_t _z_response_decode(_z_n_msg_response_t *msg, _z_zbuf_t *zbf, uint8_t switch (_Z_MID(inner_header)) { case _Z_MID_Z_REPLY: { msg->_tag = _Z_RESPONSE_BODY_REPLY; - ret = _z_reply_decode(&msg->_body._reply, zbf, inner_header); + ret = _z_reply_decode(&msg->_body._reply, zbf, inner_header, arcs); break; } case _Z_MID_Z_ERR: { msg->_tag = _Z_RESPONSE_BODY_ERR; - ret = _z_err_decode(&msg->_body._err, zbf, inner_header); + ret = _z_err_decode(&msg->_body._err, zbf, inner_header, arcs); break; } default: { @@ -513,7 +513,7 @@ z_result_t _z_network_message_encode(_z_wbuf_t *wbf, const _z_network_message_t return _Z_ERR_GENERIC; } } -z_result_t _z_network_message_decode(_z_network_message_t *msg, _z_zbuf_t *zbf) { +z_result_t _z_network_message_decode(_z_network_message_t *msg, _z_zbuf_t *zbf, _z_arc_slice_t *arcs) { uint8_t header; _Z_RETURN_IF_ERR(_z_uint8_decode(&header, zbf)); switch (_Z_MID(header)) { @@ -523,15 +523,15 @@ z_result_t _z_network_message_decode(_z_network_message_t *msg, _z_zbuf_t *zbf) } break; case _Z_MID_N_PUSH: { msg->_tag = _Z_N_PUSH; - return _z_push_decode(&msg->_body._push, zbf, header); + return _z_push_decode(&msg->_body._push, zbf, header, arcs); } break; case _Z_MID_N_REQUEST: { msg->_tag = _Z_N_REQUEST; - return _z_request_decode(&msg->_body._request, zbf, header); + return _z_request_decode(&msg->_body._request, zbf, header, arcs); } break; case _Z_MID_N_RESPONSE: { msg->_tag = _Z_N_RESPONSE; - return _z_response_decode(&msg->_body._response, zbf, header); + return _z_response_decode(&msg->_body._response, zbf, header, arcs); } break; case _Z_MID_N_RESPONSE_FINAL: { msg->_tag = _Z_N_RESPONSE_FINAL; diff --git a/src/protocol/codec/transport.c b/src/protocol/codec/transport.c index 4c0e01bd9..bf6c0aac3 100644 --- a/src/protocol/codec/transport.c +++ b/src/protocol/codec/transport.c @@ -352,7 +352,7 @@ z_result_t _z_frame_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_frame_ return ret; } -z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header) { +z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_svec_t *arc_pool) { z_result_t ret = _Z_RES_OK; *msg = (_z_t_msg_frame_t){0}; @@ -374,10 +374,17 @@ z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header _Z_RETURN_IF_ERR(_z_network_message_svec_expand(&msg->_messages)); _z_network_message_svec_init(&msg->_messages); } + // Expand arc pool if needed + if (msg_idx >= arc_pool->_capacity) { + _Z_RETURN_IF_ERR(_z_arc_slice_svec_expand(arc_pool)); + } // Mark the reading position of the iobfer size_t r_pos = _z_zbuf_get_rpos(zbf); + // Retrieve storage in svecs _z_network_message_t *nm = _z_network_message_svec_get_mut(&msg->_messages, msg_idx); - ret = _z_network_message_decode(nm, zbf); + _z_arc_slice_t *arcs = _z_arc_slice_svec_get_mut(arc_pool, msg_idx); + // Decode message + ret = _z_network_message_decode(nm, zbf, arcs); if (ret != _Z_RES_OK) { _z_network_message_svec_clear(&msg->_messages); _z_zbuf_set_rpos(zbf, r_pos); // Restore the reading position of the iobfer @@ -493,7 +500,7 @@ z_result_t _z_transport_message_encode(_z_wbuf_t *wbf, const _z_transport_messag return ret; } -z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *zbf) { +z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *zbf, _z_arc_slice_svec_t *arc_pool) { z_result_t ret = _Z_RES_OK; ret |= _z_uint8_decode(&msg->_header, zbf); // Decode the header @@ -501,7 +508,7 @@ z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *z uint8_t mid = _Z_MID(msg->_header); switch (mid) { case _Z_MID_T_FRAME: { - ret |= _z_frame_decode(&msg->_body._frame, zbf, msg->_header); + ret |= _z_frame_decode(&msg->_body._frame, zbf, msg->_header, arc_pool); } break; case _Z_MID_T_FRAGMENT: { ret |= _z_fragment_decode(&msg->_body._fragment, zbf, msg->_header); diff --git a/src/protocol/definitions/message.c b/src/protocol/definitions/message.c index 3001b3372..e8f967e62 100644 --- a/src/protocol/definitions/message.c +++ b/src/protocol/definitions/message.c @@ -23,7 +23,7 @@ void _z_msg_reply_clear(_z_msg_reply_t *msg) { _z_push_body_clear(&msg->_body); } void _z_msg_put_clear(_z_msg_put_t *msg) { - _z_bytes_drop(&msg->_payload); + _z_bytes_aliased_drop(&msg->_payload); _z_bytes_drop(&msg->_attachment); _z_encoding_clear(&msg->_encoding); _z_timestamp_clear(&msg->_commons._timestamp); @@ -44,5 +44,5 @@ void _z_msg_query_clear(_z_msg_query_t *msg) { } void _z_msg_err_clear(_z_msg_err_t *err) { _z_encoding_clear(&err->_encoding); - _z_bytes_drop(&err->_payload); + _z_bytes_aliased_drop(&err->_payload); } diff --git a/src/transport/common/rx.c b/src/transport/common/rx.c index 5c5c68073..d6545f5c8 100644 --- a/src/transport/common/rx.c +++ b/src/transport/common/rx.c @@ -72,10 +72,12 @@ z_result_t _z_link_recv_t_msg(_z_transport_message_t *t_msg, const _z_link_t *zl } if (ret == _Z_RES_OK) { _z_transport_message_t l_t_msg; - ret = _z_transport_message_decode(&l_t_msg, &zbf); + _z_arc_slice_svec_t arc_pool = _z_arc_slice_svec_make(1); + ret = _z_transport_message_decode(&l_t_msg, &zbf, &arc_pool); if (ret == _Z_RES_OK) { _z_t_msg_copy(t_msg, &l_t_msg); } + _z_arc_slice_svec_clear(&arc_pool); } _z_zbuf_clear(&zbf); diff --git a/src/transport/multicast/read.c b/src/transport/multicast/read.c index ad7a1eb1c..a5a8bca02 100644 --- a/src/transport/multicast/read.c +++ b/src/transport/multicast/read.c @@ -107,7 +107,7 @@ void *_zp_multicast_read_task(void *ztm_arg) { while (_z_zbuf_len(&zbuf) > 0) { // Decode one session message _z_transport_message_t t_msg; - z_result_t ret = _z_transport_message_decode(&t_msg, &zbuf); + z_result_t ret = _z_transport_message_decode(&t_msg, &zbuf, &ztm->_common._arc_pool); if (ret == _Z_RES_OK) { ret = _z_multicast_handle_transport_message(ztm, &t_msg, &addr); diff --git a/src/transport/multicast/rx.c b/src/transport/multicast/rx.c index c1f438c38..12c439906 100644 --- a/src/transport/multicast/rx.c +++ b/src/transport/multicast/rx.c @@ -77,7 +77,7 @@ static z_result_t _z_multicast_recv_t_msg_na(_z_transport_multicast_t *ztm, _z_t if (ret == _Z_RES_OK) { _Z_DEBUG(">> \t transport_message_decode: %ju", (uintmax_t)_z_zbuf_len(&ztm->_common._zbuf)); - ret = _z_transport_message_decode(t_msg, &ztm->_common._zbuf); + ret = _z_transport_message_decode(t_msg, &ztm->_common._zbuf, &ztm->_common._arc_pool); } _z_transport_rx_mutex_unlock(&ztm->_common); return ret; @@ -240,7 +240,9 @@ z_result_t _z_multicast_handle_transport_message(_z_transport_multicast_t *ztm, } // Decode message _z_zenoh_message_t zm = {0}; - ret = _z_network_message_decode(&zm, &zbf); + assert(ztm->_common._arc_pool._capacity >= 1); + _z_arc_slice_t *arcs = _z_arc_slice_svec_get_mut(&ztm->_common._arc_pool, 0); + ret = _z_network_message_decode(&zm, &zbf, arcs); zm._reliability = tmsg_reliability; if (ret == _Z_RES_OK) { uint16_t mapping = entry->_peer_id; diff --git a/src/transport/multicast/transport.c b/src/transport/multicast/transport.c index 776d007fb..5ba3bca4c 100644 --- a/src/transport/multicast/transport.c +++ b/src/transport/multicast/transport.c @@ -81,8 +81,11 @@ z_result_t _z_multicast_transport_create(_z_transport_t *zt, _z_link_t *zl, ztm->_common._wbuf = _z_wbuf_make(mtu, false); ztm->_common._zbuf = _z_zbuf_make(Z_BATCH_MULTICAST_SIZE); + // Initialize rx pool + ztm->_common._arc_pool = _z_arc_slice_svec_make(_Z_RES_POOL_INIT_SIZE); + // Clean up the buffers if one of them failed to be allocated - if ((_z_wbuf_capacity(&ztm->_common._wbuf) != mtu) || + if ((ztm->_common._arc_pool._capacity == 0) || (_z_wbuf_capacity(&ztm->_common._wbuf) != mtu) || (_z_zbuf_capacity(&ztm->_common._zbuf) != Z_BATCH_MULTICAST_SIZE)) { ret = _Z_ERR_SYSTEM_OUT_OF_MEMORY; _Z_ERROR("Not enough memory to allocate transport tx rx buffers!"); @@ -209,6 +212,7 @@ void _z_multicast_transport_clear(_z_transport_t *zt) { // Clean up the buffers _z_wbuf_clear(&ztm->_common._wbuf); _z_zbuf_clear(&ztm->_common._zbuf); + _z_arc_slice_svec_release(&ztm->_common._arc_pool); // Clean up peer list _z_transport_peer_entry_list_free(&ztm->_peers); diff --git a/src/transport/raweth/rx.c b/src/transport/raweth/rx.c index 389b57c70..613405ed1 100644 --- a/src/transport/raweth/rx.c +++ b/src/transport/raweth/rx.c @@ -100,7 +100,7 @@ z_result_t _z_raweth_recv_t_msg_na(_z_transport_multicast_t *ztm, _z_transport_m // Decode message if (ret == _Z_RES_OK) { _Z_DEBUG(">> \t transport_message_decode: %ju", (uintmax_t)_z_zbuf_len(&ztm->_common._zbuf)); - ret = _z_transport_message_decode(t_msg, &ztm->_common._zbuf); + ret = _z_transport_message_decode(t_msg, &ztm->_common._zbuf, &ztm->_common._arc_pool); } _z_transport_rx_mutex_unlock(&ztm->_common); return ret; diff --git a/src/transport/unicast/read.c b/src/transport/unicast/read.c index ab347251d..acc1f70e6 100644 --- a/src/transport/unicast/read.c +++ b/src/transport/unicast/read.c @@ -102,7 +102,7 @@ void *_zp_unicast_read_task(void *ztu_arg) { while (_z_zbuf_len(&zbuf) > 0) { // Decode one session message _z_transport_message_t t_msg; - z_result_t ret = _z_transport_message_decode(&t_msg, &zbuf); + z_result_t ret = _z_transport_message_decode(&t_msg, &zbuf, &ztu->_common._arc_pool); if (ret == _Z_RES_OK) { ret = _z_unicast_handle_transport_message(ztu, &t_msg); diff --git a/src/transport/unicast/rx.c b/src/transport/unicast/rx.c index 1d30e988f..a000b1624 100644 --- a/src/transport/unicast/rx.c +++ b/src/transport/unicast/rx.c @@ -75,7 +75,7 @@ z_result_t _z_unicast_recv_t_msg_na(_z_transport_unicast_t *ztu, _z_transport_me if (ret == _Z_RES_OK) { _Z_DEBUG(">> \t transport_message_decode"); - ret = _z_transport_message_decode(t_msg, &ztu->_common._zbuf); + ret = _z_transport_message_decode(t_msg, &ztu->_common._zbuf, &ztu->_common._arc_pool); // Mark the session that we have received data if (ret == _Z_RES_OK) { @@ -194,7 +194,9 @@ z_result_t _z_unicast_handle_transport_message(_z_transport_unicast_t *ztu, _z_t } // Decode message _z_zenoh_message_t zm = {0}; - ret = _z_network_message_decode(&zm, &zbf); + assert(ztu->_common._arc_pool._capacity >= 1); + _z_arc_slice_t *arcs = _z_arc_slice_svec_get_mut(&ztu->_common._arc_pool, 0); + ret = _z_network_message_decode(&zm, &zbf, arcs); zm._reliability = tmsg_reliability; if (ret == _Z_RES_OK) { _z_handle_network_message(ztu->_common._session, &zm, _Z_KEYEXPR_MAPPING_UNKNOWN_REMOTE); diff --git a/src/transport/unicast/transport.c b/src/transport/unicast/transport.c index 251eee96f..46d376cff 100644 --- a/src/transport/unicast/transport.c +++ b/src/transport/unicast/transport.c @@ -64,8 +64,11 @@ z_result_t _z_unicast_transport_create(_z_transport_t *zt, _z_link_t *zl, ztu->_common._wbuf = _z_wbuf_make(wbuf_size, false); ztu->_common._zbuf = _z_zbuf_make(zbuf_size); + // Initialize rx pool + ztu->_common._arc_pool = _z_arc_slice_svec_make(_Z_RES_POOL_INIT_SIZE); + // Clean up the buffers if one of them failed to be allocated - if ((_z_wbuf_capacity(&ztu->_common._wbuf) != wbuf_size) || + if ((ztu->_common._arc_pool._capacity == 0) || (_z_wbuf_capacity(&ztu->_common._wbuf) != wbuf_size) || (_z_zbuf_capacity(&ztu->_common._zbuf) != zbuf_size)) { ret = _Z_ERR_SYSTEM_OUT_OF_MEMORY; _Z_ERROR("Not enough memory to allocate transport tx rx buffers!"); @@ -339,6 +342,7 @@ void _z_unicast_transport_clear(_z_transport_t *zt) { // Clean up the buffers _z_wbuf_clear(&ztu->_common._wbuf); _z_zbuf_clear(&ztu->_common._zbuf); + _z_arc_slice_svec_release(&ztu->_common._arc_pool); #if Z_FEATURE_FRAGMENTATION == 1 _z_wbuf_clear(&ztu->_dbuf_reliable); _z_wbuf_clear(&ztu->_dbuf_best_effort); diff --git a/tests/z_msgcodec_test.c b/tests/z_msgcodec_test.c index d717b0bfb..2dc50c5a6 100644 --- a/tests/z_msgcodec_test.c +++ b/tests/z_msgcodec_test.c @@ -555,7 +555,8 @@ void payload_field(void) { _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); _z_bytes_t d_pld = _z_bytes_null(); - res = _z_bytes_decode(&d_pld, &zbf); + _z_arc_slice_t arcs = {0}; + res = _z_bytes_decode(&d_pld, &zbf, &arcs); assert(res == _Z_RES_OK); printf(" "); assert_eq_bytes(&e_pld, &d_pld); @@ -563,7 +564,7 @@ void payload_field(void) { // Free _z_bytes_drop(&e_pld); - _z_bytes_drop(&d_pld); + _z_bytes_aliased_drop(&d_pld); _z_zbuf_clear(&zbf); _z_wbuf_clear(&wbf); } @@ -1068,7 +1069,8 @@ void declare_message(void) { // Decode _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); _z_network_message_t d_dcl = {0}; - res = _z_network_message_decode(&d_dcl, &zbf); + _z_arc_slice_t arcs = {0}; + res = _z_network_message_decode(&d_dcl, &zbf, &arcs); assert(res == _Z_RES_OK); assert_eq_declare_message(&n_msg._body._declare, &d_dcl._body._declare); @@ -1202,8 +1204,9 @@ void push_body_message(void) { // Decode _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); _z_push_body_t d_da = {0}; + _z_arc_slice_t arcs = {0}; uint8_t header = _z_zbuf_read(&zbf); - res = _z_push_body_decode(&d_da, &zbf, header); + res = _z_push_body_decode(&d_da, &zbf, header, &arcs); assert(res == _Z_RES_OK); assert_eq_push_body(&e_da, &d_da); @@ -1269,9 +1272,10 @@ void err_message(void) { _z_msg_err_t expected = gen_err(); assert(_z_err_encode(&wbf, &expected) == _Z_RES_OK); _z_msg_err_t decoded = {0}; + _z_arc_slice_t arcs = {0}; _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); uint8_t header = _z_zbuf_read(&zbf); - assert(_Z_RES_OK == _z_err_decode(&decoded, &zbf, header)); + assert(_Z_RES_OK == _z_err_decode(&decoded, &zbf, header, &arcs)); assert_eq_err(&expected, &decoded); _z_msg_err_clear(&decoded); _z_msg_err_clear(&expected); @@ -1297,9 +1301,10 @@ void reply_message(void) { _z_msg_reply_t expected = gen_reply(); assert(_z_reply_encode(&wbf, &expected) == _Z_RES_OK); _z_msg_reply_t decoded = {0}; + _z_arc_slice_t arcs = {0}; _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); uint8_t header = _z_zbuf_read(&zbf); - assert(_Z_RES_OK == _z_reply_decode(&decoded, &zbf, header)); + assert(_Z_RES_OK == _z_reply_decode(&decoded, &zbf, header, &arcs)); assert_eq_reply(&expected, &decoded); _z_msg_reply_clear(&decoded); _z_msg_reply_clear(&expected); @@ -1329,9 +1334,10 @@ void push_message(void) { _z_n_msg_push_t expected = gen_push(); assert(_z_push_encode(&wbf, &expected) == _Z_RES_OK); _z_n_msg_push_t decoded = {0}; + _z_arc_slice_t arcs = {0}; _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); uint8_t header = _z_zbuf_read(&zbf); - assert(_Z_RES_OK == _z_push_decode(&decoded, &zbf, header)); + assert(_Z_RES_OK == _z_push_decode(&decoded, &zbf, header, &arcs)); assert_eq_push(&expected, &decoded); _z_n_msg_push_clear(&decoded); _z_n_msg_push_clear(&expected); @@ -1399,9 +1405,10 @@ void request_message(void) { _z_n_msg_request_t expected = gen_request(); assert(_z_request_encode(&wbf, &expected) == _Z_RES_OK); _z_n_msg_request_t decoded = {0}; + _z_arc_slice_t arcs = {0}; _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); uint8_t header = _z_zbuf_read(&zbf); - z_result_t ret = _z_request_decode(&decoded, &zbf, header); + z_result_t ret = _z_request_decode(&decoded, &zbf, header, &arcs); assert(_Z_RES_OK == ret); assert_eq_request(&expected, &decoded); _z_n_msg_request_clear(&decoded); @@ -1457,9 +1464,10 @@ void response_message(void) { _z_n_msg_response_t expected = gen_response(); assert(_z_response_encode(&wbf, &expected) == _Z_RES_OK); _z_n_msg_response_t decoded = {0}; + _z_arc_slice_t arcs = {0}; _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); uint8_t header = _z_zbuf_read(&zbf); - z_result_t ret = _z_response_decode(&decoded, &zbf, header); + z_result_t ret = _z_response_decode(&decoded, &zbf, header, &arcs); assert(_Z_RES_OK == ret); assert_eq_response(&expected, &decoded); _z_n_msg_response_clear(&decoded); @@ -1715,8 +1723,9 @@ void frame_message(void) { _z_transport_message_t expected = gen_frame(); assert(_z_frame_encode(&wbf, expected._header, &expected._body._frame) == _Z_RES_OK); _z_t_msg_frame_t decoded = {0}; + _z_arc_slice_svec_t arcs = _z_arc_slice_svec_make(1); _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); - z_result_t ret = _z_frame_decode(&decoded, &zbf, expected._header); + z_result_t ret = _z_frame_decode(&decoded, &zbf, expected._header, &arcs); assert(_Z_RES_OK == ret); assert_eq_frame(&expected._body._frame, &decoded); _z_t_msg_frame_clear(&decoded); @@ -1808,8 +1817,9 @@ void transport_message(void) { _z_transport_message_t expected = gen_transport(); assert(_z_transport_message_encode(&wbf, &expected) == _Z_RES_OK); _z_transport_message_t decoded = {0}; + _z_arc_slice_svec_t arcs = _z_arc_slice_svec_make(1); _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); - z_result_t ret = _z_transport_message_decode(&decoded, &zbf); + z_result_t ret = _z_transport_message_decode(&decoded, &zbf, &arcs); assert(_Z_RES_OK == ret); assert_eq_transport(&expected, &decoded); _z_t_msg_clear(&decoded); From e651026211ba15d9c74956d91d54b538b347833e Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Fri, 8 Nov 2024 19:12:12 +0100 Subject: [PATCH 14/30] feat: n msg svec is now a transport resource pool --- include/zenoh-pico/config.h | 5 --- include/zenoh-pico/config.h.in | 5 --- include/zenoh-pico/protocol/codec/transport.h | 6 ++- include/zenoh-pico/transport/transport.h | 1 + src/protocol/codec/transport.c | 38 +++++++++---------- src/transport/common/rx.c | 4 +- src/transport/multicast/read.c | 3 +- src/transport/multicast/rx.c | 2 +- src/transport/multicast/transport.c | 7 +++- src/transport/raweth/rx.c | 2 +- src/transport/unicast/read.c | 3 +- src/transport/unicast/rx.c | 2 +- src/transport/unicast/transport.c | 7 +++- tests/z_msgcodec_test.c | 6 ++- 14 files changed, 46 insertions(+), 45 deletions(-) diff --git a/include/zenoh-pico/config.h b/include/zenoh-pico/config.h index 2449535fe..5b946505f 100644 --- a/include/zenoh-pico/config.h +++ b/include/zenoh-pico/config.h @@ -177,11 +177,6 @@ */ #define Z_GET_TIMEOUT_DEFAULT 10000 -/** - * Average size of a frame message (bytes). Used to evaluate initial decoding frame size. - */ -#define Z_CONFIG_FRAME_AVG_MSG_SIZE 32 - /** * Default "nop" instruction */ diff --git a/include/zenoh-pico/config.h.in b/include/zenoh-pico/config.h.in index d6f43e3d3..4e75ac0cb 100644 --- a/include/zenoh-pico/config.h.in +++ b/include/zenoh-pico/config.h.in @@ -177,11 +177,6 @@ */ #define Z_GET_TIMEOUT_DEFAULT 10000 -/** - * Average size of a frame message (bytes). Used to evaluate initial decoding frame size. - */ -#define Z_CONFIG_FRAME_AVG_MSG_SIZE 32 - /** * Default "nop" instruction */ diff --git a/include/zenoh-pico/protocol/codec/transport.h b/include/zenoh-pico/protocol/codec/transport.h index 490227f72..4a83857b1 100644 --- a/include/zenoh-pico/protocol/codec/transport.h +++ b/include/zenoh-pico/protocol/codec/transport.h @@ -22,7 +22,8 @@ z_result_t _z_scouting_message_encode(_z_wbuf_t *buf, const _z_scouting_message_ z_result_t _z_scouting_message_decode(_z_scouting_message_t *msg, _z_zbuf_t *buf); z_result_t _z_transport_message_encode(_z_wbuf_t *buf, const _z_transport_message_t *msg); -z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *buf, _z_arc_slice_svec_t *arc_pool); +z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *buf, _z_arc_slice_svec_t *arc_pool, + _z_network_message_svec_t *msg_pool); z_result_t _z_join_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_join_t *msg); z_result_t _z_join_decode(_z_t_msg_join_t *msg, _z_zbuf_t *zbf, uint8_t header); @@ -40,7 +41,8 @@ z_result_t _z_keep_alive_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_k z_result_t _z_keep_alive_decode(_z_t_msg_keep_alive_t *msg, _z_zbuf_t *zbf, uint8_t header); z_result_t _z_frame_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_frame_t *msg); -z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_svec_t *arc_pool); +z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_svec_t *arc_pool, + _z_network_message_svec_t *msg_pool); z_result_t _z_fragment_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_fragment_t *msg); z_result_t _z_fragment_decode(_z_t_msg_fragment_t *msg, _z_zbuf_t *zbf, uint8_t header); diff --git a/include/zenoh-pico/transport/transport.h b/include/zenoh-pico/transport/transport.h index 91291a06d..e78de9366 100644 --- a/include/zenoh-pico/transport/transport.h +++ b/include/zenoh-pico/transport/transport.h @@ -82,6 +82,7 @@ typedef struct { _z_zint_t _sn_tx_reliable; _z_zint_t _sn_tx_best_effort; _z_arc_slice_svec_t _arc_pool; + _z_network_message_svec_t _msg_pool; volatile _z_zint_t _lease; volatile bool _transmitted; #if Z_FEATURE_MULTI_THREAD == 1 diff --git a/src/protocol/codec/transport.c b/src/protocol/codec/transport.c index bf6c0aac3..a3d8c2c29 100644 --- a/src/protocol/codec/transport.c +++ b/src/protocol/codec/transport.c @@ -28,10 +28,6 @@ #include "zenoh-pico/utils/logging.h" #include "zenoh-pico/utils/result.h" -#define _Z_FRAME_VEC_BASE_SIZE 8 // Abritrary small value -#define _Z_FRAME_VEC_SIZE_FROM_ZBUF_LEN(len) \ - (_Z_FRAME_VEC_BASE_SIZE + (len) / Z_CONFIG_FRAME_AVG_MSG_SIZE) // Approximate number of messages in frame - uint8_t _z_whatami_to_uint8(z_whatami_t whatami) { return (whatami >> 1) & 0x03; // get set bit index; only first 3 bits can be set } @@ -352,7 +348,8 @@ z_result_t _z_frame_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_frame_ return ret; } -z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_svec_t *arc_pool) { +z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_svec_t *arc_pool, + _z_network_message_svec_t *msg_pool) { z_result_t ret = _Z_RES_OK; *msg = (_z_t_msg_frame_t){0}; @@ -360,19 +357,15 @@ z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header if (_Z_HAS_FLAG(header, _Z_FLAG_T_Z)) { _Z_RETURN_IF_ERR(_z_msg_ext_skip_non_mandatories(zbf, 0x04)); } - // Create message vector - size_t var_size = _Z_FRAME_VEC_SIZE_FROM_ZBUF_LEN(_z_zbuf_len(zbf)); - msg->_messages = _z_network_message_svec_make(var_size); - if (msg->_messages._capacity == 0) { - return _Z_ERR_SYSTEM_OUT_OF_MEMORY; - } - _z_network_message_svec_init(&msg->_messages); + // Init message vector + msg_pool->_len = 0; + _z_network_message_svec_init(msg_pool); size_t msg_idx = 0; while (_z_zbuf_len(zbf) > 0) { // Expand message vector if needed - if (msg_idx >= msg->_messages._capacity) { - _Z_RETURN_IF_ERR(_z_network_message_svec_expand(&msg->_messages)); - _z_network_message_svec_init(&msg->_messages); + if (msg_idx >= msg_pool->_capacity) { + _Z_RETURN_IF_ERR(_z_network_message_svec_expand(msg_pool)); + _z_network_message_svec_init(msg_pool); } // Expand arc pool if needed if (msg_idx >= arc_pool->_capacity) { @@ -380,13 +373,13 @@ z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header } // Mark the reading position of the iobfer size_t r_pos = _z_zbuf_get_rpos(zbf); - // Retrieve storage in svecs - _z_network_message_t *nm = _z_network_message_svec_get_mut(&msg->_messages, msg_idx); + // Retrieve storage in resource pool + _z_network_message_t *nm = _z_network_message_svec_get_mut(msg_pool, msg_idx); _z_arc_slice_t *arcs = _z_arc_slice_svec_get_mut(arc_pool, msg_idx); // Decode message ret = _z_network_message_decode(nm, zbf, arcs); if (ret != _Z_RES_OK) { - _z_network_message_svec_clear(&msg->_messages); + _z_network_message_svec_clear(msg_pool); _z_zbuf_set_rpos(zbf, r_pos); // Restore the reading position of the iobfer // FIXME: Check for the return error, since not all of them means a decoding error @@ -398,9 +391,11 @@ z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header } return ret; } - msg->_messages._len++; + msg_pool->_len++; msg_idx++; } + // Alias network message svec in frame struct + msg->_messages = _z_network_message_svec_alias(msg_pool); return _Z_RES_OK; } @@ -500,7 +495,8 @@ z_result_t _z_transport_message_encode(_z_wbuf_t *wbf, const _z_transport_messag return ret; } -z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *zbf, _z_arc_slice_svec_t *arc_pool) { +z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *zbf, _z_arc_slice_svec_t *arc_pool, + _z_network_message_svec_t *msg_pool) { z_result_t ret = _Z_RES_OK; ret |= _z_uint8_decode(&msg->_header, zbf); // Decode the header @@ -508,7 +504,7 @@ z_result_t _z_transport_message_decode(_z_transport_message_t *msg, _z_zbuf_t *z uint8_t mid = _Z_MID(msg->_header); switch (mid) { case _Z_MID_T_FRAME: { - ret |= _z_frame_decode(&msg->_body._frame, zbf, msg->_header, arc_pool); + ret |= _z_frame_decode(&msg->_body._frame, zbf, msg->_header, arc_pool, msg_pool); } break; case _Z_MID_T_FRAGMENT: { ret |= _z_fragment_decode(&msg->_body._fragment, zbf, msg->_header); diff --git a/src/transport/common/rx.c b/src/transport/common/rx.c index d6545f5c8..49a39b6cb 100644 --- a/src/transport/common/rx.c +++ b/src/transport/common/rx.c @@ -73,11 +73,13 @@ z_result_t _z_link_recv_t_msg(_z_transport_message_t *t_msg, const _z_link_t *zl if (ret == _Z_RES_OK) { _z_transport_message_t l_t_msg; _z_arc_slice_svec_t arc_pool = _z_arc_slice_svec_make(1); - ret = _z_transport_message_decode(&l_t_msg, &zbf, &arc_pool); + _z_network_message_svec_t msg_pool = _z_network_message_svec_make(1); + ret = _z_transport_message_decode(&l_t_msg, &zbf, &arc_pool, &msg_pool); if (ret == _Z_RES_OK) { _z_t_msg_copy(t_msg, &l_t_msg); } _z_arc_slice_svec_clear(&arc_pool); + _z_network_message_svec_clear(&msg_pool); } _z_zbuf_clear(&zbf); diff --git a/src/transport/multicast/read.c b/src/transport/multicast/read.c index a5a8bca02..bea0b82f3 100644 --- a/src/transport/multicast/read.c +++ b/src/transport/multicast/read.c @@ -107,7 +107,8 @@ void *_zp_multicast_read_task(void *ztm_arg) { while (_z_zbuf_len(&zbuf) > 0) { // Decode one session message _z_transport_message_t t_msg; - z_result_t ret = _z_transport_message_decode(&t_msg, &zbuf, &ztm->_common._arc_pool); + z_result_t ret = + _z_transport_message_decode(&t_msg, &zbuf, &ztm->_common._arc_pool, &ztm->_common._msg_pool); if (ret == _Z_RES_OK) { ret = _z_multicast_handle_transport_message(ztm, &t_msg, &addr); diff --git a/src/transport/multicast/rx.c b/src/transport/multicast/rx.c index 12c439906..1ab13f161 100644 --- a/src/transport/multicast/rx.c +++ b/src/transport/multicast/rx.c @@ -77,7 +77,7 @@ static z_result_t _z_multicast_recv_t_msg_na(_z_transport_multicast_t *ztm, _z_t if (ret == _Z_RES_OK) { _Z_DEBUG(">> \t transport_message_decode: %ju", (uintmax_t)_z_zbuf_len(&ztm->_common._zbuf)); - ret = _z_transport_message_decode(t_msg, &ztm->_common._zbuf, &ztm->_common._arc_pool); + ret = _z_transport_message_decode(t_msg, &ztm->_common._zbuf, &ztm->_common._arc_pool, &ztm->_common._msg_pool); } _z_transport_rx_mutex_unlock(&ztm->_common); return ret; diff --git a/src/transport/multicast/transport.c b/src/transport/multicast/transport.c index 5ba3bca4c..3f5f1c1bf 100644 --- a/src/transport/multicast/transport.c +++ b/src/transport/multicast/transport.c @@ -81,11 +81,13 @@ z_result_t _z_multicast_transport_create(_z_transport_t *zt, _z_link_t *zl, ztm->_common._wbuf = _z_wbuf_make(mtu, false); ztm->_common._zbuf = _z_zbuf_make(Z_BATCH_MULTICAST_SIZE); - // Initialize rx pool + // Initialize resource pool ztm->_common._arc_pool = _z_arc_slice_svec_make(_Z_RES_POOL_INIT_SIZE); + ztm->_common._msg_pool = _z_network_message_svec_make(_Z_RES_POOL_INIT_SIZE); // Clean up the buffers if one of them failed to be allocated - if ((ztm->_common._arc_pool._capacity == 0) || (_z_wbuf_capacity(&ztm->_common._wbuf) != mtu) || + if ((ztm->_common._msg_pool._capacity == 0) || (ztm->_common._arc_pool._capacity == 0) || + (_z_wbuf_capacity(&ztm->_common._wbuf) != mtu) || (_z_zbuf_capacity(&ztm->_common._zbuf) != Z_BATCH_MULTICAST_SIZE)) { ret = _Z_ERR_SYSTEM_OUT_OF_MEMORY; _Z_ERROR("Not enough memory to allocate transport tx rx buffers!"); @@ -213,6 +215,7 @@ void _z_multicast_transport_clear(_z_transport_t *zt) { _z_wbuf_clear(&ztm->_common._wbuf); _z_zbuf_clear(&ztm->_common._zbuf); _z_arc_slice_svec_release(&ztm->_common._arc_pool); + _z_network_message_svec_release(&ztm->_common._msg_pool); // Clean up peer list _z_transport_peer_entry_list_free(&ztm->_peers); diff --git a/src/transport/raweth/rx.c b/src/transport/raweth/rx.c index 613405ed1..fdec282f8 100644 --- a/src/transport/raweth/rx.c +++ b/src/transport/raweth/rx.c @@ -100,7 +100,7 @@ z_result_t _z_raweth_recv_t_msg_na(_z_transport_multicast_t *ztm, _z_transport_m // Decode message if (ret == _Z_RES_OK) { _Z_DEBUG(">> \t transport_message_decode: %ju", (uintmax_t)_z_zbuf_len(&ztm->_common._zbuf)); - ret = _z_transport_message_decode(t_msg, &ztm->_common._zbuf, &ztm->_common._arc_pool); + ret = _z_transport_message_decode(t_msg, &ztm->_common._zbuf, &ztm->_common._arc_pool, &ztm->_common._msg_pool); } _z_transport_rx_mutex_unlock(&ztm->_common); return ret; diff --git a/src/transport/unicast/read.c b/src/transport/unicast/read.c index acc1f70e6..5851f3146 100644 --- a/src/transport/unicast/read.c +++ b/src/transport/unicast/read.c @@ -102,7 +102,8 @@ void *_zp_unicast_read_task(void *ztu_arg) { while (_z_zbuf_len(&zbuf) > 0) { // Decode one session message _z_transport_message_t t_msg; - z_result_t ret = _z_transport_message_decode(&t_msg, &zbuf, &ztu->_common._arc_pool); + z_result_t ret = + _z_transport_message_decode(&t_msg, &zbuf, &ztu->_common._arc_pool, &ztu->_common._msg_pool); if (ret == _Z_RES_OK) { ret = _z_unicast_handle_transport_message(ztu, &t_msg); diff --git a/src/transport/unicast/rx.c b/src/transport/unicast/rx.c index a000b1624..628f2815d 100644 --- a/src/transport/unicast/rx.c +++ b/src/transport/unicast/rx.c @@ -75,7 +75,7 @@ z_result_t _z_unicast_recv_t_msg_na(_z_transport_unicast_t *ztu, _z_transport_me if (ret == _Z_RES_OK) { _Z_DEBUG(">> \t transport_message_decode"); - ret = _z_transport_message_decode(t_msg, &ztu->_common._zbuf, &ztu->_common._arc_pool); + ret = _z_transport_message_decode(t_msg, &ztu->_common._zbuf, &ztu->_common._arc_pool, &ztu->_common._msg_pool); // Mark the session that we have received data if (ret == _Z_RES_OK) { diff --git a/src/transport/unicast/transport.c b/src/transport/unicast/transport.c index 46d376cff..6f90b4397 100644 --- a/src/transport/unicast/transport.c +++ b/src/transport/unicast/transport.c @@ -64,11 +64,13 @@ z_result_t _z_unicast_transport_create(_z_transport_t *zt, _z_link_t *zl, ztu->_common._wbuf = _z_wbuf_make(wbuf_size, false); ztu->_common._zbuf = _z_zbuf_make(zbuf_size); - // Initialize rx pool + // Initialize resources pool ztu->_common._arc_pool = _z_arc_slice_svec_make(_Z_RES_POOL_INIT_SIZE); + ztu->_common._msg_pool = _z_network_message_svec_make(_Z_RES_POOL_INIT_SIZE); // Clean up the buffers if one of them failed to be allocated - if ((ztu->_common._arc_pool._capacity == 0) || (_z_wbuf_capacity(&ztu->_common._wbuf) != wbuf_size) || + if ((ztu->_common._msg_pool._capacity == 0) || (ztu->_common._arc_pool._capacity == 0) || + (_z_wbuf_capacity(&ztu->_common._wbuf) != wbuf_size) || (_z_zbuf_capacity(&ztu->_common._zbuf) != zbuf_size)) { ret = _Z_ERR_SYSTEM_OUT_OF_MEMORY; _Z_ERROR("Not enough memory to allocate transport tx rx buffers!"); @@ -343,6 +345,7 @@ void _z_unicast_transport_clear(_z_transport_t *zt) { _z_wbuf_clear(&ztu->_common._wbuf); _z_zbuf_clear(&ztu->_common._zbuf); _z_arc_slice_svec_release(&ztu->_common._arc_pool); + _z_network_message_svec_release(&ztu->_common._msg_pool); #if Z_FEATURE_FRAGMENTATION == 1 _z_wbuf_clear(&ztu->_dbuf_reliable); _z_wbuf_clear(&ztu->_dbuf_best_effort); diff --git a/tests/z_msgcodec_test.c b/tests/z_msgcodec_test.c index 2dc50c5a6..471087659 100644 --- a/tests/z_msgcodec_test.c +++ b/tests/z_msgcodec_test.c @@ -1724,8 +1724,9 @@ void frame_message(void) { assert(_z_frame_encode(&wbf, expected._header, &expected._body._frame) == _Z_RES_OK); _z_t_msg_frame_t decoded = {0}; _z_arc_slice_svec_t arcs = _z_arc_slice_svec_make(1); + _z_network_message_svec_t msg = _z_network_message_svec_make(1); _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); - z_result_t ret = _z_frame_decode(&decoded, &zbf, expected._header, &arcs); + z_result_t ret = _z_frame_decode(&decoded, &zbf, expected._header, &arcs, &msg); assert(_Z_RES_OK == ret); assert_eq_frame(&expected._body._frame, &decoded); _z_t_msg_frame_clear(&decoded); @@ -1818,8 +1819,9 @@ void transport_message(void) { assert(_z_transport_message_encode(&wbf, &expected) == _Z_RES_OK); _z_transport_message_t decoded = {0}; _z_arc_slice_svec_t arcs = _z_arc_slice_svec_make(1); + _z_network_message_svec_t msg = _z_network_message_svec_make(1); _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); - z_result_t ret = _z_transport_message_decode(&decoded, &zbf, &arcs); + z_result_t ret = _z_transport_message_decode(&decoded, &zbf, &arcs, &msg); assert(_Z_RES_OK == ret); assert_eq_transport(&expected, &decoded); _z_t_msg_clear(&decoded); From 460bde151324eecdd2870d5981986419d9e42c17 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Fri, 8 Nov 2024 19:30:45 +0100 Subject: [PATCH 15/30] fix: add offset to svec init --- include/zenoh-pico/collections/vec.h | 70 ++++++++++++++-------------- src/collections/vec.c | 6 ++- src/protocol/codec/transport.c | 4 +- 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/include/zenoh-pico/collections/vec.h b/include/zenoh-pico/collections/vec.h index c65401e25..66aea6ac4 100644 --- a/include/zenoh-pico/collections/vec.h +++ b/include/zenoh-pico/collections/vec.h @@ -84,7 +84,7 @@ static inline _z_svec_t _z_svec_alias(const _z_svec_t *src) { return *src; } static inline _z_svec_t _z_svec_alias_element(void *element) { return (_z_svec_t){._capacity = 1, ._len = 1, ._val = element}; } -void _z_svec_init(_z_svec_t *dst, size_t element_size); +void _z_svec_init(_z_svec_t *v, size_t offset, size_t element_size); _z_svec_t _z_svec_make(size_t capacity, size_t element_size); z_result_t _z_svec_copy(_z_svec_t *dst, const _z_svec_t *src, z_element_copy_f copy, size_t element_size, bool use_elem_f); @@ -106,40 +106,40 @@ void _z_svec_clear(_z_svec_t *v, z_element_clear_f f, size_t element_size); void _z_svec_free(_z_svec_t **v, z_element_clear_f f, size_t element_size); void _z_svec_release(_z_svec_t *v); -#define _Z_SVEC_DEFINE(name, type, use_elem_f) \ - typedef _z_svec_t name##_svec_t; \ - static inline name##_svec_t name##_svec_null(void) { return _z_svec_null(); } \ - static inline name##_svec_t name##_svec_make(size_t capacity) { return _z_svec_make(capacity, sizeof(type)); } \ - static inline void name##_svec_init(name##_svec_t *v) { _z_svec_init(v, sizeof(type)); } \ - static inline size_t name##_svec_len(const name##_svec_t *v) { return _z_svec_len(v); } \ - static inline bool name##_svec_is_empty(const name##_svec_t *v) { return _z_svec_is_empty(v); } \ - static inline z_result_t name##_svec_expand(name##_svec_t *v) { \ - return _z_svec_expand(v, name##_elem_move, sizeof(type), use_elem_f); \ - } \ - static inline z_result_t name##_svec_append(name##_svec_t *v, const type *e) { \ - return _z_svec_append(v, e, name##_elem_move, sizeof(type), use_elem_f); \ - } \ - static inline type *name##_svec_get(const name##_svec_t *v, size_t pos) { \ - return (type *)_z_svec_get(v, pos, sizeof(type)); \ - } \ - static inline type *name##_svec_get_mut(name##_svec_t *v, size_t pos) { \ - return (type *)_z_svec_get_mut(v, pos, sizeof(type)); \ - } \ - static inline void name##_svec_set(name##_svec_t *v, size_t pos, type *e) { \ - _z_svec_set(v, pos, e, name##_elem_clear, sizeof(type)); \ - } \ - static inline void name##_svec_remove(name##_svec_t *v, size_t pos) { \ - _z_svec_remove(v, pos, name##_elem_clear, name##_elem_move, sizeof(type), use_elem_f); \ - } \ - static inline z_result_t name##_svec_copy(name##_svec_t *dst, const name##_svec_t *src) { \ - return _z_svec_copy(dst, src, name##_elem_copy, sizeof(type), use_elem_f); \ - } \ - static inline name##_svec_t name##_svec_alias(const name##_svec_t *v) { return _z_svec_alias(v); } \ - static inline name##_svec_t name##_svec_alias_element(type *e) { return _z_svec_alias_element((void *)e); } \ - static inline void name##_svec_move(name##_svec_t *dst, name##_svec_t *src) { _z_svec_move(dst, src); } \ - static inline void name##_svec_reset(name##_svec_t *v) { _z_svec_reset(v, name##_elem_clear, sizeof(type)); } \ - static inline void name##_svec_clear(name##_svec_t *v) { _z_svec_clear(v, name##_elem_clear, sizeof(type)); } \ - static inline void name##_svec_release(name##_svec_t *v) { _z_svec_release(v); } \ +#define _Z_SVEC_DEFINE(name, type, use_elem_f) \ + typedef _z_svec_t name##_svec_t; \ + static inline name##_svec_t name##_svec_null(void) { return _z_svec_null(); } \ + static inline name##_svec_t name##_svec_make(size_t capacity) { return _z_svec_make(capacity, sizeof(type)); } \ + static inline void name##_svec_init(name##_svec_t *v, size_t offset) { _z_svec_init(v, offset, sizeof(type)); } \ + static inline size_t name##_svec_len(const name##_svec_t *v) { return _z_svec_len(v); } \ + static inline bool name##_svec_is_empty(const name##_svec_t *v) { return _z_svec_is_empty(v); } \ + static inline z_result_t name##_svec_expand(name##_svec_t *v) { \ + return _z_svec_expand(v, name##_elem_move, sizeof(type), use_elem_f); \ + } \ + static inline z_result_t name##_svec_append(name##_svec_t *v, const type *e) { \ + return _z_svec_append(v, e, name##_elem_move, sizeof(type), use_elem_f); \ + } \ + static inline type *name##_svec_get(const name##_svec_t *v, size_t pos) { \ + return (type *)_z_svec_get(v, pos, sizeof(type)); \ + } \ + static inline type *name##_svec_get_mut(name##_svec_t *v, size_t pos) { \ + return (type *)_z_svec_get_mut(v, pos, sizeof(type)); \ + } \ + static inline void name##_svec_set(name##_svec_t *v, size_t pos, type *e) { \ + _z_svec_set(v, pos, e, name##_elem_clear, sizeof(type)); \ + } \ + static inline void name##_svec_remove(name##_svec_t *v, size_t pos) { \ + _z_svec_remove(v, pos, name##_elem_clear, name##_elem_move, sizeof(type), use_elem_f); \ + } \ + static inline z_result_t name##_svec_copy(name##_svec_t *dst, const name##_svec_t *src) { \ + return _z_svec_copy(dst, src, name##_elem_copy, sizeof(type), use_elem_f); \ + } \ + static inline name##_svec_t name##_svec_alias(const name##_svec_t *v) { return _z_svec_alias(v); } \ + static inline name##_svec_t name##_svec_alias_element(type *e) { return _z_svec_alias_element((void *)e); } \ + static inline void name##_svec_move(name##_svec_t *dst, name##_svec_t *src) { _z_svec_move(dst, src); } \ + static inline void name##_svec_reset(name##_svec_t *v) { _z_svec_reset(v, name##_elem_clear, sizeof(type)); } \ + static inline void name##_svec_clear(name##_svec_t *v) { _z_svec_clear(v, name##_elem_clear, sizeof(type)); } \ + static inline void name##_svec_release(name##_svec_t *v) { _z_svec_release(v); } \ static inline void name##_svec_free(name##_svec_t **v) { _z_svec_free(v, name##_elem_clear, sizeof(type)); } #endif /* ZENOH_PICO_COLLECTIONS_VECTOR_H */ diff --git a/src/collections/vec.c b/src/collections/vec.c index b05113404..e37614cca 100644 --- a/src/collections/vec.c +++ b/src/collections/vec.c @@ -145,7 +145,11 @@ _z_svec_t _z_svec_make(size_t capacity, size_t element_size) { return v; } -void _z_svec_init(_z_svec_t *dst, size_t element_size) { memset(dst->_val, 0, dst->_capacity * element_size); } +void _z_svec_init(_z_svec_t *v, size_t offset, size_t element_size) { + assert(offset <= v->_capacity); + void *start = _z_svec_get_mut(v, offset, element_size); + memset(start, 0, (v->_capacity - offset) * element_size); +} static inline void __z_svec_move_inner(void *dst, void *src, z_element_move_f move, size_t num_elements, size_t element_size, bool use_elem_f) { diff --git a/src/protocol/codec/transport.c b/src/protocol/codec/transport.c index a3d8c2c29..2c582d71e 100644 --- a/src/protocol/codec/transport.c +++ b/src/protocol/codec/transport.c @@ -359,13 +359,13 @@ z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header } // Init message vector msg_pool->_len = 0; - _z_network_message_svec_init(msg_pool); + _z_network_message_svec_init(msg_pool, 0); size_t msg_idx = 0; while (_z_zbuf_len(zbf) > 0) { // Expand message vector if needed if (msg_idx >= msg_pool->_capacity) { _Z_RETURN_IF_ERR(_z_network_message_svec_expand(msg_pool)); - _z_network_message_svec_init(msg_pool); + _z_network_message_svec_init(msg_pool, msg_pool->_len); } // Expand arc pool if needed if (msg_idx >= arc_pool->_capacity) { From 0fb2428e2a4eade38e1faff40d489da3ad2f4198 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Sat, 9 Nov 2024 12:27:29 +0100 Subject: [PATCH 16/30] feat: make svec use elem f a per call arg --- include/zenoh-pico/collections/bytes.h | 2 +- include/zenoh-pico/collections/string.h | 2 +- include/zenoh-pico/collections/vec.h | 10 +++++----- include/zenoh-pico/protocol/definitions/network.h | 2 +- include/zenoh-pico/session/subscription.h | 2 +- src/api/api.c | 6 +++--- src/collections/bytes.c | 6 +++--- src/net/session.c | 4 ++-- src/protocol/codec/transport.c | 4 ++-- src/protocol/core.c | 2 +- src/protocol/definitions/transport.c | 2 +- src/session/scout.c | 2 +- src/session/subscription.c | 2 +- tests/z_msgcodec_test.c | 2 +- 14 files changed, 24 insertions(+), 24 deletions(-) diff --git a/include/zenoh-pico/collections/bytes.h b/include/zenoh-pico/collections/bytes.h index 9c227e3d1..fa2ea573c 100644 --- a/include/zenoh-pico/collections/bytes.h +++ b/include/zenoh-pico/collections/bytes.h @@ -28,7 +28,7 @@ inline size_t _z_arc_slice_size(const _z_arc_slice_t *s) { return sizeof(_z_arc_slice_t); } _Z_ELEM_DEFINE(_z_arc_slice, _z_arc_slice_t, _z_arc_slice_size, _z_arc_slice_drop, _z_arc_slice_copy, _z_arc_slice_move) -_Z_SVEC_DEFINE(_z_arc_slice, _z_arc_slice_t, true) +_Z_SVEC_DEFINE(_z_arc_slice, _z_arc_slice_t) /*-------- Bytes --------*/ /** diff --git a/include/zenoh-pico/collections/string.h b/include/zenoh-pico/collections/string.h index 37c1a218b..23306aaad 100644 --- a/include/zenoh-pico/collections/string.h +++ b/include/zenoh-pico/collections/string.h @@ -98,7 +98,7 @@ _z_string_t _z_string_convert_bytes(const _z_slice_t *bs); _z_string_t _z_string_preallocate(const size_t len); _Z_ELEM_DEFINE(_z_string, _z_string_t, _z_string_len, _z_string_clear, _z_string_copy, _z_string_move) -_Z_SVEC_DEFINE(_z_string, _z_string_t, true) +_Z_SVEC_DEFINE(_z_string, _z_string_t) _Z_LIST_DEFINE(_z_string, _z_string_t) _Z_INT_MAP_DEFINE(_z_string, _z_string_t) diff --git a/include/zenoh-pico/collections/vec.h b/include/zenoh-pico/collections/vec.h index 66aea6ac4..c3d9ff525 100644 --- a/include/zenoh-pico/collections/vec.h +++ b/include/zenoh-pico/collections/vec.h @@ -106,17 +106,17 @@ void _z_svec_clear(_z_svec_t *v, z_element_clear_f f, size_t element_size); void _z_svec_free(_z_svec_t **v, z_element_clear_f f, size_t element_size); void _z_svec_release(_z_svec_t *v); -#define _Z_SVEC_DEFINE(name, type, use_elem_f) \ +#define _Z_SVEC_DEFINE(name, type) \ typedef _z_svec_t name##_svec_t; \ static inline name##_svec_t name##_svec_null(void) { return _z_svec_null(); } \ static inline name##_svec_t name##_svec_make(size_t capacity) { return _z_svec_make(capacity, sizeof(type)); } \ static inline void name##_svec_init(name##_svec_t *v, size_t offset) { _z_svec_init(v, offset, sizeof(type)); } \ static inline size_t name##_svec_len(const name##_svec_t *v) { return _z_svec_len(v); } \ static inline bool name##_svec_is_empty(const name##_svec_t *v) { return _z_svec_is_empty(v); } \ - static inline z_result_t name##_svec_expand(name##_svec_t *v) { \ + static inline z_result_t name##_svec_expand(name##_svec_t *v, bool use_elem_f) { \ return _z_svec_expand(v, name##_elem_move, sizeof(type), use_elem_f); \ } \ - static inline z_result_t name##_svec_append(name##_svec_t *v, const type *e) { \ + static inline z_result_t name##_svec_append(name##_svec_t *v, const type *e, bool use_elem_f) { \ return _z_svec_append(v, e, name##_elem_move, sizeof(type), use_elem_f); \ } \ static inline type *name##_svec_get(const name##_svec_t *v, size_t pos) { \ @@ -128,10 +128,10 @@ void _z_svec_release(_z_svec_t *v); static inline void name##_svec_set(name##_svec_t *v, size_t pos, type *e) { \ _z_svec_set(v, pos, e, name##_elem_clear, sizeof(type)); \ } \ - static inline void name##_svec_remove(name##_svec_t *v, size_t pos) { \ + static inline void name##_svec_remove(name##_svec_t *v, size_t pos, bool use_elem_f) { \ _z_svec_remove(v, pos, name##_elem_clear, name##_elem_move, sizeof(type), use_elem_f); \ } \ - static inline z_result_t name##_svec_copy(name##_svec_t *dst, const name##_svec_t *src) { \ + static inline z_result_t name##_svec_copy(name##_svec_t *dst, const name##_svec_t *src, bool use_elem_f) { \ return _z_svec_copy(dst, src, name##_elem_copy, sizeof(type), use_elem_f); \ } \ static inline name##_svec_t name##_svec_alias(const name##_svec_t *v) { return _z_svec_alias(v); } \ diff --git a/include/zenoh-pico/protocol/definitions/network.h b/include/zenoh-pico/protocol/definitions/network.h index c3ea611f8..bae5c47c1 100644 --- a/include/zenoh-pico/protocol/definitions/network.h +++ b/include/zenoh-pico/protocol/definitions/network.h @@ -290,7 +290,7 @@ void _z_n_msg_free(_z_network_message_t **m); inline static void _z_msg_clear(_z_zenoh_message_t *msg) { _z_n_msg_clear(msg); } inline static void _z_msg_free(_z_zenoh_message_t **msg) { _z_n_msg_free(msg); } _Z_ELEM_DEFINE(_z_network_message, _z_network_message_t, _z_noop_size, _z_n_msg_clear, _z_noop_copy, _z_noop_move) -_Z_SVEC_DEFINE(_z_network_message, _z_network_message_t, false) +_Z_SVEC_DEFINE(_z_network_message, _z_network_message_t) void _z_msg_fix_mapping(_z_zenoh_message_t *msg, uint16_t mapping); _z_network_message_t _z_msg_make_query(_Z_MOVE(_z_keyexpr_t) key, _Z_MOVE(_z_slice_t) parameters, _z_zint_t qid, diff --git a/include/zenoh-pico/session/subscription.h b/include/zenoh-pico/session/subscription.h index 2d7e1187a..c9b33b680 100644 --- a/include/zenoh-pico/session/subscription.h +++ b/include/zenoh-pico/session/subscription.h @@ -29,7 +29,7 @@ typedef struct { } _z_subscription_infos_t; _Z_ELEM_DEFINE(_z_subscription_infos, _z_subscription_infos_t, _z_noop_size, _z_noop_clear, _z_noop_copy, _z_noop_move) -_Z_SVEC_DEFINE(_z_subscription_infos, _z_subscription_infos_t, false) +_Z_SVEC_DEFINE(_z_subscription_infos, _z_subscription_infos_t) typedef struct { _z_keyexpr_t ke_in; diff --git a/src/api/api.c b/src/api/api.c index 59b5b4476..529c0b7ec 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -66,7 +66,7 @@ void z_string_array_new(z_owned_string_array_t *a) { a->_val = _z_string_array_n size_t z_string_array_push_by_alias(z_loaned_string_array_t *a, const z_loaned_string_t *value) { _z_string_t str = _z_string_alias(*value); - _z_string_svec_append(a, &str); + _z_string_svec_append(a, &str, true); return _z_string_svec_len(a); } @@ -74,7 +74,7 @@ size_t z_string_array_push_by_alias(z_loaned_string_array_t *a, const z_loaned_s size_t z_string_array_push_by_copy(z_loaned_string_array_t *a, const z_loaned_string_t *value) { _z_string_t str; _z_string_copy(&str, value); - _z_string_svec_append(a, &str); + _z_string_svec_append(a, &str, true); return _z_string_svec_len(a); } @@ -517,7 +517,7 @@ z_result_t z_whatami_to_view_string(z_whatami_t whatami, z_view_string_t *str_ou bool _z_string_array_check(const _z_string_svec_t *val) { return !_z_string_svec_is_empty(val); } z_result_t _z_string_array_copy(_z_string_svec_t *dst, const _z_string_svec_t *src) { - return _z_string_svec_copy(dst, src); + return _z_string_svec_copy(dst, src, true); } _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_string_svec_t, string_array, _z_string_array_check, _z_string_array_null, _z_string_array_copy, _z_string_svec_clear) diff --git a/src/collections/bytes.c b/src/collections/bytes.c index 190b41275..ab3507a95 100644 --- a/src/collections/bytes.c +++ b/src/collections/bytes.c @@ -28,7 +28,7 @@ bool _z_bytes_check(const _z_bytes_t *bytes) { return !_z_bytes_is_empty(bytes); } z_result_t _z_bytes_copy(_z_bytes_t *dst, const _z_bytes_t *src) { - return _z_arc_slice_svec_copy(&dst->_slices, &src->_slices); + return _z_arc_slice_svec_copy(&dst->_slices, &src->_slices, true); } _z_bytes_t _z_bytes_duplicate(const _z_bytes_t *src) { @@ -95,7 +95,7 @@ z_result_t _z_bytes_from_slice(_z_bytes_t *b, _z_slice_t s) { *b = _z_bytes_null(); _z_arc_slice_t arc_s = _z_arc_slice_wrap(s, 0, s.len); if (_z_arc_slice_len(&arc_s) != s.len) return _Z_ERR_SYSTEM_OUT_OF_MEMORY; - return _z_arc_slice_svec_append(&b->_slices, &arc_s); + return _z_arc_slice_svec_append(&b->_slices, &arc_s, true); } z_result_t _z_bytes_from_buf(_z_bytes_t *b, const uint8_t *src, size_t len) { @@ -128,7 +128,7 @@ z_result_t _z_bytes_to_slice(const _z_bytes_t *bytes, _z_slice_t *s) { z_result_t _z_bytes_append_slice(_z_bytes_t *dst, _z_arc_slice_t *s) { z_result_t ret = _Z_RES_OK; - ret = _z_arc_slice_svec_append(&dst->_slices, s); + ret = _z_arc_slice_svec_append(&dst->_slices, s, true); if (ret != _Z_RES_OK) { _z_arc_slice_drop(s); } diff --git a/src/net/session.c b/src/net/session.c index cf86220cd..cf3a7e991 100644 --- a/src/net/session.c +++ b/src/net/session.c @@ -95,7 +95,7 @@ z_result_t _z_open(_z_session_rc_t *zn, _z_config_t *config) { _z_hello_list_t *hellos = _z_scout_inner(what, zid, &mcast_locator, timeout, true); if (hellos != NULL) { _z_hello_t *hello = _z_hello_list_head(hellos); - _z_string_svec_copy(&locators, &hello->_locators); + _z_string_svec_copy(&locators, &hello->_locators, true); } _z_hello_list_free(&hellos); } else { @@ -112,7 +112,7 @@ z_result_t _z_open(_z_session_rc_t *zn, _z_config_t *config) { } locators = _z_string_svec_make(1); _z_string_t s = _z_string_copy_from_str(_z_config_get(config, key)); - _z_string_svec_append(&locators, &s); + _z_string_svec_append(&locators, &s, true); } ret = _Z_ERR_SCOUT_NO_RESULTS; diff --git a/src/protocol/codec/transport.c b/src/protocol/codec/transport.c index 2c582d71e..58c8a6a87 100644 --- a/src/protocol/codec/transport.c +++ b/src/protocol/codec/transport.c @@ -364,12 +364,12 @@ z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header while (_z_zbuf_len(zbf) > 0) { // Expand message vector if needed if (msg_idx >= msg_pool->_capacity) { - _Z_RETURN_IF_ERR(_z_network_message_svec_expand(msg_pool)); + _Z_RETURN_IF_ERR(_z_network_message_svec_expand(msg_pool, false)); _z_network_message_svec_init(msg_pool, msg_pool->_len); } // Expand arc pool if needed if (msg_idx >= arc_pool->_capacity) { - _Z_RETURN_IF_ERR(_z_arc_slice_svec_expand(arc_pool)); + _Z_RETURN_IF_ERR(_z_arc_slice_svec_expand(arc_pool, false)); } // Mark the reading position of the iobfer size_t r_pos = _z_zbuf_get_rpos(zbf); diff --git a/src/protocol/core.c b/src/protocol/core.c index 16842f708..da1ef9ef8 100644 --- a/src/protocol/core.c +++ b/src/protocol/core.c @@ -63,7 +63,7 @@ z_result_t _z_value_copy(_z_value_t *dst, const _z_value_t *src) { z_result_t _z_hello_copy(_z_hello_t *dst, const _z_hello_t *src) { *dst = _z_hello_null(); - _Z_RETURN_IF_ERR(_z_string_svec_copy(&dst->_locators, &src->_locators)); + _Z_RETURN_IF_ERR(_z_string_svec_copy(&dst->_locators, &src->_locators, true)); dst->_version = src->_version; dst->_whatami = src->_whatami; memcpy(&dst->_zid.id, &src->_zid.id, _Z_ID_LEN); diff --git a/src/protocol/definitions/transport.c b/src/protocol/definitions/transport.c index 2a86d95da..0cfd92356 100644 --- a/src/protocol/definitions/transport.c +++ b/src/protocol/definitions/transport.c @@ -307,7 +307,7 @@ void _z_t_msg_copy_keep_alive(_z_t_msg_keep_alive_t *clone, _z_t_msg_keep_alive_ void _z_t_msg_copy_frame(_z_t_msg_frame_t *clone, _z_t_msg_frame_t *msg) { clone->_sn = msg->_sn; - _z_network_message_svec_copy(&clone->_messages, &msg->_messages); + _z_network_message_svec_copy(&clone->_messages, &msg->_messages, false); } /*------------------ Transport Message ------------------*/ diff --git a/src/session/scout.c b/src/session/scout.c index 28244f08f..5badf7201 100644 --- a/src/session/scout.c +++ b/src/session/scout.c @@ -89,7 +89,7 @@ _z_hello_list_t *__z_scout_loop(const _z_wbuf_t *wbf, _z_string_t *locator, unsi for (size_t i = 0; i < n_loc; i++) { _z_string_t s = _z_locator_to_string(&s_msg._body._hello._locators._val[i]); - _z_string_svec_append(&hello->_locators, &s); + _z_string_svec_append(&hello->_locators, &s, true); } } else { // @TODO: construct the locator departing from the sock address diff --git a/src/session/subscription.c b/src/session/subscription.c index 3e6297176..a63bd2602 100644 --- a/src/session/subscription.c +++ b/src/session/subscription.c @@ -137,7 +137,7 @@ static z_result_t __unsafe_z_get_subscriptions_by_key(_z_session_t *zn, uint8_t if (_z_keyexpr_suffix_intersects(&_Z_RC_IN_VAL(sub)->_key, key)) { _z_subscription_infos_t new_sub_info = {.arg = _Z_RC_IN_VAL(sub)->_arg, .callback = _Z_RC_IN_VAL(sub)->_callback}; - _Z_RETURN_IF_ERR(_z_subscription_infos_svec_append(sub_infos, &new_sub_info)); + _Z_RETURN_IF_ERR(_z_subscription_infos_svec_append(sub_infos, &new_sub_info, false)); } xs = _z_subscription_rc_list_tail(xs); } diff --git a/tests/z_msgcodec_test.c b/tests/z_msgcodec_test.c index 471087659..1b0b134c5 100644 --- a/tests/z_msgcodec_test.c +++ b/tests/z_msgcodec_test.c @@ -225,7 +225,7 @@ _z_string_svec_t gen_str_array(size_t size) { _z_string_svec_t sa = _z_string_svec_make(size); for (size_t i = 0; i < size; i++) { _z_string_t s = _z_string_copy_from_str(gen_str(16)); - _z_string_svec_append(&sa, &s); + _z_string_svec_append(&sa, &s, true); } return sa; From bd76c0f9c7bc9d74cce76df4d8ba2d136fe25727 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Sat, 9 Nov 2024 12:31:40 +0100 Subject: [PATCH 17/30] feat: skip ke suffix check --- src/protocol/keyexpr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/protocol/keyexpr.c b/src/protocol/keyexpr.c index 7b7102228..1113d42ac 100644 --- a/src/protocol/keyexpr.c +++ b/src/protocol/keyexpr.c @@ -102,7 +102,10 @@ bool _z_keyexpr_equals(const _z_keyexpr_t *left, const _z_keyexpr_t *right) { if (_z_keyexpr_mapping_id(left) != _z_keyexpr_mapping_id(right)) { return false; } - return _z_string_equals(&left->_suffix, &right->_suffix); + if (_z_keyexpr_has_suffix(left) || _z_keyexpr_has_suffix(right)) { + return _z_string_equals(&left->_suffix, &right->_suffix); + } + return true; } _z_keyexpr_t _z_keyexpr_alias_from_user_defined(_z_keyexpr_t src, bool try_declared) { From e4d1a926196f07d618db87522d8a0e131b5dd362 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Sat, 9 Nov 2024 12:33:00 +0100 Subject: [PATCH 18/30] fix: arc pool --- src/protocol/codec/transport.c | 48 +++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/protocol/codec/transport.c b/src/protocol/codec/transport.c index 58c8a6a87..5e07d5fea 100644 --- a/src/protocol/codec/transport.c +++ b/src/protocol/codec/transport.c @@ -348,6 +348,48 @@ z_result_t _z_frame_encode(_z_wbuf_t *wbf, uint8_t header, const _z_t_msg_frame_ return ret; } +static void _z_frame_update_arcs_msg_pool(_z_network_message_svec_t *msg_pool, _z_arc_slice_svec_t *arc_pool) { + for (size_t i = 0; i < arc_pool->_len; i++) { + _z_network_message_t *nm = _z_network_message_svec_get(msg_pool, i); + switch (nm->_tag) { + case _Z_N_PUSH: { + if (!nm->_body._push._body._is_put) { + continue; + } + _z_bytes_alias_arc_slice(&nm->_body._push._body._body._put._payload, + _z_arc_slice_svec_get(arc_pool, i)); + } break; + case _Z_N_REQUEST: { + if (nm->_body._request._tag != _Z_REQUEST_PUT) { + continue; + } + _z_bytes_alias_arc_slice(&nm->_body._request._body._put._payload, _z_arc_slice_svec_get(arc_pool, i)); + } break; + case _Z_N_RESPONSE: { + switch (nm->_body._response._tag) { + case _Z_RESPONSE_BODY_REPLY: + if (!nm->_body._response._body._reply._body._is_put) { + continue; + } + _z_bytes_alias_arc_slice(&nm->_body._response._body._reply._body._body._put._payload, + _z_arc_slice_svec_get(arc_pool, i)); + break; + + case _Z_RESPONSE_BODY_ERR: + _z_bytes_alias_arc_slice(&nm->_body._response._body._err._payload, + _z_arc_slice_svec_get(arc_pool, i)); + break; + + default: + continue; + } + } + default: + continue; + } + } +} + z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header, _z_arc_slice_svec_t *arc_pool, _z_network_message_svec_t *msg_pool) { z_result_t ret = _Z_RES_OK; @@ -359,6 +401,7 @@ z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header } // Init message vector msg_pool->_len = 0; + arc_pool->_len = 0; _z_network_message_svec_init(msg_pool, 0); size_t msg_idx = 0; while (_z_zbuf_len(zbf) > 0) { @@ -370,6 +413,8 @@ z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header // Expand arc pool if needed if (msg_idx >= arc_pool->_capacity) { _Z_RETURN_IF_ERR(_z_arc_slice_svec_expand(arc_pool, false)); + // Update arcs references in msg pool + _z_frame_update_arcs_msg_pool(msg_pool, arc_pool); } // Mark the reading position of the iobfer size_t r_pos = _z_zbuf_get_rpos(zbf); @@ -379,7 +424,7 @@ z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header // Decode message ret = _z_network_message_decode(nm, zbf, arcs); if (ret != _Z_RES_OK) { - _z_network_message_svec_clear(msg_pool); + _z_network_message_svec_reset(msg_pool); _z_zbuf_set_rpos(zbf, r_pos); // Restore the reading position of the iobfer // FIXME: Check for the return error, since not all of them means a decoding error @@ -391,6 +436,7 @@ z_result_t _z_frame_decode(_z_t_msg_frame_t *msg, _z_zbuf_t *zbf, uint8_t header } return ret; } + arc_pool->_len++; msg_pool->_len++; msg_idx++; } From 63932661762e454293fae2d2bbe69967155bd1ce Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Sat, 9 Nov 2024 14:03:16 +0100 Subject: [PATCH 19/30] feat: improve sub perf and readability --- include/zenoh-pico/net/sample.h | 18 +++++-- include/zenoh-pico/session/subscription.h | 5 +- src/net/sample.c | 33 ------------ src/session/subscription.c | 65 ++++++++++++++++------- 4 files changed, 62 insertions(+), 59 deletions(-) diff --git a/include/zenoh-pico/net/sample.h b/include/zenoh-pico/net/sample.h index ab42e6985..374241808 100644 --- a/include/zenoh-pico/net/sample.h +++ b/include/zenoh-pico/net/sample.h @@ -46,6 +46,20 @@ static inline bool _z_sample_check(const _z_sample_t *sample) { return _z_keyexpr_check(&sample->keyexpr) || _z_encoding_check(&sample->encoding) || _z_bytes_check(&sample->payload) || _z_bytes_check(&sample->attachment); } +static inline _z_sample_t _z_sample_alias(_z_keyexpr_t *key, _z_bytes_t *payload, const _z_timestamp_t *timestamp, + _z_encoding_t *encoding, const z_sample_kind_t kind, const _z_qos_t qos, + _z_bytes_t *attachment, z_reliability_t reliability) { + return (_z_sample_t){ + .kind = kind, + .qos = qos, + .reliability = reliability, + .keyexpr = *key, + .encoding = *encoding, + .attachment = *attachment, + .payload = *payload, + .timestamp = *timestamp, + }; +} void _z_sample_move(_z_sample_t *dst, _z_sample_t *src); /** @@ -59,8 +73,4 @@ void _z_sample_free(_z_sample_t **sample); z_result_t _z_sample_copy(_z_sample_t *dst, const _z_sample_t *src); _z_sample_t _z_sample_duplicate(const _z_sample_t *src); -void _z_sample_create(_z_sample_t *s, _z_keyexpr_t *key, _z_bytes_t *payload, const _z_timestamp_t *timestamp, - _z_encoding_t *encoding, const z_sample_kind_t kind, const _z_qos_t qos, _z_bytes_t *attachment, - z_reliability_t reliability); - #endif /* ZENOH_PICO_SAMPLE_NETAPI_H */ diff --git a/include/zenoh-pico/session/subscription.h b/include/zenoh-pico/session/subscription.h index c9b33b680..852e6cd9d 100644 --- a/include/zenoh-pico/session/subscription.h +++ b/include/zenoh-pico/session/subscription.h @@ -35,10 +35,11 @@ typedef struct { _z_keyexpr_t ke_in; _z_keyexpr_t ke_out; _z_subscription_infos_svec_t infos; + size_t sub_nb; } _z_subscription_cache_t; /*------------------ Subscription ------------------*/ -void _z_trigger_local_subscriptions(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_bytes_t *payload, +void _z_trigger_local_subscriptions(_z_session_t *zn, _z_keyexpr_t *keyexpr, _z_bytes_t *payload, _z_encoding_t *encoding, const _z_n_qos_t qos, const _z_timestamp_t *timestamp, _z_bytes_t *attachment, z_reliability_t reliability); @@ -50,7 +51,7 @@ void _z_subscription_cache_clear(_z_subscription_cache_t *cache); _z_subscription_rc_t *_z_get_subscription_by_id(_z_session_t *zn, uint8_t is_local, const _z_zint_t id); _z_subscription_rc_t *_z_register_subscription(_z_session_t *zn, uint8_t is_local, _z_subscription_t *sub); -z_result_t _z_trigger_subscriptions(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_bytes_t *payload, +z_result_t _z_trigger_subscriptions(_z_session_t *zn, _z_keyexpr_t *keyexpr, _z_bytes_t *payload, _z_encoding_t *encoding, const _z_zint_t kind, const _z_timestamp_t *timestamp, const _z_n_qos_t qos, _z_bytes_t *attachment, z_reliability_t reliability); void _z_unregister_subscription(_z_session_t *zn, uint8_t is_local, _z_subscription_rc_t *sub); diff --git a/src/net/sample.c b/src/net/sample.c index 2cfac75d0..58dcd0fa1 100644 --- a/src/net/sample.c +++ b/src/net/sample.c @@ -56,36 +56,3 @@ _z_sample_t _z_sample_duplicate(const _z_sample_t *src) { _z_sample_copy(&dst, src); return dst; } - -#if Z_FEATURE_SUBSCRIPTION == 1 -void _z_sample_create(_z_sample_t *s, _z_keyexpr_t *key, _z_bytes_t *payload, const _z_timestamp_t *timestamp, - _z_encoding_t *encoding, const z_sample_kind_t kind, const _z_qos_t qos, _z_bytes_t *attachment, - z_reliability_t reliability) { - s->kind = kind; - s->qos = qos; - s->reliability = reliability; - s->keyexpr = _z_keyexpr_steal(key); - _z_encoding_move(&s->encoding, encoding); - _z_bytes_move(&s->attachment, attachment); - _z_bytes_move(&s->payload, payload); - if (_z_timestamp_check(timestamp)) { - _z_timestamp_copy(&s->timestamp, timestamp); - } else { - _z_timestamp_invalid(&s->timestamp); - } -} -#else -void _z_sample_create(_z_sample_t *s, _z_keyexpr_t *key, _z_bytes_t *payload, const _z_timestamp_t *timestamp, - _z_encoding_t *encoding, const z_sample_kind_t kind, const _z_qos_t qos, _z_bytes_t *attachment, - z_reliability_t reliability) { - _ZP_UNUSED(key); - _ZP_UNUSED(payload); - _ZP_UNUSED(timestamp); - _ZP_UNUSED(encoding); - _ZP_UNUSED(kind); - _ZP_UNUSED(qos); - _ZP_UNUSED(attachment); - _ZP_UNUSED(reliability); - *s = _z_sample_null(); -} -#endif diff --git a/src/session/subscription.c b/src/session/subscription.c index a63bd2602..cad4821a5 100644 --- a/src/session/subscription.c +++ b/src/session/subscription.c @@ -34,12 +34,13 @@ #if Z_FEATURE_RX_CACHE == 1 static inline bool _z_subscription_get_from_cache(_z_session_t *zn, const _z_keyexpr_t *ke, _z_keyexpr_t *ke_val, - _z_subscription_infos_svec_t *infos_val) { + _z_subscription_infos_svec_t *infos_val, size_t *sub_nb) { if (!_z_keyexpr_equals(ke, &zn->_subscription_cache.ke_in)) { return false; } *ke_val = _z_keyexpr_alias(zn->_subscription_cache.ke_out); *infos_val = _z_subscription_infos_svec_alias(&zn->_subscription_cache.infos); + *sub_nb = zn->_subscription_cache.sub_nb; return true; } @@ -51,6 +52,7 @@ static inline void _z_subscription_update_cache(_z_session_t *zn, const _z_keyex zn->_subscription_cache.ke_in = _z_keyexpr_duplicate(ke_in); zn->_subscription_cache.ke_out = _z_keyexpr_duplicate(ke_out); zn->_subscription_cache.infos = _z_subscription_infos_svec_alias(infos); + zn->_subscription_cache.sub_nb = _z_subscription_infos_svec_len(infos); } void _z_subscription_cache_clear(_z_subscription_cache_t *cache) { @@ -61,11 +63,12 @@ void _z_subscription_cache_clear(_z_subscription_cache_t *cache) { #else static inline bool _z_subscription_get_from_cache(_z_session_t *zn, const _z_keyexpr_t *ke, _z_keyexpr_t *ke_val, - _z_subscription_infos_svec_t *infos_val) { + _z_subscription_infos_svec_t *infos_val, size_t *sub_nb) { _ZP_UNUSED(zn); _ZP_UNUSED(ke); _ZP_UNUSED(ke_val); _ZP_UNUSED(infos_val); + _ZP_UNUSED(sub_nb); return false; } @@ -176,7 +179,7 @@ _z_subscription_rc_t *_z_register_subscription(_z_session_t *zn, uint8_t is_loca return ret; } -void _z_trigger_local_subscriptions(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_bytes_t *payload, +void _z_trigger_local_subscriptions(_z_session_t *zn, _z_keyexpr_t *keyexpr, _z_bytes_t *payload, _z_encoding_t *encoding, const _z_n_qos_t qos, const _z_timestamp_t *timestamp, _z_bytes_t *attachment, z_reliability_t reliability) { z_result_t ret = _z_trigger_subscriptions(zn, keyexpr, payload, encoding, Z_SAMPLE_KIND_PUT, timestamp, qos, @@ -184,54 +187,76 @@ void _z_trigger_local_subscriptions(_z_session_t *zn, const _z_keyexpr_t *keyexp (void)ret; } -z_result_t _z_trigger_subscriptions(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_bytes_t *payload, - _z_encoding_t *encoding, const _z_zint_t kind, const _z_timestamp_t *timestamp, - const _z_n_qos_t qos, _z_bytes_t *attachment, z_reliability_t reliability) { - _z_sample_t sample; - _z_keyexpr_t key; - _z_subscription_infos_svec_t subs; +static z_result_t _z_subscription_get_infos(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_keyexpr_t *key, + _z_subscription_infos_svec_t *subs, size_t *sub_nb) { // Check cache - if (!_z_subscription_get_from_cache(zn, keyexpr, &key, &subs)) { + if (!_z_subscription_get_from_cache(zn, keyexpr, key, subs, sub_nb)) { _Z_DEBUG("Resolving %d - %.*s on mapping 0x%x", keyexpr->_id, (int)_z_string_len(&keyexpr->_suffix), _z_string_data(&keyexpr->_suffix), _z_keyexpr_mapping_id(keyexpr)); _z_session_mutex_lock(zn); - key = __unsafe_z_get_expanded_key_from_key(zn, keyexpr, true); + *key = __unsafe_z_get_expanded_key_from_key(zn, keyexpr, true); - if (!_z_keyexpr_has_suffix(&key)) { + if (!_z_keyexpr_has_suffix(key)) { _z_session_mutex_unlock(zn); return _Z_ERR_KEYEXPR_UNKNOWN; } // Get subscription list - z_result_t ret = __unsafe_z_get_subscriptions_by_key(zn, _Z_RESOURCE_IS_LOCAL, &key, &subs); + z_result_t ret = __unsafe_z_get_subscriptions_by_key(zn, _Z_RESOURCE_IS_LOCAL, key, subs); _z_session_mutex_unlock(zn); if (ret != _Z_RES_OK) { return ret; } + *sub_nb = _z_subscription_infos_svec_len(subs); // Update cache - _z_subscription_update_cache(zn, keyexpr, &key, &subs); + _z_subscription_update_cache(zn, keyexpr, key, subs); } - // Check if there is subs - size_t sub_nb = _z_subscription_infos_svec_len(&subs); + return _Z_RES_OK; +} + +static z_result_t _z_trigger_subscriptions_inner(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_bytes_t *payload, + _z_encoding_t *encoding, const _z_zint_t kind, + const _z_timestamp_t *timestamp, const _z_n_qos_t qos, + _z_bytes_t *attachment, z_reliability_t reliability) { + _z_keyexpr_t key; + _z_subscription_infos_svec_t subs; + size_t sub_nb; + // Retrieve sub infos + _Z_RETURN_IF_ERR(_z_subscription_get_infos(zn, keyexpr, &key, &subs, &sub_nb)); + // Check if there are subs _Z_DEBUG("Triggering %ju subs for key %d - %.*s", (uintmax_t)sub_nb, key._id, (int)_z_string_len(&key._suffix), _z_string_data(&key._suffix)); if (sub_nb == 0) { + _z_keyexpr_clear(&key); return _Z_RES_OK; } - // Build the sample - _z_sample_create(&sample, &key, payload, timestamp, encoding, kind, qos, attachment, reliability); + // Create sample + _z_sample_t sample = _z_sample_alias(&key, payload, timestamp, encoding, kind, qos, attachment, reliability); // Parse subscription infos svec for (size_t i = 0; i < sub_nb; i++) { _z_subscription_infos_t *sub_info = _z_subscription_infos_svec_get(&subs, i); sub_info->callback(&sample, sub_info->arg); } // Clean up - _z_sample_clear(&sample); + _z_keyexpr_clear(&key); #if Z_FEATURE_RX_CACHE != 1 _z_subscription_infos_svec_release(&subs); // Otherwise it's released with cache #endif return _Z_RES_OK; } +z_result_t _z_trigger_subscriptions(_z_session_t *zn, _z_keyexpr_t *keyexpr, _z_bytes_t *payload, + _z_encoding_t *encoding, const _z_zint_t kind, const _z_timestamp_t *timestamp, + const _z_n_qos_t qos, _z_bytes_t *attachment, z_reliability_t reliability) { + z_result_t ret = + _z_trigger_subscriptions_inner(zn, keyexpr, payload, encoding, kind, timestamp, qos, attachment, reliability); + // Clean up + _z_keyexpr_clear(keyexpr); + _z_encoding_clear(encoding); + _z_bytes_aliased_drop(payload); + _z_bytes_drop(attachment); + return ret; +} + void _z_unregister_subscription(_z_session_t *zn, uint8_t is_local, _z_subscription_rc_t *sub) { _z_session_mutex_lock(zn); @@ -256,7 +281,7 @@ void _z_flush_subscriptions(_z_session_t *zn) { } #else // Z_FEATURE_SUBSCRIPTION == 0 -void _z_trigger_local_subscriptions(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_bytes_t *payload, +void _z_trigger_local_subscriptions(_z_session_t *zn, _z_keyexpr_t *keyexpr, _z_bytes_t *payload, _z_encoding_t *encoding, const _z_n_qos_t qos, const _z_timestamp_t *timestamp, _z_bytes_t *attachment, z_reliability_t reliability) { _ZP_UNUSED(zn); From 0f6d48f492ed7ae00de804db204a1f78e1c04c94 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Sat, 9 Nov 2024 21:19:23 +0100 Subject: [PATCH 20/30] feat: add z_string_alias_slice function --- include/zenoh-pico/collections/string.h | 1 + src/collections/string.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/include/zenoh-pico/collections/string.h b/include/zenoh-pico/collections/string.h index 23306aaad..6291db854 100644 --- a/include/zenoh-pico/collections/string.h +++ b/include/zenoh-pico/collections/string.h @@ -76,6 +76,7 @@ static inline _z_string_t _z_string_alias(const _z_string_t str) { _z_string_t _z_string_copy_from_str(const char *value); _z_string_t _z_string_copy_from_substr(const char *value, size_t len); _z_string_t *_z_string_copy_from_str_as_ptr(const char *value); +_z_string_t _z_string_alias_slice(const _z_slice_t *slice); _z_string_t _z_string_alias_str(const char *value); _z_string_t _z_string_alias_substr(const char *value, size_t len); _z_string_t _z_string_from_str_custom_deleter(char *value, _z_delete_context_t c); diff --git a/src/collections/string.c b/src/collections/string.c index d15d1438e..2dad38f40 100644 --- a/src/collections/string.c +++ b/src/collections/string.c @@ -33,6 +33,12 @@ _z_string_t _z_string_copy_from_substr(const char *value, size_t len) { return s; } +_z_string_t _z_string_alias_slice(const _z_slice_t *slice) { + _z_string_t s; + s._slice = _z_slice_alias(*slice); + return s; +} + _z_string_t _z_string_alias_str(const char *value) { _z_string_t s; s._slice = _z_slice_alias_buf((const uint8_t *)(value), strlen(value)); From 49fd11e38b12c7fe1ba507e14d2806dbdf3ee937 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Sat, 9 Nov 2024 21:30:17 +0100 Subject: [PATCH 21/30] feat: align queryable with subscription --- include/zenoh-pico/net/query.h | 19 ++- include/zenoh-pico/net/session.h | 2 + include/zenoh-pico/session/queryable.h | 27 +++- src/api/api.c | 4 +- src/net/query.c | 27 +--- src/session/queryable.c | 202 ++++++++++++++++++------- src/session/rx.c | 3 +- src/session/utils.c | 2 + 8 files changed, 192 insertions(+), 94 deletions(-) diff --git a/include/zenoh-pico/net/query.h b/include/zenoh-pico/net/query.h index 703688a65..f66996df9 100644 --- a/include/zenoh-pico/net/query.h +++ b/include/zenoh-pico/net/query.h @@ -29,8 +29,8 @@ typedef struct _z_query_t { _z_keyexpr_t _key; uint32_t _request_id; _z_session_weak_t _zn; // Can't be an rc because of cross referencing - _z_bytes_t attachment; - char *_parameters; + _z_bytes_t _attachment; + _z_string_t _parameters; bool _anyke; } _z_query_t; @@ -54,8 +54,19 @@ typedef struct { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_queryable_t _z_queryable_null(void) { return (_z_queryable_t){0}; } static inline bool _z_queryable_check(const _z_queryable_t *queryable) { return !_Z_RC_IS_NULL(&queryable->_zn); } -_z_query_t _z_query_create(_z_value_t *value, _z_keyexpr_t *key, const _z_slice_t *parameters, _z_session_rc_t *zn, - uint32_t request_id, const _z_bytes_t attachment); +static inline _z_query_t _z_query_alias(_z_value_t *value, _z_keyexpr_t *key, const _z_slice_t *parameters, + _z_session_rc_t *zn, uint32_t request_id, const _z_bytes_t *attachment, + bool anyke) { + return (_z_query_t){ + ._request_id = request_id, + ._zn = _z_session_rc_clone_as_weak(zn), + ._parameters = _z_string_alias_slice(parameters), + ._anyke = anyke, + ._key = *key, + ._attachment = *attachment, + ._value = *value, + }; +} void _z_queryable_clear(_z_queryable_t *qbl); void _z_queryable_free(_z_queryable_t **qbl); diff --git a/include/zenoh-pico/net/session.h b/include/zenoh-pico/net/session.h index b2bdd8fec..6f2eae321 100644 --- a/include/zenoh-pico/net/session.h +++ b/include/zenoh-pico/net/session.h @@ -21,6 +21,7 @@ #include "zenoh-pico/collections/list.h" #include "zenoh-pico/config.h" #include "zenoh-pico/protocol/core.h" +#include "zenoh-pico/session/queryable.h" #include "zenoh-pico/session/session.h" #include "zenoh-pico/session/subscription.h" #include "zenoh-pico/utils/config.h" @@ -55,6 +56,7 @@ typedef struct _z_session_t { _z_subscription_rc_list_t *_remote_subscriptions; #if Z_FEATURE_RX_CACHE == 1 _z_subscription_cache_t _subscription_cache; + _z_queryable_cache_t _queryable_cache; #endif #endif diff --git a/include/zenoh-pico/session/queryable.h b/include/zenoh-pico/session/queryable.h index 4498a5bed..6e8e8eeed 100644 --- a/include/zenoh-pico/session/queryable.h +++ b/include/zenoh-pico/session/queryable.h @@ -16,20 +16,37 @@ #define ZENOH_PICO_SESSION_QUERYABLE_H #include +#include -#include "zenoh-pico/net/session.h" +// Forward declaration to avoid cyclical include +typedef struct _z_session_t _z_session_t; +typedef struct _z_session_rc_t _z_session_rc_t; + +// Queryable infos +typedef struct { + _z_query_handler_t callback; + void *arg; +} _z_queryable_infos_t; + +_Z_ELEM_DEFINE(_z_queryable_infos, _z_queryable_infos_t, _z_noop_size, _z_noop_clear, _z_noop_copy, _z_noop_move) +_Z_SVEC_DEFINE(_z_queryable_infos, _z_queryable_infos_t) + +typedef struct { + _z_keyexpr_t ke_in; + _z_keyexpr_t ke_out; + _z_queryable_infos_svec_t infos; + size_t qle_nb; +} _z_queryable_cache_t; #if Z_FEATURE_QUERYABLE == 1 #define _Z_QUERYABLE_COMPLETE_DEFAULT false #define _Z_QUERYABLE_DISTANCE_DEFAULT 0 /*------------------ Queryable ------------------*/ +void _z_queryable_cache_clear(_z_queryable_cache_t *cache); _z_session_queryable_rc_t *_z_get_session_queryable_by_id(_z_session_t *zn, const _z_zint_t id); -_z_session_queryable_rc_list_t *_z_get_session_queryable_by_key(_z_session_t *zn, const _z_keyexpr_t key); - _z_session_queryable_rc_t *_z_register_session_queryable(_z_session_t *zn, _z_session_queryable_t *q); -z_result_t _z_trigger_queryables(_z_session_rc_t *zn, _z_msg_query_t *query, const _z_keyexpr_t q_key, uint32_t qid, - const _z_bytes_t attachment); +z_result_t _z_trigger_queryables(_z_session_rc_t *zn, _z_msg_query_t *query, _z_keyexpr_t *q_key, uint32_t qid); void _z_unregister_session_queryable(_z_session_t *zn, _z_session_queryable_rc_t *q); void _z_flush_session_queryable(_z_session_t *zn); #endif diff --git a/src/api/api.c b/src/api/api.c index 529c0b7ec..7cdb7d0a1 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -417,10 +417,10 @@ z_query_consolidation_t z_query_consolidation_none(void) { z_query_consolidation_t z_query_consolidation_default(void) { return z_query_consolidation_auto(); } void z_query_parameters(const z_loaned_query_t *query, z_view_string_t *parameters) { - parameters->_val = _z_string_alias_str(_Z_RC_IN_VAL(query)->_parameters); + parameters->_val = _z_string_alias(_Z_RC_IN_VAL(query)->_parameters); } -const z_loaned_bytes_t *z_query_attachment(const z_loaned_query_t *query) { return &_Z_RC_IN_VAL(query)->attachment; } +const z_loaned_bytes_t *z_query_attachment(const z_loaned_query_t *query) { return &_Z_RC_IN_VAL(query)->_attachment; } const z_loaned_keyexpr_t *z_query_keyexpr(const z_loaned_query_t *query) { return &_Z_RC_IN_VAL(query)->_key; } diff --git a/src/net/query.c b/src/net/query.c index a4b41b6aa..b2048e2b1 100644 --- a/src/net/query.c +++ b/src/net/query.c @@ -20,8 +20,8 @@ void _z_query_clear_inner(_z_query_t *q) { _z_keyexpr_clear(&q->_key); _z_value_clear(&q->_value); - _z_bytes_drop(&q->attachment); - z_free(q->_parameters); + _z_bytes_drop(&q->_attachment); + _z_string_clear(&q->_parameters); _z_session_weak_drop(&q->_zn); } @@ -46,12 +46,8 @@ z_result_t _z_query_copy(_z_query_t *dst, const _z_query_t *src) { *dst = _z_query_null(); _Z_RETURN_IF_ERR(_z_keyexpr_copy(&dst->_key, &src->_key)); _Z_CLEAN_RETURN_IF_ERR(_z_value_copy(&dst->_value, &src->_value), _z_query_clear_inner(dst)); - _Z_CLEAN_RETURN_IF_ERR(_z_bytes_copy(&dst->attachment, &src->attachment), _z_query_clear_inner(dst)); - dst->_parameters = _z_str_clone(src->_parameters); - if (dst->_parameters == NULL && src->_parameters != NULL) { - _z_query_clear_inner(dst); - return _Z_ERR_SYSTEM_OUT_OF_MEMORY; - } + _Z_CLEAN_RETURN_IF_ERR(_z_bytes_copy(&dst->_attachment, &src->_attachment), _z_query_clear_inner(dst)); + _Z_CLEAN_RETURN_IF_ERR(_z_string_copy(&dst->_parameters, &src->_parameters), _z_query_clear_inner(dst)); _z_session_weak_copy(&dst->_zn, &src->_zn); if (_Z_RC_IS_NULL(&dst->_zn)) { _z_query_clear_inner(dst); @@ -73,21 +69,6 @@ void _z_query_free(_z_query_t **query) { } #if Z_FEATURE_QUERYABLE == 1 -_z_query_t _z_query_create(_z_value_t *value, _z_keyexpr_t *key, const _z_slice_t *parameters, _z_session_rc_t *zsrc, - uint32_t request_id, const _z_bytes_t attachment) { - _z_query_t q = _z_query_null(); - q._request_id = request_id; - q._zn = _z_session_rc_clone_as_weak(zsrc); - q._parameters = (char *)z_malloc(parameters->len + 1); - memcpy(q._parameters, parameters->start, parameters->len); - q._parameters[parameters->len] = 0; - q._anyke = (strstr(q._parameters, Z_SELECTOR_QUERY_MATCH) == NULL) ? false : true; - q._key = _z_keyexpr_steal(key); - _z_bytes_copy(&q.attachment, &attachment); - _z_value_move(&q._value, value); - return q; -} - void _z_queryable_clear(_z_queryable_t *qbl) { _z_session_weak_drop(&qbl->_zn); *qbl = _z_queryable_null(); diff --git a/src/session/queryable.c b/src/session/queryable.c index ba04debd7..2ac7eb69e 100644 --- a/src/session/queryable.c +++ b/src/session/queryable.c @@ -25,8 +25,63 @@ #include "zenoh-pico/session/resource.h" #include "zenoh-pico/session/utils.h" #include "zenoh-pico/utils/logging.h" +#include "zenoh-pico/utils/pointers.h" +#include "zenoh-pico/utils/string.h" #if Z_FEATURE_QUERYABLE == 1 + +#define _Z_QLEINFOS_VEC_SIZE 4 // Arbitrary initial size + +#if Z_FEATURE_RX_CACHE == 1 +static inline bool _z_queryable_get_from_cache(_z_session_t *zn, const _z_keyexpr_t *ke, _z_keyexpr_t *ke_val, + _z_queryable_infos_svec_t *infos_val, size_t *qle_nb) { + if (!_z_keyexpr_equals(ke, &zn->_queryable_cache.ke_in)) { + return false; + } + *ke_val = _z_keyexpr_alias(zn->_queryable_cache.ke_out); + *infos_val = _z_queryable_infos_svec_alias(&zn->_queryable_cache.infos); + *qle_nb = zn->_queryable_cache.qle_nb; + return true; +} + +static inline void _z_queryable_update_cache(_z_session_t *zn, const _z_keyexpr_t *ke_in, const _z_keyexpr_t *ke_out, + _z_queryable_infos_svec_t *infos) { + // Clear previous data + _z_queryable_cache_clear(&zn->_queryable_cache); + // Register new info + zn->_queryable_cache.ke_in = _z_keyexpr_duplicate(ke_in); + zn->_queryable_cache.ke_out = _z_keyexpr_duplicate(ke_out); + zn->_queryable_cache.infos = _z_queryable_infos_svec_alias(infos); + zn->_queryable_cache.qle_nb = _z_queryable_infos_svec_len(infos); +} + +void _z_queryable_cache_clear(_z_queryable_cache_t *cache) { + _z_queryable_infos_svec_clear(&cache->infos); + _z_keyexpr_clear(&cache->ke_in); + _z_keyexpr_clear(&cache->ke_out); +} + +#else +static inline bool _z_queryable_get_from_cache(_z_session_t *zn, const _z_keyexpr_t *ke, _z_keyexpr_t *ke_val, + _z_queryable_infos_svec_t *infos_val, size_t *sub_nb) { + _ZP_UNUSED(zn); + _ZP_UNUSED(ke); + _ZP_UNUSED(ke_val); + _ZP_UNUSED(infos_val); + _ZP_UNUSED(sub_nb); + return false; +} + +static inline void _z_queryable_update_cache(_z_session_t *zn, const _z_keyexpr_t *ke_in, const _z_keyexpr_t *ke_out, + _z_queryable_infos_svec_t *infos) { + _ZP_UNUSED(zn); + _ZP_UNUSED(ke_in); + _ZP_UNUSED(ke_out); + _ZP_UNUSED(infos); + return; +} +#endif // Z_FEATURE_RX_CACHE == 1 + bool _z_session_queryable_eq(const _z_session_queryable_t *one, const _z_session_queryable_t *two) { return one->_id == two->_id; } @@ -39,7 +94,8 @@ void _z_session_queryable_clear(_z_session_queryable_t *qle) { } /*------------------ Queryable ------------------*/ -_z_session_queryable_rc_t *__z_get_session_queryable_by_id(_z_session_queryable_rc_list_t *qles, const _z_zint_t id) { +static _z_session_queryable_rc_t *__z_get_session_queryable_by_id(_z_session_queryable_rc_list_t *qles, + const _z_zint_t id) { _z_session_queryable_rc_t *ret = NULL; _z_session_queryable_rc_list_t *xs = qles; @@ -56,29 +112,12 @@ _z_session_queryable_rc_t *__z_get_session_queryable_by_id(_z_session_queryable_ return ret; } -_z_session_queryable_rc_list_t *__z_get_session_queryable_by_key(_z_session_queryable_rc_list_t *qles, - const _z_keyexpr_t key) { - _z_session_queryable_rc_list_t *ret = NULL; - - _z_session_queryable_rc_list_t *xs = qles; - while (xs != NULL) { - _z_session_queryable_rc_t *qle = _z_session_queryable_rc_list_head(xs); - if (_z_keyexpr_suffix_intersects(&_Z_RC_IN_VAL(qle)->_key, &key) == true) { - ret = _z_session_queryable_rc_list_push(ret, _z_session_queryable_rc_clone_as_ptr(qle)); - } - - xs = _z_session_queryable_rc_list_tail(xs); - } - - return ret; -} - /** * This function is unsafe because it operates in potentially concurrent data. * Make sure that the following mutexes are locked before calling this function: * - zn->_mutex_inner */ -_z_session_queryable_rc_t *__unsafe_z_get_session_queryable_by_id(_z_session_t *zn, const _z_zint_t id) { +static _z_session_queryable_rc_t *__unsafe_z_get_session_queryable_by_id(_z_session_t *zn, const _z_zint_t id) { _z_session_queryable_rc_list_t *qles = zn->_local_queryable; return __z_get_session_queryable_by_id(qles, id); } @@ -88,9 +127,23 @@ _z_session_queryable_rc_t *__unsafe_z_get_session_queryable_by_id(_z_session_t * * Make sure that the following mutexes are locked before calling this function: * - zn->_mutex_inner */ -_z_session_queryable_rc_list_t *__unsafe_z_get_session_queryable_by_key(_z_session_t *zn, const _z_keyexpr_t key) { +static z_result_t __unsafe_z_get_session_queryable_by_key(_z_session_t *zn, const _z_keyexpr_t *key, + _z_queryable_infos_svec_t *qle_infos) { _z_session_queryable_rc_list_t *qles = zn->_local_queryable; - return __z_get_session_queryable_by_key(qles, key); + + *qle_infos = _z_queryable_infos_svec_make(_Z_QLEINFOS_VEC_SIZE); + _z_session_queryable_rc_list_t *xs = qles; + while (xs != NULL) { + // Parse queryable list + _z_session_queryable_rc_t *qle = _z_session_queryable_rc_list_head(xs); + if (_z_keyexpr_suffix_intersects(&_Z_RC_IN_VAL(qle)->_key, key)) { + _z_queryable_infos_t new_qle_info = {.arg = _Z_RC_IN_VAL(qle)->_arg, + .callback = _Z_RC_IN_VAL(qle)->_callback}; + _Z_RETURN_IF_ERR(_z_queryable_infos_svec_append(qle_infos, &new_qle_info, false)); + } + xs = _z_session_queryable_rc_list_tail(xs); + } + return _Z_RES_OK; } _z_session_queryable_rc_t *_z_get_session_queryable_by_id(_z_session_t *zn, const _z_zint_t id) { @@ -103,17 +156,6 @@ _z_session_queryable_rc_t *_z_get_session_queryable_by_id(_z_session_t *zn, cons return qle; } -_z_session_queryable_rc_list_t *_z_get_session_queryable_by_key(_z_session_t *zn, const _z_keyexpr_t *keyexpr) { - _z_session_mutex_lock(zn); - - _z_keyexpr_t key = __unsafe_z_get_expanded_key_from_key(zn, keyexpr, false); - _z_session_queryable_rc_list_t *qles = __unsafe_z_get_session_queryable_by_key(zn, key); - - _z_session_mutex_unlock(zn); - - return qles; -} - _z_session_queryable_rc_t *_z_register_session_queryable(_z_session_t *zn, _z_session_queryable_t *q) { _Z_DEBUG(">>> Allocating queryable for (%ju:%.*s)", (uintmax_t)q->_key._id, (int)_z_string_len(&q->_key._suffix), _z_string_data(&q->_key._suffix)); @@ -132,37 +174,81 @@ _z_session_queryable_rc_t *_z_register_session_queryable(_z_session_t *zn, _z_se return ret; } -z_result_t _z_trigger_queryables(_z_session_rc_t *zsrc, _z_msg_query_t *msgq, const _z_keyexpr_t q_key, uint32_t qid, - const _z_bytes_t attachment) { - z_result_t ret = _Z_RES_OK; - _z_session_t *zn = _Z_RC_IN_VAL(zsrc); - - _z_session_mutex_lock(zn); - - _z_keyexpr_t key = __unsafe_z_get_expanded_key_from_key(zn, &q_key, true); - if (_z_keyexpr_has_suffix(&key)) { - _z_session_queryable_rc_list_t *qles = __unsafe_z_get_session_queryable_by_key(zn, key); - +static z_result_t _z_session_queryable_get_infos(_z_session_t *zn, const _z_keyexpr_t *keyexpr, _z_keyexpr_t *key, + _z_queryable_infos_svec_t *qles, size_t *qle_nb) { + // Check cache + if (!_z_queryable_get_from_cache(zn, keyexpr, key, qles, qle_nb)) { + _Z_DEBUG("Resolving %d - %.*s on mapping 0x%x", keyexpr->_id, (int)_z_string_len(&keyexpr->_suffix), + _z_string_data(&keyexpr->_suffix), _z_keyexpr_mapping_id(keyexpr)); + _z_session_mutex_lock(zn); + *key = __unsafe_z_get_expanded_key_from_key(zn, keyexpr, true); + + if (!_z_keyexpr_has_suffix(key)) { + _z_session_mutex_unlock(zn); + return _Z_ERR_KEYEXPR_UNKNOWN; + } + // Get queryable list + z_result_t ret = __unsafe_z_get_session_queryable_by_key(zn, key, qles); _z_session_mutex_unlock(zn); + if (ret != _Z_RES_OK) { + return ret; + } + *qle_nb = _z_queryable_infos_svec_len(qles); + // Update cache + _z_queryable_update_cache(zn, keyexpr, key, qles); + } + return _Z_RES_OK; +} - // Build the z_query - _z_query_t q = _z_query_create(&msgq->_ext_value, &key, &msgq->_parameters, zsrc, qid, attachment); - _z_query_rc_t query = _z_query_rc_new_from_val(&q); - // Parse session_queryable list - _z_session_queryable_rc_list_t *xs = qles; - while (xs != NULL) { - _z_session_queryable_rc_t *qle = _z_session_queryable_rc_list_head(xs); - _Z_RC_IN_VAL(qle)->_callback(&query, _Z_RC_IN_VAL(qle)->_arg); - xs = _z_session_queryable_rc_list_tail(xs); +static z_result_t _z_trigger_queryables_inner(_z_session_rc_t *zsrc, _z_msg_query_t *msgq, const _z_keyexpr_t *q_key, + uint32_t qid) { + _z_session_t *zn = _Z_RC_IN_VAL(zsrc); + _z_keyexpr_t key; + _z_queryable_infos_svec_t qles; + size_t qle_nb; + // Retrieve sub infos + _Z_RETURN_IF_ERR(_z_session_queryable_get_infos(zn, q_key, &key, &qles, &qle_nb)); + // Check if there are queryables + _Z_DEBUG("Triggering %ju queryables for key %d - %.*s", (uintmax_t)qle_nb, key._id, + (int)_z_string_len(&key._suffix), _z_string_data(&key._suffix)); + if (qle_nb == 0) { + _z_keyexpr_clear(&key); + return _Z_RES_OK; + } + // Check anyke + char *slice_end = _z_ptr_char_offset((char *)msgq->_parameters.start, (ptrdiff_t)msgq->_parameters.len); + bool anyke = false; + if (_z_slice_check(&msgq->_parameters)) { + if (_z_strstr((char *)msgq->_parameters.start, slice_end, Z_SELECTOR_QUERY_MATCH) != NULL) { + anyke = true; } - // Clean up - _z_query_rc_drop(&query); - _z_session_queryable_rc_list_free(&qles); - } else { - _z_session_mutex_unlock(zn); - ret = _Z_ERR_KEYEXPR_UNKNOWN; } + // Build the z_query + _z_query_t q = + _z_query_alias(&msgq->_ext_value, &key, &msgq->_parameters, zsrc, qid, &msgq->_ext_attachment, anyke); + _z_query_rc_t query = _z_query_rc_new_from_val(&q); + // Parse session_queryable svec + for (size_t i = 0; i < qle_nb; i++) { + _z_queryable_infos_t *qle_info = _z_queryable_infos_svec_get(&qles, i); + qle_info->callback(&query, qle_info->arg); + } + // Clean up + _z_keyexpr_clear(&key); + _z_query_rc_drop(&query); +#if Z_FEATURE_RX_CACHE != 1 + _z_queryable_infos_svec_release(&qles); // Otherwise it's released with cache +#endif + return _Z_RES_OK; +} +z_result_t _z_trigger_queryables(_z_session_rc_t *zsrc, _z_msg_query_t *msgq, _z_keyexpr_t *q_key, uint32_t qid) { + z_result_t ret = _z_trigger_queryables_inner(zsrc, msgq, q_key, qid); + // Clean up + _z_keyexpr_clear(q_key); + _z_encoding_clear(&msgq->_ext_value.encoding); + _z_bytes_aliased_drop(&msgq->_ext_value.payload); + _z_bytes_drop(&msgq->_ext_attachment); + _z_slice_clear(&msgq->_parameters); return ret; } diff --git a/src/session/rx.c b/src/session/rx.c index 70213b898..793682a47 100644 --- a/src/session/rx.c +++ b/src/session/rx.c @@ -93,8 +93,7 @@ z_result_t _z_handle_network_message(_z_session_rc_t *zsrc, _z_zenoh_message_t * case _Z_REQUEST_QUERY: { #if Z_FEATURE_QUERYABLE == 1 _z_msg_query_t *query = &req->_body._query; - ret = _z_trigger_queryables(zsrc, query, req->_key, (uint32_t)req->_rid, - req->_body._query._ext_attachment); + ret = _z_trigger_queryables(zsrc, query, &req->_key, (uint32_t)req->_rid); #else _Z_DEBUG("_Z_REQUEST_QUERY dropped, queryables not supported"); #endif diff --git a/src/session/utils.c b/src/session/utils.c index 4c2ae96f6..ca80d4e94 100644 --- a/src/session/utils.c +++ b/src/session/utils.c @@ -64,6 +64,7 @@ z_result_t _z_session_init(_z_session_rc_t *zsrc, _z_id_t *zid) { zn->_remote_subscriptions = NULL; #if Z_FEATURE_RX_CACHE == 1 memset(&zn->_subscription_cache, 0, sizeof(zn->_subscription_cache)); + memset(&zn->_queryable_cache, 0, sizeof(zn->_queryable_cache)); #endif #endif #if Z_FEATURE_QUERYABLE == 1 @@ -118,6 +119,7 @@ void _z_session_clear(_z_session_t *zn) { _z_flush_subscriptions(zn); #if Z_FEATURE_RX_CACHE == 1 _z_subscription_cache_clear(&zn->_subscription_cache); + _z_queryable_cache_clear(&zn->_queryable_cache); #endif #endif #if Z_FEATURE_QUERYABLE == 1 From 4ebfe6d8949735eb6e0270da90334b0abf5ba7f5 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Sat, 9 Nov 2024 22:11:15 +0100 Subject: [PATCH 22/30] feat: align reply with sub & queryables --- include/zenoh-pico/net/reply.h | 30 +++++++++++++------ src/net/reply.c | 53 ++-------------------------------- src/net/sample.c | 2 +- src/session/query.c | 27 ++++++++--------- 4 files changed, 36 insertions(+), 76 deletions(-) diff --git a/include/zenoh-pico/net/reply.h b/include/zenoh-pico/net/reply.h index fcc8876c8..c36207fa1 100644 --- a/include/zenoh-pico/net/reply.h +++ b/include/zenoh-pico/net/reply.h @@ -59,11 +59,6 @@ typedef struct _z_reply_data_t { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_reply_data_t _z_reply_data_null(void) { return (_z_reply_data_t){0}; } -static inline _z_reply_data_t _z_reply_data_init(void) { - _z_reply_data_t reply_data = _z_reply_data_null(); - reply_data._tag = _Z_REPLY_TAG_NONE; - return reply_data; -} void _z_reply_data_clear(_z_reply_data_t *rd); z_result_t _z_reply_data_copy(_z_reply_data_t *dst, const _z_reply_data_t *src); @@ -85,14 +80,31 @@ typedef struct _z_reply_t { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_reply_t _z_reply_null(void) { return (_z_reply_t){0}; } +static inline _z_reply_t _z_reply_alias(_z_keyexpr_t *keyexpr, _z_id_t id, const _z_bytes_t *payload, + const _z_timestamp_t *timestamp, _z_encoding_t *encoding, z_sample_kind_t kind, + const _z_bytes_t *attachment) { + return (_z_reply_t){ + .data.replier_id = id, + .data._tag = _Z_REPLY_TAG_DATA, + .data._result.sample.keyexpr = *keyexpr, + .data._result.sample.kind = kind, + .data._result.sample.timestamp = *timestamp, + .data._result.sample.payload = *payload, + .data._result.sample.attachment = *attachment, + .data._result.sample.encoding = *encoding, + }; +} +static inline _z_reply_t _z_reply_err_alias(const _z_bytes_t *payload, _z_encoding_t *encoding) { + return (_z_reply_t){ + .data._tag = _Z_REPLY_TAG_ERROR, + .data._result.error.payload = *payload, + .data._result.error.encoding = *encoding, + }; +} _z_reply_t _z_reply_move(_z_reply_t *src_reply); void _z_reply_clear(_z_reply_t *src); void _z_reply_free(_z_reply_t **hello); z_result_t _z_reply_copy(_z_reply_t *dst, const _z_reply_t *src); -_z_reply_t _z_reply_create(_z_keyexpr_t *keyexpr, _z_id_t id, const _z_bytes_t *payload, - const _z_timestamp_t *timestamp, _z_encoding_t *encoding, z_sample_kind_t kind, - const _z_bytes_t *attachment); -_z_reply_t _z_reply_err_create(const _z_bytes_t payload, _z_encoding_t *encoding); typedef struct _z_pending_reply_t { _z_reply_t _reply; diff --git a/src/net/reply.c b/src/net/reply.c index 67987cb35..9c06b2674 100644 --- a/src/net/reply.c +++ b/src/net/reply.c @@ -39,7 +39,6 @@ void _z_reply_data_free(_z_reply_data_t **reply_data) { } z_result_t _z_reply_data_copy(_z_reply_data_t *dst, const _z_reply_data_t *src) { - *dst = _z_reply_data_init(); if (src->_tag == _Z_REPLY_TAG_DATA) { _Z_RETURN_IF_ERR(_z_sample_copy(&dst->_result.sample, &src->_result.sample)); } else if (src->_tag == _Z_REPLY_TAG_ERROR) { @@ -69,11 +68,7 @@ void _z_reply_free(_z_reply_t **reply) { } } -z_result_t _z_reply_copy(_z_reply_t *dst, const _z_reply_t *src) { - *dst = _z_reply_null(); - _Z_RETURN_IF_ERR(_z_reply_data_copy(&dst->data, &src->data)); - return _Z_RES_OK; -} +z_result_t _z_reply_copy(_z_reply_t *dst, const _z_reply_t *src) { return _z_reply_data_copy(&dst->data, &src->data); } bool _z_pending_reply_eq(const _z_pending_reply_t *one, const _z_pending_reply_t *two) { return one->_tstamp.time == two->_tstamp.time; @@ -87,48 +82,4 @@ void _z_pending_reply_clear(_z_pending_reply_t *pr) { _z_timestamp_clear(&pr->_tstamp); } -_z_reply_t _z_reply_create(_z_keyexpr_t *keyexpr, _z_id_t id, const _z_bytes_t *payload, - const _z_timestamp_t *timestamp, _z_encoding_t *encoding, z_sample_kind_t kind, - const _z_bytes_t *attachment) { - _z_reply_t reply = _z_reply_null(); - reply.data._tag = _Z_REPLY_TAG_DATA; - reply.data.replier_id = id; - - // Create reply sample - reply.data._result.sample.keyexpr = _z_keyexpr_steal(keyexpr); - reply.data._result.sample.kind = kind; - reply.data._result.sample.timestamp = _z_timestamp_duplicate(timestamp); - _z_bytes_copy(&reply.data._result.sample.payload, payload); - _z_bytes_copy(&reply.data._result.sample.attachment, attachment); - _z_encoding_move(&reply.data._result.sample.encoding, encoding); - - return reply; -} - -_z_reply_t _z_reply_err_create(const _z_bytes_t payload, _z_encoding_t *encoding) { - _z_reply_t reply = _z_reply_null(); - reply.data._tag = _Z_REPLY_TAG_ERROR; - _z_bytes_copy(&reply.data._result.error.payload, &payload); - _z_encoding_move(&reply.data._result.error.encoding, encoding); - return reply; -} -#else -_z_reply_t _z_reply_create(_z_keyexpr_t *keyexpr, _z_id_t id, const _z_bytes_t *payload, - const _z_timestamp_t *timestamp, _z_encoding_t *encoding, z_sample_kind_t kind, - const _z_bytes_t *attachment) { - _ZP_UNUSED(keyexpr); - _ZP_UNUSED(id); - _ZP_UNUSED(payload); - _ZP_UNUSED(timestamp); - _ZP_UNUSED(encoding); - _ZP_UNUSED(kind); - _ZP_UNUSED(attachment); - return _z_reply_null(); -} - -_z_reply_t _z_reply_err_create(const _z_bytes_t payload, _z_encoding_t *encoding) { - _ZP_UNUSED(payload); - _ZP_UNUSED(encoding); - return _z_reply_null(); -} -#endif +#endif // Z_FEATURE_QUERY == 1 diff --git a/src/net/sample.c b/src/net/sample.c index 58dcd0fa1..b700e49c1 100644 --- a/src/net/sample.c +++ b/src/net/sample.c @@ -27,7 +27,7 @@ void _z_sample_move(_z_sample_t *dst, _z_sample_t *src) { void _z_sample_clear(_z_sample_t *sample) { _z_keyexpr_clear(&sample->keyexpr); _z_encoding_clear(&sample->encoding); - _z_bytes_aliased_drop(&sample->payload); + _z_bytes_drop(&sample->payload); _z_bytes_drop(&sample->attachment); } diff --git a/src/session/query.c b/src/session/query.c index 241839551..9653b8882 100644 --- a/src/session/query.c +++ b/src/session/query.c @@ -129,8 +129,8 @@ z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, } // Build the reply - _z_reply_t reply = _z_reply_create(&expanded_ke, zn->_local_zid, &msg->_payload, &msg->_commons._timestamp, - &msg->_encoding, kind, &msg->_attachment); + _z_reply_t reply = _z_reply_alias(&expanded_ke, zn->_local_zid, &msg->_payload, &msg->_commons._timestamp, + &msg->_encoding, kind, &msg->_attachment); bool drop = false; // Verify if this is a newer reply, free the old one in case it is @@ -161,15 +161,13 @@ z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, if (pen_rep != NULL) { if (pen_qry->_consolidation == Z_CONSOLIDATION_MODE_MONOTONIC) { // No need to store the whole reply in the monotonic mode. - _z_reply_t partial_reply; - (void)memset(&partial_reply, 0, - sizeof(_z_reply_t)); // Avoid warnings on uninitialized values on the reply - partial_reply.data._tag = _Z_REPLY_TAG_DATA; - partial_reply.data._result.sample.keyexpr = + pen_rep->_reply = _z_reply_null(); + pen_rep->_reply.data._tag = _Z_REPLY_TAG_DATA; + pen_rep->_reply.data._result.sample.keyexpr = _z_keyexpr_duplicate(&reply.data._result.sample.keyexpr); - pen_rep->_reply = partial_reply; } else { - pen_rep->_reply = reply; // Store the whole reply in the latest mode + // Copy the reply to store it out of context + ret = _z_reply_copy(&pen_rep->_reply, &reply); } pen_rep->_tstamp = _z_timestamp_duplicate(&msg->_commons._timestamp); pen_qry->_pending_replies = _z_pending_reply_list_push(pen_qry->_pending_replies, pen_rep); @@ -189,11 +187,10 @@ z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, _z_reply_clear(&cb_reply); return ret; } - // Other cases - if (drop || (ret != _Z_RES_OK)) { - _z_reply_clear(&reply); - } - + // Clean up + _z_bytes_aliased_drop(&msg->_payload); + _z_bytes_drop(&msg->_attachment); + _z_encoding_clear(&msg->_encoding); return ret; } @@ -208,7 +205,7 @@ z_result_t _z_trigger_query_reply_err(_z_session_t *zn, _z_zint_t id, _z_msg_err } // Build the reply - _z_reply_t reply = _z_reply_err_create(msg->_payload, &msg->_encoding); + _z_reply_t reply = _z_reply_err_alias(&msg->_payload, &msg->_encoding); _z_session_mutex_unlock(zn); From e73e357a30eb6414a0df174668e79fc0249500f8 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Sat, 9 Nov 2024 22:12:53 +0100 Subject: [PATCH 23/30] feat: nothing to clear in frame --- src/protocol/definitions/transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/protocol/definitions/transport.c b/src/protocol/definitions/transport.c index 0cfd92356..fa910b771 100644 --- a/src/protocol/definitions/transport.c +++ b/src/protocol/definitions/transport.c @@ -40,7 +40,7 @@ void _z_t_msg_close_clear(_z_t_msg_close_t *msg) { (void)(msg); } void _z_t_msg_keep_alive_clear(_z_t_msg_keep_alive_t *msg) { (void)(msg); } -void _z_t_msg_frame_clear(_z_t_msg_frame_t *msg) { _z_network_message_svec_clear(&msg->_messages); } +void _z_t_msg_frame_clear(_z_t_msg_frame_t *msg) { (void)(msg); } void _z_t_msg_fragment_clear(_z_t_msg_fragment_t *msg) { _z_slice_clear(&msg->_payload); } From a6548499e86f3848fd69c6a8dc39806920c1e0cf Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Sat, 9 Nov 2024 22:20:29 +0100 Subject: [PATCH 24/30] fix: reply clean up --- src/session/query.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/session/query.c b/src/session/query.c index 9653b8882..215e64ed6 100644 --- a/src/session/query.c +++ b/src/session/query.c @@ -184,8 +184,6 @@ z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, _z_reply_t cb_reply = _z_reply_null(); cb_reply = _z_reply_move(&reply); pen_qry->_callback(&cb_reply, pen_qry->_arg); - _z_reply_clear(&cb_reply); - return ret; } // Clean up _z_bytes_aliased_drop(&msg->_payload); @@ -214,14 +212,11 @@ z_result_t _z_trigger_query_reply_err(_z_session_t *zn, _z_zint_t id, _z_msg_err _z_reply_t cb_reply = _z_reply_null(); cb_reply = _z_reply_move(&reply); pen_qry->_callback(&cb_reply, pen_qry->_arg); - _z_reply_clear(&cb_reply); } - - if (ret != _Z_RES_OK) { - _z_reply_clear(&reply); - } - - return ret; + // Clean up + _z_bytes_aliased_drop(&msg->_payload); + _z_encoding_clear(&msg->_encoding); + return ret; } z_result_t _z_trigger_query_reply_final(_z_session_t *zn, _z_zint_t id) { From 10a7c2a4f6f8c573b72a39a1336de2065385a821 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Sat, 9 Nov 2024 22:51:11 +0100 Subject: [PATCH 25/30] feat: streamline replies --- include/zenoh-pico/session/query.h | 2 +- include/zenoh-pico/session/reply.h | 2 +- src/session/query.c | 110 +++++++++++++---------------- src/session/reply.c | 2 +- src/session/rx.c | 2 +- 5 files changed, 53 insertions(+), 65 deletions(-) diff --git a/include/zenoh-pico/session/query.h b/include/zenoh-pico/session/query.h index 9a8ea69ae..c1267e348 100644 --- a/include/zenoh-pico/session/query.h +++ b/include/zenoh-pico/session/query.h @@ -27,7 +27,7 @@ _z_zint_t _z_get_query_id(_z_session_t *zn); _z_pending_query_t *_z_get_pending_query_by_id(_z_session_t *zn, const _z_zint_t id); z_result_t _z_register_pending_query(_z_session_t *zn, _z_pending_query_t *pq); -z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, _z_zint_t reply_context, const _z_keyexpr_t keyexpr, +z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, _z_zint_t reply_context, _z_keyexpr_t *keyexpr, _z_msg_put_t *msg, z_sample_kind_t kind); z_result_t _z_trigger_query_reply_err(_z_session_t *zn, _z_zint_t id, _z_msg_err_t *msg); z_result_t _z_trigger_query_reply_final(_z_session_t *zn, _z_zint_t id); diff --git a/include/zenoh-pico/session/reply.h b/include/zenoh-pico/session/reply.h index c10aa0b28..083fed40f 100644 --- a/include/zenoh-pico/session/reply.h +++ b/include/zenoh-pico/session/reply.h @@ -22,7 +22,7 @@ #ifndef ZENOH_PICO_SESSION_REPLY_H #define ZENOH_PICO_SESSION_REPLY_H -z_result_t _z_trigger_reply_partial(_z_session_t *zn, _z_zint_t id, _z_keyexpr_t key, _z_msg_reply_t *reply); +z_result_t _z_trigger_reply_partial(_z_session_t *zn, _z_zint_t id, _z_keyexpr_t *key, _z_msg_reply_t *reply); z_result_t _z_trigger_reply_err(_z_session_t *zn, _z_zint_t id, _z_msg_err_t *error); diff --git a/src/session/query.c b/src/session/query.c index 215e64ed6..22f05571c 100644 --- a/src/session/query.c +++ b/src/session/query.c @@ -111,39 +111,38 @@ z_result_t _z_register_pending_query(_z_session_t *zn, _z_pending_query_t *pen_q return ret; } -z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, const _z_keyexpr_t keyexpr, - _z_msg_put_t *msg, z_sample_kind_t kind) { - z_result_t ret = _Z_RES_OK; - +static z_result_t _z_trigger_query_reply_partial_inner(_z_session_t *zn, const _z_zint_t id, + const _z_keyexpr_t *keyexpr, _z_msg_put_t *msg, + z_sample_kind_t kind) { _z_session_mutex_lock(zn); + // Get query infos _z_pending_query_t *pen_qry = __unsafe__z_get_pending_query_by_id(zn, id); - if ((ret == _Z_RES_OK) && (pen_qry == NULL)) { - ret = _Z_ERR_ENTITY_UNKNOWN; + if (pen_qry == NULL) { + _z_session_mutex_unlock(zn); + return _Z_ERR_ENTITY_UNKNOWN; } - - _z_keyexpr_t expanded_ke = __unsafe_z_get_expanded_key_from_key(zn, &keyexpr, true); - if ((ret == _Z_RES_OK) && - ((pen_qry->_anykey == false) && (_z_keyexpr_suffix_intersects(&pen_qry->_key, &keyexpr) == false))) { - ret = _Z_ERR_QUERY_NOT_MATCH; + _z_keyexpr_t expanded_ke = __unsafe_z_get_expanded_key_from_key(zn, keyexpr, true); + if (!pen_qry->_anykey && !_z_keyexpr_suffix_intersects(&pen_qry->_key, keyexpr)) { + _z_session_mutex_unlock(zn); + return _Z_ERR_QUERY_NOT_MATCH; } - // Build the reply _z_reply_t reply = _z_reply_alias(&expanded_ke, zn->_local_zid, &msg->_payload, &msg->_commons._timestamp, &msg->_encoding, kind, &msg->_attachment); - - bool drop = false; - // Verify if this is a newer reply, free the old one in case it is - if ((ret == _Z_RES_OK) && ((pen_qry->_consolidation == Z_CONSOLIDATION_MODE_LATEST) || - (pen_qry->_consolidation == Z_CONSOLIDATION_MODE_MONOTONIC))) { + // Process monotonic & latest consolidation mode + if ((pen_qry->_consolidation == Z_CONSOLIDATION_MODE_LATEST) || + (pen_qry->_consolidation == Z_CONSOLIDATION_MODE_MONOTONIC)) { + bool drop = false; _z_pending_reply_list_t *pen_rps = pen_qry->_pending_replies; _z_pending_reply_t *pen_rep = NULL; + + // Verify if this is a newer reply, free the old one in case it is while (pen_rps != NULL) { pen_rep = _z_pending_reply_list_head(pen_rps); - // Check if this is the same resource key if (_z_string_equals(&pen_rep->_reply.data._result.sample.keyexpr._suffix, - &reply.data._result.sample.keyexpr._suffix) == true) { + &reply.data._result.sample.keyexpr._suffix)) { if (msg->_commons._timestamp.time <= pen_rep->_tstamp.time) { drop = true; } else { @@ -154,38 +153,39 @@ z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, } pen_rps = _z_pending_reply_list_tail(pen_rps); } - - if (drop == false) { + if (!drop) { // Cache most recent reply pen_rep = (_z_pending_reply_t *)z_malloc(sizeof(_z_pending_reply_t)); - if (pen_rep != NULL) { - if (pen_qry->_consolidation == Z_CONSOLIDATION_MODE_MONOTONIC) { - // No need to store the whole reply in the monotonic mode. - pen_rep->_reply = _z_reply_null(); - pen_rep->_reply.data._tag = _Z_REPLY_TAG_DATA; - pen_rep->_reply.data._result.sample.keyexpr = - _z_keyexpr_duplicate(&reply.data._result.sample.keyexpr); - } else { - // Copy the reply to store it out of context - ret = _z_reply_copy(&pen_rep->_reply, &reply); - } - pen_rep->_tstamp = _z_timestamp_duplicate(&msg->_commons._timestamp); - pen_qry->_pending_replies = _z_pending_reply_list_push(pen_qry->_pending_replies, pen_rep); + if (pen_rep == NULL) { + return _Z_ERR_SYSTEM_OUT_OF_MEMORY; + } + if (pen_qry->_consolidation == Z_CONSOLIDATION_MODE_MONOTONIC) { + // No need to store the whole reply in the monotonic mode. + pen_rep->_reply = _z_reply_null(); + pen_rep->_reply.data._tag = _Z_REPLY_TAG_DATA; + pen_rep->_reply.data._result.sample.keyexpr = _z_keyexpr_duplicate(&reply.data._result.sample.keyexpr); } else { - ret = _Z_ERR_SYSTEM_OUT_OF_MEMORY; + // Copy the reply to store it out of context + _Z_RETURN_IF_ERR(_z_reply_copy(&pen_rep->_reply, &reply)); } + pen_rep->_tstamp = _z_timestamp_duplicate(&msg->_commons._timestamp); + pen_qry->_pending_replies = _z_pending_reply_list_push(pen_qry->_pending_replies, pen_rep); } } - _z_session_mutex_unlock(zn); - // Trigger the user callback - if ((ret == _Z_RES_OK) && (pen_qry->_consolidation != Z_CONSOLIDATION_MODE_LATEST)) { - _z_reply_t cb_reply = _z_reply_null(); - cb_reply = _z_reply_move(&reply); - pen_qry->_callback(&cb_reply, pen_qry->_arg); + // Trigger callback if applicable + if (pen_qry->_consolidation != Z_CONSOLIDATION_MODE_LATEST) { + pen_qry->_callback(&reply, pen_qry->_arg); } + return _Z_RES_OK; +} + +z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, _z_keyexpr_t *keyexpr, + _z_msg_put_t *msg, z_sample_kind_t kind) { + z_result_t ret = _z_trigger_query_reply_partial_inner(zn, id, keyexpr, msg, kind); // Clean up + _z_keyexpr_clear(keyexpr); _z_bytes_aliased_drop(&msg->_payload); _z_bytes_drop(&msg->_attachment); _z_encoding_clear(&msg->_encoding); @@ -195,38 +195,32 @@ z_result_t _z_trigger_query_reply_partial(_z_session_t *zn, const _z_zint_t id, z_result_t _z_trigger_query_reply_err(_z_session_t *zn, _z_zint_t id, _z_msg_err_t *msg) { z_result_t ret = _Z_RES_OK; + // Retrieve query _z_session_mutex_lock(zn); - _z_pending_query_t *pen_qry = __unsafe__z_get_pending_query_by_id(zn, id); - if ((ret == _Z_RES_OK) && (pen_qry == NULL)) { + if (pen_qry == NULL) { ret = _Z_ERR_ENTITY_UNKNOWN; } - - // Build the reply - _z_reply_t reply = _z_reply_err_alias(&msg->_payload, &msg->_encoding); - _z_session_mutex_unlock(zn); // Trigger the user callback if (ret == _Z_RES_OK) { - _z_reply_t cb_reply = _z_reply_null(); - cb_reply = _z_reply_move(&reply); - pen_qry->_callback(&cb_reply, pen_qry->_arg); + _z_reply_t reply = _z_reply_err_alias(&msg->_payload, &msg->_encoding); + pen_qry->_callback(&reply, pen_qry->_arg); } // Clean up _z_bytes_aliased_drop(&msg->_payload); _z_encoding_clear(&msg->_encoding); - return ret; + return ret; } z_result_t _z_trigger_query_reply_final(_z_session_t *zn, _z_zint_t id) { z_result_t ret = _Z_RES_OK; + // Retrieve query _z_session_mutex_lock(zn); - - // Final reply received for unknown query id _z_pending_query_t *pen_qry = __unsafe__z_get_pending_query_by_id(zn, id); - if ((ret == _Z_RES_OK) && (pen_qry == NULL)) { + if (pen_qry == NULL) { ret = _Z_ERR_ENTITY_UNKNOWN; } // The reply is the final one, apply consolidation if needed @@ -235,21 +229,15 @@ z_result_t _z_trigger_query_reply_final(_z_session_t *zn, _z_zint_t id) { _z_pending_reply_t *pen_rep = _z_pending_reply_list_head(pen_qry->_pending_replies); // Trigger the query handler - _z_reply_t cb_reply = _z_reply_null(); - cb_reply = _z_reply_move(&pen_rep->_reply); - pen_qry->_callback(&cb_reply, pen_qry->_arg); + pen_qry->_callback(&pen_rep->_reply, pen_qry->_arg); pen_qry->_pending_replies = _z_pending_reply_list_pop(pen_qry->_pending_replies, NULL); - _z_reply_clear(&cb_reply); } } - if (ret == _Z_RES_OK) { // Dropping a pending query triggers the dropper callback that is now the equivalent to a reply with the FINAL zn->_pending_queries = _z_pending_query_list_drop_filter(zn->_pending_queries, _z_pending_query_eq, pen_qry); } - _z_session_mutex_unlock(zn); - return ret; } diff --git a/src/session/reply.c b/src/session/reply.c index 7eb13194c..6361099ee 100644 --- a/src/session/reply.c +++ b/src/session/reply.c @@ -19,7 +19,7 @@ #include "zenoh-pico/session/query.h" #include "zenoh-pico/utils/logging.h" -z_result_t _z_trigger_reply_partial(_z_session_t *zn, _z_zint_t id, _z_keyexpr_t key, _z_msg_reply_t *reply) { +z_result_t _z_trigger_reply_partial(_z_session_t *zn, _z_zint_t id, _z_keyexpr_t *key, _z_msg_reply_t *reply) { z_result_t ret = _Z_RES_OK; // TODO check id to know where to dispatch diff --git a/src/session/rx.c b/src/session/rx.c index 793682a47..c15e53810 100644 --- a/src/session/rx.c +++ b/src/session/rx.c @@ -132,7 +132,7 @@ z_result_t _z_handle_network_message(_z_session_rc_t *zsrc, _z_zenoh_message_t * switch (response->_tag) { case _Z_RESPONSE_BODY_REPLY: { _z_msg_reply_t *reply = &response->_body._reply; - ret = _z_trigger_reply_partial(zn, response->_request_id, response->_key, reply); + ret = _z_trigger_reply_partial(zn, response->_request_id, &response->_key, reply); } break; case _Z_RESPONSE_BODY_ERR: { _z_msg_err_t *error = &response->_body._err; From b59d97dad972274f1462c18d763ae54e5a15aaff Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Sun, 10 Nov 2024 10:01:36 +0100 Subject: [PATCH 26/30] feat: query is not a rc and store a session rc --- examples/unix/c11/z_get_attachment.c | 7 ++-- examples/unix/c11/z_queryable_attachment.c | 7 ++-- include/zenoh-pico/api/types.h | 2 +- include/zenoh-pico/net/query.h | 10 +++--- include/zenoh-pico/net/reply.h | 6 ++-- include/zenoh-pico/protocol/core.h | 3 ++ include/zenoh-pico/session/session.h | 4 +-- src/api/api.c | 40 +++++++--------------- src/net/query.c | 9 ++--- src/session/queryable.c | 6 ++-- 10 files changed, 40 insertions(+), 54 deletions(-) diff --git a/examples/unix/c11/z_get_attachment.c b/examples/unix/c11/z_get_attachment.c index 65404138b..959d45a09 100644 --- a/examples/unix/c11/z_get_attachment.c +++ b/examples/unix/c11/z_get_attachment.c @@ -68,12 +68,11 @@ void reply_handler(z_loaned_reply_t *reply, void *ctx) { // Check attachment const z_loaned_bytes_t *attachment = z_sample_attachment(sample); - if (attachment == NULL) { - return; - } ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); size_t attachment_len; - ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len); + if (ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len) != 0) { + return; + } kv_pair_t *kvp = (kv_pair_t *)malloc(sizeof(kv_pair_t) * attachment_len); for (size_t i = 0; i < attachment_len; ++i) { ze_deserializer_deserialize_string(&deserializer, &kvp[i].key); diff --git a/examples/unix/c11/z_queryable_attachment.c b/examples/unix/c11/z_queryable_attachment.c index 20a2e9ad2..f1d121d28 100644 --- a/examples/unix/c11/z_queryable_attachment.c +++ b/examples/unix/c11/z_queryable_attachment.c @@ -68,10 +68,9 @@ void query_handler(z_loaned_query_t *query, void *ctx) { // Check attachment const z_loaned_bytes_t *attachment = z_query_attachment(query); - if (attachment != NULL) { - ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); - size_t attachment_len; - ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len); + ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); + size_t attachment_len; + if (ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len) == 0) { kv_pair_t *kvp = (kv_pair_t *)malloc(sizeof(kv_pair_t) * attachment_len); for (size_t i = 0; i < attachment_len; ++i) { ze_deserializer_deserialize_string(&deserializer, &kvp[i].key); diff --git a/include/zenoh-pico/api/types.h b/include/zenoh-pico/api/types.h index 53010ece7..26c703161 100644 --- a/include/zenoh-pico/api/types.h +++ b/include/zenoh-pico/api/types.h @@ -125,7 +125,7 @@ _Z_OWNED_TYPE_VALUE(_z_queryable_t, queryable) /** * Represents a Zenoh Query entity, received by Zenoh Queryable entities. */ -_Z_OWNED_TYPE_RC(_z_query_rc_t, query) +_Z_OWNED_TYPE_VALUE(_z_query_t, query) /** * Represents the encoding of a payload, in a MIME-like format. diff --git a/include/zenoh-pico/net/query.h b/include/zenoh-pico/net/query.h index f66996df9..ee774b27e 100644 --- a/include/zenoh-pico/net/query.h +++ b/include/zenoh-pico/net/query.h @@ -28,7 +28,7 @@ typedef struct _z_query_t { _z_value_t _value; _z_keyexpr_t _key; uint32_t _request_id; - _z_session_weak_t _zn; // Can't be an rc because of cross referencing + _z_session_rc_t _zn; _z_bytes_t _attachment; _z_string_t _parameters; bool _anyke; @@ -36,12 +36,14 @@ typedef struct _z_query_t { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_query_t _z_query_null(void) { return (_z_query_t){0}; } +static inline bool _z_query_check(const _z_query_t *query) { + return _z_keyexpr_check(&query->_key) || _z_value_check(&query->_value) || _z_bytes_check(&query->_attachment) || + _z_string_check(&query->_parameters); +} void _z_query_clear(_z_query_t *q); z_result_t _z_query_copy(_z_query_t *dst, const _z_query_t *src); void _z_query_free(_z_query_t **query); -_Z_REFCOUNT_DEFINE(_z_query, _z_query) - /** * Return type when declaring a queryable. */ @@ -59,7 +61,7 @@ static inline _z_query_t _z_query_alias(_z_value_t *value, _z_keyexpr_t *key, co bool anyke) { return (_z_query_t){ ._request_id = request_id, - ._zn = _z_session_rc_clone_as_weak(zn), + ._zn = *zn, ._parameters = _z_string_alias_slice(parameters), ._anyke = anyke, ._key = *key, diff --git a/include/zenoh-pico/net/reply.h b/include/zenoh-pico/net/reply.h index c36207fa1..48c4e2e52 100644 --- a/include/zenoh-pico/net/reply.h +++ b/include/zenoh-pico/net/reply.h @@ -83,7 +83,7 @@ static inline _z_reply_t _z_reply_null(void) { return (_z_reply_t){0}; } static inline _z_reply_t _z_reply_alias(_z_keyexpr_t *keyexpr, _z_id_t id, const _z_bytes_t *payload, const _z_timestamp_t *timestamp, _z_encoding_t *encoding, z_sample_kind_t kind, const _z_bytes_t *attachment) { - return (_z_reply_t){ + _z_reply_t r = { .data.replier_id = id, .data._tag = _Z_REPLY_TAG_DATA, .data._result.sample.keyexpr = *keyexpr, @@ -93,13 +93,15 @@ static inline _z_reply_t _z_reply_alias(_z_keyexpr_t *keyexpr, _z_id_t id, const .data._result.sample.attachment = *attachment, .data._result.sample.encoding = *encoding, }; + return r; } static inline _z_reply_t _z_reply_err_alias(const _z_bytes_t *payload, _z_encoding_t *encoding) { - return (_z_reply_t){ + _z_reply_t r = { .data._tag = _Z_REPLY_TAG_ERROR, .data._result.error.payload = *payload, .data._result.error.encoding = *encoding, }; + return r; } _z_reply_t _z_reply_move(_z_reply_t *src_reply); void _z_reply_clear(_z_reply_t *src); diff --git a/include/zenoh-pico/protocol/core.h b/include/zenoh-pico/protocol/core.h index d7ff3ec2f..c793656bd 100644 --- a/include/zenoh-pico/protocol/core.h +++ b/include/zenoh-pico/protocol/core.h @@ -172,6 +172,9 @@ typedef struct { // Warning: None of the sub-types require a non-0 initialization. Add a init function if it changes. static inline _z_value_t _z_value_null(void) { return (_z_value_t){0}; } +static inline bool _z_value_check(const _z_value_t *value) { + return _z_bytes_check(&value->payload) || _z_encoding_check(&value->encoding); +} _z_value_t _z_value_steal(_z_value_t *value); z_result_t _z_value_copy(_z_value_t *dst, const _z_value_t *src); void _z_value_move(_z_value_t *dst, _z_value_t *src); diff --git a/include/zenoh-pico/session/session.h b/include/zenoh-pico/session/session.h index d2aa10129..6296ad1f1 100644 --- a/include/zenoh-pico/session/session.h +++ b/include/zenoh-pico/session/session.h @@ -80,12 +80,12 @@ typedef struct { } _z_publication_t; // Forward type declaration to avoid cyclical include -typedef struct _z_query_rc_t _z_query_rc_t; +typedef struct _z_query_t _z_query_t; /** * The callback signature of the functions handling query messages. */ -typedef void (*_z_query_handler_t)(_z_query_rc_t *query, void *arg); +typedef void (*_z_query_handler_t)(_z_query_t *query, void *arg); typedef struct { _z_keyexpr_t _key; diff --git a/src/api/api.c b/src/api/api.c index 7cdb7d0a1..93c811f0b 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -417,17 +417,16 @@ z_query_consolidation_t z_query_consolidation_none(void) { z_query_consolidation_t z_query_consolidation_default(void) { return z_query_consolidation_auto(); } void z_query_parameters(const z_loaned_query_t *query, z_view_string_t *parameters) { - parameters->_val = _z_string_alias(_Z_RC_IN_VAL(query)->_parameters); + parameters->_val = _z_string_alias(query->_parameters); } -const z_loaned_bytes_t *z_query_attachment(const z_loaned_query_t *query) { return &_Z_RC_IN_VAL(query)->_attachment; } +const z_loaned_bytes_t *z_query_attachment(const z_loaned_query_t *query) { return &query->_attachment; } -const z_loaned_keyexpr_t *z_query_keyexpr(const z_loaned_query_t *query) { return &_Z_RC_IN_VAL(query)->_key; } +const z_loaned_keyexpr_t *z_query_keyexpr(const z_loaned_query_t *query) { return &query->_key; } -const z_loaned_bytes_t *z_query_payload(const z_loaned_query_t *query) { return &_Z_RC_IN_VAL(query)->_value.payload; } -const z_loaned_encoding_t *z_query_encoding(const z_loaned_query_t *query) { - return &_Z_RC_IN_VAL(query)->_value.encoding; -} +const z_loaned_bytes_t *z_query_payload(const z_loaned_query_t *query) { return &query->_value.payload; } + +const z_loaned_encoding_t *z_query_encoding(const z_loaned_query_t *query) { return &query->_value.encoding; } void z_closure_sample_call(const z_loaned_closure_sample_t *closure, z_loaned_sample_t *sample) { if (closure->call != NULL) { @@ -470,9 +469,6 @@ _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_config_t, config, _z_config_check, _z_config_nu _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_string_t, string, _z_string_check, _z_string_null, _z_string_copy, _z_string_clear) -bool _z_value_check(const _z_value_t *value) { - return _z_encoding_check(&value->encoding) || _z_bytes_check(&value->payload); -} _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_value_t, reply_err, _z_value_check, _z_value_null, _z_value_copy, _z_value_clear) _Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_keyexpr_t, keyexpr, _z_keyexpr_check, _z_keyexpr_null, _z_keyexpr_copy, @@ -1121,7 +1117,7 @@ bool z_reply_replier_id(const z_loaned_reply_t *reply, z_id_t *out_id) { #endif #if Z_FEATURE_QUERYABLE == 1 -_Z_OWNED_FUNCTIONS_RC_IMPL(query) +_Z_OWNED_FUNCTIONS_VALUE_IMPL(_z_query_t, query, _z_query_check, _z_query_null, _z_query_copy, _z_query_clear) void _z_queryable_drop(_z_queryable_t *queryable) { _z_undeclare_queryable(queryable); @@ -1191,9 +1187,7 @@ void z_query_reply_options_default(z_query_reply_options_t *options) { z_result_t z_query_reply(const z_loaned_query_t *query, const z_loaned_keyexpr_t *keyexpr, z_moved_bytes_t *payload, const z_query_reply_options_t *options) { - // Try upgrading session weak to rc - _z_session_rc_t sess_rc = _z_session_weak_upgrade_if_open(&_Z_RC_IN_VAL(query)->_zn); - if (_Z_RC_IS_NULL(&sess_rc)) { + if (_Z_RC_IS_NULL(&query->_zn)) { return _Z_ERR_SESSION_CLOSED; } // Set options @@ -1208,12 +1202,11 @@ z_result_t z_query_reply(const z_loaned_query_t *query, const z_loaned_keyexpr_t _z_value_t value = {.payload = _z_bytes_from_owned_bytes(&payload->_this), .encoding = _z_encoding_from_owned(&opts.encoding->_this)}; - z_result_t ret = _z_send_reply(_Z_RC_IN_VAL(query), &sess_rc, keyexpr_aliased, value, Z_SAMPLE_KIND_PUT, + z_result_t ret = _z_send_reply(query, &query->_zn, keyexpr_aliased, value, Z_SAMPLE_KIND_PUT, opts.congestion_control, opts.priority, opts.is_express, opts.timestamp, _z_bytes_from_owned_bytes(&opts.attachment->_this)); z_bytes_drop(payload); // Clean-up - _z_session_rc_drop(&sess_rc); z_encoding_drop(opts.encoding); z_bytes_drop(opts.attachment); return ret; @@ -1229,9 +1222,7 @@ void z_query_reply_del_options_default(z_query_reply_del_options_t *options) { z_result_t z_query_reply_del(const z_loaned_query_t *query, const z_loaned_keyexpr_t *keyexpr, const z_query_reply_del_options_t *options) { - // Try upgrading session weak to rc - _z_session_rc_t sess_rc = _z_session_weak_upgrade_if_open(&_Z_RC_IN_VAL(query)->_zn); - if (_Z_RC_IS_NULL(&sess_rc)) { + if (_Z_RC_IS_NULL(&query->_zn)) { return _Z_ERR_SESSION_CLOSED; } _z_keyexpr_t keyexpr_aliased = _z_keyexpr_alias_from_user_defined(*keyexpr, true); @@ -1244,11 +1235,10 @@ z_result_t z_query_reply_del(const z_loaned_query_t *query, const z_loaned_keyex _z_value_t value = {.payload = _z_bytes_null(), .encoding = _z_encoding_null()}; - z_result_t ret = _z_send_reply(_Z_RC_IN_VAL(query), &sess_rc, keyexpr_aliased, value, Z_SAMPLE_KIND_DELETE, + z_result_t ret = _z_send_reply(query, &query->_zn, keyexpr_aliased, value, Z_SAMPLE_KIND_DELETE, opts.congestion_control, opts.priority, opts.is_express, opts.timestamp, _z_bytes_from_owned_bytes(&opts.attachment->_this)); // Clean-up - _z_session_rc_drop(&sess_rc); z_bytes_drop(opts.attachment); return ret; } @@ -1257,9 +1247,7 @@ void z_query_reply_err_options_default(z_query_reply_err_options_t *options) { o z_result_t z_query_reply_err(const z_loaned_query_t *query, z_moved_bytes_t *payload, const z_query_reply_err_options_t *options) { - // Try upgrading session weak to rc - _z_session_rc_t sess_rc = _z_session_weak_upgrade_if_open(&_Z_RC_IN_VAL(query)->_zn); - if (_Z_RC_IS_NULL(&sess_rc)) { + if (_Z_RC_IS_NULL(&query->_zn)) { return _Z_ERR_SESSION_CLOSED; } z_query_reply_err_options_t opts; @@ -1271,9 +1259,7 @@ z_result_t z_query_reply_err(const z_loaned_query_t *query, z_moved_bytes_t *pay // Set value _z_value_t value = {.payload = _z_bytes_from_owned_bytes(&payload->_this), .encoding = _z_encoding_from_owned(&opts.encoding->_this)}; - - z_result_t ret = _z_send_reply_err(_Z_RC_IN_VAL(query), &sess_rc, value); - _z_session_rc_drop(&sess_rc); + z_result_t ret = _z_send_reply_err(query, &query->_zn, value); z_bytes_drop(payload); // Clean-up z_encoding_drop(opts.encoding); diff --git a/src/net/query.c b/src/net/query.c index b2048e2b1..dcf5b647a 100644 --- a/src/net/query.c +++ b/src/net/query.c @@ -22,13 +22,11 @@ void _z_query_clear_inner(_z_query_t *q) { _z_value_clear(&q->_value); _z_bytes_drop(&q->_attachment); _z_string_clear(&q->_parameters); - _z_session_weak_drop(&q->_zn); + _z_session_rc_drop(&q->_zn); } void _z_query_clear(_z_query_t *q) { - // Try to upgrade session weak to rc - _z_session_rc_t sess_rc = _z_session_weak_upgrade_if_open(&q->_zn); - if (!_Z_RC_IS_NULL(&sess_rc)) { + if (!_Z_RC_IS_NULL(&q->_zn)) { // Send REPLY_FINAL message _z_zenoh_message_t z_msg = _z_n_msg_make_response_final(q->_request_id); if (_z_send_n_msg(_Z_RC_IN_VAL(&q->_zn), &z_msg, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK) != @@ -36,7 +34,6 @@ void _z_query_clear(_z_query_t *q) { _Z_ERROR("Query send REPLY_FINAL transport failure !"); } _z_msg_clear(&z_msg); - _z_session_rc_drop(&sess_rc); } // Clean up memory _z_query_clear_inner(q); @@ -48,7 +45,7 @@ z_result_t _z_query_copy(_z_query_t *dst, const _z_query_t *src) { _Z_CLEAN_RETURN_IF_ERR(_z_value_copy(&dst->_value, &src->_value), _z_query_clear_inner(dst)); _Z_CLEAN_RETURN_IF_ERR(_z_bytes_copy(&dst->_attachment, &src->_attachment), _z_query_clear_inner(dst)); _Z_CLEAN_RETURN_IF_ERR(_z_string_copy(&dst->_parameters, &src->_parameters), _z_query_clear_inner(dst)); - _z_session_weak_copy(&dst->_zn, &src->_zn); + _z_session_rc_copy(&dst->_zn, &src->_zn); if (_Z_RC_IS_NULL(&dst->_zn)) { _z_query_clear_inner(dst); return _Z_ERR_SYSTEM_OUT_OF_MEMORY; diff --git a/src/session/queryable.c b/src/session/queryable.c index 2ac7eb69e..d3b120751 100644 --- a/src/session/queryable.c +++ b/src/session/queryable.c @@ -224,9 +224,8 @@ static z_result_t _z_trigger_queryables_inner(_z_session_rc_t *zsrc, _z_msg_quer } } // Build the z_query - _z_query_t q = + _z_query_t query = _z_query_alias(&msgq->_ext_value, &key, &msgq->_parameters, zsrc, qid, &msgq->_ext_attachment, anyke); - _z_query_rc_t query = _z_query_rc_new_from_val(&q); // Parse session_queryable svec for (size_t i = 0; i < qle_nb; i++) { _z_queryable_infos_t *qle_info = _z_queryable_infos_svec_get(&qles, i); @@ -234,7 +233,6 @@ static z_result_t _z_trigger_queryables_inner(_z_session_rc_t *zsrc, _z_msg_quer } // Clean up _z_keyexpr_clear(&key); - _z_query_rc_drop(&query); #if Z_FEATURE_RX_CACHE != 1 _z_queryable_infos_svec_release(&qles); // Otherwise it's released with cache #endif @@ -246,7 +244,7 @@ z_result_t _z_trigger_queryables(_z_session_rc_t *zsrc, _z_msg_query_t *msgq, _z // Clean up _z_keyexpr_clear(q_key); _z_encoding_clear(&msgq->_ext_value.encoding); - _z_bytes_aliased_drop(&msgq->_ext_value.payload); + _z_bytes_drop(&msgq->_ext_value.payload); _z_bytes_drop(&msgq->_ext_attachment); _z_slice_clear(&msgq->_parameters); return ret; From 8772aae473dbe362288d16955c7277191dafd69e Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Sun, 10 Nov 2024 11:52:34 +0100 Subject: [PATCH 27/30] fix: ci issues --- include/zenoh-pico/net/query.h | 8 +++---- include/zenoh-pico/net/reply.h | 24 +++++++------------ include/zenoh-pico/net/sample.h | 17 ++++++------- include/zenoh-pico/net/session.h | 4 +++- .../zenoh-pico/protocol/definitions/network.h | 2 +- src/session/utils.c | 8 +++++-- tests/modularity.py | 10 ++++---- 7 files changed, 38 insertions(+), 35 deletions(-) diff --git a/include/zenoh-pico/net/query.h b/include/zenoh-pico/net/query.h index ee774b27e..4cf60a4f7 100644 --- a/include/zenoh-pico/net/query.h +++ b/include/zenoh-pico/net/query.h @@ -25,8 +25,8 @@ * The query to be answered by a queryable. */ typedef struct _z_query_t { - _z_value_t _value; _z_keyexpr_t _key; + _z_value_t _value; uint32_t _request_id; _z_session_rc_t _zn; _z_bytes_t _attachment; @@ -60,13 +60,13 @@ static inline _z_query_t _z_query_alias(_z_value_t *value, _z_keyexpr_t *key, co _z_session_rc_t *zn, uint32_t request_id, const _z_bytes_t *attachment, bool anyke) { return (_z_query_t){ + ._key = *key, + ._value = *value, ._request_id = request_id, ._zn = *zn, + ._attachment = *attachment, ._parameters = _z_string_alias_slice(parameters), ._anyke = anyke, - ._key = *key, - ._attachment = *attachment, - ._value = *value, }; } void _z_queryable_clear(_z_queryable_t *qbl); diff --git a/include/zenoh-pico/net/reply.h b/include/zenoh-pico/net/reply.h index 48c4e2e52..f352be9a1 100644 --- a/include/zenoh-pico/net/reply.h +++ b/include/zenoh-pico/net/reply.h @@ -83,24 +83,18 @@ static inline _z_reply_t _z_reply_null(void) { return (_z_reply_t){0}; } static inline _z_reply_t _z_reply_alias(_z_keyexpr_t *keyexpr, _z_id_t id, const _z_bytes_t *payload, const _z_timestamp_t *timestamp, _z_encoding_t *encoding, z_sample_kind_t kind, const _z_bytes_t *attachment) { - _z_reply_t r = { - .data.replier_id = id, - .data._tag = _Z_REPLY_TAG_DATA, - .data._result.sample.keyexpr = *keyexpr, - .data._result.sample.kind = kind, - .data._result.sample.timestamp = *timestamp, - .data._result.sample.payload = *payload, - .data._result.sample.attachment = *attachment, - .data._result.sample.encoding = *encoding, - }; + _z_reply_t r; + r.data.replier_id = id; + r.data._tag = _Z_REPLY_TAG_DATA; + r.data._result.sample = _z_sample_alias(keyexpr, payload, timestamp, encoding, kind, _Z_N_QOS_DEFAULT, attachment, + Z_RELIABILITY_DEFAULT); return r; } static inline _z_reply_t _z_reply_err_alias(const _z_bytes_t *payload, _z_encoding_t *encoding) { - _z_reply_t r = { - .data._tag = _Z_REPLY_TAG_ERROR, - .data._result.error.payload = *payload, - .data._result.error.encoding = *encoding, - }; + _z_reply_t r; + r.data._tag = _Z_REPLY_TAG_ERROR; + r.data._result.error.payload = *payload; + r.data._result.error.encoding = *encoding; return r; } _z_reply_t _z_reply_move(_z_reply_t *src_reply); diff --git a/include/zenoh-pico/net/sample.h b/include/zenoh-pico/net/sample.h index 374241808..718fe95da 100644 --- a/include/zenoh-pico/net/sample.h +++ b/include/zenoh-pico/net/sample.h @@ -46,18 +46,19 @@ static inline bool _z_sample_check(const _z_sample_t *sample) { return _z_keyexpr_check(&sample->keyexpr) || _z_encoding_check(&sample->encoding) || _z_bytes_check(&sample->payload) || _z_bytes_check(&sample->attachment); } -static inline _z_sample_t _z_sample_alias(_z_keyexpr_t *key, _z_bytes_t *payload, const _z_timestamp_t *timestamp, - _z_encoding_t *encoding, const z_sample_kind_t kind, const _z_qos_t qos, - _z_bytes_t *attachment, z_reliability_t reliability) { +static inline _z_sample_t _z_sample_alias(const _z_keyexpr_t *key, const _z_bytes_t *payload, + const _z_timestamp_t *timestamp, const _z_encoding_t *encoding, + const z_sample_kind_t kind, const _z_qos_t qos, const _z_bytes_t *attachment, + z_reliability_t reliability) { return (_z_sample_t){ - .kind = kind, - .qos = qos, - .reliability = reliability, .keyexpr = *key, - .encoding = *encoding, - .attachment = *attachment, .payload = *payload, .timestamp = *timestamp, + .encoding = *encoding, + .kind = kind, + .qos = qos, + .attachment = *attachment, + .reliability = reliability, }; } void _z_sample_move(_z_sample_t *dst, _z_sample_t *src); diff --git a/include/zenoh-pico/net/session.h b/include/zenoh-pico/net/session.h index 6f2eae321..5362c1921 100644 --- a/include/zenoh-pico/net/session.h +++ b/include/zenoh-pico/net/session.h @@ -56,13 +56,15 @@ typedef struct _z_session_t { _z_subscription_rc_list_t *_remote_subscriptions; #if Z_FEATURE_RX_CACHE == 1 _z_subscription_cache_t _subscription_cache; - _z_queryable_cache_t _queryable_cache; #endif #endif // Session queryables #if Z_FEATURE_QUERYABLE == 1 _z_session_queryable_rc_list_t *_local_queryable; +#if Z_FEATURE_RX_CACHE == 1 + _z_queryable_cache_t _queryable_cache; +#endif #endif #if Z_FEATURE_QUERY == 1 _z_pending_query_list_t *_pending_queries; diff --git a/include/zenoh-pico/protocol/definitions/network.h b/include/zenoh-pico/protocol/definitions/network.h index bae5c47c1..24d86102c 100644 --- a/include/zenoh-pico/protocol/definitions/network.h +++ b/include/zenoh-pico/protocol/definitions/network.h @@ -91,7 +91,7 @@ static inline bool _z_n_qos_get_express(_z_n_qos_t n_qos) { return (bool)(n_qos. #define _z_n_qos_make(express, nodrop, priority) \ _z_n_qos_create((bool)express, nodrop ? Z_CONGESTION_CONTROL_BLOCK : Z_CONGESTION_CONTROL_DROP, \ (z_priority_t)priority) -#define _Z_N_QOS_DEFAULT _z_n_qos_make(0, 0, 5) +#define _Z_N_QOS_DEFAULT ((_z_qos_t){._val = 5}) // RESPONSE FINAL message flags: // Z Extensions if Z==1 then Zenoh extensions are present diff --git a/src/session/utils.c b/src/session/utils.c index ca80d4e94..84ad8793e 100644 --- a/src/session/utils.c +++ b/src/session/utils.c @@ -64,11 +64,13 @@ z_result_t _z_session_init(_z_session_rc_t *zsrc, _z_id_t *zid) { zn->_remote_subscriptions = NULL; #if Z_FEATURE_RX_CACHE == 1 memset(&zn->_subscription_cache, 0, sizeof(zn->_subscription_cache)); - memset(&zn->_queryable_cache, 0, sizeof(zn->_queryable_cache)); #endif #endif #if Z_FEATURE_QUERYABLE == 1 zn->_local_queryable = NULL; +#if Z_FEATURE_RX_CACHE == 1 + memset(&zn->_queryable_cache, 0, sizeof(zn->_queryable_cache)); +#endif #endif #if Z_FEATURE_QUERY == 1 zn->_pending_queries = NULL; @@ -119,11 +121,13 @@ void _z_session_clear(_z_session_t *zn) { _z_flush_subscriptions(zn); #if Z_FEATURE_RX_CACHE == 1 _z_subscription_cache_clear(&zn->_subscription_cache); - _z_queryable_cache_clear(&zn->_queryable_cache); #endif #endif #if Z_FEATURE_QUERYABLE == 1 _z_flush_session_queryable(zn); +#if Z_FEATURE_RX_CACHE == 1 + _z_queryable_cache_clear(&zn->_queryable_cache); +#endif #endif #if Z_FEATURE_QUERY == 1 _z_flush_pending_queries(zn); diff --git a/tests/modularity.py b/tests/modularity.py index 7350ae70a..c268e5756 100644 --- a/tests/modularity.py +++ b/tests/modularity.py @@ -47,8 +47,8 @@ def pub_and_sub(args): # Expected z_sub output & status if args.sub == 1: - z_sub_expected_status = -2 if args.pub == 1: + z_sub_expected_status = 0 z_sub_expected_output = """Opening session... Declaring Subscriber on 'demo/example/**'... Press CTRL-C to quit... @@ -63,6 +63,7 @@ def pub_and_sub(args): >> [Subscriber] Received ('demo/example/zenoh-pico-pub': '[ 8] Pub from Pico!') >> [Subscriber] Received ('demo/example/zenoh-pico-pub': '[ 9] Pub from Pico!')""" else: + z_sub_expected_status = -2 z_sub_expected_output = """Opening session... Declaring Subscriber on 'demo/example/**'... Press CTRL-C to quit...""" @@ -72,7 +73,7 @@ def pub_and_sub(args): print("Start subscriber") # Start z_sub in the background - z_sub_command = f"stdbuf -oL -eL ./{DIR_EXAMPLES}/z_sub" + z_sub_command = f"stdbuf -oL -eL ./{DIR_EXAMPLES}/z_sub -n 10" z_sub_process = subprocess.Popen( z_sub_command, shell=True, @@ -175,14 +176,15 @@ def query_and_queryable(args): # Expected z_queryable output & status if args.queryable == 1: - z_queryable_expected_status = -2 if args.query == 1: + z_queryable_expected_status = 0 z_queryable_expected_output = """Opening session... Creating Queryable on 'demo/example/zenoh-pico-queryable'... Press CTRL-C to quit... >> [Queryable handler] Received Query 'demo/example/**' """ else: + z_queryable_expected_status = -2 z_queryable_expected_output = """Opening session... Creating Queryable on 'demo/example/zenoh-pico-queryable'... Press CTRL-C to quit...""" @@ -192,7 +194,7 @@ def query_and_queryable(args): print("Start queryable") # Start z_queryable in the background - z_queryable_command = f"stdbuf -oL -eL ./{DIR_EXAMPLES}/z_queryable" + z_queryable_command = f"stdbuf -oL -eL ./{DIR_EXAMPLES}/z_queryable -n 1" z_queryable_process = subprocess.Popen( z_queryable_command, shell=True, From e29eae5431491bc2376f57987e1e2517aeb5237f Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Wed, 13 Nov 2024 09:50:07 +0100 Subject: [PATCH 28/30] fix: attachment examples --- examples/unix/c11/z_get_attachment.c | 2 +- examples/unix/c11/z_queryable_attachment.c | 2 +- examples/unix/c11/z_sub_attachment.c | 8 +++----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/examples/unix/c11/z_get_attachment.c b/examples/unix/c11/z_get_attachment.c index 959d45a09..2d7ddcccc 100644 --- a/examples/unix/c11/z_get_attachment.c +++ b/examples/unix/c11/z_get_attachment.c @@ -70,7 +70,7 @@ void reply_handler(z_loaned_reply_t *reply, void *ctx) { const z_loaned_bytes_t *attachment = z_sample_attachment(sample); ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); size_t attachment_len; - if (ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len) != 0) { + if (ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len) < 0) { return; } kv_pair_t *kvp = (kv_pair_t *)malloc(sizeof(kv_pair_t) * attachment_len); diff --git a/examples/unix/c11/z_queryable_attachment.c b/examples/unix/c11/z_queryable_attachment.c index f1d121d28..ace30bb48 100644 --- a/examples/unix/c11/z_queryable_attachment.c +++ b/examples/unix/c11/z_queryable_attachment.c @@ -70,7 +70,7 @@ void query_handler(z_loaned_query_t *query, void *ctx) { const z_loaned_bytes_t *attachment = z_query_attachment(query); ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); size_t attachment_len; - if (ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len) == 0) { + if (ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len) == Z_OK) { kv_pair_t *kvp = (kv_pair_t *)malloc(sizeof(kv_pair_t) * attachment_len); for (size_t i = 0; i < attachment_len; ++i) { ze_deserializer_deserialize_string(&deserializer, &kvp[i].key); diff --git a/examples/unix/c11/z_sub_attachment.c b/examples/unix/c11/z_sub_attachment.c index 5720f86fd..823280673 100644 --- a/examples/unix/c11/z_sub_attachment.c +++ b/examples/unix/c11/z_sub_attachment.c @@ -64,12 +64,10 @@ void data_handler(z_loaned_sample_t *sample, void *ctx) { printf(" with timestamp: %" PRIu64 "\n", z_timestamp_ntp64_time(ts)); } // Check attachment - const z_loaned_bytes_t *attachment = z_sample_attachment(sample); - if (attachment != NULL) { - ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); - size_t attachment_len; - ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len); + ze_deserializer_t deserializer = ze_deserializer_from_bytes(attachment); + size_t attachment_len; + if (ze_deserializer_deserialize_sequence_length(&deserializer, &attachment_len) == Z_OK) { kv_pair_t *kvp = (kv_pair_t *)malloc(sizeof(kv_pair_t) * attachment_len); for (size_t i = 0; i < attachment_len; ++i) { ze_deserializer_deserialize_string(&deserializer, &kvp[i].key); From bc5f1ea71e284f9dcdae3fc2ed1c11c1aab9995b Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Wed, 13 Nov 2024 09:53:18 +0100 Subject: [PATCH 29/30] fix: keyexpr equals --- src/protocol/keyexpr.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/protocol/keyexpr.c b/src/protocol/keyexpr.c index 1113d42ac..15e1beee0 100644 --- a/src/protocol/keyexpr.c +++ b/src/protocol/keyexpr.c @@ -102,7 +102,12 @@ bool _z_keyexpr_equals(const _z_keyexpr_t *left, const _z_keyexpr_t *right) { if (_z_keyexpr_mapping_id(left) != _z_keyexpr_mapping_id(right)) { return false; } - if (_z_keyexpr_has_suffix(left) || _z_keyexpr_has_suffix(right)) { + bool l_suffix = _z_keyexpr_has_suffix(left); + bool r_suffix = _z_keyexpr_has_suffix(right); + if (l_suffix != r_suffix) { + return false; + } + if (l_suffix && r_suffix) { return _z_string_equals(&left->_suffix, &right->_suffix); } return true; From 63123b9366f9312d5456d49deed9b301b2e8e140 Mon Sep 17 00:00:00 2001 From: Jean-Roland Date: Wed, 13 Nov 2024 10:30:33 +0100 Subject: [PATCH 30/30] fix: flaky test --- tests/modularity.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/modularity.py b/tests/modularity.py index c268e5756..be18d86c1 100644 --- a/tests/modularity.py +++ b/tests/modularity.py @@ -48,7 +48,7 @@ def pub_and_sub(args): # Expected z_sub output & status if args.sub == 1: if args.pub == 1: - z_sub_expected_status = 0 + z_sub_expected_status = [0, -2] z_sub_expected_output = """Opening session... Declaring Subscriber on 'demo/example/**'... Press CTRL-C to quit... @@ -63,12 +63,12 @@ def pub_and_sub(args): >> [Subscriber] Received ('demo/example/zenoh-pico-pub': '[ 8] Pub from Pico!') >> [Subscriber] Received ('demo/example/zenoh-pico-pub': '[ 9] Pub from Pico!')""" else: - z_sub_expected_status = -2 + z_sub_expected_status = [-2] z_sub_expected_output = """Opening session... Declaring Subscriber on 'demo/example/**'... Press CTRL-C to quit...""" else: - z_sub_expected_status = 254 + z_sub_expected_status = [254] z_sub_expected_output = "ERROR: Zenoh pico was compiled without " "Z_FEATURE_SUBSCRIPTION but this example requires it." print("Start subscriber") @@ -133,7 +133,7 @@ def pub_and_sub(args): print("Check subscriber status & output") # Check the exit status of z_sub z_sub_status = z_sub_process.returncode - if z_sub_status == z_sub_expected_status: + if z_sub_status in z_sub_expected_status: print("z_sub status valid") else: print(f"z_sub status invalid, expected: {z_sub_expected_status}, received: {z_sub_status}") @@ -177,19 +177,19 @@ def query_and_queryable(args): # Expected z_queryable output & status if args.queryable == 1: if args.query == 1: - z_queryable_expected_status = 0 + z_queryable_expected_status = [0, -2] z_queryable_expected_output = """Opening session... Creating Queryable on 'demo/example/zenoh-pico-queryable'... Press CTRL-C to quit... >> [Queryable handler] Received Query 'demo/example/**' """ else: - z_queryable_expected_status = -2 + z_queryable_expected_status = [-2] z_queryable_expected_output = """Opening session... Creating Queryable on 'demo/example/zenoh-pico-queryable'... Press CTRL-C to quit...""" else: - z_queryable_expected_status = 254 + z_queryable_expected_status = [254] z_queryable_expected_output = "ERROR: Zenoh pico was compiled without " "Z_FEATURE_QUERYABLE but this example requires it." print("Start queryable") @@ -254,7 +254,7 @@ def query_and_queryable(args): print("Check queryable status & output") # Check the exit status of z_queryable z_queryable_status = z_queryable_process.returncode - if z_queryable_status == z_queryable_expected_status: + if z_queryable_status in z_queryable_expected_status: print("z_queryable status valid") else: print(f"z_queryable status invalid, expected: {z_queryable_expected_status}," f" received: {z_queryable_status}")