From aceca42818e84425a94c7ca7a937a18e6eab4d04 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 19 Mar 2024 14:42:21 +0100 Subject: [PATCH 01/21] Remove ACK message --- include/zenoh-pico/protocol/codec/message.h | 3 -- .../zenoh-pico/protocol/definitions/message.h | 20 -------- .../zenoh-pico/protocol/definitions/network.h | 3 -- src/protocol/codec/message.c | 50 ------------------- src/protocol/codec/network.c | 9 ---- src/protocol/definitions/network.c | 16 +----- src/session/rx.c | 7 --- tests/z_msgcodec_test.c | 39 ++------------- zenohpico.pc | 2 +- 9 files changed, 5 insertions(+), 144 deletions(-) diff --git a/include/zenoh-pico/protocol/codec/message.h b/include/zenoh-pico/protocol/codec/message.h index 89080475a..87e596a70 100644 --- a/include/zenoh-pico/protocol/codec/message.h +++ b/include/zenoh-pico/protocol/codec/message.h @@ -33,9 +33,6 @@ int8_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header); int8_t _z_err_encode(_z_wbuf_t *wbf, const _z_msg_err_t *err); int8_t _z_err_decode(_z_msg_err_t *err, _z_zbuf_t *zbf, uint8_t header); -int8_t _z_ack_encode(_z_wbuf_t *wbf, const _z_msg_ack_t *ack); -int8_t _z_ack_decode(_z_msg_ack_t *ack, _z_zbuf_t *zbf, uint8_t header); - int8_t _z_push_body_encode(_z_wbuf_t *wbf, const _z_push_body_t *pshb); int8_t _z_push_body_decode(_z_push_body_t *body, _z_zbuf_t *zbf, uint8_t header); diff --git a/include/zenoh-pico/protocol/definitions/message.h b/include/zenoh-pico/protocol/definitions/message.h index 83d8f61ba..28425943e 100644 --- a/include/zenoh-pico/protocol/definitions/message.h +++ b/include/zenoh-pico/protocol/definitions/message.h @@ -24,7 +24,6 @@ #define _Z_MID_Z_QUERY 0x03 #define _Z_MID_Z_REPLY 0x04 #define _Z_MID_Z_ERR 0x05 -#define _Z_MID_Z_ACK 0x06 #define _Z_MID_Z_PULL 0x07 #define _Z_MID_Z_LINK_STATE_LIST 0x10 @@ -70,25 +69,6 @@ typedef struct { } _z_msg_err_t; void _z_msg_err_clear(_z_msg_err_t *err); -/// Flags: -/// - T: Timestamp If T==1 then the timestamp if present -/// - X: Reserved -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|X|T| ACK | -/// +-+-+-+---------+ -/// ~ ts: ~ if T==1 -/// +---------------+ -/// ~ [err_exts] ~ if Z==1 -/// +---------------+ -typedef struct { - _z_timestamp_t _timestamp; - _z_source_info_t _ext_source_info; -} _z_msg_ack_t; -#define _Z_FLAG_Z_A_T 0x20 - /// Flags: /// - T: Timestamp If T==1 then the timestamp if present /// - X: Reserved diff --git a/include/zenoh-pico/protocol/definitions/network.h b/include/zenoh-pico/protocol/definitions/network.h index 689102dbe..9e6441685 100644 --- a/include/zenoh-pico/protocol/definitions/network.h +++ b/include/zenoh-pico/protocol/definitions/network.h @@ -180,14 +180,12 @@ typedef struct { enum { _Z_RESPONSE_BODY_REPLY, _Z_RESPONSE_BODY_ERR, - _Z_RESPONSE_BODY_ACK, _Z_RESPONSE_BODY_PUT, _Z_RESPONSE_BODY_DEL, } _tag; union { _z_msg_reply_t _reply; _z_msg_err_t _err; - _z_msg_ack_t _ack; _z_msg_put_t _put; _z_msg_del_t _del; } _body; @@ -231,7 +229,6 @@ _z_network_message_t _z_msg_make_query(_Z_MOVE(_z_keyexpr_t) key, _Z_MOVE(_z_byt #endif ); _z_network_message_t _z_n_msg_make_reply(_z_zint_t rid, _Z_MOVE(_z_keyexpr_t) key, _Z_MOVE(_z_push_body_t) body); -_z_network_message_t _z_n_msg_make_ack(_z_zint_t rid, _Z_MOVE(_z_keyexpr_t) key); _z_network_message_t _z_n_msg_make_response_final(_z_zint_t rid); _z_network_message_t _z_n_msg_make_declare(_z_declaration_t declaration); _z_network_message_t _z_n_msg_make_push(_Z_MOVE(_z_keyexpr_t) key, _Z_MOVE(_z_push_body_t) body); diff --git a/src/protocol/codec/message.c b/src/protocol/codec/message.c index 806d4d2ab..667de4d89 100644 --- a/src/protocol/codec/message.c +++ b/src/protocol/codec/message.c @@ -617,56 +617,6 @@ int8_t _z_err_decode(_z_msg_err_t *err, _z_zbuf_t *zbf, uint8_t header) { return _Z_RES_OK; } -int8_t _z_ack_encode(_z_wbuf_t *wbf, const _z_msg_ack_t *ack) { - int8_t ret = _Z_RES_OK; - uint8_t header = _Z_MID_Z_ACK; - _Bool has_ts = _z_timestamp_check(&ack->_timestamp); - _Bool has_sinfo_ext = _z_id_check(ack->_ext_source_info._id) || ack->_ext_source_info._source_sn != 0 || - ack->_ext_source_info._entity_id != 0; - if (has_ts) { - header |= _Z_FLAG_Z_A_T; - } - if (has_sinfo_ext) { - header |= _Z_FLAG_Z_Z; - } - _Z_RETURN_IF_ERR(_z_uint8_encode(wbf, header)); - if (has_ts) { - _Z_RETURN_IF_ERR(_z_timestamp_encode(wbf, &ack->_timestamp)); - } - if (has_sinfo_ext) { - _Z_RETURN_IF_ERR(_z_uint8_encode(wbf, _Z_MSG_EXT_ENC_ZBUF | 0x01)); - _Z_RETURN_IF_ERR(_z_source_info_encode_ext(wbf, &ack->_ext_source_info)); - } - return ret; -} -int8_t _z_ack_decode_extension(_z_msg_ext_t *extension, void *ctx) { - int8_t ret = _Z_RES_OK; - _z_msg_ack_t *ack = (_z_msg_ack_t *)ctx; - switch (_Z_EXT_FULL_ID(extension->_header)) { - case _Z_MSG_EXT_ENC_ZBUF | 0x01: { - _z_zbuf_t zbf = _z_zbytes_as_zbuf(extension->_body._zbuf._val); - ret = _z_source_info_decode(&ack->_ext_source_info, &zbf); - break; - } - default: - if (_Z_HAS_FLAG(extension->_header, _Z_MSG_EXT_FLAG_M)) { - ret = _z_msg_ext_unknown_error(extension, 0x0b); - } - } - return ret; -} -int8_t _z_ack_decode(_z_msg_ack_t *ack, _z_zbuf_t *zbf, uint8_t header) { - int8_t ret = _Z_RES_OK; - *ack = (_z_msg_ack_t){0}; - if (_Z_HAS_FLAG(header, _Z_FLAG_Z_A_T)) { - _Z_RETURN_IF_ERR(_z_timestamp_decode(&ack->_timestamp, zbf)); - } - if (_Z_HAS_FLAG(header, _Z_FLAG_Z_Z)) { - ret = _z_msg_ext_decode_iter(zbf, _z_ack_decode_extension, ack); - } - return ret; -} - int8_t _z_pull_encode(_z_wbuf_t *wbf, const _z_msg_pull_t *pull) { int8_t ret = _Z_RES_OK; uint8_t header = _Z_MID_Z_PULL; diff --git a/src/protocol/codec/network.c b/src/protocol/codec/network.c index 22615cc09..a971b2272 100644 --- a/src/protocol/codec/network.c +++ b/src/protocol/codec/network.c @@ -305,10 +305,6 @@ int8_t _z_response_encode(_z_wbuf_t *wbf, const _z_n_msg_response_t *msg) { _Z_RETURN_IF_ERR(_z_err_encode(wbf, &msg->_body._err)); break; } - case _Z_RESPONSE_BODY_ACK: { - _Z_RETURN_IF_ERR(_z_ack_encode(wbf, &msg->_body._ack)); - break; - } case _Z_RESPONSE_BODY_PUT: { _Z_RETURN_IF_ERR(_z_put_encode(wbf, &msg->_body._put)); break; @@ -379,11 +375,6 @@ int8_t _z_response_decode(_z_n_msg_response_t *msg, _z_zbuf_t *zbf, uint8_t head ret = _z_err_decode(&msg->_body._err, zbf, inner_header); break; } - case _Z_MID_Z_ACK: { - msg->_tag = _Z_RESPONSE_BODY_ACK; - ret = _z_ack_decode(&msg->_body._ack, zbf, inner_header); - break; - } case _Z_MID_Z_PUT: { msg->_tag = _Z_RESPONSE_BODY_PUT; ret = _z_put_decode(&msg->_body._put, zbf, inner_header); diff --git a/src/protocol/definitions/network.c b/src/protocol/definitions/network.c index 5f26ecf58..5cef555d8 100644 --- a/src/protocol/definitions/network.c +++ b/src/protocol/definitions/network.c @@ -100,9 +100,6 @@ void _z_n_msg_response_clear(_z_n_msg_response_t *msg) { _z_msg_err_clear(&msg->_body._err); break; } - case _Z_RESPONSE_BODY_ACK: { - break; - } case _Z_RESPONSE_BODY_PUT: { _z_msg_put_clear(&msg->_body._put); break; @@ -244,18 +241,7 @@ _z_network_message_t _z_n_msg_make_reply(_z_zint_t rid, _Z_MOVE(_z_keyexpr_t) ke }; } -_z_network_message_t _z_n_msg_make_ack(_z_zint_t rid, _Z_MOVE(_z_keyexpr_t) key) { - return (_z_network_message_t){ - ._tag = _Z_N_RESPONSE, - ._body._response = - { - ._tag = _Z_RESPONSE_BODY_ACK, - ._request_id = rid, - ._key = _z_keyexpr_steal(key), - ._body._ack = {._timestamp = _z_timestamp_null(), ._ext_source_info = _z_source_info_null()}, - }, - }; -} + void _z_msg_fix_mapping(_z_zenoh_message_t *msg, uint16_t mapping) { switch (msg->_tag) { case _Z_N_DECLARE: { diff --git a/src/session/rx.c b/src/session/rx.c index fae8d2a36..44507ccf3 100644 --- a/src/session/rx.c +++ b/src/session/rx.c @@ -115,8 +115,6 @@ int8_t _z_handle_network_message(_z_session_t *zn, _z_zenoh_message_t *msg, uint ); #endif if (ret == _Z_RES_OK) { - _z_network_message_t ack = _z_n_msg_make_ack(req._rid, &req._key); - ret = _z_send_n_msg(zn, &ack, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK); _z_network_message_t final = _z_n_msg_make_response_final(req._rid); ret |= _z_send_n_msg(zn, &final, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK); } @@ -133,8 +131,6 @@ int8_t _z_handle_network_message(_z_session_t *zn, _z_zenoh_message_t *msg, uint ); #endif if (ret == _Z_RES_OK) { - _z_network_message_t ack = _z_n_msg_make_ack(req._rid, &req._key); - ret = _z_send_n_msg(zn, &ack, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK); _z_network_message_t final = _z_n_msg_make_response_final(req._rid); ret |= _z_send_n_msg(zn, &final, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK); } @@ -159,9 +155,6 @@ int8_t _z_handle_network_message(_z_session_t *zn, _z_zenoh_message_t *msg, uint _Z_ERROR("Received Err for query %zu: message=%.*s", response._request_id, (int)payload.len, payload.start); } break; - case _Z_RESPONSE_BODY_ACK: { - // @TODO: implement ACKs for puts/dels - } break; case _Z_RESPONSE_BODY_PUT: { _z_msg_put_t put = response._body._put; #if Z_FEATURE_SUBSCRIPTION == 1 diff --git a/tests/z_msgcodec_test.c b/tests/z_msgcodec_test.c index c88d0ceef..aa88739f2 100644 --- a/tests/z_msgcodec_test.c +++ b/tests/z_msgcodec_test.c @@ -1195,32 +1195,6 @@ void err_message(void) { _z_wbuf_clear(&wbf); } -_z_msg_ack_t gen_ack(void) { - return (_z_msg_ack_t){ - ._ext_source_info = gen_bool() ? gen_source_info() : _z_source_info_null(), - ._timestamp = gen_timestamp(), - }; -} - -void assert_eq_ack(const _z_msg_ack_t *left, const _z_msg_ack_t *right) { - assert_eq_timestamp(&left->_timestamp, &right->_timestamp); - assert_eq_source_info(&left->_ext_source_info, &right->_ext_source_info); -} - -void ack_message(void) { - printf("\n>> Ack message\n"); - _z_wbuf_t wbf = gen_wbuf(UINT16_MAX); - _z_msg_ack_t expected = gen_ack(); - assert(_z_ack_encode(&wbf, &expected) == _Z_RES_OK); - _z_msg_ack_t decoded; - _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); - uint8_t header = _z_zbuf_read(&zbf); - assert(_Z_RES_OK == _z_ack_decode(&decoded, &zbf, header)); - assert_eq_ack(&expected, &decoded); - _z_zbuf_clear(&zbf); - _z_wbuf_clear(&wbf); -} - _z_msg_reply_t gen_reply(void) { return (_z_msg_reply_t){ ._consolidation = (gen_uint8() % 4) - 1, @@ -1367,19 +1341,16 @@ _z_n_msg_response_t gen_response(void) { ._ext_timestamp = gen_bool() ? gen_timestamp() : _z_timestamp_null(), ._ext_responder = {._eid = gen_uint16(), ._zid = gen_zid()}, }; - switch (gen_uint() % 5) { + switch (gen_uint() % 3) { case 0: { - ret._tag = _Z_RESPONSE_BODY_ACK; - ret._body._ack = gen_ack(); - } break; - case 1: { ret._tag = _Z_RESPONSE_BODY_ERR; ret._body._err = gen_err(); } break; - case 2: { + case 1: { ret._tag = _Z_RESPONSE_BODY_REPLY; ret._body._reply = gen_reply(); } break; + case 2: default: { _z_push_body_t body = gen_push_body(); if (body._is_put) { @@ -1409,9 +1380,6 @@ void assert_eq_response(const _z_n_msg_response_t *left, const _z_n_msg_response case _Z_RESPONSE_BODY_ERR: { assert_eq_err(&left->_body._err, &right->_body._err); } break; - case _Z_RESPONSE_BODY_ACK: { - assert_eq_ack(&left->_body._ack, &right->_body._ack); - } break; case _Z_RESPONSE_BODY_PUT: { assert_eq_push_body(&(_z_push_body_t){._is_put = true, ._body._put = left->_body._put}, &(_z_push_body_t){._is_put = true, ._body._put = right->_body._put}); @@ -1850,7 +1818,6 @@ int main(void) { pull_message(); query_message(); err_message(); - ack_message(); reply_message(); // Network messages diff --git a/zenohpico.pc b/zenohpico.pc index 9f520a887..19ac5e7de 100644 --- a/zenohpico.pc +++ b/zenohpico.pc @@ -3,6 +3,6 @@ prefix=/usr/local Name: zenohpico Description: URL: -Version: 0.11.20240208dev +Version: 0.11.20240319dev Cflags: -I${prefix}/include Libs: -L${prefix}/lib -lzenohpico From 61683e4ad991b21489d298057f98b924d21ebbc5 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 19 Mar 2024 15:07:52 +0100 Subject: [PATCH 02/21] Cleanup pull and subscriber --- examples/arduino/z_pull.ino | 24 +++---- examples/espidf/z_pull.c | 32 ++++----- examples/freertos_plus_tcp/z_pull.c | 24 +++---- examples/mbed/z_pull.cpp | 30 +++++---- examples/unix/c11/z_get.c | 2 +- examples/unix/c11/z_pull.c | 37 ++++++----- examples/unix/c99/z_get.c | 2 +- examples/unix/c99/z_pull.c | 38 ++++++----- examples/windows/z_get.c | 2 +- examples/windows/z_pull.c | 34 +++++----- examples/zephyr/z_pull.c | 28 ++++---- include/zenoh-pico/api/constants.h | 10 --- include/zenoh-pico/api/macros.h | 13 ---- include/zenoh-pico/api/primitives.h | 66 ------------------- include/zenoh-pico/api/types.h | 25 ------- include/zenoh-pico/net/primitives.h | 11 ---- include/zenoh-pico/net/session.h | 1 - include/zenoh-pico/net/subscribe.h | 12 +--- include/zenoh-pico/protocol/codec/core.h | 4 -- include/zenoh-pico/protocol/codec/message.h | 6 -- include/zenoh-pico/protocol/core.h | 18 ----- .../protocol/definitions/declarations.h | 3 +- .../zenoh-pico/protocol/definitions/message.h | 17 ----- .../zenoh-pico/protocol/definitions/network.h | 8 ++- include/zenoh-pico/session/subscription.h | 3 - src/api/api.c | 45 +------------ src/net/primitives.c | 22 +------ src/net/subscribe.c | 14 +--- src/protocol/codec.c | 32 --------- src/protocol/codec/declarations.c | 6 +- src/protocol/codec/message.c | 40 ----------- src/protocol/codec/network.c | 7 -- src/protocol/definitions/declarations.c | 7 +- src/protocol/definitions/network.c | 28 +------- src/session/rx.c | 3 - src/session/subscription.c | 3 - src/session/utils.c | 1 - tests/z_api_alignment_test.c | 23 ------- tests/z_api_null_drop_test.c | 7 -- tests/z_msgcodec_test.c | 65 +----------------- 40 files changed, 156 insertions(+), 597 deletions(-) diff --git a/examples/arduino/z_pull.ino b/examples/arduino/z_pull.ino index 7dc5600e8..7f10ef35c 100644 --- a/examples/arduino/z_pull.ino +++ b/examples/arduino/z_pull.ino @@ -34,7 +34,7 @@ #define KEYEXPR "demo/example/**" -z_owned_pull_subscriber_t sub; +// z_owned_pull_subscriber_t sub; void data_handler(const z_sample_t *sample, void *arg) { z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); @@ -92,22 +92,24 @@ void setup() { Serial.print(KEYEXPR); Serial.println(" ..."); z_owned_closure_sample_t callback = z_closure_sample(data_handler, NULL, NULL); - sub = z_declare_pull_subscriber(z_session_loan(&s), z_keyexpr(KEYEXPR), z_closure_sample_move(&callback), NULL); - if (!z_pull_subscriber_check(&sub)) { - Serial.println("Unable to declare subscriber."); - while (1) { - ; - } - } - Serial.println("OK"); - Serial.println("Zenoh setup finished!"); + // @TODO + // sub = z_declare_pull_subscriber(z_session_loan(&s), z_keyexpr(KEYEXPR), z_closure_sample_move(&callback), NULL); + // if (!z_pull_subscriber_check(&sub)) { + // Serial.println("Unable to declare subscriber."); + // while (1) { + // ; + // } + // } + // Serial.println("OK"); + // Serial.println("Zenoh setup finished!"); + Serial.println("Pull Subscriber not supported... exiting"); delay(300); } void loop() { delay(5000); - z_subscriber_pull(z_pull_subscriber_loan(&sub)); + // z_subscriber_pull(z_pull_subscriber_loan(&sub)); } #else void setup() { diff --git a/examples/espidf/z_pull.c b/examples/espidf/z_pull.c index 5f42b2852..819f861da 100644 --- a/examples/espidf/z_pull.c +++ b/examples/espidf/z_pull.c @@ -146,21 +146,23 @@ void app_main() { printf("Declaring Subscriber on '%s'...", KEYEXPR); z_owned_closure_sample_t callback = z_closure(data_handler); - z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(KEYEXPR), z_move(callback), NULL); - if (!z_check(sub)) { - printf("Unable to declare subscriber.\n"); - exit(-1); - } - printf("OK!\n"); - - while (1) { - sleep(5); - printf("Pulling data from '%s'...\n", KEYEXPR); - z_subscriber_pull(z_loan(sub)); - } - - printf("Closing Zenoh Session..."); - z_undeclare_pull_subscriber(z_move(sub)); + // @TODO + // z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(KEYEXPR), z_move(callback), NULL); + // if (!z_check(sub)) { + // printf("Unable to declare subscriber.\n"); + // exit(-1); + // } + // printf("OK!\n"); + + // while (1) { + // sleep(5); + // printf("Pulling data from '%s'...\n", KEYEXPR); + // z_subscriber_pull(z_loan(sub)); + // } + + // printf("Closing Zenoh Session..."); + // z_undeclare_pull_subscriber(z_move(sub)); + printf("Pull Subscriber not supported... exiting\n"); // Stop the receive and the session lease loop for zenoh-pico zp_stop_read_task(z_loan(s)); diff --git a/examples/freertos_plus_tcp/z_pull.c b/examples/freertos_plus_tcp/z_pull.c index b8f5c5ee8..83f855403 100644 --- a/examples/freertos_plus_tcp/z_pull.c +++ b/examples/freertos_plus_tcp/z_pull.c @@ -59,19 +59,21 @@ void app_main(void) { z_owned_closure_sample_t callback = z_closure(data_handler); printf("Declaring Subscriber on '%s'...\n", KEYEXPR); - z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(KEYEXPR), z_move(callback), NULL); - if (!z_check(sub)) { - printf("Unable to declare subscriber.\n"); - return; - } + // @TODO + // z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(KEYEXPR), z_move(callback), NULL); + // if (!z_check(sub)) { + // printf("Unable to declare subscriber.\n"); + // return; + // } - while (1) { - zp_sleep_s(5); - printf("Pulling data from '%s'...\n", KEYEXPR); - z_subscriber_pull(z_loan(sub)); - } + // while (1) { + // zp_sleep_s(5); + // printf("Pulling data from '%s'...\n", KEYEXPR); + // z_subscriber_pull(z_loan(sub)); + // } - z_undeclare_pull_subscriber(z_move(sub)); + // z_undeclare_pull_subscriber(z_move(sub)); + printf("Pull Subscriber not supported... exiting\n"); // Stop read and lease tasks for zenoh-pico zp_stop_read_task(z_loan(s)); diff --git a/examples/mbed/z_pull.cpp b/examples/mbed/z_pull.cpp index 4bcd33ed5..0ebfcff50 100644 --- a/examples/mbed/z_pull.cpp +++ b/examples/mbed/z_pull.cpp @@ -66,22 +66,24 @@ int main(int argc, char **argv) { printf("Declaring Subscriber on '%s'...", KEYEXPR); z_owned_closure_sample_t callback = z_closure_sample(data_handler, NULL, NULL); - z_owned_pull_subscriber_t sub = - z_declare_pull_subscriber(z_session_loan(&s), z_keyexpr(KEYEXPR), z_closure_sample_move(&callback), NULL); - if (!z_pull_subscriber_check(&sub)) { - printf("Unable to declare subscriber.\n"); - exit(-1); - } - printf("OK!\n"); + // @TODO + // z_owned_pull_subscriber_t sub = + // z_declare_pull_subscriber(z_session_loan(&s), z_keyexpr(KEYEXPR), z_closure_sample_move(&callback), NULL); + // if (!z_pull_subscriber_check(&sub)) { + // printf("Unable to declare subscriber.\n"); + // exit(-1); + // } + // printf("OK!\n"); - while (1) { - zp_sleep_s(5); - printf("Pulling data from '%s'...\n", KEYEXPR); - z_subscriber_pull(z_pull_subscriber_loan(&sub)); - } + // while (1) { + // zp_sleep_s(5); + // printf("Pulling data from '%s'...\n", KEYEXPR); + // z_subscriber_pull(z_pull_subscriber_loan(&sub)); + // } - printf("Closing Zenoh Session..."); - z_undeclare_pull_subscriber(z_pull_subscriber_move(&sub)); + // printf("Closing Zenoh Session..."); + // z_undeclare_pull_subscriber(z_pull_subscriber_move(&sub)); + printf("Pull Subscriber not supported... exiting\n"); // Stop the receive and the session lease loop for zenoh-pico zp_stop_read_task(z_session_loan(&s)); diff --git a/examples/unix/c11/z_get.c b/examples/unix/c11/z_get.c index ca45ec493..eb7543f21 100644 --- a/examples/unix/c11/z_get.c +++ b/examples/unix/c11/z_get.c @@ -102,7 +102,7 @@ int main(int argc, char **argv) { return -1; } - printf("Enter any key to pull data or 'q' to quit...\n"); + printf("Enter any key to get data or 'q' to quit...\n"); char c = '\0'; while (1) { fflush(stdin); diff --git a/examples/unix/c11/z_pull.c b/examples/unix/c11/z_pull.c index c6f710bfb..21c4a7916 100644 --- a/examples/unix/c11/z_pull.c +++ b/examples/unix/c11/z_pull.c @@ -73,25 +73,28 @@ int main(int argc, char **argv) { z_owned_closure_sample_t callback = z_closure(data_handler); printf("Declaring Subscriber on '%s'...\n", keyexpr); - z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); - if (!z_check(sub)) { - printf("Unable to declare subscriber.\n"); - return -1; - } - printf("Enter any key to pull data or 'q' to quit...\n"); - char c = '\0'; - while (1) { - fflush(stdin); - int ret = scanf("%c", &c); - (void)ret; // Remove unused result warning - if (c == 'q') { - break; - } - z_subscriber_pull(z_loan(sub)); - } + // @TODO + // z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); + // if (!z_check(sub)) { + // printf("Unable to declare subscriber.\n"); + // return -1; + // } + + // printf("Enter any key to pull data or 'q' to quit...\n"); + // char c = '\0'; + // while (1) { + // fflush(stdin); + // int ret = scanf("%c", &c); + // (void)ret; // Remove unused result warning + // if (c == 'q') { + // break; + // } + // z_subscriber_pull(z_loan(sub)); + // } - z_undeclare_pull_subscriber(z_move(sub)); + // z_undeclare_pull_subscriber(z_move(sub)); + printf("Pull Subscriber not supported... exiting\n"); // Stop read and lease tasks for zenoh-pico zp_stop_read_task(z_loan(s)); diff --git a/examples/unix/c99/z_get.c b/examples/unix/c99/z_get.c index 46121e59e..bfb1dacc1 100644 --- a/examples/unix/c99/z_get.c +++ b/examples/unix/c99/z_get.c @@ -102,7 +102,7 @@ int main(int argc, char **argv) { return -1; } - printf("Enter any key to pull data or 'q' to quit...\n"); + printf("Enter any key to get data or 'q' to quit...\n"); char c = '\0'; while (1) { fflush(stdin); diff --git a/examples/unix/c99/z_pull.c b/examples/unix/c99/z_pull.c index efe2ba8bf..dee9d618f 100644 --- a/examples/unix/c99/z_pull.c +++ b/examples/unix/c99/z_pull.c @@ -73,26 +73,28 @@ int main(int argc, char **argv) { z_owned_closure_sample_t callback = z_closure_sample(data_handler, NULL, NULL); printf("Declaring Subscriber on '%s'...\n", keyexpr); - z_owned_pull_subscriber_t sub = - z_declare_pull_subscriber(z_session_loan(&s), z_keyexpr(keyexpr), z_closure_sample_move(&callback), NULL); - if (!z_pull_subscriber_check(&sub)) { - printf("Unable to declare subscriber.\n"); - return -1; - } + // @TODO + // z_owned_pull_subscriber_t sub = + // z_declare_pull_subscriber(z_session_loan(&s), z_keyexpr(keyexpr), z_closure_sample_move(&callback), NULL); + // if (!z_pull_subscriber_check(&sub)) { + // printf("Unable to declare subscriber.\n"); + // return -1; + // } - printf("Enter any key to pull data or 'q' to quit...\n"); - char c = '\0'; - while (1) { - fflush(stdin); - int ret = scanf("%c", &c); - (void)ret; // Clear unused result warning - if (c == 'q') { - break; - } - z_subscriber_pull(z_pull_subscriber_loan(&sub)); - } + // printf("Enter any key to pull data or 'q' to quit...\n"); + // char c = '\0'; + // while (1) { + // fflush(stdin); + // int ret = scanf("%c", &c); + // (void)ret; // Clear unused result warning + // if (c == 'q') { + // break; + // } + // z_subscriber_pull(z_pull_subscriber_loan(&sub)); + // } - z_undeclare_pull_subscriber(z_pull_subscriber_move(&sub)); + // z_undeclare_pull_subscriber(z_pull_subscriber_move(&sub)); + printf("Pull Subscriber not supported... exiting\n"); // Stop read and lease tasks for zenoh-pico zp_stop_read_task(z_session_loan(&s)); diff --git a/examples/windows/z_get.c b/examples/windows/z_get.c index 2815656dc..7843f600b 100644 --- a/examples/windows/z_get.c +++ b/examples/windows/z_get.c @@ -67,7 +67,7 @@ int main(int argc, char **argv) { return -1; } - printf("Enter any key to pull data or 'q' to quit...\n"); + printf("Enter any key to get data or 'q' to quit...\n"); char c = '\0'; while (1) { fflush(stdin); diff --git a/examples/windows/z_pull.c b/examples/windows/z_pull.c index 512b2bb79..90f2b892c 100644 --- a/examples/windows/z_pull.c +++ b/examples/windows/z_pull.c @@ -53,24 +53,26 @@ int main(int argc, char **argv) { z_owned_closure_sample_t callback = z_closure(data_handler); printf("Declaring Subscriber on '%s'...\n", keyexpr); - z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); - if (!z_check(sub)) { - printf("Unable to declare subscriber.\n"); - return -1; - } + // @TODO + // z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); + // if (!z_check(sub)) { + // printf("Unable to declare subscriber.\n"); + // return -1; + // } - printf("Enter any key to pull data or 'q' to quit...\n"); - char c = '\0'; - while (1) { - fflush(stdin); - scanf("%c", &c); - if (c == 'q') { - break; - } - z_subscriber_pull(z_loan(sub)); - } + // printf("Enter any key to pull data or 'q' to quit...\n"); + // char c = '\0'; + // while (1) { + // fflush(stdin); + // scanf("%c", &c); + // if (c == 'q') { + // break; + // } + // z_subscriber_pull(z_loan(sub)); + // } - z_undeclare_pull_subscriber(z_move(sub)); + // z_undeclare_pull_subscriber(z_move(sub)); + printf("Pull Subscriber not supported... exiting\n"); // Stop read and lease tasks for zenoh-pico zp_stop_read_task(z_loan(s)); diff --git a/examples/zephyr/z_pull.c b/examples/zephyr/z_pull.c index 61bed75d0..4246f0814 100644 --- a/examples/zephyr/z_pull.c +++ b/examples/zephyr/z_pull.c @@ -61,21 +61,23 @@ int main(int argc, char **argv) { printf("Declaring Subscriber on '%s'...", KEYEXPR); z_owned_closure_sample_t callback = z_closure(data_handler); - z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(KEYEXPR), z_move(callback), NULL); - if (!z_check(sub)) { - printf("Unable to declare subscriber.\n"); - exit(-1); - } - printf("OK!\n"); + // @TODO + // z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(KEYEXPR), z_move(callback), NULL); + // if (!z_check(sub)) { + // printf("Unable to declare subscriber.\n"); + // exit(-1); + // } + // printf("OK!\n"); - while (1) { - sleep(5); - printf("Pulling data from '%s'...\n", KEYEXPR); - z_subscriber_pull(z_loan(sub)); - } + // while (1) { + // sleep(5); + // printf("Pulling data from '%s'...\n", KEYEXPR); + // z_subscriber_pull(z_loan(sub)); + // } - printf("Closing Zenoh Session..."); - z_undeclare_pull_subscriber(z_move(sub)); + // printf("Closing Zenoh Session..."); + // z_undeclare_pull_subscriber(z_move(sub)); + printf("Pull Subscriber not supported... exiting\n"); // Stop the receive and the session lease loop for zenoh-pico zp_stop_read_task(z_loan(s)); diff --git a/include/zenoh-pico/api/constants.h b/include/zenoh-pico/api/constants.h index 9e9e095ca..a43286225 100644 --- a/include/zenoh-pico/api/constants.h +++ b/include/zenoh-pico/api/constants.h @@ -214,16 +214,6 @@ typedef enum { } z_priority_t; #define Z_PRIORITY_DEFAULT Z_PRIORITY_DATA -/** - * Subscription mode values. - * - * Enumerators: - * Z_SUBMODE_PUSH: Defines the subscription with a push paradigm. - * Z_SUBMODE_PULL: Defines the subscription with a pull paradigm. - */ -typedef enum { Z_SUBMODE_PUSH = 0, Z_SUBMODE_PULL = 1 } z_submode_t; -#define Z_SUBMODE_DEFAULT Z_SUBMODE_PUSH - /** * Query target values. * diff --git a/include/zenoh-pico/api/macros.h b/include/zenoh-pico/api/macros.h index c7cb700a9..0a99bf736 100644 --- a/include/zenoh-pico/api/macros.h +++ b/include/zenoh-pico/api/macros.h @@ -38,7 +38,6 @@ z_owned_config_t : z_config_loan, \ z_owned_scouting_config_t : z_scouting_config_loan, \ z_owned_session_t : z_session_loan, \ - z_owned_pull_subscriber_t : z_pull_subscriber_loan, \ z_owned_publisher_t : z_publisher_loan, \ z_owned_reply_t : z_reply_loan, \ z_owned_hello_t : z_hello_loan, \ @@ -57,7 +56,6 @@ z_owned_scouting_config_t * : z_scouting_config_drop, \ z_owned_session_t * : z_session_drop, \ z_owned_subscriber_t * : z_subscriber_drop, \ - z_owned_pull_subscriber_t * : z_pull_subscriber_drop, \ z_owned_publisher_t * : z_publisher_drop, \ z_owned_queryable_t * : z_queryable_drop, \ z_owned_reply_t * : z_reply_drop, \ @@ -83,7 +81,6 @@ z_owned_keyexpr_t * : z_keyexpr_null, \ z_owned_config_t * : z_config_null, \ z_owned_scouting_config_t * : z_scouting_config_null, \ - z_owned_pull_subscriber_t * : z_pull_subscriber_null, \ z_owned_subscriber_t * : z_subscriber_null, \ z_owned_queryable_t * : z_queryable_null, \ z_owned_reply_t * : z_reply_null, \ @@ -113,7 +110,6 @@ z_owned_scouting_config_t : z_scouting_config_check, \ z_owned_session_t : z_session_check, \ z_owned_subscriber_t : z_subscriber_check, \ - z_owned_pull_subscriber_t : z_pull_subscriber_check, \ z_owned_publisher_t : z_publisher_check, \ z_owned_queryable_t : z_queryable_check, \ z_owned_reply_t : z_reply_check, \ @@ -152,7 +148,6 @@ z_owned_scouting_config_t : z_scouting_config_move, \ z_owned_session_t : z_session_move, \ z_owned_subscriber_t : z_subscriber_move, \ - z_owned_pull_subscriber_t : z_pull_subscriber_move, \ z_owned_publisher_t : z_publisher_move, \ z_owned_queryable_t : z_queryable_move, \ z_owned_reply_t : z_reply_move, \ @@ -180,7 +175,6 @@ z_owned_config_t : z_config_clone, \ z_owned_session_t : z_session_clone, \ z_owned_subscriber_t : z_subscriber_clone, \ - z_owned_pull_subscriber_t : z_pull_subscriber_clone, \ z_owned_publisher_t : z_publisher_clone, \ z_owned_queryable_t : z_queryable_clone, \ z_owned_reply_t : z_reply_clone, \ @@ -201,7 +195,6 @@ z_owned_keyexpr_t * : z_keyexpr_null, \ z_owned_config_t * : z_config_null, \ z_owned_scouting_config_t * : z_scouting_config_null, \ - z_owned_pull_subscriber_t * : z_pull_subscriber_null, \ z_owned_subscriber_t * : z_subscriber_null, \ z_owned_queryable_t * : z_queryable_null, \ z_owned_reply_t * : z_reply_null, \ @@ -242,7 +235,6 @@ template<> struct zenoh_loan_type{ typedef z_session_t type; template<> struct zenoh_loan_type{ typedef z_keyexpr_t type; }; template<> struct zenoh_loan_type{ typedef z_config_t type; }; template<> struct zenoh_loan_type{ typedef z_publisher_t type; }; -template<> struct zenoh_loan_type{ typedef z_pull_subscriber_t type; }; template<> struct zenoh_loan_type{ typedef z_hello_t type; }; template<> struct zenoh_loan_type{ typedef const char* type; }; @@ -250,7 +242,6 @@ template<> inline z_session_t z_loan(const z_owned_session_t& x) { return z_sess template<> inline z_keyexpr_t z_loan(const z_owned_keyexpr_t& x) { return z_keyexpr_loan(&x); } template<> inline z_config_t z_loan(const z_owned_config_t& x) { return z_config_loan(&x); } template<> inline z_publisher_t z_loan(const z_owned_publisher_t& x) { return z_publisher_loan(&x); } -template<> inline z_pull_subscriber_t z_loan(const z_owned_pull_subscriber_t& x) { return z_pull_subscriber_loan(&x); } template<> inline z_hello_t z_loan(const z_owned_hello_t& x) { return z_hello_loan(&x); } template<> inline const char* z_loan(const z_owned_str_t& x) { return z_str_loan(&x); } @@ -262,7 +253,6 @@ template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; -template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef int8_t type; }; template<> struct zenoh_drop_type { typedef void type; }; @@ -279,7 +269,6 @@ template<> inline int8_t z_drop(z_owned_publisher_t* v) { return z_undeclare_pub template<> inline void z_drop(z_owned_keyexpr_t* v) { z_keyexpr_drop(v); } template<> inline void z_drop(z_owned_config_t* v) { z_config_drop(v); } template<> inline void z_drop(z_owned_scouting_config_t* v) { z_scouting_config_drop(v); } -template<> inline int8_t z_drop(z_owned_pull_subscriber_t* v) { return z_undeclare_pull_subscriber(v); } template<> inline int8_t z_drop(z_owned_subscriber_t* v) { return z_undeclare_subscriber(v); } template<> inline int8_t z_drop(z_owned_queryable_t* v) { return z_undeclare_queryable(v); } template<> inline void z_drop(z_owned_reply_t* v) { z_reply_drop(v); } @@ -296,7 +285,6 @@ inline void z_null(z_owned_publisher_t& v) { v = z_publisher_null(); } inline void z_null(z_owned_keyexpr_t& v) { v = z_keyexpr_null(); } inline void z_null(z_owned_config_t& v) { v = z_config_null(); } inline void z_null(z_owned_scouting_config_t& v) { v = z_scouting_config_null(); } -inline void z_null(z_owned_pull_subscriber_t& v) { v = z_pull_subscriber_null(); } inline void z_null(z_owned_subscriber_t& v) { v = z_subscriber_null(); } inline void z_null(z_owned_queryable_t& v) { v = z_queryable_null(); } inline void z_null(z_owned_reply_t& v) { v = z_reply_null(); } @@ -316,7 +304,6 @@ inline bool z_check(const z_owned_config_t& v) { return z_config_check(&v); } inline bool z_check(const z_owned_scouting_config_t& v) { return z_scouting_config_check(&v); } inline bool z_check(const z_bytes_t& v) { return z_bytes_check(&v); } inline bool z_check(const z_owned_subscriber_t& v) { return z_subscriber_check(&v); } -inline bool z_check(const z_owned_pull_subscriber_t& v) { return z_pull_subscriber_check(&v); } inline bool z_check(const z_owned_queryable_t& v) { return z_queryable_check(&v); } inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } diff --git a/include/zenoh-pico/api/primitives.h b/include/zenoh-pico/api/primitives.h index f661ca4cb..a72878b99 100644 --- a/include/zenoh-pico/api/primitives.h +++ b/include/zenoh-pico/api/primitives.h @@ -687,7 +687,6 @@ _OWNED_FUNCTIONS(z_config_t, z_owned_config_t, config) _OWNED_FUNCTIONS(z_scouting_config_t, z_owned_scouting_config_t, scouting_config) _OWNED_FUNCTIONS(z_session_t, z_owned_session_t, session) _OWNED_FUNCTIONS(z_subscriber_t, z_owned_subscriber_t, subscriber) -_OWNED_FUNCTIONS(z_pull_subscriber_t, z_owned_pull_subscriber_t, pull_subscriber) _OWNED_FUNCTIONS(z_publisher_t, z_owned_publisher_t, publisher) _OWNED_FUNCTIONS(z_queryable_t, z_owned_queryable_t, queryable) _OWNED_FUNCTIONS(z_hello_t, z_owned_hello_t, hello) @@ -1190,71 +1189,6 @@ int8_t z_undeclare_subscriber(z_owned_subscriber_t *sub); * */ z_owned_keyexpr_t z_subscriber_keyexpr(z_subscriber_t sub); - -/** - * Constructs the default values for the pull subscriber entity. - * - * Returns: - * Returns the constructed :c:type:`z_pull_subscriber_options_t`. - */ -z_pull_subscriber_options_t z_pull_subscriber_options_default(void); - -/** - * Declares a pull subscriber for the given keyexpr. - * - * Data can be pulled with this subscriber with the help of the - * :c:func:`z_pull` function. Received data is processed by means of callbacks. - * - * Like most ``z_owned_X_t`` types, you may obtain an instance of :c:type:`z_owned_pull_subscriber_t` by loaning it - * using ``z_pull_subscriber_loan(&val)``. The ``z_loan(val)`` macro, available if your compiler supports C11's - * ``_Generic``, is equivalent to writing ``z_pull_subscriber_loan(&val)``. - * - * Like all ``z_owned_X_t``, an instance will be destroyed by any function which takes a mutable pointer to said - * instance, as this implies the instance's inners were moved. To make this fact more obvious when reading your code, - * consider using ``z_move(val)`` instead of ``&val`` as the argument. After a ``z_move``, ``val`` will still exist, but - * will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your ``val`` - * is valid. - * - * To check if ``val`` is still valid, you may use ``z_pull_subscriber_check(&val)`` or ``z_check(val)`` if your - * compiler supports ``_Generic``, which will return ``true`` if ``val`` is valid, or ``false`` otherwise. - * - * Parameters: - * zs: A loaned instance of the the :c:type:`z_session_t` where to declare the subscriber. - * keyexpr: A loaned instance of :c:type:`z_keyexpr_t` to associate with the subscriber. - * callback: A moved instance of :c:type:`z_owned_closure_sample_t` containing the callbacks to be called and the - * context to pass to them. options: The options to apply to the pull subscriber. If ``NULL`` is passed, the default - * options will be applied. - * - * Returns: - * A :c:type:`z_owned_pull_subscriber_t` with either a valid subscriber or a failing subscriber. - * Should the pull subscriber be invalid, ``z_check(val)`` ing the returned value will return ``false``. - */ -z_owned_pull_subscriber_t z_declare_pull_subscriber(z_session_t zs, z_keyexpr_t keyexpr, - z_owned_closure_sample_t *callback, - const z_pull_subscriber_options_t *options); - -/** - * Undeclares the pull subscriber generated by a call to :c:func:`z_declare_pull_subscriber`. - * - * Parameters: - * sub: A moved instance of :c:type:`z_owned_pull_subscriber_t` to undeclare. - * - * Returns: - * Returns ``0`` if the undeclare pull subscriber operation is successful, or a ``negative value`` otherwise. - */ -int8_t z_undeclare_pull_subscriber(z_owned_pull_subscriber_t *sub); - -/** - * Pulls data for :c:type:`z_owned_pull_subscriber_t`. The pulled data will be provided - * by calling the **callback** function provided to the :c:func:`z_declare_pull_subscriber` function. - * - * Parameters: - * sub: A loaned instance of :c:type:`z_pull_subscriber_t` from where to pull the data. - * - * Returns: - * Returns ``0`` if the pull operation is successful, or a ``negative value`` otherwise. - */ -int8_t z_subscriber_pull(const z_pull_subscriber_t sub); #endif /** diff --git a/include/zenoh-pico/api/types.h b/include/zenoh-pico/api/types.h index d7bb29451..6932536e4 100644 --- a/include/zenoh-pico/api/types.h +++ b/include/zenoh-pico/api/types.h @@ -149,20 +149,6 @@ typedef struct { } z_subscriber_t; _OWNED_TYPE_PTR(_z_subscriber_t, subscriber) -/** - * Represents a Zenoh Pull Subscriber entity. - * - * Operations over :c:type:`z_pull_subscriber_t` must be done using the provided functions: - * - * - :c:func:`z_declare_pull_subscriber` - * - :c:func:`z_undeclare_pull_subscriber` - * - :c:func:`z_subscriber_pull` - */ -typedef struct { - _z_pull_subscriber_t *_val; -} z_pull_subscriber_t; -_OWNED_TYPE_PTR(_z_pull_subscriber_t, pull_subscriber) - /** * Represents a Zenoh Publisher entity. * @@ -233,17 +219,6 @@ typedef struct { z_reliability_t reliability; } z_subscriber_options_t; -/** - * Represents the set of options that can be applied to a pull subscriber, - * upon its declaration via :c:func:`z_declare_pull_subscriber`. - * - * Members: - * z_reliability_t reliability: The subscription reliability. - */ -typedef struct { - z_reliability_t reliability; -} z_pull_subscriber_options_t; - /** * Represents the replies consolidation to apply on replies to a :c:func:`z_get`. * diff --git a/include/zenoh-pico/net/primitives.h b/include/zenoh-pico/net/primitives.h index 1d95bac7c..ae8980ceb 100644 --- a/include/zenoh-pico/net/primitives.h +++ b/include/zenoh-pico/net/primitives.h @@ -156,17 +156,6 @@ _z_subscriber_t *_z_declare_subscriber(_z_session_rc_t *zn, _z_keyexpr_t keyexpr * 0 if success, or a negative value identifying the error. */ int8_t _z_undeclare_subscriber(_z_subscriber_t *sub); - -/** - * Pull data for a pull mode :c:type:`_z_subscriber_t`. The pulled data will be provided - * by calling the **callback** function provided to the :c:func:`_z_declare_subscriber` function. - * - * Parameters: - * sub: The :c:type:`_z_subscriber_t` to pull from. - * Returns: - * ``0`` in case of success, ``-1`` in case of failure. - */ -int8_t _z_subscriber_pull(const _z_subscriber_t *sub); #endif #if Z_FEATURE_QUERYABLE == 1 diff --git a/include/zenoh-pico/net/session.h b/include/zenoh-pico/net/session.h index 8d68188b4..822bbf094 100644 --- a/include/zenoh-pico/net/session.h +++ b/include/zenoh-pico/net/session.h @@ -41,7 +41,6 @@ typedef struct _z_session_t { // Session counters uint16_t _resource_id; uint32_t _entity_id; - _z_zint_t _pull_id; _z_zint_t _query_id; _z_zint_t _interest_id; diff --git a/include/zenoh-pico/net/subscribe.h b/include/zenoh-pico/net/subscribe.h index e2aafe540..bc98a9972 100644 --- a/include/zenoh-pico/net/subscribe.h +++ b/include/zenoh-pico/net/subscribe.h @@ -28,8 +28,6 @@ typedef struct { _z_session_rc_t _zn; } _z_subscriber_t; -typedef _z_subscriber_t _z_pull_subscriber_t; - #if Z_FEATURE_SUBSCRIPTION == 1 /** * Create a default subscription info for a push subscriber. @@ -37,15 +35,7 @@ typedef _z_subscriber_t _z_pull_subscriber_t; * Returns: * A :c:type:`_z_subinfo_t` containing the created subscription info. */ -_z_subinfo_t _z_subinfo_push_default(void); - -/** - * Create a default subscription info for a pull subscriber. - * - * Returns: - * A :c:type:`_z_subinfo_t` containing the created subscription info. - */ -_z_subinfo_t _z_subinfo_pull_default(void); +_z_subinfo_t _z_subinfo_default(void); void _z_subscriber_clear(_z_subscriber_t *sub); void _z_subscriber_free(_z_subscriber_t **sub); diff --git a/include/zenoh-pico/protocol/codec/core.h b/include/zenoh-pico/protocol/codec/core.h index 13725f8d9..5320a5ce8 100644 --- a/include/zenoh-pico/protocol/codec/core.h +++ b/include/zenoh-pico/protocol/codec/core.h @@ -82,10 +82,6 @@ int8_t _z_zbuf_read_exact(_z_zbuf_t *zbf, uint8_t *dest, size_t length); int8_t _z_str_encode(_z_wbuf_t *buf, const char *s); int8_t _z_str_decode(char **str, _z_zbuf_t *buf); -int8_t _z_period_encode(_z_wbuf_t *wbf, const _z_period_t *m); -int8_t _z_period_decode(_z_period_t *p, _z_zbuf_t *zbf); -int8_t _z_period_decode_na(_z_period_t *p, _z_zbuf_t *zbf); - int8_t _z_keyexpr_encode(_z_wbuf_t *buf, _Bool has_suffix, const _z_keyexpr_t *ke); int8_t _z_keyexpr_decode(_z_keyexpr_t *ke, _z_zbuf_t *buf, _Bool has_suffix); diff --git a/include/zenoh-pico/protocol/codec/message.h b/include/zenoh-pico/protocol/codec/message.h index 87e596a70..c40f2824a 100644 --- a/include/zenoh-pico/protocol/codec/message.h +++ b/include/zenoh-pico/protocol/codec/message.h @@ -18,15 +18,9 @@ #include "zenoh-pico/protocol/definitions/network.h" #include "zenoh-pico/protocol/iobuf.h" -int8_t _z_push_body_encode(_z_wbuf_t *buf, const _z_push_body_t *ts); -int8_t _z_push_body_decode(_z_push_body_t *ts, _z_zbuf_t *buf, uint8_t header); - int8_t _z_query_encode(_z_wbuf_t *wbf, const _z_msg_query_t *query); int8_t _z_query_decode(_z_msg_query_t *query, _z_zbuf_t *zbf, uint8_t header); -int8_t _z_pull_encode(_z_wbuf_t *wbf, const _z_msg_pull_t *pull); -int8_t _z_pull_decode(_z_msg_pull_t *pull, _z_zbuf_t *zbf, uint8_t header); - int8_t _z_reply_encode(_z_wbuf_t *wbf, const _z_msg_reply_t *reply); int8_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header); diff --git a/include/zenoh-pico/protocol/core.h b/include/zenoh-pico/protocol/core.h index 2eaa3e495..113566319 100644 --- a/include/zenoh-pico/protocol/core.h +++ b/include/zenoh-pico/protocol/core.h @@ -272,33 +272,15 @@ typedef struct { _z_zint_t n; } _z_target_complete_body_t; -/** - * The subscription period. - * - * Members: - * unsigned int origin: - * unsigned int period: - * unsigned int duration: - */ -typedef struct { - unsigned int origin; - unsigned int period; - unsigned int duration; -} _z_period_t; - /** * Informations to be passed to :c:func:`_z_declare_subscriber` to configure the created * :c:type:`_z_subscription_rc_t`. * * Members: - * _z_period_t *period: The subscription period. * z_reliability_t reliability: The subscription reliability. - * _z_submode_t mode: The subscription mode. */ typedef struct { - _z_period_t period; z_reliability_t reliability; - z_submode_t mode; } _z_subinfo_t; typedef struct { diff --git a/include/zenoh-pico/protocol/definitions/declarations.h b/include/zenoh-pico/protocol/definitions/declarations.h index 1df9c60f7..4e0bae713 100644 --- a/include/zenoh-pico/protocol/definitions/declarations.h +++ b/include/zenoh-pico/protocol/definitions/declarations.h @@ -34,7 +34,6 @@ typedef struct { _z_keyexpr_t _keyexpr; uint32_t _id; struct { - _Bool _pull_mode; _Bool _reliable; } _ext_subinfo; } _z_decl_subscriber_t; @@ -130,7 +129,7 @@ void _z_decl_fix_mapping(_z_declaration_t* msg, uint16_t mapping); _z_declaration_t _z_make_decl_keyexpr(uint16_t id, _Z_MOVE(_z_keyexpr_t) key); _z_declaration_t _z_make_undecl_keyexpr(uint16_t id); -_z_declaration_t _z_make_decl_subscriber(_Z_MOVE(_z_keyexpr_t) key, uint32_t id, _Bool reliable, _Bool pull_mode); +_z_declaration_t _z_make_decl_subscriber(_Z_MOVE(_z_keyexpr_t) key, uint32_t id, _Bool reliable); _z_declaration_t _z_make_undecl_subscriber(uint32_t id, _Z_OPTIONAL const _z_keyexpr_t* key); _z_declaration_t _z_make_decl_queryable(_Z_MOVE(_z_keyexpr_t) key, uint32_t id, uint32_t distance, uint8_t complete); diff --git a/include/zenoh-pico/protocol/definitions/message.h b/include/zenoh-pico/protocol/definitions/message.h index 28425943e..ea3311318 100644 --- a/include/zenoh-pico/protocol/definitions/message.h +++ b/include/zenoh-pico/protocol/definitions/message.h @@ -36,7 +36,6 @@ #define _Z_FLAG_Z_I 0x40 // 1 << 6 | DataInfo if I==1 then DataInfo is present #define _Z_FLAG_Z_K 0x80 // 1 << 7 | ResourceKey if K==1 then keyexpr is string #define _Z_FLAG_Z_N 0x40 // 1 << 6 | MaxSamples if N==1 then the MaxSamples is indicated -#define _Z_FLAG_Z_P 0x20 // 1 << 7 | Period if P==1 then a period is present #define _Z_FLAG_Z_Q 0x40 // 1 << 6 | QueryableKind if Q==1 then the queryable kind is present #define _Z_FLAG_Z_R \ 0x20 // 1 << 5 | Reliable if R==1 then it concerns the reliable channel, best-effort otherwise @@ -69,22 +68,6 @@ typedef struct { } _z_msg_err_t; void _z_msg_err_clear(_z_msg_err_t *err); -/// Flags: -/// - T: Timestamp If T==1 then the timestamp if present -/// - X: Reserved -/// - Z: Extension If Z==1 then at least one extension is present -/// -/// 7 6 5 4 3 2 1 0 -/// +-+-+-+-+-+-+-+-+ -/// |Z|X|X| PULL | -/// +---------------+ -/// ~ [pull_exts] ~ if Z==1 -/// +---------------+ -typedef struct { - _z_source_info_t _ext_source_info; -} _z_msg_pull_t; -static inline void _z_msg_pull_clear(_z_msg_pull_t *pull) { (void)pull; } - typedef struct { _z_timestamp_t _timestamp; _z_source_info_t _source_info; diff --git a/include/zenoh-pico/protocol/definitions/network.h b/include/zenoh-pico/protocol/definitions/network.h index 9e6441685..55fad899b 100644 --- a/include/zenoh-pico/protocol/definitions/network.h +++ b/include/zenoh-pico/protocol/definitions/network.h @@ -99,12 +99,15 @@ typedef struct { z_query_target_t _ext_target; uint32_t _ext_budget; uint32_t _ext_timeout_ms; - enum { _Z_REQUEST_QUERY, _Z_REQUEST_PUT, _Z_REQUEST_DEL, _Z_REQUEST_PULL } _tag; + enum { + _Z_REQUEST_QUERY, + _Z_REQUEST_PUT, + _Z_REQUEST_DEL, + } _tag; union { _z_msg_query_t _query; _z_msg_put_t _put; _z_msg_del_t _del; - _z_msg_pull_t _pull; } _body; } _z_n_msg_request_t; typedef struct { @@ -220,7 +223,6 @@ _Z_ELEM_DEFINE(_z_network_message, _z_network_message_t, _z_noop_size, _z_n_msg_ _Z_VEC_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_pull(_z_keyexpr_t key, _z_zint_t pull_id); _z_network_message_t _z_msg_make_query(_Z_MOVE(_z_keyexpr_t) key, _Z_MOVE(_z_bytes_t) parameters, _z_zint_t qid, z_consolidation_mode_t consolidation, _Z_MOVE(_z_value_t) value #if Z_FEATURE_ATTACHMENT == 1 diff --git a/include/zenoh-pico/session/subscription.h b/include/zenoh-pico/session/subscription.h index f13ffe05f..b84091f2c 100644 --- a/include/zenoh-pico/session/subscription.h +++ b/include/zenoh-pico/session/subscription.h @@ -39,9 +39,6 @@ int8_t _z_trigger_subscriptions(_z_session_t *zn, const _z_keyexpr_t keyexpr, co ); void _z_unregister_subscription(_z_session_t *zn, uint8_t is_local, _z_subscription_rc_t *sub); void _z_flush_subscriptions(_z_session_t *zn); - -/*------------------ Pull ------------------*/ -_z_zint_t _z_get_pull_id(_z_session_t *zn); #endif #endif /* INCLUDE_ZENOH_PICO_SESSION_SUBSCRIPTION_H */ diff --git a/src/api/api.c b/src/api/api.c index 9a64be720..1369c82b1 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -976,18 +976,10 @@ OWNED_FUNCTIONS_PTR_COMMON(z_subscriber_t, z_owned_subscriber_t, subscriber) OWNED_FUNCTIONS_PTR_CLONE(z_subscriber_t, z_owned_subscriber_t, subscriber, _z_owner_noop_copy) void z_subscriber_drop(z_owned_subscriber_t *val) { z_undeclare_subscriber(val); } -OWNED_FUNCTIONS_PTR_COMMON(z_pull_subscriber_t, z_owned_pull_subscriber_t, pull_subscriber) -OWNED_FUNCTIONS_PTR_CLONE(z_pull_subscriber_t, z_owned_pull_subscriber_t, pull_subscriber, _z_owner_noop_copy) -void z_pull_subscriber_drop(z_owned_pull_subscriber_t *val) { z_undeclare_pull_subscriber(val); } - z_subscriber_options_t z_subscriber_options_default(void) { return (z_subscriber_options_t){.reliability = Z_RELIABILITY_DEFAULT}; } -z_pull_subscriber_options_t z_pull_subscriber_options_default(void) { - return (z_pull_subscriber_options_t){.reliability = Z_RELIABILITY_DEFAULT}; -} - z_owned_subscriber_t z_declare_subscriber(z_session_t zs, z_keyexpr_t keyexpr, z_owned_closure_sample_t *callback, const z_subscriber_options_t *options) { void *ctx = callback->context; @@ -1023,7 +1015,7 @@ z_owned_subscriber_t z_declare_subscriber(z_session_t zs, z_keyexpr_t keyexpr, z } } - _z_subinfo_t subinfo = _z_subinfo_push_default(); + _z_subinfo_t subinfo = _z_subinfo_default(); if (options != NULL) { subinfo.reliability = options->reliability; } @@ -1035,30 +1027,6 @@ z_owned_subscriber_t z_declare_subscriber(z_session_t zs, z_keyexpr_t keyexpr, z return (z_owned_subscriber_t){._value = sub}; } -z_owned_pull_subscriber_t z_declare_pull_subscriber(z_session_t zs, z_keyexpr_t keyexpr, - z_owned_closure_sample_t *callback, - const z_pull_subscriber_options_t *options) { - (void)(options); - - void *ctx = callback->context; - callback->context = NULL; - - z_keyexpr_t key = keyexpr; - _z_resource_t *r = _z_get_resource_by_key(&zs._val.in->val, &keyexpr); - if (r == NULL) { - uint16_t id = _z_declare_resource(&zs._val.in->val, keyexpr); - key = _z_rid_with_suffix(id, NULL); - } - - _z_subinfo_t subinfo = _z_subinfo_pull_default(); - if (options != NULL) { - subinfo.reliability = options->reliability; - } - - return (z_owned_pull_subscriber_t){ - ._value = _z_declare_subscriber(&zs._val, key, subinfo, callback->call, callback->drop, ctx)}; -} - int8_t z_undeclare_subscriber(z_owned_subscriber_t *sub) { int8_t ret = _Z_RES_OK; @@ -1068,17 +1036,6 @@ int8_t z_undeclare_subscriber(z_owned_subscriber_t *sub) { return ret; } -int8_t z_undeclare_pull_subscriber(z_owned_pull_subscriber_t *sub) { - int8_t ret = _Z_RES_OK; - - _z_undeclare_subscriber(sub->_value); - _z_subscriber_free(&sub->_value); - - return ret; -} - -int8_t z_subscriber_pull(const z_pull_subscriber_t sub) { return _z_subscriber_pull(sub._val); } - z_owned_keyexpr_t z_subscriber_keyexpr(z_subscriber_t sub) { z_owned_keyexpr_t ret = z_keyexpr_null(); uint32_t lookup = sub._val->_entity_id; diff --git a/src/net/primitives.c b/src/net/primitives.c index 2aa5b7920..7d459350a 100644 --- a/src/net/primitives.c +++ b/src/net/primitives.c @@ -212,8 +212,8 @@ _z_subscriber_t *_z_declare_subscriber(_z_session_rc_t *zn, _z_keyexpr_t keyexpr return NULL; } // Build the declare message to send on the wire - _z_declaration_t declaration = _z_make_decl_subscriber( - &keyexpr, s._id, sub_info.reliability == Z_RELIABILITY_RELIABLE, sub_info.mode == Z_SUBMODE_PULL); + _z_declaration_t declaration = + _z_make_decl_subscriber(&keyexpr, s._id, sub_info.reliability == Z_RELIABILITY_RELIABLE); _z_network_message_t n_msg = _z_n_msg_make_declare(declaration); if (_z_send_n_msg(&zn->in->val, &n_msg, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK) != _Z_RES_OK) { _z_unregister_subscription(&zn->in->val, _Z_RESOURCE_IS_LOCAL, sp_s); @@ -254,24 +254,6 @@ int8_t _z_undeclare_subscriber(_z_subscriber_t *sub) { _z_session_rc_drop(&sub->_zn); return _Z_RES_OK; } - -/*------------------ Pull ------------------*/ -int8_t _z_subscriber_pull(const _z_subscriber_t *sub) { - int8_t ret = _Z_RES_OK; - - _z_subscription_rc_t *s = _z_get_subscription_by_id(&sub->_zn.in->val, _Z_RESOURCE_IS_LOCAL, sub->_entity_id); - if (s != NULL) { - _z_zint_t pull_id = _z_get_pull_id(&sub->_zn.in->val); - _z_zenoh_message_t z_msg = _z_msg_make_pull(_z_keyexpr_alias(s->in->val._key), pull_id); - if (_z_send_n_msg(&sub->_zn.in->val, &z_msg, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK) != _Z_RES_OK) { - ret = _Z_ERR_TRANSPORT_TX_FAILED; - } - } else { - ret = _Z_ERR_ENTITY_UNKNOWN; - } - - return ret; -} #endif #if Z_FEATURE_QUERYABLE == 1 diff --git a/src/net/subscribe.c b/src/net/subscribe.c index 316966897..23c7faddb 100644 --- a/src/net/subscribe.c +++ b/src/net/subscribe.c @@ -14,19 +14,9 @@ #include "zenoh-pico/net/subscribe.h" #if Z_FEATURE_SUBSCRIPTION == 1 -_z_subinfo_t _z_subinfo_push_default(void) { +_z_subinfo_t _z_subinfo_default(void) { _z_subinfo_t si; - si.reliability = Z_RELIABILITY_RELIABLE; - si.mode = Z_SUBMODE_PUSH; - si.period = (_z_period_t){.origin = 0, .period = 0, .duration = 0}; - return si; -} - -_z_subinfo_t _z_subinfo_pull_default(void) { - _z_subinfo_t si; - si.reliability = Z_RELIABILITY_RELIABLE; - si.mode = Z_SUBMODE_PULL; - si.period = (_z_period_t){.origin = 0, .period = 0, .duration = 0}; + si.reliability = Z_RELIABILITY_BEST_EFFORT; return si; } diff --git a/src/protocol/codec.c b/src/protocol/codec.c index 5320f12b1..2e13129ed 100644 --- a/src/protocol/codec.c +++ b/src/protocol/codec.c @@ -20,38 +20,6 @@ #include "zenoh-pico/utils/logging.h" #include "zenoh-pico/utils/result.h" -/*------------------ period ------------------*/ -int8_t _z_period_encode(_z_wbuf_t *buf, const _z_period_t *tp) { - _Z_RETURN_IF_ERR(_z_uint_encode(buf, tp->origin)) - _Z_RETURN_IF_ERR(_z_uint_encode(buf, tp->period)) - return _z_uint_encode(buf, tp->duration); -} - -int8_t _z_period_decode_na(_z_period_t *p, _z_zbuf_t *buf) { - int8_t ret = _Z_RES_OK; - - ret |= _z_uint_decode(&p->origin, buf); - if (ret == _Z_RES_OK) { - ret |= _z_uint_decode(&p->period, buf); - } else { - p->origin = 0; - } - - if (ret == _Z_RES_OK) { - ret |= _z_uint_decode(&p->duration, buf); - } else { - p->period = 0; - } - - if (ret != _Z_RES_OK) { - p->duration = 0; - } - - return ret; -} - -int8_t _z_period_decode(_z_period_t *p, _z_zbuf_t *buf) { return _z_period_decode_na(p, buf); } - /*------------------ uint8 -------------------*/ int8_t _z_encoding_prefix_encode(_z_wbuf_t *wbf, z_encoding_prefix_t en) { return _z_zint_encode(wbf, en); } diff --git a/src/protocol/codec/declarations.c b/src/protocol/codec/declarations.c index 0ba99c755..207bd6129 100644 --- a/src/protocol/codec/declarations.c +++ b/src/protocol/codec/declarations.c @@ -77,12 +77,11 @@ int8_t _z_decl_commons_encode(_z_wbuf_t *wbf, uint8_t header, _Bool has_extensio } int8_t _z_decl_subscriber_encode(_z_wbuf_t *wbf, const _z_decl_subscriber_t *decl) { uint8_t header = _Z_DECL_SUBSCRIBER_MID; - _Bool has_submode_ext = decl->_ext_subinfo._pull_mode || decl->_ext_subinfo._reliable; + _Bool has_submode_ext = decl->_ext_subinfo._reliable; _Z_RETURN_IF_ERR(_z_decl_commons_encode(wbf, header, has_submode_ext, decl->_id, decl->_keyexpr)); if (has_submode_ext) { _Z_RETURN_IF_ERR(_z_uint8_encode(wbf, _Z_MSG_EXT_ENC_ZINT | 0x01)); - _Z_RETURN_IF_ERR( - _z_uint8_encode(wbf, (decl->_ext_subinfo._pull_mode ? 2 : 0) | (decl->_ext_subinfo._reliable ? 1 : 0))); + _Z_RETURN_IF_ERR(_z_uint8_encode(wbf, (decl->_ext_subinfo._reliable ? 1 : 0))); } return _Z_RES_OK; @@ -301,7 +300,6 @@ int8_t _z_decl_subscriber_decode_extensions(_z_msg_ext_t *extension, void *ctx) _z_decl_subscriber_t *decl = (_z_decl_subscriber_t *)ctx; switch (extension->_header) { case _Z_MSG_EXT_ENC_ZINT | 0x01: { - decl->_ext_subinfo._pull_mode = _Z_HAS_FLAG(extension->_body._zint._val, 2); decl->_ext_subinfo._reliable = _Z_HAS_FLAG(extension->_body._zint._val, 1); } break; default: diff --git a/src/protocol/codec/message.c b/src/protocol/codec/message.c index 667de4d89..f79a641ee 100644 --- a/src/protocol/codec/message.c +++ b/src/protocol/codec/message.c @@ -617,46 +617,6 @@ int8_t _z_err_decode(_z_msg_err_t *err, _z_zbuf_t *zbf, uint8_t header) { return _Z_RES_OK; } -int8_t _z_pull_encode(_z_wbuf_t *wbf, const _z_msg_pull_t *pull) { - int8_t ret = _Z_RES_OK; - uint8_t header = _Z_MID_Z_PULL; - _Bool has_info_ext = _z_id_check(pull->_ext_source_info._id) || pull->_ext_source_info._source_sn != 0 || - pull->_ext_source_info._entity_id != 0; - if (has_info_ext) { - header |= _Z_FLAG_Z_Z; - } - _Z_RETURN_IF_ERR(_z_uint8_encode(wbf, header)); - if (has_info_ext) { - _Z_RETURN_IF_ERR(_z_uint8_encode(wbf, _Z_MSG_EXT_ENC_ZBUF | 0x01)); - _Z_RETURN_IF_ERR(_z_source_info_encode_ext(wbf, &pull->_ext_source_info)); - } - return ret; -} -int8_t _z_pull_decode_extension(_z_msg_ext_t *extension, void *ctx) { - int8_t ret = _Z_RES_OK; - _z_msg_pull_t *pull = (_z_msg_pull_t *)ctx; - switch (_Z_EXT_FULL_ID(extension->_header)) { - case _Z_MSG_EXT_ENC_ZBUF | 0x01: { - _z_zbuf_t zbf = _z_zbytes_as_zbuf(extension->_body._zbuf._val); - ret = _z_source_info_decode(&pull->_ext_source_info, &zbf); - break; - } - default: - if (_Z_HAS_FLAG(extension->_header, _Z_MSG_EXT_FLAG_M)) { - ret = _z_msg_ext_unknown_error(extension, 0x0c); - } - } - return ret; -} -int8_t _z_pull_decode(_z_msg_pull_t *pull, _z_zbuf_t *zbf, uint8_t header) { - *pull = (_z_msg_pull_t){0}; - int8_t ret = _Z_RES_OK; - if ((ret == _Z_RES_OK) && _Z_HAS_FLAG(header, _Z_FLAG_Z_Z)) { - ret = _z_msg_ext_decode_iter(zbf, _z_pull_decode_extension, pull); - } - return ret; -} - /*=============================*/ /* Scouting Messages */ /*=============================*/ diff --git a/src/protocol/codec/network.c b/src/protocol/codec/network.c index a971b2272..2c60d2f4c 100644 --- a/src/protocol/codec/network.c +++ b/src/protocol/codec/network.c @@ -162,9 +162,6 @@ int8_t _z_request_encode(_z_wbuf_t *wbf, const _z_n_msg_request_t *msg) { case _Z_REQUEST_DEL: { _Z_RETURN_IF_ERR(_z_del_encode(wbf, &msg->_body._del)); } break; - case _Z_REQUEST_PULL: { - _Z_RETURN_IF_ERR(_z_pull_encode(wbf, &msg->_body._pull)); - } break; } return ret; } @@ -233,10 +230,6 @@ int8_t _z_request_decode(_z_n_msg_request_t *msg, _z_zbuf_t *zbf, const uint8_t msg->_tag = _Z_REQUEST_DEL; _Z_RETURN_IF_ERR(_z_del_decode(&msg->_body._del, zbf, zheader)); } break; - case _Z_MID_Z_PULL: { - msg->_tag = _Z_REQUEST_PULL; - _Z_RETURN_IF_ERR(_z_pull_decode(&msg->_body._pull, zbf, zheader)); - } break; default: return _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; } diff --git a/src/protocol/definitions/declarations.c b/src/protocol/definitions/declarations.c index 56f004a18..709899619 100644 --- a/src/protocol/definitions/declarations.c +++ b/src/protocol/definitions/declarations.c @@ -69,12 +69,11 @@ _z_declaration_t _z_make_decl_keyexpr(uint16_t id, _Z_MOVE(_z_keyexpr_t) key) { _z_declaration_t _z_make_undecl_keyexpr(uint16_t id) { return (_z_declaration_t){._tag = _Z_UNDECL_KEXPR, ._body = {._undecl_kexpr = {._id = id}}}; } -_z_declaration_t _z_make_decl_subscriber(_Z_MOVE(_z_keyexpr_t) key, uint32_t id, _Bool reliable, _Bool pull_mode) { +_z_declaration_t _z_make_decl_subscriber(_Z_MOVE(_z_keyexpr_t) key, uint32_t id, _Bool reliable) { return (_z_declaration_t){ ._tag = _Z_DECL_SUBSCRIBER, - ._body = {._decl_subscriber = {._id = id, - ._keyexpr = _z_keyexpr_steal(key), - ._ext_subinfo = {._pull_mode = pull_mode, ._reliable = reliable}}}}; + ._body = {._decl_subscriber = { + ._id = id, ._keyexpr = _z_keyexpr_steal(key), ._ext_subinfo = {._reliable = reliable}}}}; } _z_declaration_t _z_make_undecl_subscriber(uint32_t id, _Z_OPTIONAL const _z_keyexpr_t *key) { diff --git a/src/protocol/definitions/network.c b/src/protocol/definitions/network.c index 5cef555d8..3ba4df67e 100644 --- a/src/protocol/definitions/network.c +++ b/src/protocol/definitions/network.c @@ -56,9 +56,6 @@ void _z_n_msg_request_clear(_z_n_msg_request_t *msg) { case _Z_REQUEST_DEL: { _z_msg_del_clear(&msg->_body._del); } break; - case _Z_REQUEST_PULL: { - _z_msg_pull_clear(&msg->_body._pull); - } break; } } @@ -140,30 +137,7 @@ void _z_n_msg_free(_z_network_message_t **msg) { *msg = NULL; } } -_z_network_message_t _z_msg_make_pull(_z_keyexpr_t key, _z_zint_t pull_id) { - _z_network_message_t ret = { - ._tag = _Z_N_REQUEST, - ._body = - { - ._request = - { - ._rid = pull_id, - ._key = key, - ._tag = _Z_REQUEST_PULL, - ._body = - { - ._pull = {._ext_source_info = _z_source_info_null()}, - }, - ._ext_budget = 0, - ._ext_qos = _Z_N_QOS_DEFAULT, - ._ext_target = Z_QUERY_TARGET_BEST_MATCHING, - ._ext_timestamp = _z_timestamp_null(), - ._ext_timeout_ms = 0, - }, - }, - }; - return ret; -} + _z_zenoh_message_t _z_msg_make_query(_Z_MOVE(_z_keyexpr_t) key, _Z_MOVE(_z_bytes_t) parameters, _z_zint_t qid, z_consolidation_mode_t consolidation, _Z_MOVE(_z_value_t) value #if Z_FEATURE_ATTACHMENT == 1 diff --git a/src/session/rx.c b/src/session/rx.c index 44507ccf3..7f5b6e209 100644 --- a/src/session/rx.c +++ b/src/session/rx.c @@ -135,9 +135,6 @@ int8_t _z_handle_network_message(_z_session_t *zn, _z_zenoh_message_t *msg, uint ret |= _z_send_n_msg(zn, &final, Z_RELIABILITY_RELIABLE, Z_CONGESTION_CONTROL_BLOCK); } } break; - case _Z_REQUEST_PULL: { - // @TODO: define behaviour - } break; } } break; case _Z_N_RESPONSE: { diff --git a/src/session/subscription.c b/src/session/subscription.c index 68e0cb300..bbe38d100 100644 --- a/src/session/subscription.c +++ b/src/session/subscription.c @@ -37,9 +37,6 @@ void _z_subscription_clear(_z_subscription_t *sub) { _z_keyexpr_clear(&sub->_key); } -/*------------------ Pull ------------------*/ -_z_zint_t _z_get_pull_id(_z_session_t *zn) { return zn->_pull_id++; } - _z_subscription_rc_t *__z_get_subscription_by_id(_z_subscription_rc_list_t *subs, const _z_zint_t id) { _z_subscription_rc_t *ret = NULL; diff --git a/src/session/utils.c b/src/session/utils.c index 0791f4e47..d5d7fe1d7 100644 --- a/src/session/utils.c +++ b/src/session/utils.c @@ -57,7 +57,6 @@ int8_t _z_session_init(_z_session_t *zn, _z_id_t *zid) { zn->_entity_id = 1; zn->_resource_id = 1; zn->_query_id = 1; - zn->_pull_id = 1; // Initialize the data structs zn->_local_resources = NULL; diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index f95fb38e3..b8cd885fa 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -325,14 +325,6 @@ int main(int argc, char **argv) { _ret_int8 = z_undeclare_subscriber(z_move(_ret_sub)); assert_eq(_ret_int8, 0); - printf("Declaring Pull Subscriber..."); - z_owned_closure_sample_t _ret_closure_sample2 = z_closure(data_handler, NULL, &ls1); - z_pull_subscriber_options_t _ret_psub_opt = z_pull_subscriber_options_default(); - z_owned_pull_subscriber_t _ret_psub = - z_declare_pull_subscriber(z_loan(s2), z_keyexpr(keyexpr_str), z_move(_ret_closure_sample2), &_ret_psub_opt); - assert(z_check(_ret_psub)); - printf("Ok\n"); - printf("Declaring Publisher..."); z_publisher_options_t _ret_pub_opt = z_publisher_options_default(); _ret_pub_opt.congestion_control = Z_CONGESTION_CONTROL_BLOCK; @@ -350,11 +342,6 @@ int main(int argc, char **argv) { sleep(SLEEP); - printf("Pull Subscriber Pulling data..."); - _ret_int8 = z_subscriber_pull(z_loan(_ret_psub)); - assert_eq(_ret_int8, 0); - printf("Ok\n"); - sleep(SLEEP); assert_eq(datas, 3); @@ -366,11 +353,6 @@ int main(int argc, char **argv) { sleep(SLEEP); - printf("Pull Subscriber Pulling data..."); - _ret_int8 = z_subscriber_pull(z_loan(_ret_psub)); - assert_eq(_ret_int8, 0); - printf("Ok\n"); - sleep(SLEEP); assert_eq(datas, 4); @@ -380,11 +362,6 @@ int main(int argc, char **argv) { assert(!z_check(_ret_pub)); printf("Ok\n"); - printf("Undeclaring Pull Subscriber..."); - _ret_int8 = z_undeclare_pull_subscriber(z_move(_ret_psub)); - assert_eq(_ret_int8, 0); - printf("Ok\n"); - sleep(SLEEP); printf("Declaring Queryable..."); diff --git a/tests/z_api_null_drop_test.c b/tests/z_api_null_drop_test.c index a3c0f74cf..51d65328d 100644 --- a/tests/z_api_null_drop_test.c +++ b/tests/z_api_null_drop_test.c @@ -81,15 +81,10 @@ int main(void) { assert(!z_check(publisher_null_2)); #endif #if Z_FEATURE_SUBSCRIPTION == 1 - z_owned_pull_subscriber_t pull_subscriber_null_1 = z_pull_subscriber_null(); z_owned_subscriber_t subscriber_null_1 = z_subscriber_null(); - assert(!z_check(pull_subscriber_null_1)); assert(!z_check(subscriber_null_1)); - z_owned_pull_subscriber_t pull_subscriber_null_2; z_owned_subscriber_t subscriber_null_2; - z_null(&pull_subscriber_null_2); z_null(&subscriber_null_2); - assert(!z_check(pull_subscriber_null_2)); assert(!z_check(subscriber_null_2)); #endif #if Z_FEATURE_QUERYABLE == 1 @@ -150,9 +145,7 @@ int main(void) { z_drop(z_move(publisher_null_2)); #endif #if Z_FEATURE_SUBSCRIPTION == 1 - z_drop(z_move(pull_subscriber_null_1)); z_drop(z_move(subscriber_null_1)); - z_drop(z_move(pull_subscriber_null_2)); z_drop(z_move(subscriber_null_2)); #endif #if Z_FEATURE_QUERYABLE == 1 diff --git a/tests/z_msgcodec_test.c b/tests/z_msgcodec_test.c index aa88739f2..586cee3e5 100644 --- a/tests/z_msgcodec_test.c +++ b/tests/z_msgcodec_test.c @@ -573,37 +573,15 @@ void timestamp_field(void) { /*------------------ SubInfo field ------------------*/ _z_subinfo_t gen_subinfo(void) { _z_subinfo_t sm; - sm.mode = gen_bool() ? Z_SUBMODE_PUSH : Z_SUBMODE_PULL; sm.reliability = gen_bool() ? Z_RELIABILITY_RELIABLE : Z_RELIABILITY_BEST_EFFORT; - if (gen_bool()) { - sm.period.origin = gen_uint(); - sm.period.period = gen_uint(); - sm.period.duration = gen_uint(); - } else { - sm.period.origin = 0; - sm.period.period = 0; - sm.period.duration = 0; - } return sm; } void assert_eq_subinfo(_z_subinfo_t *left, _z_subinfo_t *right) { printf("SubInfo -> "); - printf("Mode (%u:%u), ", left->mode, right->mode); - assert(left->mode == right->mode); - printf("Reliable (%u:%u), ", left->reliability, right->reliability); assert(left->reliability == right->reliability); - - printf("Period ("); - printf("<%u:%u,%u>", left->period.origin, left->period.period, left->period.duration); - printf(":"); - printf("<%u:%u,%u>", right->period.origin, right->period.period, right->period.duration); - printf(")"); - assert(left->period.origin == right->period.origin); - assert(left->period.period == right->period.period); - assert(left->period.duration == right->period.duration); } /*------------------ ResKey field ------------------*/ @@ -718,15 +696,13 @@ _z_decl_subscriber_t gen_subscriber_declaration(void) { _z_subinfo_t subinfo = gen_subinfo(); _z_decl_subscriber_t e_sd = {._keyexpr = gen_keyexpr(), ._id = (uint32_t)gen_uint64(), - ._ext_subinfo = {._pull_mode = subinfo.mode == Z_SUBMODE_PULL, - ._reliable = subinfo.reliability == Z_RELIABILITY_RELIABLE}}; + ._ext_subinfo = {._reliable = subinfo.reliability == Z_RELIABILITY_RELIABLE}}; return e_sd; } void assert_eq_subscriber_declaration(const _z_decl_subscriber_t *left, const _z_decl_subscriber_t *right) { assert_eq_keyexpr(&left->_keyexpr, &right->_keyexpr); assert(left->_id == right->_id); - assert(left->_ext_subinfo._pull_mode == right->_ext_subinfo._pull_mode); assert(left->_ext_subinfo._reliable == right->_ext_subinfo._reliable); } @@ -1104,33 +1080,6 @@ void push_body_message(void) { _z_wbuf_clear(&wbf); } -/*------------------ Pull message ------------------*/ -_z_msg_pull_t gen_pull_message(void) { return (_z_msg_pull_t){._ext_source_info = _z_source_info_null()}; } - -void assert_eq_pull_message(_z_msg_pull_t *left, _z_msg_pull_t *right) { - assert_eq_source_info(&left->_ext_source_info, &right->_ext_source_info); -} - -void pull_message(void) { - printf("\n>> Pull message\n"); - _z_wbuf_t wbf = gen_wbuf(UINT16_MAX); - _z_msg_pull_t e_pull_msg = gen_pull_message(); - - assert(_z_pull_encode(&wbf, &e_pull_msg) == _Z_RES_OK); - - _z_zbuf_t zbf = _z_wbuf_to_zbuf(&wbf); - uint8_t header = _z_zbuf_read(&zbf); - - _z_msg_pull_t d_pull_msg; - assert(_z_pull_decode(&d_pull_msg, &zbf, header) == _Z_RES_OK); - assert_eq_pull_message(&e_pull_msg, &d_pull_msg); - - _z_msg_pull_clear(&e_pull_msg); - _z_msg_pull_clear(&d_pull_msg); - _z_zbuf_clear(&zbf); - _z_wbuf_clear(&wbf); -} - _z_msg_query_t gen_query(void) { return (_z_msg_query_t){ ._consolidation = (gen_uint8() % 4) - 1, @@ -1265,16 +1214,12 @@ _z_n_msg_request_t gen_request(void) { ._ext_budget = gen_bool() ? (uint32_t)gen_uint64() : 0, ._ext_timeout_ms = gen_bool() ? (uint32_t)gen_uint64() : 0, }; - switch (gen_uint8() % 4) { + switch (gen_uint8() % 2) { case 0: { request._tag = _Z_REQUEST_QUERY; request._body._query = gen_query(); } break; - case 1: { - request._tag = _Z_REQUEST_PULL; - request._body._pull = - (_z_msg_pull_t){._ext_source_info = gen_bool() ? gen_source_info() : _z_source_info_null()}; - } break; + case 1: default: { _z_push_body_t body = gen_push_body(); if (body._is_put) { @@ -1310,9 +1255,6 @@ void assert_eq_request(const _z_n_msg_request_t *left, const _z_n_msg_request_t assert_eq_push_body(&(_z_push_body_t){._is_put = false, ._body._del = left->_body._del}, &(_z_push_body_t){._is_put = false, ._body._del = right->_body._del}); } break; - case _Z_REQUEST_PULL: { - assert_eq_source_info(&left->_body._pull._ext_source_info, &right->_body._pull._ext_source_info); - } break; } } @@ -1815,7 +1757,6 @@ int main(void) { // Zenoh messages declare_message(); push_body_message(); - pull_message(); query_message(); err_message(); reply_message(); From 61254245b936681b780c141a22fdb2c3a20444a7 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 19 Mar 2024 15:13:15 +0100 Subject: [PATCH 03/21] Remove Put/Del from ResponseBody --- include/zenoh-pico/protocol/codec/message.h | 6 ++--- .../zenoh-pico/protocol/definitions/network.h | 4 --- src/protocol/codec/network.c | 18 ------------- src/protocol/definitions/network.c | 7 ----- src/session/rx.c | 27 ------------------- tests/z_msgcodec_test.c | 25 +++-------------- 6 files changed, 7 insertions(+), 80 deletions(-) diff --git a/include/zenoh-pico/protocol/codec/message.h b/include/zenoh-pico/protocol/codec/message.h index c40f2824a..1ad2de4ba 100644 --- a/include/zenoh-pico/protocol/codec/message.h +++ b/include/zenoh-pico/protocol/codec/message.h @@ -18,6 +18,9 @@ #include "zenoh-pico/protocol/definitions/network.h" #include "zenoh-pico/protocol/iobuf.h" +int8_t _z_push_body_encode(_z_wbuf_t *wbf, const _z_push_body_t *pshb); +int8_t _z_push_body_decode(_z_push_body_t *body, _z_zbuf_t *zbf, uint8_t header); + int8_t _z_query_encode(_z_wbuf_t *wbf, const _z_msg_query_t *query); int8_t _z_query_decode(_z_msg_query_t *query, _z_zbuf_t *zbf, uint8_t header); @@ -27,9 +30,6 @@ int8_t _z_reply_decode(_z_msg_reply_t *reply, _z_zbuf_t *zbf, uint8_t header); int8_t _z_err_encode(_z_wbuf_t *wbf, const _z_msg_err_t *err); int8_t _z_err_decode(_z_msg_err_t *err, _z_zbuf_t *zbf, uint8_t header); -int8_t _z_push_body_encode(_z_wbuf_t *wbf, const _z_push_body_t *pshb); -int8_t _z_push_body_decode(_z_push_body_t *body, _z_zbuf_t *zbf, uint8_t header); - int8_t _z_put_encode(_z_wbuf_t *wbf, const _z_msg_put_t *put); int8_t _z_put_decode(_z_msg_put_t *put, _z_zbuf_t *zbf, uint8_t header); diff --git a/include/zenoh-pico/protocol/definitions/network.h b/include/zenoh-pico/protocol/definitions/network.h index 55fad899b..94d7736c8 100644 --- a/include/zenoh-pico/protocol/definitions/network.h +++ b/include/zenoh-pico/protocol/definitions/network.h @@ -183,14 +183,10 @@ typedef struct { enum { _Z_RESPONSE_BODY_REPLY, _Z_RESPONSE_BODY_ERR, - _Z_RESPONSE_BODY_PUT, - _Z_RESPONSE_BODY_DEL, } _tag; union { _z_msg_reply_t _reply; _z_msg_err_t _err; - _z_msg_put_t _put; - _z_msg_del_t _del; } _body; } _z_n_msg_response_t; void _z_n_msg_response_clear(_z_n_msg_response_t *msg); diff --git a/src/protocol/codec/network.c b/src/protocol/codec/network.c index 2c60d2f4c..53d534e6f 100644 --- a/src/protocol/codec/network.c +++ b/src/protocol/codec/network.c @@ -298,14 +298,6 @@ int8_t _z_response_encode(_z_wbuf_t *wbf, const _z_n_msg_response_t *msg) { _Z_RETURN_IF_ERR(_z_err_encode(wbf, &msg->_body._err)); break; } - case _Z_RESPONSE_BODY_PUT: { - _Z_RETURN_IF_ERR(_z_put_encode(wbf, &msg->_body._put)); - break; - } - case _Z_RESPONSE_BODY_DEL: { - _Z_RETURN_IF_ERR(_z_del_encode(wbf, &msg->_body._del)); - break; - } } return ret; @@ -368,16 +360,6 @@ int8_t _z_response_decode(_z_n_msg_response_t *msg, _z_zbuf_t *zbf, uint8_t head ret = _z_err_decode(&msg->_body._err, zbf, inner_header); break; } - case _Z_MID_Z_PUT: { - msg->_tag = _Z_RESPONSE_BODY_PUT; - ret = _z_put_decode(&msg->_body._put, zbf, inner_header); - break; - } - case _Z_MID_Z_DEL: { - msg->_tag = _Z_RESPONSE_BODY_DEL; - ret = _z_del_decode(&msg->_body._del, zbf, inner_header); - break; - } default: { _Z_ERROR("Unknown N_MID: %d", _Z_MID(inner_header)); ret = _Z_ERR_MESSAGE_DESERIALIZATION_FAILED; diff --git a/src/protocol/definitions/network.c b/src/protocol/definitions/network.c index 3ba4df67e..9836113cb 100644 --- a/src/protocol/definitions/network.c +++ b/src/protocol/definitions/network.c @@ -97,13 +97,6 @@ void _z_n_msg_response_clear(_z_n_msg_response_t *msg) { _z_msg_err_clear(&msg->_body._err); break; } - case _Z_RESPONSE_BODY_PUT: { - _z_msg_put_clear(&msg->_body._put); - break; - } - case _Z_RESPONSE_BODY_DEL: { - break; - } } } diff --git a/src/session/rx.c b/src/session/rx.c index 7f5b6e209..451ed1551 100644 --- a/src/session/rx.c +++ b/src/session/rx.c @@ -152,33 +152,6 @@ int8_t _z_handle_network_message(_z_session_t *zn, _z_zenoh_message_t *msg, uint _Z_ERROR("Received Err for query %zu: message=%.*s", response._request_id, (int)payload.len, payload.start); } break; - case _Z_RESPONSE_BODY_PUT: { - _z_msg_put_t put = response._body._put; -#if Z_FEATURE_SUBSCRIPTION == 1 -#if Z_FEATURE_ATTACHMENT == 1 - z_attachment_t att = _z_encoded_as_attachment(&put._attachment); -#endif - ret = _z_trigger_subscriptions(zn, response._key, put._payload, put._encoding, Z_SAMPLE_KIND_PUT, - put._commons._timestamp -#if Z_FEATURE_ATTACHMENT == 1 - , - att -#endif - ); -#endif - } break; - case _Z_RESPONSE_BODY_DEL: { - _z_msg_del_t del = response._body._del; -#if Z_FEATURE_SUBSCRIPTION == 1 - ret = _z_trigger_subscriptions(zn, response._key, _z_bytes_empty(), z_encoding_default(), - Z_SAMPLE_KIND_DELETE, del._commons._timestamp -#if Z_FEATURE_ATTACHMENT == 1 - , - z_attachment_null() -#endif - ); -#endif - } break; } } break; case _Z_N_RESPONSE_FINAL: { diff --git a/tests/z_msgcodec_test.c b/tests/z_msgcodec_test.c index 586cee3e5..cd7f562f1 100644 --- a/tests/z_msgcodec_test.c +++ b/tests/z_msgcodec_test.c @@ -1283,26 +1283,16 @@ _z_n_msg_response_t gen_response(void) { ._ext_timestamp = gen_bool() ? gen_timestamp() : _z_timestamp_null(), ._ext_responder = {._eid = gen_uint16(), ._zid = gen_zid()}, }; - switch (gen_uint() % 3) { + switch (gen_uint() % 2) { case 0: { ret._tag = _Z_RESPONSE_BODY_ERR; ret._body._err = gen_err(); } break; - case 1: { + case 1: + default: { ret._tag = _Z_RESPONSE_BODY_REPLY; ret._body._reply = gen_reply(); } break; - case 2: - default: { - _z_push_body_t body = gen_push_body(); - if (body._is_put) { - ret._tag = _Z_RESPONSE_BODY_PUT; - ret._body._put = body._body._put; - } else { - ret._tag = _Z_RESPONSE_BODY_DEL; - ret._body._del = body._body._del; - } - } break; } return ret; } @@ -1321,14 +1311,7 @@ void assert_eq_response(const _z_n_msg_response_t *left, const _z_n_msg_response } break; case _Z_RESPONSE_BODY_ERR: { assert_eq_err(&left->_body._err, &right->_body._err); - } break; - case _Z_RESPONSE_BODY_PUT: { - assert_eq_push_body(&(_z_push_body_t){._is_put = true, ._body._put = left->_body._put}, - &(_z_push_body_t){._is_put = true, ._body._put = right->_body._put}); - } break; - case _Z_RESPONSE_BODY_DEL: { - assert_eq_push_body(&(_z_push_body_t){._is_put = false, ._body._del = left->_body._del}, - &(_z_push_body_t){._is_put = false, ._body._del = right->_body._del}); + } break; } } From e781e8476498a9ef9091e42462e590c3b09b0b41 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 19 Mar 2024 15:14:18 +0100 Subject: [PATCH 04/21] Cleanup flags --- include/zenoh-pico/protocol/definitions/message.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/include/zenoh-pico/protocol/definitions/message.h b/include/zenoh-pico/protocol/definitions/message.h index ea3311318..f1bfed6b5 100644 --- a/include/zenoh-pico/protocol/definitions/message.h +++ b/include/zenoh-pico/protocol/definitions/message.h @@ -24,23 +24,13 @@ #define _Z_MID_Z_QUERY 0x03 #define _Z_MID_Z_REPLY 0x04 #define _Z_MID_Z_ERR 0x05 -#define _Z_MID_Z_PULL 0x07 -#define _Z_MID_Z_LINK_STATE_LIST 0x10 /* Zenoh message flags */ #define _Z_FLAG_Z_Z 0x80 -#define _Z_FLAG_Z_B 0x40 // 1 << 6 | QueryPayload if B==1 then QueryPayload is present #define _Z_FLAG_Z_D 0x20 // 1 << 5 | Dropping if D==1 then the message can be dropped -#define _Z_FLAG_Z_F \ - 0x20 // 1 << 5 | Final if F==1 then this is the final message (e.g., ReplyContext, Pull) -#define _Z_FLAG_Z_I 0x40 // 1 << 6 | DataInfo if I==1 then DataInfo is present #define _Z_FLAG_Z_K 0x80 // 1 << 7 | ResourceKey if K==1 then keyexpr is string -#define _Z_FLAG_Z_N 0x40 // 1 << 6 | MaxSamples if N==1 then the MaxSamples is indicated -#define _Z_FLAG_Z_Q 0x40 // 1 << 6 | QueryableKind if Q==1 then the queryable kind is present #define _Z_FLAG_Z_R \ 0x20 // 1 << 5 | Reliable if R==1 then it concerns the reliable channel, best-effort otherwise -#define _Z_FLAG_Z_S 0x40 // 1 << 6 | SubMode if S==1 then the declaration SubMode is indicated -#define _Z_FLAG_Z_T 0x20 // 1 << 5 | QueryTarget if T==1 then the query target is present #define _Z_FLAG_Z_X 0x00 // Unused flags are set to zero #define _Z_FRAG_BUFF_BASE_SIZE 128 // Arbitrary base size of the buffer to encode a fragment message header From 557e6653dc572529928f7a64bb0ab3995805cfea Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 19 Mar 2024 15:55:06 +0100 Subject: [PATCH 05/21] Comment unusued variables in pull examples --- examples/arduino/z_pull.ino | 25 ++++++++++++++----------- examples/espidf/z_pull.c | 16 +++++++++------- examples/freertos_plus_tcp/z_pull.c | 18 ++++++++++-------- examples/mbed/z_pull.cpp | 16 +++++++++------- examples/unix/c11/z_pull.c | 18 ++++++++++-------- examples/unix/c99/z_pull.c | 18 ++++++++++-------- examples/windows/z_pull.c | 18 ++++++++++-------- examples/zephyr/z_pull.c | 16 +++++++++------- 8 files changed, 81 insertions(+), 64 deletions(-) diff --git a/examples/arduino/z_pull.ino b/examples/arduino/z_pull.ino index 7f10ef35c..17b7b3722 100644 --- a/examples/arduino/z_pull.ino +++ b/examples/arduino/z_pull.ino @@ -34,20 +34,22 @@ #define KEYEXPR "demo/example/**" +// @TODO // z_owned_pull_subscriber_t sub; -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - std::string val((const char *)sample->payload.start, sample->payload.len); +// @TODO +// void data_handler(const z_sample_t *sample, void *arg) { +// z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); +// std::string val((const char *)sample->payload.start, sample->payload.len); - Serial.print(" >> [Subscription listener] Received ("); - Serial.print(z_str_loan(&keystr)); - Serial.print(", "); - Serial.print(val.c_str()); - Serial.println(")"); +// Serial.print(" >> [Subscription listener] Received ("); +// Serial.print(z_str_loan(&keystr)); +// Serial.print(", "); +// Serial.print(val.c_str()); +// Serial.println(")"); - z_str_drop(z_str_move(&keystr)); -} +// z_str_drop(z_str_move(&keystr)); +// } void setup() { // Initialize Serial for debug @@ -91,7 +93,8 @@ void setup() { Serial.print("Declaring Subscriber on "); Serial.print(KEYEXPR); Serial.println(" ..."); - z_owned_closure_sample_t callback = z_closure_sample(data_handler, NULL, NULL); + // @TODO + // z_owned_closure_sample_t callback = z_closure_sample(data_handler, NULL, NULL); // @TODO // sub = z_declare_pull_subscriber(z_session_loan(&s), z_keyexpr(KEYEXPR), z_closure_sample_move(&callback), NULL); // if (!z_pull_subscriber_check(&sub)) { diff --git a/examples/espidf/z_pull.c b/examples/espidf/z_pull.c index 819f861da..1f092d8eb 100644 --- a/examples/espidf/z_pull.c +++ b/examples/espidf/z_pull.c @@ -100,12 +100,13 @@ void wifi_init_sta(void) { vEventGroupDelete(s_event_group_handler); } -void data_handler(const z_sample_t* sample, void* arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(" >> [Subscriber handler] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, - sample->payload.start); - z_drop(z_move(keystr)); -} +// @TODO +// void data_handler(const z_sample_t* sample, void* arg) { +// z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); +// printf(" >> [Subscriber handler] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, +// sample->payload.start); +// z_drop(z_move(keystr)); +// } void app_main() { esp_err_t ret = nvs_flash_init(); @@ -144,8 +145,9 @@ void app_main() { zp_start_read_task(z_loan(s), NULL); zp_start_lease_task(z_loan(s), NULL); + // @TODO + // z_owned_closure_sample_t callback = z_closure(data_handler); printf("Declaring Subscriber on '%s'...", KEYEXPR); - z_owned_closure_sample_t callback = z_closure(data_handler); // @TODO // z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(KEYEXPR), z_move(callback), NULL); // if (!z_check(sub)) { diff --git a/examples/freertos_plus_tcp/z_pull.c b/examples/freertos_plus_tcp/z_pull.c index 83f855403..b4da92a31 100644 --- a/examples/freertos_plus_tcp/z_pull.c +++ b/examples/freertos_plus_tcp/z_pull.c @@ -28,13 +28,14 @@ #define KEYEXPR "demo/example/**" -void data_handler(const z_sample_t *sample, void *ctx) { - (void)(ctx); - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, - sample->payload.start); - z_drop(z_move(keystr)); -} +// @TODO +// void data_handler(const z_sample_t *sample, void *ctx) { +// (void)(ctx); +// z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); +// printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, +// sample->payload.start); +// z_drop(z_move(keystr)); +// } void app_main(void) { z_owned_config_t config = z_config_default(); @@ -57,7 +58,8 @@ void app_main(void) { return; } - z_owned_closure_sample_t callback = z_closure(data_handler); + // @TODO + // z_owned_closure_sample_t callback = z_closure(data_handler); printf("Declaring Subscriber on '%s'...\n", KEYEXPR); // @TODO // z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(KEYEXPR), z_move(callback), NULL); diff --git a/examples/mbed/z_pull.cpp b/examples/mbed/z_pull.cpp index 0ebfcff50..aae56316e 100644 --- a/examples/mbed/z_pull.cpp +++ b/examples/mbed/z_pull.cpp @@ -30,12 +30,13 @@ #define KEYEXPR "demo/example/**" -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(" >> [Subscriber handler] Received ('%s': '%.*s')\n", z_str_loan(&keystr), (int)sample->payload.len, - sample->payload.start); - z_str_drop(z_str_move(&keystr)); -} +// @TODO +// void data_handler(const z_sample_t *sample, void *arg) { +// z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); +// printf(" >> [Subscriber handler] Received ('%s': '%.*s')\n", z_str_loan(&keystr), (int)sample->payload.len, +// sample->payload.start); +// z_str_drop(z_str_move(&keystr)); +// } int main(int argc, char **argv) { randLIB_seed_random(); @@ -64,8 +65,9 @@ int main(int argc, char **argv) { zp_start_read_task(z_session_loan(&s), NULL); zp_start_lease_task(z_session_loan(&s), NULL); + // @TODO + // z_owned_closure_sample_t callback = z_closure_sample(data_handler, NULL, NULL); printf("Declaring Subscriber on '%s'...", KEYEXPR); - z_owned_closure_sample_t callback = z_closure_sample(data_handler, NULL, NULL); // @TODO // z_owned_pull_subscriber_t sub = // z_declare_pull_subscriber(z_session_loan(&s), z_keyexpr(KEYEXPR), z_closure_sample_move(&callback), NULL); diff --git a/examples/unix/c11/z_pull.c b/examples/unix/c11/z_pull.c index 21c4a7916..a52a23b0d 100644 --- a/examples/unix/c11/z_pull.c +++ b/examples/unix/c11/z_pull.c @@ -19,13 +19,14 @@ #include #if Z_FEATURE_SUBSCRIPTION == 1 -void data_handler(const z_sample_t *sample, void *ctx) { - (void)(ctx); - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, - sample->payload.start); - z_drop(z_move(keystr)); -} +// @TODO +// void data_handler(const z_sample_t *sample, void *ctx) { +// (void)(ctx); +// z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); +// printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, +// sample->payload.start); +// z_drop(z_move(keystr)); +// } int main(int argc, char **argv) { const char *keyexpr = "demo/example/**"; @@ -71,7 +72,8 @@ int main(int argc, char **argv) { return -1; } - z_owned_closure_sample_t callback = z_closure(data_handler); + // @TODO + // z_owned_closure_sample_t callback = z_closure(data_handler); printf("Declaring Subscriber on '%s'...\n", keyexpr); // @TODO diff --git a/examples/unix/c99/z_pull.c b/examples/unix/c99/z_pull.c index dee9d618f..72cc35216 100644 --- a/examples/unix/c99/z_pull.c +++ b/examples/unix/c99/z_pull.c @@ -19,13 +19,14 @@ #include #if Z_FEATURE_SUBSCRIPTION == 1 -void data_handler(const z_sample_t *sample, void *ctx) { - (void)(ctx); - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_str_loan(&keystr), (int)sample->payload.len, - sample->payload.start); - z_str_drop(z_str_move(&keystr)); -} +// @TODO +// void data_handler(const z_sample_t *sample, void *ctx) { +// (void)(ctx); +// z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); +// printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_str_loan(&keystr), (int)sample->payload.len, +// sample->payload.start); +// z_str_drop(z_str_move(&keystr)); +// } int main(int argc, char **argv) { const char *keyexpr = "demo/example/**"; @@ -71,7 +72,8 @@ int main(int argc, char **argv) { return -1; } - z_owned_closure_sample_t callback = z_closure_sample(data_handler, NULL, NULL); + // @TODO + // z_owned_closure_sample_t callback = z_closure_sample(data_handler, NULL, NULL); printf("Declaring Subscriber on '%s'...\n", keyexpr); // @TODO // z_owned_pull_subscriber_t sub = diff --git a/examples/windows/z_pull.c b/examples/windows/z_pull.c index 90f2b892c..515b5e618 100644 --- a/examples/windows/z_pull.c +++ b/examples/windows/z_pull.c @@ -18,13 +18,14 @@ #include #if Z_FEATURE_SUBSCRIPTION == 1 -void data_handler(const z_sample_t *sample, void *ctx) { - (void)(ctx); - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, - sample->payload.start); - z_drop(z_move(keystr)); -} +// @TODO +// void data_handler(const z_sample_t *sample, void *ctx) { +// (void)(ctx); +// z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); +// printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, +// sample->payload.start); +// z_drop(z_move(keystr)); +// } int main(int argc, char **argv) { (void)(argc); @@ -51,7 +52,8 @@ int main(int argc, char **argv) { return -1; } - z_owned_closure_sample_t callback = z_closure(data_handler); + // @TODO + // z_owned_closure_sample_t callback = z_closure(data_handler); printf("Declaring Subscriber on '%s'...\n", keyexpr); // @TODO // z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); diff --git a/examples/zephyr/z_pull.c b/examples/zephyr/z_pull.c index 4246f0814..20e4109b5 100644 --- a/examples/zephyr/z_pull.c +++ b/examples/zephyr/z_pull.c @@ -29,12 +29,13 @@ #define KEYEXPR "demo/example/**" -void data_handler(const z_sample_t *sample, void *arg) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(" >> [Subscriber handler] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, - sample->payload.start); - z_drop(z_move(keystr)); -} +// @TODO +// void data_handler(const z_sample_t *sample, void *arg) { +// z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); +// printf(" >> [Subscriber handler] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, +// sample->payload.start); +// z_drop(z_move(keystr)); +// } int main(int argc, char **argv) { sleep(5); @@ -59,8 +60,9 @@ int main(int argc, char **argv) { zp_start_read_task(z_loan(s), NULL); zp_start_lease_task(z_loan(s), NULL); + // @TODO + // z_owned_closure_sample_t callback = z_closure(data_handler); printf("Declaring Subscriber on '%s'...", KEYEXPR); - z_owned_closure_sample_t callback = z_closure(data_handler); // @TODO // z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(KEYEXPR), z_move(callback), NULL); // if (!z_check(sub)) { From 235226fd94bf6c9d4792229912eb6e8e06a73782 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 19 Mar 2024 17:25:20 +0100 Subject: [PATCH 06/21] Fix alignment test --- tests/z_api_alignment_test.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/z_api_alignment_test.c b/tests/z_api_alignment_test.c index b8cd885fa..84a3a53df 100644 --- a/tests/z_api_alignment_test.c +++ b/tests/z_api_alignment_test.c @@ -308,6 +308,7 @@ int main(int argc, char **argv) { printf("Session delete..."); z_delete_options_t _ret_delete_opt = z_delete_options_default(); + _ret_delete_opt.congestion_control = Z_CONGESTION_CONTROL_BLOCK; _ret_int8 = z_delete(z_loan(s1), z_loan(_ret_expr), &_ret_delete_opt); assert_eq(_ret_int8, 0); printf("Ok\n"); @@ -322,9 +323,6 @@ int main(int argc, char **argv) { assert(!z_check(_ret_expr)); printf("Ok\n"); - _ret_int8 = z_undeclare_subscriber(z_move(_ret_sub)); - assert_eq(_ret_int8, 0); - printf("Declaring Publisher..."); z_publisher_options_t _ret_pub_opt = z_publisher_options_default(); _ret_pub_opt.congestion_control = Z_CONGESTION_CONTROL_BLOCK; @@ -340,8 +338,6 @@ int main(int argc, char **argv) { assert_eq(_ret_int8, 0); printf("Ok\n"); - sleep(SLEEP); - sleep(SLEEP); assert_eq(datas, 3); @@ -351,8 +347,6 @@ int main(int argc, char **argv) { assert_eq(_ret_int8, 0); printf("Ok\n"); - sleep(SLEEP); - sleep(SLEEP); assert_eq(datas, 4); @@ -364,6 +358,14 @@ int main(int argc, char **argv) { sleep(SLEEP); + printf("Undeclaring Subscriber..."); + _ret_int8 = z_undeclare_subscriber(z_move(_ret_sub)); + assert_eq(_ret_int8, 0); + assert(!z_check(_ret_sub)); + printf("Ok\n"); + + sleep(SLEEP); + printf("Declaring Queryable..."); z_owned_closure_query_t _ret_closure_query = z_closure(query_handler, NULL, &ls1); z_queryable_options_t _ret_qle_opt = z_queryable_options_default(); From be9bf0ec2827a090264ffbbe718204a902dfa623 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Tue, 19 Mar 2024 20:37:57 +0100 Subject: [PATCH 07/21] Add ring to collections --- CMakeLists.txt | 2 + include/zenoh-pico/collections/ring.h | 73 +++++++++++++++ include/zenoh-pico/collections/string.h | 6 +- src/collections/ring.c | 96 ++++++++++++++++++++ src/collections/string.c | 2 + tests/z_collections_test.c | 115 ++++++++++++++++++++++++ 6 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 include/zenoh-pico/collections/ring.h create mode 100644 src/collections/ring.c create mode 100644 tests/z_collections_test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 3df82dd66..dd7f6e40d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,6 +331,7 @@ if(UNIX OR MSVC) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests") add_executable(z_data_struct_test ${PROJECT_SOURCE_DIR}/tests/z_data_struct_test.c) + add_executable(z_collections_test ${PROJECT_SOURCE_DIR}/tests/z_collections_test.c) add_executable(z_endpoint_test ${PROJECT_SOURCE_DIR}/tests/z_endpoint_test.c) add_executable(z_iobuf_test ${PROJECT_SOURCE_DIR}/tests/z_iobuf_test.c) add_executable(z_msgcodec_test ${PROJECT_SOURCE_DIR}/tests/z_msgcodec_test.c) @@ -343,6 +344,7 @@ if(UNIX OR MSVC) add_executable(z_perf_rx ${PROJECT_SOURCE_DIR}/tests/z_perf_rx.c) target_link_libraries(z_data_struct_test ${Libname}) + target_link_libraries(z_collections_test ${Libname}) target_link_libraries(z_endpoint_test ${Libname}) target_link_libraries(z_iobuf_test ${Libname}) target_link_libraries(z_msgcodec_test ${Libname}) diff --git a/include/zenoh-pico/collections/ring.h b/include/zenoh-pico/collections/ring.h new file mode 100644 index 000000000..3bcf39e42 --- /dev/null +++ b/include/zenoh-pico/collections/ring.h @@ -0,0 +1,73 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#ifndef ZENOH_PICO_COLLECTIONS_RING_H +#define ZENOH_PICO_COLLECTIONS_RING_H + +#include +#include + +#include "zenoh-pico/collections/element.h" + +/*-------- Ring Queue --------*/ +/** + * A ring queue implemented with a single-linked list. + * + * Members: + * struct _z_ring_t *_head: the head of the single-linked list + * size_t _capacity: The capacity of the ring queue + */ +typedef struct { + size_t _capacity; + size_t _len; + size_t _r_idx; + size_t _w_idx; + void **_val; +} _z_ring_t; + +_z_ring_t _z_ring_make(size_t capacity); + +void *_z_ring_push(_z_ring_t *r, void *e); +void *_z_ring_push_force(_z_ring_t *r, void *e); +void *_z_ring_pull(_z_ring_t *r); + +size_t _z_ring_capacity(const _z_ring_t *r); +size_t _z_ring_len(const _z_ring_t *r); +_Bool _z_ring_is_empty(const _z_ring_t *r); +_Bool _z_ring_is_full(const _z_ring_t *r); + +// _z_ring_t *_z_ring_clone(const _z_ring_t *xs, z_element_clone_f d_f); + +void _z_ring_clear(_z_ring_t *v, z_element_free_f f); +void _z_ring_free(_z_ring_t **xs, z_element_free_f f_f); + +#define _Z_RING_DEFINE(name, type) \ + typedef _z_ring_t name##_ring_t; \ + static inline name##_ring_t name##_ring_make(size_t capacity) { return _z_ring_make(capacity); } \ + static inline size_t name##_ring_capacity(const name##_ring_t *r) { return _z_ring_capacity(r); } \ + static inline size_t name##_ring_len(const name##_ring_t *r) { return _z_ring_len(r); } \ + static inline _Bool name##_ring_is_empty(const name##_ring_t *r) { return _z_ring_is_empty(r); } \ + static inline _Bool name##_ring_is_full(const name##_ring_t *r) { return _z_ring_is_full(r); } \ + static inline type *name##_ring_push(name##_ring_t *r, type *e) { return _z_ring_push(r, (void *)e); } \ + static inline type *name##_ring_push_force(name##_ring_t *r, type *e) { return _z_ring_push_force(r, (void *)e); } \ + static inline void name##_ring_push_force_drop(name##_ring_t *r, type *e) { \ + void *x = _z_ring_push_force(r, (void *)e); \ + if (x != NULL) { \ + name##_elem_free(&x); \ + } \ + } \ + static inline type *name##_ring_pull(name##_ring_t *r) { return (type *)_z_ring_pull(r); } \ + static inline void name##_ring_clear(name##_ring_t *r) { return _z_ring_clear(r, name##_elem_free); } \ + static inline void name##_ring_free(name##_ring_t **r) { _z_ring_free(r, name##_elem_free); } + +#endif /* ZENOH_PICO_COLLECTIONS_RING_H */ diff --git a/include/zenoh-pico/collections/string.h b/include/zenoh-pico/collections/string.h index 38fe3d334..cfbc33978 100644 --- a/include/zenoh-pico/collections/string.h +++ b/include/zenoh-pico/collections/string.h @@ -33,7 +33,7 @@ size_t _z_str_size(const char *src); void _z_str_copy(char *dst, const char *src); void _z_str_n_copy(char *dst, const char *src, size_t size); _Z_ELEM_DEFINE(_z_str, char, _z_str_size, _z_noop_clear, _z_str_copy) -// _Z_ARRAY_DEFINE(_z_str, char *) + // This is here for reference on why // the _z_str_array_t was not defined using this macro // but instead manually as find below @@ -73,6 +73,8 @@ typedef struct { } _z_string_t; _z_string_t _z_string_make(const char *value); + +size_t _z_string_size(const _z_string_t *s); void _z_string_copy(_z_string_t *dst, const _z_string_t *src); void _z_string_move(_z_string_t *dst, _z_string_t *src); void _z_string_move_str(_z_string_t *dst, char *src); @@ -81,6 +83,8 @@ void _z_string_free(_z_string_t **s); void _z_string_reset(_z_string_t *s); _z_string_t _z_string_from_bytes(const _z_bytes_t *bs); +_Z_ELEM_DEFINE(_z_string, _z_string_t, _z_string_size, _z_string_clear, _z_string_copy) + /*-------- str_array --------*/ /** * An array of NULL terminated strings. diff --git a/src/collections/ring.c b/src/collections/ring.c new file mode 100644 index 000000000..e60f64575 --- /dev/null +++ b/src/collections/ring.c @@ -0,0 +1,96 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#include "zenoh-pico/collections/ring.h" + +#include +#include +#include + +/*-------- ring --------*/ +_z_ring_t _z_ring_make(size_t capacity) { + // We need one more element to differentiate wether the ring is empty or full + capacity += 1; + + _z_ring_t v = {._capacity = capacity, ._r_idx = 0, ._w_idx = 0, ._val = NULL}; + if (capacity != 0) { + v._val = (void **)zp_malloc(sizeof(void *) * capacity); + } + if (v._val != NULL) { + memset(v._val, 0, capacity); + v._capacity = capacity; + } + return v; +} + +size_t _z_ring_capacity(const _z_ring_t *r) { return r->_capacity - 1; } + +size_t _z_ring_len(const _z_ring_t *r) { + if (r->_w_idx >= r->_r_idx) { + return r->_w_idx - r->_r_idx; + } else { + return r->_w_idx + (r->_capacity - r->_r_idx); + } +} + +_Bool _z_ring_is_empty(const _z_ring_t *r) { return r->_w_idx == r->_r_idx; } + +_Bool _z_ring_is_full(const _z_ring_t *r) { return _z_ring_len(r) == _z_ring_capacity(r); } + +void *_z_ring_push(_z_ring_t *r, void *e) { + void *ret = e; + if (!_z_ring_is_full(r)) { + r->_val[r->_w_idx] = e; + r->_w_idx = (r->_w_idx + 1) % r->_capacity; + ret = NULL; + } + return ret; +} + +void *_z_ring_push_force(_z_ring_t *r, void *e) { + void *ret = _z_ring_push(r, e); + if (ret != NULL) { + ret = _z_ring_pull(r); + _z_ring_push(r, e); + } + return ret; +} + +void *_z_ring_pull(_z_ring_t *r) { + void *ret = NULL; + if (!_z_ring_is_empty(r)) { + ret = r->_val[r->_r_idx]; + r->_val[r->_r_idx] = NULL; + r->_r_idx = (r->_r_idx + 1) % r->_capacity; + } + return ret; +} + +void _z_ring_clear(_z_ring_t *r, z_element_free_f free_f) { + void *e = _z_ring_pull(r); + while (e != NULL) { + free_f(e); + e = _z_ring_pull(r); + } + r->_r_idx = 0; + r->_w_idx = 0; +} + +void _z_ring_free(_z_ring_t **r, z_element_free_f free_f) { + _z_ring_t *ptr = (_z_ring_t *)*r; + if (ptr != NULL) { + _z_ring_clear(ptr, free_f); + zp_free(ptr); + *r = NULL; + } +} diff --git a/src/collections/string.c b/src/collections/string.c index 98d7dda3d..b53f942c8 100644 --- a/src/collections/string.c +++ b/src/collections/string.c @@ -25,6 +25,8 @@ _z_string_t _z_string_make(const char *value) { return s; } +size_t _z_string_size(const _z_string_t *s) { return s->len; } + void _z_string_copy(_z_string_t *dst, const _z_string_t *src) { if (src->val != NULL) { dst->val = _z_str_clone(src->val); diff --git a/tests/z_collections_test.c b/tests/z_collections_test.c new file mode 100644 index 000000000..02d7f53fd --- /dev/null +++ b/tests/z_collections_test.c @@ -0,0 +1,115 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#include +#include +#include +#include + +#include "zenoh-pico/collections/string.h" +// aa +#include "zenoh-pico/collections/ring.h" + +_Z_RING_DEFINE(_z_str, char) + +#undef NDEBUG +#include + +void print_ring(_z_ring_t *r) { + printf("Ring { capacity: %zu, r_idx: %zu, w_idx: %zu, len: %zu }\n", _z_ring_capacity(r), r->_r_idx, r->_w_idx, + _z_ring_len(r)); +} + +void ring_test(void) { + char *a = "a"; + char *b = "b"; + char *c = "c"; + char *d = "d"; + + _z_str_ring_t r = _z_str_ring_make(3); + print_ring(&r); + assert(_z_str_ring_is_empty(&r)); + + // One + _z_str_ring_push(&r, a); + print_ring(&r); + assert(_z_str_ring_len(&r) == 1); + + char *s = _z_str_ring_pull(&r); + print_ring(&r); + assert(strcmp(a, s) == 0); + assert(_z_str_ring_is_empty(&r)); + + s = _z_str_ring_pull(&r); + print_ring(&r); + assert(s == NULL); + assert(_z_str_ring_is_empty(&r)); + + // Two + s = _z_str_ring_push(&r, a); + print_ring(&r); + assert(s == NULL); + assert(_z_str_ring_len(&r) == 1); + + s = _z_str_ring_push(&r, b); + print_ring(&r); + assert(s == NULL); + assert(_z_str_ring_len(&r) == 2); + + s = _z_str_ring_push(&r, c); + print_ring(&r); + assert(s == NULL); + assert(_z_str_ring_len(&r) == 3); + assert(_z_str_ring_is_full(&r)); + + s = _z_str_ring_push(&r, d); + print_ring(&r); + assert(strcmp(d, s) == 0); + assert(_z_str_ring_len(&r) == 3); + assert(_z_str_ring_is_full(&r)); + + s = _z_str_ring_push_force(&r, d); + print_ring(&r); + assert(strcmp(a, s) == 0); + assert(_z_str_ring_len(&r) == 3); + assert(_z_str_ring_is_full(&r)); + + s = _z_str_ring_push_force(&r, d); + print_ring(&r); + assert(strcmp(b, s) == 0); + assert(_z_str_ring_len(&r) == 3); + assert(_z_str_ring_is_full(&r)); + + s = _z_str_ring_push_force(&r, d); + print_ring(&r); + assert(strcmp(c, s) == 0); + assert(_z_str_ring_len(&r) == 3); + assert(_z_str_ring_is_full(&r)); + + s = _z_str_ring_pull(&r); + print_ring(&r); + assert(strcmp(d, s) == 0); + assert(_z_str_ring_len(&r) == 2); + + s = _z_str_ring_pull(&r); + print_ring(&r); + assert(strcmp(d, s) == 0); + assert(_z_str_ring_len(&r) == 1); + + s = _z_str_ring_pull(&r); + print_ring(&r); + assert(strcmp(d, s) == 0); + assert(_z_str_ring_is_empty(&r)); +} + +int main(void) { ring_test(); } From bff0356fe58651d823dfd252b75c0c4eca2f6d4f Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Wed, 20 Mar 2024 14:56:38 +0100 Subject: [PATCH 08/21] Pull examples. Fake z_owned_sample_t --- examples/unix/c11/z_pull.c | 63 +++++++++++++----------- include/zenoh-pico.h | 3 +- include/zenoh-pico/api/types.h | 2 +- include/zenoh-pico/api/utils.h | 45 +++++++++++++++++ include/zenoh-pico/collections/ring.h | 27 ++++------ src/api/utils.c | 71 +++++++++++++++++++++++++++ src/collections/ring.c | 30 +++++++---- zenohpico.pc | 2 +- 8 files changed, 184 insertions(+), 59 deletions(-) create mode 100644 include/zenoh-pico/api/utils.h create mode 100644 src/api/utils.c diff --git a/examples/unix/c11/z_pull.c b/examples/unix/c11/z_pull.c index a52a23b0d..908a80638 100644 --- a/examples/unix/c11/z_pull.c +++ b/examples/unix/c11/z_pull.c @@ -19,14 +19,11 @@ #include #if Z_FEATURE_SUBSCRIPTION == 1 -// @TODO -// void data_handler(const z_sample_t *sample, void *ctx) { -// (void)(ctx); -// z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); -// printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, -// sample->payload.start); -// z_drop(z_move(keystr)); -// } +// The handler simply insert the received sample in the ringbuffer. +void data_handler(const z_sample_t *sample, void *ctx) { + z_sample_ring_t *r = (z_sample_ring_t *)ctx; + z_sample_ring_push(r, (z_sample_t *)sample); +} int main(int argc, char **argv) { const char *keyexpr = "demo/example/**"; @@ -72,31 +69,39 @@ int main(int argc, char **argv) { return -1; } - // @TODO - // z_owned_closure_sample_t callback = z_closure(data_handler); printf("Declaring Subscriber on '%s'...\n", keyexpr); + z_sample_ring_t ring = z_sample_ring_make(3); + z_owned_closure_sample_t callback = z_closure(data_handler, NULL, (void *)&ring); - // @TODO - // z_owned_pull_subscriber_t sub = z_declare_pull_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); - // if (!z_check(sub)) { - // printf("Unable to declare subscriber.\n"); - // return -1; - // } + z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); + if (!z_check(sub)) { + printf("Unable to declare subscriber.\n"); + return -1; + } - // printf("Enter any key to pull data or 'q' to quit...\n"); - // char c = '\0'; - // while (1) { - // fflush(stdin); - // int ret = scanf("%c", &c); - // (void)ret; // Remove unused result warning - // if (c == 'q') { - // break; - // } - // z_subscriber_pull(z_loan(sub)); - // } + printf("Enter any key to pull data or 'q' to quit...\n"); + char c = '\0'; + while (1) { + fflush(stdin); + int ret = scanf("%c", &c); + (void)ret; // Remove unused result warning + if (c == 'q') { + break; + } + + z_owned_sample_t *sample = z_sample_ring_pull(&ring); + if (sample != NULL) { + z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); + printf(">> [Subscriber] Pulled ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, + sample->payload.start); + z_drop(z_move(keystr)); + } else { + printf(">> [Subscriber] Nothing to pull...\n"); + } + } - // z_undeclare_pull_subscriber(z_move(sub)); - printf("Pull Subscriber not supported... exiting\n"); + z_undeclare_subscriber(z_move(sub)); + z_sample_ring_clear(&ring); // Stop read and lease tasks for zenoh-pico zp_stop_read_task(z_loan(s)); diff --git a/include/zenoh-pico.h b/include/zenoh-pico.h index f1ea60301..bf3feab68 100644 --- a/include/zenoh-pico.h +++ b/include/zenoh-pico.h @@ -17,7 +17,7 @@ #define ZENOH_PICO "0.11.0.0" #define ZENOH_PICO_MAJOR 0 -#define ZENOH_PICO_MINOR 10 +#define ZENOH_PICO_MINOR 11 #define ZENOH_PICO_PATCH 0 #define ZENOH_PICO_TWEAK 0 @@ -25,5 +25,6 @@ #include "zenoh-pico/api/macros.h" #include "zenoh-pico/api/primitives.h" #include "zenoh-pico/api/types.h" +#include "zenoh-pico/api/utils.h" #endif /* ZENOH_PICO_H */ diff --git a/include/zenoh-pico/api/types.h b/include/zenoh-pico/api/types.h index 6932536e4..3c9eda0b9 100644 --- a/include/zenoh-pico/api/types.h +++ b/include/zenoh-pico/api/types.h @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // Błażej Sowa, - +// #ifndef INCLUDE_ZENOH_PICO_API_TYPES_H #define INCLUDE_ZENOH_PICO_API_TYPES_H diff --git a/include/zenoh-pico/api/utils.h b/include/zenoh-pico/api/utils.h new file mode 100644 index 000000000..3112e72c4 --- /dev/null +++ b/include/zenoh-pico/api/utils.h @@ -0,0 +1,45 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#ifndef INCLUDE_ZENOH_PICO_API_UTILS_H +#define INCLUDE_ZENOH_PICO_API_UTILS_H + +#include "zenoh-pico/api/macros.h" +#include "zenoh-pico/api/types.h" +#include "zenoh-pico/collections/element.h" +#include "zenoh-pico/collections/ring.h" +#include "zenoh-pico/system/platform.h" + +typedef struct { + z_keyexpr_t keyexpr; + z_bytes_t payload; +} z_owned_sample_t; + +_Z_ELEM_DEFINE(_z_sample, z_owned_sample_t, _z_noop_size, _z_noop_size, _z_noop_copy) +_Z_RING_DEFINE(_z_sample, z_owned_sample_t) + +typedef struct { + _z_sample_ring_t _ring; +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_t _mutex; +#endif +} z_sample_ring_t; + +z_sample_ring_t z_sample_ring_make(size_t capacity); +void z_sample_ring_clear(z_sample_ring_t *r); +void z_sample_ring_free(z_sample_ring_t **r); + +void z_sample_ring_push(z_sample_ring_t *r, const z_sample_t *e); +z_owned_sample_t *z_sample_ring_pull(z_sample_ring_t *r); + +#endif // INCLUDE_ZENOH_PICO_API_UTILS_H \ No newline at end of file diff --git a/include/zenoh-pico/collections/ring.h b/include/zenoh-pico/collections/ring.h index 3bcf39e42..5f6083b95 100644 --- a/include/zenoh-pico/collections/ring.h +++ b/include/zenoh-pico/collections/ring.h @@ -19,14 +19,7 @@ #include "zenoh-pico/collections/element.h" -/*-------- Ring Queue --------*/ -/** - * A ring queue implemented with a single-linked list. - * - * Members: - * struct _z_ring_t *_head: the head of the single-linked list - * size_t _capacity: The capacity of the ring queue - */ +/*-------- Ring Buffer --------*/ typedef struct { size_t _capacity; size_t _len; @@ -37,16 +30,17 @@ typedef struct { _z_ring_t _z_ring_make(size_t capacity); -void *_z_ring_push(_z_ring_t *r, void *e); -void *_z_ring_push_force(_z_ring_t *r, void *e); -void *_z_ring_pull(_z_ring_t *r); - size_t _z_ring_capacity(const _z_ring_t *r); size_t _z_ring_len(const _z_ring_t *r); _Bool _z_ring_is_empty(const _z_ring_t *r); _Bool _z_ring_is_full(const _z_ring_t *r); -// _z_ring_t *_z_ring_clone(const _z_ring_t *xs, z_element_clone_f d_f); +void *_z_ring_push(_z_ring_t *r, void *e); +void *_z_ring_push_force(_z_ring_t *r, void *e); +void _z_ring_push_force_drop(_z_ring_t *r, void *e, z_element_free_f f); +void *_z_ring_pull(_z_ring_t *r); + +_z_ring_t *_z_ring_clone(const _z_ring_t *xs, z_element_clone_f d_f); void _z_ring_clear(_z_ring_t *v, z_element_free_f f); void _z_ring_free(_z_ring_t **xs, z_element_free_f f_f); @@ -61,13 +55,10 @@ void _z_ring_free(_z_ring_t **xs, z_element_free_f f_f); static inline type *name##_ring_push(name##_ring_t *r, type *e) { return _z_ring_push(r, (void *)e); } \ static inline type *name##_ring_push_force(name##_ring_t *r, type *e) { return _z_ring_push_force(r, (void *)e); } \ static inline void name##_ring_push_force_drop(name##_ring_t *r, type *e) { \ - void *x = _z_ring_push_force(r, (void *)e); \ - if (x != NULL) { \ - name##_elem_free(&x); \ - } \ + return _z_ring_push_force_drop(r, (void *)e, name##_elem_free); \ } \ static inline type *name##_ring_pull(name##_ring_t *r) { return (type *)_z_ring_pull(r); } \ - static inline void name##_ring_clear(name##_ring_t *r) { return _z_ring_clear(r, name##_elem_free); } \ + static inline void name##_ring_clear(name##_ring_t *r) { _z_ring_clear(r, name##_elem_free); } \ static inline void name##_ring_free(name##_ring_t **r) { _z_ring_free(r, name##_elem_free); } #endif /* ZENOH_PICO_COLLECTIONS_RING_H */ diff --git a/src/api/utils.c b/src/api/utils.c new file mode 100644 index 000000000..d7d49453a --- /dev/null +++ b/src/api/utils.c @@ -0,0 +1,71 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#include "zenoh-pico/api/utils.h" + +#include "zenoh-pico/api/macros.h" +#include "zenoh-pico/protocol/core.h" +#include "zenoh-pico/system/platform.h" + +z_sample_ring_t z_sample_ring_make(size_t capacity) { + z_sample_ring_t ring; + ring._ring = _z_sample_ring_make(capacity); + +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_init(&ring._mutex); +#endif + + return ring; +} + +void z_sample_ring_clear(z_sample_ring_t *r) { +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_lock(&r->_mutex); +#endif + _z_sample_ring_clear(&r->_ring); +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_unlock(&r->_mutex); + zp_mutex_free(&r->_mutex); +#endif +} + +void z_sample_ring_free(z_sample_ring_t **r) { + z_sample_ring_t *ptr = *r; + z_sample_ring_clear(ptr); + zp_free(ptr); + *r = NULL; +} + +void z_sample_ring_push(z_sample_ring_t *r, const z_sample_t *s) { + z_owned_sample_t *os = (z_owned_sample_t *)zp_malloc(sizeof(z_owned_sample_t)); + memcpy(&os->keyexpr, &s->keyexpr, sizeof(_z_keyexpr_t)); + memcpy(&os->payload, &s->payload, sizeof(z_bytes_t)); +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_lock(&r->_mutex); +#endif + _z_sample_ring_push_force_drop(&r->_ring, os); +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_unlock(&r->_mutex); +#endif +} + +z_owned_sample_t *z_sample_ring_pull(z_sample_ring_t *r) { +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_lock(&r->_mutex); +#endif + z_owned_sample_t *ret = _z_sample_ring_pull(&r->_ring); +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_unlock(&r->_mutex); +#endif + return ret; +} diff --git a/src/collections/ring.c b/src/collections/ring.c index e60f64575..b935f0bc0 100644 --- a/src/collections/ring.c +++ b/src/collections/ring.c @@ -20,10 +20,10 @@ /*-------- ring --------*/ _z_ring_t _z_ring_make(size_t capacity) { // We need one more element to differentiate wether the ring is empty or full - capacity += 1; + capacity++; - _z_ring_t v = {._capacity = capacity, ._r_idx = 0, ._w_idx = 0, ._val = NULL}; - if (capacity != 0) { + _z_ring_t v = {._capacity = capacity, ._r_idx = (size_t)0, ._w_idx = (size_t)0, ._val = NULL}; + if (capacity != (size_t)0) { v._val = (void **)zp_malloc(sizeof(void *) * capacity); } if (v._val != NULL) { @@ -33,7 +33,7 @@ _z_ring_t _z_ring_make(size_t capacity) { return v; } -size_t _z_ring_capacity(const _z_ring_t *r) { return r->_capacity - 1; } +size_t _z_ring_capacity(const _z_ring_t *r) { return r->_capacity - (size_t)1; } size_t _z_ring_len(const _z_ring_t *r) { if (r->_w_idx >= r->_r_idx) { @@ -51,7 +51,7 @@ void *_z_ring_push(_z_ring_t *r, void *e) { void *ret = e; if (!_z_ring_is_full(r)) { r->_val[r->_w_idx] = e; - r->_w_idx = (r->_w_idx + 1) % r->_capacity; + r->_w_idx = (r->_w_idx + (size_t)1) % r->_capacity; ret = NULL; } return ret; @@ -66,12 +66,19 @@ void *_z_ring_push_force(_z_ring_t *r, void *e) { return ret; } +void _z_ring_push_force_drop(_z_ring_t *r, void *e, z_element_free_f free_f) { + void *ret = _z_ring_push_force(r, e); + if (ret != NULL) { + free_f(&ret); + } +} + void *_z_ring_pull(_z_ring_t *r) { void *ret = NULL; if (!_z_ring_is_empty(r)) { ret = r->_val[r->_r_idx]; r->_val[r->_r_idx] = NULL; - r->_r_idx = (r->_r_idx + 1) % r->_capacity; + r->_r_idx = (r->_r_idx + (size_t)1) % r->_capacity; } return ret; } @@ -79,11 +86,16 @@ void *_z_ring_pull(_z_ring_t *r) { void _z_ring_clear(_z_ring_t *r, z_element_free_f free_f) { void *e = _z_ring_pull(r); while (e != NULL) { - free_f(e); + free_f(&e); e = _z_ring_pull(r); } - r->_r_idx = 0; - r->_w_idx = 0; + zp_free(r->_val); + + r->_val = NULL; + r->_capacity = (size_t)0; + r->_len = (size_t)0; + r->_r_idx = (size_t)0; + r->_w_idx = (size_t)0; } void _z_ring_free(_z_ring_t **r, z_element_free_f free_f) { diff --git a/zenohpico.pc b/zenohpico.pc index 19ac5e7de..d55859ef7 100644 --- a/zenohpico.pc +++ b/zenohpico.pc @@ -3,6 +3,6 @@ prefix=/usr/local Name: zenohpico Description: URL: -Version: 0.11.20240319dev +Version: 0.11.20240320dev Cflags: -I${prefix}/include Libs: -L${prefix}/lib -lzenohpico From ede9911435e7649d478578d0a8bcc482bd244fbc Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 21 Mar 2024 14:54:11 +0100 Subject: [PATCH 09/21] Channels initial commit --- examples/unix/c11/z_pull.c | 25 ++--- include/zenoh-pico/api/utils.h | 143 ++++++++++++++++++++++++-- include/zenoh-pico/collections/ring.h | 6 +- src/api/utils.c | 87 +++++++--------- src/collections/ring.c | 16 +++ zenohpico.pc | 2 +- 6 files changed, 204 insertions(+), 75 deletions(-) diff --git a/examples/unix/c11/z_pull.c b/examples/unix/c11/z_pull.c index 908a80638..f1d071d3d 100644 --- a/examples/unix/c11/z_pull.c +++ b/examples/unix/c11/z_pull.c @@ -19,12 +19,6 @@ #include #if Z_FEATURE_SUBSCRIPTION == 1 -// The handler simply insert the received sample in the ringbuffer. -void data_handler(const z_sample_t *sample, void *ctx) { - z_sample_ring_t *r = (z_sample_ring_t *)ctx; - z_sample_ring_push(r, (z_sample_t *)sample); -} - int main(int argc, char **argv) { const char *keyexpr = "demo/example/**"; char *locator = NULL; @@ -70,10 +64,8 @@ int main(int argc, char **argv) { } printf("Declaring Subscriber on '%s'...\n", keyexpr); - z_sample_ring_t ring = z_sample_ring_make(3); - z_owned_closure_sample_t callback = z_closure(data_handler, NULL, (void *)&ring); - - z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(callback), NULL); + z_owned_sample_channel_t channel = z_owned_sample_ring_make(3); + z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(channel.send), NULL); if (!z_check(sub)) { printf("Unable to declare subscriber.\n"); return -1; @@ -81,6 +73,7 @@ int main(int argc, char **argv) { printf("Enter any key to pull data or 'q' to quit...\n"); char c = '\0'; + z_owned_sample_t sample = z_owned_sample_null(); while (1) { fflush(stdin); int ret = scanf("%c", &c); @@ -89,19 +82,19 @@ int main(int argc, char **argv) { break; } - z_owned_sample_t *sample = z_sample_ring_pull(&ring); - if (sample != NULL) { - z_owned_str_t keystr = z_keyexpr_to_string(sample->keyexpr); - printf(">> [Subscriber] Pulled ('%s': '%.*s')\n", z_loan(keystr), (int)sample->payload.len, - sample->payload.start); + z_owned_sample_channel_recv_call(&channel.recv, &sample); + if (z_sample_check(&sample)) { + z_owned_str_t keystr = z_keyexpr_to_string(z_loan(sample.keyexpr)); + printf(">> [Subscriber] Pulled ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, + sample.payload.start); z_drop(z_move(keystr)); } else { printf(">> [Subscriber] Nothing to pull...\n"); } + z_owned_sample_drop(&sample); } z_undeclare_subscriber(z_move(sub)); - z_sample_ring_clear(&ring); // Stop read and lease tasks for zenoh-pico zp_stop_read_task(z_loan(s)); diff --git a/include/zenoh-pico/api/utils.h b/include/zenoh-pico/api/utils.h index 3112e72c4..4278f4869 100644 --- a/include/zenoh-pico/api/utils.h +++ b/include/zenoh-pico/api/utils.h @@ -14,6 +14,9 @@ #ifndef INCLUDE_ZENOH_PICO_API_UTILS_H #define INCLUDE_ZENOH_PICO_API_UTILS_H +#include +#include + #include "zenoh-pico/api/macros.h" #include "zenoh-pico/api/types.h" #include "zenoh-pico/collections/element.h" @@ -21,25 +24,145 @@ #include "zenoh-pico/system/platform.h" typedef struct { - z_keyexpr_t keyexpr; + z_owned_keyexpr_t keyexpr; z_bytes_t payload; + // @TODO: implement the rest of the fields } z_owned_sample_t; -_Z_ELEM_DEFINE(_z_sample, z_owned_sample_t, _z_noop_size, _z_noop_size, _z_noop_copy) -_Z_RING_DEFINE(_z_sample, z_owned_sample_t) +static inline z_owned_sample_t z_owned_sample_null() { + z_owned_sample_t sample; + sample.keyexpr = z_keyexpr_null(); + sample.payload = z_bytes_null(); + return sample; +} + +static inline bool z_sample_check(const z_owned_sample_t *sample) { + return z_keyexpr_check(&sample->keyexpr) && z_bytes_check(&sample->payload); +} + +static inline z_owned_sample_t z_sample_to_owned(const z_sample_t *src) { + z_owned_sample_t dst = z_owned_sample_null(); + + if (src == NULL) { + return dst; + } + + _z_keyexpr_t *ke = (_z_keyexpr_t *)zp_malloc(sizeof(_z_keyexpr_t)); + if (ke == NULL) { + return dst; + } + *ke = _z_keyexpr_duplicate(src->keyexpr); + dst.keyexpr._value = ke; + dst.payload = _z_bytes_duplicate(&src->payload); + + return dst; +} + +static inline void z_owned_sample_drop(z_owned_sample_t *s) { + if (s != NULL) { + z_keyexpr_drop(&s->keyexpr); + _z_bytes_clear(&s->payload); + } +} + +// -- Channel +typedef z_owned_closure_sample_t z_owned_closure_sample_send_t; +typedef int8_t (*_z_owned_sample_handler_t)(z_owned_sample_t *dst, void *context); typedef struct { - _z_sample_ring_t _ring; + void *context; + _z_owned_sample_handler_t call; + _z_dropper_handler_t drop; +} z_owned_closure_sample_recv_t; + +typedef struct { + z_owned_closure_sample_send_t send; + z_owned_closure_sample_recv_t recv; +} z_owned_sample_channel_t; + +static inline z_owned_sample_channel_t z_owned_sample_channel_null() { + z_owned_sample_channel_t ch = {.send = NULL, .recv = NULL}; + return ch; +} + +static inline int8_t z_owned_sample_channel_recv_call(z_owned_closure_sample_recv_t *recv, z_owned_sample_t *dst) { + int8_t res = _Z_ERR_GENERIC; + if (recv != NULL) { + res = (recv->call)(dst, recv->context); + } + return res; +} + +// -- Ring +_Z_ELEM_DEFINE(_z_owned_sample, z_owned_sample_t, _z_noop_size, _z_noop_clear, _z_noop_copy) +_Z_RING_DEFINE(_z_owned_sample, z_owned_sample_t) + +typedef struct { + _z_owned_sample_ring_t _ring; #if Z_FEATURE_MULTI_THREAD == 1 zp_mutex_t _mutex; #endif -} z_sample_ring_t; +} z_owned_sample_ring_t; + +static inline void z_owned_sample_ring_push(const z_sample_t *src, void *context) { + if (src == NULL || context == NULL) { + return; + } + + z_owned_sample_ring_t *r = (z_owned_sample_ring_t *)context; + z_owned_sample_t *dst = (z_owned_sample_t *)zp_malloc(sizeof(z_owned_sample_t)); + if (dst == NULL) { + return; + } + *dst = z_sample_to_owned(src); + +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_lock(&r->_mutex); +#endif + _z_owned_sample_ring_push_force_drop(&r->_ring, dst); +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_unlock(&r->_mutex); +#endif +} + +static inline int8_t z_owned_sample_ring_pull(z_owned_sample_t *dst, void *context) { + int8_t ret = _Z_RES_OK; + + z_owned_sample_ring_t *r = (z_owned_sample_ring_t *)context; + +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_lock(&r->_mutex); +#endif + z_owned_sample_t *src = _z_owned_sample_ring_pull(&r->_ring); +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_unlock(&r->_mutex); +#endif + + if (src == NULL) { + *dst = z_owned_sample_null(); + } else { + memcpy(dst, src, sizeof(z_owned_sample_t)); + } + return ret; +} + +static inline z_owned_sample_channel_t z_owned_sample_ring_make(size_t capacity) { + z_owned_sample_channel_t ch = z_owned_sample_channel_null(); -z_sample_ring_t z_sample_ring_make(size_t capacity); -void z_sample_ring_clear(z_sample_ring_t *r); -void z_sample_ring_free(z_sample_ring_t **r); + z_owned_sample_ring_t *ring = (z_owned_sample_ring_t *)zp_malloc(sizeof(z_owned_sample_ring_t)); + if (ring != NULL) { + int8_t res = _z_owned_sample_ring_init(&ring->_ring, capacity); + if (res == _Z_RES_OK) { + z_owned_closure_sample_send_t send = z_closure(z_owned_sample_ring_push, NULL, ring); + ch.send = send; + z_owned_closure_sample_recv_t recv = z_closure(z_owned_sample_ring_pull, NULL, ring); + ch.recv = recv; + } else { + zp_free(ring); + } + } -void z_sample_ring_push(z_sample_ring_t *r, const z_sample_t *e); -z_owned_sample_t *z_sample_ring_pull(z_sample_ring_t *r); + return ch; +} #endif // INCLUDE_ZENOH_PICO_API_UTILS_H \ No newline at end of file diff --git a/include/zenoh-pico/collections/ring.h b/include/zenoh-pico/collections/ring.h index 5f6083b95..333c7e0d6 100644 --- a/include/zenoh-pico/collections/ring.h +++ b/include/zenoh-pico/collections/ring.h @@ -21,13 +21,14 @@ /*-------- Ring Buffer --------*/ typedef struct { + void **_val; size_t _capacity; size_t _len; size_t _r_idx; size_t _w_idx; - void **_val; } _z_ring_t; +int8_t _z_ring_init(_z_ring_t *ring, size_t capacity); _z_ring_t _z_ring_make(size_t capacity); size_t _z_ring_capacity(const _z_ring_t *r); @@ -47,6 +48,9 @@ void _z_ring_free(_z_ring_t **xs, z_element_free_f f_f); #define _Z_RING_DEFINE(name, type) \ typedef _z_ring_t name##_ring_t; \ + static inline int8_t name##_ring_init(name##_ring_t *ring, size_t capacity) { \ + return _z_ring_init(ring, capacity); \ + } \ static inline name##_ring_t name##_ring_make(size_t capacity) { return _z_ring_make(capacity); } \ static inline size_t name##_ring_capacity(const name##_ring_t *r) { return _z_ring_capacity(r); } \ static inline size_t name##_ring_len(const name##_ring_t *r) { return _z_ring_len(r); } \ diff --git a/src/api/utils.c b/src/api/utils.c index d7d49453a..6a4f431f9 100644 --- a/src/api/utils.c +++ b/src/api/utils.c @@ -17,55 +17,48 @@ #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/system/platform.h" -z_sample_ring_t z_sample_ring_make(size_t capacity) { - z_sample_ring_t ring; - ring._ring = _z_sample_ring_make(capacity); +// z_owned_sample_ring_t z_owned_sample_ring_make(size_t capacity) { +// z_owned_sample_ring_t ring; +// ring._ring = _z_owned_sample_ring_make(capacity); -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_init(&ring._mutex); -#endif +// #if Z_FEATURE_MULTI_THREAD == 1 +// zp_mutex_init(&ring._mutex); +// #endif - return ring; -} +// return ring; +// } -void z_sample_ring_clear(z_sample_ring_t *r) { -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_lock(&r->_mutex); -#endif - _z_sample_ring_clear(&r->_ring); -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_unlock(&r->_mutex); - zp_mutex_free(&r->_mutex); -#endif -} +// void z_owned_sample_ring_drop(z_owned_sample_ring_t *r) { +// #if Z_FEATURE_MULTI_THREAD == 1 +// zp_mutex_lock(&r->_mutex); +// #endif +// _z_owned_sample_ring_clear(&r->_ring); +// #if Z_FEATURE_MULTI_THREAD == 1 +// zp_mutex_unlock(&r->_mutex); +// zp_mutex_free(&r->_mutex); +// #endif +// } -void z_sample_ring_free(z_sample_ring_t **r) { - z_sample_ring_t *ptr = *r; - z_sample_ring_clear(ptr); - zp_free(ptr); - *r = NULL; -} +// void z_owned_sample_ring_push(z_owned_sample_ring_t *r, const z_sample_t *s) { +// z_owned_sample_t *os = (z_owned_sample_t *)zp_malloc(sizeof(z_owned_sample_t)); +// memcpy(&os->keyexpr, &s->keyexpr, sizeof(_z_keyexpr_t)); +// memcpy(&os->payload, &s->payload, sizeof(z_bytes_t)); +// #if Z_FEATURE_MULTI_THREAD == 1 +// zp_mutex_lock(&r->_mutex); +// #endif +// _z_owned_sample_ring_push_force_drop(&r->_ring, os); +// #if Z_FEATURE_MULTI_THREAD == 1 +// zp_mutex_unlock(&r->_mutex); +// #endif +// } -void z_sample_ring_push(z_sample_ring_t *r, const z_sample_t *s) { - z_owned_sample_t *os = (z_owned_sample_t *)zp_malloc(sizeof(z_owned_sample_t)); - memcpy(&os->keyexpr, &s->keyexpr, sizeof(_z_keyexpr_t)); - memcpy(&os->payload, &s->payload, sizeof(z_bytes_t)); -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_lock(&r->_mutex); -#endif - _z_sample_ring_push_force_drop(&r->_ring, os); -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_unlock(&r->_mutex); -#endif -} - -z_owned_sample_t *z_sample_ring_pull(z_sample_ring_t *r) { -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_lock(&r->_mutex); -#endif - z_owned_sample_t *ret = _z_sample_ring_pull(&r->_ring); -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_unlock(&r->_mutex); -#endif - return ret; -} +// z_owned_sample_t *z_owned_sample_ring_pull(z_owned_sample_ring_t *r) { +// #if Z_FEATURE_MULTI_THREAD == 1 +// zp_mutex_lock(&r->_mutex); +// #endif +// z_owned_sample_t *ret = _z_owned_sample_ring_pull(&r->_ring); +// #if Z_FEATURE_MULTI_THREAD == 1 +// zp_mutex_unlock(&r->_mutex); +// #endif +// return ret; +// } diff --git a/src/collections/ring.c b/src/collections/ring.c index b935f0bc0..266e91091 100644 --- a/src/collections/ring.c +++ b/src/collections/ring.c @@ -18,6 +18,22 @@ #include /*-------- ring --------*/ +int8_t _z_ring_init(_z_ring_t *r, size_t capacity) { + // We need one more element to differentiate wether the ring is empty or full + capacity++; + + memset(r, 0, sizeof(_z_ring_t)); + // r = {._capacity = capacity, ._r_idx = (size_t)0, ._w_idx = (size_t)0, ._val = NULL}; + if (capacity != (size_t)0) { + r->_val = (void **)zp_malloc(sizeof(void *) * capacity); + } + if (r->_val != NULL) { + memset(r->_val, 0, capacity); + r->_capacity = capacity; + } + return 0; +} + _z_ring_t _z_ring_make(size_t capacity) { // We need one more element to differentiate wether the ring is empty or full capacity++; diff --git a/zenohpico.pc b/zenohpico.pc index d55859ef7..0f777182f 100644 --- a/zenohpico.pc +++ b/zenohpico.pc @@ -3,6 +3,6 @@ prefix=/usr/local Name: zenohpico Description: URL: -Version: 0.11.20240320dev +Version: 0.11.20240321dev Cflags: -I${prefix}/include Libs: -L${prefix}/lib -lzenohpico From defb3acdea84b791f90b11c65f838c3bf0ebd020 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 21 Mar 2024 16:21:17 +0100 Subject: [PATCH 10/21] Added channel macros --- examples/unix/c11/z_pull.c | 21 ++++++--------- include/zenoh-pico/api/macros.h | 47 +++++++++++---------------------- include/zenoh-pico/api/utils.h | 26 +++++++++--------- src/api/utils.c | 4 +-- 4 files changed, 39 insertions(+), 59 deletions(-) diff --git a/examples/unix/c11/z_pull.c b/examples/unix/c11/z_pull.c index f1d071d3d..cbbcf4ef6 100644 --- a/examples/unix/c11/z_pull.c +++ b/examples/unix/c11/z_pull.c @@ -64,7 +64,7 @@ int main(int argc, char **argv) { } printf("Declaring Subscriber on '%s'...\n", keyexpr); - z_owned_sample_channel_t channel = z_owned_sample_ring_make(3); + z_owned_sample_channel_t channel = z_sample_ring_new(3); z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(channel.send), NULL); if (!z_check(sub)) { printf("Unable to declare subscriber.\n"); @@ -73,17 +73,12 @@ int main(int argc, char **argv) { printf("Enter any key to pull data or 'q' to quit...\n"); char c = '\0'; - z_owned_sample_t sample = z_owned_sample_null(); - while (1) { - fflush(stdin); - int ret = scanf("%c", &c); - (void)ret; // Remove unused result warning - if (c == 'q') { - break; - } - - z_owned_sample_channel_recv_call(&channel.recv, &sample); - if (z_sample_check(&sample)) { + for (int ret = scanf("%c", &c); c != 'q'; ret = scanf("%c", &c)) { + // Try to receive one sample from the ring channel + z_owned_sample_t sample = z_sample_null(); + z_call(channel.recv, &sample); + // Check if we actually received something + if (z_check(sample)) { z_owned_str_t keystr = z_keyexpr_to_string(z_loan(sample.keyexpr)); printf(">> [Subscriber] Pulled ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, sample.payload.start); @@ -91,7 +86,7 @@ int main(int argc, char **argv) { } else { printf(">> [Subscriber] Nothing to pull...\n"); } - z_owned_sample_drop(&sample); + z_drop(z_move(sample)); } z_undeclare_subscriber(z_move(sub)); diff --git a/include/zenoh-pico/api/macros.h b/include/zenoh-pico/api/macros.h index 0a99bf736..5ad7478b5 100644 --- a/include/zenoh-pico/api/macros.h +++ b/include/zenoh-pico/api/macros.h @@ -42,7 +42,8 @@ z_owned_reply_t : z_reply_loan, \ z_owned_hello_t : z_hello_loan, \ z_owned_str_t : z_str_loan, \ - z_owned_str_array_t : z_str_array_loan \ + z_owned_str_array_t : z_str_array_loan, \ + z_owned_sample_t : z_sample_loan \ )(&x) /** * Defines a generic function for dropping any of the ``z_owned_X_t`` types. @@ -62,6 +63,7 @@ z_owned_hello_t * : z_hello_drop, \ z_owned_str_t * : z_str_drop, \ z_owned_str_array_t * : z_str_array_drop, \ + z_owned_sample_t * : z_sample_drop, \ z_owned_closure_sample_t * : z_closure_sample_drop, \ z_owned_closure_query_t * : z_closure_query_drop, \ z_owned_closure_reply_t * : z_closure_reply_drop, \ @@ -69,29 +71,6 @@ z_owned_closure_zid_t * : z_closure_zid_drop \ )(x) -/** - * Defines a generic function for making null object of any of the ``z_owned_X_t`` types. - * - * Returns: - * Returns the uninitialized instance of `x`. - */ -#define z_null(x) (*x = _Generic((x), \ - z_owned_session_t * : z_session_null, \ - z_owned_publisher_t * : z_publisher_null, \ - z_owned_keyexpr_t * : z_keyexpr_null, \ - z_owned_config_t * : z_config_null, \ - z_owned_scouting_config_t * : z_scouting_config_null, \ - z_owned_subscriber_t * : z_subscriber_null, \ - z_owned_queryable_t * : z_queryable_null, \ - z_owned_reply_t * : z_reply_null, \ - z_owned_hello_t * : z_hello_null, \ - z_owned_str_t * : z_str_null, \ - z_owned_closure_sample_t * : z_closure_sample_null, \ - z_owned_closure_query_t * : z_closure_query_null, \ - z_owned_closure_reply_t * : z_closure_reply_null, \ - z_owned_closure_hello_t * : z_closure_hello_null, \ - z_owned_closure_zid_t * : z_closure_zid_null \ - )()) /** * Defines a generic function for checking the validity of any of the ``z_owned_X_t`` types. * @@ -116,7 +95,8 @@ z_owned_hello_t : z_hello_check, \ z_owned_str_t : z_str_check, \ z_owned_str_array_t : z_str_array_check, \ - z_bytes_t : z_bytes_check \ + z_bytes_t : z_bytes_check, \ + z_owned_sample_t : z_sample_check \ )(&x) /** @@ -126,11 +106,12 @@ * x: The closure to call */ #define z_call(x, ...) \ - _Generic((x), z_owned_closure_sample_t : z_closure_sample_call, \ - z_owned_closure_query_t : z_closure_query_call, \ - z_owned_closure_reply_t : z_closure_reply_call, \ - z_owned_closure_hello_t : z_closure_hello_call, \ - z_owned_closure_zid_t : z_closure_zid_call \ + _Generic((x), z_owned_closure_sample_t : z_closure_sample_call, \ + z_owned_closure_query_t : z_closure_query_call, \ + z_owned_closure_reply_t : z_closure_reply_call, \ + z_owned_closure_hello_t : z_closure_hello_call, \ + z_owned_closure_zid_t : z_closure_zid_call, \ + z_owned_closure_owned_sample_t : z_closure_owned_sample_call \ ) (&x, __VA_ARGS__) /** @@ -158,7 +139,8 @@ z_owned_closure_query_t : z_closure_query_move, \ z_owned_closure_reply_t : z_closure_reply_move, \ z_owned_closure_hello_t : z_closure_hello_move, \ - z_owned_closure_zid_t : z_closure_zid_move \ + z_owned_closure_zid_t : z_closure_zid_move, \ + z_owned_sample_t : z_sample_move \ )(&x) /** @@ -204,7 +186,8 @@ z_owned_closure_query_t * : z_closure_query_null, \ z_owned_closure_reply_t * : z_closure_reply_null, \ z_owned_closure_hello_t * : z_closure_hello_null, \ - z_owned_closure_zid_t * : z_closure_zid_null \ + z_owned_closure_zid_t * : z_closure_zid_null, \ + z_owned_sample_t * : z_sample_null \ )()) // clang-format on diff --git a/include/zenoh-pico/api/utils.h b/include/zenoh-pico/api/utils.h index 4278f4869..175eb0aa4 100644 --- a/include/zenoh-pico/api/utils.h +++ b/include/zenoh-pico/api/utils.h @@ -29,19 +29,22 @@ typedef struct { // @TODO: implement the rest of the fields } z_owned_sample_t; -static inline z_owned_sample_t z_owned_sample_null() { +static inline z_owned_sample_t z_sample_null(void) { z_owned_sample_t sample; sample.keyexpr = z_keyexpr_null(); sample.payload = z_bytes_null(); return sample; } +static inline z_owned_sample_t *z_sample_move(z_owned_sample_t *sample) { return sample; } +static inline z_owned_sample_t *z_sample_loan(z_owned_sample_t *sample) { return sample; } + static inline bool z_sample_check(const z_owned_sample_t *sample) { return z_keyexpr_check(&sample->keyexpr) && z_bytes_check(&sample->payload); } static inline z_owned_sample_t z_sample_to_owned(const z_sample_t *src) { - z_owned_sample_t dst = z_owned_sample_null(); + z_owned_sample_t dst = z_sample_null(); if (src == NULL) { return dst; @@ -58,7 +61,7 @@ static inline z_owned_sample_t z_sample_to_owned(const z_sample_t *src) { return dst; } -static inline void z_owned_sample_drop(z_owned_sample_t *s) { +static inline void z_sample_drop(z_owned_sample_t *s) { if (s != NULL) { z_keyexpr_drop(&s->keyexpr); _z_bytes_clear(&s->payload); @@ -66,18 +69,17 @@ static inline void z_owned_sample_drop(z_owned_sample_t *s) { } // -- Channel -typedef z_owned_closure_sample_t z_owned_closure_sample_send_t; typedef int8_t (*_z_owned_sample_handler_t)(z_owned_sample_t *dst, void *context); typedef struct { void *context; _z_owned_sample_handler_t call; _z_dropper_handler_t drop; -} z_owned_closure_sample_recv_t; +} z_owned_closure_owned_sample_t; typedef struct { - z_owned_closure_sample_send_t send; - z_owned_closure_sample_recv_t recv; + z_owned_closure_sample_t send; + z_owned_closure_owned_sample_t recv; } z_owned_sample_channel_t; static inline z_owned_sample_channel_t z_owned_sample_channel_null() { @@ -85,7 +87,7 @@ static inline z_owned_sample_channel_t z_owned_sample_channel_null() { return ch; } -static inline int8_t z_owned_sample_channel_recv_call(z_owned_closure_sample_recv_t *recv, z_owned_sample_t *dst) { +static inline int8_t z_closure_owned_sample_call(z_owned_closure_owned_sample_t *recv, z_owned_sample_t *dst) { int8_t res = _Z_ERR_GENERIC; if (recv != NULL) { res = (recv->call)(dst, recv->context); @@ -139,23 +141,23 @@ static inline int8_t z_owned_sample_ring_pull(z_owned_sample_t *dst, void *conte #endif if (src == NULL) { - *dst = z_owned_sample_null(); + *dst = z_sample_null(); } else { memcpy(dst, src, sizeof(z_owned_sample_t)); } return ret; } -static inline z_owned_sample_channel_t z_owned_sample_ring_make(size_t capacity) { +static inline z_owned_sample_channel_t z_sample_ring_new(size_t capacity) { z_owned_sample_channel_t ch = z_owned_sample_channel_null(); z_owned_sample_ring_t *ring = (z_owned_sample_ring_t *)zp_malloc(sizeof(z_owned_sample_ring_t)); if (ring != NULL) { int8_t res = _z_owned_sample_ring_init(&ring->_ring, capacity); if (res == _Z_RES_OK) { - z_owned_closure_sample_send_t send = z_closure(z_owned_sample_ring_push, NULL, ring); + z_owned_closure_sample_t send = z_closure(z_owned_sample_ring_push, NULL, ring); ch.send = send; - z_owned_closure_sample_recv_t recv = z_closure(z_owned_sample_ring_pull, NULL, ring); + z_owned_closure_owned_sample_t recv = z_closure(z_owned_sample_ring_pull, NULL, ring); ch.recv = recv; } else { zp_free(ring); diff --git a/src/api/utils.c b/src/api/utils.c index 6a4f431f9..b70d128cb 100644 --- a/src/api/utils.c +++ b/src/api/utils.c @@ -17,9 +17,9 @@ #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/system/platform.h" -// z_owned_sample_ring_t z_owned_sample_ring_make(size_t capacity) { +// z_owned_sample_ring_t z_sample_ring_new(size_t capacity) { // z_owned_sample_ring_t ring; -// ring._ring = _z_owned_sample_ring_make(capacity); +// ring._ring = _z_sample_ring_new(capacity); // #if Z_FEATURE_MULTI_THREAD == 1 // zp_mutex_init(&ring._mutex); From 3d68a8c85d8103b5842fd157be24a5a00198d932 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 21 Mar 2024 17:38:53 +0100 Subject: [PATCH 11/21] Rename sample_ring to sample_channel_ring --- examples/unix/c11/z_pull.c | 2 +- include/zenoh-pico/api/utils.h | 10 +- include/zenoh-pico/collections/ring.h | 8 +- src/api/utils.c | 6 +- src/collections/ring.c | 18 +-- tests/z_collections_test.c | 176 ++++++++++++++++++++++++-- 6 files changed, 181 insertions(+), 39 deletions(-) diff --git a/examples/unix/c11/z_pull.c b/examples/unix/c11/z_pull.c index cbbcf4ef6..3abdd2ad5 100644 --- a/examples/unix/c11/z_pull.c +++ b/examples/unix/c11/z_pull.c @@ -64,7 +64,7 @@ int main(int argc, char **argv) { } printf("Declaring Subscriber on '%s'...\n", keyexpr); - z_owned_sample_channel_t channel = z_sample_ring_new(3); + z_owned_sample_channel_t channel = z_sample_channel_ring_new(3); z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(channel.send), NULL); if (!z_check(sub)) { printf("Unable to declare subscriber.\n"); diff --git a/include/zenoh-pico/api/utils.h b/include/zenoh-pico/api/utils.h index 175eb0aa4..36325fbf8 100644 --- a/include/zenoh-pico/api/utils.h +++ b/include/zenoh-pico/api/utils.h @@ -106,7 +106,7 @@ typedef struct { #endif } z_owned_sample_ring_t; -static inline void z_owned_sample_ring_push(const z_sample_t *src, void *context) { +static inline void z_sample_channel_ring_push(const z_sample_t *src, void *context) { if (src == NULL || context == NULL) { return; } @@ -127,7 +127,7 @@ static inline void z_owned_sample_ring_push(const z_sample_t *src, void *context #endif } -static inline int8_t z_owned_sample_ring_pull(z_owned_sample_t *dst, void *context) { +static inline int8_t z_sample_channel_ring_pull(z_owned_sample_t *dst, void *context) { int8_t ret = _Z_RES_OK; z_owned_sample_ring_t *r = (z_owned_sample_ring_t *)context; @@ -148,16 +148,16 @@ static inline int8_t z_owned_sample_ring_pull(z_owned_sample_t *dst, void *conte return ret; } -static inline z_owned_sample_channel_t z_sample_ring_new(size_t capacity) { +static inline z_owned_sample_channel_t z_sample_channel_ring_new(size_t capacity) { z_owned_sample_channel_t ch = z_owned_sample_channel_null(); z_owned_sample_ring_t *ring = (z_owned_sample_ring_t *)zp_malloc(sizeof(z_owned_sample_ring_t)); if (ring != NULL) { int8_t res = _z_owned_sample_ring_init(&ring->_ring, capacity); if (res == _Z_RES_OK) { - z_owned_closure_sample_t send = z_closure(z_owned_sample_ring_push, NULL, ring); + z_owned_closure_sample_t send = z_closure(z_sample_channel_ring_push, NULL, ring); ch.send = send; - z_owned_closure_owned_sample_t recv = z_closure(z_owned_sample_ring_pull, NULL, ring); + z_owned_closure_owned_sample_t recv = z_closure(z_sample_channel_ring_pull, NULL, ring); ch.recv = recv; } else { zp_free(ring); diff --git a/include/zenoh-pico/collections/ring.h b/include/zenoh-pico/collections/ring.h index 333c7e0d6..4bda2a7cc 100644 --- a/include/zenoh-pico/collections/ring.h +++ b/include/zenoh-pico/collections/ring.h @@ -33,8 +33,8 @@ _z_ring_t _z_ring_make(size_t capacity); size_t _z_ring_capacity(const _z_ring_t *r); size_t _z_ring_len(const _z_ring_t *r); -_Bool _z_ring_is_empty(const _z_ring_t *r); -_Bool _z_ring_is_full(const _z_ring_t *r); +bool _z_ring_is_empty(const _z_ring_t *r); +bool _z_ring_is_full(const _z_ring_t *r); void *_z_ring_push(_z_ring_t *r, void *e); void *_z_ring_push_force(_z_ring_t *r, void *e); @@ -54,8 +54,8 @@ void _z_ring_free(_z_ring_t **xs, z_element_free_f f_f); static inline name##_ring_t name##_ring_make(size_t capacity) { return _z_ring_make(capacity); } \ static inline size_t name##_ring_capacity(const name##_ring_t *r) { return _z_ring_capacity(r); } \ static inline size_t name##_ring_len(const name##_ring_t *r) { return _z_ring_len(r); } \ - static inline _Bool name##_ring_is_empty(const name##_ring_t *r) { return _z_ring_is_empty(r); } \ - static inline _Bool name##_ring_is_full(const name##_ring_t *r) { return _z_ring_is_full(r); } \ + static inline bool name##_ring_is_empty(const name##_ring_t *r) { return _z_ring_is_empty(r); } \ + static inline bool name##_ring_is_full(const name##_ring_t *r) { return _z_ring_is_full(r); } \ static inline type *name##_ring_push(name##_ring_t *r, type *e) { return _z_ring_push(r, (void *)e); } \ static inline type *name##_ring_push_force(name##_ring_t *r, type *e) { return _z_ring_push_force(r, (void *)e); } \ static inline void name##_ring_push_force_drop(name##_ring_t *r, type *e) { \ diff --git a/src/api/utils.c b/src/api/utils.c index b70d128cb..d4c49bf7b 100644 --- a/src/api/utils.c +++ b/src/api/utils.c @@ -17,7 +17,7 @@ #include "zenoh-pico/protocol/core.h" #include "zenoh-pico/system/platform.h" -// z_owned_sample_ring_t z_sample_ring_new(size_t capacity) { +// z_owned_sample_ring_t z_sample_channel_ring_new(size_t capacity) { // z_owned_sample_ring_t ring; // ring._ring = _z_sample_ring_new(capacity); @@ -39,7 +39,7 @@ // #endif // } -// void z_owned_sample_ring_push(z_owned_sample_ring_t *r, const z_sample_t *s) { +// void z_sample_channel_ring_push(z_owned_sample_ring_t *r, const z_sample_t *s) { // z_owned_sample_t *os = (z_owned_sample_t *)zp_malloc(sizeof(z_owned_sample_t)); // memcpy(&os->keyexpr, &s->keyexpr, sizeof(_z_keyexpr_t)); // memcpy(&os->payload, &s->payload, sizeof(z_bytes_t)); @@ -52,7 +52,7 @@ // #endif // } -// z_owned_sample_t *z_owned_sample_ring_pull(z_owned_sample_ring_t *r) { +// z_owned_sample_t *z_sample_channel_ring_pull(z_owned_sample_ring_t *r) { // #if Z_FEATURE_MULTI_THREAD == 1 // zp_mutex_lock(&r->_mutex); // #endif diff --git a/src/collections/ring.c b/src/collections/ring.c index 266e91091..912dcf4bb 100644 --- a/src/collections/ring.c +++ b/src/collections/ring.c @@ -23,7 +23,6 @@ int8_t _z_ring_init(_z_ring_t *r, size_t capacity) { capacity++; memset(r, 0, sizeof(_z_ring_t)); - // r = {._capacity = capacity, ._r_idx = (size_t)0, ._w_idx = (size_t)0, ._val = NULL}; if (capacity != (size_t)0) { r->_val = (void **)zp_malloc(sizeof(void *) * capacity); } @@ -35,17 +34,8 @@ int8_t _z_ring_init(_z_ring_t *r, size_t capacity) { } _z_ring_t _z_ring_make(size_t capacity) { - // We need one more element to differentiate wether the ring is empty or full - capacity++; - - _z_ring_t v = {._capacity = capacity, ._r_idx = (size_t)0, ._w_idx = (size_t)0, ._val = NULL}; - if (capacity != (size_t)0) { - v._val = (void **)zp_malloc(sizeof(void *) * capacity); - } - if (v._val != NULL) { - memset(v._val, 0, capacity); - v._capacity = capacity; - } + _z_ring_t v; + _z_ring_init(&v, capacity); return v; } @@ -59,9 +49,9 @@ size_t _z_ring_len(const _z_ring_t *r) { } } -_Bool _z_ring_is_empty(const _z_ring_t *r) { return r->_w_idx == r->_r_idx; } +bool _z_ring_is_empty(const _z_ring_t *r) { return r->_w_idx == r->_r_idx; } -_Bool _z_ring_is_full(const _z_ring_t *r) { return _z_ring_len(r) == _z_ring_capacity(r); } +bool _z_ring_is_full(const _z_ring_t *r) { return _z_ring_len(r) == _z_ring_capacity(r); } void *_z_ring_push(_z_ring_t *r, void *e) { void *ret = e; diff --git a/tests/z_collections_test.c b/tests/z_collections_test.c index 02d7f53fd..9b5c76de4 100644 --- a/tests/z_collections_test.c +++ b/tests/z_collections_test.c @@ -16,36 +16,38 @@ #include #include -#include "zenoh-pico/collections/string.h" -// aa +#include "zenoh-pico/collections/lifo.h" #include "zenoh-pico/collections/ring.h" - -_Z_RING_DEFINE(_z_str, char) +#include "zenoh-pico/collections/string.h" #undef NDEBUG #include +char *a = "a"; +char *b = "b"; +char *c = "c"; +char *d = "d"; + +// RING +_Z_RING_DEFINE(_z_str, char) + void print_ring(_z_ring_t *r) { printf("Ring { capacity: %zu, r_idx: %zu, w_idx: %zu, len: %zu }\n", _z_ring_capacity(r), r->_r_idx, r->_w_idx, _z_ring_len(r)); } void ring_test(void) { - char *a = "a"; - char *b = "b"; - char *c = "c"; - char *d = "d"; - _z_str_ring_t r = _z_str_ring_make(3); print_ring(&r); assert(_z_str_ring_is_empty(&r)); // One - _z_str_ring_push(&r, a); + char *s = _z_str_ring_push(&r, a); print_ring(&r); + assert(s == NULL); assert(_z_str_ring_len(&r) == 1); - char *s = _z_str_ring_pull(&r); + s = _z_str_ring_pull(&r); print_ring(&r); assert(strcmp(a, s) == 0); assert(_z_str_ring_is_empty(&r)); @@ -74,42 +76,192 @@ void ring_test(void) { s = _z_str_ring_push(&r, d); print_ring(&r); + printf("%s == %s\n", d, s); assert(strcmp(d, s) == 0); assert(_z_str_ring_len(&r) == 3); assert(_z_str_ring_is_full(&r)); s = _z_str_ring_push_force(&r, d); print_ring(&r); + printf("%s == %s\n", a, s); assert(strcmp(a, s) == 0); assert(_z_str_ring_len(&r) == 3); assert(_z_str_ring_is_full(&r)); s = _z_str_ring_push_force(&r, d); print_ring(&r); + printf("%s == %s\n", b, s); assert(strcmp(b, s) == 0); assert(_z_str_ring_len(&r) == 3); assert(_z_str_ring_is_full(&r)); s = _z_str_ring_push_force(&r, d); print_ring(&r); + printf("%s == %s\n", c, s); assert(strcmp(c, s) == 0); assert(_z_str_ring_len(&r) == 3); assert(_z_str_ring_is_full(&r)); s = _z_str_ring_pull(&r); print_ring(&r); + printf("%s == %s\n", d, s); assert(strcmp(d, s) == 0); assert(_z_str_ring_len(&r) == 2); s = _z_str_ring_pull(&r); print_ring(&r); + printf("%s == %s\n", d, s); assert(strcmp(d, s) == 0); assert(_z_str_ring_len(&r) == 1); s = _z_str_ring_pull(&r); print_ring(&r); + printf("%s == %s\n", d, s); assert(strcmp(d, s) == 0); assert(_z_str_ring_is_empty(&r)); } -int main(void) { ring_test(); } +// LIFO +_Z_LIFO_DEFINE(_z_str, char) + +void print_lifo(_z_lifo_t *r) { printf("Lifo { capacity: %zu, len: %zu }\n", _z_lifo_capacity(r), _z_lifo_len(r)); } + +void lifo_test(void) { + _z_str_lifo_t r = _z_str_lifo_make(3); + print_lifo(&r); + assert(_z_str_lifo_is_empty(&r)); + + // One + char *s = _z_str_lifo_push(&r, a); + print_lifo(&r); + assert(s == NULL); + assert(_z_str_lifo_len(&r) == 1); + + s = _z_str_lifo_pull(&r); + print_lifo(&r); + printf("%s == %s\n", a, s); + assert(strcmp(a, s) == 0); + assert(_z_str_lifo_is_empty(&r)); + + s = _z_str_lifo_pull(&r); + print_lifo(&r); + assert(s == NULL); + assert(_z_str_lifo_is_empty(&r)); + + // Two + s = _z_str_lifo_push(&r, a); + print_lifo(&r); + assert(s == NULL); + assert(_z_str_lifo_len(&r) == 1); + + s = _z_str_lifo_push(&r, b); + print_lifo(&r); + assert(s == NULL); + assert(_z_str_lifo_len(&r) == 2); + + s = _z_str_lifo_push(&r, c); + print_lifo(&r); + assert(s == NULL); + assert(_z_str_lifo_len(&r) == 3); + assert(_z_str_lifo_is_full(&r)); + + s = _z_str_lifo_push(&r, d); + print_lifo(&r); + printf("%s == %s\n", d, s); + assert(strcmp(d, s) == 0); + assert(_z_str_lifo_len(&r) == 3); + assert(_z_str_lifo_is_full(&r)); + + s = _z_str_lifo_pull(&r); + print_lifo(&r); + printf("%s == %s\n", c, s); + assert(strcmp(c, s) == 0); + assert(_z_str_lifo_len(&r) == 2); + + s = _z_str_lifo_pull(&r); + print_lifo(&r); + printf("%s == %s\n", b, s); + assert(strcmp(b, s) == 0); + assert(_z_str_lifo_len(&r) == 1); + + s = _z_str_lifo_pull(&r); + print_lifo(&r); + printf("%s == %s\n", a, s); + assert(strcmp(a, s) == 0); + assert(_z_str_lifo_is_empty(&r)); +} + +// // FIFO +// _Z_FIFO_DEFINE(_z_str, char) + +// void print_fifo(_z_fifo_t *r) { printf("Fifo { capacity: %zu, len: %zu }\n", _z_fifo_capacity(r), _z_fifo_len(r)); } + +// void fifo_test(void) { +// _z_str_fifo_t r = _z_str_fifo_make(3); +// print_fifo(&r); +// assert(_z_str_fifo_is_empty(&r)); + +// // One +// char *s = _z_str_fifo_push(&r, a); +// print_fifo(&r); +// assert(s == NULL); +// assert(_z_str_fifo_len(&r) == 1); + +// s = _z_str_fifo_pull(&r); +// print_fifo(&r); +// printf("%s == %s\n", a, s); +// assert(strcmp(a, s) == 0); +// assert(_z_str_fifo_is_empty(&r)); + +// s = _z_str_fifo_pull(&r); +// print_fifo(&r); +// assert(s == NULL); +// assert(_z_str_fifo_is_empty(&r)); + +// // Two +// s = _z_str_fifo_push(&r, a); +// print_fifo(&r); +// assert(s == NULL); +// assert(_z_str_fifo_len(&r) == 1); + +// s = _z_str_fifo_push(&r, b); +// print_fifo(&r); +// assert(s == NULL); +// assert(_z_str_fifo_len(&r) == 2); + +// s = _z_str_fifo_push(&r, c); +// print_fifo(&r); +// assert(s == NULL); +// assert(_z_str_fifo_len(&r) == 3); +// assert(_z_str_fifo_is_full(&r)); + +// s = _z_str_fifo_push(&r, d); +// print_fifo(&r); +// printf("%s == %s\n", d, s); +// assert(strcmp(d, s) == 0); +// assert(_z_str_fifo_len(&r) == 3); +// assert(_z_str_fifo_is_full(&r)); + +// s = _z_str_fifo_pull(&r); +// print_fifo(&r); +// printf("%s == %s\n", c, s); +// assert(strcmp(c, s) == 0); +// assert(_z_str_fifo_len(&r) == 2); + +// s = _z_str_fifo_pull(&r); +// print_fifo(&r); +// printf("%s == %s\n", b, s); +// assert(strcmp(b, s) == 0); +// assert(_z_str_fifo_len(&r) == 1); + +// s = _z_str_fifo_pull(&r); +// print_fifo(&r); +// printf("%s == %s\n", a, s); +// assert(strcmp(a, s) == 0); +// assert(_z_str_fifo_is_empty(&r)); +// } + +int main(void) { + ring_test(); + lifo_test(); +} From 2e13913064e6f03c3fd01421cc7fb4c4c135f646 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Thu, 21 Mar 2024 17:41:36 +0100 Subject: [PATCH 12/21] Add fifo and lifo collections --- include/zenoh-pico/collections/fifo.h | 63 ++++++++++++ include/zenoh-pico/collections/lifo.h | 64 ++++++++++++ src/collections/fifo.c | 53 ++++++++++ src/collections/lifo.c | 90 +++++++++++++++++ tests/z_collections_test.c | 140 +++++++++++++------------- 5 files changed, 341 insertions(+), 69 deletions(-) create mode 100644 include/zenoh-pico/collections/fifo.h create mode 100644 include/zenoh-pico/collections/lifo.h create mode 100644 src/collections/fifo.c create mode 100644 src/collections/lifo.c diff --git a/include/zenoh-pico/collections/fifo.h b/include/zenoh-pico/collections/fifo.h new file mode 100644 index 000000000..1deef22c5 --- /dev/null +++ b/include/zenoh-pico/collections/fifo.h @@ -0,0 +1,63 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#ifndef ZENOH_PICO_COLLECTIONS_FIFO_H +#define ZENOH_PICO_COLLECTIONS_FIFO_H + +#include +#include + +#include "zenoh-pico/collections/element.h" +#include "zenoh-pico/collections/ring.h" + +/*-------- Fifo Buffer --------*/ +typedef struct { + _z_ring_t _ring; +} _z_fifo_t; + +int8_t _z_fifo_init(_z_fifo_t *fifo, size_t capacity); +_z_fifo_t _z_fifo_make(size_t capacity); + +size_t _z_fifo_capacity(const _z_fifo_t *r); +size_t _z_fifo_len(const _z_fifo_t *r); +_Bool _z_fifo_is_empty(const _z_fifo_t *r); +_Bool _z_fifo_is_full(const _z_fifo_t *r); + +void *_z_fifo_push(_z_fifo_t *r, void *e); +void _z_fifo_push_drop(_z_fifo_t *r, void *e, z_element_free_f f); +void *_z_fifo_pull(_z_fifo_t *r); + +_z_fifo_t *_z_fifo_clone(const _z_fifo_t *xs, z_element_clone_f d_f); + +void _z_fifo_clear(_z_fifo_t *v, z_element_free_f f); +void _z_fifo_free(_z_fifo_t **xs, z_element_free_f f_f); + +#define _Z_FIFO_DEFINE(name, type) \ + typedef _z_fifo_t name##_fifo_t; \ + static inline int8_t name##_fifo_init(name##_fifo_t *fifo, size_t capacity) { \ + return _z_fifo_init(fifo, capacity); \ + } \ + static inline name##_fifo_t name##_fifo_make(size_t capacity) { return _z_fifo_make(capacity); } \ + static inline size_t name##_fifo_capacity(const name##_fifo_t *r) { return _z_fifo_capacity(r); } \ + static inline size_t name##_fifo_len(const name##_fifo_t *r) { return _z_fifo_len(r); } \ + static inline _Bool name##_fifo_is_empty(const name##_fifo_t *r) { return _z_fifo_is_empty(r); } \ + static inline _Bool name##_fifo_is_full(const name##_fifo_t *r) { return _z_fifo_is_full(r); } \ + static inline type *name##_fifo_push(name##_fifo_t *r, type *e) { return _z_fifo_push(r, (void *)e); } \ + static inline void name##_fifo_push_drop(name##_fifo_t *r, type *e) { \ + return _z_fifo_push_drop(r, (void *)e, name##_elem_free); \ + } \ + static inline type *name##_fifo_pull(name##_fifo_t *r) { return (type *)_z_fifo_pull(r); } \ + static inline void name##_fifo_clear(name##_fifo_t *r) { _z_fifo_clear(r, name##_elem_free); } \ + static inline void name##_fifo_free(name##_fifo_t **r) { _z_fifo_free(r, name##_elem_free); } + +#endif /* ZENOH_PICO_COLLECTIONS_FIFO_H */ diff --git a/include/zenoh-pico/collections/lifo.h b/include/zenoh-pico/collections/lifo.h new file mode 100644 index 000000000..0a2da7023 --- /dev/null +++ b/include/zenoh-pico/collections/lifo.h @@ -0,0 +1,64 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#ifndef ZENOH_PICO_COLLECTIONS_LIFO_H +#define ZENOH_PICO_COLLECTIONS_LIFO_H + +#include +#include + +#include "zenoh-pico/collections/element.h" + +/*-------- Ring Buffer --------*/ +typedef struct { + void **_val; + size_t _capacity; + size_t _len; +} _z_lifo_t; + +int8_t _z_lifo_init(_z_lifo_t *lifo, size_t capacity); +_z_lifo_t _z_lifo_make(size_t capacity); + +size_t _z_lifo_capacity(const _z_lifo_t *r); +size_t _z_lifo_len(const _z_lifo_t *r); +_Bool _z_lifo_is_empty(const _z_lifo_t *r); +_Bool _z_lifo_is_full(const _z_lifo_t *r); + +void *_z_lifo_push(_z_lifo_t *r, void *e); +void _z_lifo_push_drop(_z_lifo_t *r, void *e, z_element_free_f f); +void *_z_lifo_pull(_z_lifo_t *r); + +_z_lifo_t *_z_lifo_clone(const _z_lifo_t *xs, z_element_clone_f d_f); + +void _z_lifo_clear(_z_lifo_t *v, z_element_free_f f); +void _z_lifo_free(_z_lifo_t **xs, z_element_free_f f_f); + +#define _Z_LIFO_DEFINE(name, type) \ + typedef _z_lifo_t name##_lifo_t; \ + static inline int8_t name##_lifo_init(name##_lifo_t *lifo, size_t capacity) { \ + return _z_lifo_init(lifo, capacity); \ + } \ + static inline name##_lifo_t name##_lifo_make(size_t capacity) { return _z_lifo_make(capacity); } \ + static inline size_t name##_lifo_capacity(const name##_lifo_t *r) { return _z_lifo_capacity(r); } \ + static inline size_t name##_lifo_len(const name##_lifo_t *r) { return _z_lifo_len(r); } \ + static inline _Bool name##_lifo_is_empty(const name##_lifo_t *r) { return _z_lifo_is_empty(r); } \ + static inline _Bool name##_lifo_is_full(const name##_lifo_t *r) { return _z_lifo_is_full(r); } \ + static inline type *name##_lifo_push(name##_lifo_t *r, type *e) { return _z_lifo_push(r, (void *)e); } \ + static inline void name##_lifo_push_drop(name##_lifo_t *r, type *e) { \ + return _z_lifo_push_drop(r, (void *)e, name##_elem_free); \ + } \ + static inline type *name##_lifo_pull(name##_lifo_t *r) { return (type *)_z_lifo_pull(r); } \ + static inline void name##_lifo_clear(name##_lifo_t *r) { _z_lifo_clear(r, name##_elem_free); } \ + static inline void name##_lifo_free(name##_lifo_t **r) { _z_lifo_free(r, name##_elem_free); } + +#endif /* ZENOH_PICO_COLLECTIONS_LIFO_H */ diff --git a/src/collections/fifo.c b/src/collections/fifo.c new file mode 100644 index 000000000..463c7f9db --- /dev/null +++ b/src/collections/fifo.c @@ -0,0 +1,53 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#include "zenoh-pico/collections/fifo.h" + +#include +#include +#include + +/*-------- fifo --------*/ +int8_t _z_fifo_init(_z_fifo_t *r, size_t capacity) { + _z_ring_init(&r->_ring, capacity); + return 0; +} + +_z_fifo_t _z_fifo_make(size_t capacity) { + _z_fifo_t v; + _z_fifo_init(&v, capacity); + return v; +} + +size_t _z_fifo_capacity(const _z_fifo_t *r) { return _z_ring_capacity(&r->_ring); } +size_t _z_fifo_len(const _z_fifo_t *r) { return _z_ring_len(&r->_ring); } +bool _z_fifo_is_empty(const _z_fifo_t *r) { return _z_ring_is_empty(&r->_ring); } +bool _z_fifo_is_full(const _z_fifo_t *r) { return _z_fifo_len(r) == _z_fifo_capacity(r); } + +void *_z_fifo_push(_z_fifo_t *r, void *e) { return _z_ring_push(&r->_ring, e); } +void _z_fifo_push_drop(_z_fifo_t *r, void *e, z_element_free_f free_f) { + void *ret = _z_fifo_push(r, e); + if (ret != NULL) { + free_f(&ret); + } +} +void *_z_fifo_pull(_z_fifo_t *r) { return _z_ring_pull(&r->_ring); } +void _z_fifo_clear(_z_fifo_t *r, z_element_free_f free_f) { _z_ring_clear(&r->_ring, free_f); } +void _z_fifo_free(_z_fifo_t **r, z_element_free_f free_f) { + _z_fifo_t *ptr = (_z_fifo_t *)*r; + if (ptr != NULL) { + _z_fifo_clear(ptr, free_f); + zp_free(ptr); + *r = NULL; + } +} diff --git a/src/collections/lifo.c b/src/collections/lifo.c new file mode 100644 index 000000000..6cccca8fa --- /dev/null +++ b/src/collections/lifo.c @@ -0,0 +1,90 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#include "zenoh-pico/collections/lifo.h" + +#include +#include +#include + +/*-------- lifo --------*/ +int8_t _z_lifo_init(_z_lifo_t *r, size_t capacity) { + memset(r, 0, sizeof(_z_lifo_t)); + if (capacity != (size_t)0) { + r->_val = (void **)zp_malloc(sizeof(void *) * capacity); + } + if (r->_val != NULL) { + memset(r->_val, 0, capacity); + r->_capacity = capacity; + } + return 0; +} + +_z_lifo_t _z_lifo_make(size_t capacity) { + _z_lifo_t v; + _z_lifo_init(&v, capacity); + return v; +} + +size_t _z_lifo_capacity(const _z_lifo_t *r) { return r->_capacity; } +size_t _z_lifo_len(const _z_lifo_t *r) { return r->_len; } +_Bool _z_lifo_is_empty(const _z_lifo_t *r) { return r->_len == 0; } +_Bool _z_lifo_is_full(const _z_lifo_t *r) { return r->_len == r->_capacity; } + +void *_z_lifo_push(_z_lifo_t *r, void *e) { + void *ret = e; + if (!_z_lifo_is_full(r)) { + r->_val[r->_len] = e; + r->_len++; + ret = NULL; + } + return ret; +} + +void _z_lifo_push_drop(_z_lifo_t *r, void *e, z_element_free_f free_f) { + void *ret = _z_lifo_push(r, e); + if (ret != NULL) { + free_f(&ret); + } +} + +void *_z_lifo_pull(_z_lifo_t *r) { + void *ret = NULL; + if (!_z_lifo_is_empty(r)) { + r->_len--; + ret = r->_val[r->_len]; + } + return ret; +} + +void _z_lifo_clear(_z_lifo_t *r, z_element_free_f free_f) { + void *e = _z_lifo_pull(r); + while (e != NULL) { + free_f(&e); + e = _z_lifo_pull(r); + } + zp_free(r->_val); + + r->_val = NULL; + r->_capacity = (size_t)0; + r->_len = (size_t)0; +} + +void _z_lifo_free(_z_lifo_t **r, z_element_free_f free_f) { + _z_lifo_t *ptr = (_z_lifo_t *)*r; + if (ptr != NULL) { + _z_lifo_clear(ptr, free_f); + zp_free(ptr); + *r = NULL; + } +} diff --git a/tests/z_collections_test.c b/tests/z_collections_test.c index 9b5c76de4..4f61cadf8 100644 --- a/tests/z_collections_test.c +++ b/tests/z_collections_test.c @@ -16,6 +16,7 @@ #include #include +#include "zenoh-pico/collections/fifo.h" #include "zenoh-pico/collections/lifo.h" #include "zenoh-pico/collections/ring.h" #include "zenoh-pico/collections/string.h" @@ -191,77 +192,78 @@ void lifo_test(void) { assert(_z_str_lifo_is_empty(&r)); } -// // FIFO -// _Z_FIFO_DEFINE(_z_str, char) - -// void print_fifo(_z_fifo_t *r) { printf("Fifo { capacity: %zu, len: %zu }\n", _z_fifo_capacity(r), _z_fifo_len(r)); } - -// void fifo_test(void) { -// _z_str_fifo_t r = _z_str_fifo_make(3); -// print_fifo(&r); -// assert(_z_str_fifo_is_empty(&r)); - -// // One -// char *s = _z_str_fifo_push(&r, a); -// print_fifo(&r); -// assert(s == NULL); -// assert(_z_str_fifo_len(&r) == 1); - -// s = _z_str_fifo_pull(&r); -// print_fifo(&r); -// printf("%s == %s\n", a, s); -// assert(strcmp(a, s) == 0); -// assert(_z_str_fifo_is_empty(&r)); - -// s = _z_str_fifo_pull(&r); -// print_fifo(&r); -// assert(s == NULL); -// assert(_z_str_fifo_is_empty(&r)); - -// // Two -// s = _z_str_fifo_push(&r, a); -// print_fifo(&r); -// assert(s == NULL); -// assert(_z_str_fifo_len(&r) == 1); - -// s = _z_str_fifo_push(&r, b); -// print_fifo(&r); -// assert(s == NULL); -// assert(_z_str_fifo_len(&r) == 2); - -// s = _z_str_fifo_push(&r, c); -// print_fifo(&r); -// assert(s == NULL); -// assert(_z_str_fifo_len(&r) == 3); -// assert(_z_str_fifo_is_full(&r)); - -// s = _z_str_fifo_push(&r, d); -// print_fifo(&r); -// printf("%s == %s\n", d, s); -// assert(strcmp(d, s) == 0); -// assert(_z_str_fifo_len(&r) == 3); -// assert(_z_str_fifo_is_full(&r)); - -// s = _z_str_fifo_pull(&r); -// print_fifo(&r); -// printf("%s == %s\n", c, s); -// assert(strcmp(c, s) == 0); -// assert(_z_str_fifo_len(&r) == 2); - -// s = _z_str_fifo_pull(&r); -// print_fifo(&r); -// printf("%s == %s\n", b, s); -// assert(strcmp(b, s) == 0); -// assert(_z_str_fifo_len(&r) == 1); - -// s = _z_str_fifo_pull(&r); -// print_fifo(&r); -// printf("%s == %s\n", a, s); -// assert(strcmp(a, s) == 0); -// assert(_z_str_fifo_is_empty(&r)); -// } +// FIFO +_Z_FIFO_DEFINE(_z_str, char) + +void print_fifo(_z_fifo_t *r) { printf("Fifo { capacity: %zu, len: %zu }\n", _z_fifo_capacity(r), _z_fifo_len(r)); } + +void fifo_test(void) { + _z_str_fifo_t r = _z_str_fifo_make(3); + print_fifo(&r); + assert(_z_str_fifo_is_empty(&r)); + + // One + char *s = _z_str_fifo_push(&r, a); + print_fifo(&r); + assert(s == NULL); + assert(_z_str_fifo_len(&r) == 1); + + s = _z_str_fifo_pull(&r); + print_fifo(&r); + printf("%s == %s\n", a, s); + assert(strcmp(a, s) == 0); + assert(_z_str_fifo_is_empty(&r)); + + s = _z_str_fifo_pull(&r); + print_fifo(&r); + assert(s == NULL); + assert(_z_str_fifo_is_empty(&r)); + + // Two + s = _z_str_fifo_push(&r, a); + print_fifo(&r); + assert(s == NULL); + assert(_z_str_fifo_len(&r) == 1); + + s = _z_str_fifo_push(&r, b); + print_fifo(&r); + assert(s == NULL); + assert(_z_str_fifo_len(&r) == 2); + + s = _z_str_fifo_push(&r, c); + print_fifo(&r); + assert(s == NULL); + assert(_z_str_fifo_len(&r) == 3); + assert(_z_str_fifo_is_full(&r)); + + s = _z_str_fifo_push(&r, d); + print_fifo(&r); + printf("%s == %s\n", d, s); + assert(strcmp(d, s) == 0); + assert(_z_str_fifo_len(&r) == 3); + assert(_z_str_fifo_is_full(&r)); + + s = _z_str_fifo_pull(&r); + print_fifo(&r); + printf("%s == %s\n", a, s); + assert(strcmp(a, s) == 0); + assert(_z_str_fifo_len(&r) == 2); + + s = _z_str_fifo_pull(&r); + print_fifo(&r); + printf("%s == %s\n", b, s); + assert(strcmp(b, s) == 0); + assert(_z_str_fifo_len(&r) == 1); + + s = _z_str_fifo_pull(&r); + print_fifo(&r); + printf("%s == %s\n", c, s); + assert(strcmp(c, s) == 0); + assert(_z_str_fifo_is_empty(&r)); +} int main(void) { ring_test(); lifo_test(); + fifo_test(); } From 25b0661fd3a9eadb0a121d8338895da45e1000e2 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 22 Mar 2024 16:53:05 +0100 Subject: [PATCH 13/21] Moved utils to handlers. Added FIFO handlers. Add z_sub_channel. --- examples/CMakeLists.txt | 5 +- examples/unix/c11/z_sub_channel.c | 99 ++++++++++ include/zenoh-pico.h | 2 +- .../zenoh-pico/api/{utils.h => handlers.h} | 95 +++------ src/api/handlers.c | 186 ++++++++++++++++++ src/api/utils.c | 64 ------ zenohpico.pc | 2 +- 7 files changed, 315 insertions(+), 138 deletions(-) create mode 100644 examples/unix/c11/z_sub_channel.c rename include/zenoh-pico/api/{utils.h => handlers.h} (52%) create mode 100644 src/api/handlers.c delete mode 100644 src/api/utils.c diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 05e76b29b..a70eb7691 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -24,6 +24,7 @@ if(UNIX) add_example(z_pub unix/c99/z_pub.c) add_example(z_pub_st unix/c99/z_pub_st.c) add_example(z_sub unix/c99/z_sub.c) + add_example(z_sub_channel unix/c99/z_sub_channel.c) add_example(z_sub_st unix/c99/z_sub_st.c) add_example(z_pull unix/c99/z_pull.c) add_example(z_get unix/c99/z_get.c) @@ -37,6 +38,7 @@ if(UNIX) add_example(z_pub unix/c11/z_pub.c) add_example(z_pub_st unix/c11/z_pub_st.c) add_example(z_sub unix/c11/z_sub.c) + add_example(z_sub_channel unix/c11/z_sub_channel.c) add_example(z_sub_st unix/c11/z_sub_st.c) add_example(z_pull unix/c11/z_pull.c) add_example(z_get unix/c11/z_get.c) @@ -53,8 +55,9 @@ elseif(MSVC) add_example(z_pub windows/z_pub.c) add_example(z_pub_st windows/z_pub_st.c) add_example(z_sub windows/z_sub.c) + add_example(z_sub windows/z_sub_channel.c) add_example(z_sub_st windows/z_sub_st.c) - add_example(z_pull windows/z_pull.c) + add_example(z_sub_channel windows/z_pull.c) add_example(z_get windows/z_get.c) add_example(z_queryable windows/z_queryable.c) add_example(z_info windows/z_info.c) diff --git a/examples/unix/c11/z_sub_channel.c b/examples/unix/c11/z_sub_channel.c new file mode 100644 index 000000000..005fc60e4 --- /dev/null +++ b/examples/unix/c11/z_sub_channel.c @@ -0,0 +1,99 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, + +#include +#include +#include +#include +#include +#include + +#if Z_FEATURE_SUBSCRIPTION == 1 +int main(int argc, char **argv) { + const char *keyexpr = "demo/example/**"; + char *locator = NULL; + + int opt; + while ((opt = getopt(argc, argv, "k:e:")) != -1) { + switch (opt) { + case 'k': + keyexpr = optarg; + break; + case 'e': + locator = optarg; + break; + case '?': + if (optopt == 'k' || optopt == 'e') { + fprintf(stderr, "Option -%c requires an argument.\n", optopt); + } else { + fprintf(stderr, "Unknown option `-%c'.\n", optopt); + } + return 1; + default: + return -1; + } + } + + z_owned_config_t config = z_config_default(); + if (locator != NULL) { + zp_config_insert(z_loan(config), Z_CONFIG_CONNECT_KEY, z_string_make(locator)); + } + + printf("Opening session...\n"); + z_owned_session_t s = z_open(z_move(config)); + if (!z_check(s)) { + printf("Unable to open session!\n"); + return -1; + } + + // Start read and lease tasks for zenoh-pico + if (zp_start_read_task(z_loan(s), NULL) < 0 || zp_start_lease_task(z_loan(s), NULL) < 0) { + printf("Unable to start read and lease tasks\n"); + z_close(z_session_move(&s)); + return -1; + } + + printf("Declaring Subscriber on '%s'...\n", keyexpr); + z_owned_sample_channel_t channel = z_sample_channel_fifo_new(3); + z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(channel.send), NULL); + if (!z_check(sub)) { + printf("Unable to declare subscriber.\n"); + return -1; + } + + z_owned_sample_t sample = z_sample_null(); + for (z_call(channel.recv, &sample); z_check(sample); z_call(channel.recv, &sample)) { + z_owned_str_t keystr = z_keyexpr_to_string(z_loan(sample.keyexpr)); + printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, + sample.payload.start); + z_drop(z_move(keystr)); + z_drop(z_move(sample)); + sample = z_sample_null(); + } + + z_undeclare_subscriber(z_move(sub)); + + // Stop read and lease tasks for zenoh-pico + zp_stop_read_task(z_loan(s)); + zp_stop_lease_task(z_loan(s)); + + z_close(z_move(s)); + + return 0; +} +#else +int main(void) { + printf("ERROR: Zenoh pico was compiled without Z_FEATURE_SUBSCRIPTION but this example requires it.\n"); + return -2; +} +#endif diff --git a/include/zenoh-pico.h b/include/zenoh-pico.h index bf3feab68..4f9ebb636 100644 --- a/include/zenoh-pico.h +++ b/include/zenoh-pico.h @@ -22,9 +22,9 @@ #define ZENOH_PICO_TWEAK 0 #include "zenoh-pico/api/constants.h" +#include "zenoh-pico/api/handlers.h" #include "zenoh-pico/api/macros.h" #include "zenoh-pico/api/primitives.h" #include "zenoh-pico/api/types.h" -#include "zenoh-pico/api/utils.h" #endif /* ZENOH_PICO_H */ diff --git a/include/zenoh-pico/api/utils.h b/include/zenoh-pico/api/handlers.h similarity index 52% rename from include/zenoh-pico/api/utils.h rename to include/zenoh-pico/api/handlers.h index 36325fbf8..928a9fa59 100644 --- a/include/zenoh-pico/api/utils.h +++ b/include/zenoh-pico/api/handlers.h @@ -11,8 +11,8 @@ // Contributors: // ZettaScale Zenoh Team, // -#ifndef INCLUDE_ZENOH_PICO_API_UTILS_H -#define INCLUDE_ZENOH_PICO_API_UTILS_H +#ifndef INCLUDE_ZENOH_PICO_API_HANDLERS_H +#define INCLUDE_ZENOH_PICO_API_HANDLERS_H #include #include @@ -20,9 +20,12 @@ #include "zenoh-pico/api/macros.h" #include "zenoh-pico/api/types.h" #include "zenoh-pico/collections/element.h" +#include "zenoh-pico/collections/fifo.h" #include "zenoh-pico/collections/ring.h" #include "zenoh-pico/system/platform.h" +// -- Owned sample +// @TODO: define it via dedicated macros and move it to the appropriate place in types. typedef struct { z_owned_keyexpr_t keyexpr; z_bytes_t payload; @@ -68,6 +71,8 @@ static inline void z_sample_drop(z_owned_sample_t *s) { } } +_Z_ELEM_DEFINE(_z_owned_sample, z_owned_sample_t, _z_noop_size, z_sample_drop, _z_noop_copy) + // -- Channel typedef int8_t (*_z_owned_sample_handler_t)(z_owned_sample_t *dst, void *context); @@ -82,21 +87,10 @@ typedef struct { z_owned_closure_owned_sample_t recv; } z_owned_sample_channel_t; -static inline z_owned_sample_channel_t z_owned_sample_channel_null() { - z_owned_sample_channel_t ch = {.send = NULL, .recv = NULL}; - return ch; -} - -static inline int8_t z_closure_owned_sample_call(z_owned_closure_owned_sample_t *recv, z_owned_sample_t *dst) { - int8_t res = _Z_ERR_GENERIC; - if (recv != NULL) { - res = (recv->call)(dst, recv->context); - } - return res; -} +z_owned_sample_channel_t z_owned_sample_channel_null(); +int8_t z_closure_owned_sample_call(z_owned_closure_owned_sample_t *recv, z_owned_sample_t *dst); // -- Ring -_Z_ELEM_DEFINE(_z_owned_sample, z_owned_sample_t, _z_noop_size, _z_noop_clear, _z_noop_copy) _Z_RING_DEFINE(_z_owned_sample, z_owned_sample_t) typedef struct { @@ -106,65 +100,24 @@ typedef struct { #endif } z_owned_sample_ring_t; -static inline void z_sample_channel_ring_push(const z_sample_t *src, void *context) { - if (src == NULL || context == NULL) { - return; - } - - z_owned_sample_ring_t *r = (z_owned_sample_ring_t *)context; - z_owned_sample_t *dst = (z_owned_sample_t *)zp_malloc(sizeof(z_owned_sample_t)); - if (dst == NULL) { - return; - } - *dst = z_sample_to_owned(src); - -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_lock(&r->_mutex); -#endif - _z_owned_sample_ring_push_force_drop(&r->_ring, dst); -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_unlock(&r->_mutex); -#endif -} - -static inline int8_t z_sample_channel_ring_pull(z_owned_sample_t *dst, void *context) { - int8_t ret = _Z_RES_OK; +z_owned_sample_channel_t z_sample_channel_ring_new(size_t capacity); +void z_sample_channel_ring_push(const z_sample_t *src, void *context); +int8_t z_sample_channel_ring_pull(z_owned_sample_t *dst, void *context); - z_owned_sample_ring_t *r = (z_owned_sample_ring_t *)context; +// -- Fifo +_Z_FIFO_DEFINE(_z_owned_sample, z_owned_sample_t) +typedef struct { + _z_owned_sample_fifo_t _fifo; #if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_lock(&r->_mutex); -#endif - z_owned_sample_t *src = _z_owned_sample_ring_pull(&r->_ring); -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_unlock(&r->_mutex); + zp_mutex_t _mutex; + zp_condvar_t _cv_not_full; + zp_condvar_t _cv_not_empty; #endif +} z_owned_sample_fifo_t; - if (src == NULL) { - *dst = z_sample_null(); - } else { - memcpy(dst, src, sizeof(z_owned_sample_t)); - } - return ret; -} - -static inline z_owned_sample_channel_t z_sample_channel_ring_new(size_t capacity) { - z_owned_sample_channel_t ch = z_owned_sample_channel_null(); - - z_owned_sample_ring_t *ring = (z_owned_sample_ring_t *)zp_malloc(sizeof(z_owned_sample_ring_t)); - if (ring != NULL) { - int8_t res = _z_owned_sample_ring_init(&ring->_ring, capacity); - if (res == _Z_RES_OK) { - z_owned_closure_sample_t send = z_closure(z_sample_channel_ring_push, NULL, ring); - ch.send = send; - z_owned_closure_owned_sample_t recv = z_closure(z_sample_channel_ring_pull, NULL, ring); - ch.recv = recv; - } else { - zp_free(ring); - } - } - - return ch; -} +z_owned_sample_channel_t z_sample_channel_fifo_new(size_t capacity); +void z_sample_channel_fifo_push(const z_sample_t *src, void *context); +int8_t z_sample_channel_fifo_pull(z_owned_sample_t *dst, void *context); -#endif // INCLUDE_ZENOH_PICO_API_UTILS_H \ No newline at end of file +#endif // INCLUDE_ZENOH_PICO_API_HANDLERS_H \ No newline at end of file diff --git a/src/api/handlers.c b/src/api/handlers.c new file mode 100644 index 000000000..5850541a6 --- /dev/null +++ b/src/api/handlers.c @@ -0,0 +1,186 @@ +// +// Copyright (c) 2022 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#include "zenoh-pico/api/handlers.h" + +#include "zenoh-pico/api/macros.h" +#include "zenoh-pico/protocol/core.h" +#include "zenoh-pico/system/platform.h" + +// -- Channel +z_owned_sample_channel_t z_owned_sample_channel_null() { + z_owned_sample_channel_t ch = {.send = NULL, .recv = NULL}; + return ch; +} + +int8_t z_closure_owned_sample_call(z_owned_closure_owned_sample_t *recv, z_owned_sample_t *dst) { + int8_t res = _Z_ERR_GENERIC; + if (recv != NULL) { + res = (recv->call)(dst, recv->context); + } + return res; +} + +// -- Ring +void z_sample_channel_ring_push(const z_sample_t *src, void *context) { + if (src == NULL || context == NULL) { + return; + } + + z_owned_sample_ring_t *r = (z_owned_sample_ring_t *)context; + z_owned_sample_t *dst = (z_owned_sample_t *)zp_malloc(sizeof(z_owned_sample_t)); + if (dst == NULL) { + return; + } + *dst = z_sample_to_owned(src); + +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_lock(&r->_mutex); +#endif + _z_owned_sample_ring_push_force_drop(&r->_ring, dst); +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_unlock(&r->_mutex); +#endif +} + +int8_t z_sample_channel_ring_pull(z_owned_sample_t *dst, void *context) { + int8_t ret = _Z_RES_OK; + + z_owned_sample_ring_t *r = (z_owned_sample_ring_t *)context; + +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_lock(&r->_mutex); +#endif + z_owned_sample_t *src = _z_owned_sample_ring_pull(&r->_ring); +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_unlock(&r->_mutex); +#endif + + if (src == NULL) { + *dst = z_sample_null(); + } else { + memcpy(dst, src, sizeof(z_owned_sample_t)); + } + return ret; +} + +z_owned_sample_channel_t z_sample_channel_ring_new(size_t capacity) { + z_owned_sample_channel_t ch = z_owned_sample_channel_null(); + + z_owned_sample_ring_t *ring = (z_owned_sample_ring_t *)zp_malloc(sizeof(z_owned_sample_ring_t)); + if (ring != NULL) { + int8_t res = _z_owned_sample_ring_init(&ring->_ring, capacity); +#if Z_FEATURE_MULTI_THREAD == 1 + res = zp_mutex_init(&ring->_mutex); +#endif + if (res == _Z_RES_OK) { + z_owned_closure_sample_t send = z_closure(z_sample_channel_ring_push, NULL, ring); + ch.send = send; + z_owned_closure_owned_sample_t recv = z_closure(z_sample_channel_ring_pull, NULL, ring); + ch.recv = recv; + } else { + zp_free(ring); + } + } + + return ch; +} + +// -- Fifo +void z_sample_channel_fifo_push(const z_sample_t *src, void *context) { + if (src == NULL || context == NULL) { + return; + } + + z_owned_sample_fifo_t *f = (z_owned_sample_fifo_t *)context; + z_owned_sample_t *dst = (z_owned_sample_t *)zp_malloc(sizeof(z_owned_sample_t)); + if (dst == NULL) { + return; + } + *dst = z_sample_to_owned(src); + +#if Z_FEATURE_MULTI_THREAD == 1 + + zp_mutex_lock(&f->_mutex); + while (dst != NULL) { + dst = _z_owned_sample_fifo_push(&f->_fifo, dst); + if (dst != NULL) { + zp_condvar_wait(&f->_cv_not_full, &f->_mutex); + } else { + zp_condvar_signal(&f->_cv_not_empty); + } + } + zp_mutex_unlock(&f->_mutex); + +#elif // Z_FEATURE_MULTI_THREAD == 1 + + _z_owned_sample_fifo_push_drop(&f->_fifo, dst); + +#endif // Z_FEATURE_MULTI_THREAD == 1 +} + +int8_t z_sample_channel_fifo_pull(z_owned_sample_t *dst, void *context) { + int8_t ret = _Z_RES_OK; + + z_owned_sample_fifo_t *f = (z_owned_sample_fifo_t *)context; + +#if Z_FEATURE_MULTI_THREAD == 1 + + z_owned_sample_t *src = NULL; + zp_mutex_lock(&f->_mutex); + while (src == NULL) { + src = _z_owned_sample_fifo_pull(&f->_fifo); + if (src == NULL) { + zp_condvar_wait(&f->_cv_not_empty, &f->_mutex); + } else { + zp_condvar_signal(&f->_cv_not_full); + } + } + zp_mutex_unlock(&f->_mutex); + memcpy(dst, src, sizeof(z_owned_sample_t)); + +#elif // Z_FEATURE_MULTI_THREAD == 1 + + z_owned_sample_t *src = _z_owned_sample_fifo_pull(&f->_fifo); + if (src != NULL) { + memcpy(dst, src, sizeof(z_owned_sample_t)); + } + +#endif // Z_FEATURE_MULTI_THREAD == 1 + + return ret; +} + +z_owned_sample_channel_t z_sample_channel_fifo_new(size_t capacity) { + z_owned_sample_channel_t ch = z_owned_sample_channel_null(); + + z_owned_sample_fifo_t *fifo = (z_owned_sample_fifo_t *)zp_malloc(sizeof(z_owned_sample_fifo_t)); + if (fifo != NULL) { + int8_t res = _z_owned_sample_fifo_init(&fifo->_fifo, capacity); +#if Z_FEATURE_MULTI_THREAD == 1 + res = zp_mutex_init(&fifo->_mutex); + res = zp_condvar_init(&fifo->_cv_not_full); + res = zp_condvar_init(&fifo->_cv_not_empty); +#endif + if (res == _Z_RES_OK) { + z_owned_closure_sample_t send = z_closure(z_sample_channel_fifo_push, NULL, fifo); + ch.send = send; + z_owned_closure_owned_sample_t recv = z_closure(z_sample_channel_fifo_pull, NULL, fifo); + ch.recv = recv; + } else { + zp_free(fifo); + } + } + + return ch; +} \ No newline at end of file diff --git a/src/api/utils.c b/src/api/utils.c deleted file mode 100644 index d4c49bf7b..000000000 --- a/src/api/utils.c +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright (c) 2022 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -#include "zenoh-pico/api/utils.h" - -#include "zenoh-pico/api/macros.h" -#include "zenoh-pico/protocol/core.h" -#include "zenoh-pico/system/platform.h" - -// z_owned_sample_ring_t z_sample_channel_ring_new(size_t capacity) { -// z_owned_sample_ring_t ring; -// ring._ring = _z_sample_ring_new(capacity); - -// #if Z_FEATURE_MULTI_THREAD == 1 -// zp_mutex_init(&ring._mutex); -// #endif - -// return ring; -// } - -// void z_owned_sample_ring_drop(z_owned_sample_ring_t *r) { -// #if Z_FEATURE_MULTI_THREAD == 1 -// zp_mutex_lock(&r->_mutex); -// #endif -// _z_owned_sample_ring_clear(&r->_ring); -// #if Z_FEATURE_MULTI_THREAD == 1 -// zp_mutex_unlock(&r->_mutex); -// zp_mutex_free(&r->_mutex); -// #endif -// } - -// void z_sample_channel_ring_push(z_owned_sample_ring_t *r, const z_sample_t *s) { -// z_owned_sample_t *os = (z_owned_sample_t *)zp_malloc(sizeof(z_owned_sample_t)); -// memcpy(&os->keyexpr, &s->keyexpr, sizeof(_z_keyexpr_t)); -// memcpy(&os->payload, &s->payload, sizeof(z_bytes_t)); -// #if Z_FEATURE_MULTI_THREAD == 1 -// zp_mutex_lock(&r->_mutex); -// #endif -// _z_owned_sample_ring_push_force_drop(&r->_ring, os); -// #if Z_FEATURE_MULTI_THREAD == 1 -// zp_mutex_unlock(&r->_mutex); -// #endif -// } - -// z_owned_sample_t *z_sample_channel_ring_pull(z_owned_sample_ring_t *r) { -// #if Z_FEATURE_MULTI_THREAD == 1 -// zp_mutex_lock(&r->_mutex); -// #endif -// z_owned_sample_t *ret = _z_owned_sample_ring_pull(&r->_ring); -// #if Z_FEATURE_MULTI_THREAD == 1 -// zp_mutex_unlock(&r->_mutex); -// #endif -// return ret; -// } diff --git a/zenohpico.pc b/zenohpico.pc index 0f777182f..cc0cb80b6 100644 --- a/zenohpico.pc +++ b/zenohpico.pc @@ -3,6 +3,6 @@ prefix=/usr/local Name: zenohpico Description: URL: -Version: 0.11.20240321dev +Version: 0.11.20240322dev Cflags: -I${prefix}/include Libs: -L${prefix}/lib -lzenohpico From 0d76f92fb07839320b0b9f2fbe33248073442e1a Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Fri, 22 Mar 2024 18:17:36 +0100 Subject: [PATCH 14/21] Improve pull example --- examples/unix/c11/z_pull.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/examples/unix/c11/z_pull.c b/examples/unix/c11/z_pull.c index 3abdd2ad5..2b194abf8 100644 --- a/examples/unix/c11/z_pull.c +++ b/examples/unix/c11/z_pull.c @@ -22,9 +22,11 @@ int main(int argc, char **argv) { const char *keyexpr = "demo/example/**"; char *locator = NULL; + size_t interval = 5000; + size_t size = 3; int opt; - while ((opt = getopt(argc, argv, "k:e:")) != -1) { + while ((opt = getopt(argc, argv, "k:e:i:s:")) != -1) { switch (opt) { case 'k': keyexpr = optarg; @@ -32,8 +34,14 @@ int main(int argc, char **argv) { case 'e': locator = optarg; break; + case 'i': + interval = (size_t)atoi(optarg); + break; + case 's': + size = (size_t)atoi(optarg); + break; case '?': - if (optopt == 'k' || optopt == 'e') { + if (optopt == 'k' || optopt == 'e' || optopt == 'i' || optopt == 's') { fprintf(stderr, "Option -%c requires an argument.\n", optopt); } else { fprintf(stderr, "Unknown option `-%c'.\n", optopt); @@ -64,29 +72,25 @@ int main(int argc, char **argv) { } printf("Declaring Subscriber on '%s'...\n", keyexpr); - z_owned_sample_channel_t channel = z_sample_channel_ring_new(3); + z_owned_sample_channel_t channel = z_sample_channel_ring_new(size); z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(channel.send), NULL); if (!z_check(sub)) { printf("Unable to declare subscriber.\n"); return -1; } - printf("Enter any key to pull data or 'q' to quit...\n"); - char c = '\0'; - for (int ret = scanf("%c", &c); c != 'q'; ret = scanf("%c", &c)) { - // Try to receive one sample from the ring channel - z_owned_sample_t sample = z_sample_null(); - z_call(channel.recv, &sample); - // Check if we actually received something - if (z_check(sample)) { + printf("Pulling data every %zu ms... Ring size: %zd\n", interval, size); + z_owned_sample_t sample = z_sample_null(); + while (true) { + for (z_call(channel.recv, &sample); z_check(sample); z_call(channel.recv, &sample)) { z_owned_str_t keystr = z_keyexpr_to_string(z_loan(sample.keyexpr)); printf(">> [Subscriber] Pulled ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, sample.payload.start); z_drop(z_move(keystr)); - } else { - printf(">> [Subscriber] Nothing to pull...\n"); + z_drop(z_move(sample)); } - z_drop(z_move(sample)); + printf(">> [Subscriber] Nothing to pull... sleep for %zu ms\n", interval); + zp_sleep_ms(interval); } z_undeclare_subscriber(z_move(sub)); From b5546d51622339e64bdf1214a93901d60eff9328 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Sat, 23 Mar 2024 09:44:36 +0100 Subject: [PATCH 15/21] Fix return in void functions --- include/zenoh-pico/collections/fifo.h | 2 +- include/zenoh-pico/collections/lifo.h | 2 +- include/zenoh-pico/collections/ring.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/zenoh-pico/collections/fifo.h b/include/zenoh-pico/collections/fifo.h index 1deef22c5..23562e460 100644 --- a/include/zenoh-pico/collections/fifo.h +++ b/include/zenoh-pico/collections/fifo.h @@ -54,7 +54,7 @@ void _z_fifo_free(_z_fifo_t **xs, z_element_free_f f_f); static inline _Bool name##_fifo_is_full(const name##_fifo_t *r) { return _z_fifo_is_full(r); } \ static inline type *name##_fifo_push(name##_fifo_t *r, type *e) { return _z_fifo_push(r, (void *)e); } \ static inline void name##_fifo_push_drop(name##_fifo_t *r, type *e) { \ - return _z_fifo_push_drop(r, (void *)e, name##_elem_free); \ + _z_fifo_push_drop(r, (void *)e, name##_elem_free); \ } \ static inline type *name##_fifo_pull(name##_fifo_t *r) { return (type *)_z_fifo_pull(r); } \ static inline void name##_fifo_clear(name##_fifo_t *r) { _z_fifo_clear(r, name##_elem_free); } \ diff --git a/include/zenoh-pico/collections/lifo.h b/include/zenoh-pico/collections/lifo.h index 0a2da7023..caba25d18 100644 --- a/include/zenoh-pico/collections/lifo.h +++ b/include/zenoh-pico/collections/lifo.h @@ -55,7 +55,7 @@ void _z_lifo_free(_z_lifo_t **xs, z_element_free_f f_f); static inline _Bool name##_lifo_is_full(const name##_lifo_t *r) { return _z_lifo_is_full(r); } \ static inline type *name##_lifo_push(name##_lifo_t *r, type *e) { return _z_lifo_push(r, (void *)e); } \ static inline void name##_lifo_push_drop(name##_lifo_t *r, type *e) { \ - return _z_lifo_push_drop(r, (void *)e, name##_elem_free); \ + _z_lifo_push_drop(r, (void *)e, name##_elem_free); \ } \ static inline type *name##_lifo_pull(name##_lifo_t *r) { return (type *)_z_lifo_pull(r); } \ static inline void name##_lifo_clear(name##_lifo_t *r) { _z_lifo_clear(r, name##_elem_free); } \ diff --git a/include/zenoh-pico/collections/ring.h b/include/zenoh-pico/collections/ring.h index 4bda2a7cc..3cdcc057c 100644 --- a/include/zenoh-pico/collections/ring.h +++ b/include/zenoh-pico/collections/ring.h @@ -59,7 +59,7 @@ void _z_ring_free(_z_ring_t **xs, z_element_free_f f_f); static inline type *name##_ring_push(name##_ring_t *r, type *e) { return _z_ring_push(r, (void *)e); } \ static inline type *name##_ring_push_force(name##_ring_t *r, type *e) { return _z_ring_push_force(r, (void *)e); } \ static inline void name##_ring_push_force_drop(name##_ring_t *r, type *e) { \ - return _z_ring_push_force_drop(r, (void *)e, name##_elem_free); \ + _z_ring_push_force_drop(r, (void *)e, name##_elem_free); \ } \ static inline type *name##_ring_pull(name##_ring_t *r) { return (type *)_z_ring_pull(r); } \ static inline void name##_ring_clear(name##_ring_t *r) { _z_ring_clear(r, name##_elem_free); } \ From c736568491f3fd9b96b33a61ab57f45dd97a5761 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Sat, 23 Mar 2024 09:47:40 +0100 Subject: [PATCH 16/21] Fix prototype --- include/zenoh-pico/api/handlers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zenoh-pico/api/handlers.h b/include/zenoh-pico/api/handlers.h index 928a9fa59..06048321e 100644 --- a/include/zenoh-pico/api/handlers.h +++ b/include/zenoh-pico/api/handlers.h @@ -87,7 +87,7 @@ typedef struct { z_owned_closure_owned_sample_t recv; } z_owned_sample_channel_t; -z_owned_sample_channel_t z_owned_sample_channel_null(); +z_owned_sample_channel_t z_owned_sample_channel_null(void); int8_t z_closure_owned_sample_call(z_owned_closure_owned_sample_t *recv, z_owned_sample_t *dst); // -- Ring From 2e24b297f8bb1ded7d95dbd179c059b83600b831 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Sat, 23 Mar 2024 09:51:53 +0100 Subject: [PATCH 17/21] Fix newline at end of the file --- include/zenoh-pico/api/handlers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zenoh-pico/api/handlers.h b/include/zenoh-pico/api/handlers.h index 06048321e..ffd41c855 100644 --- a/include/zenoh-pico/api/handlers.h +++ b/include/zenoh-pico/api/handlers.h @@ -120,4 +120,4 @@ z_owned_sample_channel_t z_sample_channel_fifo_new(size_t capacity); void z_sample_channel_fifo_push(const z_sample_t *src, void *context); int8_t z_sample_channel_fifo_pull(z_owned_sample_t *dst, void *context); -#endif // INCLUDE_ZENOH_PICO_API_HANDLERS_H \ No newline at end of file +#endif // INCLUDE_ZENOH_PICO_API_HANDLERS_H From 917169520ca258a8878da940160e476ea0510cdd Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Sat, 23 Mar 2024 09:52:35 +0100 Subject: [PATCH 18/21] Fix windows examples target --- examples/CMakeLists.txt | 4 ++-- zenohpico.pc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a70eb7691..b523f8f45 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -55,9 +55,9 @@ elseif(MSVC) add_example(z_pub windows/z_pub.c) add_example(z_pub_st windows/z_pub_st.c) add_example(z_sub windows/z_sub.c) - add_example(z_sub windows/z_sub_channel.c) + add_example(z_sub_channel windows/z_sub_channel.c) add_example(z_sub_st windows/z_sub_st.c) - add_example(z_sub_channel windows/z_pull.c) + add_example(z_pull windows/z_pull.c) add_example(z_get windows/z_get.c) add_example(z_queryable windows/z_queryable.c) add_example(z_info windows/z_info.c) diff --git a/zenohpico.pc b/zenohpico.pc index cc0cb80b6..1643bd7bb 100644 --- a/zenohpico.pc +++ b/zenohpico.pc @@ -3,6 +3,6 @@ prefix=/usr/local Name: zenohpico Description: URL: -Version: 0.11.20240322dev +Version: 0.11.20240323dev Cflags: -I${prefix}/include Libs: -L${prefix}/lib -lzenohpico From c2d6d275e5a0548b7962d031511c410e075c7f87 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Sat, 23 Mar 2024 10:02:37 +0100 Subject: [PATCH 19/21] Remove unexisting windows z_sub_channel from CMAke --- examples/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b523f8f45..08f1e5916 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -55,7 +55,6 @@ elseif(MSVC) add_example(z_pub windows/z_pub.c) add_example(z_pub_st windows/z_pub_st.c) add_example(z_sub windows/z_sub.c) - add_example(z_sub_channel windows/z_sub_channel.c) add_example(z_sub_st windows/z_sub_st.c) add_example(z_pull windows/z_pull.c) add_example(z_get windows/z_get.c) From 84f22e6c4440c3d92a320b33b8734e144410d185 Mon Sep 17 00:00:00 2001 From: Luca Cominardi Date: Sat, 23 Mar 2024 10:07:01 +0100 Subject: [PATCH 20/21] Remove unexisting unix c99 z_sub_channel from CMAke --- examples/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 08f1e5916..1924dad9e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -24,7 +24,6 @@ if(UNIX) add_example(z_pub unix/c99/z_pub.c) add_example(z_pub_st unix/c99/z_pub_st.c) add_example(z_sub unix/c99/z_sub.c) - add_example(z_sub_channel unix/c99/z_sub_channel.c) add_example(z_sub_st unix/c99/z_sub_st.c) add_example(z_pull unix/c99/z_pull.c) add_example(z_get unix/c99/z_get.c) From 3559b3ee6bacdde1f04ebeafd41cda6bfa8c3fe9 Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 5 Apr 2024 12:48:41 +0200 Subject: [PATCH 21/21] Rework owned sample (#391) * Owned sample draft * Continue owned sample implementation * [skip ci] Channel macro draft * [skip ci] Fix element copy * Add fifo channel * Add channel clean up and some refactoring/fixes * Syntax fix * Refactoring, cleanup * Rename elem copy to move * Improve naming * TODO resolving * Add channel tests * Apply review feedback * Add encoding copy --- CMakeLists.txt | 6 +- examples/unix/c11/z_pull.c | 9 +- examples/unix/c11/z_sub_channel.c | 9 +- include/zenoh-pico/api/handlers.h | 157 ++++++++------------ include/zenoh-pico/api/macros.h | 53 ++++--- include/zenoh-pico/api/primitives.h | 26 ++++ include/zenoh-pico/api/types.h | 21 +++ include/zenoh-pico/collections/element.h | 1 + include/zenoh-pico/collections/fifo_mt.h | 43 ++++++ include/zenoh-pico/collections/ring_mt.h | 41 ++++++ include/zenoh-pico/net/memory.h | 2 + include/zenoh-pico/protocol/core.h | 3 + src/api/api.c | 25 +++- src/api/handlers.c | 175 ++--------------------- src/collections/fifo_mt.c | 115 +++++++++++++++ src/collections/ring.c | 1 + src/collections/ring_mt.c | 97 +++++++++++++ src/net/memory.c | 21 +++ tests/z_channels_test.c | 118 +++++++++++++++ 19 files changed, 632 insertions(+), 291 deletions(-) create mode 100644 include/zenoh-pico/collections/fifo_mt.h create mode 100644 include/zenoh-pico/collections/ring_mt.h create mode 100644 src/collections/fifo_mt.c create mode 100644 src/collections/ring_mt.c create mode 100644 tests/z_channels_test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index dd7f6e40d..704c4b4e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -331,6 +331,7 @@ if(UNIX OR MSVC) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests") add_executable(z_data_struct_test ${PROJECT_SOURCE_DIR}/tests/z_data_struct_test.c) + add_executable(z_channels_test ${PROJECT_SOURCE_DIR}/tests/z_channels_test.c) add_executable(z_collections_test ${PROJECT_SOURCE_DIR}/tests/z_collections_test.c) add_executable(z_endpoint_test ${PROJECT_SOURCE_DIR}/tests/z_endpoint_test.c) add_executable(z_iobuf_test ${PROJECT_SOURCE_DIR}/tests/z_iobuf_test.c) @@ -344,6 +345,7 @@ if(UNIX OR MSVC) add_executable(z_perf_rx ${PROJECT_SOURCE_DIR}/tests/z_perf_rx.c) target_link_libraries(z_data_struct_test ${Libname}) + target_link_libraries(z_channels_test ${Libname}) target_link_libraries(z_collections_test ${Libname}) target_link_libraries(z_endpoint_test ${Libname}) target_link_libraries(z_iobuf_test ${Libname}) @@ -363,6 +365,8 @@ if(UNIX OR MSVC) enable_testing() add_test(z_data_struct_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/z_data_struct_test) + add_test(z_channels_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/z_channels_test) + add_test(z_collections_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/z_collections_test) add_test(z_endpoint_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/z_endpoint_test) add_test(z_iobuf_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/z_iobuf_test) add_test(z_msgcodec_test ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/z_msgcodec_test) @@ -477,4 +481,4 @@ if(PACKAGING) include(CPack) endif() -endif() \ No newline at end of file +endif() diff --git a/examples/unix/c11/z_pull.c b/examples/unix/c11/z_pull.c index 2b194abf8..c6bb58f20 100644 --- a/examples/unix/c11/z_pull.c +++ b/examples/unix/c11/z_pull.c @@ -72,7 +72,7 @@ int main(int argc, char **argv) { } printf("Declaring Subscriber on '%s'...\n", keyexpr); - z_owned_sample_channel_t channel = z_sample_channel_ring_new(size); + z_owned_sample_ring_channel_t channel = z_sample_ring_channel_new(size); z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(channel.send), NULL); if (!z_check(sub)) { printf("Unable to declare subscriber.\n"); @@ -83,9 +83,9 @@ int main(int argc, char **argv) { z_owned_sample_t sample = z_sample_null(); while (true) { for (z_call(channel.recv, &sample); z_check(sample); z_call(channel.recv, &sample)) { - z_owned_str_t keystr = z_keyexpr_to_string(z_loan(sample.keyexpr)); - printf(">> [Subscriber] Pulled ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, - sample.payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_loan(sample).keyexpr); + printf(">> [Subscriber] Pulled ('%s': '%.*s')\n", z_loan(keystr), (int)z_loan(sample).payload.len, + z_loan(sample).payload.start); z_drop(z_move(keystr)); z_drop(z_move(sample)); } @@ -94,6 +94,7 @@ int main(int argc, char **argv) { } z_undeclare_subscriber(z_move(sub)); + z_drop(z_move(channel)); // Stop read and lease tasks for zenoh-pico zp_stop_read_task(z_loan(s)); diff --git a/examples/unix/c11/z_sub_channel.c b/examples/unix/c11/z_sub_channel.c index 005fc60e4..43548d1ba 100644 --- a/examples/unix/c11/z_sub_channel.c +++ b/examples/unix/c11/z_sub_channel.c @@ -64,7 +64,7 @@ int main(int argc, char **argv) { } printf("Declaring Subscriber on '%s'...\n", keyexpr); - z_owned_sample_channel_t channel = z_sample_channel_fifo_new(3); + z_owned_sample_fifo_channel_t channel = z_sample_fifo_channel_new(3); z_owned_subscriber_t sub = z_declare_subscriber(z_loan(s), z_keyexpr(keyexpr), z_move(channel.send), NULL); if (!z_check(sub)) { printf("Unable to declare subscriber.\n"); @@ -73,15 +73,16 @@ int main(int argc, char **argv) { z_owned_sample_t sample = z_sample_null(); for (z_call(channel.recv, &sample); z_check(sample); z_call(channel.recv, &sample)) { - z_owned_str_t keystr = z_keyexpr_to_string(z_loan(sample.keyexpr)); - printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)sample.payload.len, - sample.payload.start); + z_owned_str_t keystr = z_keyexpr_to_string(z_loan(sample).keyexpr); + printf(">> [Subscriber] Received ('%s': '%.*s')\n", z_loan(keystr), (int)z_loan(sample).payload.len, + z_loan(sample).payload.start); z_drop(z_move(keystr)); z_drop(z_move(sample)); sample = z_sample_null(); } z_undeclare_subscriber(z_move(sub)); + z_drop(z_move(channel)); // Stop read and lease tasks for zenoh-pico zp_stop_read_task(z_loan(s)); diff --git a/include/zenoh-pico/api/handlers.h b/include/zenoh-pico/api/handlers.h index ffd41c855..d48c2e8fc 100644 --- a/include/zenoh-pico/api/handlers.h +++ b/include/zenoh-pico/api/handlers.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2022 ZettaScale Technology +// Copyright (c) 2024 ZettaScale Technology // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License 2.0 which is available at @@ -15,109 +15,74 @@ #define INCLUDE_ZENOH_PICO_API_HANDLERS_H #include -#include #include "zenoh-pico/api/macros.h" #include "zenoh-pico/api/types.h" #include "zenoh-pico/collections/element.h" -#include "zenoh-pico/collections/fifo.h" -#include "zenoh-pico/collections/ring.h" -#include "zenoh-pico/system/platform.h" +#include "zenoh-pico/collections/fifo_mt.h" +#include "zenoh-pico/collections/ring_mt.h" +#include "zenoh-pico/utils/logging.h" -// -- Owned sample -// @TODO: define it via dedicated macros and move it to the appropriate place in types. -typedef struct { - z_owned_keyexpr_t keyexpr; - z_bytes_t payload; - // @TODO: implement the rest of the fields -} z_owned_sample_t; - -static inline z_owned_sample_t z_sample_null(void) { - z_owned_sample_t sample; - sample.keyexpr = z_keyexpr_null(); - sample.payload = z_bytes_null(); - return sample; -} - -static inline z_owned_sample_t *z_sample_move(z_owned_sample_t *sample) { return sample; } -static inline z_owned_sample_t *z_sample_loan(z_owned_sample_t *sample) { return sample; } - -static inline bool z_sample_check(const z_owned_sample_t *sample) { - return z_keyexpr_check(&sample->keyexpr) && z_bytes_check(&sample->payload); -} - -static inline z_owned_sample_t z_sample_to_owned(const z_sample_t *src) { - z_owned_sample_t dst = z_sample_null(); - - if (src == NULL) { - return dst; - } - - _z_keyexpr_t *ke = (_z_keyexpr_t *)zp_malloc(sizeof(_z_keyexpr_t)); - if (ke == NULL) { - return dst; - } - *ke = _z_keyexpr_duplicate(src->keyexpr); - dst.keyexpr._value = ke; - dst.payload = _z_bytes_duplicate(&src->payload); - - return dst; -} - -static inline void z_sample_drop(z_owned_sample_t *s) { - if (s != NULL) { - z_keyexpr_drop(&s->keyexpr); - _z_bytes_clear(&s->payload); - } -} - -_Z_ELEM_DEFINE(_z_owned_sample, z_owned_sample_t, _z_noop_size, z_sample_drop, _z_noop_copy) +// -- Samples handler +void _z_owned_sample_move(z_owned_sample_t *dst, const z_owned_sample_t *src); +z_owned_sample_t *_z_sample_to_owned_ptr(const _z_sample_t *src); // -- Channel -typedef int8_t (*_z_owned_sample_handler_t)(z_owned_sample_t *dst, void *context); - -typedef struct { - void *context; - _z_owned_sample_handler_t call; - _z_dropper_handler_t drop; -} z_owned_closure_owned_sample_t; - -typedef struct { - z_owned_closure_sample_t send; - z_owned_closure_owned_sample_t recv; -} z_owned_sample_channel_t; - -z_owned_sample_channel_t z_owned_sample_channel_null(void); -int8_t z_closure_owned_sample_call(z_owned_closure_owned_sample_t *recv, z_owned_sample_t *dst); - -// -- Ring -_Z_RING_DEFINE(_z_owned_sample, z_owned_sample_t) - -typedef struct { - _z_owned_sample_ring_t _ring; -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_t _mutex; -#endif -} z_owned_sample_ring_t; - -z_owned_sample_channel_t z_sample_channel_ring_new(size_t capacity); -void z_sample_channel_ring_push(const z_sample_t *src, void *context); -int8_t z_sample_channel_ring_pull(z_owned_sample_t *dst, void *context); - -// -- Fifo -_Z_FIFO_DEFINE(_z_owned_sample, z_owned_sample_t) +#define _Z_CHANNEL_DEFINE(name, send_closure_name, recv_closure_name, send_type, recv_type, collection_type, \ + collection_new_f, collection_free_f, collection_push_f, collection_pull_f, elem_move_f, \ + elem_convert_f, elem_free_f) \ + typedef struct { \ + z_owned_##send_closure_name##_t send; \ + z_owned_##recv_closure_name##_t recv; \ + collection_type *collection; \ + } z_owned_##name##_t; \ + \ + static inline void _z_##name##_elem_free(void **elem) { \ + elem_free_f((recv_type *)*elem); \ + *elem = NULL; \ + } \ + static inline void _z_##name##_elem_move(void *dst, const void *src) { \ + elem_move_f((recv_type *)dst, (const recv_type *)src); \ + } \ + static inline void _z_##name##_send(const send_type *elem, void *context) { \ + void *internal_elem = elem_convert_f(elem); \ + if (internal_elem == NULL) { \ + return; \ + } \ + int8_t ret = collection_push_f(internal_elem, context, _z_##name##_elem_free); \ + if (ret != _Z_RES_OK) { \ + _Z_ERROR("%s failed: %i", #collection_push_f, ret); \ + } \ + } \ + static inline void _z_##name##_recv(recv_type *elem, void *context) { \ + int8_t ret = collection_pull_f(elem, context, _z_##name##_elem_move); \ + if (ret != _Z_RES_OK) { \ + _Z_ERROR("%s failed: %i", #collection_pull_f, ret); \ + } \ + } \ + \ + static inline z_owned_##name##_t z_##name##_new(size_t capacity) { \ + z_owned_##name##_t channel; \ + channel.collection = collection_new_f(capacity); \ + channel.send = z_##send_closure_name(_z_##name##_send, NULL, channel.collection); \ + channel.recv = z_##recv_closure_name(_z_##name##_recv, NULL, channel.collection); \ + return channel; \ + } \ + static inline z_owned_##name##_t *z_##name##_move(z_owned_##name##_t *val) { return val; } \ + static inline void z_##name##_drop(z_owned_##name##_t *channel) { \ + collection_free_f(channel->collection, _z_##name##_elem_free); \ + z_##send_closure_name##_drop(&channel->send); \ + z_##recv_closure_name##_drop(&channel->recv); \ + } -typedef struct { - _z_owned_sample_fifo_t _fifo; -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_t _mutex; - zp_condvar_t _cv_not_full; - zp_condvar_t _cv_not_empty; -#endif -} z_owned_sample_fifo_t; +// z_owned_sample_ring_channel_t +_Z_CHANNEL_DEFINE(sample_ring_channel, closure_sample, closure_owned_sample, z_sample_t, z_owned_sample_t, _z_ring_mt_t, + _z_ring_mt_new, _z_ring_mt_free, _z_ring_mt_push, _z_ring_mt_pull, _z_owned_sample_move, + _z_sample_to_owned_ptr, z_sample_drop) -z_owned_sample_channel_t z_sample_channel_fifo_new(size_t capacity); -void z_sample_channel_fifo_push(const z_sample_t *src, void *context); -int8_t z_sample_channel_fifo_pull(z_owned_sample_t *dst, void *context); +// z_owned_sample_fifo_channel_t +_Z_CHANNEL_DEFINE(sample_fifo_channel, closure_sample, closure_owned_sample, z_sample_t, z_owned_sample_t, _z_fifo_mt_t, + _z_fifo_mt_new, _z_fifo_mt_free, _z_fifo_mt_push, _z_fifo_mt_pull, _z_owned_sample_move, + _z_sample_to_owned_ptr, z_sample_drop) #endif // INCLUDE_ZENOH_PICO_API_HANDLERS_H diff --git a/include/zenoh-pico/api/macros.h b/include/zenoh-pico/api/macros.h index 5ad7478b5..e64f1f84a 100644 --- a/include/zenoh-pico/api/macros.h +++ b/include/zenoh-pico/api/macros.h @@ -65,10 +65,13 @@ z_owned_str_array_t * : z_str_array_drop, \ z_owned_sample_t * : z_sample_drop, \ z_owned_closure_sample_t * : z_closure_sample_drop, \ + z_owned_closure_owned_sample_t * : z_closure_owned_sample_drop, \ z_owned_closure_query_t * : z_closure_query_drop, \ z_owned_closure_reply_t * : z_closure_reply_drop, \ z_owned_closure_hello_t * : z_closure_hello_drop, \ - z_owned_closure_zid_t * : z_closure_zid_drop \ + z_owned_closure_zid_t * : z_closure_zid_drop, \ + z_owned_sample_ring_channel_t * : z_sample_ring_channel_drop, \ + z_owned_sample_fifo_channel_t * : z_sample_fifo_channel_drop \ )(x) /** @@ -124,23 +127,26 @@ * Returns the instance associated with `x`. */ #define z_move(x) _Generic((x), \ - z_owned_keyexpr_t : z_keyexpr_move, \ - z_owned_config_t : z_config_move, \ - z_owned_scouting_config_t : z_scouting_config_move, \ - z_owned_session_t : z_session_move, \ - z_owned_subscriber_t : z_subscriber_move, \ - z_owned_publisher_t : z_publisher_move, \ - z_owned_queryable_t : z_queryable_move, \ - z_owned_reply_t : z_reply_move, \ - z_owned_hello_t : z_hello_move, \ - z_owned_str_t : z_str_move, \ - z_owned_str_array_t : z_str_array_move, \ - z_owned_closure_sample_t : z_closure_sample_move, \ - z_owned_closure_query_t : z_closure_query_move, \ - z_owned_closure_reply_t : z_closure_reply_move, \ - z_owned_closure_hello_t : z_closure_hello_move, \ - z_owned_closure_zid_t : z_closure_zid_move, \ - z_owned_sample_t : z_sample_move \ + z_owned_keyexpr_t : z_keyexpr_move, \ + z_owned_config_t : z_config_move, \ + z_owned_scouting_config_t : z_scouting_config_move, \ + z_owned_session_t : z_session_move, \ + z_owned_subscriber_t : z_subscriber_move, \ + z_owned_publisher_t : z_publisher_move, \ + z_owned_queryable_t : z_queryable_move, \ + z_owned_reply_t : z_reply_move, \ + z_owned_hello_t : z_hello_move, \ + z_owned_str_t : z_str_move, \ + z_owned_str_array_t : z_str_array_move, \ + z_owned_closure_sample_t : z_closure_sample_move, \ + z_owned_closure_owned_sample_t : z_closure_owned_sample_move, \ + z_owned_closure_query_t : z_closure_query_move, \ + z_owned_closure_reply_t : z_closure_reply_move, \ + z_owned_closure_hello_t : z_closure_hello_move, \ + z_owned_closure_zid_t : z_closure_zid_move, \ + z_owned_sample_t : z_sample_move, \ + z_owned_sample_ring_channel_t : z_sample_ring_channel_move, \ + z_owned_sample_fifo_channel_t : z_sample_fifo_channel_move \ )(&x) /** @@ -183,6 +189,7 @@ z_owned_hello_t * : z_hello_null, \ z_owned_str_t * : z_str_null, \ z_owned_closure_sample_t * : z_closure_sample_null, \ + z_owned_closure_owned_sample_t * : z_closure_owned_sample_null, \ z_owned_closure_query_t * : z_closure_query_null, \ z_owned_closure_reply_t * : z_closure_reply_null, \ z_owned_closure_hello_t * : z_closure_hello_null, \ @@ -242,10 +249,13 @@ template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; +template<> struct zenoh_drop_type { typedef void type; }; template<> inline int8_t z_drop(z_owned_session_t* v) { return z_close(v); } template<> inline int8_t z_drop(z_owned_publisher_t* v) { return z_undeclare_publisher(v); } @@ -258,10 +268,13 @@ template<> inline void z_drop(z_owned_reply_t* v) { z_reply_drop(v); } template<> inline void z_drop(z_owned_hello_t* v) { z_hello_drop(v); } template<> inline void z_drop(z_owned_str_t* v) { z_str_drop(v); } template<> inline void z_drop(z_owned_closure_sample_t* v) { z_closure_sample_drop(v); } +template<> inline void z_drop(z_owned_closure_owned_sample_t* v) { z_closure_owned_sample_drop(v); } template<> inline void z_drop(z_owned_closure_query_t* v) { z_closure_query_drop(v); } template<> inline void z_drop(z_owned_closure_reply_t* v) { z_closure_reply_drop(v); } template<> inline void z_drop(z_owned_closure_hello_t* v) { z_closure_hello_drop(v); } template<> inline void z_drop(z_owned_closure_zid_t* v) { z_closure_zid_drop(v); } +template<> inline void z_drop(z_owned_sample_ring_channel_t* v) { z_owned_sample_ring_channel_drop(v); } +template<> inline void z_drop(z_owned_sample_fifo_channel_t* v) { z_owned_sample_fifo_channel_drop(v); } inline void z_null(z_owned_session_t& v) { v = z_session_null(); } inline void z_null(z_owned_publisher_t& v) { v = z_publisher_null(); } @@ -274,6 +287,7 @@ inline void z_null(z_owned_reply_t& v) { v = z_reply_null(); } inline void z_null(z_owned_hello_t& v) { v = z_hello_null(); } inline void z_null(z_owned_str_t& v) { v = z_str_null(); } inline void z_null(z_owned_closure_sample_t& v) { v = z_closure_sample_null(); } +inline void z_null(z_owned_clusure_owned_sample_t& v) { v = z_closure_owned_sample_null(); } inline void z_null(z_owned_closure_query_t& v) { v = z_closure_query_null(); } inline void z_null(z_owned_closure_reply_t& v) { v = z_closure_reply_null(); } inline void z_null(z_owned_closure_hello_t& v) { v = z_closure_hello_null(); } @@ -291,9 +305,12 @@ inline bool z_check(const z_owned_queryable_t& v) { return z_queryable_check(&v) inline bool z_check(const z_owned_reply_t& v) { return z_reply_check(&v); } inline bool z_check(const z_owned_hello_t& v) { return z_hello_check(&v); } inline bool z_check(const z_owned_str_t& v) { return z_str_check(&v); } +inline bool z_check(const z_owned_str_t& v) { return z_sample_check(&v); } inline void z_call(const z_owned_closure_sample_t &closure, const z_sample_t *sample) { z_closure_sample_call(&closure, sample); } +inline void z_call(const z_owned_closure_owned_sample_t &closure, const z_sample_t *sample) + { z_closure_owned_sample_call(&closure, sample); } inline void z_call(const z_owned_closure_query_t &closure, const z_query_t *query) { z_closure_query_call(&closure, query); } inline void z_call(const z_owned_closure_reply_t &closure, z_owned_reply_t *sample) diff --git a/include/zenoh-pico/api/primitives.h b/include/zenoh-pico/api/primitives.h index a72878b99..022e1c729 100644 --- a/include/zenoh-pico/api/primitives.h +++ b/include/zenoh-pico/api/primitives.h @@ -564,6 +564,30 @@ z_keyexpr_t z_query_keyexpr(const z_query_t *query); */ z_owned_closure_sample_t z_closure_sample(_z_data_handler_t call, _z_dropper_handler_t drop, void *context); +/** + * Return a new sample closure. + * It consists on a structure that contains all the elements for stateful, memory-leak-free callbacks. + * + * Like all ``z_owned_X_t``, an instance will be destroyed by any function which takes a mutable pointer to said + * instance, as this implies the instance's inners were moved. To make this fact more obvious when reading your code, + * consider using ``z_move(val)`` instead of ``&val`` as the argument. After a ``z_move``, ``val`` will still exist, but + * will no longer be valid. The destructors are double-drop-safe, but other functions will still trust that your ``val`` + * is valid. + * + * To check if ``val`` is still valid, you may use ``z_closure_owned_sample_check(&val)`` or ``z_check(val)`` if your + * compiler supports ``_Generic``, which will return ``true`` if ``val`` is valid, or ``false`` otherwise. + * + * Parameters: + * call: the typical callback function. ``context`` will be passed as its last argument. + * drop: allows the callback's state to be freed. ``context`` will be passed as its last argument. + * context: a pointer to an arbitrary state. + * + * Returns: + * Returns a new sample closure. + */ +z_owned_closure_owned_sample_t z_closure_owned_sample(_z_owned_sample_handler_t call, _z_dropper_handler_t drop, + void *context); + /** * Return a new query closure. * It consists on a structure that contains all the elements for stateful, memory-leak-free callbacks. @@ -692,6 +716,7 @@ _OWNED_FUNCTIONS(z_queryable_t, z_owned_queryable_t, queryable) _OWNED_FUNCTIONS(z_hello_t, z_owned_hello_t, hello) _OWNED_FUNCTIONS(z_reply_t, z_owned_reply_t, reply) _OWNED_FUNCTIONS(z_str_array_t, z_owned_str_array_t, str_array) +_OWNED_FUNCTIONS(z_sample_t, z_owned_sample_t, sample) #define _OWNED_FUNCTIONS_CLOSURE(ownedtype, name) \ _Bool z_##name##_check(const ownedtype *val); \ @@ -701,6 +726,7 @@ _OWNED_FUNCTIONS(z_str_array_t, z_owned_str_array_t, str_array) _OWNED_FUNCTIONS_CLOSURE(z_owned_closure_sample_t, closure_sample) _OWNED_FUNCTIONS_CLOSURE(z_owned_closure_query_t, closure_query) +_OWNED_FUNCTIONS_CLOSURE(z_owned_closure_owned_sample_t, closure_owned_sample) _OWNED_FUNCTIONS_CLOSURE(z_owned_closure_reply_t, closure_reply) _OWNED_FUNCTIONS_CLOSURE(z_owned_closure_hello_t, closure_hello) _OWNED_FUNCTIONS_CLOSURE(z_owned_closure_zid_t, closure_zid) diff --git a/include/zenoh-pico/api/types.h b/include/zenoh-pico/api/types.h index 3c9eda0b9..4a39ccaec 100644 --- a/include/zenoh-pico/api/types.h +++ b/include/zenoh-pico/api/types.h @@ -401,6 +401,7 @@ typedef struct { * z_timestamp_t timestamp: The timestamp of this data sample. */ typedef _z_sample_t z_sample_t; +_OWNED_TYPE_PTR(z_sample_t, sample) /** * Represents the content of a `hello` message returned by a zenoh entity as a reply to a `scout` message. @@ -448,6 +449,7 @@ _Bool z_str_array_is_empty(const z_str_array_t *a); _OWNED_TYPE_PTR(z_str_array_t, str_array) typedef void (*_z_dropper_handler_t)(void *arg); +typedef void (*_z_owned_sample_handler_t)(z_owned_sample_t *sample, void *arg); /** * Represents the sample closure. @@ -467,6 +469,25 @@ typedef struct { void z_closure_sample_call(const z_owned_closure_sample_t *closure, const z_sample_t *sample); +/** + * Represents the owned sample closure. + * + * A closure is a structure that contains all the elements for stateful, memory-leak-free callbacks. + * + * Members: + * _z_owned_sample_handler_t call: `void *call(const struct z_owned_sample_t*, const void *context)` is the callback + * function. + * _z_dropper_handler_t drop: `void *drop(void*)` allows the callback's state to be freed. void *context: a + * pointer to an arbitrary state. + */ +typedef struct { + void *context; + _z_owned_sample_handler_t call; + _z_dropper_handler_t drop; +} z_owned_closure_owned_sample_t; + +void z_closure_owned_sample_call(const z_owned_closure_owned_sample_t *closure, z_owned_sample_t *sample); + /** * Represents the query callback closure. * diff --git a/include/zenoh-pico/collections/element.h b/include/zenoh-pico/collections/element.h index 5e8997954..39583abe4 100644 --- a/include/zenoh-pico/collections/element.h +++ b/include/zenoh-pico/collections/element.h @@ -25,6 +25,7 @@ typedef size_t (*z_element_size_f)(void *e); typedef void (*z_element_clear_f)(void *e); typedef void (*z_element_free_f)(void **e); typedef void (*z_element_copy_f)(void *dst, const void *src); +typedef void (*z_element_move_f)(void *dst, const void *src); typedef void *(*z_element_clone_f)(const void *e); typedef _Bool (*z_element_eq_f)(const void *left, const void *right); diff --git a/include/zenoh-pico/collections/fifo_mt.h b/include/zenoh-pico/collections/fifo_mt.h new file mode 100644 index 000000000..bcf8d700c --- /dev/null +++ b/include/zenoh-pico/collections/fifo_mt.h @@ -0,0 +1,43 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#ifndef ZENOH_PICO_COLLECTIONS_FIFO_MT_H +#define ZENOH_PICO_COLLECTIONS_FIFO_MT_H + +#include + +#include "zenoh-pico/collections/element.h" +#include "zenoh-pico/collections/fifo.h" +#include "zenoh-pico/system/platform.h" + +/*-------- Fifo Buffer Multithreaded --------*/ +typedef struct { + _z_fifo_t _fifo; +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_t _mutex; + zp_condvar_t _cv_not_full; + zp_condvar_t _cv_not_empty; +#endif +} _z_fifo_mt_t; + +int8_t _z_fifo_mti_init(size_t capacity); +_z_fifo_mt_t *_z_fifo_mt_new(size_t capacity); + +void _z_fifo_mt_clear(_z_fifo_mt_t *fifo, z_element_free_f free_f); +void _z_fifo_mt_free(_z_fifo_mt_t *fifo, z_element_free_f free_f); + +int8_t _z_fifo_mt_push(const void *src, void *context, z_element_free_f element_free); + +int8_t _z_fifo_mt_pull(void *dst, void *context, z_element_move_f element_move); + +#endif // ZENOH_PICO_COLLECTIONS_FIFO_MT_H diff --git a/include/zenoh-pico/collections/ring_mt.h b/include/zenoh-pico/collections/ring_mt.h new file mode 100644 index 000000000..98a413e20 --- /dev/null +++ b/include/zenoh-pico/collections/ring_mt.h @@ -0,0 +1,41 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#ifndef ZENOH_PICO_COLLECTIONS_RING_MT_H +#define ZENOH_PICO_COLLECTIONS_RING_MT_H + +#include + +#include "zenoh-pico/collections/element.h" +#include "zenoh-pico/collections/fifo.h" +#include "zenoh-pico/system/platform.h" + +/*-------- Ring Buffer Multithreaded --------*/ +typedef struct { + _z_ring_t _ring; +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_t _mutex; +#endif +} _z_ring_mt_t; + +int8_t _z_ring_mt_init(_z_ring_mt_t *ring, size_t capacity); +_z_ring_mt_t *_z_ring_mt_new(size_t capacity); + +void _z_ring_mt_clear(_z_ring_mt_t *ring, z_element_free_f free_f); +void _z_ring_mt_free(_z_ring_mt_t *ring, z_element_free_f free_f); + +int8_t _z_ring_mt_push(const void *src, void *context, z_element_free_f element_free); + +int8_t _z_ring_mt_pull(void *dst, void *context, z_element_move_f element_move); + +#endif // ZENOH_PICO_COLLECTIONS_RING_MT_H diff --git a/include/zenoh-pico/net/memory.h b/include/zenoh-pico/net/memory.h index 750bcff4d..cf578faf3 100644 --- a/include/zenoh-pico/net/memory.h +++ b/include/zenoh-pico/net/memory.h @@ -26,5 +26,7 @@ void _z_sample_move(_z_sample_t *dst, _z_sample_t *src); void _z_sample_clear(_z_sample_t *sample); void _z_sample_free(_z_sample_t **sample); +void _z_sample_copy(_z_sample_t *dst, const _z_sample_t *src); +_z_sample_t _z_sample_duplicate(const _z_sample_t *src); #endif /* ZENOH_PICO_MEMORY_NETAPI_H */ diff --git a/include/zenoh-pico/protocol/core.h b/include/zenoh-pico/protocol/core.h index 113566319..c8a27ecd2 100644 --- a/include/zenoh-pico/protocol/core.h +++ b/include/zenoh-pico/protocol/core.h @@ -231,6 +231,9 @@ typedef struct { z_attachment_t attachment; #endif } _z_sample_t; +static inline bool _z_sample_check(const _z_sample_t *sample) { + return _z_keyexpr_check(sample->keyexpr) && _z_bytes_check(sample->payload); +} /** * Represents a Zenoh value. diff --git a/src/api/api.c b/src/api/api.c index 1369c82b1..19527e0a5 100644 --- a/src/api/api.c +++ b/src/api/api.c @@ -312,31 +312,37 @@ _Bool z_value_is_initialized(z_value_t *value) { } void z_closure_sample_call(const z_owned_closure_sample_t *closure, const z_sample_t *sample) { - if (closure->call) { + if (closure->call != NULL) { + (closure->call)(sample, closure->context); + } +} + +void z_closure_owned_sample_call(const z_owned_closure_owned_sample_t *closure, z_owned_sample_t *sample) { + if (closure->call != NULL) { (closure->call)(sample, closure->context); } } void z_closure_query_call(const z_owned_closure_query_t *closure, const z_query_t *query) { - if (closure->call) { + if (closure->call != NULL) { (closure->call)(query, closure->context); } } void z_closure_reply_call(const z_owned_closure_reply_t *closure, z_owned_reply_t *reply) { - if (closure->call) { + if (closure->call != NULL) { (closure->call)(reply, closure->context); } } void z_closure_hello_call(const z_owned_closure_hello_t *closure, z_owned_hello_t *hello) { - if (closure->call) { + if (closure->call != NULL) { (closure->call)(hello, closure->context); } } void z_closure_zid_call(const z_owned_closure_zid_t *closure, const z_id_t *id) { - if (closure->call) { + if (closure->call != NULL) { (closure->call)(id, closure->context); } } @@ -422,6 +428,7 @@ OWNED_FUNCTIONS_PTR_DROP(z_scouting_config_t, z_owned_scouting_config_t, scoutin OWNED_FUNCTIONS_PTR_INTERNAL(z_keyexpr_t, z_owned_keyexpr_t, keyexpr, _z_keyexpr_free, _z_keyexpr_copy) OWNED_FUNCTIONS_PTR_INTERNAL(z_hello_t, z_owned_hello_t, hello, _z_hello_free, _z_owner_noop_copy) OWNED_FUNCTIONS_PTR_INTERNAL(z_str_array_t, z_owned_str_array_t, str_array, _z_str_array_free, _z_owner_noop_copy) +OWNED_FUNCTIONS_PTR_INTERNAL(z_sample_t, z_owned_sample_t, sample, _z_sample_free, _z_sample_copy) _Bool z_session_check(const z_owned_session_t *val) { return val->_value.in != NULL; } z_session_t z_session_loan(const z_owned_session_t *val) { return (z_session_t){._val = val->_value}; } @@ -454,6 +461,11 @@ z_owned_closure_sample_t z_closure_sample(_z_data_handler_t call, _z_dropper_han return (z_owned_closure_sample_t){.call = call, .drop = drop, .context = context}; } +z_owned_closure_owned_sample_t z_closure_owned_sample(_z_owned_sample_handler_t call, _z_dropper_handler_t drop, + void *context) { + return (z_owned_closure_owned_sample_t){.call = call, .drop = drop, .context = context}; +} + z_owned_closure_query_t z_closure_query(_z_queryable_handler_t call, _z_dropper_handler_t drop, void *context) { return (z_owned_closure_query_t){.call = call, .drop = drop, .context = context}; } @@ -471,6 +483,7 @@ z_owned_closure_zid_t z_closure_zid(z_id_handler_t call, _z_dropper_handler_t dr } OWNED_FUNCTIONS_CLOSURE(z_owned_closure_sample_t, closure_sample) +OWNED_FUNCTIONS_CLOSURE(z_owned_closure_owned_sample_t, closure_owned_sample) OWNED_FUNCTIONS_CLOSURE(z_owned_closure_query_t, closure_query) OWNED_FUNCTIONS_CLOSURE(z_owned_closure_reply_t, closure_reply) OWNED_FUNCTIONS_CLOSURE(z_owned_closure_hello_t, closure_hello) @@ -1258,4 +1271,4 @@ z_owned_bytes_map_t z_bytes_map_new(void) { return (z_owned_bytes_map_t){._inner z_owned_bytes_map_t z_bytes_map_null(void) { return (z_owned_bytes_map_t){._inner = NULL}; } z_bytes_t z_bytes_from_str(const char *str) { return z_bytes_wrap((const uint8_t *)str, strlen(str)); } z_bytes_t z_bytes_null(void) { return (z_bytes_t){.len = 0, ._is_alloc = false, .start = NULL}; } -#endif \ No newline at end of file +#endif diff --git a/src/api/handlers.c b/src/api/handlers.c index 5850541a6..e1f0594b9 100644 --- a/src/api/handlers.c +++ b/src/api/handlers.c @@ -1,5 +1,5 @@ // -// Copyright (c) 2022 ZettaScale Technology +// Copyright (c) 2024 ZettaScale Technology // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License 2.0 which is available at @@ -11,176 +11,27 @@ // Contributors: // ZettaScale Zenoh Team, // + #include "zenoh-pico/api/handlers.h" -#include "zenoh-pico/api/macros.h" -#include "zenoh-pico/protocol/core.h" +#include "zenoh-pico/net/memory.h" #include "zenoh-pico/system/platform.h" -// -- Channel -z_owned_sample_channel_t z_owned_sample_channel_null() { - z_owned_sample_channel_t ch = {.send = NULL, .recv = NULL}; - return ch; -} - -int8_t z_closure_owned_sample_call(z_owned_closure_owned_sample_t *recv, z_owned_sample_t *dst) { - int8_t res = _Z_ERR_GENERIC; - if (recv != NULL) { - res = (recv->call)(dst, recv->context); - } - return res; +// -- Sample +void _z_owned_sample_move(z_owned_sample_t *dst, const z_owned_sample_t *src) { + memcpy(dst, src, sizeof(z_owned_sample_t)); } -// -- Ring -void z_sample_channel_ring_push(const z_sample_t *src, void *context) { - if (src == NULL || context == NULL) { - return; - } - - z_owned_sample_ring_t *r = (z_owned_sample_ring_t *)context; +z_owned_sample_t *_z_sample_to_owned_ptr(const _z_sample_t *src) { z_owned_sample_t *dst = (z_owned_sample_t *)zp_malloc(sizeof(z_owned_sample_t)); if (dst == NULL) { - return; + return NULL; } - *dst = z_sample_to_owned(src); - -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_lock(&r->_mutex); -#endif - _z_owned_sample_ring_push_force_drop(&r->_ring, dst); -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_unlock(&r->_mutex); -#endif -} - -int8_t z_sample_channel_ring_pull(z_owned_sample_t *dst, void *context) { - int8_t ret = _Z_RES_OK; - - z_owned_sample_ring_t *r = (z_owned_sample_ring_t *)context; - -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_lock(&r->_mutex); -#endif - z_owned_sample_t *src = _z_owned_sample_ring_pull(&r->_ring); -#if Z_FEATURE_MULTI_THREAD == 1 - zp_mutex_unlock(&r->_mutex); -#endif - - if (src == NULL) { - *dst = z_sample_null(); - } else { - memcpy(dst, src, sizeof(z_owned_sample_t)); - } - return ret; -} - -z_owned_sample_channel_t z_sample_channel_ring_new(size_t capacity) { - z_owned_sample_channel_t ch = z_owned_sample_channel_null(); - - z_owned_sample_ring_t *ring = (z_owned_sample_ring_t *)zp_malloc(sizeof(z_owned_sample_ring_t)); - if (ring != NULL) { - int8_t res = _z_owned_sample_ring_init(&ring->_ring, capacity); -#if Z_FEATURE_MULTI_THREAD == 1 - res = zp_mutex_init(&ring->_mutex); -#endif - if (res == _Z_RES_OK) { - z_owned_closure_sample_t send = z_closure(z_sample_channel_ring_push, NULL, ring); - ch.send = send; - z_owned_closure_owned_sample_t recv = z_closure(z_sample_channel_ring_pull, NULL, ring); - ch.recv = recv; - } else { - zp_free(ring); - } - } - - return ch; -} - -// -- Fifo -void z_sample_channel_fifo_push(const z_sample_t *src, void *context) { - if (src == NULL || context == NULL) { - return; - } - - z_owned_sample_fifo_t *f = (z_owned_sample_fifo_t *)context; - z_owned_sample_t *dst = (z_owned_sample_t *)zp_malloc(sizeof(z_owned_sample_t)); - if (dst == NULL) { - return; - } - *dst = z_sample_to_owned(src); - -#if Z_FEATURE_MULTI_THREAD == 1 - - zp_mutex_lock(&f->_mutex); - while (dst != NULL) { - dst = _z_owned_sample_fifo_push(&f->_fifo, dst); - if (dst != NULL) { - zp_condvar_wait(&f->_cv_not_full, &f->_mutex); - } else { - zp_condvar_signal(&f->_cv_not_empty); - } - } - zp_mutex_unlock(&f->_mutex); - -#elif // Z_FEATURE_MULTI_THREAD == 1 - - _z_owned_sample_fifo_push_drop(&f->_fifo, dst); - -#endif // Z_FEATURE_MULTI_THREAD == 1 -} - -int8_t z_sample_channel_fifo_pull(z_owned_sample_t *dst, void *context) { - int8_t ret = _Z_RES_OK; - - z_owned_sample_fifo_t *f = (z_owned_sample_fifo_t *)context; - -#if Z_FEATURE_MULTI_THREAD == 1 - - z_owned_sample_t *src = NULL; - zp_mutex_lock(&f->_mutex); - while (src == NULL) { - src = _z_owned_sample_fifo_pull(&f->_fifo); - if (src == NULL) { - zp_condvar_wait(&f->_cv_not_empty, &f->_mutex); - } else { - zp_condvar_signal(&f->_cv_not_full); - } - } - zp_mutex_unlock(&f->_mutex); - memcpy(dst, src, sizeof(z_owned_sample_t)); - -#elif // Z_FEATURE_MULTI_THREAD == 1 - - z_owned_sample_t *src = _z_owned_sample_fifo_pull(&f->_fifo); if (src != NULL) { - memcpy(dst, src, sizeof(z_owned_sample_t)); + dst->_value = (_z_sample_t *)zp_malloc(sizeof(_z_sample_t)); + _z_sample_copy(dst->_value, src); + } else { + dst->_value = NULL; } - -#endif // Z_FEATURE_MULTI_THREAD == 1 - - return ret; + return dst; } - -z_owned_sample_channel_t z_sample_channel_fifo_new(size_t capacity) { - z_owned_sample_channel_t ch = z_owned_sample_channel_null(); - - z_owned_sample_fifo_t *fifo = (z_owned_sample_fifo_t *)zp_malloc(sizeof(z_owned_sample_fifo_t)); - if (fifo != NULL) { - int8_t res = _z_owned_sample_fifo_init(&fifo->_fifo, capacity); -#if Z_FEATURE_MULTI_THREAD == 1 - res = zp_mutex_init(&fifo->_mutex); - res = zp_condvar_init(&fifo->_cv_not_full); - res = zp_condvar_init(&fifo->_cv_not_empty); -#endif - if (res == _Z_RES_OK) { - z_owned_closure_sample_t send = z_closure(z_sample_channel_fifo_push, NULL, fifo); - ch.send = send; - z_owned_closure_owned_sample_t recv = z_closure(z_sample_channel_fifo_pull, NULL, fifo); - ch.recv = recv; - } else { - zp_free(fifo); - } - } - - return ch; -} \ No newline at end of file diff --git a/src/collections/fifo_mt.c b/src/collections/fifo_mt.c new file mode 100644 index 000000000..48837b5dd --- /dev/null +++ b/src/collections/fifo_mt.c @@ -0,0 +1,115 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +#include "zenoh-pico/collections/fifo_mt.h" + +#include "zenoh-pico/protocol/codec/core.h" +#include "zenoh-pico/protocol/core.h" +#include "zenoh-pico/utils/logging.h" + +/*-------- Fifo Buffer Multithreaded --------*/ +int8_t _z_fifo_mt_init(_z_fifo_mt_t *fifo, size_t capacity) { + _Z_RETURN_IF_ERR(_z_fifo_init(&fifo->_fifo, capacity)) + +#if Z_FEATURE_MULTI_THREAD == 1 + _Z_RETURN_IF_ERR(zp_mutex_init(&fifo->_mutex)) + _Z_RETURN_IF_ERR(zp_condvar_init(&fifo->_cv_not_full)) + _Z_RETURN_IF_ERR(zp_condvar_init(&fifo->_cv_not_empty)) +#endif + + return _Z_RES_OK; +} + +_z_fifo_mt_t *_z_fifo_mt_new(size_t capacity) { + _z_fifo_mt_t *fifo = (_z_fifo_mt_t *)zp_malloc(sizeof(_z_fifo_mt_t)); + if (fifo == NULL) { + _Z_ERROR("zp_malloc failed"); + return NULL; + } + + int8_t ret = _z_fifo_mt_init(fifo, capacity); + if (ret != _Z_RES_OK) { + _Z_ERROR("_z_fifo_mt_init failed: %i", ret); + zp_free(fifo); + return NULL; + } + + return fifo; +} + +void _z_fifo_mt_clear(_z_fifo_mt_t *fifo, z_element_free_f free_f) { +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_free(&fifo->_mutex); + zp_condvar_free(&fifo->_cv_not_full); + zp_condvar_free(&fifo->_cv_not_empty); +#endif + + _z_fifo_clear(&fifo->_fifo, free_f); +} + +void _z_fifo_mt_free(_z_fifo_mt_t *fifo, z_element_free_f free_f) { + _z_fifo_mt_clear(fifo, free_f); + zp_free(fifo); +} + +int8_t _z_fifo_mt_push(const void *elem, void *context, z_element_free_f element_free) { + if (elem == NULL || context == NULL) { + return _Z_ERR_GENERIC; + } + + _z_fifo_mt_t *f = (_z_fifo_mt_t *)context; + +#if Z_FEATURE_MULTI_THREAD == 1 + _Z_RETURN_IF_ERR(zp_mutex_lock(&f->_mutex)) + while (elem != NULL) { + elem = _z_fifo_push(&f->_fifo, (void *)elem); + if (elem != NULL) { + _Z_RETURN_IF_ERR(zp_condvar_wait(&f->_cv_not_full, &f->_mutex)) + } else { + _Z_RETURN_IF_ERR(zp_condvar_signal(&f->_cv_not_empty)) + } + } + _Z_RETURN_IF_ERR(zp_mutex_unlock(&f->_mutex)) +#else // Z_FEATURE_MULTI_THREAD == 1 + _z_fifo_push_drop(&f->_fifo, elem, element_free); +#endif // Z_FEATURE_MULTI_THREAD == 1 + + return _Z_RES_OK; +} + +int8_t _z_fifo_mt_pull(void *dst, void *context, z_element_move_f element_move) { + _z_fifo_mt_t *f = (_z_fifo_mt_t *)context; + +#if Z_FEATURE_MULTI_THREAD == 1 + void *src = NULL; + _Z_RETURN_IF_ERR(zp_mutex_lock(&f->_mutex)) + while (src == NULL) { + src = _z_fifo_pull(&f->_fifo); + if (src == NULL) { + _Z_RETURN_IF_ERR(zp_condvar_wait(&f->_cv_not_empty, &f->_mutex)) + } else { + _Z_RETURN_IF_ERR(zp_condvar_signal(&f->_cv_not_full)) + } + } + _Z_RETURN_IF_ERR(zp_mutex_unlock(&f->_mutex)) + element_move(dst, src); +#else // Z_FEATURE_MULTI_THREAD == 1 + void *src = _z_fifo_pull(&f->_fifo); + if (src) { + element_move(dst, src); + } +#endif // Z_FEATURE_MULTI_THREAD == 1 + + return _Z_RES_OK; +} diff --git a/src/collections/ring.c b/src/collections/ring.c index 912dcf4bb..ce3e90894 100644 --- a/src/collections/ring.c +++ b/src/collections/ring.c @@ -11,6 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // + #include "zenoh-pico/collections/ring.h" #include diff --git a/src/collections/ring_mt.c b/src/collections/ring_mt.c new file mode 100644 index 000000000..ab7083be0 --- /dev/null +++ b/src/collections/ring_mt.c @@ -0,0 +1,97 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +#include "zenoh-pico/collections/ring_mt.h" + +#include "zenoh-pico/protocol/codec/core.h" +#include "zenoh-pico/protocol/core.h" +#include "zenoh-pico/utils/logging.h" + +/*-------- Ring Buffer Multithreaded --------*/ +int8_t _z_ring_mt_init(_z_ring_mt_t *ring, size_t capacity) { + _Z_RETURN_IF_ERR(_z_ring_init(&ring->_ring, capacity)) + +#if Z_FEATURE_MULTI_THREAD == 1 + _Z_RETURN_IF_ERR(zp_mutex_init(&ring->_mutex)) +#endif + return _Z_RES_OK; +} + +_z_ring_mt_t *_z_ring_mt_new(size_t capacity) { + _z_ring_mt_t *ring = (_z_ring_mt_t *)zp_malloc(sizeof(_z_ring_mt_t)); + if (ring == NULL) { + _Z_ERROR("zp_malloc failed"); + return NULL; + } + + int8_t ret = _z_ring_mt_init(ring, capacity); + if (ret != _Z_RES_OK) { + _Z_ERROR("_z_ring_mt_init failed: %i", ret); + return NULL; + } + + return ring; +} + +void _z_ring_mt_clear(_z_ring_mt_t *ring, z_element_free_f free_f) { +#if Z_FEATURE_MULTI_THREAD == 1 + zp_mutex_free(&ring->_mutex); +#endif + + _z_ring_clear(&ring->_ring, free_f); +} + +void _z_ring_mt_free(_z_ring_mt_t *ring, z_element_free_f free_f) { + _z_ring_mt_clear(ring, free_f); + + zp_free(ring); +} + +int8_t _z_ring_mt_push(const void *elem, void *context, z_element_free_f element_free) { + if (elem == NULL || context == NULL) { + return _Z_ERR_GENERIC; + } + + _z_ring_mt_t *r = (_z_ring_mt_t *)context; + +#if Z_FEATURE_MULTI_THREAD == 1 + _Z_RETURN_IF_ERR(zp_mutex_lock(&r->_mutex)) +#endif + + _z_ring_push_force_drop(&r->_ring, (void *)elem, element_free); + +#if Z_FEATURE_MULTI_THREAD == 1 + _Z_RETURN_IF_ERR(zp_mutex_unlock(&r->_mutex)) +#endif + return _Z_RES_OK; +} + +int8_t _z_ring_mt_pull(void *dst, void *context, z_element_move_f element_move) { + _z_ring_mt_t *r = (_z_ring_mt_t *)context; + +#if Z_FEATURE_MULTI_THREAD == 1 + _Z_RETURN_IF_ERR(zp_mutex_lock(&r->_mutex)) +#endif + + void *src = _z_ring_pull(&r->_ring); + +#if Z_FEATURE_MULTI_THREAD == 1 + _Z_RETURN_IF_ERR(zp_mutex_unlock(&r->_mutex)) +#endif + + if (src) { + element_move(dst, src); + } + return _Z_RES_OK; +} diff --git a/src/net/memory.c b/src/net/memory.c index b8cd9f55c..0c2e930b0 100644 --- a/src/net/memory.c +++ b/src/net/memory.c @@ -49,6 +49,27 @@ void _z_sample_free(_z_sample_t **sample) { } } +void _z_sample_copy(_z_sample_t *dst, const _z_sample_t *src) { + dst->keyexpr = _z_keyexpr_duplicate(src->keyexpr); + dst->payload = _z_bytes_duplicate(&src->payload); + dst->timestamp = _z_timestamp_duplicate(&src->timestamp); + + // TODO(sashacmc): should be changed after encoding rework + dst->encoding.prefix = src->encoding.prefix; + _z_bytes_copy(&dst->encoding.suffix, &src->encoding.suffix); + + dst->kind = src->kind; +#if Z_FEATURE_ATTACHMENT == 1 + dst->attachment = src->attachment; +#endif +} + +_z_sample_t _z_sample_duplicate(const _z_sample_t *src) { + _z_sample_t dst; + _z_sample_copy(&dst, src); + return dst; +} + void _z_hello_clear(_z_hello_t *hello) { if (hello->locators.len > 0) { _z_str_array_clear(&hello->locators); diff --git a/tests/z_channels_test.c b/tests/z_channels_test.c new file mode 100644 index 000000000..b390908d7 --- /dev/null +++ b/tests/z_channels_test.c @@ -0,0 +1,118 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#include +#include +#include +#include + +#include "zenoh-pico/api/handlers.h" + +#undef NDEBUG +#include + +#define SEND(channel, v) \ + do { \ + z_sample_t sample; \ + sample.payload.start = (const uint8_t *)v; \ + sample.payload.len = strlen(v); \ + sample.keyexpr = _z_rname("key"); \ + z_call(channel.send, &sample); \ + } while (0); + +#define RECV(channel, buf) \ + do { \ + z_owned_sample_t sample = z_sample_null(); \ + z_call(channel.recv, &sample); \ + if (z_check(sample)) { \ + strncpy(buf, (const char *)z_loan(sample).payload.start, (size_t)z_loan(sample).payload.len); \ + buf[z_loan(sample).payload.len] = '\0'; \ + z_drop(z_move(sample)); \ + } else { \ + buf[0] = '\0'; \ + } \ + } while (0); + +void sample_fifo_channel_test(void) { + z_owned_sample_fifo_channel_t channel = z_sample_fifo_channel_new(10); + + SEND(channel, "v1") + SEND(channel, "v22") + SEND(channel, "v333") + SEND(channel, "v4444") + + char buf[100]; + + RECV(channel, buf) + assert(strcmp(buf, "v1") == 0); + RECV(channel, buf) + assert(strcmp(buf, "v22") == 0); + RECV(channel, buf) + assert(strcmp(buf, "v333") == 0); + RECV(channel, buf) + assert(strcmp(buf, "v4444") == 0); + + z_drop(z_move(channel)); +} + +void sample_ring_channel_test_in_size(void) { + z_owned_sample_ring_channel_t channel = z_sample_ring_channel_new(10); + + SEND(channel, "v1") + SEND(channel, "v22") + SEND(channel, "v333") + SEND(channel, "v4444") + + char buf[100]; + + RECV(channel, buf) + assert(strcmp(buf, "v1") == 0); + RECV(channel, buf) + assert(strcmp(buf, "v22") == 0); + RECV(channel, buf) + assert(strcmp(buf, "v333") == 0); + RECV(channel, buf) + assert(strcmp(buf, "v4444") == 0); + RECV(channel, buf) + assert(strcmp(buf, "") == 0); + + z_drop(z_move(channel)); +} + +void sample_ring_channel_test_over_size(void) { + z_owned_sample_ring_channel_t channel = z_sample_ring_channel_new(3); + + SEND(channel, "v1") + SEND(channel, "v22") + SEND(channel, "v333") + SEND(channel, "v4444") + + char buf[100]; + + RECV(channel, buf) + assert(strcmp(buf, "v22") == 0); + RECV(channel, buf) + assert(strcmp(buf, "v333") == 0); + RECV(channel, buf) + assert(strcmp(buf, "v4444") == 0); + RECV(channel, buf) + assert(strcmp(buf, "") == 0); + + z_drop(z_move(channel)); +} + +int main(void) { + sample_fifo_channel_test(); + sample_ring_channel_test_in_size(); + sample_ring_channel_test_over_size(); +}