Merge branch 'upstream-libuv' into update-libuv

# By libuv upstream
* upstream-libuv:
  libuv 2026-03-11 (d2a45ce3)
This commit is contained in:
Brad King
2026-08-13 09:52:24 -04:00
24 changed files with 119 additions and 61 deletions
+1 -1
View File
@@ -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;
};
+1 -1
View File
@@ -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 ""
+6 -6
View File
@@ -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;
+1 -1
View File
@@ -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();
}
+24
View File
@@ -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;
}
+1 -1
View File
@@ -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) {
+1 -1
View File
@@ -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();
}
+1 -1
View File
@@ -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();
}
+13 -12
View File
@@ -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);
}
+9 -2
View File
@@ -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;
+1 -1
View File
@@ -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();
}
+1 -1
View File
@@ -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();
}
+1 -1
View File
@@ -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();
}
+4 -3
View File
@@ -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;
}
+16 -7
View File
@@ -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;
+1 -1
View File
@@ -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();
}
+1 -1
View File
@@ -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();
}
+14 -3
View File
@@ -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;
}
+1 -1
View File
@@ -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();
}
+1 -1
View File
@@ -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();
}
+5 -1
View File
@@ -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
+1 -1
View File
@@ -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__ */
+12 -7
View File
@@ -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,
+2 -6
View File
@@ -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);