diff --git a/Utilities/cmlibuv/include/uv.h b/Utilities/cmlibuv/include/uv.h index 8e45dae82e..654a45c30c 100644 --- a/Utilities/cmlibuv/include/uv.h +++ b/Utilities/cmlibuv/include/uv.h @@ -1228,7 +1228,7 @@ struct uv_cpu_times_s { }; struct uv_cpu_info_s { - char* model; + const char* model; int speed; struct uv_cpu_times_s cpu_times; }; diff --git a/Utilities/cmlibuv/include/uv/version.h b/Utilities/cmlibuv/include/uv/version.h index b70cd6f60d..70f071a478 100644 --- a/Utilities/cmlibuv/include/uv/version.h +++ b/Utilities/cmlibuv/include/uv/version.h @@ -32,7 +32,7 @@ #define UV_VERSION_MAJOR 1 #define UV_VERSION_MINOR 52 -#define UV_VERSION_PATCH 0 +#define UV_VERSION_PATCH 1 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/Utilities/cmlibuv/src/inet.c b/Utilities/cmlibuv/src/inet.c index 8c890dd0e4..f7416b46e9 100644 --- a/Utilities/cmlibuv/src/inet.c +++ b/Utilities/cmlibuv/src/inet.c @@ -151,19 +151,19 @@ int uv_inet_pton(int af, const char* src, void* dst) { case AF_INET: return (inet_pton4(src, dst)); case AF_INET6: { - int len; - char tmp[UV__INET6_ADDRSTRLEN], *s, *p; - s = (char*) src; + const char *p; p = strchr(src, '%'); if (p != NULL) { - s = tmp; + int len; + char s[UV__INET6_ADDRSTRLEN]; len = p - src; if (len > UV__INET6_ADDRSTRLEN-1) return UV_EINVAL; memcpy(s, src, len); s[len] = '\0'; - } - return inet_pton6(s, dst); + return inet_pton6(s, dst); + } else + return inet_pton6(src, dst); } default: return UV_EAFNOSUPPORT; diff --git a/Utilities/cmlibuv/src/unix/aix.c b/Utilities/cmlibuv/src/unix/aix.c index 30a2a894f2..4c0f4adb4c 100644 --- a/Utilities/cmlibuv/src/unix/aix.c +++ b/Utilities/cmlibuv/src/unix/aix.c @@ -380,7 +380,7 @@ uint64_t uv_get_total_memory(void) { uint64_t uv_get_constrained_memory(void) { - return 0; /* Memory constraints are unknown. */ + return uv__get_rlimit_max_memory(); } diff --git a/Utilities/cmlibuv/src/unix/core.c b/Utilities/cmlibuv/src/unix/core.c index 0f997a2da9..08fdae0e46 100644 --- a/Utilities/cmlibuv/src/unix/core.c +++ b/Utilities/cmlibuv/src/unix/core.c @@ -2192,3 +2192,27 @@ int uv__sock_reuseport(int fd) { return 0; } + +/* Check if rlimit has any expressed restrictions on usable memory. */ +uint64_t uv__get_rlimit_max_memory(void) { + struct rlimit rl; + uint64_t result = 0; + uint64_t rlimit_value; + +#if defined(RLIMIT_AS) + if (getrlimit(RLIMIT_AS, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) { + rlimit_value = rl.rlim_cur; + result = rlimit_value; + } +#endif + +#if defined(RLIMIT_DATA) + if (getrlimit(RLIMIT_DATA, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) { + rlimit_value = rl.rlim_cur; + if (result == 0 || rlimit_value < result) + result = rlimit_value; + } +#endif + + return result; +} diff --git a/Utilities/cmlibuv/src/unix/cygwin.c b/Utilities/cmlibuv/src/unix/cygwin.c index 4913108223..29861ce8be 100644 --- a/Utilities/cmlibuv/src/unix/cygwin.c +++ b/Utilities/cmlibuv/src/unix/cygwin.c @@ -85,7 +85,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { } uint64_t uv_get_constrained_memory(void) { - return 0; /* Memory constraints are unknown. */ + return uv__get_rlimit_max_memory(); } uint64_t uv_get_available_memory(void) { diff --git a/Utilities/cmlibuv/src/unix/darwin.c b/Utilities/cmlibuv/src/unix/darwin.c index a4e8129c39..e0d06bfebb 100644 --- a/Utilities/cmlibuv/src/unix/darwin.c +++ b/Utilities/cmlibuv/src/unix/darwin.c @@ -133,7 +133,7 @@ uint64_t uv_get_total_memory(void) { uint64_t uv_get_constrained_memory(void) { - return 0; /* Memory constraints are unknown. */ + return uv__get_rlimit_max_memory(); } diff --git a/Utilities/cmlibuv/src/unix/freebsd.c b/Utilities/cmlibuv/src/unix/freebsd.c index a6de29c558..d7ac94b0c2 100644 --- a/Utilities/cmlibuv/src/unix/freebsd.c +++ b/Utilities/cmlibuv/src/unix/freebsd.c @@ -117,7 +117,7 @@ uint64_t uv_get_total_memory(void) { uint64_t uv_get_constrained_memory(void) { - return 0; /* Memory constraints are unknown. */ + return uv__get_rlimit_max_memory(); } diff --git a/Utilities/cmlibuv/src/unix/fs.c b/Utilities/cmlibuv/src/unix/fs.c index dea3a55c9f..4900869580 100644 --- a/Utilities/cmlibuv/src/unix/fs.c +++ b/Utilities/cmlibuv/src/unix/fs.c @@ -487,27 +487,28 @@ static ssize_t uv__preadv_or_pwritev(int fd, off_t off, _Atomic uintptr_t* cache, int is_pread) { - ssize_t (*f)(int, const struct iovec*, uv__iovcnt, off_t); - void* p; + union { + ssize_t (*f)(int, const struct iovec*, uv__iovcnt, off_t); + void* p; + } u; - p = (void*) atomic_load_explicit(cache, memory_order_relaxed); - if (p == NULL) { + u.p = (void*) atomic_load_explicit(cache, memory_order_relaxed); + if (u.p == NULL) { #ifdef RTLD_DEFAULT /* Try _LARGEFILE_SOURCE version of preadv/pwritev first, * then fall back to the plain version, for libcs like musl. */ - p = dlsym(RTLD_DEFAULT, is_pread ? "preadv64" : "pwritev64"); - if (p == NULL) - p = dlsym(RTLD_DEFAULT, is_pread ? "preadv" : "pwritev"); + u.p = dlsym(RTLD_DEFAULT, is_pread ? "preadv64" : "pwritev64"); + if (u.p == NULL) + u.p = dlsym(RTLD_DEFAULT, is_pread ? "preadv" : "pwritev"); dlerror(); /* Clear errors. */ #endif /* RTLD_DEFAULT */ - if (p == NULL) - p = is_pread ? uv__preadv_emul : uv__pwritev_emul; - atomic_store_explicit(cache, (uintptr_t) p, memory_order_relaxed); + if (u.p == NULL) + u.f = is_pread ? uv__preadv_emul : uv__pwritev_emul; + atomic_store_explicit(cache, (uintptr_t) u.p, memory_order_relaxed); } - f = p; - return f(fd, bufs, nbufs, off); + return u.f(fd, bufs, nbufs, off); } diff --git a/Utilities/cmlibuv/src/unix/getaddrinfo.c b/Utilities/cmlibuv/src/unix/getaddrinfo.c index 6c44012726..5d90c7a59b 100644 --- a/Utilities/cmlibuv/src/unix/getaddrinfo.c +++ b/Utilities/cmlibuv/src/unix/getaddrinfo.c @@ -107,7 +107,9 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { uv_getaddrinfo_t* req; req = container_of(w, uv_getaddrinfo_t, work_req); - uv__req_unregister(req->loop); + + if (req->loop != NULL) + uv__req_unregister(req->loop); /* See initialization in uv_getaddrinfo(). */ if (req->hints) @@ -149,6 +151,8 @@ int uv_getaddrinfo(uv_loop_t* loop, if (req == NULL || (hostname == NULL && service == NULL)) return UV_EINVAL; + if (loop == NULL && cb != NULL) + return UV_EINVAL; /* FIXME(bnoordhuis) IDNA does not seem to work z/OS, * probably because it uses EBCDIC rather than ASCII. @@ -175,7 +179,10 @@ int uv_getaddrinfo(uv_loop_t* loop, if (buf == NULL) return UV_ENOMEM; - uv__req_init(loop, req, UV_GETADDRINFO); + UV_REQ_INIT(req, UV_GETADDRINFO); + if (loop != NULL) + uv__req_register(loop); + req->loop = loop; req->cb = cb; req->addrinfo = NULL; diff --git a/Utilities/cmlibuv/src/unix/haiku.c b/Utilities/cmlibuv/src/unix/haiku.c index 0d3645f014..22c165916a 100644 --- a/Utilities/cmlibuv/src/unix/haiku.c +++ b/Utilities/cmlibuv/src/unix/haiku.c @@ -80,7 +80,7 @@ uint64_t uv_get_total_memory(void) { uint64_t uv_get_constrained_memory(void) { - return 0; /* Memory constraints are unknown. */ + return uv__get_rlimit_max_memory(); } diff --git a/Utilities/cmlibuv/src/unix/hurd.c b/Utilities/cmlibuv/src/unix/hurd.c index 63c878123f..99f4f2ae48 100644 --- a/Utilities/cmlibuv/src/unix/hurd.c +++ b/Utilities/cmlibuv/src/unix/hurd.c @@ -163,7 +163,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { } uint64_t uv_get_constrained_memory(void) { - return 0; /* Memory constraints are unknown. */ + return uv__get_rlimit_max_memory(); } diff --git a/Utilities/cmlibuv/src/unix/ibmi.c b/Utilities/cmlibuv/src/unix/ibmi.c index d5adaad137..2ede46b7f0 100644 --- a/Utilities/cmlibuv/src/unix/ibmi.c +++ b/Utilities/cmlibuv/src/unix/ibmi.c @@ -245,7 +245,7 @@ uint64_t uv_get_total_memory(void) { uint64_t uv_get_constrained_memory(void) { - return 0; /* Memory constraints are unknown. */ + return uv__get_rlimit_max_memory(); } diff --git a/Utilities/cmlibuv/src/unix/internal.h b/Utilities/cmlibuv/src/unix/internal.h index 55af6d4d9d..1abbff0258 100644 --- a/Utilities/cmlibuv/src/unix/internal.h +++ b/Utilities/cmlibuv/src/unix/internal.h @@ -391,6 +391,7 @@ int uv__signal_loop_fork(uv_loop_t* loop); /* platform specific */ uint64_t uv__hrtime(uv_clocktype_t type); +uint64_t uv__get_rlimit_max_memory(void); int uv__kqueue_init(uv_loop_t* loop); int uv__platform_loop_init(uv_loop_t* loop); void uv__platform_loop_delete(uv_loop_t* loop); @@ -481,12 +482,12 @@ UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) { loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000; } -UV_UNUSED(static char* uv__basename_r(const char* path)) { - char* s; +UV_UNUSED(static const char* uv__basename_r(const char* path)) { + const char* s; s = strrchr(path, '/'); if (s == NULL) - return (char*) path; + return path; return s + 1; } diff --git a/Utilities/cmlibuv/src/unix/linux.c b/Utilities/cmlibuv/src/unix/linux.c index 0ba2e987a3..6d1eb91a70 100644 --- a/Utilities/cmlibuv/src/unix/linux.c +++ b/Utilities/cmlibuv/src/unix/linux.c @@ -1742,7 +1742,7 @@ int uv_cpu_info(uv_cpu_info_t** ci, int* count) { unsigned model; }; FILE* fp; - char* p; + const char* p; int found; int n; unsigned i; @@ -2204,11 +2204,20 @@ static uint64_t uv__get_cgroup_constrained_memory(char buf[static 1024]) { uint64_t uv_get_constrained_memory(void) { char buf[1024]; + uint64_t cgroup_limit; + uint64_t rlimit_limit; - if (uv__slurp("/proc/self/cgroup", buf, sizeof(buf))) - return 0; + cgroup_limit = 0; + if (uv__slurp("/proc/self/cgroup", buf, sizeof(buf)) == 0) + cgroup_limit = uv__get_cgroup_constrained_memory(buf); + rlimit_limit = uv__get_rlimit_max_memory(); - return uv__get_cgroup_constrained_memory(buf); + /* Return the minimum of cgroup and rlimit constraints. */ + if (cgroup_limit == 0) + return rlimit_limit; + if (rlimit_limit == 0) + return cgroup_limit; + return cgroup_limit < rlimit_limit ? cgroup_limit : rlimit_limit; } @@ -2365,10 +2374,10 @@ next: return 0; } -static char* uv__cgroup1_find_cpu_controller(const char* cgroup, +static const char* uv__cgroup1_find_cpu_controller(const char* cgroup, int* cgroup_size) { /* Seek to the cpu controller line. */ - char* cgroup_cpu = strstr(cgroup, ":cpu,"); + const char* cgroup_cpu = strstr(cgroup, ":cpu,"); if (cgroup_cpu != NULL) { /* Skip the controller prefix to the start of the cgroup path. */ @@ -2385,7 +2394,7 @@ static int uv__get_cgroupv1_constrained_cpu(const char* cgroup, char path[256]; char buf[1024]; int cgroup_size; - char* cgroup_cpu; + const char* cgroup_cpu; long long period_length; long long quota_per_period; diff --git a/Utilities/cmlibuv/src/unix/netbsd.c b/Utilities/cmlibuv/src/unix/netbsd.c index fa21e98e41..37d962c4b1 100644 --- a/Utilities/cmlibuv/src/unix/netbsd.c +++ b/Utilities/cmlibuv/src/unix/netbsd.c @@ -127,7 +127,7 @@ uint64_t uv_get_total_memory(void) { uint64_t uv_get_constrained_memory(void) { - return 0; /* Memory constraints are unknown. */ + return uv__get_rlimit_max_memory(); } diff --git a/Utilities/cmlibuv/src/unix/openbsd.c b/Utilities/cmlibuv/src/unix/openbsd.c index a6d58b948e..bc66316955 100644 --- a/Utilities/cmlibuv/src/unix/openbsd.c +++ b/Utilities/cmlibuv/src/unix/openbsd.c @@ -94,7 +94,7 @@ uint64_t uv_get_total_memory(void) { uint64_t uv_get_constrained_memory(void) { - return 0; /* Memory constraints are unknown. */ + return uv__get_rlimit_max_memory(); } diff --git a/Utilities/cmlibuv/src/unix/os390.c b/Utilities/cmlibuv/src/unix/os390.c index c049884c4b..6ba2f9158b 100644 --- a/Utilities/cmlibuv/src/unix/os390.c +++ b/Utilities/cmlibuv/src/unix/os390.c @@ -188,12 +188,23 @@ uint64_t uv_get_total_memory(void) { uint64_t uv_get_constrained_memory(void) { struct rlimit rl; + uint64_t memlimit; + uint64_t rlimit_limit; /* RLIMIT_MEMLIMIT return value is in megabytes rather than bytes. */ - if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0) - return rl.rlim_cur * 1024 * 1024; + memlimit = 0; + if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) + memlimit = rl.rlim_cur * 1024 * 1024; - return 0; /* There is no memory limit set. */ + /* Also check RLIMIT_AS and RLIMIT_DATA. */ + rlimit_limit = uv__get_rlimit_max_memory(); + + /* Return the minimum of RLIMIT_MEMLIMIT and other rlimits. */ + if (memlimit == 0) + return rlimit_limit; + if (rlimit_limit == 0) + return memlimit; + return memlimit < rlimit_limit ? memlimit : rlimit_limit; } diff --git a/Utilities/cmlibuv/src/unix/qnx.c b/Utilities/cmlibuv/src/unix/qnx.c index d873165fee..c1030caf74 100644 --- a/Utilities/cmlibuv/src/unix/qnx.c +++ b/Utilities/cmlibuv/src/unix/qnx.c @@ -118,7 +118,7 @@ uint64_t uv_get_total_memory(void) { uint64_t uv_get_constrained_memory(void) { - return 0; + return uv__get_rlimit_max_memory(); } diff --git a/Utilities/cmlibuv/src/unix/sunos.c b/Utilities/cmlibuv/src/unix/sunos.c index 0793122976..5abe077d57 100644 --- a/Utilities/cmlibuv/src/unix/sunos.c +++ b/Utilities/cmlibuv/src/unix/sunos.c @@ -397,7 +397,7 @@ uint64_t uv_get_total_memory(void) { uint64_t uv_get_constrained_memory(void) { - return 0; /* Memory constraints are unknown. */ + return uv__get_rlimit_max_memory(); } diff --git a/Utilities/cmlibuv/src/unix/udp.c b/Utilities/cmlibuv/src/unix/udp.c index 20dc85fc3f..d473469f0f 100644 --- a/Utilities/cmlibuv/src/unix/udp.c +++ b/Utilities/cmlibuv/src/unix/udp.c @@ -183,7 +183,11 @@ void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) { /* Just Linux support for now. */ #if defined(__linux__) - if (revents & POLLERR) + /* Guard against the case where the POLLIN callback above (e.g. via + * uv_udp_recv_stop + uv_close) already cleared recv_cb in the same + * revents iteration. uv__udp_recvmsg asserts recv_cb != NULL, so + * calling it with a NULL recv_cb would be wrong regardless of POLLERR. */ + if ((revents & POLLERR) && uv__is_active(handle)) uv__udp_recvmsg(handle, MSG_ERRQUEUE); #endif diff --git a/Utilities/cmlibuv/src/uv-common.c b/Utilities/cmlibuv/src/uv-common.c index 050bc9dd9b..c0d850f3b3 100644 --- a/Utilities/cmlibuv/src/uv-common.c +++ b/Utilities/cmlibuv/src/uv-common.c @@ -959,7 +959,7 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { int i; for (i = 0; i < count; i++) - uv__free(cpu_infos[i].model); + uv__free((char*) cpu_infos[i].model); uv__free(cpu_infos); #endif /* __linux__ */ diff --git a/Utilities/cmlibuv/src/win/getaddrinfo.c b/Utilities/cmlibuv/src/win/getaddrinfo.c index 4b8ee75a06..9404ccf70f 100644 --- a/Utilities/cmlibuv/src/win/getaddrinfo.c +++ b/Utilities/cmlibuv/src/win/getaddrinfo.c @@ -208,7 +208,8 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { } complete: - uv__req_unregister(req->loop); + if (req->loop != NULL) + uv__req_unregister(req->loop); /* finally do callback with converted result */ if (req->getaddrinfo_cb) @@ -239,7 +240,7 @@ void uv_freeaddrinfo(struct addrinfo* ai) { */ int uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* req, - uv_getaddrinfo_cb getaddrinfo_cb, + uv_getaddrinfo_cb cb, const char* node, const char* service, const struct addrinfo* hints) { @@ -252,12 +253,15 @@ int uv_getaddrinfo(uv_loop_t* loop, size_t hintoff = 0; ssize_t rc; - if (req == NULL || (node == NULL && service == NULL)) { + if (req == NULL || (node == NULL && service == NULL)) return UV_EINVAL; - } + if (loop == NULL && cb != NULL) + return UV_EINVAL; + + uv__once_init(); UV_REQ_INIT(req, UV_GETADDRINFO); - req->getaddrinfo_cb = getaddrinfo_cb; + req->getaddrinfo_cb = cb; req->addrinfo = NULL; req->loop = loop; req->retcode = 0; @@ -330,9 +334,10 @@ int uv_getaddrinfo(uv_loop_t* loop, req->addrinfow = NULL; } - uv__req_register(loop); + if (loop != NULL) + uv__req_register(loop); - if (getaddrinfo_cb) { + if (cb) { uv__work_submit(loop, &req->work_req, UV__WORK_SLOW_IO, diff --git a/Utilities/cmlibuv/src/win/util.c b/Utilities/cmlibuv/src/win/util.c index fec07b269f..436bf30557 100644 --- a/Utilities/cmlibuv/src/win/util.c +++ b/Utilities/cmlibuv/src/win/util.c @@ -627,7 +627,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { uv__convert_utf16_to_utf8(cpu_brand, cpu_brand_size / sizeof(WCHAR), - &(cpu_info->model)); + (char**) &(cpu_info->model)); } uv__free(sppi); @@ -639,12 +639,8 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { error: if (cpu_infos != NULL) { - /* This is safe because the cpu_infos array is zeroed on allocation. */ - for (i = 0; i < cpu_count; i++) - uv__free(cpu_infos[i].model); + uv_free_cpu_info(cpu_infos, cpu_count); } - - uv__free(cpu_infos); uv__free(sppi); return uv_translate_sys_error(err);