Skip to content

Commit

Permalink
Introduce loaned closures (#485)
Browse files Browse the repository at this point in the history
* introduce loaned closures;
make closure_call require loaned closure;
fix reusing of moved closure_zid_t in z_api_alignment_test;

* fix _zp_multicast_fetch_zid signature

* fix docs

* simplify macros
  • Loading branch information
DenisBiryukov91 authored Jul 2, 2024
1 parent e3f5d49 commit 0b0e0d1
Show file tree
Hide file tree
Showing 12 changed files with 241 additions and 140 deletions.
43 changes: 38 additions & 5 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,45 @@ It is guaranteed that:
- ``drop`` will only be called **once**, and **after every** ``call`` has ended.
- The two previous guarantees imply that ``call`` and ``drop`` are never called concurrently.

Represents a `sample` closure.

.. autoctype:: types.h::z_owned_closure_sample_t
.. autoctype:: types.h::z_owned_closure_query_t
.. autoctype:: types.h::z_owned_closure_reply_t
.. autoctype:: types.h::z_owned_closure_hello_t
.. autoctype:: types.h::z_owned_closure_zid_t
.. c:type:: types.h::z_owned_closure_sample_t
Represents a loaned `sample` closure.

.. c:type:: types.h::z_loaned_closure_sample_t
Represents a `query` closure.

.. c:type:: types.h::z_owned_closure_query_t
Represents a loaned `query` closure.

.. c:type:: types.h::z_loaned_closure_query_t
Represents a `reply` closure.

.. c:type:: types.h::z_owned_closure_reply_t
Represents a loaned `reply` closure.

.. c:type:: types.h::z_loaned_closure_reply_t
Represents a `hello` closure.

.. c:type:: types.h::z_owned_closure_hello_t
Represents a loaned `hello` closure.

.. c:type:: types.h::z_loaned_closure_hello_t
Represents a `Zenoh id` closure.

.. c:type:: types.h::z_owned_closure_zid_t
Represents a loaned `Zenoh id` closure.

.. c:type:: types.h::z_loaned_closure_zid_t
Zenoh Functions
Expand Down
109 changes: 79 additions & 30 deletions include/zenoh-pico/api/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@
z_owned_ring_handler_query_t : z_ring_handler_query_loan, \
z_owned_ring_handler_reply_t : z_ring_handler_reply_loan, \
z_owned_ring_handler_sample_t : z_ring_handler_sample_loan, \
z_owned_reply_err_t : z_reply_err_loan \
z_owned_reply_err_t : z_reply_err_loan, \
z_owned_closure_sample_t : z_closure_sample_loan, \
z_owned_closure_reply_t : z_closure_reply_loan, \
z_owned_closure_query_t : z_closure_query_loan, \
z_owned_closure_hello_t : z_closure_hello_loan, \
z_owned_closure_zid_t : z_closure_zid_loan \
)(&x)

#define z_loan_mut(x) _Generic((x), \
Expand Down Expand Up @@ -160,11 +165,11 @@
* 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_loaned_closure_sample_t : z_closure_sample_call, \
z_loaned_closure_query_t : z_closure_query_call, \
z_loaned_closure_reply_t : z_closure_reply_call, \
z_loaned_closure_hello_t : z_closure_hello_call, \
z_loaned_closure_zid_t : z_closure_zid_call \
) (&x, __VA_ARGS__)

#define z_try_recv(x, ...) \
Expand Down Expand Up @@ -289,9 +294,9 @@

#define _z_closure_overloader(closure, callback, dropper, ctx, ...) \
do { \
(closure)->call = callback; \
(closure)->drop = dropper; \
(closure)->context = ctx; \
(closure)->_val.call = callback; \
(closure)->_val.drop = dropper; \
(closure)->_val.context = ctx; \
} while (0);

/**
Expand Down Expand Up @@ -334,7 +339,11 @@ inline const z_loaned_task_t* z_loan(const z_owned_task_t& x) { return z_task_lo
inline const z_loaned_mutex_t* z_loan(const z_owned_mutex_t& x) { return z_mutex_loan(&x); }
inline const z_loaned_condvar_t* z_loan(const z_owned_condvar_t& x) { return z_condvar_loan(&x); }
inline const z_loaned_reply_err_t* z_loan(const z_owned_reply_err_t& x) { return z_reply_err_loan(&x); }

inline const z_loaned_closure_sample_t* z_loan(const z_owned_closure_sample_t& x) { return z_closure_sample_loan(&x); }
inline const z_loaned_closure_reply_t* z_loan(const z_owned_closure_reply_t& x) { return z_closure_reply_loan(&x); }
inline const z_loaned_closure_query_t* z_loan(const z_owned_closure_query_t& x) { return z_closure_query_loan(&x); }
inline const z_loaned_closure_hello_t* z_loan(const z_owned_closure_hello_t& x) { return z_closure_hello_loan(&x); }
inline const z_loaned_closure_zid_t* z_loan(const z_owned_closure_zid_t& x) { return z_closure_zid_loan(&x); }
// z_loan_mut definition
inline z_loaned_keyexpr_t* z_loan_mut(z_owned_keyexpr_t& x) { return z_keyexpr_loan_mut(&x); }
inline z_loaned_keyexpr_t* z_loan_mut(z_view_keyexpr_t& x) { return z_view_keyexpr_loan_mut(&x); }
Expand Down Expand Up @@ -428,61 +437,61 @@ inline bool z_check(const z_owned_reply_err_t& v) { return z_reply_err_check(&v)

// z_call definition

inline void z_call(const z_owned_closure_sample_t &closure, const z_loaned_sample_t *sample)
inline void z_call(const z_loaned_closure_sample_t &closure, const z_loaned_sample_t *sample)
{ z_closure_sample_call(&closure, sample); }
inline void z_call(const z_owned_closure_query_t &closure, const z_loaned_query_t *query)
inline void z_call(const z_loaned_closure_query_t &closure, const z_loaned_query_t *query)
{ z_closure_query_call(&closure, query); }
inline void z_call(const z_owned_closure_reply_t &closure, const z_loaned_reply_t *reply)
inline void z_call(const z_loaned_closure_reply_t &closure, const z_loaned_reply_t *reply)
{ z_closure_reply_call(&closure, reply); }
inline void z_call(const z_owned_closure_hello_t &closure, const z_loaned_hello_t *hello)
inline void z_call(const z_loaned_closure_hello_t &closure, const z_loaned_hello_t *hello)
{ z_closure_hello_call(&closure, hello); }
inline void z_call(const z_owned_closure_zid_t &closure, const z_id_t *zid)
inline void z_call(const z_loaned_closure_zid_t &closure, const z_id_t *zid)
{ z_closure_zid_call(&closure, zid); }

inline void z_closure(
z_owned_closure_hello_t* closure,
void (*call)(const z_loaned_hello_t*, void*),
void (*drop)(void*) = NULL,
void *context = NULL) {
closure->context = context;
closure->drop = drop;
closure->call = call;
closure->_val.context = context;
closure->_val.drop = drop;
closure->_val.call = call;
};
inline void z_closure(
z_owned_closure_query_t* closure,
void (*call)(const z_loaned_query_t*, void*),
void (*drop)(void*) = NULL,
void *context = NULL) {
closure->context = context;
closure->drop = drop;
closure->call = call;
closure->_val.context = context;
closure->_val.drop = drop;
closure->_val.call = call;
};
inline void z_closure(
z_owned_closure_reply_t* closure,
void (*call)(const z_loaned_reply_t*, void*),
void (*drop)(void*) = NULL,
void *context = NULL) {
closure->context = context;
closure->drop = drop;
closure->call = call;
closure->_val.context = context;
closure->_val.drop = drop;
closure->_val.call = call;
};
inline void z_closure(
z_owned_closure_sample_t* closure,
void (*call)(const z_loaned_sample_t*, void*),
void (*drop)(void*) = NULL,
void *context = NULL) {
closure->context = context;
closure->drop = drop;
closure->call = call;
closure->_val.context = context;
closure->_val.drop = drop;
closure->_val.call = call;
};
inline void z_closure(
z_owned_closure_zid_t* closure,
void (*call)(const z_id_t*, void*),
void (*drop)(void*) = NULL,
void *context = NULL) {
closure->context = context;
closure->drop = drop;
closure->call = call;
closure->_val.context = context;
closure->_val.drop = drop;
closure->_val.call = call;
};

inline bool z_try_recv(const z_loaned_fifo_handler_query_t* this_, z_owned_query_t* query) {
Expand Down Expand Up @@ -721,6 +730,46 @@ template <>
struct z_owned_to_loaned_type_t<z_owned_subscriber_t> {
typedef z_loaned_subscriber_t type;
};
template <>
struct z_owned_to_loaned_type_t<z_owned_closure_sample_t> {
typedef z_loaned_closure_sample_t type;
};
template <>
struct z_loaned_to_owned_type_t<z_loaned_closure_sample_t> {
typedef z_owned_closure_sample_t type;
};
template <>
struct z_owned_to_loaned_type_t<z_owned_closure_reply_t> {
typedef z_loaned_closure_reply_t type;
};
template <>
struct z_loaned_to_owned_type_t<z_loaned_closure_reply_t> {
typedef z_owned_closure_reply_t type;
};
template <>
struct z_owned_to_loaned_type_t<z_owned_closure_query_t> {
typedef z_loaned_closure_query_t type;
};
template <>
struct z_loaned_to_owned_type_t<z_loaned_closure_query_t> {
typedef z_owned_closure_query_t type;
};
template <>
struct z_owned_to_loaned_type_t<z_owned_closure_hello_t> {
typedef z_loaned_closure_hello_t type;
};
template <>
struct z_loaned_to_owned_type_t<z_loaned_closure_hello_t> {
typedef z_owned_closure_hello_t type;
};
template <>
struct z_owned_to_loaned_type_t<z_owned_closure_zid_t> {
typedef z_loaned_closure_zid_t type;
};
template <>
struct z_loaned_to_owned_type_t<z_loaned_closure_zid_t> {
typedef z_owned_closure_zid_t type;
};

#endif

Expand Down
58 changes: 30 additions & 28 deletions include/zenoh-pico/api/olv_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,34 +156,36 @@
const z_loaned_##name##_t *z_view_##name##_loan(const z_view_##name##_t *obj) { return &obj->_val; } \
z_loaned_##name##_t *z_view_##name##_loan_mut(z_view_##name##_t *obj) { return &obj->_val; }

#define _Z_OWNED_FUNCTIONS_CLOSURE_DEF(ownedtype, name) \
_Bool z_##name##_check(const ownedtype *val); \
ownedtype *z_##name##_move(ownedtype *val); \
void z_##name##_drop(ownedtype *val); \
void z_##name##_null(ownedtype *name);

#define _Z_OWNED_FUNCTIONS_CLOSURE_IMPL(ownedtype, name, f_call, f_drop) \
_Bool z_##name##_check(const ownedtype *val) { return val->call != NULL; } \
ownedtype *z_##name##_move(ownedtype *val) { return val; } \
void z_##name##_drop(ownedtype *val) { \
if (val->drop != NULL) { \
(val->drop)(val->context); \
val->drop = NULL; \
} \
val->call = NULL; \
val->context = NULL; \
} \
void z_##name##_null(ownedtype *val) { \
val->call = NULL; \
val->drop = NULL; \
val->context = NULL; \
} \
int8_t z_##name(ownedtype *closure, f_call call, f_drop drop, void *context) { \
closure->call = call; \
closure->drop = drop; \
closure->context = context; \
\
return _Z_RES_OK; \
#define _Z_OWNED_FUNCTIONS_CLOSURE_DEF(name) \
_Bool z_##name##_check(const z_owned_##name##_t *val); \
z_owned_##name##_t *z_##name##_move(z_owned_##name##_t *val); \
void z_##name##_drop(z_owned_##name##_t *val); \
const z_loaned_##name##_t *z_##name##_loan(const z_owned_##name##_t *val); \
void z_##name##_null(z_owned_##name##_t *name);

#define _Z_OWNED_FUNCTIONS_CLOSURE_IMPL(name, f_call, f_drop) \
_Bool z_##name##_check(const z_owned_##name##_t *val) { return val->_val.call != NULL; } \
z_owned_##name##_t *z_##name##_move(z_owned_##name##_t *val) { return val; } \
void z_##name##_drop(z_owned_##name##_t *val) { \
if (val->_val.drop != NULL) { \
(val->_val.drop)(val->_val.context); \
val->_val.drop = NULL; \
} \
val->_val.call = NULL; \
val->_val.context = NULL; \
} \
void z_##name##_null(z_owned_##name##_t *val) { \
val->_val.call = NULL; \
val->_val.drop = NULL; \
val->_val.context = NULL; \
} \
const z_loaned_##name##_t *z_##name##_loan(const z_owned_##name##_t *val) { return &val->_val; } \
int8_t z_##name(z_owned_##name##_t *closure, f_call call, f_drop drop, void *context) { \
closure->_val.call = call; \
closure->_val.drop = drop; \
closure->_val.context = context; \
\
return _Z_RES_OK; \
}

// Gets internal value from refcounted type (e.g. z_loaned_session_t, z_query_t)
Expand Down
10 changes: 5 additions & 5 deletions include/zenoh-pico/api/primitives.h
Original file line number Diff line number Diff line change
Expand Up @@ -1051,11 +1051,11 @@ _Z_OWNED_FUNCTIONS_DEF(bytes_writer)
_Z_OWNED_FUNCTIONS_DEF(reply_err)
_Z_OWNED_FUNCTIONS_DEF(encoding)

_Z_OWNED_FUNCTIONS_CLOSURE_DEF(z_owned_closure_sample_t, closure_sample)
_Z_OWNED_FUNCTIONS_CLOSURE_DEF(z_owned_closure_query_t, closure_query)
_Z_OWNED_FUNCTIONS_CLOSURE_DEF(z_owned_closure_reply_t, closure_reply)
_Z_OWNED_FUNCTIONS_CLOSURE_DEF(z_owned_closure_hello_t, closure_hello)
_Z_OWNED_FUNCTIONS_CLOSURE_DEF(z_owned_closure_zid_t, closure_zid)
_Z_OWNED_FUNCTIONS_CLOSURE_DEF(closure_sample)
_Z_OWNED_FUNCTIONS_CLOSURE_DEF(closure_query)
_Z_OWNED_FUNCTIONS_CLOSURE_DEF(closure_reply)
_Z_OWNED_FUNCTIONS_CLOSURE_DEF(closure_hello)
_Z_OWNED_FUNCTIONS_CLOSURE_DEF(closure_zid)

_Z_VIEW_FUNCTIONS_DEF(keyexpr)
_Z_VIEW_FUNCTIONS_DEF(string)
Expand Down
Loading

0 comments on commit 0b0e0d1

Please sign in to comment.