]> git.meshlink.io Git - meshlink/blobdiff - src/meshlink.c
Fix race condition when calling meshlink_stop() immediately after meshlink_start().
[meshlink] / src / meshlink.c
index e9250e2509efd15e920e6ddc04c379d535fef00b..b3b18074b171c9d93b3217fcbde533b7a4a80326 100644 (file)
@@ -39,6 +39,7 @@ typedef struct {
 #include "node.h"
 #include "protocol.h"
 #include "route.h"
+#include "sockaddr.h"
 #include "utils.h"
 #include "xalloc.h"
 #include "ed25519/sha512.h"
@@ -944,6 +945,12 @@ bool meshlink_start(meshlink_handle_t *mesh) {
        
        logger(mesh, MESHLINK_DEBUG, "meshlink_start called\n");
 
+       if(mesh->listen_socket[0].tcp.fd < 0) {
+               logger(mesh, MESHLINK_ERROR, "Listening socket not open\n");
+               meshlink_errno = MESHLINK_ENETWORK;
+               return false;
+       }
+
        mesh->thedatalen = 0;
 
        // TODO: open listening sockets first
@@ -958,6 +965,8 @@ bool meshlink_start(meshlink_handle_t *mesh) {
 
        // Start the main thread
 
+       event_loop_start(&mesh->loop);
+
        if(pthread_create(&mesh->thread, NULL, meshlink_main_loop, mesh) != 0) {
                logger(mesh, MESHLINK_DEBUG, "Could not start thread: %s\n", strerror(errno));
                memset(&mesh->thread, 0, sizeof mesh->thread);
@@ -986,10 +995,16 @@ void meshlink_stop(meshlink_handle_t *mesh) {
        // Stop discovery
        discovery_stop(mesh);
 
-       // Shut down a listening socket to signal the main thread to shut down
+       pthread_mutex_lock(&(mesh->mesh_mutex));
+       logger(mesh, MESHLINK_DEBUG, "meshlink_stop called\n");
 
+       // Shut down the main thread
+       event_loop_stop(&mesh->loop);
+
+       // Send ourselves a UDP packet to kick the event loop
        listen_socket_t *s = &mesh->listen_socket[0];
-       shutdown(s->tcp.fd, SHUT_RDWR);
+       if(sendto(s->udp.fd, "", 1, MSG_NOSIGNAL, &s->sa.sa, SALEN(s->sa.sa)) == -1)
+               logger(mesh, MESHLINK_ERROR, "Could not send a UDP packet to ourself");
 
        // Wait for the main thread to finish
        pthread_mutex_unlock(&(mesh->mesh_mutex));
@@ -998,16 +1013,6 @@ void meshlink_stop(meshlink_handle_t *mesh) {
 
        mesh->threadstarted = false;
 
-       // Fix the socket
-       
-       closesocket(s->tcp.fd);
-       io_del(&mesh->loop, &s->tcp);
-       s->tcp.fd = setup_listen_socket(&s->sa);
-       if(s->tcp.fd < 0)
-               logger(mesh, MESHLINK_ERROR, "Could not repair listenen socket!");
-       else
-               io_add(&mesh->loop, &s->tcp, handle_new_meta_connection, s, s->tcp.fd, IO_READ);
-       
        pthread_mutex_unlock(&(mesh->mesh_mutex));
 }
 
@@ -1233,6 +1238,15 @@ char *meshlink_get_fingerprint(meshlink_handle_t *mesh, meshlink_node_t *node) {
        return fingerprint;
 }
 
+meshlink_node_t *meshlink_get_self(meshlink_handle_t *mesh) {
+       if(!mesh) {
+               meshlink_errno = MESHLINK_EINVAL;
+               return NULL;
+       }
+
+       return (meshlink_node_t *)mesh->self;
+}
+
 meshlink_node_t *meshlink_get_node(meshlink_handle_t *mesh, const char *name) {
        if(!mesh || !name) {
                meshlink_errno = MESHLINK_EINVAL;