]> git.lizzy.rs Git - dragonnet.git/commitdiff
Properly interrupt accept thread
authorElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 30 Apr 2022 11:48:09 +0000 (13:48 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 30 Apr 2022 11:48:09 +0000 (13:48 +0200)
dragonnet/listen.c
dragonnet/listen.h
dragonnet/sock.h

index 24ba59d54c0611c359d56e7bea6065c81cdbc875..a0a8256c53ed9dd127979748fc086956d8e1d06d 100644 (file)
@@ -3,12 +3,15 @@
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #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)
index 03a23056086c9ac957b3db8a2556ac331f1d462e..9ee4802ad796e94a54a6712be5c85bc2a128dae4 100644 (file)
@@ -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 *);
index de1eb9128aa06a99951166179aa6dfe7889c9ad2..a02ca460977d505bb5a461ff4b2a8c00866625ff 100644 (file)
@@ -10,6 +10,7 @@
 #define MSG_MORE 0
 #else
 #include <sys/types.h>
+#include <sys/select.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>