mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-06 14:19:59 -05:00
libuv 2017-05-25 (dc596109)
Code extracted from:
https://github.com/libuv/libuv.git
at commit dc596109d5a22db1dbf57098630eebd30fce8068 (v1.x).
This commit is contained in:
committed by
Brad King
parent
12a78bc824
commit
362435f02a
@@ -0,0 +1,31 @@
|
||||
/* Copyright libuv project 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.
|
||||
*/
|
||||
|
||||
#ifndef UV_POSIX_H
|
||||
#define UV_POSIX_H
|
||||
|
||||
#define UV_PLATFORM_LOOP_FIELDS \
|
||||
struct pollfd* poll_fds; \
|
||||
size_t poll_fds_used; \
|
||||
size_t poll_fds_size; \
|
||||
unsigned char poll_fds_iterating; \
|
||||
|
||||
#endif /* UV_POSIX_H */
|
||||
@@ -60,6 +60,8 @@
|
||||
defined(__OpenBSD__) || \
|
||||
defined(__NetBSD__)
|
||||
# include "uv-bsd.h"
|
||||
#elif defined(__CYGWIN__) || defined(__MSYS__)
|
||||
# include "uv-posix.h"
|
||||
#endif
|
||||
|
||||
#ifndef PTHREAD_BARRIER_SERIAL_THREAD
|
||||
|
||||
@@ -1078,6 +1078,8 @@ UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size);
|
||||
UV_EXTERN int uv_os_setenv(const char* name, const char* value);
|
||||
UV_EXTERN int uv_os_unsetenv(const char* name);
|
||||
|
||||
UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size);
|
||||
|
||||
|
||||
typedef enum {
|
||||
UV_FS_UNKNOWN = -1,
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#if !defined(__CYGWIN__) && !defined(__MSYS__)
|
||||
#include <net/if_dl.h>
|
||||
#endif
|
||||
|
||||
static int uv__ifaddr_exclude(struct ifaddrs *ent) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
||||
@@ -107,9 +109,13 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
|
||||
for (i = 0; i < *count; i++) {
|
||||
if (strcmp(address->name, ent->ifa_name) == 0) {
|
||||
#if defined(__CYGWIN__) || defined(__MSYS__)
|
||||
memset(address->phys_addr, 0, sizeof(address->phys_addr));
|
||||
#else
|
||||
struct sockaddr_dl* sa_addr;
|
||||
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
|
||||
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
|
||||
#endif
|
||||
}
|
||||
address++;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h> /* MAXHOSTNAMELEN on Linux and the BSDs */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@@ -42,6 +43,7 @@
|
||||
#include <pwd.h>
|
||||
|
||||
#ifdef __sun
|
||||
# include <netdb.h> /* MAXHOSTNAMELEN on Solaris */
|
||||
# include <sys/filio.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/wait.h>
|
||||
@@ -80,6 +82,11 @@
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
/* Fallback for the maximum hostname length */
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
# define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
static int uv__run_pending(uv_loop_t* loop);
|
||||
|
||||
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
|
||||
@@ -538,6 +545,7 @@ int uv__nonblock_ioctl(int fd, int set) {
|
||||
}
|
||||
|
||||
|
||||
#if !defined(__CYGWIN__) && !defined(__MSYS__)
|
||||
int uv__cloexec_ioctl(int fd, int set) {
|
||||
int r;
|
||||
|
||||
@@ -550,6 +558,7 @@ int uv__cloexec_ioctl(int fd, int set) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int uv__nonblock_fcntl(int fd, int set) {
|
||||
@@ -1285,3 +1294,33 @@ int uv_os_unsetenv(const char* name) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_os_gethostname(char* buffer, size_t* size) {
|
||||
/*
|
||||
On some platforms, if the input buffer is not large enough, gethostname()
|
||||
succeeds, but truncates the result. libuv can detect this and return ENOBUFS
|
||||
instead by creating a large enough buffer and comparing the hostname length
|
||||
to the size input.
|
||||
*/
|
||||
char buf[MAXHOSTNAMELEN + 1];
|
||||
size_t len;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (gethostname(buf, sizeof(buf)) != 0)
|
||||
return -errno;
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
|
||||
len = strlen(buf);
|
||||
|
||||
if (len >= *size) {
|
||||
*size = len + 1;
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
memcpy(buffer, buf, len + 1);
|
||||
*size = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/* Copyright libuv project 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 "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <sys/sysinfo.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int uv_uptime(double* uptime) {
|
||||
struct sysinfo info;
|
||||
|
||||
if (sysinfo(&info) < 0)
|
||||
return -errno;
|
||||
|
||||
*uptime = info.uptime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_resident_set_memory(size_t* rss) {
|
||||
/* FIXME: read /proc/meminfo? */
|
||||
*rss = 0;
|
||||
return UV_ENOSYS;
|
||||
}
|
||||
|
||||
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
||||
/* FIXME: read /proc/stat? */
|
||||
*cpu_infos = NULL;
|
||||
*count = 0;
|
||||
return UV_ENOSYS;
|
||||
}
|
||||
|
||||
void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
||||
(void)cpu_infos;
|
||||
(void)count;
|
||||
}
|
||||
@@ -378,9 +378,6 @@ static void uv__fsevents_destroy_stream(uv_loop_t* loop) {
|
||||
if (state->fsevent_stream == NULL)
|
||||
return;
|
||||
|
||||
/* Flush all accumulated events */
|
||||
pFSEventStreamFlushSync(state->fsevent_stream);
|
||||
|
||||
/* Stop emitting events */
|
||||
pFSEventStreamStop(state->fsevent_stream);
|
||||
|
||||
|
||||
@@ -472,55 +472,6 @@ uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
}
|
||||
|
||||
|
||||
void uv_loadavg(double avg[3]) {
|
||||
struct sysinfo info;
|
||||
|
||||
if (sysinfo(&info) < 0) return;
|
||||
|
||||
avg[0] = (double) info.loads[0] / 65536.0;
|
||||
avg[1] = (double) info.loads[1] / 65536.0;
|
||||
avg[2] = (double) info.loads[2] / 65536.0;
|
||||
}
|
||||
|
||||
|
||||
int uv_exepath(char* buffer, size_t* size) {
|
||||
ssize_t n;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
n = *size - 1;
|
||||
if (n > 0)
|
||||
n = readlink("/proc/self/exe", buffer, n);
|
||||
|
||||
if (n == -1)
|
||||
return -errno;
|
||||
|
||||
buffer[n] = '\0';
|
||||
*size = n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_free_memory(void) {
|
||||
struct sysinfo info;
|
||||
|
||||
if (sysinfo(&info) == 0)
|
||||
return (uint64_t) info.freeram * info.mem_unit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_total_memory(void) {
|
||||
struct sysinfo info;
|
||||
|
||||
if (sysinfo(&info) == 0)
|
||||
return (uint64_t) info.totalram * info.mem_unit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_resident_set_memory(size_t* rss) {
|
||||
char buf[1024];
|
||||
const char* s;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/* Copyright libuv project 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 "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb,
|
||||
const char* filename, unsigned int flags) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
int uv_fs_event_stop(uv_fs_event_t* handle) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
void uv__fs_event_close(uv_fs_event_t* handle) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/* Copyright libuv project 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 "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
char** uv_setup_args(int argc, char** argv) {
|
||||
return argv;
|
||||
}
|
||||
|
||||
int uv_set_process_title(const char* title) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_get_process_title(char* buffer, size_t size) {
|
||||
if (buffer == NULL || size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
buffer[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
@@ -30,7 +30,6 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <kvm.h>
|
||||
#include <paths.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -663,28 +663,6 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__fs_event_close(uv_fs_event_t* handle) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb,
|
||||
const char* filename, unsigned int flags) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_event_stop(uv_fs_event_t* handle) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
|
||||
void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
static const int max_safe_timeout = 1789569;
|
||||
struct epoll_event events[1024];
|
||||
|
||||
@@ -181,6 +181,14 @@ void uv_pipe_connect(uv_connect_t* req,
|
||||
|
||||
if (r == -1 && errno != EINPROGRESS) {
|
||||
err = -errno;
|
||||
#if defined(__CYGWIN__) || defined(__MSYS__)
|
||||
/* EBADF is supposed to mean that the socket fd is bad, but
|
||||
Cygwin reports EBADF instead of ENOTSOCK when the file is
|
||||
not a socket. We do not expect to see a bad fd here
|
||||
(e.g. due to new_sock), so translate the error. */
|
||||
if (err == -EBADF)
|
||||
err = -ENOTSOCK;
|
||||
#endif
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
/* Copyright libuv project 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 "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
/* POSIX defines poll() as a portable way to wait on file descriptors.
|
||||
* Here we maintain a dynamically sized array of file descriptors and
|
||||
* events to pass as the first argument to poll().
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop) {
|
||||
loop->poll_fds = NULL;
|
||||
loop->poll_fds_used = 0;
|
||||
loop->poll_fds_size = 0;
|
||||
loop->poll_fds_iterating = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
uv__free(loop->poll_fds);
|
||||
loop->poll_fds = NULL;
|
||||
}
|
||||
|
||||
int uv__io_fork(uv_loop_t* loop) {
|
||||
uv__platform_loop_delete(loop);
|
||||
return uv__platform_loop_init(loop);
|
||||
}
|
||||
|
||||
/* Allocate or dynamically resize our poll fds array. */
|
||||
static void uv__pollfds_maybe_resize(uv_loop_t* loop) {
|
||||
size_t i;
|
||||
size_t n;
|
||||
struct pollfd* p;
|
||||
|
||||
if (loop->poll_fds_used < loop->poll_fds_size)
|
||||
return;
|
||||
|
||||
n = loop->poll_fds_size ? loop->poll_fds_size * 2 : 64;
|
||||
p = uv__realloc(loop->poll_fds, n * sizeof(*loop->poll_fds));
|
||||
if (p == NULL)
|
||||
abort();
|
||||
|
||||
loop->poll_fds = p;
|
||||
for (i = loop->poll_fds_size; i < n; i++) {
|
||||
loop->poll_fds[i].fd = -1;
|
||||
loop->poll_fds[i].events = 0;
|
||||
loop->poll_fds[i].revents = 0;
|
||||
}
|
||||
loop->poll_fds_size = n;
|
||||
}
|
||||
|
||||
/* Primitive swap operation on poll fds array elements. */
|
||||
static void uv__pollfds_swap(uv_loop_t* loop, size_t l, size_t r) {
|
||||
struct pollfd pfd;
|
||||
pfd = loop->poll_fds[l];
|
||||
loop->poll_fds[l] = loop->poll_fds[r];
|
||||
loop->poll_fds[r] = pfd;
|
||||
}
|
||||
|
||||
/* Add a watcher's fd to our poll fds array with its pending events. */
|
||||
static void uv__pollfds_add(uv_loop_t* loop, uv__io_t* w) {
|
||||
size_t i;
|
||||
struct pollfd* pe;
|
||||
|
||||
/* If the fd is already in the set just update its events. */
|
||||
assert(!loop->poll_fds_iterating);
|
||||
for (i = 0; i < loop->poll_fds_used; ++i) {
|
||||
if (loop->poll_fds[i].fd == w->fd) {
|
||||
loop->poll_fds[i].events = w->pevents;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, allocate a new slot in the set for the fd. */
|
||||
uv__pollfds_maybe_resize(loop);
|
||||
pe = &loop->poll_fds[loop->poll_fds_used++];
|
||||
pe->fd = w->fd;
|
||||
pe->events = w->pevents;
|
||||
}
|
||||
|
||||
/* Remove a watcher's fd from our poll fds array. */
|
||||
static void uv__pollfds_del(uv_loop_t* loop, int fd) {
|
||||
size_t i;
|
||||
assert(!loop->poll_fds_iterating);
|
||||
for (i = 0; i < loop->poll_fds_used; ++i) {
|
||||
if (loop->poll_fds[i].fd == fd) {
|
||||
/* swap to last position and remove */
|
||||
--loop->poll_fds_used;
|
||||
uv__pollfds_swap(loop, i, loop->poll_fds_used);
|
||||
loop->poll_fds[loop->poll_fds_used].fd = -1;
|
||||
loop->poll_fds[loop->poll_fds_used].events = 0;
|
||||
loop->poll_fds[loop->poll_fds_used].revents = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
sigset_t* pset;
|
||||
sigset_t set;
|
||||
uint64_t time_base;
|
||||
uint64_t time_diff;
|
||||
QUEUE* q;
|
||||
uv__io_t* w;
|
||||
size_t i;
|
||||
unsigned int nevents;
|
||||
int nfds;
|
||||
int have_signals;
|
||||
struct pollfd* pe;
|
||||
int fd;
|
||||
|
||||
if (loop->nfds == 0) {
|
||||
assert(QUEUE_EMPTY(&loop->watcher_queue));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Take queued watchers and add their fds to our poll fds array. */
|
||||
while (!QUEUE_EMPTY(&loop->watcher_queue)) {
|
||||
q = QUEUE_HEAD(&loop->watcher_queue);
|
||||
QUEUE_REMOVE(q);
|
||||
QUEUE_INIT(q);
|
||||
|
||||
w = QUEUE_DATA(q, uv__io_t, watcher_queue);
|
||||
assert(w->pevents != 0);
|
||||
assert(w->fd >= 0);
|
||||
assert(w->fd < (int) loop->nwatchers);
|
||||
|
||||
uv__pollfds_add(loop, w);
|
||||
|
||||
w->events = w->pevents;
|
||||
}
|
||||
|
||||
/* Prepare a set of signals to block around poll(), if any. */
|
||||
pset = NULL;
|
||||
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
|
||||
pset = &set;
|
||||
sigemptyset(pset);
|
||||
sigaddset(pset, SIGPROF);
|
||||
}
|
||||
|
||||
assert(timeout >= -1);
|
||||
time_base = loop->time;
|
||||
|
||||
/* Loop calls to poll() and processing of results. If we get some
|
||||
* results from poll() but they turn out not to be interesting to
|
||||
* our caller then we need to loop around and poll() again.
|
||||
*/
|
||||
for (;;) {
|
||||
if (pset != NULL)
|
||||
if (pthread_sigmask(SIG_BLOCK, pset, NULL))
|
||||
abort();
|
||||
nfds = poll(loop->poll_fds, (nfds_t)loop->poll_fds_used, timeout);
|
||||
if (pset != NULL)
|
||||
if (pthread_sigmask(SIG_UNBLOCK, pset, NULL))
|
||||
abort();
|
||||
|
||||
/* Update loop->time unconditionally. It's tempting to skip the update when
|
||||
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
|
||||
* operating system didn't reschedule our process while in the syscall.
|
||||
*/
|
||||
SAVE_ERRNO(uv__update_time(loop));
|
||||
|
||||
if (nfds == 0) {
|
||||
assert(timeout != -1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nfds == -1) {
|
||||
if (errno != EINTR)
|
||||
abort();
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
/* Interrupted by a signal. Update timeout and poll again. */
|
||||
goto update_timeout;
|
||||
}
|
||||
|
||||
/* Tell uv__platform_invalidate_fd not to manipulate our array
|
||||
* while we are iterating over it.
|
||||
*/
|
||||
loop->poll_fds_iterating = 1;
|
||||
|
||||
/* Initialize a count of events that we care about. */
|
||||
nevents = 0;
|
||||
have_signals = 0;
|
||||
|
||||
/* Loop over the entire poll fds array looking for returned events. */
|
||||
for (i = 0; i < loop->poll_fds_used; i++) {
|
||||
pe = loop->poll_fds + i;
|
||||
fd = pe->fd;
|
||||
|
||||
/* Skip invalidated events, see uv__platform_invalidate_fd. */
|
||||
if (fd == -1)
|
||||
continue;
|
||||
|
||||
assert(fd >= 0);
|
||||
assert((unsigned) fd < loop->nwatchers);
|
||||
|
||||
w = loop->watchers[fd];
|
||||
|
||||
if (w == NULL) {
|
||||
/* File descriptor that we've stopped watching, ignore. */
|
||||
uv__platform_invalidate_fd(loop, fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Filter out events that user has not requested us to watch
|
||||
* (e.g. POLLNVAL).
|
||||
*/
|
||||
pe->revents &= w->pevents | POLLERR | POLLHUP;
|
||||
|
||||
if (pe->revents != 0) {
|
||||
/* Run signal watchers last. */
|
||||
if (w == &loop->signal_io_watcher) {
|
||||
have_signals = 1;
|
||||
} else {
|
||||
w->cb(loop, w, pe->revents);
|
||||
}
|
||||
|
||||
nevents++;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_signals != 0)
|
||||
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
||||
|
||||
loop->poll_fds_iterating = 0;
|
||||
|
||||
/* Purge invalidated fds from our poll fds array. */
|
||||
uv__pollfds_del(loop, -1);
|
||||
|
||||
if (have_signals != 0)
|
||||
return; /* Event loop should cycle now so don't poll again. */
|
||||
|
||||
if (nevents != 0)
|
||||
return;
|
||||
|
||||
if (timeout == 0)
|
||||
return;
|
||||
|
||||
if (timeout == -1)
|
||||
continue;
|
||||
|
||||
update_timeout:
|
||||
assert(timeout > 0);
|
||||
|
||||
time_diff = loop->time - time_base;
|
||||
if (time_diff >= (uint64_t) timeout)
|
||||
return;
|
||||
|
||||
timeout -= time_diff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the given fd from our poll fds array because no one
|
||||
* is interested in its events anymore.
|
||||
*/
|
||||
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
|
||||
size_t i;
|
||||
|
||||
if (loop->poll_fds_iterating) {
|
||||
/* uv__io_poll is currently iterating. Just invalidate fd. */
|
||||
for (i = 0; i < loop->poll_fds_used; i++)
|
||||
if (loop->poll_fds[i].fd == fd) {
|
||||
loop->poll_fds[i].fd = -1;
|
||||
loop->poll_fds[i].events = 0;
|
||||
loop->poll_fds[i].revents = 0;
|
||||
}
|
||||
} else {
|
||||
/* uv__io_poll is not iterating. Delete fd from the set. */
|
||||
uv__pollfds_del(loop, fd);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether the given fd is supported by poll(). */
|
||||
int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
||||
struct pollfd p[1];
|
||||
int rv;
|
||||
|
||||
p[0].fd = fd;
|
||||
p[0].events = POLLIN;
|
||||
|
||||
do
|
||||
rv = poll(p, 1, 0);
|
||||
while (rv == -1 && (errno == EINTR || errno == EAGAIN));
|
||||
|
||||
if (rv == -1)
|
||||
return -errno;
|
||||
|
||||
if (p[0].revents & POLLNVAL)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Copyright libuv project 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 "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int uv_exepath(char* buffer, size_t* size) {
|
||||
ssize_t n;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
n = *size - 1;
|
||||
if (n > 0)
|
||||
n = readlink("/proc/self/exe", buffer, n);
|
||||
|
||||
if (n == -1)
|
||||
return -errno;
|
||||
|
||||
buffer[n] = '\0';
|
||||
*size = n;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+13
-2
@@ -390,7 +390,7 @@ failed_malloc:
|
||||
|
||||
|
||||
int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
|
||||
#if defined(__APPLE__) || defined(__MVS__)
|
||||
#if defined(__APPLE__)
|
||||
int enable;
|
||||
#endif
|
||||
|
||||
@@ -409,7 +409,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__) || defined(__MVS__)
|
||||
#if defined(__APPLE__)
|
||||
enable = 1;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) &&
|
||||
errno != ENOTSOCK &&
|
||||
@@ -1173,6 +1173,11 @@ static void uv__read(uv_stream_t* stream) {
|
||||
uv__stream_osx_interrupt_select(stream);
|
||||
}
|
||||
stream->read_cb(stream, 0, &buf);
|
||||
#if defined(__CYGWIN__) || defined(__MSYS__)
|
||||
} else if (errno == ECONNRESET && stream->type == UV_NAMED_PIPE) {
|
||||
uv__stream_eof(stream, &buf);
|
||||
return;
|
||||
#endif
|
||||
} else {
|
||||
/* Error. User should call uv_close(). */
|
||||
stream->read_cb(stream, -errno, &buf);
|
||||
@@ -1405,6 +1410,12 @@ int uv_write2(uv_write_t* req,
|
||||
*/
|
||||
if (uv__handle_fd((uv_handle_t*) send_handle) < 0)
|
||||
return -EBADF;
|
||||
|
||||
#if defined(__CYGWIN__) || defined(__MSYS__)
|
||||
/* Cygwin recvmsg always sets msg_controllen to zero, so we cannot send it.
|
||||
See https://github.com/mirror/newlib-cygwin/blob/86fc4bf0/winsup/cygwin/fhandler_socket.cc#L1736-L1743 */
|
||||
return -ENOSYS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* It's legal for write_queue_size > 0 even when the write_queue is empty;
|
||||
|
||||
@@ -545,25 +545,6 @@ void uv__fs_event_close(uv_fs_event_t* handle) {
|
||||
#endif /* defined(PORT_SOURCE_FILE) */
|
||||
|
||||
|
||||
char** uv_setup_args(int argc, char** argv) {
|
||||
return argv;
|
||||
}
|
||||
|
||||
|
||||
int uv_set_process_title(const char* title) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_get_process_title(char* buffer, size_t size) {
|
||||
if (buffer == NULL || size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
buffer[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_resident_set_memory(size_t* rss) {
|
||||
psinfo_t psinfo;
|
||||
int err;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/* Copyright libuv project 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 "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
void uv_loadavg(double avg[3]) {
|
||||
struct sysinfo info;
|
||||
|
||||
if (sysinfo(&info) < 0) return;
|
||||
|
||||
avg[0] = (double) info.loads[0] / 65536.0;
|
||||
avg[1] = (double) info.loads[1] / 65536.0;
|
||||
avg[2] = (double) info.loads[2] / 65536.0;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/* Copyright libuv project 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 "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
uint64_t uv_get_free_memory(void) {
|
||||
struct sysinfo info;
|
||||
|
||||
if (sysinfo(&info) == 0)
|
||||
return (uint64_t) info.freeram * info.mem_unit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t uv_get_total_memory(void) {
|
||||
struct sysinfo info;
|
||||
|
||||
if (sysinfo(&info) == 0)
|
||||
return (uint64_t) info.totalram * info.mem_unit;
|
||||
return 0;
|
||||
}
|
||||
@@ -59,6 +59,14 @@
|
||||
# define UNLEN 256
|
||||
#endif
|
||||
|
||||
/*
|
||||
Max hostname length. The Windows gethostname() documentation states that 256
|
||||
bytes will always be large enough to hold the null-terminated hostname.
|
||||
*/
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
# define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
/* Maximum environment variable size, including the terminating null */
|
||||
#define MAX_ENV_VAR_LENGTH 32767
|
||||
|
||||
@@ -1540,3 +1548,29 @@ int uv_os_unsetenv(const char* name) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_os_gethostname(char* buffer, size_t* size) {
|
||||
char buf[MAXHOSTNAMELEN + 1];
|
||||
size_t len;
|
||||
|
||||
if (buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
uv__once_init(); /* Initialize winsock */
|
||||
|
||||
if (gethostname(buf, sizeof(buf)) != 0)
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
|
||||
len = strlen(buf);
|
||||
|
||||
if (len >= *size) {
|
||||
*size = len + 1;
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
|
||||
memcpy(buffer, buf, len + 1);
|
||||
*size = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user