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;
while (!_must_stop) {
fd_set read = conn, except = conn;
int fd;
try {
while (!_must_stop) {
fd_set read = conn, except = conn;
int fd;
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
if (select(maxfd + 1, &read, 0, &except, &tv) < 0) {
printError("select");
break;
}
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
if (select(maxfd + 1, &read, 0, &except, &tv) < 0) {
printError("select");
break;
}
for (fd = 0; fd <= maxfd; ++fd) {
if (FD_ISSET(fd, &read)) {
if (fd == _sock) {
int newfd;
socklen_t nsize = sizeof(_sock_addr);
for (fd = 0; fd <= maxfd; ++fd) {
if (FD_ISSET(fd, &read)) {
if (fd == _sock) {
int newfd;
socklen_t nsize = sizeof(_sock_addr);
newfd = accept(_sock, (struct sockaddr*) &_sock_addr,
&nsize);
newfd = accept(_sock, (struct sockaddr*) &_sock_addr,
&nsize);
printf("connection accepted - fd %d\n", newfd);
if (newfd < 0) {
throw std::runtime_error("accept");
} else {
printInfo("setting TCP_NODELAY to 1\n");
int flag = 1;
int optResult = setsockopt(newfd, IPPROTO_TCP,
TCP_NODELAY, (char *)&flag, sizeof(int));
if (optResult < 0)
throw std::runtime_error("TCP_NODELAY error");
if (newfd > maxfd) {
maxfd = newfd;
printf("connection accepted - fd %d\n", newfd);
if (newfd < 0) {
throw std::runtime_error("accept");
} else {
printInfo("setting TCP_NODELAY to 1\n");
int flag = 1;
int optResult = setsockopt(newfd, IPPROTO_TCP,
TCP_NODELAY, (char *)&flag, sizeof(int));
if (optResult < 0)
throw std::runtime_error("TCP_NODELAY error");
if (newfd > maxfd) {
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;
}
@ -224,6 +228,7 @@ bool XVC_server::listen_loop()
_must_stop = true;
close_connection();
while (!_is_stopped){}
_thread->join();
delete _thread;
return true;