]> git.meshlink.io Git - meshlink/commitdiff
Add meshlink_set_channel_flags().
authorGuus Sliepen <guus@meshlink.io>
Tue, 23 Feb 2021 18:56:31 +0000 (19:56 +0100)
committerGuus Sliepen <guus@meshlink.io>
Tue, 23 Feb 2021 18:56:31 +0000 (19:56 +0100)
This allows changing some of the flags of a channel. Currently it can be
used to change MESHLINK_CHANNEL_NO_PARTIAL and MESHLINK_CHANNEL_DROP_LATE.

src/meshlink++.h
src/meshlink.c
src/meshlink.h
src/meshlink.sym
src/utcp.c
src/utcp.h
test/channels-no-partial.c

index 551913d4ba2a94ceb4df51852dd8595ce563a28d..b7ba5b9111c746eb81961d591e916b26f714fa37 100644 (file)
@@ -885,6 +885,19 @@ public:
                meshlink_set_channel_rcvbuf(handle, channel, size);
        }
 
+       /// Set the flags of a channel.
+       /** This function allows changing some of the channel flags.
+        *  Currently only MESHLINK_CHANNEL_NO_PARTIAL and MESHLINK_CHANNEL_DROP_LATE are supported, other flags are ignored.
+        *  These flags only affect the local side of the channel with the peer.
+        *  The changes take effect immediately.
+        *
+        *  @param channel   A handle for the channel.
+        *  @param flags     A bitwise-or'd combination of flags that set the semantics for this channel.
+        */
+       void set_channel_flags(channel *channel, uint32_t flags) {
+               meshlink_set_channel_flags(handle, channel, flags);
+       }
+
        /// Set the connection timeout used for channels to the given node.
        /** This sets the timeout after which unresponsive channels will be reported as closed.
         *  The timeout is set for all current and future channels to the given node.
index 31fc205aef72e745b6b3215de26392cd391cb7c8..fd8e2f9889f646d66e51f322eab7343abe49371f 100644 (file)
@@ -4082,6 +4082,20 @@ void meshlink_set_channel_rcvbuf(meshlink_handle_t *mesh, meshlink_channel_t *ch
        pthread_mutex_unlock(&mesh->mutex);
 }
 
+void meshlink_set_channel_flags(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint32_t flags) {
+       if(!mesh || !channel) {
+               meshlink_errno = MESHLINK_EINVAL;
+               return;
+       }
+
+       if(pthread_mutex_lock(&mesh->mutex) != 0) {
+               abort();
+       }
+
+       utcp_set_flags(channel->c, flags);
+       pthread_mutex_unlock(&mesh->mutex);
+}
+
 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) {
                abort();        // TODO: handle non-NULL data
index 1acd99b0663bd021ba6fc70a4e0ecfcb48ff319a..b3ccf8f0cf9b4ade4de87f28c15a36e2536d8cdd 100644 (file)
@@ -1381,6 +1381,19 @@ void meshlink_set_channel_sndbuf(struct meshlink_handle *mesh, struct meshlink_c
  */
 void meshlink_set_channel_rcvbuf(struct meshlink_handle *mesh, struct meshlink_channel *channel, size_t size);
 
+/// Set the flags of a channel.
+/** This function allows changing some of the channel flags.
+ *  Currently only MESHLINK_CHANNEL_NO_PARTIAL and MESHLINK_CHANNEL_DROP_LATE are supported, other flags are ignored.
+ *  These flags only affect the local side of the channel with the peer.
+ *  The changes take effect immediately.
+ *
+ *  \memberof meshlink_channel
+ *  @param mesh      A handle which represents an instance of MeshLink.
+ *  @param channel   A handle for the channel.
+ *  @param flags     A bitwise-or'd combination of flags that set the semantics for this channel.
+ */
+void meshlink_set_channel_flags(struct meshlink_handle *mesh, struct meshlink_channel *channel, uint32_t flags);
+
 /// 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.
index 51511ee9e1d5ed9a1eb8680306ac09f386657160..faa3517d0ca400169245df0051c288d4603d3ee9 100644 (file)
@@ -72,6 +72,7 @@ meshlink_send
 meshlink_set_blacklisted_cb
 meshlink_set_canonical_address
 meshlink_set_channel_accept_cb
+meshlink_set_channel_flags
 meshlink_set_channel_listen_cb
 meshlink_set_channel_poll_cb
 meshlink_set_channel_rcvbuf
index 20dd0aba049757ca30833779ec772c63ba685310..f237270f85c7173610c84b447ea314f617fd79dd 100644 (file)
@@ -2428,6 +2428,11 @@ void utcp_expect_data(struct utcp_connection *c, bool expect) {
        }
 }
 
+void utcp_set_flags(struct utcp_connection *c, uint32_t flags) {
+       c->flags &= ~UTCP_CHANGEABLE_FLAGS;
+       c->flags |= flags & UTCP_CHANGEABLE_FLAGS;
+}
+
 void utcp_offline(struct utcp *utcp, bool offline) {
        struct timespec now;
        clock_gettime(UTCP_CLOCK, &now);
index 2c537014da503548ea0633527ec38b7750691f9b..9921a3755e252dce0bbceb25f986231f33e0d591 100644 (file)
@@ -53,6 +53,7 @@ struct utcp_connection;
 
 #define UTCP_TCP 3
 #define UTCP_UDP 0
+#define UTCP_CHANGEABLE_FLAGS 0x18U
 
 typedef bool (*utcp_listen_t)(struct utcp *utcp, uint16_t port);
 typedef void (*utcp_accept_t)(struct utcp_connection *utcp_connection, uint16_t port);
@@ -118,6 +119,8 @@ size_t utcp_get_outq(struct utcp_connection *connection);
 
 void utcp_expect_data(struct utcp_connection *connection, bool expect);
 
+void utcp_set_flags(struct utcp_connection *connection, uint32_t flags);
+
 // Completely global options
 
 void utcp_set_clock_granularity(long granularity);
index c765456abff08e3de1b9c8a5151182e59c6ddd4d..43792be39ec7a671034995cdef47a94e61777457 100644 (file)
@@ -73,6 +73,19 @@ int main(int argc, char *argv[]) {
        assert_after(!meshlink_channel_get_sendq(mesh_a, channel), 30);
        assert(meshlink_channel_send(mesh_a, channel, buf, 512) == 512);
 
+       // Check that we can change the NO_PARTIAL flag
+
+       assert_after(!meshlink_channel_get_sendq(mesh_a, channel), 30);
+       meshlink_set_channel_sndbuf(mesh_a, channel, 256);
+       assert(meshlink_channel_send(mesh_a, channel, buf, 257) == -1);
+       meshlink_set_channel_flags(mesh_a, channel, 0);
+       assert(meshlink_channel_send(mesh_a, channel, buf, 257) == 256);
+
+       assert_after(!meshlink_channel_get_sendq(mesh_a, channel), 30);
+       meshlink_set_channel_flags(mesh_a, channel, MESHLINK_CHANNEL_NO_PARTIAL);
+       assert(meshlink_channel_send(mesh_a, channel, buf, 257) == -1);
+       assert(meshlink_channel_send(mesh_a, channel, buf, 256) == 256);
+
        // Clean up.
 
        close_meshlink_pair(mesh_a, mesh_b);