Index: runtime/bin/socket_linux.cc |
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc |
index 5f4096bb75f3120625ccbc2bb3fb705f70fdeeee..20a80de1562e4d7518abbb1c1ee65b1e597011d1 100644 |
--- a/runtime/bin/socket_linux.cc |
+++ b/runtime/bin/socket_linux.cc |
@@ -188,13 +188,30 @@ intptr_t ServerSocket::CreateBindListen(const char* host, |
return fd; |
} |
+ |
+static bool IsTemporaryAcceptError(int error) { |
+ // On Linux a number of protocol errors should be treated as EAGAIN. |
+ // These are the ones for TCP/IP. |
+ return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) || |
+ (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) || |
+ (error == EHOSTUNREACH) || (error == EOPNOTSUPP) || |
+ (error == ENETUNREACH); |
+} |
+ |
+ |
intptr_t ServerSocket::Accept(intptr_t fd) { |
intptr_t socket; |
struct sockaddr clientaddr; |
socklen_t addrlen = sizeof(clientaddr); |
socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen)); |
- if (socket < 0) { |
- fprintf(stderr, "Error Accept: %s\n", strerror(errno)); |
+ if (socket == -1) { |
+ if (IsTemporaryAcceptError(errno)) { |
+ // We need to signal to the caller that this is actually not an |
+ // error. We got woken up from the poll on the listening socket, |
+ // but there is no connection ready to be accepted. |
+ ASSERT(kTemporaryFailure != -1); |
+ socket = kTemporaryFailure; |
+ } |
} else { |
FDUtils::SetNonBlocking(socket); |
} |