forked from cory/tildefriends
libuv 1.44.2
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3934 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
110
deps/libuv/src/unix/core.c
vendored
110
deps/libuv/src/unix/core.c
vendored
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
#include "strtok.h"
|
||||
|
||||
#include <stddef.h> /* NULL */
|
||||
#include <stdio.h> /* printf */
|
||||
@@ -80,7 +81,8 @@ extern char** environ;
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
#include <sys/ioctl.h>
|
||||
# include <sys/ioctl.h>
|
||||
# include "zos-sys-info.h"
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
@@ -93,7 +95,7 @@ extern char** environ;
|
||||
# include <sanitizer/linux_syscall_hooks.h>
|
||||
#endif
|
||||
|
||||
static int uv__run_pending(uv_loop_t* loop);
|
||||
static void uv__run_pending(uv_loop_t* loop);
|
||||
|
||||
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
|
||||
STATIC_ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec));
|
||||
@@ -159,6 +161,15 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
|
||||
|
||||
case UV_FS_EVENT:
|
||||
uv__fs_event_close((uv_fs_event_t*)handle);
|
||||
#if defined(__sun) || defined(__MVS__)
|
||||
/*
|
||||
* On Solaris, illumos, and z/OS we will not be able to dissociate the
|
||||
* watcher for an event which is pending delivery, so we cannot always call
|
||||
* uv__make_close_pending() straight away. The backend will call the
|
||||
* function once the event has cleared.
|
||||
*/
|
||||
return;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case UV_POLL:
|
||||
@@ -371,7 +382,7 @@ int uv_loop_alive(const uv_loop_t* loop) {
|
||||
int uv_run(uv_loop_t* loop, uv_run_mode mode) {
|
||||
int timeout;
|
||||
int r;
|
||||
int ran_pending;
|
||||
int can_sleep;
|
||||
|
||||
r = uv__loop_alive(loop);
|
||||
if (!r)
|
||||
@@ -380,16 +391,25 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) {
|
||||
while (r != 0 && loop->stop_flag == 0) {
|
||||
uv__update_time(loop);
|
||||
uv__run_timers(loop);
|
||||
ran_pending = uv__run_pending(loop);
|
||||
|
||||
can_sleep =
|
||||
QUEUE_EMPTY(&loop->pending_queue) && QUEUE_EMPTY(&loop->idle_handles);
|
||||
|
||||
uv__run_pending(loop);
|
||||
uv__run_idle(loop);
|
||||
uv__run_prepare(loop);
|
||||
|
||||
timeout = 0;
|
||||
if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
|
||||
if ((mode == UV_RUN_ONCE && can_sleep) || mode == UV_RUN_DEFAULT)
|
||||
timeout = uv__backend_timeout(loop);
|
||||
|
||||
uv__io_poll(loop, timeout);
|
||||
|
||||
/* Process immediate callbacks (e.g. write_cb) a small fixed number of
|
||||
* times to avoid loop starvation.*/
|
||||
for (r = 0; r < 8 && !QUEUE_EMPTY(&loop->pending_queue); r++)
|
||||
uv__run_pending(loop);
|
||||
|
||||
/* Run one final update on the provider_idle_time in case uv__io_poll
|
||||
* returned because the timeout expired, but no events were received. This
|
||||
* call will be ignored if the provider_entry_time was either never set (if
|
||||
@@ -653,28 +673,23 @@ int uv__cloexec(int fd, int set) {
|
||||
|
||||
|
||||
ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
|
||||
struct cmsghdr* cmsg;
|
||||
#if defined(__ANDROID__) || \
|
||||
defined(__DragonFly__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__NetBSD__) || \
|
||||
defined(__OpenBSD__) || \
|
||||
defined(__linux__)
|
||||
ssize_t rc;
|
||||
rc = recvmsg(fd, msg, flags | MSG_CMSG_CLOEXEC);
|
||||
if (rc == -1)
|
||||
return UV__ERR(errno);
|
||||
return rc;
|
||||
#else
|
||||
struct cmsghdr* cmsg;
|
||||
int* pfd;
|
||||
int* end;
|
||||
#if defined(__linux__)
|
||||
static int no_msg_cmsg_cloexec;
|
||||
if (0 == uv__load_relaxed(&no_msg_cmsg_cloexec)) {
|
||||
rc = recvmsg(fd, msg, flags | 0x40000000); /* MSG_CMSG_CLOEXEC */
|
||||
if (rc != -1)
|
||||
return rc;
|
||||
if (errno != EINVAL)
|
||||
return UV__ERR(errno);
|
||||
rc = recvmsg(fd, msg, flags);
|
||||
if (rc == -1)
|
||||
return UV__ERR(errno);
|
||||
uv__store_relaxed(&no_msg_cmsg_cloexec, 1);
|
||||
} else {
|
||||
rc = recvmsg(fd, msg, flags);
|
||||
}
|
||||
#else
|
||||
ssize_t rc;
|
||||
rc = recvmsg(fd, msg, flags);
|
||||
#endif
|
||||
if (rc == -1)
|
||||
return UV__ERR(errno);
|
||||
if (msg->msg_controllen == 0)
|
||||
@@ -687,6 +702,7 @@ ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
|
||||
pfd += 1)
|
||||
uv__cloexec(*pfd, 1);
|
||||
return rc;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -779,14 +795,11 @@ int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__run_pending(uv_loop_t* loop) {
|
||||
static void uv__run_pending(uv_loop_t* loop) {
|
||||
QUEUE* q;
|
||||
QUEUE pq;
|
||||
uv__io_t* w;
|
||||
|
||||
if (QUEUE_EMPTY(&loop->pending_queue))
|
||||
return 0;
|
||||
|
||||
QUEUE_MOVE(&loop->pending_queue, &pq);
|
||||
|
||||
while (!QUEUE_EMPTY(&pq)) {
|
||||
@@ -796,8 +809,6 @@ static int uv__run_pending(uv_loop_t* loop) {
|
||||
w = QUEUE_DATA(q, uv__io_t, pending_queue);
|
||||
w->cb(loop, w, POLLOUT);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1162,24 +1173,17 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
|
||||
size_t name_size;
|
||||
size_t homedir_size;
|
||||
size_t shell_size;
|
||||
long initsize;
|
||||
int r;
|
||||
|
||||
if (pwd == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
initsize = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
|
||||
if (initsize <= 0)
|
||||
bufsize = 4096;
|
||||
else
|
||||
bufsize = (size_t) initsize;
|
||||
|
||||
uid = geteuid();
|
||||
buf = NULL;
|
||||
|
||||
for (;;) {
|
||||
uv__free(buf);
|
||||
/* Calling sysconf(_SC_GETPW_R_SIZE_MAX) would get the suggested size, but it
|
||||
* is frequently 1024 or 4096, so we can just use that directly. The pwent
|
||||
* will not usually be large. */
|
||||
for (bufsize = 2000;; bufsize *= 2) {
|
||||
buf = uv__malloc(bufsize);
|
||||
|
||||
if (buf == NULL)
|
||||
@@ -1189,21 +1193,18 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
|
||||
r = getpwuid_r(uid, &pw, buf, bufsize, &result);
|
||||
while (r == EINTR);
|
||||
|
||||
if (r != 0 || result == NULL)
|
||||
uv__free(buf);
|
||||
|
||||
if (r != ERANGE)
|
||||
break;
|
||||
|
||||
bufsize *= 2;
|
||||
}
|
||||
|
||||
if (r != 0) {
|
||||
uv__free(buf);
|
||||
if (r != 0)
|
||||
return UV__ERR(r);
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
uv__free(buf);
|
||||
if (result == NULL)
|
||||
return UV_ENOENT;
|
||||
}
|
||||
|
||||
/* Allocate memory for the username, shell, and home directory */
|
||||
name_size = strlen(pw.pw_name) + 1;
|
||||
@@ -1556,6 +1557,7 @@ int uv__search_path(const char* prog, char* buf, size_t* buflen) {
|
||||
char* cloned_path;
|
||||
char* path_env;
|
||||
char* token;
|
||||
char* itr;
|
||||
|
||||
if (buf == NULL || buflen == NULL || *buflen == 0)
|
||||
return UV_EINVAL;
|
||||
@@ -1597,7 +1599,7 @@ int uv__search_path(const char* prog, char* buf, size_t* buflen) {
|
||||
if (cloned_path == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
token = strtok(cloned_path, ":");
|
||||
token = uv__strtok(cloned_path, ":", &itr);
|
||||
while (token != NULL) {
|
||||
snprintf(trypath, sizeof(trypath) - 1, "%s/%s", token, prog);
|
||||
if (realpath(trypath, abspath) == abspath) {
|
||||
@@ -1616,7 +1618,7 @@ int uv__search_path(const char* prog, char* buf, size_t* buflen) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
token = strtok(NULL, ":");
|
||||
token = uv__strtok(NULL, ":", &itr);
|
||||
}
|
||||
uv__free(cloned_path);
|
||||
|
||||
@@ -1646,7 +1648,13 @@ unsigned int uv_available_parallelism(void) {
|
||||
|
||||
return (unsigned) rc;
|
||||
#elif defined(__MVS__)
|
||||
return 1; /* TODO(bnoordhuis) Read from CSD_NUMBER_ONLINE_CPUS? */
|
||||
int rc;
|
||||
|
||||
rc = __get_num_online_cpus();
|
||||
if (rc < 1)
|
||||
rc = 1;
|
||||
|
||||
return (unsigned) rc;
|
||||
#else /* __linux__ */
|
||||
long rc;
|
||||
|
||||
|
Reference in New Issue
Block a user