libuv 1.44.0

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3856 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
2022-03-07 21:34:07 +00:00
parent b488db9137
commit 41cabad264
81 changed files with 2216 additions and 2026 deletions

View File

@ -23,7 +23,9 @@ BENCHMARK_DECLARE (sizes)
BENCHMARK_DECLARE (loop_count)
BENCHMARK_DECLARE (loop_count_timed)
BENCHMARK_DECLARE (ping_pongs)
BENCHMARK_DECLARE (ping_udp)
BENCHMARK_DECLARE (ping_udp1)
BENCHMARK_DECLARE (ping_udp10)
BENCHMARK_DECLARE (ping_udp100)
BENCHMARK_DECLARE (tcp_write_batch)
BENCHMARK_DECLARE (tcp4_pound_100)
BENCHMARK_DECLARE (tcp4_pound_1000)
@ -72,6 +74,7 @@ BENCHMARK_DECLARE (async_pummel_1)
BENCHMARK_DECLARE (async_pummel_2)
BENCHMARK_DECLARE (async_pummel_4)
BENCHMARK_DECLARE (async_pummel_8)
BENCHMARK_DECLARE (queue_work)
BENCHMARK_DECLARE (spawn)
BENCHMARK_DECLARE (thread_create)
BENCHMARK_DECLARE (million_async)
@ -90,6 +93,10 @@ TASK_LIST_START
BENCHMARK_ENTRY (ping_pongs)
BENCHMARK_HELPER (ping_pongs, tcp4_echo_server)
BENCHMARK_ENTRY (ping_udp1)
BENCHMARK_ENTRY (ping_udp10)
BENCHMARK_ENTRY (ping_udp100)
BENCHMARK_ENTRY (tcp_write_batch)
BENCHMARK_HELPER (tcp_write_batch, tcp4_blackhole_server)
@ -155,6 +162,7 @@ TASK_LIST_START
BENCHMARK_ENTRY (async_pummel_2)
BENCHMARK_ENTRY (async_pummel_4)
BENCHMARK_ENTRY (async_pummel_8)
BENCHMARK_ENTRY (queue_work)
BENCHMARK_ENTRY (spawn)
BENCHMARK_ENTRY (thread_create)

View File

@ -94,6 +94,9 @@ static void pinger_read_cb(uv_udp_t* udp,
pinger_t* pinger;
pinger = (pinger_t*)udp->data;
/* No data here means something went wrong */
ASSERT(nread > 0);
/* Now we count the pings */
for (i = 0; i < nread; i++) {
ASSERT(buf->base[i] == PING[pinger->state]);
@ -108,7 +111,8 @@ static void pinger_read_cb(uv_udp_t* udp,
}
}
buf_free(buf);
if (buf && !(flags & UV_UDP_MMSG_CHUNK))
buf_free(buf);
}
static void udp_pinger_new(void) {
@ -122,6 +126,8 @@ static void udp_pinger_new(void) {
/* Try to do NUM_PINGS ping-pongs (connection-less). */
r = uv_udp_init(loop, &pinger->udp);
ASSERT(r == 0);
r = uv_udp_bind(&pinger->udp, (const struct sockaddr*) &pinger->server_addr, 0);
ASSERT(r == 0);
pinger->udp.data = pinger;

68
deps/libuv/test/benchmark-queue-work.c vendored Normal file
View File

@ -0,0 +1,68 @@
/* Copyright libuv contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "task.h"
#include "uv.h"
static int done = 0;
static unsigned events = 0;
static unsigned result;
static unsigned fastrand(void) {
static unsigned g = 0;
g = g * 214013 + 2531011;
return g;
}
static void work_cb(uv_work_t* req) {
req->data = &result;
*(unsigned*)req->data = fastrand();
}
static void after_work_cb(uv_work_t* req, int status) {
events++;
if (!done)
ASSERT_EQ(0, uv_queue_work(req->loop, req, work_cb, after_work_cb));
}
static void timer_cb(uv_timer_t* handle) { done = 1; }
BENCHMARK_IMPL(queue_work) {
uv_timer_t timer_handle;
uv_work_t work;
uv_loop_t* loop;
int timeout;
loop = uv_default_loop();
timeout = 5000;
ASSERT_EQ(0, uv_timer_init(loop, &timer_handle));
ASSERT_EQ(0, uv_timer_start(&timer_handle, timer_cb, timeout, 0));
ASSERT_EQ(0, uv_queue_work(loop, &work, work_cb, after_work_cb));
ASSERT_EQ(0, uv_run(loop, UV_RUN_DEFAULT));
printf("%s async jobs in %.1f seconds (%s/s)\n", fmt(events), timeout / 1000.,
fmt(events / (timeout / 1000.)));
MAKE_VALGRIND_HAPPY();
return 0;
}

View File

@ -49,7 +49,6 @@ __attribute__((constructor)) void init() {
int ipc_helper(int listen_after_write);
int ipc_helper_heavy_traffic_deadlock_bug(void);
int ipc_helper_tcp_connection(void);
int ipc_helper_closed_handle(void);
int ipc_send_recv_helper(void);
int ipc_helper_bind_twice(void);
int ipc_helper_send_zero(void);
@ -119,10 +118,6 @@ static int maybe_run_test(int argc, char **argv) {
return ipc_helper_tcp_connection();
}
if (strcmp(argv[1], "ipc_helper_closed_handle") == 0) {
return ipc_helper_closed_handle();
}
if (strcmp(argv[1], "ipc_helper_bind_twice") == 0) {
return ipc_helper_bind_twice();
}

View File

@ -333,8 +333,8 @@ int process_wait(process_info_t* vec, int n, int timeout) {
abort();
terminate:
close(args.pipe[0]);
close(args.pipe[1]);
closefd(args.pipe[0]);
closefd(args.pipe[1]);
return retval;
}

View File

@ -851,7 +851,12 @@ static void check_utime(const char* path,
#endif
st_atim = s->st_atim.tv_sec + s->st_atim.tv_nsec / 1e9;
st_mtim = s->st_mtim.tv_sec + s->st_mtim.tv_nsec / 1e9;
ASSERT_DOUBLE_EQ(st_atim, atime);
/*
* Linux does not allow reading reliably the atime of a symlink
* since readlink() can update it
*/
if (!test_lutime)
ASSERT_DOUBLE_EQ(st_atim, atime);
ASSERT_DOUBLE_EQ(st_mtim, mtime);
}

View File

@ -22,6 +22,10 @@
#include "uv.h"
#include "task.h"
#include <string.h>
#ifndef _WIN32
#include <unistd.h>
#include <sys/types.h>
#endif
TEST_IMPL(get_passwd) {
/* TODO(gengjiawen): Fix test on QEMU. */
@ -64,11 +68,15 @@ TEST_IMPL(get_passwd) {
#endif
#ifdef _WIN32
ASSERT(pwd.uid == -1);
ASSERT(pwd.gid == -1);
ASSERT_EQ(pwd.uid, (unsigned)-1);
ASSERT_EQ(pwd.gid, (unsigned)-1);
#else
ASSERT(pwd.uid >= 0);
ASSERT(pwd.gid >= 0);
ASSERT_NE(pwd.uid, (unsigned)-1);
ASSERT_NE(pwd.gid, (unsigned)-1);
ASSERT_EQ(pwd.uid, geteuid());
if (pwd.uid != 0 && pwd.gid != getgid())
/* This will be likely true, as only root could have changed it. */
ASSERT_EQ(pwd.gid, getegid());
#endif
/* Test uv_os_free_passwd() */

View File

@ -308,8 +308,12 @@ static void read_cb(uv_stream_t* handle,
return;
}
ASSERT_GE(nread, 0);
pipe = (uv_pipe_t*) handle;
do {
ASSERT_EQ(pipe, &ctx2.channel);
while (uv_pipe_pending_count(pipe) > 0) {
if (++read_cb_count == 2) {
recv = &ctx2.recv;
write_req = &ctx2.write_req;
@ -318,10 +322,6 @@ static void read_cb(uv_stream_t* handle,
write_req = &ctx2.write_req2;
}
ASSERT(pipe == &ctx2.channel);
ASSERT(nread >= 0);
ASSERT(uv_pipe_pending_count(pipe) > 0);
pending = uv_pipe_pending_type(pipe);
ASSERT(pending == UV_NAMED_PIPE || pending == UV_TCP);
@ -344,7 +344,7 @@ static void read_cb(uv_stream_t* handle,
&recv->stream,
write2_cb);
ASSERT(r == 0);
} while (uv_pipe_pending_count(pipe) > 0);
}
}
static void send_recv_start(void) {

View File

@ -45,8 +45,6 @@ static int close_cb_called;
static int connection_accepted;
static int tcp_conn_read_cb_called;
static int tcp_conn_write_cb_called;
static int closed_handle_data_read;
static int closed_handle_write;
static int send_zero_write;
typedef struct {
@ -57,15 +55,6 @@ typedef struct {
#define CONN_COUNT 100
#define BACKLOG 128
#define LARGE_SIZE 100000
static uv_buf_t large_buf;
static char buffer[LARGE_SIZE];
static uv_write_t write_reqs[300];
static int write_reqs_completed;
static unsigned int write_until_data_queued(void);
static void send_handle_and_close(void);
static void close_server_conn_cb(uv_handle_t* handle) {
@ -417,26 +406,6 @@ static void on_read_connection(uv_stream_t* handle,
}
#ifndef _WIN32
static void on_read_closed_handle(uv_stream_t* handle,
ssize_t nread,
const uv_buf_t* buf) {
if (nread == 0 || nread == UV_EOF) {
free(buf->base);
return;
}
if (nread < 0) {
printf("error recving on channel: %s\n", uv_strerror(nread));
abort();
}
closed_handle_data_read += nread;
free(buf->base);
}
#endif
static void on_read_send_zero(uv_stream_t* handle,
ssize_t nread,
const uv_buf_t* buf) {
@ -498,15 +467,6 @@ TEST_IMPL(ipc_tcp_connection) {
return r;
}
#ifndef _WIN32
TEST_IMPL(ipc_closed_handle) {
int r;
r = run_ipc_test("ipc_helper_closed_handle", on_read_closed_handle);
ASSERT_EQ(r, 0);
return 0;
}
#endif
#ifdef _WIN32
TEST_IMPL(listen_with_simultaneous_accepts) {
@ -602,23 +562,6 @@ static void tcp_connection_write_cb(uv_write_t* req, int status) {
}
static void closed_handle_large_write_cb(uv_write_t* req, int status) {
ASSERT_EQ(status, 0);
ASSERT(closed_handle_data_read = LARGE_SIZE);
if (++write_reqs_completed == ARRAY_SIZE(write_reqs)) {
write_reqs_completed = 0;
if (write_until_data_queued() > 0)
send_handle_and_close();
}
}
static void closed_handle_write_cb(uv_write_t* req, int status) {
ASSERT_EQ(status, UV_EBADF);
closed_handle_write = 1;
}
static void send_zero_write_cb(uv_write_t* req, int status) {
ASSERT_EQ(status, 0);
send_zero_write++;
@ -835,76 +778,6 @@ int ipc_helper_tcp_connection(void) {
return 0;
}
static unsigned int write_until_data_queued() {
unsigned int i;
int r;
i = 0;
do {
r = uv_write(&write_reqs[i],
(uv_stream_t*)&channel,
&large_buf,
1,
closed_handle_large_write_cb);
ASSERT_EQ(r, 0);
i++;
} while (channel.write_queue_size == 0 &&
i < ARRAY_SIZE(write_reqs));
return channel.write_queue_size;
}
static void send_handle_and_close() {
int r;
struct sockaddr_in addr;
r = uv_tcp_init(uv_default_loop(), &tcp_server);
ASSERT_EQ(r, 0);
ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
ASSERT_EQ(r, 0);
r = uv_write2(&write_req,
(uv_stream_t*)&channel,
&large_buf,
1,
(uv_stream_t*)&tcp_server,
closed_handle_write_cb);
ASSERT_EQ(r, 0);
uv_close((uv_handle_t*)&tcp_server, NULL);
}
int ipc_helper_closed_handle(void) {
int r;
memset(buffer, '.', LARGE_SIZE);
large_buf = uv_buf_init(buffer, LARGE_SIZE);
r = uv_pipe_init(uv_default_loop(), &channel, 1);
ASSERT_EQ(r, 0);
uv_pipe_open(&channel, 0);
ASSERT_EQ(1, uv_is_readable((uv_stream_t*) &channel));
ASSERT_EQ(1, uv_is_writable((uv_stream_t*) &channel));
ASSERT_EQ(0, uv_is_closing((uv_handle_t*) &channel));
if (write_until_data_queued() > 0)
send_handle_and_close();
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT_EQ(r, 0);
ASSERT_EQ(closed_handle_write, 1);
MAKE_VALGRIND_HAPPY();
return 0;
}
int ipc_helper_bind_twice(void) {
/*
* This is launched from test-ipc.c. stdin is a duplex channel

View File

@ -91,9 +91,6 @@ TEST_DECLARE (ipc_send_recv_tcp)
TEST_DECLARE (ipc_send_recv_tcp_inprocess)
TEST_DECLARE (ipc_tcp_connection)
TEST_DECLARE (ipc_send_zero)
#ifndef _WIN32
TEST_DECLARE (ipc_closed_handle)
#endif
TEST_DECLARE (tcp_alloc_cb_fail)
TEST_DECLARE (tcp_ping_pong)
TEST_DECLARE (tcp_ping_pong_vec)
@ -320,6 +317,7 @@ TEST_DECLARE (spawn_reads_child_path)
TEST_DECLARE (spawn_inherit_streams)
TEST_DECLARE (spawn_quoted_path)
TEST_DECLARE (spawn_tcp_server)
TEST_DECLARE (spawn_exercise_sigchld_issue)
TEST_DECLARE (fs_poll)
TEST_DECLARE (fs_poll_getpath)
TEST_DECLARE (fs_poll_close_request)
@ -627,9 +625,6 @@ TASK_LIST_START
TEST_ENTRY (ipc_send_recv_tcp_inprocess)
TEST_ENTRY (ipc_tcp_connection)
TEST_ENTRY (ipc_send_zero)
#ifndef _WIN32
TEST_ENTRY (ipc_closed_handle)
#endif
TEST_ENTRY (tcp_alloc_cb_fail)
@ -950,6 +945,7 @@ TASK_LIST_START
TEST_ENTRY (spawn_inherit_streams)
TEST_ENTRY (spawn_quoted_path)
TEST_ENTRY (spawn_tcp_server)
TEST_ENTRY (spawn_exercise_sigchld_issue)
TEST_ENTRY (fs_poll)
TEST_ENTRY (fs_poll_getpath)
TEST_ENTRY (fs_poll_close_request)

View File

@ -28,7 +28,7 @@ TEST_IMPL(loop_update_time) {
start = uv_now(uv_default_loop());
while (uv_now(uv_default_loop()) - start < 1000)
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT));
ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_NOWAIT));
MAKE_VALGRIND_HAPPY();
return 0;
@ -43,20 +43,26 @@ TEST_IMPL(loop_backend_timeout) {
uv_timer_t timer;
int r;
r = uv_timer_init(loop, &timer);
ASSERT(r == 0);
/* The default loop has some internal watchers to initialize. */
loop->active_handles++;
r = uv_run(loop, UV_RUN_NOWAIT);
ASSERT_EQ(r, 1);
loop->active_handles--;
ASSERT_EQ(uv_loop_alive(loop), 0);
ASSERT(!uv_loop_alive(loop));
ASSERT(uv_backend_timeout(loop) == 0);
r = uv_timer_init(loop, &timer);
ASSERT_EQ(r, 0);
ASSERT_EQ(uv_loop_alive(loop), 0);
ASSERT_EQ(uv_backend_timeout(loop), 0);
r = uv_timer_start(&timer, cb, 1000, 0); /* 1 sec */
ASSERT(r == 0);
ASSERT(uv_backend_timeout(loop) > 100); /* 0.1 sec */
ASSERT(uv_backend_timeout(loop) <= 1000); /* 1 sec */
ASSERT_EQ(r, 0);
ASSERT_EQ(uv_backend_timeout(loop), 1000);
r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(uv_backend_timeout(loop) == 0);
ASSERT_EQ(r, 0);
ASSERT_EQ(uv_backend_timeout(loop), 0);
MAKE_VALGRIND_HAPPY();
return 0;

View File

@ -46,11 +46,7 @@ static void thread_main(void* arg) {
uv_fs_req_cleanup(&req);
} while (n > 0 || (n == -1 && uv_errno == UV_EINTR));
#ifdef _WIN32
ASSERT(n == UV_EOF);
#else
ASSERT(n == 0);
#endif
}

View File

@ -41,6 +41,7 @@ TEST_IMPL(platform_output) {
uv_interface_address_t* interfaces;
uv_passwd_t pwd;
uv_utsname_t uname;
unsigned par;
int count;
int i;
int err;
@ -88,6 +89,10 @@ TEST_IMPL(platform_output) {
printf(" maximum resident set size: %llu\n",
(unsigned long long) rusage.ru_maxrss);
par = uv_available_parallelism();
ASSERT_GE(par, 1);
printf("uv_available_parallelism: %u\n", par);
err = uv_cpu_info(&cpus, &count);
#if defined(__CYGWIN__) || defined(__MSYS__)
ASSERT(err == UV_ENOSYS);

View File

@ -1891,6 +1891,44 @@ TEST_IMPL(spawn_quoted_path) {
#endif
}
TEST_IMPL(spawn_exercise_sigchld_issue) {
int r;
int i;
uv_process_options_t dummy_options = {0};
uv_process_t dummy_processes[100];
char* args[2];
init_process_options("spawn_helper1", exit_cb);
r = uv_spawn(uv_default_loop(), &process, &options);
ASSERT_EQ(r, 0);
// This test exercises a bug in the darwin kernel that causes SIGCHLD not to
// be delivered sometimes. Calling posix_spawn many times increases the
// likelihood of encountering this issue, so spin a few times to make this
// test more reliable.
dummy_options.file = args[0] = "program-that-had-better-not-exist";
args[1] = NULL;
dummy_options.args = args;
dummy_options.exit_cb = fail_cb;
dummy_options.flags = 0;
for (i = 0; i < 100; i++) {
r = uv_spawn(uv_default_loop(), &dummy_processes[i], &dummy_options);
if (r != UV_ENOENT)
ASSERT_EQ(r, UV_EACCES);
uv_close((uv_handle_t*) &dummy_processes[i], close_cb);
}
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT_EQ(r, 0);
ASSERT_EQ(exit_cb_called, 1);
ASSERT_EQ(close_cb_called, 101);
MAKE_VALGRIND_HAPPY();
return 0;
}
/* Helper for child process of spawn_inherit_streams */
#ifndef _WIN32
void spawn_stdin_stdout(void) {

View File

@ -273,6 +273,11 @@ TEST_IMPL(thread_stack_size_explicit) {
thread_check_stack, &options));
ASSERT(0 == uv_thread_join(&thread));
options.stack_size = 42;
ASSERT(0 == uv_thread_create_ex(&thread, &options,
thread_check_stack, &options));
ASSERT(0 == uv_thread_join(&thread));
#ifdef PTHREAD_STACK_MIN
options.stack_size = PTHREAD_STACK_MIN - 42; /* unaligned size */
ASSERT(0 == uv_thread_create_ex(&thread, &options,

View File

@ -29,14 +29,15 @@
#define CHECK_HANDLE(handle) \
ASSERT((uv_udp_t*)(handle) == &recver || (uv_udp_t*)(handle) == &sender)
#define BUFFER_MULTIPLIER 4
#define BUFFER_MULTIPLIER 20
#define MAX_DGRAM_SIZE (64 * 1024)
#define NUM_SENDS 8
#define NUM_SENDS 40
#define EXPECTED_MMSG_ALLOCS (NUM_SENDS / BUFFER_MULTIPLIER)
static uv_udp_t recver;
static uv_udp_t sender;
static int recv_cb_called;
static int received_datagrams;
static int close_cb_called;
static int alloc_cb_called;
@ -68,10 +69,10 @@ static void close_cb(uv_handle_t* handle) {
static void recv_cb(uv_udp_t* handle,
ssize_t nread,
const uv_buf_t* rcvbuf,
const struct sockaddr* addr,
unsigned flags) {
ssize_t nread,
const uv_buf_t* rcvbuf,
const struct sockaddr* addr,
unsigned flags) {
ASSERT_GE(nread, 0);
/* free and return if this is a mmsg free-only callback invocation */
@ -82,14 +83,20 @@ static void recv_cb(uv_udp_t* handle,
return;
}
ASSERT_EQ(nread, 4);
ASSERT_NOT_NULL(addr);
ASSERT_MEM_EQ("PING", rcvbuf->base, nread);
if (nread == 0) {
/* There can be no more available data for the time being. */
ASSERT_NULL(addr);
} else {
ASSERT_EQ(nread, 4);
ASSERT_NOT_NULL(addr);
ASSERT_MEM_EQ("PING", rcvbuf->base, nread);
received_datagrams++;
}
recv_cb_called++;
if (recv_cb_called == NUM_SENDS) {
uv_close((uv_handle_t*)handle, close_cb);
uv_close((uv_handle_t*)&sender, close_cb);
if (received_datagrams == NUM_SENDS) {
uv_close((uv_handle_t*) handle, close_cb);
uv_close((uv_handle_t*) &sender, close_cb);
}
/* Don't free if the buffer could be reused via mmsg */
@ -124,7 +131,7 @@ TEST_IMPL(udp_mmsg) {
ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT));
ASSERT_EQ(close_cb_called, 2);
ASSERT_EQ(recv_cb_called, NUM_SENDS);
ASSERT_EQ(received_datagrams, NUM_SENDS);
ASSERT_EQ(sender.send_queue_size, 0);
ASSERT_EQ(recver.send_queue_size, 0);