From 84e02f6f2123197074b482b207a7cb13ff31a00f Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Thu, 15 May 2014 17:53:54 +0200 Subject: [PATCH] Make sure meshlink_stop() works as advertised. At least on Linux, one way to signal a sleeping select() call in the thread is to call shutdown() on the listening sockets. A subsequent accept() returns EINVAL, we use that as a cue to shut down the main loop. --- src/meshlink.c | 7 ++++++- src/net_socket.c | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/meshlink.c b/src/meshlink.c index 2aa79def..bfadf61b 100644 --- a/src/meshlink.c +++ b/src/meshlink.c @@ -828,7 +828,12 @@ bool meshlink_start(meshlink_handle_t *mesh) { } void meshlink_stop(meshlink_handle_t *mesh) { - // TODO: close the listening sockets to signal the main thread to shut down + // Shut down the listening sockets to signal the main thread to shut down + + for(int i = 0; i < mesh->listen_sockets; i++) { + shutdown(mesh->listen_socket[i].tcp.fd, SHUT_RDWR); + shutdown(mesh->listen_socket[i].udp.fd, SHUT_RDWR); + } // Wait for the main thread to finish diff --git a/src/net_socket.c b/src/net_socket.c index c6fc1242..3cbc5dd6 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -545,6 +545,11 @@ void handle_new_meta_connection(event_loop_t *loop, void *data, int flags) { fd = accept(l->tcp.fd, &sa.sa, &len); if(fd < 0) { + if(errno == EINVAL) { // TODO: check if Windows agrees + event_loop_stop(loop); + return; + } + logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno)); return; } -- 2.39.2