#include <pthread.h>
#include <sys/types.h>
#include <sys/ioctl.h>
-#include <sys/epoll.h>
+#include <sys/poll.h>
#include <signal.h>
#include <errno.h>
#include <ctype.h>
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;
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);
}
if (sock == -1) {
perror("accept");
- exit(1);
+ usleep(100000);
+ continue;
}
// Set the socket as nonblocking.
// 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)
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);