OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include <arpa/inet.h> | 5 #include <arpa/inet.h> |
6 #include <errno.h> | 6 #include <errno.h> |
7 #include <netdb.h> | 7 #include <netdb.h> |
8 #include <stdio.h> | 8 #include <stdio.h> |
9 #include <stdlib.h> | 9 #include <stdlib.h> |
10 #include <string.h> | 10 #include <string.h> |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 181 |
182 if (TEMP_FAILURE_RETRY(listen(fd, backlog)) != 0) { | 182 if (TEMP_FAILURE_RETRY(listen(fd, backlog)) != 0) { |
183 fprintf(stderr, "Error Listen: %s\n", strerror(errno)); | 183 fprintf(stderr, "Error Listen: %s\n", strerror(errno)); |
184 return -1; | 184 return -1; |
185 } | 185 } |
186 | 186 |
187 FDUtils::SetNonBlocking(fd); | 187 FDUtils::SetNonBlocking(fd); |
188 return fd; | 188 return fd; |
189 } | 189 } |
190 | 190 |
| 191 |
| 192 static bool IsTemporaryAcceptError(int error) { |
| 193 // On Linux a number of protocol errors should be treated as EAGAIN. |
| 194 // These are the ones for TCP/IP. |
| 195 return (error == EAGAIN) || (error == ENETDOWN) || (error == EPROTO) || |
| 196 (error == ENOPROTOOPT) || (error == EHOSTDOWN) || (error == ENONET) || |
| 197 (error == EHOSTUNREACH) || (error == EOPNOTSUPP) || |
| 198 (error == ENETUNREACH); |
| 199 } |
| 200 |
| 201 |
191 intptr_t ServerSocket::Accept(intptr_t fd) { | 202 intptr_t ServerSocket::Accept(intptr_t fd) { |
192 intptr_t socket; | 203 intptr_t socket; |
193 struct sockaddr clientaddr; | 204 struct sockaddr clientaddr; |
194 socklen_t addrlen = sizeof(clientaddr); | 205 socklen_t addrlen = sizeof(clientaddr); |
195 socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen)); | 206 socket = TEMP_FAILURE_RETRY(accept(fd, &clientaddr, &addrlen)); |
196 if (socket < 0) { | 207 if (socket == -1) { |
197 fprintf(stderr, "Error Accept: %s\n", strerror(errno)); | 208 if (IsTemporaryAcceptError(errno)) { |
| 209 // We need to signal to the caller that this is actually not an |
| 210 // error. We got woken up from the poll on the listening socket, |
| 211 // but there is no connection ready to be accepted. |
| 212 ASSERT(kTemporaryFailure != -1); |
| 213 socket = kTemporaryFailure; |
| 214 } |
198 } else { | 215 } else { |
199 FDUtils::SetNonBlocking(socket); | 216 FDUtils::SetNonBlocking(socket); |
200 } | 217 } |
201 return socket; | 218 return socket; |
202 } | 219 } |
OLD | NEW |