Skip to content

Commit e9a514d

Browse files
cjihrigaddaleax
authored andcommittedSep 22, 2020
deps: upgrade to libuv 1.38.1
Notable changes: - A probable compiler bug in VS2019 was causing a failed assertion in libuv which appeared to the user as though the system clock was drifting. The `uv_hrtime()` code on Windows has been rearranged to work around the issue. - On Linux, `uv_loadavg()` attempts to read from `/proc/loadavg` before falling back to calling `sysinfo()`. This works around a bug in LXC. - A deadlock in the Windows TTY code has been fixed. - An issue on macOS related to monotonic clocks jumping back in time has been worked around. PR-URL: #34187 Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
1 parent a04d76d commit e9a514d

28 files changed

+774
-148
lines changed
 

‎deps/uv/AUTHORS

+3
Original file line numberDiff line numberDiff line change
@@ -432,3 +432,6 @@ Philip Chimento <philip.chimento@gmail.com>
432432
Michal Artazov <michal@artazov.cz>
433433
Jeroen Roovers <jer@gentoo.org>
434434
MasterDuke17 <MasterDuke17@users.noreply.github.com>
435+
Alexander Tokmakov <avtokmakov@yandex-team.ru>
436+
Arenoros <arenoros@gmail.com>
437+
lander0s <dh.landeros08@gmail.com>

‎deps/uv/CMakeLists.txt

+5-5
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
182182
endif()
183183

184184
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
185+
list(APPEND uv_defines _GNU_SOURCE)
185186
list(APPEND uv_libraries dl)
186187
list(APPEND uv_sources
187188
src/unix/android-ifaddrs.c
@@ -192,8 +193,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android")
192193
src/unix/pthread-fixes.c
193194
src/unix/random-getentropy.c
194195
src/unix/random-getrandom.c
195-
src/unix/random-sysctl-linux.c
196-
src/unix/sysinfo-loadavg.c)
196+
src/unix/random-sysctl-linux.c)
197197
endif()
198198

199199
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux|OS390")
@@ -206,7 +206,6 @@ endif()
206206

207207
if(CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|NetBSD|OpenBSD")
208208
list(APPEND uv_sources src/unix/posix-hrtime.c src/unix/bsd-proctitle.c)
209-
list(APPEND uv_libraries kvm)
210209
endif()
211210

212211
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|NetBSD|OpenBSD")
@@ -238,12 +237,12 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
238237
src/unix/linux-syscalls.c
239238
src/unix/procfs-exepath.c
240239
src/unix/random-getrandom.c
241-
src/unix/random-sysctl-linux.c
242-
src/unix/sysinfo-loadavg.c)
240+
src/unix/random-sysctl-linux.c)
243241
endif()
244242

245243
if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
246244
list(APPEND uv_sources src/unix/netbsd.c)
245+
list(APPEND uv_libraries kvm)
247246
endif()
248247

249248
if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
@@ -510,6 +509,7 @@ if(LIBUV_BUILD_TESTS)
510509
test/test-udp-send-and-recv.c
511510
test/test-udp-send-hang-loop.c
512511
test/test-udp-send-immediate.c
512+
test/test-udp-sendmmsg-error.c
513513
test/test-udp-send-unreachable.c
514514
test/test-udp-try-send.c
515515
test/test-uname.c

‎deps/uv/ChangeLog

+39
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,42 @@
1+
2020.07.04, Version 1.38.1 (Stable), e8b989ea1f7f9d4083511a2caec7791e9abd1871
2+
3+
Changes since version 1.38.0:
4+
5+
* test: use last matching qemu version (cjihrig)
6+
7+
* win, util: rearrange uv_hrtime (Bartosz Sosnowski)
8+
9+
* test: skip signal_multiple_loops test on QEMU (gengjiawen)
10+
11+
* build: add android build to CI (gengjiawen)
12+
13+
* test: extend fs_event_error_reporting timeout (cjihrig)
14+
15+
* build: link libkvm on netbsd only (Alexander Tokmakov)
16+
17+
* linux: refactor /proc file reader logic (Ben Noordhuis)
18+
19+
* linux: read load average from /proc/loadavg (Ben Noordhuis)
20+
21+
* android: remove patch code for below 21 (gengjiawen)
22+
23+
* win: fix visual studio 2008 build (Arenoros)
24+
25+
* win,tty: fix deadlock caused by inconsistent state (lander0s)
26+
27+
* unix: use relaxed loads/stores for feature checks (Ben Noordhuis)
28+
29+
* build: don't .gitignore m4/ax_pthread.m4 (Ben Noordhuis)
30+
31+
* unix: fix gcc atomics feature check (Ben Noordhuis)
32+
33+
* darwin: work around clock jumping back in time (Ben Noordhuis)
34+
35+
* udp: fix write_queue cleanup on sendmmsg error (Santiago Gimeno)
36+
37+
* src: build fix for Android (David Carlier)
38+
39+
140
2020.05.18, Version 1.38.0 (Stable), 1ab9ea3790378f9f25c4e78e9e2b511c75f9c9ed
241

342
Changes since version 1.37.0:

‎deps/uv/Makefile.am

+4-4
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
296296
test/test-udp-send-and-recv.c \
297297
test/test-udp-send-hang-loop.c \
298298
test/test-udp-send-immediate.c \
299+
test/test-udp-sendmmsg-error.c \
299300
test/test-udp-send-unreachable.c \
300301
test/test-udp-try-send.c \
301302
test/test-uname.c \
@@ -379,15 +380,15 @@ endif
379380

380381
if ANDROID
381382
uvinclude_HEADERS += include/uv/android-ifaddrs.h
383+
libuv_la_CFLAGS += -D_GNU_SOURCE
382384
libuv_la_SOURCES += src/unix/android-ifaddrs.c \
383385
src/unix/linux-core.c \
384386
src/unix/linux-inotify.c \
385387
src/unix/linux-syscalls.c \
386388
src/unix/procfs-exepath.c \
387389
src/unix/pthread-fixes.c \
388390
src/unix/random-getrandom.c \
389-
src/unix/random-sysctl-linux.c \
390-
src/unix/sysinfo-loadavg.c
391+
src/unix/random-sysctl-linux.c
391392
endif
392393

393394
if CYGWIN
@@ -468,8 +469,7 @@ libuv_la_SOURCES += src/unix/linux-core.c \
468469
src/unix/procfs-exepath.c \
469470
src/unix/proctitle.c \
470471
src/unix/random-getrandom.c \
471-
src/unix/random-sysctl-linux.c \
472-
src/unix/sysinfo-loadavg.c
472+
src/unix/random-sysctl-linux.c
473473
test_run_tests_LDFLAGS += -lutil
474474
endif
475475

‎deps/uv/configure.ac

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1414

1515
AC_PREREQ(2.57)
16-
AC_INIT([libuv], [1.38.0], [https://github.com/libuv/libuv/issues])
16+
AC_INIT([libuv], [1.38.1], [https://github.com/libuv/libuv/issues])
1717
AC_CONFIG_MACRO_DIR([m4])
1818
m4_include([m4/libuv-extra-automake-flags.m4])
1919
m4_include([m4/as_case.m4])

‎deps/uv/include/uv/version.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
#define UV_VERSION_MAJOR 1
3434
#define UV_VERSION_MINOR 38
35-
#define UV_VERSION_PATCH 0
35+
#define UV_VERSION_PATCH 1
3636
#define UV_VERSION_IS_RELEASE 1
3737
#define UV_VERSION_SUFFIX ""
3838

‎deps/uv/m4/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Ignore libtoolize-generated files.
22
*.m4
33
!as_case.m4
4+
!ax_pthread.m4
45
!libuv-check-flags.m4

‎deps/uv/m4/ax_pthread.m4

+485
Large diffs are not rendered by default.

‎deps/uv/src/unix/core.c

+19-22
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,6 @@ extern char** environ;
7979
# endif
8080
#endif
8181

82-
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
83-
# include <dlfcn.h> /* for dlsym */
84-
#endif
85-
8682
#if defined(__MVS__)
8783
#include <sys/ioctl.h>
8884
#endif
@@ -220,15 +216,23 @@ int uv__getiovmax(void) {
220216
#if defined(IOV_MAX)
221217
return IOV_MAX;
222218
#elif defined(_SC_IOV_MAX)
223-
static int iovmax = -1;
224-
if (iovmax == -1) {
225-
iovmax = sysconf(_SC_IOV_MAX);
226-
/* On some embedded devices (arm-linux-uclibc based ip camera),
227-
* sysconf(_SC_IOV_MAX) can not get the correct value. The return
228-
* value is -1 and the errno is EINPROGRESS. Degrade the value to 1.
229-
*/
230-
if (iovmax == -1) iovmax = 1;
231-
}
219+
static int iovmax_cached = -1;
220+
int iovmax;
221+
222+
iovmax = uv__load_relaxed(&iovmax_cached);
223+
if (iovmax != -1)
224+
return iovmax;
225+
226+
/* On some embedded devices (arm-linux-uclibc based ip camera),
227+
* sysconf(_SC_IOV_MAX) can not get the correct value. The return
228+
* value is -1 and the errno is EINPROGRESS. Degrade the value to 1.
229+
*/
230+
iovmax = sysconf(_SC_IOV_MAX);
231+
if (iovmax == -1)
232+
iovmax = 1;
233+
234+
uv__store_relaxed(&iovmax_cached, iovmax);
235+
232236
return iovmax;
233237
#else
234238
return 1024;
@@ -662,7 +666,7 @@ ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
662666
int* end;
663667
#if defined(__linux__)
664668
static int no_msg_cmsg_cloexec;
665-
if (no_msg_cmsg_cloexec == 0) {
669+
if (0 == uv__load_relaxed(&no_msg_cmsg_cloexec)) {
666670
rc = recvmsg(fd, msg, flags | 0x40000000); /* MSG_CMSG_CLOEXEC */
667671
if (rc != -1)
668672
return rc;
@@ -671,7 +675,7 @@ ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
671675
rc = recvmsg(fd, msg, flags);
672676
if (rc == -1)
673677
return UV__ERR(errno);
674-
no_msg_cmsg_cloexec = 1;
678+
uv__store_relaxed(&no_msg_cmsg_cloexec, 1);
675679
} else {
676680
rc = recvmsg(fd, msg, flags);
677681
}
@@ -1142,13 +1146,6 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
11421146
size_t shell_size;
11431147
long initsize;
11441148
int r;
1145-
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
1146-
int (*getpwuid_r)(uid_t, struct passwd*, char*, size_t, struct passwd**);
1147-
1148-
getpwuid_r = dlsym(RTLD_DEFAULT, "getpwuid_r");
1149-
if (getpwuid_r == NULL)
1150-
return UV_ENOSYS;
1151-
#endif
11521149

11531150
if (pwd == NULL)
11541151
return UV_EINVAL;

‎deps/uv/src/unix/darwin.c

+16-7
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@
2525
#include <stdint.h>
2626
#include <errno.h>
2727

28+
#include <dlfcn.h>
2829
#include <mach/mach.h>
2930
#include <mach/mach_time.h>
3031
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
3132
#include <sys/resource.h>
3233
#include <sys/sysctl.h>
3334
#include <unistd.h> /* sysconf */
3435

36+
static uv_once_t once = UV_ONCE_INIT;
37+
static uint64_t (*time_func)(void);
38+
static mach_timebase_info_data_t timebase;
39+
3540

3641
int uv__platform_loop_init(uv_loop_t* loop) {
3742
loop->cf_state = NULL;
@@ -48,15 +53,19 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
4853
}
4954

5055

51-
uint64_t uv__hrtime(uv_clocktype_t type) {
52-
static mach_timebase_info_data_t info;
53-
54-
if ((ACCESS_ONCE(uint32_t, info.numer) == 0 ||
55-
ACCESS_ONCE(uint32_t, info.denom) == 0) &&
56-
mach_timebase_info(&info) != KERN_SUCCESS)
56+
static void uv__hrtime_init_once(void) {
57+
if (KERN_SUCCESS != mach_timebase_info(&timebase))
5758
abort();
5859

59-
return mach_absolute_time() * info.numer / info.denom;
60+
time_func = (uint64_t (*)(void)) dlsym(RTLD_DEFAULT, "mach_continuous_time");
61+
if (time_func == NULL)
62+
time_func = mach_absolute_time;
63+
}
64+
65+
66+
uint64_t uv__hrtime(uv_clocktype_t type) {
67+
uv_once(&once, uv__hrtime_init_once);
68+
return time_func() * timebase.numer / timebase.denom;
6069
}
6170

6271

‎deps/uv/src/unix/fs.c

+6-10
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,7 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
229229
struct timespec ts[2];
230230
ts[0] = uv__fs_to_timespec(req->atime);
231231
ts[1] = uv__fs_to_timespec(req->mtime);
232-
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
233-
return utimensat(req->file, NULL, ts, 0);
234-
#else
235232
return futimens(req->file, ts);
236-
#endif
237233
#elif defined(__APPLE__) \
238234
|| defined(__DragonFly__) \
239235
|| defined(__FreeBSD__) \
@@ -316,7 +312,7 @@ static int uv__fs_mkstemp(uv_fs_t* req) {
316312
uv_once(&once, uv__mkostemp_initonce);
317313

318314
#ifdef O_CLOEXEC
319-
if (no_cloexec_support == 0 && uv__mkostemp != NULL) {
315+
if (uv__load_relaxed(&no_cloexec_support) == 0 && uv__mkostemp != NULL) {
320316
r = uv__mkostemp(path, O_CLOEXEC);
321317

322318
if (r >= 0)
@@ -329,7 +325,7 @@ static int uv__fs_mkstemp(uv_fs_t* req) {
329325

330326
/* We set the static variable so that next calls don't even
331327
try to use mkostemp. */
332-
no_cloexec_support = 1;
328+
uv__store_relaxed(&no_cloexec_support, 1);
333329
}
334330
#endif /* O_CLOEXEC */
335331

@@ -460,7 +456,7 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
460456
result = preadv(req->file, (struct iovec*) req->bufs, req->nbufs, req->off);
461457
#else
462458
# if defined(__linux__)
463-
if (no_preadv) retry:
459+
if (uv__load_relaxed(&no_preadv)) retry:
464460
# endif
465461
{
466462
result = uv__fs_preadv(req->file, req->bufs, req->nbufs, req->off);
@@ -472,7 +468,7 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
472468
req->nbufs,
473469
req->off);
474470
if (result == -1 && errno == ENOSYS) {
475-
no_preadv = 1;
471+
uv__store_relaxed(&no_preadv, 1);
476472
goto retry;
477473
}
478474
}
@@ -1355,7 +1351,7 @@ static int uv__fs_statx(int fd,
13551351
int mode;
13561352
int rc;
13571353

1358-
if (no_statx)
1354+
if (uv__load_relaxed(&no_statx))
13591355
return UV_ENOSYS;
13601356

13611357
dirfd = AT_FDCWD;
@@ -1388,7 +1384,7 @@ static int uv__fs_statx(int fd,
13881384
* implemented, rc might return 1 with 0 set as the error code in which
13891385
* case we return ENOSYS.
13901386
*/
1391-
no_statx = 1;
1387+
uv__store_relaxed(&no_statx, 1);
13921388
return UV_ENOSYS;
13931389
}
13941390

‎deps/uv/src/unix/kqueue.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ int uv__io_fork(uv_loop_t* loop) {
8282
process. So we sidestep the issue by pretending like we never
8383
started it in the first place.
8484
*/
85-
uv__has_forked_with_cfrunloop = 1;
85+
uv__store_relaxed(&uv__has_forked_with_cfrunloop, 1);
8686
uv__free(loop->cf_state);
8787
loop->cf_state = NULL;
8888
}
@@ -487,7 +487,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
487487
if (!(statbuf.st_mode & S_IFDIR))
488488
goto fallback;
489489

490-
if (!uv__has_forked_with_cfrunloop) {
490+
if (0 == uv__load_relaxed(&uv__has_forked_with_cfrunloop)) {
491491
int r;
492492
/* The fallback fd is no longer needed */
493493
uv__close_nocheckstdio(fd);
@@ -522,8 +522,9 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
522522
uv__handle_stop(handle);
523523

524524
#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
525-
if (!uv__has_forked_with_cfrunloop && handle->cf_cb != NULL)
526-
r = uv__fsevents_close(handle);
525+
if (0 == uv__load_relaxed(&uv__has_forked_with_cfrunloop))
526+
if (handle->cf_cb != NULL)
527+
r = uv__fsevents_close(handle);
527528
#endif
528529

529530
if (handle->event_watcher.fd != -1) {

‎deps/uv/src/unix/linux-core.c

+68-58
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,7 @@ static uint64_t read_cpufreq(unsigned int cpunum);
8585

8686
int uv__platform_loop_init(uv_loop_t* loop) {
8787
int fd;
88-
89-
/* It was reported that EPOLL_CLOEXEC is not defined on Android API < 21,
90-
* a.k.a. Lollipop. Since EPOLL_CLOEXEC is an alias for O_CLOEXEC on all
91-
* architectures, we just use that instead.
92-
*/
93-
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
94-
fd = -1;
95-
errno = ENOSYS;
96-
#else
9788
fd = epoll_create1(O_CLOEXEC);
98-
#endif
9989

10090
/* epoll_create1() can fail either because it's not implemented (old kernel)
10191
* or because it doesn't understand the O_CLOEXEC flag.
@@ -208,8 +198,10 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
208198
* that being the largest value I have seen in the wild (and only once.)
209199
*/
210200
static const int max_safe_timeout = 1789569;
211-
static int no_epoll_pwait;
212-
static int no_epoll_wait;
201+
static int no_epoll_pwait_cached;
202+
static int no_epoll_wait_cached;
203+
int no_epoll_pwait;
204+
int no_epoll_wait;
213205
struct epoll_event events[1024];
214206
struct epoll_event* pe;
215207
struct epoll_event e;
@@ -281,6 +273,15 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
281273
count = 48; /* Benchmarks suggest this gives the best throughput. */
282274
real_timeout = timeout;
283275

276+
/* You could argue there is a dependency between these two but
277+
* ultimately we don't care about their ordering with respect
278+
* to one another. Worst case, we make a few system calls that
279+
* could have been avoided because another thread already knows
280+
* they fail with ENOSYS. Hardly the end of the world.
281+
*/
282+
no_epoll_pwait = uv__load_relaxed(&no_epoll_pwait_cached);
283+
no_epoll_wait = uv__load_relaxed(&no_epoll_wait_cached);
284+
284285
for (;;) {
285286
/* See the comment for max_safe_timeout for an explanation of why
286287
* this is necessary. Executive summary: kernel bug workaround.
@@ -293,25 +294,24 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
293294
abort();
294295

295296
if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) {
296-
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
297-
nfds = -1;
298-
errno = ENOSYS;
299-
#else
300297
nfds = epoll_pwait(loop->backend_fd,
301298
events,
302299
ARRAY_SIZE(events),
303300
timeout,
304301
&sigset);
305-
#endif
306-
if (nfds == -1 && errno == ENOSYS)
302+
if (nfds == -1 && errno == ENOSYS) {
303+
uv__store_relaxed(&no_epoll_pwait_cached, 1);
307304
no_epoll_pwait = 1;
305+
}
308306
} else {
309307
nfds = epoll_wait(loop->backend_fd,
310308
events,
311309
ARRAY_SIZE(events),
312310
timeout);
313-
if (nfds == -1 && errno == ENOSYS)
311+
if (nfds == -1 && errno == ENOSYS) {
312+
uv__store_relaxed(&no_epoll_wait_cached, 1);
314313
no_epoll_wait = 1;
314+
}
315315
}
316316

317317
if (sigmask != 0 && no_epoll_pwait != 0)
@@ -982,43 +982,51 @@ void uv__set_process_title(const char* title) {
982982
}
983983

984984

985-
static uint64_t uv__read_proc_meminfo(const char* what) {
986-
uint64_t rc;
985+
static int uv__slurp(const char* filename, char* buf, size_t len) {
987986
ssize_t n;
988-
char* p;
989987
int fd;
990-
char buf[4096]; /* Large enough to hold all of /proc/meminfo. */
991988

992-
rc = 0;
993-
fd = uv__open_cloexec("/proc/meminfo", O_RDONLY);
989+
assert(len > 0);
994990

991+
fd = uv__open_cloexec(filename, O_RDONLY);
995992
if (fd < 0)
996-
return 0;
993+
return fd;
994+
995+
do
996+
n = read(fd, buf, len - 1);
997+
while (n == -1 && errno == EINTR);
997998

998-
n = read(fd, buf, sizeof(buf) - 1);
999+
if (uv__close_nocheckstdio(fd))
1000+
abort();
9991001

1000-
if (n <= 0)
1001-
goto out;
1002+
if (n < 0)
1003+
return UV__ERR(errno);
10021004

10031005
buf[n] = '\0';
1004-
p = strstr(buf, what);
10051006

1006-
if (p == NULL)
1007-
goto out;
1007+
return 0;
1008+
}
10081009

1009-
p += strlen(what);
10101010

1011-
if (1 != sscanf(p, "%" PRIu64 " kB", &rc))
1012-
goto out;
1011+
static uint64_t uv__read_proc_meminfo(const char* what) {
1012+
uint64_t rc;
1013+
char* p;
1014+
char buf[4096]; /* Large enough to hold all of /proc/meminfo. */
10131015

1014-
rc *= 1024;
1016+
if (uv__slurp("/proc/meminfo", buf, sizeof(buf)))
1017+
return 0;
10151018

1016-
out:
1019+
p = strstr(buf, what);
10171020

1018-
if (uv__close_nocheckstdio(fd))
1019-
abort();
1021+
if (p == NULL)
1022+
return 0;
10201023

1021-
return rc;
1024+
p += strlen(what);
1025+
1026+
rc = 0;
1027+
sscanf(p, "%" PRIu64 " kB", &rc);
1028+
1029+
return rc * 1024;
10221030
}
10231031

10241032

@@ -1056,28 +1064,13 @@ uint64_t uv_get_total_memory(void) {
10561064

10571065
static uint64_t uv__read_cgroups_uint64(const char* cgroup, const char* param) {
10581066
char filename[256];
1059-
uint64_t rc;
1060-
int fd;
1061-
ssize_t n;
10621067
char buf[32]; /* Large enough to hold an encoded uint64_t. */
1063-
1064-
snprintf(filename, 256, "/sys/fs/cgroup/%s/%s", cgroup, param);
1068+
uint64_t rc;
10651069

10661070
rc = 0;
1067-
fd = uv__open_cloexec(filename, O_RDONLY);
1068-
1069-
if (fd < 0)
1070-
return 0;
1071-
1072-
n = read(fd, buf, sizeof(buf) - 1);
1073-
1074-
if (n > 0) {
1075-
buf[n] = '\0';
1071+
snprintf(filename, sizeof(filename), "/sys/fs/cgroup/%s/%s", cgroup, param);
1072+
if (0 == uv__slurp(filename, buf, sizeof(buf)))
10761073
sscanf(buf, "%" PRIu64, &rc);
1077-
}
1078-
1079-
if (uv__close_nocheckstdio(fd))
1080-
abort();
10811074

10821075
return rc;
10831076
}
@@ -1091,3 +1084,20 @@ uint64_t uv_get_constrained_memory(void) {
10911084
*/
10921085
return uv__read_cgroups_uint64("memory", "memory.limit_in_bytes");
10931086
}
1087+
1088+
1089+
void uv_loadavg(double avg[3]) {
1090+
struct sysinfo info;
1091+
char buf[128]; /* Large enough to hold all of /proc/loadavg. */
1092+
1093+
if (0 == uv__slurp("/proc/loadavg", buf, sizeof(buf)))
1094+
if (3 == sscanf(buf, "%lf %lf %lf", &avg[0], &avg[1], &avg[2]))
1095+
return;
1096+
1097+
if (sysinfo(&info) < 0)
1098+
return;
1099+
1100+
avg[0] = (double) info.loads[0] / 65536.0;
1101+
avg[1] = (double) info.loads[1] / 65536.0;
1102+
avg[2] = (double) info.loads[2] / 65536.0;
1103+
}

‎deps/uv/src/unix/os390-syscalls.c

-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#pragma linkage(BPX4CTW, OS)
3434
#pragma linkage(BPX1CTW, OS)
3535

36-
static int number_of_epolls;
3736
static QUEUE global_epoll_queue;
3837
static uv_mutex_t global_epoll_lock;
3938
static uv_once_t once = UV_ONCE_INIT;

‎deps/uv/src/unix/pthread-fixes.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
*/
3131

3232
/* Android versions < 4.1 have a broken pthread_sigmask. */
33+
#include "uv-common.h"
34+
3335
#include <errno.h>
3436
#include <pthread.h>
3537
#include <signal.h>
@@ -38,13 +40,13 @@ int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset) {
3840
static int workaround;
3941
int err;
4042

41-
if (workaround) {
43+
if (uv__load_relaxed(&workaround)) {
4244
return sigprocmask(how, set, oset);
4345
} else {
4446
err = pthread_sigmask(how, set, oset);
4547
if (err) {
4648
if (err == EINVAL && sigprocmask(how, set, oset) == 0) {
47-
workaround = 1;
49+
uv__store_relaxed(&workaround, 1);
4850
return 0;
4951
} else {
5052
return -1;

‎deps/uv/src/unix/tcp.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -326,16 +326,19 @@ int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) {
326326

327327

328328
int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
329-
static int single_accept = -1;
329+
static int single_accept_cached = -1;
330330
unsigned long flags;
331+
int single_accept;
331332
int err;
332333

333334
if (tcp->delayed_error)
334335
return tcp->delayed_error;
335336

337+
single_accept = uv__load_relaxed(&single_accept_cached);
336338
if (single_accept == -1) {
337339
const char* val = getenv("UV_TCP_SINGLE_ACCEPT");
338340
single_accept = (val != NULL && atoi(val) != 0); /* Off by default. */
341+
uv__store_relaxed(&single_accept_cached, single_accept);
339342
}
340343

341344
if (single_accept)

‎deps/uv/src/unix/thread.c

-11
Original file line numberDiff line numberDiff line change
@@ -709,11 +709,9 @@ int uv_cond_init(uv_cond_t* cond) {
709709
if (err)
710710
return UV__ERR(err);
711711

712-
#if !(defined(__ANDROID_API__) && __ANDROID_API__ < 21)
713712
err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
714713
if (err)
715714
goto error2;
716-
#endif
717715

718716
err = pthread_cond_init(cond, &attr);
719717
if (err)
@@ -805,16 +803,7 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
805803
#endif
806804
ts.tv_sec = timeout / NANOSEC;
807805
ts.tv_nsec = timeout % NANOSEC;
808-
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
809-
810-
/*
811-
* The bionic pthread implementation doesn't support CLOCK_MONOTONIC,
812-
* but has this alternative function instead.
813-
*/
814-
r = pthread_cond_timedwait_monotonic_np(cond, mutex, &ts);
815-
#else
816806
r = pthread_cond_timedwait(cond, mutex, &ts);
817-
#endif /* __ANDROID_API__ */
818807
#endif
819808

820809

‎deps/uv/src/unix/udp.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ static void uv__udp_sendmmsg(uv_udp_t* handle) {
367367
return;
368368
for (i = 0, q = QUEUE_HEAD(&handle->write_queue);
369369
i < pkts && q != &handle->write_queue;
370-
++i, q = QUEUE_HEAD(q)) {
370+
++i, q = QUEUE_HEAD(&handle->write_queue)) {
371371
assert(q != NULL);
372372
req = QUEUE_DATA(q, uv_udp_send_t, queue);
373373
assert(req != NULL);

‎deps/uv/src/uv-common.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -859,11 +859,11 @@ __attribute__((destructor))
859859
void uv_library_shutdown(void) {
860860
static int was_shutdown;
861861

862-
if (was_shutdown)
862+
if (uv__load_relaxed(&was_shutdown))
863863
return;
864864

865865
uv__process_title_cleanup();
866866
uv__signal_cleanup();
867867
uv__threadpool_cleanup();
868-
was_shutdown = 1;
868+
uv__store_relaxed(&was_shutdown, 1);
869869
}

‎deps/uv/src/uv-common.h

+8
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ extern int snprintf(char*, size_t, const char*, ...);
6060
#define STATIC_ASSERT(expr) \
6161
void uv__static_assert(int static_assert_failed[1 - 2 * !(expr)])
6262

63+
#if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 7)
64+
#define uv__load_relaxed(p) __atomic_load_n(p, __ATOMIC_RELAXED)
65+
#define uv__store_relaxed(p, v) __atomic_store_n(p, v, __ATOMIC_RELAXED)
66+
#else
67+
#define uv__load_relaxed(p) (*p)
68+
#define uv__store_relaxed(p, v) do *p = v; while (0)
69+
#endif
70+
6371
/* Handle flags. Some flags are specific to Windows or UNIX. */
6472
enum {
6573
/* Used by all handles. */

‎deps/uv/src/win/internal.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
266266
*/
267267
void uv__util_init(void);
268268

269-
uint64_t uv__hrtime(double scale);
269+
uint64_t uv__hrtime(unsigned int scale);
270270
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
271271
int uv__getpwuid_r(uv_passwd_t* pwd);
272272
int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8);

‎deps/uv/src/win/tty.c

+1
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
517517
status = InterlockedExchange(&uv__read_console_status, IN_PROGRESS);
518518
if (status == TRAP_REQUESTED) {
519519
SET_REQ_SUCCESS(req);
520+
InterlockedExchange(&uv__read_console_status, COMPLETED);
520521
req->u.io.overlapped.InternalHigh = 0;
521522
POST_COMPLETION_FOR_REQ(loop, req);
522523
return 0;

‎deps/uv/src/win/udp.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,9 @@ int uv__udp_set_source_membership6(uv_udp_t* handle,
752752
int optname;
753753
int err;
754754

755+
STATIC_ASSERT(sizeof(mreq.gsr_group) >= sizeof(*multicast_addr));
756+
STATIC_ASSERT(sizeof(mreq.gsr_source) >= sizeof(*source_addr));
757+
755758
if ((handle->flags & UV_HANDLE_BOUND) && !(handle->flags & UV_HANDLE_IPV6))
756759
return UV_EINVAL;
757760

@@ -774,8 +777,6 @@ int uv__udp_set_source_membership6(uv_udp_t* handle,
774777
mreq.gsr_interface = 0;
775778
}
776779

777-
STATIC_ASSERT(sizeof(mreq.gsr_group) >= sizeof(*multicast_addr));
778-
STATIC_ASSERT(sizeof(mreq.gsr_source) >= sizeof(*source_addr));
779780
memcpy(&mreq.gsr_group, multicast_addr, sizeof(*multicast_addr));
780781
memcpy(&mreq.gsr_source, source_addr, sizeof(*source_addr));
781782

‎deps/uv/src/win/util.c

+14-12
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ extern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength);
6767
static char *process_title;
6868
static CRITICAL_SECTION process_title_lock;
6969

70-
/* Interval (in seconds) of the high-resolution clock. */
71-
static double hrtime_interval_ = 0;
70+
/* Frequency of the high-resolution clock. */
71+
static uint64_t hrtime_frequency_ = 0;
7272

7373

7474
/*
@@ -84,9 +84,9 @@ void uv__util_init(void) {
8484
* and precompute its reciprocal.
8585
*/
8686
if (QueryPerformanceFrequency(&perf_frequency)) {
87-
hrtime_interval_ = 1.0 / perf_frequency.QuadPart;
87+
hrtime_frequency_ = perf_frequency.QuadPart;
8888
} else {
89-
hrtime_interval_= 0;
89+
uv_fatal_error(GetLastError(), "QueryPerformanceFrequency");
9090
}
9191
}
9292

@@ -490,23 +490,25 @@ uint64_t uv_hrtime(void) {
490490
return uv__hrtime(UV__NANOSEC);
491491
}
492492

493-
uint64_t uv__hrtime(double scale) {
493+
uint64_t uv__hrtime(unsigned int scale) {
494494
LARGE_INTEGER counter;
495+
double scaled_freq;
496+
double result;
495497

496-
/* If the performance interval is zero, there's no support. */
497-
if (hrtime_interval_ == 0) {
498-
return 0;
499-
}
500-
498+
assert(hrtime_frequency_ != 0);
499+
assert(scale != 0);
501500
if (!QueryPerformanceCounter(&counter)) {
502-
return 0;
501+
uv_fatal_error(GetLastError(), "QueryPerformanceCounter");
503502
}
503+
assert(counter.QuadPart != 0);
504504

505505
/* Because we have no guarantee about the order of magnitude of the
506506
* performance counter interval, integer math could cause this computation
507507
* to overflow. Therefore we resort to floating point math.
508508
*/
509-
return (uint64_t) ((double) counter.QuadPart * hrtime_interval_ * scale);
509+
scaled_freq = (double) hrtime_frequency_ / scale;
510+
result = (double) counter.QuadPart / scaled_freq;
511+
return (uint64_t) result;
510512
}
511513

512514

‎deps/uv/test/test-list.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ TEST_DECLARE (udp_open_connect)
180180
#ifndef _WIN32
181181
TEST_DECLARE (udp_send_unix)
182182
#endif
183+
TEST_DECLARE (udp_sendmmsg_error)
183184
TEST_DECLARE (udp_try_send)
184185
TEST_DECLARE (pipe_bind_error_addrinuse)
185186
TEST_DECLARE (pipe_bind_error_addrnotavail)
@@ -720,6 +721,7 @@ TASK_LIST_START
720721
TEST_ENTRY (udp_multicast_join)
721722
TEST_ENTRY (udp_multicast_join6)
722723
TEST_ENTRY (udp_multicast_ttl)
724+
TEST_ENTRY (udp_sendmmsg_error)
723725
TEST_ENTRY (udp_try_send)
724726

725727
TEST_ENTRY (udp_open)
@@ -1010,7 +1012,7 @@ TASK_LIST_START
10101012
TEST_ENTRY (fs_event_close_with_pending_event)
10111013
TEST_ENTRY (fs_event_close_in_callback)
10121014
TEST_ENTRY (fs_event_start_and_close)
1013-
TEST_ENTRY (fs_event_error_reporting)
1015+
TEST_ENTRY_CUSTOM (fs_event_error_reporting, 0, 0, 60000)
10141016
TEST_ENTRY (fs_event_getpath)
10151017
TEST_ENTRY (fs_scandir_empty_dir)
10161018
TEST_ENTRY (fs_scandir_non_existent_dir)

‎deps/uv/test/test-signal-multiple-loops.c

+5
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ TEST_IMPL(signal_multiple_loops) {
199199
though it is supposed to be blocking. Also the test hangs during
200200
thread setup occasionally. */
201201
RETURN_SKIP("FIXME: This test needs more investigation on Cygwin");
202+
#endif
203+
/* TODO(gengjiawen): Fix test on QEMU. */
204+
#if defined(__QEMU__)
205+
// See https://github.com/libuv/libuv/issues/2859
206+
RETURN_SKIP("QEMU's signal emulation code is notoriously tricky");
202207
#endif
203208
uv_thread_t loop_creating_threads[NUM_LOOP_CREATING_THREADS];
204209
uv_thread_t signal_handling_threads[NUM_SIGNAL_HANDLING_THREADS];
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/* Copyright libuv project and contributors. All rights reserved.
2+
*
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to
5+
* deal in the Software without restriction, including without limitation the
6+
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7+
* sell copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19+
* IN THE SOFTWARE.
20+
*/
21+
22+
#include "uv.h"
23+
#include "task.h"
24+
25+
#include <stdio.h>
26+
#include <stdlib.h>
27+
28+
#define DATAGRAMS 6
29+
30+
static uv_udp_t client;
31+
static uv_udp_send_t req[DATAGRAMS];
32+
33+
static int send_cb_called;
34+
static int close_cb_called;
35+
36+
37+
static void close_cb(uv_handle_t* handle) {
38+
ASSERT_PTR_EQ(handle, &client);
39+
ASSERT(uv_is_closing(handle));
40+
close_cb_called++;
41+
}
42+
43+
44+
static void send_cb(uv_udp_send_t* req, int status) {
45+
if (status != 0)
46+
ASSERT_EQ(status, UV_ECONNREFUSED);
47+
48+
if (++send_cb_called == DATAGRAMS)
49+
uv_close((uv_handle_t*)&client, close_cb);
50+
}
51+
52+
53+
TEST_IMPL(udp_sendmmsg_error) {
54+
struct sockaddr_in addr;
55+
uv_buf_t buf;
56+
int i;
57+
58+
ASSERT_EQ(0, uv_udp_init(uv_default_loop(), &client));
59+
ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
60+
ASSERT_EQ(0, uv_udp_connect(&client, (const struct sockaddr*)&addr));
61+
62+
buf = uv_buf_init("TEST", 4);
63+
for (i = 0; i < DATAGRAMS; ++i)
64+
ASSERT_EQ(0, uv_udp_send(&req[i], &client, &buf, 1, NULL, send_cb));
65+
66+
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
67+
68+
ASSERT_EQ(1, close_cb_called);
69+
ASSERT_EQ(DATAGRAMS, send_cb_called);
70+
71+
ASSERT_EQ(0, client.send_queue_size);
72+
73+
MAKE_VALGRIND_HAPPY();
74+
return 0;
75+
}

‎deps/uv/uv.gyp

-2
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,6 @@
245245
'src/unix/procfs-exepath.c',
246246
'src/unix/random-getrandom.c',
247247
'src/unix/random-sysctl-linux.c',
248-
'src/unix/sysinfo-loadavg.c',
249248
],
250249
'link_settings': {
251250
'libraries': [ '-ldl', '-lrt' ],
@@ -262,7 +261,6 @@
262261
'src/unix/procfs-exepath.c',
263262
'src/unix/random-getrandom.c',
264263
'src/unix/random-sysctl-linux.c',
265-
'src/unix/sysinfo-loadavg.c',
266264
],
267265
'link_settings': {
268266
'libraries': [ '-ldl' ],

0 commit comments

Comments
 (0)
Please sign in to comment.