| 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);
|
| }
|
|
|