From: Guus Sliepen Date: Fri, 6 Nov 2015 22:33:58 +0000 (+0100) Subject: Fix meshlink_stop() on Mac OS X. X-Git-Url: https://git.meshlink.io/?a=commitdiff_plain;h=d25cba261290114e9d50cc3e30b8ebda4d77fc40;p=meshlink Fix meshlink_stop() on Mac OS X. Mac OS X doesn't like shutdown(SHUT_RDWR) on listening sockets, and also doesn't allow reopening a listening socket right after closing the previous one on the same port. So avoid the whole business of closing and reopening sockets by stopping the event loop and then doing a dummy connect() to ourself to ensure select() in the network thread returns immediately. # Conflicts: # src/meshlink.c --- diff --git a/src/meshlink.c b/src/meshlink.c index c67be830..41297664 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -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" @@ -992,10 +993,17 @@ 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); + // Fake a connection to kick the event loop listen_socket_t *s = &mesh->listen_socket[0]; - shutdown(s->tcp.fd, SHUT_RDWR); + int fd = socket(s->sa.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); + connect(fd, &s->sa.sa, SALEN(s->sa.sa)); + close(fd); // Wait for the main thread to finish pthread_mutex_unlock(&(mesh->mesh_mutex)); @@ -1004,16 +1012,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)); }