"...git@developer.sourcefind.cn:renzhc/diffusers_dcu.git" did not exist on "44c3101685f2cb6807b7157587d4da450ac629c1"
Unverified Commit 83f71466 authored by mszarma's avatar mszarma Committed by GitHub
Browse files

Handle EINTR in TCP layer (#1766)



Added handling EINTR signal by
retrying when returned value and
errno are related to EINTR interrupt
error which my appear during tcp
function execution.
Added information about EAGAIN timeout
failure in accept stage.
Added printing out errno in logs.
Co-authored-by: default avatarChao Ma <mctt90@gmail.com>
parent 27cad329
...@@ -26,7 +26,7 @@ TCPSocket::TCPSocket() { ...@@ -26,7 +26,7 @@ TCPSocket::TCPSocket() {
// init socket // init socket
socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (socket_ < 0) { if (socket_ < 0) {
LOG(FATAL) << "Can't create new socket."; LOG(FATAL) << "Can't create new socket. Errno=" << errno;
} }
} }
...@@ -39,11 +39,15 @@ bool TCPSocket::Connect(const char * ip, int port) { ...@@ -39,11 +39,15 @@ bool TCPSocket::Connect(const char * ip, int port) {
sa_server.sin_family = AF_INET; sa_server.sin_family = AF_INET;
sa_server.sin_port = htons(port); sa_server.sin_port = htons(port);
if (0 < inet_pton(AF_INET, ip, &sa_server.sin_addr) && int retval = 0;
0 <= connect(socket_, reinterpret_cast<SA*>(&sa_server), do { // retry if EINTR failure appears
sizeof(sa_server))) { if (0 < inet_pton(AF_INET, ip, &sa_server.sin_addr) &&
return true; 0 <= (retval = connect(socket_, reinterpret_cast<SA*>(&sa_server),
} sizeof(sa_server)))) {
return true;
}
} while (retval == -1 && errno == EINTR);
return false; return false;
} }
...@@ -51,23 +55,28 @@ bool TCPSocket::Bind(const char * ip, int port) { ...@@ -51,23 +55,28 @@ bool TCPSocket::Bind(const char * ip, int port) {
SAI sa_server; SAI sa_server;
sa_server.sin_family = AF_INET; sa_server.sin_family = AF_INET;
sa_server.sin_port = htons(port); sa_server.sin_port = htons(port);
int retval = 0;
if (0 < inet_pton(AF_INET, ip, &sa_server.sin_addr) && do { // retry if EINTR failure appears
0 <= bind(socket_, reinterpret_cast<SA*>(&sa_server), if (0 < inet_pton(AF_INET, ip, &sa_server.sin_addr) &&
sizeof(sa_server))) { 0 <= (retval = bind(socket_, reinterpret_cast<SA*>(&sa_server),
return true; sizeof(sa_server)))) {
} return true;
}
LOG(ERROR) << "Failed bind on " << ip << ":" << port; } while (retval == -1 && errno == EINTR);
LOG(ERROR) << "Failed bind on " << ip << ":" << port << " ,errno=" << errno;
return false; return false;
} }
bool TCPSocket::Listen(int max_connection) { bool TCPSocket::Listen(int max_connection) {
if (0 <= listen(socket_, max_connection)) { int retval;
return true; do { // retry if EINTR failure appears
} if (0 <= (retval = listen(socket_, max_connection))) {
return true;
LOG(ERROR) << "Failed listen on socket fd: " << socket_; }
} while (retval == -1 && errno == EINTR);
LOG(ERROR) << "Failed listen on socket fd: " << socket_ << " ,errno=" << errno;
return false; return false;
} }
...@@ -76,9 +85,13 @@ bool TCPSocket::Accept(TCPSocket * socket, std::string * ip, int * port) { ...@@ -76,9 +85,13 @@ bool TCPSocket::Accept(TCPSocket * socket, std::string * ip, int * port) {
SAI sa_client; SAI sa_client;
socklen_t len = sizeof(sa_client); socklen_t len = sizeof(sa_client);
sock_client = accept(socket_, reinterpret_cast<SA*>(&sa_client), &len); do { // retry if EINTR failure appears
sock_client = accept(socket_, reinterpret_cast<SA*>(&sa_client), &len);
} while (sock_client == -1 && errno == EINTR);
if (sock_client < 0) { if (sock_client < 0) {
LOG(ERROR) << "Failed accept connection on " << *ip << ":" << *port; LOG(ERROR) << "Failed accept connection on " << *ip << ":" << *port
<< " ,errno=" << errno << (errno == EAGAIN ? " SO_RCVTIMEO timeout reached" : "");
return false; return false;
} }
...@@ -164,11 +177,23 @@ void TCPSocket::Close() { ...@@ -164,11 +177,23 @@ void TCPSocket::Close() {
} }
int64_t TCPSocket::Send(const char * data, int64_t len_data) { int64_t TCPSocket::Send(const char * data, int64_t len_data) {
return send(socket_, data, len_data, 0); int64_t number_send;
do { // retry if EINTR failure appears
number_send = send(socket_, data, len_data, 0);
} while (number_send == -1 && errno == EINTR);
return number_send;
} }
int64_t TCPSocket::Receive(char * buffer, int64_t size_buffer) { int64_t TCPSocket::Receive(char * buffer, int64_t size_buffer) {
return recv(socket_, buffer, size_buffer, 0); int64_t number_recv;
do { // retry if EINTR failure appears
number_recv = recv(socket_, buffer, size_buffer, 0);
} while (number_recv == -1 && errno == EINTR);
return number_recv;
} }
int TCPSocket::Socket() const { int TCPSocket::Socket() const {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment