deps: upgrade to libuv 1.29.1

Notable changes:

- uv_get_constrained_memory() has been added.
- A race condition in uv_async_send() has been fixed.
- uv_get_free_memory() and uv_get_total_memory() now read from
  /proc/meminfo, which should improve correctness when called
  from inside an lxc container.
- A failed assertion in uv_fs_poll_stop() has been fixed.
- A bug in MAC addresses for IP-aliases has been fixed.

Fixes: https://github.com/nodejs/node/issues/27170
Fixes: https://github.com/nodejs/node/issues/27493
PR-URL: https://github.com/nodejs/node/pull/27718
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
cjihrig 2019-05-15 13:24:08 -04:00
parent 0ca9297c39
commit 46d8af5e61
No known key found for this signature in database
GPG Key ID: 7434390BDBE9B9C5
39 changed files with 596 additions and 76 deletions

1
deps/uv/.mailmap vendored
View File

@ -46,3 +46,4 @@ Yuki Okumura <mjt@cltn.org>
jBarz <jBarz@users.noreply.github.com> <jbarboza@ca.ibm.com>
jBarz <jBarz@users.noreply.github.com> <jbarz@users.noreply.github.com>
ptlomholt <pt@lomholt.com>
zlargon <zlargon1988@gmail.com>

6
deps/uv/AUTHORS vendored
View File

@ -376,3 +376,9 @@ Rich Trott <rtrott@gmail.com>
Milad Farazmand <miladfar@ca.ibm.com>
zlargon <zlargon1988@gmail.com>
Yury Selivanov <yury@magic.io>
Oscar Waddell <owaddell@beckman.com>
FX Coudert <fxcoudert@gmail.com>
George Zhao <zhaozg@gmail.com>
Kyle Edwards <kyle.edwards@kitware.com>
ken-cunningham-webuse <ken.cunningham.webuse@gmail.com>
Kelvin Jin <kelvinjin@google.com>

View File

@ -297,8 +297,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
src/unix/linux-inotify.c
src/unix/linux-syscalls.c
src/unix/procfs-exepath.c
src/unix/sysinfo-loadavg.c
src/unix/sysinfo-memory.c)
src/unix/sysinfo-loadavg.c)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")

56
deps/uv/ChangeLog vendored
View File

@ -1,3 +1,59 @@
2019.05.22, Version 1.29.1 (Stable), d16e6094e1eb3b0b5981ef1dd7e03ec4d466944d
Changes since version 1.29.0:
* unix: simplify uv/posix.h include logic (cjihrig)
* test: increase test timeout (cjihrig)
* linux: fix sscanf() overflows reading from /proc (Ben Noordhuis)
2019.05.16, Version 1.29.0 (Stable), 43957efd92c167b352b4c948b617ca7afbee0ed1
Changes since version 1.28.0:
* ibmi: read memory and CPU usage info (Xu Meng)
* doc: update the cmake testing instruction (zlargon)
* unix: fix race condition in uv_async_send() (Ben Noordhuis)
* linux: use O_CLOEXEC instead of EPOLL_CLOEXEC (Ben Noordhuis)
* doc: mark uv_async_send() as async-signal-safe (Ben Noordhuis)
* linux: init st_flags and st_gen when using statx (Oscar Waddell)
* linux: read free/total memory from /proc/meminfo (Ben Noordhuis)
* test: test zero-sized uv_fs_sendfile() writes (Ben Noordhuis)
* unix: don't assert on UV_PROCESS_WINDOWS_* flags (Ben Noordhuis)
* linux: set correct mac address for IP-aliases (Santiago Gimeno)
* win,util: fix null pointer dereferencing (Tobias Nießen)
* unix,win: fix `uv_fs_poll_stop()` when active (Anna Henningsen)
* doc: add missing uv_fs_type entries (Michele Caini)
* doc: fix build with sphinx 2.x (FX Coudert)
* unix: don't make statx system call on Android (George Zhao)
* unix: fix clang scan-build warning (Kyle Edwards)
* unix: fall back to kqueue on older macOS systems (ken-cunningham-webuse)
* unix,win: add uv_get_constrained_memory() (Kelvin Jin)
* darwin: fix thread cancellation fd leak (Ben Noordhuis)
* linux: fix thread cancellation fd leak (Ben Noordhuis)
2019.04.16, Version 1.28.0 (Stable), 7bf8fabfa934660ee0fe889f78e151198a1165fc
Changes since version 1.27.0:

3
deps/uv/Makefile.am vendored
View File

@ -425,8 +425,7 @@ libuv_la_SOURCES += src/unix/linux-core.c \
src/unix/linux-syscalls.h \
src/unix/procfs-exepath.c \
src/unix/proctitle.c \
src/unix/sysinfo-loadavg.c \
src/unix/sysinfo-memory.c
src/unix/sysinfo-loadavg.c
test_run_tests_LDFLAGS += -lutil
endif

13
deps/uv/README.md vendored
View File

@ -172,11 +172,14 @@ $ make install
To build with [CMake](https://cmake.org/):
```bash
$ mkdir -p out/cmake ; cd out/cmake ; cmake -DBUILD_TESTING=ON ../..
$ make all test
# Or manually:
$ ./uv_run_tests # shared library build
$ ./uv_run_tests_a # static library build
$ mkdir -p out/cmake ; cd out/cmake # create build directory
$ cmake ../.. -DBUILD_TESTING=ON # generate project with test
$ cmake --build . # build
$ ctest -C Debug --output-on-failure # run tests
# Or manually run tests:
$ ./out/cmake/uv_run_tests # shared library build
$ ./out/cmake/uv_run_tests_a # static library build
```
To build with GYP, first run:

View File

@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
AC_INIT([libuv], [1.28.0], [https://github.com/libuv/libuv/issues])
AC_INIT([libuv], [1.29.1], [https://github.com/libuv/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4])

View File

@ -50,6 +50,10 @@ API
It's safe to call this function from any thread. The callback will be called on the
loop thread.
.. note::
:c:func:`uv_async_send` is `async-signal-safe <http://man7.org/linux/man-pages/man7/signal-safety.7.html>`_.
It's safe to call this function from a signal handler.
.. warning::
libuv will coalesce calls to :c:func:`uv_async_send`, that is, not every call to it will
yield an execution of the callback. For example: if :c:func:`uv_async_send` is called 5

View File

@ -96,7 +96,10 @@ Data types
UV_FS_FCHOWN,
UV_FS_REALPATH,
UV_FS_COPYFILE,
UV_FS_LCHOWN
UV_FS_LCHOWN,
UV_FS_OPENDIR,
UV_FS_READDIR,
UV_FS_CLOSEDIR
} uv_fs_type;
.. c:type:: uv_dirent_t

View File

@ -461,6 +461,19 @@ API
Gets memory information (in bytes).
.. c:function:: uint64_t uv_get_constrained_memory(void)
Gets the amount of memory available to the process (in bytes) based on
limits imposed by the OS. If there is no such constraint, or the constraint
is unknown, `0` is returned. Note that it is not unusual for this value to
be less than or greater than :c:func:`uv_get_total_memory`.
.. note::
This function currently only returns a non-zero value on Linux, based
on cgroups if it is present.
.. versionadded:: 1.29.0
.. c:function:: uint64_t uv_hrtime(void)
Returns the current high-resolution real time. This is expressed in

View File

@ -39,7 +39,6 @@ def man_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
def setup(app):
app.info('Initializing manpage plugin')
app.add_role('man', man_role)
app.add_config_value('man_url_regex', None, 'env')
return

View File

@ -1561,6 +1561,7 @@ UV_EXTERN int uv_chdir(const char* dir);
UV_EXTERN uint64_t uv_get_free_memory(void);
UV_EXTERN uint64_t uv_get_total_memory(void);
UV_EXTERN uint64_t uv_get_constrained_memory(void);
UV_EXTERN uint64_t uv_hrtime(void);

View File

@ -49,8 +49,6 @@
# include "uv/linux.h"
#elif defined (__MVS__)
# include "uv/os390.h"
#elif defined(__PASE__)
# include "uv/posix.h"
#elif defined(_AIX)
# include "uv/aix.h"
#elif defined(__sun)
@ -63,9 +61,10 @@
defined(__OpenBSD__) || \
defined(__NetBSD__)
# include "uv/bsd.h"
#elif defined(__CYGWIN__) || defined(__MSYS__)
# include "uv/posix.h"
#elif defined(__GNU__)
#elif defined(__PASE__) || \
defined(__CYGWIN__) || \
defined(__MSYS__) || \
defined(__GNU__)
# include "uv/posix.h"
#endif

View File

@ -31,8 +31,8 @@
*/
#define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 28
#define UV_VERSION_PATCH 0
#define UV_VERSION_MINOR 29
#define UV_VERSION_PATCH 1
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""

View File

@ -241,7 +241,7 @@ static void timer_close_cb(uv_handle_t* timer) {
handle = ctx->parent_handle;
if (ctx == handle->poll_ctx) {
handle->poll_ctx = ctx->previous;
if (handle->poll_ctx == NULL)
if (handle->poll_ctx == NULL && uv__is_closing(handle))
uv__make_close_pending((uv_handle_t*)handle);
} else {
for (last = handle->poll_ctx, it = last->previous;

View File

@ -344,6 +344,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
void uv_loadavg(double avg[3]) {
perfstat_cpu_total_t ps_total;
int result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);

View File

@ -61,14 +61,43 @@ int uv_async_send(uv_async_t* handle) {
if (ACCESS_ONCE(int, handle->pending) != 0)
return 0;
if (cmpxchgi(&handle->pending, 0, 1) == 0)
uv__async_send(handle->loop);
/* Tell the other thread we're busy with the handle. */
if (cmpxchgi(&handle->pending, 0, 1) != 0)
return 0;
/* Wake up the other thread's event loop. */
uv__async_send(handle->loop);
/* Tell the other thread we're done. */
if (cmpxchgi(&handle->pending, 1, 2) != 1)
abort();
return 0;
}
/* Only call this from the event loop thread. */
static int uv__async_spin(uv_async_t* handle) {
int rc;
for (;;) {
/* rc=0 -- handle is not pending.
* rc=1 -- handle is pending, other thread is still working with it.
* rc=2 -- handle is pending, other thread is done.
*/
rc = cmpxchgi(&handle->pending, 2, 0);
if (rc != 1)
return rc;
/* Other thread is busy with this handle, spin until it's done. */
cpu_relax();
}
}
void uv__async_close(uv_async_t* handle) {
uv__async_spin(handle);
QUEUE_REMOVE(&handle->queue);
uv__handle_stop(handle);
}
@ -109,8 +138,8 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
QUEUE_REMOVE(q);
QUEUE_INSERT_TAIL(&loop->async_handles, q);
if (cmpxchgi(&h->pending, 1, 0) == 0)
continue;
if (0 == uv__async_spin(h))
continue; /* Not pending. */
if (h->async_cb == NULL)
continue;

View File

@ -88,6 +88,10 @@
#include <sys/ioctl.h>
#endif
#if defined(__linux__)
#include <sys/syscall.h>
#endif
static int uv__run_pending(uv_loop_t* loop);
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
@ -510,6 +514,29 @@ skip:
}
/* close() on macos has the "interesting" quirk that it fails with EINTR
* without closing the file descriptor when a thread is in the cancel state.
* That's why libuv calls close$NOCANCEL() instead.
*
* glibc on linux has a similar issue: close() is a cancellation point and
* will unwind the thread when it's in the cancel state. Work around that
* by making the system call directly. Musl libc is unaffected.
*/
int uv__close_nocancel(int fd) {
#if defined(__APPLE__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension"
extern int close$NOCANCEL(int);
return close$NOCANCEL(fd);
#pragma GCC diagnostic pop
#elif defined(__linux__)
return syscall(SYS_close, fd);
#else
return close(fd);
#endif
}
int uv__close_nocheckstdio(int fd) {
int saved_errno;
int rc;
@ -517,7 +544,7 @@ int uv__close_nocheckstdio(int fd) {
assert(fd > -1); /* Catch uninitialized io_watcher.fd bugs. */
saved_errno = errno;
rc = close(fd);
rc = uv__close_nocancel(fd);
if (rc == -1) {
rc = UV__ERR(errno);
if (rc == UV_EINTR || rc == UV__ERR(EINPROGRESS))

View File

@ -117,6 +117,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
void uv_loadavg(double avg[3]) {
struct loadavg info;
size_t size = sizeof(info);

View File

@ -137,6 +137,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
void uv_loadavg(double avg[3]) {
struct loadavg info;
size_t size = sizeof(info);

View File

@ -145,7 +145,7 @@ extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */
static int uv__fs_close(int fd) {
int rc;
rc = close(fd);
rc = uv__close_nocancel(fd);
if (rc == -1)
if (errno == EINTR || errno == EINPROGRESS)
rc = 0; /* The close is in progress, not an error. */
@ -1165,6 +1165,8 @@ static int uv__fs_statx(int fd,
buf->st_ctim.tv_nsec = statxbuf.stx_ctime.tv_nsec;
buf->st_birthtim.tv_sec = statxbuf.stx_btime.tv_sec;
buf->st_birthtim.tv_nsec = statxbuf.stx_btime.tv_nsec;
buf->st_flags = 0;
buf->st_gen = 0;
return 0;
#else

View File

@ -21,9 +21,10 @@
#include "uv.h"
#include "internal.h"
#if TARGET_OS_IPHONE
#if TARGET_OS_IPHONE || MAC_OS_X_VERSION_MAX_ALLOWED < 1070
/* iOS (currently) doesn't provide the FSEvents-API (nor CoreServices) */
/* macOS prior to 10.7 doesn't provide the full FSEvents API so use kqueue */
int uv__fsevents_init(uv_fs_event_t* handle) {
return 0;

View File

@ -55,19 +55,155 @@
#include <strings.h>
#include <sys/vnode.h>
#include <as400_protos.h>
typedef struct {
int bytes_available;
int bytes_returned;
char current_date_and_time[8];
char system_name[8];
char elapsed_time[6];
char restricted_state_flag;
char reserved;
int percent_processing_unit_used;
int jobs_in_system;
int percent_permanent_addresses;
int percent_temporary_addresses;
int system_asp;
int percent_system_asp_used;
int total_auxiliary_storage;
int current_unprotected_storage_used;
int maximum_unprotected_storage_used;
int percent_db_capability;
int main_storage_size;
int number_of_partitions;
int partition_identifier;
int reserved1;
int current_processing_capacity;
char processor_sharing_attribute;
char reserved2[3];
int number_of_processors;
int active_jobs_in_system;
int active_threads_in_system;
int maximum_jobs_in_system;
int percent_temporary_256mb_segments_used;
int percent_temporary_4gb_segments_used;
int percent_permanent_256mb_segments_used;
int percent_permanent_4gb_segments_used;
int percent_current_interactive_performance;
int percent_uncapped_cpu_capacity_used;
int percent_shared_processor_pool_used;
long main_storage_size_long;
} SSTS0200;
static int get_ibmi_system_status(SSTS0200* rcvr) {
/* rcvrlen is input parameter 2 to QWCRSSTS */
unsigned int rcvrlen = sizeof(*rcvr);
/* format is input parameter 3 to QWCRSSTS ("SSTS0200" in EBCDIC) */
unsigned char format[] = {0xE2, 0xE2, 0xE3, 0xE2, 0xF0, 0xF2, 0xF0, 0xF0};
/* reset_status is input parameter 4 to QWCRSSTS ("*NO " in EBCDIC) */
unsigned char reset_status[] = {
0x5C, 0xD5, 0xD6, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
};
/* errcode is input parameter 5 to QWCRSSTS */
struct _errcode {
int bytes_provided;
int bytes_available;
char msgid[7];
} errcode;
/* qwcrssts_pointer is the 16-byte tagged system pointer to QWCRSSTS */
ILEpointer __attribute__((aligned(16))) qwcrssts_pointer;
/* qwcrssts_argv is the array of argument pointers to QWCRSSTS */
void* qwcrssts_argv[6];
/* Set the IBM i pointer to the QSYS/QWCRSSTS *PGM object */
int rc = _RSLOBJ2(&qwcrssts_pointer, RSLOBJ_TS_PGM, "QWCRSSTS", "QSYS");
if (rc != 0)
return rc;
/* initialize the QWCRSSTS returned info structure */
memset(rcvr, 0, sizeof(*rcvr));
/* initialize the QWCRSSTS error code structure */
memset(&errcode, 0, sizeof(errcode));
errcode.bytes_provided = sizeof(errcode);
/* initialize the array of argument pointers for the QWCRSSTS API */
qwcrssts_argv[0] = rcvr;
qwcrssts_argv[1] = &rcvrlen;
qwcrssts_argv[2] = &format;
qwcrssts_argv[3] = &reset_status;
qwcrssts_argv[4] = &errcode;
qwcrssts_argv[5] = NULL;
/* Call the IBM i QWCRSSTS API from PASE */
rc = _PGMCALL(&qwcrssts_pointer, (void**)&qwcrssts_argv, 0);
return rc;
}
uint64_t uv_get_free_memory(void) {
return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES);
SSTS0200 rcvr;
if (get_ibmi_system_status(&rcvr))
return 0;
/* The amount of main storage, in kilobytes, in the system. */
uint64_t main_storage_size = rcvr.main_storage_size;
/* The current amount of storage in use for temporary objects.
* in millions (M) of bytes.
*/
uint64_t current_unprotected_storage_used =
rcvr.current_unprotected_storage_used * 1024ULL;
uint64_t free_storage_size =
(main_storage_size - current_unprotected_storage_used) * 1024ULL;
return free_storage_size < 0 ? 0 : free_storage_size;
}
uint64_t uv_get_total_memory(void) {
return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES);
SSTS0200 rcvr;
if (get_ibmi_system_status(&rcvr))
return 0;
return (uint64_t)rcvr.main_storage_size * 1024ULL;
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
void uv_loadavg(double avg[3]) {
SSTS0200 rcvr;
if (get_ibmi_system_status(&rcvr)) {
avg[0] = avg[1] = avg[2] = 0;
return;
}
/* The average (in tenths) of the elapsed time during which the processing
* units were in use. For example, a value of 411 in binary would be 41.1%.
* This percentage could be greater than 100% for an uncapped partition.
*/
double processing_unit_used_percent =
rcvr.percent_processing_unit_used / 1000.0;
avg[0] = avg[1] = avg[2] = processing_unit_used_percent;
}
@ -110,4 +246,4 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
*count = numcpus;
return 0;
}
}

View File

@ -183,6 +183,7 @@ int uv__nonblock_ioctl(int fd, int set);
int uv__nonblock_fcntl(int fd, int set);
int uv__close(int fd); /* preserves errno */
int uv__close_nocheckstdio(int fd);
int uv__close_nocancel(int fd);
int uv__socket(int domain, int type, int protocol);
ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags);
void uv__make_close_pending(uv_handle_t* handle);

View File

@ -59,7 +59,7 @@ int uv__kqueue_init(uv_loop_t* loop) {
}
#if defined(__APPLE__)
#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
static int uv__has_forked_with_cfrunloop;
#endif
@ -70,7 +70,7 @@ int uv__io_fork(uv_loop_t* loop) {
if (err)
return err;
#if defined(__APPLE__)
#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
if (loop->cf_state != NULL) {
/* We cannot start another CFRunloop and/or thread in the child
process; CF aborts if you try or if you try to touch the thread
@ -86,7 +86,7 @@ int uv__io_fork(uv_loop_t* loop) {
uv__free(loop->cf_state);
loop->cf_state = NULL;
}
#endif
#endif /* #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */
return err;
}
@ -458,7 +458,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
if (uv__is_active(handle))
return UV_EINVAL;
#if defined(__APPLE__)
#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
/* Nullify field to perform checks later */
handle->cf_cb = NULL;
handle->realpath = NULL;
@ -482,7 +482,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
}
return r;
}
#endif /* defined(__APPLE__) */
#endif /* #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */
/* TODO open asynchronously - but how do we report back errors? */
fd = open(path, O_RDONLY);
@ -513,7 +513,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
uv__handle_stop(handle);
#if defined(__APPLE__)
#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
if (!uv__has_forked_with_cfrunloop)
r = uv__fsevents_close(handle);
#endif

View File

@ -26,6 +26,7 @@
#include "uv.h"
#include "internal.h"
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@ -79,16 +80,20 @@ static int read_times(FILE* statfile_fp,
unsigned int numcpus,
uv_cpu_info_t* ci);
static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci);
static unsigned long read_cpufreq(unsigned int cpunum);
static uint64_t read_cpufreq(unsigned int cpunum);
int uv__platform_loop_init(uv_loop_t* loop) {
int fd;
fd = epoll_create1(EPOLL_CLOEXEC);
/* It was reported that EPOLL_CLOEXEC is not defined on Android API < 21,
* a.k.a. Lollipop. Since EPOLL_CLOEXEC is an alias for O_CLOEXEC on all
* architectures, we just use that instead.
*/
fd = epoll_create1(O_CLOEXEC);
/* epoll_create1() can fail either because it's not implemented (old kernel)
* or because it doesn't understand the EPOLL_CLOEXEC flag.
* or because it doesn't understand the O_CLOEXEC flag.
*/
if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) {
fd = epoll_create(256);
@ -715,20 +720,20 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
static int read_times(FILE* statfile_fp,
unsigned int numcpus,
uv_cpu_info_t* ci) {
unsigned long clock_ticks;
struct uv_cpu_times_s ts;
unsigned long user;
unsigned long nice;
unsigned long sys;
unsigned long idle;
unsigned long dummy;
unsigned long irq;
unsigned int num;
unsigned int len;
uint64_t clock_ticks;
uint64_t user;
uint64_t nice;
uint64_t sys;
uint64_t idle;
uint64_t dummy;
uint64_t irq;
uint64_t num;
uint64_t len;
char buf[1024];
clock_ticks = sysconf(_SC_CLK_TCK);
assert(clock_ticks != (unsigned long) -1);
assert(clock_ticks != (uint64_t) -1);
assert(clock_ticks != 0);
rewind(statfile_fp);
@ -761,7 +766,8 @@ static int read_times(FILE* statfile_fp,
* fields, they're not allowed in C89 mode.
*/
if (6 != sscanf(buf + len,
"%lu %lu %lu %lu %lu %lu",
"%" PRIu64 " %" PRIu64 " %" PRIu64
"%" PRIu64 " %" PRIu64 " %" PRIu64,
&user,
&nice,
&sys,
@ -783,8 +789,8 @@ static int read_times(FILE* statfile_fp,
}
static unsigned long read_cpufreq(unsigned int cpunum) {
unsigned long val;
static uint64_t read_cpufreq(unsigned int cpunum) {
uint64_t val;
char buf[1024];
FILE* fp;
@ -797,7 +803,7 @@ static unsigned long read_cpufreq(unsigned int cpunum) {
if (fp == NULL)
return 0;
if (fscanf(fp, "%lu", &val) != 1)
if (fscanf(fp, "%" PRIu64, &val) != 1)
val = 0;
fclose(fp);
@ -900,7 +906,10 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
address = *addresses;
for (i = 0; i < (*count); i++) {
if (strcmp(address->name, ent->ifa_name) == 0) {
size_t namelen = strlen(ent->ifa_name);
/* Alias interface share the same physical address */
if (strncmp(address->name, ent->ifa_name, namelen) == 0 &&
(address->name[namelen] == 0 || address->name[namelen] == ':')) {
sll = (struct sockaddr_ll*)ent->ifa_addr;
memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr));
}
@ -932,3 +941,114 @@ void uv__set_process_title(const char* title) {
prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */
#endif
}
static uint64_t uv__read_proc_meminfo(const char* what) {
uint64_t rc;
ssize_t n;
char* p;
int fd;
char buf[4096]; /* Large enough to hold all of /proc/meminfo. */
rc = 0;
fd = uv__open_cloexec("/proc/meminfo", O_RDONLY);
if (fd == -1)
return 0;
n = read(fd, buf, sizeof(buf) - 1);
if (n <= 0)
goto out;
buf[n] = '\0';
p = strstr(buf, what);
if (p == NULL)
goto out;
p += strlen(what);
if (1 != sscanf(p, "%" PRIu64 " kB", &rc))
goto out;
rc *= 1024;
out:
if (uv__close_nocheckstdio(fd))
abort();
return rc;
}
uint64_t uv_get_free_memory(void) {
struct sysinfo info;
uint64_t rc;
rc = uv__read_proc_meminfo("MemFree:");
if (rc != 0)
return rc;
if (0 == sysinfo(&info))
return (uint64_t) info.freeram * info.mem_unit;
return 0;
}
uint64_t uv_get_total_memory(void) {
struct sysinfo info;
uint64_t rc;
rc = uv__read_proc_meminfo("MemTotal:");
if (rc != 0)
return rc;
if (0 == sysinfo(&info))
return (uint64_t) info.totalram * info.mem_unit;
return 0;
}
static uint64_t uv__read_cgroups_uint64(const char* cgroup, const char* param) {
char filename[256];
uint64_t rc;
int fd;
ssize_t n;
char buf[32]; /* Large enough to hold an encoded uint64_t. */
snprintf(filename, 256, "/sys/fs/cgroup/%s/%s", cgroup, param);
rc = 0;
fd = uv__open_cloexec(filename, O_RDONLY);
if (fd < 0)
return 0;
n = read(fd, buf, sizeof(buf) - 1);
if (n > 0) {
buf[n] = '\0';
sscanf(buf, "%" PRIu64, &rc);
}
if (uv__close_nocheckstdio(fd))
abort();
return rc;
}
uint64_t uv_get_constrained_memory(void) {
/*
* This might return 0 if there was a problem getting the memory limit from
* cgroups. This is OK because a return value of 0 signifies that the memory
* limit is unknown.
*/
return uv__read_cgroups_uint64("memory", "memory.limit_in_bytes");
}

View File

@ -358,7 +358,10 @@ int uv__statx(int dirfd,
int flags,
unsigned int mask,
struct uv__statx* statxbuf) {
#if defined(__NR_statx)
/* __NR_statx make Android box killed by SIGSYS.
* That looks like a seccomp2 sandbox filter rejecting the system call.
*/
#if defined(__NR_statx) && !defined(__ANDROID__)
return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
#else
return errno = ENOSYS, -1;

View File

@ -126,6 +126,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
int uv_resident_set_memory(size_t* rss) {
kvm_t *kd = NULL;
struct kinfo_proc2 *kinfo = NULL;

View File

@ -136,6 +136,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
int uv_resident_set_memory(size_t* rss) {
struct kinfo_proc kinfo;
size_t page_size = getpagesize();

View File

@ -356,6 +356,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
int uv_resident_set_memory(size_t* rss) {
char* ascb;
char* rax;

View File

@ -315,7 +315,7 @@ static void uv__process_child_init(const uv_process_options_t* options,
use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
close_fd = use_fd;
if (use_fd == -1) {
if (use_fd < 0) {
uv__write_int(error_fd, UV__ERR(errno));
_exit(127);
}
@ -431,6 +431,8 @@ int uv_spawn(uv_loop_t* loop,
UV_PROCESS_SETGID |
UV_PROCESS_SETUID |
UV_PROCESS_WINDOWS_HIDE |
UV_PROCESS_WINDOWS_HIDE_CONSOLE |
UV_PROCESS_WINDOWS_HIDE_GUI |
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);

View File

@ -380,6 +380,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
void uv_loadavg(double avg[3]) {
(void) getloadavg(avg, 3);
}

View File

@ -320,6 +320,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
uv_pid_t uv_os_getpid(void) {
return GetCurrentProcessId();
}
@ -703,9 +708,11 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
return 0;
error:
/* 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);
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_infos);
uv__free(sppi);

View File

@ -37,6 +37,10 @@ static void poll_cb_fail(uv_fs_poll_t* handle,
int status,
const uv_stat_t* prev,
const uv_stat_t* curr);
static void poll_cb_noop(uv_fs_poll_t* handle,
int status,
const uv_stat_t* prev,
const uv_stat_t* curr);
static uv_fs_poll_t poll_handle;
static uv_timer_t timer_handle;
@ -84,6 +88,12 @@ static void poll_cb_fail(uv_fs_poll_t* handle,
ASSERT(0 && "fail_cb called");
}
static void poll_cb_noop(uv_fs_poll_t* handle,
int status,
const uv_stat_t* prev,
const uv_stat_t* curr) {
}
static void poll_cb(uv_fs_poll_t* handle,
int status,
@ -259,3 +269,32 @@ TEST_IMPL(fs_poll_close_request_multi_stop_start) {
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(fs_poll_close_request_stop_when_active) {
/* Regression test for https://github.com/libuv/libuv/issues/2287. */
uv_loop_t loop;
uv_fs_poll_t poll_handle;
remove(FIXTURE);
ASSERT(0 == uv_loop_init(&loop));
/* Set up all handles. */
ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle));
ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_noop, FIXTURE, 100));
uv_run(&loop, UV_RUN_ONCE);
/* Close the timer handle, and do not crash. */
ASSERT(0 == uv_fs_poll_stop(&poll_handle));
uv_run(&loop, UV_RUN_ONCE);
/* Clean up after the test. */
uv_close((uv_handle_t*) &poll_handle, close_cb);
uv_run(&loop, UV_RUN_ONCE);
ASSERT(close_cb_called == 1);
ASSERT(0 == uv_loop_close(&loop));
MAKE_VALGRIND_HAPPY();
return 0;
}

View File

@ -611,6 +611,15 @@ static void sendfile_cb(uv_fs_t* req) {
}
static void sendfile_nodata_cb(uv_fs_t* req) {
ASSERT(req == &sendfile_req);
ASSERT(req->fs_type == UV_FS_SENDFILE);
ASSERT(req->result == 0);
sendfile_cb_count++;
uv_fs_req_cleanup(req);
}
static void open_noent_cb(uv_fs_t* req) {
ASSERT(req->fs_type == UV_FS_OPEN);
ASSERT(req->result == UV_ENOENT);
@ -1049,7 +1058,7 @@ TEST_IMPL(fs_async_dir) {
}
TEST_IMPL(fs_async_sendfile) {
static int test_sendfile(void (*setup)(int), uv_fs_cb cb, off_t expected_size) {
int f, r;
struct stat s1, s2;
@ -1062,14 +1071,8 @@ TEST_IMPL(fs_async_sendfile) {
f = open("test_file", O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR);
ASSERT(f != -1);
r = write(f, "begin\n", 6);
ASSERT(r == 6);
r = lseek(f, 65536, SEEK_CUR);
ASSERT(r == 65542);
r = write(f, "end\n", 4);
ASSERT(r != -1);
if (setup != NULL)
setup(f);
r = close(f);
ASSERT(r == 0);
@ -1087,7 +1090,7 @@ TEST_IMPL(fs_async_sendfile) {
uv_fs_req_cleanup(&open_req2);
r = uv_fs_sendfile(loop, &sendfile_req, open_req2.result, open_req1.result,
0, 131072, sendfile_cb);
0, 131072, cb);
ASSERT(r == 0);
uv_run(loop, UV_RUN_DEFAULT);
@ -1100,9 +1103,10 @@ TEST_IMPL(fs_async_sendfile) {
ASSERT(r == 0);
uv_fs_req_cleanup(&close_req);
stat("test_file", &s1);
stat("test_file2", &s2);
ASSERT(65546 == s2.st_size && s1.st_size == s2.st_size);
ASSERT(0 == stat("test_file", &s1));
ASSERT(0 == stat("test_file2", &s2));
ASSERT(s1.st_size == s2.st_size);
ASSERT(s2.st_size == expected_size);
/* Cleanup. */
unlink("test_file");
@ -1113,6 +1117,23 @@ TEST_IMPL(fs_async_sendfile) {
}
static void sendfile_setup(int f) {
ASSERT(6 == write(f, "begin\n", 6));
ASSERT(65542 == lseek(f, 65536, SEEK_CUR));
ASSERT(4 == write(f, "end\n", 4));
}
TEST_IMPL(fs_async_sendfile) {
return test_sendfile(sendfile_setup, sendfile_cb, 65546);
}
TEST_IMPL(fs_async_sendfile_nodata) {
return test_sendfile(NULL, sendfile_nodata_cb, 0);
}
TEST_IMPL(fs_mkdtemp) {
int r;
const char* path_template = "test_dir_XXXXXX";
@ -1171,6 +1192,7 @@ TEST_IMPL(fs_fstat) {
ASSERT(req.result == sizeof(test_buf));
uv_fs_req_cleanup(&req);
memset(&req.statbuf, 0xaa, sizeof(req.statbuf));
r = uv_fs_fstat(NULL, &req, file, NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
@ -1257,6 +1279,8 @@ TEST_IMPL(fs_fstat) {
s->st_birthtim.tv_sec == t.st_ctim.tv_sec);
ASSERT(s->st_birthtim.tv_nsec == 0 ||
s->st_birthtim.tv_nsec == t.st_ctim.tv_nsec);
ASSERT(s->st_flags == 0);
ASSERT(s->st_gen == 0);
#endif
uv_fs_req_cleanup(&req);

View File

@ -25,10 +25,12 @@
TEST_IMPL(get_memory) {
uint64_t free_mem = uv_get_free_memory();
uint64_t total_mem = uv_get_total_memory();
uint64_t constrained_mem = uv_get_constrained_memory();
printf("free_mem=%llu, total_mem=%llu\n",
printf("free_mem=%llu, total_mem=%llu, constrained_mem=%llu\n",
(unsigned long long) free_mem,
(unsigned long long) total_mem);
(unsigned long long) total_mem,
(unsigned long long) constrained_mem);
ASSERT(free_mem > 0);
ASSERT(total_mem > 0);

View File

@ -290,6 +290,7 @@ TEST_DECLARE (fs_poll_getpath)
TEST_DECLARE (fs_poll_close_request)
TEST_DECLARE (fs_poll_close_request_multi_start_stop)
TEST_DECLARE (fs_poll_close_request_multi_stop_start)
TEST_DECLARE (fs_poll_close_request_stop_when_active)
TEST_DECLARE (kill)
TEST_DECLARE (kill_invalid_signum)
TEST_DECLARE (fs_file_noent)
@ -300,6 +301,7 @@ TEST_DECLARE (fs_file_sync)
TEST_DECLARE (fs_file_write_null_buffer)
TEST_DECLARE (fs_async_dir)
TEST_DECLARE (fs_async_sendfile)
TEST_DECLARE (fs_async_sendfile_nodata)
TEST_DECLARE (fs_mkdtemp)
TEST_DECLARE (fs_fstat)
TEST_DECLARE (fs_access)
@ -843,6 +845,7 @@ TASK_LIST_START
TEST_ENTRY (fs_poll_close_request)
TEST_ENTRY (fs_poll_close_request_multi_start_stop)
TEST_ENTRY (fs_poll_close_request_multi_stop_start)
TEST_ENTRY (fs_poll_close_request_stop_when_active)
TEST_ENTRY (kill)
TEST_ENTRY (kill_invalid_signum)
@ -886,6 +889,7 @@ TASK_LIST_START
TEST_ENTRY (fs_file_write_null_buffer)
TEST_ENTRY (fs_async_dir)
TEST_ENTRY (fs_async_sendfile)
TEST_ENTRY (fs_async_sendfile_nodata)
TEST_ENTRY (fs_mkdtemp)
TEST_ENTRY (fs_fstat)
TEST_ENTRY (fs_access)
@ -959,7 +963,7 @@ TASK_LIST_START
TEST_ENTRY (strscpy)
TEST_ENTRY (threadpool_queue_work_simple)
TEST_ENTRY (threadpool_queue_work_einval)
TEST_ENTRY (threadpool_multiple_event_loops)
TEST_ENTRY_CUSTOM (threadpool_multiple_event_loops, 0, 0, 60000)
TEST_ENTRY (threadpool_cancel_getaddrinfo)
TEST_ENTRY (threadpool_cancel_getnameinfo)
TEST_ENTRY (threadpool_cancel_work)

View File

@ -1406,6 +1406,12 @@ TEST_IMPL(spawn_setuid_fails) {
options.flags |= UV_PROCESS_SETUID;
options.uid = 0;
/* These flags should be ignored on Unices. */
options.flags |= UV_PROCESS_WINDOWS_HIDE;
options.flags |= UV_PROCESS_WINDOWS_HIDE_CONSOLE;
options.flags |= UV_PROCESS_WINDOWS_HIDE_GUI;
options.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS;
r = uv_spawn(uv_default_loop(), &process, &options);
#if defined(__CYGWIN__)
ASSERT(r == UV_EINVAL);

1
deps/uv/uv.gyp vendored
View File

@ -241,7 +241,6 @@
'src/unix/linux-syscalls.h',
'src/unix/procfs-exepath.c',
'src/unix/sysinfo-loadavg.c',
'src/unix/sysinfo-memory.c',
],
'link_settings': {
'libraries': [ '-ldl', '-lrt' ],