From b0319f8d358c476e29d3c6daeef1cda616cfd447 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Sun, 13 Oct 2019 21:39:11 +0200 Subject: [PATCH] Add a way to set the channel's priv pointer when opening it. This prevents a race condition where between opening a channel and setting the priv pointer, the receive callback is called. --- src/meshlink++.h | 2 ++ src/meshlink.c | 7 ++++++- src/meshlink.h | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/meshlink++.h b/src/meshlink++.h index f5921363..64673f58 100644 --- a/src/meshlink++.h +++ b/src/meshlink++.h @@ -732,6 +732,7 @@ public: * @param cb A pointer to the function which will be called when the remote node sends data to the local node. * @param data A pointer to a buffer containing data to already queue for sending. * @param len The length of the data. + * If len is 0, the data pointer is copied into the channel's priv member. * @param flags A bitwise-or'd combination of flags that set the semantics for this channel. * * @return A handle for the channel, or NULL in case of an error. @@ -756,6 +757,7 @@ public: * @param port The port number the peer wishes to connect to. * @param data A pointer to a buffer containing data to already queue for sending. * @param len The length of the data. + * If len is 0, the data pointer is copied into the channel's priv member. * @param flags A bitwise-or'd combination of flags that set the semantics for this channel. * * @return A handle for the channel, or NULL in case of an error. diff --git a/src/meshlink.c b/src/meshlink.c index e82ea4f1..f1b6a334 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -3150,7 +3150,7 @@ void meshlink_set_channel_rcvbuf(meshlink_handle_t *mesh, meshlink_channel_t *ch } meshlink_channel_t *meshlink_channel_open_ex(meshlink_handle_t *mesh, meshlink_node_t *node, uint16_t port, meshlink_channel_receive_cb_t cb, const void *data, size_t len, uint32_t flags) { - if(data || len) { + if(data && len) { abort(); // TODO: handle non-NULL data } @@ -3183,6 +3183,11 @@ meshlink_channel_t *meshlink_channel_open_ex(meshlink_handle_t *mesh, meshlink_n meshlink_channel_t *channel = xzalloc(sizeof(*channel)); channel->node = n; channel->receive_cb = cb; + + if(data && !len) { + channel->priv = (void *)data; + } + channel->c = utcp_connect_ex(n->utcp, port, channel_recv, channel, flags); pthread_mutex_unlock(&mesh->mutex); diff --git a/src/meshlink.h b/src/meshlink.h index 11395f04..e043d8d2 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -1171,6 +1171,7 @@ extern void meshlink_set_channel_rcvbuf(struct meshlink_handle *mesh, struct mes * The pointer may be NULL, in which case incoming data is ignored. * @param data A pointer to a buffer containing data to already queue for sending, or NULL if there is no data to send. * After meshlink_send() returns, the application is free to overwrite or free this buffer. + * If len is 0, the data pointer is copied into the channel's priv member. * @param len The length of the data, or 0 if there is no data to send. * @param flags A bitwise-or'd combination of flags that set the semantics for this channel. * @@ -1199,6 +1200,7 @@ extern struct meshlink_channel *meshlink_channel_open_ex(struct meshlink_handle * @param data A pointer to a buffer containing data to already queue for sending, or NULL if there is no data to send. * After meshlink_send() returns, the application is free to overwrite or free this buffer. * @param len The length of the data, or 0 if there is no data to send. + * If len is 0, the data pointer is copied into the channel's priv member. * * @return A handle for the channel, or NULL in case of an error. * The handle is valid until meshlink_channel_close() is called. -- 2.39.2