]> git.meshlink.io Git - meshlink/blobdiff - test/channels-aio.c
Don't use assert() to check the results of pthread_*() calls.
[meshlink] / test / channels-aio.c
index 42cdadd5a5555cf15e7e1ee90c4d7f456387dfb4..c43f1da1edac717ab1217e7e4741703f7a40cc50 100644 (file)
@@ -1,9 +1,13 @@
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+
 #include <assert.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/time.h>
+#include <time.h>
 
 #include "meshlink.h"
 #include "utils.h"
@@ -15,7 +19,7 @@ static const size_t nchannels = 4; // number of simultaneous channels
 struct aio_info {
        int callbacks;
        size_t size;
-       struct timeval tv;
+       struct timespec ts;
        struct sync_flag flag;
 };
 
@@ -24,9 +28,9 @@ struct channel_info {
        struct aio_info aio_infos[2];
 };
 
-static size_t bar_received_len;
-static struct timeval bar_received_tv;
-static struct sync_flag bar_received_flag;
+static size_t b_received_len;
+static struct timespec b_received_ts;
+static struct sync_flag b_received_flag;
 
 static void aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const void *data, size_t len, void *priv) {
        (void)mesh;
@@ -35,7 +39,7 @@ static void aio_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, const v
        (void)len;
 
        struct aio_info *info = priv;
-       gettimeofday(&info->tv, NULL);
+       clock_gettime(CLOCK_MONOTONIC, &info->ts);
        info->callbacks++;
        info->size += len;
        set_sync_flag(&info->flag, true);
@@ -56,11 +60,11 @@ static void receive_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, con
        (void)channel;
        (void)data;
 
-       bar_received_len += len;
+       b_received_len += len;
 
-       if(bar_received_len >= smallsize) {
-               gettimeofday(&bar_received_tv, NULL);
-               set_sync_flag(&bar_received_flag, true);
+       if(b_received_len >= smallsize) {
+               clock_gettime(CLOCK_MONOTONIC, &b_received_ts);
+               set_sync_flag(&b_received_flag, true);
        }
 }
 
@@ -82,14 +86,14 @@ static bool accept_cb(meshlink_handle_t *mesh, meshlink_channel_t *channel, uint
        return true;
 }
 
-int main(int argc, char *argv[]) {
-       (void)argc;
-       (void)argv;
+int main(void) {
+       init_sync_flag(&b_received_flag);
+
+       meshlink_set_log_cb(NULL, MESHLINK_WARNING, log_cb);
 
        // Prepare data buffers
 
        char *outdata = malloc(size);
-
        assert(outdata);
 
        for(size_t i = 0; i < size; i++) {
@@ -105,6 +109,11 @@ int main(int argc, char *argv[]) {
        memset(out_infos, 0, sizeof(out_infos));
 
        for(size_t i = 0; i < nchannels; i++) {
+               init_sync_flag(&in_infos[i].aio_infos[0].flag);
+               init_sync_flag(&in_infos[i].aio_infos[1].flag);
+               init_sync_flag(&out_infos[i].aio_infos[0].flag);
+               init_sync_flag(&out_infos[i].aio_infos[1].flag);
+
                in_infos[i].data = malloc(size);
                assert(in_infos[i].data);
                out_infos[i].data = outdata;
@@ -112,70 +121,46 @@ int main(int argc, char *argv[]) {
 
        // Open two new meshlink instance.
 
-       meshlink_destroy("channels_aio_conf.1");
-       meshlink_destroy("channels_aio_conf.2");
-
-       meshlink_handle_t *mesh1 = meshlink_open("channels_aio_conf.1", "foo", "channels", DEV_CLASS_BACKBONE);
-       assert(mesh1);
-
-       meshlink_handle_t *mesh2 = meshlink_open("channels_aio_conf.2", "bar", "channels", DEV_CLASS_BACKBONE);
-       assert(mesh2);
-
-       mesh2->priv = in_infos;
-
-       meshlink_enable_discovery(mesh1, false);
-       meshlink_enable_discovery(mesh2, false);
-
-       // Import and export both side's data
-
-       meshlink_add_address(mesh1, "localhost");
-
-       char *data = meshlink_export(mesh1);
-       assert(data);
-       assert(meshlink_import(mesh2, data));
-       free(data);
-
-       data = meshlink_export(mesh2);
-       assert(data);
-       assert(meshlink_import(mesh1, data));
-       free(data);
+       meshlink_handle_t *mesh_a, *mesh_b;
+       open_meshlink_pair(&mesh_a, &mesh_b, "channels_aio");
 
        // Set the callbacks.
 
-       meshlink_set_channel_accept_cb(mesh1, reject_cb);
-       meshlink_set_channel_accept_cb(mesh2, accept_cb);
+       mesh_b->priv = in_infos;
+
+       meshlink_set_channel_accept_cb(mesh_a, reject_cb);
+       meshlink_set_channel_accept_cb(mesh_b, accept_cb);
 
        // Start both instances
 
-       assert(meshlink_start(mesh1));
-       assert(meshlink_start(mesh2));
+       start_meshlink_pair(mesh_a, mesh_b);
 
-       // Open channels from foo to bar.
+       // Open channels from a to b.
 
-       meshlink_node_t *bar = meshlink_get_node(mesh1, "bar");
-       assert(bar);
+       meshlink_node_t *b = meshlink_get_node(mesh_a, "b");
+       assert(b);
 
        meshlink_channel_t *channels[nchannels + 1];
 
        for(size_t i = 0; i < nchannels + 1; i++) {
-               channels[i] = meshlink_channel_open(mesh1, bar, i + 1, NULL, NULL, 0);
+               channels[i] = meshlink_channel_open(mesh_a, b, i + 1, NULL, NULL, 0);
                assert(channels[i]);
        }
 
        // Send a large buffer of data on each channel.
 
        for(size_t i = 0; i < nchannels; i++) {
-               assert(meshlink_channel_aio_send(mesh1, channels[i], outdata, size / 3, aio_cb, &out_infos[i].aio_infos[0]));
-               assert(meshlink_channel_aio_send(mesh1, channels[i], outdata + size / 3, size - size / 3, aio_cb, &out_infos[i].aio_infos[1]));
+               assert(meshlink_channel_aio_send(mesh_a, channels[i], outdata, size / 3, aio_cb, &out_infos[i].aio_infos[0]));
+               assert(meshlink_channel_aio_send(mesh_a, channels[i], outdata + size / 3, size - size / 3, aio_cb, &out_infos[i].aio_infos[1]));
        }
 
        // Send a little bit on the last channel using a regular send
 
-       assert(meshlink_channel_send(mesh1, channels[nchannels], outdata, smallsize) == smallsize);
+       assert(meshlink_channel_send(mesh_a, channels[nchannels], outdata, smallsize) == (ssize_t)smallsize);
 
        // Wait for everyone to finish.
 
-       assert(wait_sync_flag(&bar_received_flag, 10));
+       assert(wait_sync_flag(&b_received_flag, 10));
 
        for(size_t i = 0; i < nchannels; i++) {
                assert(wait_sync_flag(&out_infos[i].aio_infos[0].flag, 10));
@@ -186,7 +171,7 @@ int main(int argc, char *argv[]) {
 
        // Check that everything is correct.
 
-       assert(bar_received_len == smallsize);
+       assert(b_received_len == smallsize);
 
        for(size_t i = 0; i < nchannels; i++) {
                // Data should be transferred intact.
@@ -206,19 +191,16 @@ int main(int argc, char *argv[]) {
 
                // First batch of data should all be sent and received before the second batch
                for(size_t j = 0; j < nchannels; j++) {
-                       assert(timercmp(&out_infos[i].aio_infos[0].tv, &out_infos[j].aio_infos[1].tv, <=));
-                       assert(timercmp(&in_infos[i].aio_infos[0].tv, &in_infos[j].aio_infos[1].tv, <=));
+                       assert(timespec_lt(&out_infos[i].aio_infos[0].ts, &out_infos[j].aio_infos[1].ts));
+                       assert(timespec_lt(&in_infos[i].aio_infos[0].ts, &in_infos[j].aio_infos[1].ts));
                }
 
                // The non-AIO transfer should have completed before everything else
-               assert(timercmp(&out_infos[i].aio_infos[0].tv, &bar_received_tv, >=));
-               assert(timercmp(&in_infos[i].aio_infos[0].tv, &bar_received_tv, >=));
+               assert(!timespec_lt(&out_infos[i].aio_infos[0].ts, &b_received_ts));
+               assert(!timespec_lt(&in_infos[i].aio_infos[0].ts, &b_received_ts));
        }
 
        // Clean up.
 
-       meshlink_close(mesh2);
-       meshlink_close(mesh1);
-
-       return 0;
+       close_meshlink_pair(mesh_a, mesh_b);
 }