From c6cc7da56d108f05ea6f9a2f765f699e6e2353db Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Wed, 1 Oct 2014 19:36:58 +0200 Subject: [PATCH] Add a poll callback to channels. The callback is called whenever the a call to meshlink_channel_send() will accept a non-zero number of bytes. --- src/meshlink++.h | 22 ++++++++++++++++++++++ src/meshlink.c | 15 +++++++++++++++ src/meshlink.h | 23 +++++++++++++++++++++++ src/meshlink_internal.h | 1 + src/utcp | 2 +- 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/meshlink++.h b/src/meshlink++.h index ef578b11..4f35e8a9 100644 --- a/src/meshlink++.h +++ b/src/meshlink++.h @@ -77,6 +77,13 @@ namespace meshlink { */ typedef void (*channel_receive_cb_t)(mesh *mesh, channel *channel, const void *data, size_t len); + /// A callback that is called when data can be send on a channel. + /** @param mesh A handle which represents an instance of MeshLink. + * @param channel A handle for the channel. + * @param len The maximum length of data that is guaranteed to be accepted by a call to channel_send(). + */ + typedef void (*channel_poll_cb_t)(mesh *mesh, channel *channel, size_t len); + /// A class describing a MeshLink node. class node: public meshlink_node_t { }; @@ -292,6 +299,21 @@ namespace meshlink { return meshlink_set_channel_accept_cb(this, (meshlink_channel_accept_cb_t)cb); } + /// Set the poll callback. + /** This functions sets the callback that is called whenever data can be sent to another node. + * The callback is run in MeshLink's own thread. + * It is therefore important that the callback uses apprioriate methods (queues, pipes, locking, etc.) + * to pass data to or from the application's thread. + * The callback should also not block itself and return as quickly as possible. + * + * @param channel A handle for the channel. + * @param cb A pointer to the function which will be called when data can be sent to another node. + * If a NULL pointer is given, the callback will be disabled. + */ + void set_channel_poll_cb(channel *channel, channel_poll_cb_t cb) { + return meshlink_set_channel_poll_cb(this, (meshlink_channel_poll_cb_t)cb); + } + /// Open a reliable stream channel to another node. /** This function is called whenever a remote node wants to open a channel to the local node. * The application then has to decide whether to accept or reject this channel. diff --git a/src/meshlink.c b/src/meshlink.c index bd74b1d8..4538548d 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -1961,6 +1961,21 @@ static void channel_receive(meshlink_handle_t *mesh, meshlink_node_t *source, co utcp_recv(n->utcp, data, len); } +static void channel_poll(struct utcp_connection *connection, size_t len) { + meshlink_channel_t *channel = connection->priv; + if(!channel) + abort(); + node_t *n = channel->node; + meshlink_handle_t *mesh = n->mesh; + if(channel->poll_cb) + channel->poll_cb(mesh, channel, len); +} + +void meshlink_set_channel_poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_poll_cb_t cb) { + channel->poll_cb = cb; + utcp_set_poll_cb(channel->c, cb ? channel_poll : NULL); +} + void meshlink_set_channel_accept_cb(meshlink_handle_t *mesh, meshlink_channel_accept_cb_t cb) { pthread_mutex_lock(&mesh->mesh_mutex); mesh->channel_accept_cb = cb; diff --git a/src/meshlink.h b/src/meshlink.h index 17545ed2..6a83f6c6 100644 --- a/src/meshlink.h +++ b/src/meshlink.h @@ -524,6 +524,15 @@ typedef bool (*meshlink_channel_accept_cb_t)(meshlink_handle_t *mesh, meshlink_c */ typedef void (*meshlink_channel_receive_cb_t)(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len); +/// A callback informing the application when data can be sent on a channel. +/** This function is called whenever there is enough free buffer space so a call to meshlink_channel_send() will succeed. + * + * @param mesh A handle which represents an instance of MeshLink. + * @param channel A handle for the channel. + * @param len The maximum amount of data that is guaranteed to be accepted by meshlink_channel_send(). + */ +typedef void (*meshlink_channel_poll_cb_t)(meshlink_handle_t *mesh, meshlink_channel_t *channel, size_t len); + /// Set the accept callback. /** This functions sets the callback that is called whenever another node sends data to the local node. * The callback is run in MeshLink's own thread. @@ -553,6 +562,20 @@ extern void meshlink_set_channel_accept_cb(meshlink_handle_t *mesh, meshlink_cha */ extern void meshlink_set_channel_receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_receive_cb_t cb); +/// Set the poll callback. +/** This functions sets the callback that is called whenever data can be sent to another node. + * The callback is run in MeshLink's own thread. + * It is therefore important that the callback uses apprioriate methods (queues, pipes, locking, etc.) + * to pass data to or from the application's thread. + * The callback should also not block itself and return as quickly as possible. + * + * @param mesh A handle which represents an instance of MeshLink. + * @param channel A handle for the channel. + * @param cb A pointer to the function which will be called when data can be sent to another node. + * If a NULL pointer is given, the callback will be disabled. + */ +extern void meshlink_set_channel_poll_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, meshlink_channel_poll_cb_t cb); + /// Open a reliable stream channel to another node. /** This function is called whenever a remote node wants to open a channel to the local node. * The application then has to decide whether to accept or reject this channel. diff --git a/src/meshlink_internal.h b/src/meshlink_internal.h index 782cc76e..e36fd95f 100644 --- a/src/meshlink_internal.h +++ b/src/meshlink_internal.h @@ -152,6 +152,7 @@ struct meshlink_channel { struct utcp_connection *c; meshlink_channel_receive_cb_t receive_cb; + meshlink_channel_poll_cb_t poll_cb; }; /// Header for data packets routed between nodes diff --git a/src/utcp b/src/utcp index d5888c10..5d4cf9d0 160000 --- a/src/utcp +++ b/src/utcp @@ -1 +1 @@ -Subproject commit d5888c10a181d6247e407f480524d36be6319b3e +Subproject commit 5d4cf9d0eb85c7322298a2a0526132197e3bf633 -- 2.39.5