From 4783d7059eb7cd55600c64ee56adf5e57ff60e93 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sat, 30 Apr 2022 13:48:09 +0200 Subject: [PATCH] Properly interrupt accept thread --- dragonnet/listen.c | 41 ++++++++++++++++++++++++++++++++++++++--- dragonnet/listen.h | 3 +++ dragonnet/sock.h | 1 + 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/dragonnet/listen.c b/dragonnet/listen.c index 24ba59d..a0a8256 100644 --- a/dragonnet/listen.c +++ b/dragonnet/listen.c @@ -3,12 +3,15 @@ #include #include #include +#include #include "addr.h" #include "error.h" #include "listen.h" #include "recv.h" #include "sock.h" +#define mymax(a, b) ((a) > (b) ? (a) : (b)) + // ---- // Peer // ---- @@ -106,10 +109,34 @@ static void *listener_main(void *g_listener) struct sockaddr_storage clt_addr; socklen_t clt_addrlen = sizeof clt_addr; + struct timeval *tv = NULL; + + fd_set set; + FD_ZERO(&set); + FD_SET(l->sock, &set); + int nfds = l->sock; + +#ifdef _WIN32 + // on windows, we can't listen on the pipe, set timeout instead + tv = &(struct timeval) {1, 0}; +#else // _WIN32 + FD_SET(l->intr[0], &set); + + if (nfds < l->intr[0]) + nfds = l->intr[0]; +#endif // _WIN32 + + if (select(nfds + 1, &set, NULL, NULL, tv) < 0) { + dragonnet_perror("select"); + continue; + } + + if (!FD_ISSET(l->sock, &set)) + continue; + int clt_sock = accept(l->sock, (struct sockaddr *) &clt_addr, &clt_addrlen); if (clt_sock < 0) { - if (!dragonnet_isintrerr()) - dragonnet_perror("accept"); + dragonnet_perror("accept"); continue; } @@ -131,6 +158,9 @@ static void *listener_main(void *g_listener) void dragonnet_listener_run(DragonnetListener *l) { +#ifndef _WIN32 + pipe(l->intr); +#endif // _WIN32 pthread_create(&l->accept_thread, NULL, &listener_main, l); } @@ -138,8 +168,13 @@ void dragonnet_listener_close(DragonnetListener *l) { l->active = false; - pthread_kill(l->accept_thread, SIGINT); +#ifndef _WIN32 + close(l->intr[1]); +#endif // _WIN32 pthread_join(l->accept_thread, NULL); +#ifndef _WIN32 + close(l->intr[0]); +#endif // _WIN32 } void dragonnet_listener_delete(DragonnetListener *l) diff --git a/dragonnet/listen.h b/dragonnet/listen.h index 03a2305..9ee4802 100644 --- a/dragonnet/listen.h +++ b/dragonnet/listen.h @@ -10,6 +10,9 @@ typedef struct { pthread_t accept_thread; bool active; +#ifndef _WIN32 + int intr[2]; +#endif // _WIN32 void (*on_connect)(DragonnetPeer *); void (*on_disconnect)(DragonnetPeer *); diff --git a/dragonnet/sock.h b/dragonnet/sock.h index de1eb91..a02ca46 100644 --- a/dragonnet/sock.h +++ b/dragonnet/sock.h @@ -10,6 +10,7 @@ #define MSG_MORE 0 #else #include +#include #include #include #include -- 2.44.0