xvc_server: Make thread exit cleanly (#526)
This commit is contained in:
parent
b2c2ae80c0
commit
703af08c91
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue