xvc_server: Make thread exit cleanly (#526)

This commit is contained in:
Marcus Comstedt 2025-03-10 21:25:13 +01:00 committed by GitHub
parent b2c2ae80c0
commit 703af08c91
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 50 additions and 45 deletions

View File

@ -156,60 +156,64 @@ void XVC_server::thread_listen()
maxfd = _sock; maxfd = _sock;
while (!_must_stop) { try {
fd_set read = conn, except = conn; while (!_must_stop) {
int fd; fd_set read = conn, except = conn;
int fd;
struct timeval tv; struct timeval tv;
tv.tv_sec = 1; tv.tv_sec = 1;
tv.tv_usec = 0; tv.tv_usec = 0;
if (select(maxfd + 1, &read, 0, &except, &tv) < 0) { if (select(maxfd + 1, &read, 0, &except, &tv) < 0) {
printError("select"); printError("select");
break; break;
} }
for (fd = 0; fd <= maxfd; ++fd) { for (fd = 0; fd <= maxfd; ++fd) {
if (FD_ISSET(fd, &read)) { if (FD_ISSET(fd, &read)) {
if (fd == _sock) { if (fd == _sock) {
int newfd; int newfd;
socklen_t nsize = sizeof(_sock_addr); socklen_t nsize = sizeof(_sock_addr);
newfd = accept(_sock, (struct sockaddr*) &_sock_addr, newfd = accept(_sock, (struct sockaddr*) &_sock_addr,
&nsize); &nsize);
printf("connection accepted - fd %d\n", newfd); printf("connection accepted - fd %d\n", newfd);
if (newfd < 0) { if (newfd < 0) {
throw std::runtime_error("accept"); throw std::runtime_error("accept");
} else { } else {
printInfo("setting TCP_NODELAY to 1\n"); printInfo("setting TCP_NODELAY to 1\n");
int flag = 1; int flag = 1;
int optResult = setsockopt(newfd, IPPROTO_TCP, int optResult = setsockopt(newfd, IPPROTO_TCP,
TCP_NODELAY, (char *)&flag, sizeof(int)); TCP_NODELAY, (char *)&flag, sizeof(int));
if (optResult < 0) if (optResult < 0)
throw std::runtime_error("TCP_NODELAY error"); throw std::runtime_error("TCP_NODELAY error");
if (newfd > maxfd) { if (newfd > maxfd) {
maxfd = newfd; maxfd = newfd;
}
FD_SET(newfd, &conn);
}
} else {
int ret = handle_data(fd);
if (ret != 0) {
printInfo("connection closed - fd " + std::to_string(fd));
close(fd);
FD_CLR(fd, &conn);
if (ret == 3)
throw std::runtime_error("communication failure");
} }
FD_SET(newfd, &conn);
}
} else {
int ret = handle_data(fd);
if (ret != 0) {
printInfo("connection closed - fd " + std::to_string(fd));
close(fd);
FD_CLR(fd, &conn);
if (ret == 3)
throw std::runtime_error("communication failure");
} }
} else if (FD_ISSET(fd, &except)) {
printWarn("connection aborted - fd " + std::to_string(fd));
close(fd);
FD_CLR(fd, &conn);
if (fd == _sock)
break;
} }
} else if (FD_ISSET(fd, &except)) {
printWarn("connection aborted - fd " + std::to_string(fd));
close(fd);
FD_CLR(fd, &conn);
if (fd == _sock)
break;
} }
} }
} catch (const std::runtime_error& e) {
std::cerr << "thread exiting with error: " << e.what() << std::endl;
} }
_is_stopped = true; _is_stopped = true;
} }
@ -224,6 +228,7 @@ bool XVC_server::listen_loop()
_must_stop = true; _must_stop = true;
close_connection(); close_connection();
while (!_is_stopped){} while (!_is_stopped){}
_thread->join();
delete _thread; delete _thread;
return true; return true;