unix: don't retry close() on EINTR

Linux 2.6 always closes the file descriptor, even on EINTR. Retrying the close()
call isn't merely useless, it's actively harmful - the file descriptor may have
been acquired by another thread.
This commit is contained in:
Ben Noordhuis 2012-01-18 15:06:15 +01:00
parent 52511b9ddc
commit dee86dd5b0
2 changed files with 8 additions and 20 deletions

View File

@ -790,23 +790,6 @@ int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) {
}
int uv__close(int fd) {
int status;
/*
* Retry on EINTR. You may think this is academic but on linux
* and probably other Unices too, close(2) is interruptible.
* Failing to handle EINTR is a common source of fd leaks.
*/
do {
status = close(fd);
}
while (status == -1 && errno == EINTR);
return status;
}
int uv__nonblock(int fd, int set) {
#if FIONBIO
return ioctl(fd, FIONBIO, &set);

View File

@ -154,14 +154,19 @@ enum {
UV_TCP_KEEPALIVE = 0x100 /* Turn on keep-alive. */
};
int uv__close(int fd);
/* core */
void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle, uv_handle_type type);
int uv__nonblock(int fd, int set) __attribute__((unused));
int uv__cloexec(int fd, int set) __attribute__((unused));
int uv__socket(int domain, int type, int protocol);
/* We used to handle EINTR in uv__close() but linux 2.6 will have closed the
* file descriptor anyway, even on EINTR. Retrying in that case isn't merely
* useless, it's actively harmful - the file descriptor may have been acquired
* by another thread.
*/
#define uv__close(fd) close(fd)
/* error */
uv_err_code uv_translate_sys_error(int sys_errno);
void uv_fatal_error(const int errorno, const char* syscall);