doc: bump min supported linux and freebsd versions (#3830)
The old Linux baseline was essentially RHEL 6 but that distro has been out of support for two years now. Move to RHEL 7. This commit also moves FreeBSD to tier 2 because it isn't actually part of libuv's CI matrix, only Node's. Fixes: https://github.com/libuv/libuv/issues/3822
This commit is contained in:
parent
238ba3b625
commit
8ddffeeea3
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
| System | Support type | Supported versions | Notes |
|
| System | Support type | Supported versions | Notes |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | |
|
| GNU/Linux | Tier 1 | Linux >= 3.10 with glibc >= 2.17 | |
|
||||||
| macOS | Tier 1 | macOS >= 10.15 | Current and previous macOS release |
|
| macOS | Tier 1 | macOS >= 10.15 | Current and previous macOS release |
|
||||||
| Windows | Tier 1 | >= Windows 8 | VS 2015 and later are supported |
|
| Windows | Tier 1 | >= Windows 8 | VS 2015 and later are supported |
|
||||||
| FreeBSD | Tier 1 | >= 10 | |
|
| FreeBSD | Tier 2 | >= 12 | |
|
||||||
| AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix |
|
| AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix |
|
||||||
| IBM i | Tier 2 | >= IBM i 7.2 | Maintainers: @libuv/ibmi |
|
| IBM i | Tier 2 | >= IBM i 7.2 | Maintainers: @libuv/ibmi |
|
||||||
| z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos |
|
| z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos |
|
||||||
|
|||||||
@ -269,30 +269,6 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
|
||||||
#if __FreeBSD__ >= 11 && !defined(__DragonFly__)
|
|
||||||
return sendmmsg(fd,
|
|
||||||
(struct mmsghdr*) mmsg,
|
|
||||||
vlen,
|
|
||||||
0 /* flags */);
|
|
||||||
#else
|
|
||||||
return errno = ENOSYS, -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
|
||||||
#if __FreeBSD__ >= 11 && !defined(__DragonFly__)
|
|
||||||
return recvmmsg(fd,
|
|
||||||
(struct mmsghdr*) mmsg,
|
|
||||||
vlen,
|
|
||||||
0 /* flags */,
|
|
||||||
NULL /* timeout */);
|
|
||||||
#else
|
|
||||||
return errno = ENOSYS, -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
uv__fs_copy_file_range(int fd_in,
|
uv__fs_copy_file_range(int fd_in,
|
||||||
off_t* off_in,
|
off_t* off_in,
|
||||||
|
|||||||
@ -411,22 +411,6 @@ int uv__getsockpeername(const uv_handle_t* handle,
|
|||||||
struct sockaddr* name,
|
struct sockaddr* name,
|
||||||
int* namelen);
|
int* namelen);
|
||||||
|
|
||||||
#if defined(__linux__) || \
|
|
||||||
defined(__FreeBSD__) || \
|
|
||||||
defined(__FreeBSD_kernel__) || \
|
|
||||||
defined(__DragonFly__)
|
|
||||||
#define HAVE_MMSG 1
|
|
||||||
struct uv__mmsghdr {
|
|
||||||
struct msghdr msg_hdr;
|
|
||||||
unsigned int msg_len;
|
|
||||||
};
|
|
||||||
|
|
||||||
int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen);
|
|
||||||
int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen);
|
|
||||||
#else
|
|
||||||
#define HAVE_MMSG 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__sun)
|
#if defined(__sun)
|
||||||
#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L
|
#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L
|
||||||
size_t strnlen(const char* s, size_t maxlen);
|
size_t strnlen(const char* s, size_t maxlen);
|
||||||
|
|||||||
102
src/unix/linux.c
102
src/unix/linux.c
@ -55,22 +55,6 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif /* __arm__ */
|
#endif /* __arm__ */
|
||||||
|
|
||||||
#ifndef __NR_recvmmsg
|
|
||||||
# if defined(__x86_64__)
|
|
||||||
# define __NR_recvmmsg 299
|
|
||||||
# elif defined(__arm__)
|
|
||||||
# define __NR_recvmmsg (UV_SYSCALL_BASE + 365)
|
|
||||||
# endif
|
|
||||||
#endif /* __NR_recvmsg */
|
|
||||||
|
|
||||||
#ifndef __NR_sendmmsg
|
|
||||||
# if defined(__x86_64__)
|
|
||||||
# define __NR_sendmmsg 307
|
|
||||||
# elif defined(__arm__)
|
|
||||||
# define __NR_sendmmsg (UV_SYSCALL_BASE + 374)
|
|
||||||
# endif
|
|
||||||
#endif /* __NR_sendmmsg */
|
|
||||||
|
|
||||||
#ifndef __NR_copy_file_range
|
#ifndef __NR_copy_file_range
|
||||||
# if defined(__x86_64__)
|
# if defined(__x86_64__)
|
||||||
# define __NR_copy_file_range 326
|
# define __NR_copy_file_range 326
|
||||||
@ -1796,89 +1780,3 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
|
|||||||
void uv__fs_event_close(uv_fs_event_t* handle) {
|
void uv__fs_event_close(uv_fs_event_t* handle) {
|
||||||
uv_fs_event_stop(handle);
|
uv_fs_event_stop(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
|
||||||
#if defined(__i386__)
|
|
||||||
unsigned long args[4];
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
args[0] = (unsigned long) fd;
|
|
||||||
args[1] = (unsigned long) mmsg;
|
|
||||||
args[2] = (unsigned long) vlen;
|
|
||||||
args[3] = /* flags */ 0;
|
|
||||||
|
|
||||||
/* socketcall() raises EINVAL when SYS_SENDMMSG is not supported. */
|
|
||||||
rc = syscall(/* __NR_socketcall */ 102, 20 /* SYS_SENDMMSG */, args);
|
|
||||||
if (rc == -1)
|
|
||||||
if (errno == EINVAL)
|
|
||||||
errno = ENOSYS;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
#elif defined(__NR_sendmmsg)
|
|
||||||
return syscall(__NR_sendmmsg, fd, mmsg, vlen, /* flags */ 0);
|
|
||||||
#else
|
|
||||||
return errno = ENOSYS, -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__recvmmsg_unpoison(struct uv__mmsghdr* mmsg, int rc) {
|
|
||||||
struct uv__mmsghdr* m;
|
|
||||||
struct msghdr* h;
|
|
||||||
struct iovec* v;
|
|
||||||
size_t j;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < rc; i++) {
|
|
||||||
m = mmsg + i;
|
|
||||||
uv__msan_unpoison(m, sizeof(*m));
|
|
||||||
|
|
||||||
h = &m->msg_hdr;
|
|
||||||
if (h->msg_name != NULL)
|
|
||||||
uv__msan_unpoison(h->msg_name, h->msg_namelen);
|
|
||||||
|
|
||||||
if (h->msg_iov != NULL)
|
|
||||||
uv__msan_unpoison(h->msg_iov, h->msg_iovlen * sizeof(*h->msg_iov));
|
|
||||||
|
|
||||||
for (j = 0; j < h->msg_iovlen; j++) {
|
|
||||||
v = h->msg_iov + j;
|
|
||||||
uv__msan_unpoison(v->iov_base, v->iov_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (h->msg_control != NULL)
|
|
||||||
uv__msan_unpoison(h->msg_control, h->msg_controllen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
|
|
||||||
#if defined(__i386__)
|
|
||||||
unsigned long args[5];
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
args[0] = (unsigned long) fd;
|
|
||||||
args[1] = (unsigned long) mmsg;
|
|
||||||
args[2] = (unsigned long) vlen;
|
|
||||||
args[3] = /* flags */ 0;
|
|
||||||
args[4] = /* timeout */ 0;
|
|
||||||
|
|
||||||
/* socketcall() raises EINVAL when SYS_RECVMMSG is not supported. */
|
|
||||||
rc = syscall(/* __NR_socketcall */ 102, 19 /* SYS_RECVMMSG */, args);
|
|
||||||
uv__recvmmsg_unpoison(mmsg, rc);
|
|
||||||
if (rc == -1)
|
|
||||||
if (errno == EINVAL)
|
|
||||||
errno = ENOSYS;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
#elif defined(__NR_recvmmsg)
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = syscall(__NR_recvmmsg, fd, mmsg, vlen, /* flags */ 0, /* timeout */ 0);
|
|
||||||
uv__recvmmsg_unpoison(mmsg, rc);
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
#else
|
|
||||||
return errno = ENOSYS, -1;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|||||||
@ -54,36 +54,6 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
|
|||||||
int domain,
|
int domain,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
#if HAVE_MMSG
|
|
||||||
|
|
||||||
#define UV__MMSG_MAXWIDTH 20
|
|
||||||
|
|
||||||
static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf);
|
|
||||||
static void uv__udp_sendmmsg(uv_udp_t* handle);
|
|
||||||
|
|
||||||
static int uv__recvmmsg_avail;
|
|
||||||
static int uv__sendmmsg_avail;
|
|
||||||
static uv_once_t once = UV_ONCE_INIT;
|
|
||||||
|
|
||||||
static void uv__udp_mmsg_init(void) {
|
|
||||||
int ret;
|
|
||||||
int s;
|
|
||||||
s = uv__socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (s < 0)
|
|
||||||
return;
|
|
||||||
ret = uv__sendmmsg(s, NULL, 0);
|
|
||||||
if (ret == 0 || errno != ENOSYS) {
|
|
||||||
uv__sendmmsg_avail = 1;
|
|
||||||
uv__recvmmsg_avail = 1;
|
|
||||||
} else {
|
|
||||||
ret = uv__recvmmsg(s, NULL, 0);
|
|
||||||
if (ret == 0 || errno != ENOSYS)
|
|
||||||
uv__recvmmsg_avail = 1;
|
|
||||||
}
|
|
||||||
uv__close(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void uv__udp_close(uv_udp_t* handle) {
|
void uv__udp_close(uv_udp_t* handle) {
|
||||||
uv__io_close(handle->loop, &handle->io_watcher);
|
uv__io_close(handle->loop, &handle->io_watcher);
|
||||||
@ -183,11 +153,11 @@ static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_MMSG
|
|
||||||
static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
|
static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
|
||||||
struct sockaddr_in6 peers[UV__MMSG_MAXWIDTH];
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
struct iovec iov[UV__MMSG_MAXWIDTH];
|
struct sockaddr_in6 peers[20];
|
||||||
struct uv__mmsghdr msgs[UV__MMSG_MAXWIDTH];
|
struct iovec iov[ARRAY_SIZE(peers)];
|
||||||
|
struct mmsghdr msgs[ARRAY_SIZE(peers)];
|
||||||
ssize_t nread;
|
ssize_t nread;
|
||||||
uv_buf_t chunk_buf;
|
uv_buf_t chunk_buf;
|
||||||
size_t chunks;
|
size_t chunks;
|
||||||
@ -212,7 +182,7 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
nread = uv__recvmmsg(handle->io_watcher.fd, msgs, chunks);
|
nread = recvmmsg(handle->io_watcher.fd, msgs, chunks, 0, NULL);
|
||||||
while (nread == -1 && errno == EINTR);
|
while (nread == -1 && errno == EINTR);
|
||||||
|
|
||||||
if (nread < 1) {
|
if (nread < 1) {
|
||||||
@ -240,8 +210,10 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
|
|||||||
handle->recv_cb(handle, 0, buf, NULL, UV_UDP_MMSG_FREE);
|
handle->recv_cb(handle, 0, buf, NULL, UV_UDP_MMSG_FREE);
|
||||||
}
|
}
|
||||||
return nread;
|
return nread;
|
||||||
|
#else /* __linux__ || ____FreeBSD__ || __FreeBSD_kernel__ */
|
||||||
|
return UV_ENOSYS;
|
||||||
|
#endif /* __linux__ || ____FreeBSD__ || __FreeBSD_kernel__ */
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void uv__udp_recvmsg(uv_udp_t* handle) {
|
static void uv__udp_recvmsg(uv_udp_t* handle) {
|
||||||
struct sockaddr_storage peer;
|
struct sockaddr_storage peer;
|
||||||
@ -268,14 +240,12 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
|
|||||||
}
|
}
|
||||||
assert(buf.base != NULL);
|
assert(buf.base != NULL);
|
||||||
|
|
||||||
#if HAVE_MMSG
|
|
||||||
if (uv_udp_using_recvmmsg(handle)) {
|
if (uv_udp_using_recvmmsg(handle)) {
|
||||||
nread = uv__udp_recvmmsg(handle, &buf);
|
nread = uv__udp_recvmmsg(handle, &buf);
|
||||||
if (nread > 0)
|
if (nread > 0)
|
||||||
count -= nread;
|
count -= nread;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
memset(&h, 0, sizeof(h));
|
memset(&h, 0, sizeof(h));
|
||||||
memset(&peer, 0, sizeof(peer));
|
memset(&peer, 0, sizeof(peer));
|
||||||
@ -311,11 +281,11 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
|
|||||||
&& handle->recv_cb != NULL);
|
&& handle->recv_cb != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_MMSG
|
static void uv__udp_sendmsg(uv_udp_t* handle) {
|
||||||
static void uv__udp_sendmmsg(uv_udp_t* handle) {
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
uv_udp_send_t* req;
|
uv_udp_send_t* req;
|
||||||
struct uv__mmsghdr h[UV__MMSG_MAXWIDTH];
|
struct mmsghdr h[20];
|
||||||
struct uv__mmsghdr *p;
|
struct mmsghdr* p;
|
||||||
QUEUE* q;
|
QUEUE* q;
|
||||||
ssize_t npkts;
|
ssize_t npkts;
|
||||||
size_t pkts;
|
size_t pkts;
|
||||||
@ -326,7 +296,7 @@ static void uv__udp_sendmmsg(uv_udp_t* handle) {
|
|||||||
|
|
||||||
write_queue_drain:
|
write_queue_drain:
|
||||||
for (pkts = 0, q = QUEUE_HEAD(&handle->write_queue);
|
for (pkts = 0, q = QUEUE_HEAD(&handle->write_queue);
|
||||||
pkts < UV__MMSG_MAXWIDTH && q != &handle->write_queue;
|
pkts < ARRAY_SIZE(h) && q != &handle->write_queue;
|
||||||
++pkts, q = QUEUE_HEAD(q)) {
|
++pkts, q = QUEUE_HEAD(q)) {
|
||||||
assert(q != NULL);
|
assert(q != NULL);
|
||||||
req = QUEUE_DATA(q, uv_udp_send_t, queue);
|
req = QUEUE_DATA(q, uv_udp_send_t, queue);
|
||||||
@ -355,7 +325,7 @@ write_queue_drain:
|
|||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
npkts = uv__sendmmsg(handle->io_watcher.fd, h, pkts);
|
npkts = sendmmsg(handle->io_watcher.fd, h, pkts, 0);
|
||||||
while (npkts == -1 && errno == EINTR);
|
while (npkts == -1 && errno == EINTR);
|
||||||
|
|
||||||
if (npkts < 1) {
|
if (npkts < 1) {
|
||||||
@ -401,24 +371,12 @@ write_queue_drain:
|
|||||||
if (!QUEUE_EMPTY(&handle->write_queue))
|
if (!QUEUE_EMPTY(&handle->write_queue))
|
||||||
goto write_queue_drain;
|
goto write_queue_drain;
|
||||||
uv__io_feed(handle->loop, &handle->io_watcher);
|
uv__io_feed(handle->loop, &handle->io_watcher);
|
||||||
return;
|
#else /* __linux__ || ____FreeBSD__ || __FreeBSD_kernel__ */
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void uv__udp_sendmsg(uv_udp_t* handle) {
|
|
||||||
uv_udp_send_t* req;
|
uv_udp_send_t* req;
|
||||||
struct msghdr h;
|
struct msghdr h;
|
||||||
QUEUE* q;
|
QUEUE* q;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
|
|
||||||
#if HAVE_MMSG
|
|
||||||
uv_once(&once, uv__udp_mmsg_init);
|
|
||||||
if (uv__sendmmsg_avail) {
|
|
||||||
uv__udp_sendmmsg(handle);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (!QUEUE_EMPTY(&handle->write_queue)) {
|
while (!QUEUE_EMPTY(&handle->write_queue)) {
|
||||||
q = QUEUE_HEAD(&handle->write_queue);
|
q = QUEUE_HEAD(&handle->write_queue);
|
||||||
assert(q != NULL);
|
assert(q != NULL);
|
||||||
@ -466,6 +424,7 @@ static void uv__udp_sendmsg(uv_udp_t* handle) {
|
|||||||
QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue);
|
QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue);
|
||||||
uv__io_feed(handle->loop, &handle->io_watcher);
|
uv__io_feed(handle->loop, &handle->io_watcher);
|
||||||
}
|
}
|
||||||
|
#endif /* __linux__ || ____FreeBSD__ || __FreeBSD_kernel__ */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some additional
|
/* On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some additional
|
||||||
@ -1061,11 +1020,9 @@ int uv__udp_init_ex(uv_loop_t* loop,
|
|||||||
|
|
||||||
|
|
||||||
int uv_udp_using_recvmmsg(const uv_udp_t* handle) {
|
int uv_udp_using_recvmmsg(const uv_udp_t* handle) {
|
||||||
#if HAVE_MMSG
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||||
if (handle->flags & UV_HANDLE_UDP_RECVMMSG) {
|
if (handle->flags & UV_HANDLE_UDP_RECVMMSG)
|
||||||
uv_once(&once, uv__udp_mmsg_init);
|
return 1;
|
||||||
return uv__recvmmsg_avail;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user