From 61bac622cc696a98c9dcec8a78771c742232958e Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Mon, 8 Apr 2013 20:27:03 +0200 Subject: [PATCH] Make the acceptor thread stop nicely, so that it does not try to mess up the server while we are shutting down the server. --- cubemap.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/cubemap.cpp b/cubemap.cpp index 008126c..a52ee76 100644 --- a/cubemap.cpp +++ b/cubemap.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include @@ -58,6 +58,12 @@ int create_server_socket(int port) exit(1); } + // Set as non-blocking, so the acceptor thread can notice that we want to shut it down. + if (ioctl(server_sock, FIONBIO, &one) == -1) { + perror("ioctl(FIONBIO)"); + exit(1); + } + sockaddr_in6 addr; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; @@ -79,7 +85,23 @@ int create_server_socket(int port) void *acceptor_thread_run(void *arg) { int server_sock = int(intptr_t(arg)); - for ( ;; ) { + while (!hupped) { + // Since we are non-blocking, we need to wait for the right state first. + // Wait up to 50 ms, then check hupped. + pollfd pfd; + pfd.fd = server_sock; + pfd.events = POLLIN; + + int nfds = poll(&pfd, 1, 50); + if (nfds == 0 || (nfds == -1 && errno == EAGAIN)) { + continue; + } + if (nfds == -1) { + perror("poll"); + usleep(100000); + continue; + } + sockaddr_in6 addr; socklen_t addrlen = sizeof(addr); @@ -104,6 +126,7 @@ void *acceptor_thread_run(void *arg) // Pick a server, round-robin, and hand over the socket to it. servers->add_client(sock); } + return NULL; } // Serialize the given state to a file descriptor, and return the (still open) @@ -285,6 +308,11 @@ int main(int argc, char **argv) delete inputs[i]; // TODO: serialize instead of using libcurl. } + if (pthread_join(acceptor_thread, NULL) == -1) { + perror("pthread_join"); + exit(1); + } + CubemapStateProto state; state.set_server_sock(server_sock); state.set_port(port); -- 2.39.2