linux: simplify uv__accept()
Assume the presence of the accept4() system call on Linux. It was added in 2.6.28 and our baseline is 2.6.32. That lets us get rid of the system call wrapper and the fallback logic in uv__accept(). PR-URL: https://github.com/libuv/libuv/pull/2665 Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
9f1a052094
commit
067473ed5c
@ -71,17 +71,12 @@ extern char** environ;
|
||||
# include <sys/sysctl.h>
|
||||
# include <sys/filio.h>
|
||||
# include <sys/wait.h>
|
||||
# if defined(__FreeBSD__)
|
||||
# if defined(__FreeBSD__) || defined(__linux__)
|
||||
# define uv__accept4 accept4
|
||||
# endif
|
||||
# if defined(__NetBSD__)
|
||||
# define uv__accept4(a, b, c, d) paccept((a), (b), (c), NULL, (d))
|
||||
# endif
|
||||
# if (defined(__FreeBSD__) && __FreeBSD__ >= 10) || \
|
||||
defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
# define UV__SOCK_NONBLOCK SOCK_NONBLOCK
|
||||
# define UV__SOCK_CLOEXEC SOCK_CLOEXEC
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
|
||||
@ -469,50 +464,32 @@ int uv__accept(int sockfd) {
|
||||
int peerfd;
|
||||
int err;
|
||||
|
||||
(void) &err;
|
||||
assert(sockfd >= 0);
|
||||
|
||||
while (1) {
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
static int no_accept4;
|
||||
do
|
||||
#ifdef uv__accept4
|
||||
peerfd = uv__accept4(sockfd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
|
||||
#else
|
||||
peerfd = accept(sockfd, NULL, NULL);
|
||||
#endif
|
||||
while (peerfd == -1 && errno == EINTR);
|
||||
|
||||
if (no_accept4)
|
||||
goto skip;
|
||||
if (peerfd == -1)
|
||||
return UV__ERR(errno);
|
||||
|
||||
peerfd = uv__accept4(sockfd,
|
||||
NULL,
|
||||
NULL,
|
||||
UV__SOCK_NONBLOCK|UV__SOCK_CLOEXEC);
|
||||
if (peerfd != -1)
|
||||
return peerfd;
|
||||
#ifndef uv__accept4
|
||||
err = uv__cloexec(peerfd, 1);
|
||||
if (err == 0)
|
||||
err = uv__nonblock(peerfd, 1);
|
||||
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (errno != ENOSYS)
|
||||
return UV__ERR(errno);
|
||||
|
||||
no_accept4 = 1;
|
||||
skip:
|
||||
if (err != 0) {
|
||||
uv__close(peerfd);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
peerfd = accept(sockfd, NULL, NULL);
|
||||
if (peerfd == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return UV__ERR(errno);
|
||||
}
|
||||
|
||||
err = uv__cloexec(peerfd, 1);
|
||||
if (err == 0)
|
||||
err = uv__nonblock(peerfd, 1);
|
||||
|
||||
if (err) {
|
||||
uv__close(peerfd);
|
||||
return err;
|
||||
}
|
||||
|
||||
return peerfd;
|
||||
}
|
||||
return peerfd;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -33,12 +33,6 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__i386__)
|
||||
# ifndef __NR_socketcall
|
||||
# define __NR_socketcall 102
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__arm__)
|
||||
# if defined(__thumb__) || defined(__ARM_EABI__)
|
||||
# define UV_SYSCALL_BASE 0
|
||||
@ -47,16 +41,6 @@
|
||||
# endif
|
||||
#endif /* __arm__ */
|
||||
|
||||
#ifndef __NR_accept4
|
||||
# if defined(__x86_64__)
|
||||
# define __NR_accept4 288
|
||||
# elif defined(__i386__)
|
||||
/* Nothing. Handled through socketcall(). */
|
||||
# elif defined(__arm__)
|
||||
# define __NR_accept4 (UV_SYSCALL_BASE + 366)
|
||||
# endif
|
||||
#endif /* __NR_accept4 */
|
||||
|
||||
#ifndef __NR_eventfd
|
||||
# if defined(__x86_64__)
|
||||
# define __NR_eventfd 284
|
||||
@ -219,35 +203,6 @@
|
||||
# endif
|
||||
#endif /* __NR_getrandom */
|
||||
|
||||
int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
|
||||
#if defined(__i386__)
|
||||
unsigned long args[4];
|
||||
int r;
|
||||
|
||||
args[0] = (unsigned long) fd;
|
||||
args[1] = (unsigned long) addr;
|
||||
args[2] = (unsigned long) addrlen;
|
||||
args[3] = (unsigned long) flags;
|
||||
|
||||
r = syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args);
|
||||
|
||||
/* socketcall() raises EINVAL when SYS_ACCEPT4 is not supported but so does
|
||||
* a bad flags argument. Try to distinguish between the two cases.
|
||||
*/
|
||||
if (r == -1)
|
||||
if (errno == EINVAL)
|
||||
if ((flags & ~(UV__SOCK_CLOEXEC|UV__SOCK_NONBLOCK)) == 0)
|
||||
errno = ENOSYS;
|
||||
|
||||
return r;
|
||||
#elif defined(__NR_accept4)
|
||||
return syscall(__NR_accept4, fd, addr, addrlen, flags);
|
||||
#else
|
||||
return errno = ENOSYS, -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int uv__eventfd(unsigned int count) {
|
||||
#if defined(__NR_eventfd)
|
||||
return syscall(__NR_eventfd, count);
|
||||
|
||||
@ -123,7 +123,6 @@ struct uv__mmsghdr {
|
||||
unsigned int msg_len;
|
||||
};
|
||||
|
||||
int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags);
|
||||
int uv__eventfd(unsigned int count);
|
||||
int uv__eventfd2(unsigned int count, int flags);
|
||||
int uv__inotify_init(void);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user