diff options
Diffstat (limited to 'deps/uv')
41 files changed, 1250 insertions, 795 deletions
diff --git a/deps/uv/config-unix.mk b/deps/uv/config-unix.mk index 64501832f4..2af3f3c4df 100644 --- a/deps/uv/config-unix.mk +++ b/deps/uv/config-unix.mk @@ -27,18 +27,24 @@ LINKFLAGS=-lm CPPFLAGS += -D_LARGEFILE_SOURCE CPPFLAGS += -D_FILE_OFFSET_BITS=64 +OBJS += src/unix/async.o +OBJS += src/unix/cares.o +OBJS += src/unix/check.o OBJS += src/unix/core.o OBJS += src/unix/dl.o -OBJS += src/unix/fs.o -OBJS += src/unix/cares.o -OBJS += src/unix/udp.o OBJS += src/unix/error.o -OBJS += src/unix/thread.o +OBJS += src/unix/fs.o +OBJS += src/unix/idle.o +OBJS += src/unix/loop.o +OBJS += src/unix/pipe.o +OBJS += src/unix/prepare.o OBJS += src/unix/process.o +OBJS += src/unix/stream.o OBJS += src/unix/tcp.o -OBJS += src/unix/pipe.o +OBJS += src/unix/thread.o +OBJS += src/unix/timer.o OBJS += src/unix/tty.o -OBJS += src/unix/stream.o +OBJS += src/unix/udp.o ifeq (SunOS,$(uname_S)) EV_CONFIG=config_sunos.h @@ -51,7 +57,7 @@ endif ifeq (Darwin,$(uname_S)) EV_CONFIG=config_darwin.h EIO_CONFIG=config_darwin.h -CPPFLAGS += -Isrc/ares/config_darwin +CPPFLAGS += -D_DARWIN_USE_64_BIT_INODE=1 -Isrc/ares/config_darwin LINKFLAGS+=-framework CoreServices OBJS += src/unix/darwin.o OBJS += src/unix/kqueue.o @@ -63,7 +69,7 @@ EIO_CONFIG=config_linux.h CSTDFLAG += -D_GNU_SOURCE CPPFLAGS += -Isrc/ares/config_linux LINKFLAGS+=-ldl -lrt -OBJS += src/unix/linux/core.o src/unix/linux/inotify.o +OBJS += src/unix/linux/core.o src/unix/linux/inotify.o src/unix/linux/syscalls.o endif ifeq (FreeBSD,$(uname_S)) diff --git a/deps/uv/include/uv-private/tree.h b/deps/uv/include/uv-private/tree.h index eb05cdcd14..f936416e3d 100644 --- a/deps/uv/include/uv-private/tree.h +++ b/deps/uv/include/uv-private/tree.h @@ -26,10 +26,12 @@ #ifndef UV_TREE_H_ #define UV_TREE_H_ -#if __GNUC__ -# define __unused __attribute__((unused)) -#else -# define __unused +#ifndef UV__UNUSED +# if __GNUC__ +# define UV__UNUSED __attribute__((unused)) +# else +# define UV__UNUSED +# endif #endif /* @@ -381,7 +383,7 @@ struct { \ #define RB_PROTOTYPE(name, type, field, cmp) \ RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) #define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ - RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static) + RB_PROTOTYPE_INTERNAL(name, type, field, cmp, UV__UNUSED static) #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ @@ -400,7 +402,7 @@ attr struct type *name##_RB_MINMAX(struct name *, int); \ #define RB_GENERATE(name, type, field, cmp) \ RB_GENERATE_INTERNAL(name, type, field, cmp,) #define RB_GENERATE_STATIC(name, type, field, cmp) \ - RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static) + RB_GENERATE_INTERNAL(name, type, field, cmp, UV__UNUSED static) #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ attr void \ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ diff --git a/deps/uv/include/uv-private/uv-unix.h b/deps/uv/include/uv-private/uv-unix.h index 798be5e0e7..0137c0c362 100644 --- a/deps/uv/include/uv-private/uv-unix.h +++ b/deps/uv/include/uv-private/uv-unix.h @@ -55,6 +55,9 @@ typedef pthread_rwlock_t uv_rwlock_t; typedef void* uv_lib_t; #define UV_DYNAMIC /* empty */ +#define UV_HANDLE_TYPE_PRIVATE /* empty */ +#define UV_REQ_TYPE_PRIVATE /* empty */ + #if __linux__ # define UV_LOOP_PRIVATE_PLATFORM_FIELDS \ /* RB_HEAD(uv__inotify_watchers, uv_fs_event_s) */ \ @@ -74,7 +77,7 @@ typedef void* uv_lib_t; * sure that we're always calling ares_process. See the warning above the \ * definition of ares_timeout(). \ */ \ - ev_timer timer; \ + uv_timer_t timer; \ /* Poll result queue */ \ eio_channel uv_eio_channel; \ struct ev_loop* ev; \ @@ -82,6 +85,7 @@ typedef void* uv_lib_t; uv_async_t uv_eio_want_poll_notifier; \ uv_async_t uv_eio_done_poll_notifier; \ uv_idle_t uv_eio_poller; \ + uv_handle_t* endgame_handles; \ UV_LOOP_PRIVATE_PLATFORM_FIELDS #define UV_REQ_BUFSML_SIZE (4) @@ -118,7 +122,7 @@ typedef void* uv_lib_t; #define UV_HANDLE_PRIVATE_FIELDS \ int fd; \ int flags; \ - ev_idle next_watcher; + uv_handle_t* endgame_next; /* that's what uv-win calls it */ \ #define UV_STREAM_PRIVATE_FIELDS \ @@ -182,11 +186,6 @@ typedef void* uv_lib_t; ev_timer timer_watcher; \ uv_timer_cb timer_cb; -#define UV_ARES_TASK_PRIVATE_FIELDS \ - int sock; \ - ev_io read_watcher; \ - ev_io write_watcher; - #define UV_GETADDRINFO_PRIVATE_FIELDS \ uv_getaddrinfo_cb cb; \ struct addrinfo* hints; \ @@ -223,7 +222,7 @@ typedef void* uv_lib_t; ev_io read_watcher; \ uv_fs_event_cb cb; -#elif (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060) \ +#elif defined(__APPLE__) \ || defined(__FreeBSD__) \ || defined(__OpenBSD__) \ || defined(__NetBSD__) diff --git a/deps/uv/include/uv-private/uv-win.h b/deps/uv/include/uv-private/uv-win.h index 812b274173..baeb3e3627 100644 --- a/deps/uv/include/uv-private/uv-win.h +++ b/deps/uv/include/uv-private/uv-win.h @@ -206,15 +206,21 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s); /* Counter to keep track of active udp streams */ \ unsigned int active_udp_streams; +#define UV_HANDLE_TYPE_PRIVATE \ + UV_ARES_EVENT, + #define UV_REQ_TYPE_PRIVATE \ /* TODO: remove the req suffix */ \ + UV_ACCEPT, \ UV_ARES_EVENT_REQ, \ UV_ARES_CLEANUP_REQ, \ + UV_FS_EVENT_REQ, \ UV_GETADDRINFO_REQ, \ UV_PROCESS_EXIT, \ UV_PROCESS_CLOSE, \ + UV_READ, \ UV_UDP_RECV, \ - UV_FS_EVENT_REQ + UV_WAKEUP, #define UV_REQ_PRIVATE_FIELDS \ union { \ @@ -390,13 +396,6 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s); uv_handle_t* endgame_next; \ unsigned int flags; -#define UV_ARES_TASK_PRIVATE_FIELDS \ - struct uv_req_s ares_req; \ - SOCKET sock; \ - HANDLE h_wait; \ - WSAEVENT h_event; \ - HANDLE h_close_event; - #define UV_GETADDRINFO_PRIVATE_FIELDS \ struct uv_req_s getadddrinfo_req; \ uv_getaddrinfo_cb getaddrinfo_cb; \ diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 16098845c2..0ede3083d3 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -132,37 +132,46 @@ typedef enum { } uv_err_code; #undef UV_ERRNO_GEN +#define UV_HANDLE_TYPE_MAP(XX) \ + XX(ARES_TASK, ares_task) \ + XX(ASYNC, async) \ + XX(CHECK, check) \ + XX(FS_EVENT, fs_event) \ + XX(IDLE, idle) \ + XX(NAMED_PIPE, pipe) \ + XX(PREPARE, prepare) \ + XX(PROCESS, process) \ + XX(TCP, tcp) \ + XX(TIMER, timer) \ + XX(TTY, tty) \ + XX(UDP, udp) \ + +#define UV_REQ_TYPE_MAP(XX) \ + XX(CONNECT, connect) \ + XX(WRITE, write) \ + XX(SHUTDOWN, shutdown) \ + XX(UDP_SEND, udp_send) \ + XX(FS, fs) \ + XX(WORK, work) \ + XX(GETADDRINFO, getaddrinfo) \ + typedef enum { UV_UNKNOWN_HANDLE = 0, - UV_TCP, - UV_UDP, - UV_NAMED_PIPE, - UV_TTY, +#define XX(uc, lc) UV_##uc, + UV_HANDLE_TYPE_MAP(XX) +#undef XX UV_FILE, - UV_TIMER, - UV_PREPARE, - UV_CHECK, - UV_IDLE, - UV_ASYNC, - UV_ARES_TASK, - UV_ARES_EVENT, - UV_PROCESS, - UV_FS_EVENT + UV_HANDLE_TYPE_PRIVATE + UV_HANDLE_TYPE_MAX } uv_handle_type; typedef enum { UV_UNKNOWN_REQ = 0, - UV_CONNECT, - UV_ACCEPT, - UV_READ, - UV_WRITE, - UV_SHUTDOWN, - UV_WAKEUP, - UV_UDP_SEND, - UV_FS, - UV_WORK, - UV_GETADDRINFO, +#define XX(uc, lc) UV_##uc, + UV_REQ_TYPE_MAP(XX) +#undef XX UV_REQ_TYPE_PRIVATE + UV_REQ_TYPE_MAX } uv_req_type; @@ -374,6 +383,18 @@ struct uv_handle_s { }; /* + * Returns size of various handle types, useful for FFI + * bindings to allocate correct memory without copying struct + * definitions + */ +UV_EXTERN size_t uv_handle_size(uv_handle_type type); + +/* + * Returns size of request types, useful for dynamic lookup with FFI + */ +UV_EXTERN size_t uv_req_size(uv_req_type type); + +/* * Returns 1 if the prepare/check/idle/timer handle has been started, 0 * otherwise. For other handle types this always returns 1. */ @@ -523,6 +544,16 @@ UV_EXTERN int uv_is_writable(uv_stream_t* handle); /* + * Used to determine whether a stream is closing or closed. + * + * N.B. is only valid between the initialization of the handle + * and the arrival of the close callback, and cannot be used + * to validate the handle. + */ +UV_EXTERN int uv_is_closing(uv_handle_t* handle); + + +/* * uv_tcp_t is a subclass of uv_stream_t * * Represents a TCP stream or TCP server. @@ -1501,6 +1532,7 @@ struct uv_loop_s { /* Don't export the private CPP symbols. */ +#undef UV_HANDLE_TYPE_PRIVATE #undef UV_REQ_TYPE_PRIVATE #undef UV_REQ_PRIVATE_FIELDS #undef UV_STREAM_PRIVATE_FIELDS diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c new file mode 100644 index 0000000000..638774c6f7 --- /dev/null +++ b/deps/uv/src/unix/async.c @@ -0,0 +1,58 @@ +/* Copyright Joyent, Inc. and other Node 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" + + +static void uv__async(EV_P_ ev_async* w, int revents) { + uv_async_t* async = container_of(w, uv_async_t, async_watcher); + + if (async->async_cb) { + async->async_cb(async, 0); + } +} + + +int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb) { + uv__handle_init(loop, (uv_handle_t*)async, UV_ASYNC); + loop->counters.async_init++; + + ev_async_init(&async->async_watcher, uv__async); + async->async_cb = async_cb; + + /* Note: This does not have symmetry with the other libev wrappers. */ + ev_async_start(loop->ev, &async->async_watcher); + ev_unref(loop->ev); + + return 0; +} + + +int uv_async_send(uv_async_t* async) { + ev_async_send(async->loop->ev, &async->async_watcher); + return 0; +} + + +void uv__async_close(uv_async_t* handle) { + ev_async_stop(handle->loop->ev, &handle->async_watcher); + ev_ref(handle->loop->ev); +} diff --git a/deps/uv/src/unix/cares.c b/deps/uv/src/unix/cares.c index 18cdefe376..03667fda39 100644 --- a/deps/uv/src/unix/cares.c +++ b/deps/uv/src/unix/cares.c @@ -31,17 +31,23 @@ * This is called once per second by loop->timer. It is used to * constantly callback into c-ares for possibly processing timeouts. */ -static void uv__ares_timeout(struct ev_loop* ev, struct ev_timer* watcher, - int revents) { - uv_loop_t* loop = ev_userdata(ev); +static void uv__ares_timeout(uv_timer_t* handle, int status) { + assert(!uv_ares_handles_empty(handle->loop)); + ares_process_fd(handle->loop->channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); +} + + +static void uv__ares_timer_start(uv_loop_t* loop) { + if (uv_is_active((uv_handle_t*)&loop->timer)) return; + uv_timer_start(&loop->timer, uv__ares_timeout, 1000, 1000); + uv_ref(loop); +} - assert(ev == loop->ev); - assert((uv_loop_t*)watcher->data == loop); - assert(watcher == &loop->timer); - assert(revents == EV_TIMER); - assert(!uv_ares_handles_empty(loop)); - ares_process_fd(loop->channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); +static void uv__ares_timer_stop(uv_loop_t* loop) { + if (!uv_is_active((uv_handle_t*)&loop->timer)) return; + uv_timer_stop(&loop->timer); + uv_unref(loop); } @@ -52,7 +58,7 @@ static void uv__ares_io(struct ev_loop* ev, struct ev_io* watcher, assert(ev == loop->ev); /* Reset the idle timer */ - ev_timer_again(ev, &loop->timer); + uv_timer_again(&loop->timer); /* Process DNS responses */ ares_process_fd(loop->channel, @@ -98,9 +104,9 @@ static void uv__ares_sockstate_cb(void* data, ares_socket_t sock, /* New socket */ /* If this is the first socket then start the timer. */ - if (!ev_is_active(&loop->timer)) { + if (!uv_is_active((uv_handle_t*)&loop->timer)) { assert(uv_ares_handles_empty(loop)); - ev_timer_again(loop->ev, &loop->timer); + uv__ares_timer_start(loop); } h = uv__ares_task_create(loop, sock); @@ -134,7 +140,7 @@ static void uv__ares_sockstate_cb(void* data, ares_socket_t sock, free(h); if (uv_ares_handles_empty(loop)) { - ev_timer_stop(loop->ev, &loop->timer); + uv__ares_timer_stop(loop); } } } @@ -169,7 +175,8 @@ int uv_ares_init_options(uv_loop_t* loop, ares_channel *channelptr, * Initialize the timeout timer. The timer won't be started until the * first socket is opened. */ - ev_timer_init(&loop->timer, uv__ares_timeout, 1., 1.); + uv_timer_init(loop, &loop->timer); + uv_unref(loop); loop->timer.data = loop; return rc; @@ -180,7 +187,7 @@ int uv_ares_init_options(uv_loop_t* loop, ares_channel *channelptr, void uv_ares_destroy(uv_loop_t* loop, ares_channel channel) { /* only allow destroy if did init */ if (loop->channel) { - ev_timer_stop(loop->ev, &loop->timer); + uv__ares_timer_stop(loop); ares_destroy(channel); loop->channel = NULL; } diff --git a/deps/uv/src/unix/check.c b/deps/uv/src/unix/check.c new file mode 100644 index 0000000000..a975210072 --- /dev/null +++ b/deps/uv/src/unix/check.c @@ -0,0 +1,80 @@ +/* Copyright Joyent, Inc. and other Node 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" + + +static void uv__check(EV_P_ ev_check* w, int revents) { + uv_check_t* check = container_of(w, uv_check_t, check_watcher); + + if (check->check_cb) { + check->check_cb(check, 0); + } +} + + +int uv_check_init(uv_loop_t* loop, uv_check_t* check) { + uv__handle_init(loop, (uv_handle_t*)check, UV_CHECK); + loop->counters.check_init++; + + ev_check_init(&check->check_watcher, uv__check); + check->check_cb = NULL; + + return 0; +} + + +int uv_check_start(uv_check_t* check, uv_check_cb cb) { + int was_active = ev_is_active(&check->check_watcher); + + check->check_cb = cb; + + ev_check_start(check->loop->ev, &check->check_watcher); + + if (!was_active) { + ev_unref(check->loop->ev); + } + + return 0; +} + + +int uv_check_stop(uv_check_t* check) { + int was_active = ev_is_active(&check->check_watcher); + + ev_check_stop(check->loop->ev, &check->check_watcher); + + if (was_active) { + ev_ref(check->loop->ev); + } + + return 0; +} + + +int uv__check_active(const uv_check_t* handle) { + return ev_is_active(&handle->check_watcher); +} + + +void uv__check_close(uv_check_t* handle) { + uv_check_stop(handle); +} diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index e4d481ae4d..5d5048ad3b 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -59,102 +59,78 @@ static uv_loop_t default_loop_struct; static uv_loop_t* default_loop_ptr; -void uv__next(EV_P_ ev_idle* watcher, int revents); static void uv__finish_close(uv_handle_t* handle); void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { - uv_async_t* async; - uv_stream_t* stream; - uv_process_t* process; - handle->close_cb = close_cb; switch (handle->type) { - case UV_NAMED_PIPE: - uv_pipe_cleanup((uv_pipe_t*)handle); - /* Fall through. */ - - case UV_TTY: - case UV_TCP: - stream = (uv_stream_t*)handle; - - uv_read_stop(stream); - ev_io_stop(stream->loop->ev, &stream->write_watcher); - - close(stream->fd); - stream->fd = -1; - - if (stream->accepted_fd >= 0) { - close(stream->accepted_fd); - stream->accepted_fd = -1; - } + case UV_NAMED_PIPE: + uv__pipe_close((uv_pipe_t*)handle); + break; - assert(!ev_is_active(&stream->read_watcher)); - assert(!ev_is_active(&stream->write_watcher)); - break; + case UV_TTY: + case UV_TCP: + uv__stream_close((uv_stream_t*)handle); + break; - case UV_UDP: - uv__udp_start_close((uv_udp_t*)handle); - break; + case UV_UDP: + uv__udp_close((uv_udp_t*)handle); + break; - case UV_PREPARE: - uv_prepare_stop((uv_prepare_t*) handle); - break; + case UV_PREPARE: + uv__prepare_close((uv_prepare_t*)handle); + break; - case UV_CHECK: - uv_check_stop((uv_check_t*) handle); - break; + case UV_CHECK: + uv__check_close((uv_check_t*)handle); + break; - case UV_IDLE: - uv_idle_stop((uv_idle_t*) handle); - break; + case UV_IDLE: + uv__idle_close((uv_idle_t*)handle); + break; - case UV_ASYNC: - async = (uv_async_t*)handle; - ev_async_stop(async->loop->ev, &async->async_watcher); - ev_ref(async->loop->ev); - break; + case UV_ASYNC: + uv__async_close((uv_async_t*)handle); + break; - case UV_TIMER: - uv_timer_stop((uv_timer_t*)handle); - break; + case UV_TIMER: + uv__timer_close((uv_timer_t*)handle); + break; - case UV_PROCESS: - process = (uv_process_t*)handle; - ev_child_stop(process->loop->ev, &process->child_watcher); - break; + case UV_PROCESS: + uv__process_close((uv_process_t*)handle); + break; - case UV_FS_EVENT: - uv__fs_event_destroy((uv_fs_event_t*)handle); - break; + case UV_FS_EVENT: + uv__fs_event_close((uv_fs_event_t*)handle); + break; - default: - assert(0); + default: + assert(0); } handle->flags |= UV_CLOSING; + handle->endgame_next = handle->loop->endgame_handles; + handle->loop->endgame_handles = handle; + uv_unref(handle->loop); +} + - /* This is used to call the on_close callback in the next loop. */ - ev_idle_start(handle->loop->ev, &handle->next_watcher); - ev_feed_event(handle->loop->ev, &handle->next_watcher, EV_IDLE); - assert(ev_is_pending(&handle->next_watcher)); +int uv_is_closing(uv_handle_t* handle) { + return handle->flags & (UV_CLOSING | UV_CLOSED); } -static int uv__loop_init(uv_loop_t* loop, - struct ev_loop *(ev_loop_new)(unsigned int flags)) { - memset(loop, 0, sizeof(*loop)); - RB_INIT(&loop->uv_ares_handles_); -#if HAVE_KQUEUE - loop->ev = ev_loop_new(EVBACKEND_KQUEUE); -#else - loop->ev = ev_loop_new(EVFLAG_AUTO); -#endif - ev_set_userdata(loop->ev, loop); - eio_channel_init(&loop->uv_eio_channel, loop); - uv__loop_platform_init(loop); - return 0; +uv_loop_t* uv_default_loop(void) { + if (default_loop_ptr) + return default_loop_ptr; + + if (uv__loop_init(&default_loop_struct, /* default_loop? */ 1)) + return NULL; + + return (default_loop_ptr = &default_loop_struct); } @@ -164,7 +140,7 @@ uv_loop_t* uv_loop_new(void) { if ((loop = malloc(sizeof(*loop))) == NULL) return NULL; - if (uv__loop_init(loop, ev_loop_new)) { + if (uv__loop_init(loop, /* default_loop? */ 0)) { free(loop); return NULL; } @@ -174,9 +150,7 @@ uv_loop_t* uv_loop_new(void) { void uv_loop_delete(uv_loop_t* loop) { - uv_ares_destroy(loop, loop->channel); - ev_loop_destroy(loop->ev); - uv__loop_platform_delete(loop); + uv__loop_delete(loop); #ifndef NDEBUG memset(loop, -1, sizeof *loop); #endif @@ -192,26 +166,25 @@ int uv_loop_refcount(const uv_loop_t* loop) { } -uv_loop_t* uv_default_loop(void) { - if (default_loop_ptr) - return default_loop_ptr; - - if (uv__loop_init(&default_loop_struct, ev_default_loop)) - return NULL; +void uv__run(uv_loop_t* loop) { + ev_run(loop->ev, EVRUN_ONCE); - default_loop_ptr = &default_loop_struct; - return default_loop_ptr; + while (loop->endgame_handles) + uv__finish_close(loop->endgame_handles); } int uv_run(uv_loop_t* loop) { - ev_run(loop->ev, 0); + do + uv__run(loop); + while (uv_loop_refcount(loop) > 0); + return 0; } int uv_run_once(uv_loop_t* loop) { - ev_run(loop->ev, EVRUN_ONCE); + uv__run(loop); return 0; } @@ -223,11 +196,8 @@ void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle, handle->loop = loop; handle->type = type; handle->flags = 0; - - ev_init(&handle->next_watcher, uv__next); - - /* Ref the loop until this handle is closed. See uv__finish_close. */ - ev_ref(loop->ev); + handle->endgame_next = NULL; + uv_ref(loop); /* unref'd in uv_close() */ } @@ -284,26 +254,12 @@ void uv__finish_close(uv_handle_t* handle) { break; } - ev_idle_stop(loop->ev, &handle->next_watcher); + + loop->endgame_handles = handle->endgame_next; if (handle->close_cb) { handle->close_cb(handle); } - - ev_unref(loop->ev); -} - - -void uv__next(EV_P_ ev_idle* w, int revents) { - uv_handle_t* handle = container_of(w, uv_handle_t, next_watcher); - - assert(revents == EV_IDLE); - - /* For now this function is only to handle the closing event, but we might - * put more stuff here later. - */ - assert(handle->flags & UV_CLOSING); - uv__finish_close(handle); } @@ -333,299 +289,22 @@ void uv__req_init(uv_loop_t* loop, uv_req_t* req) { } -static void uv__prepare(EV_P_ ev_prepare* w, int revents) { - uv_prepare_t* prepare = container_of(w, uv_prepare_t, prepare_watcher); - - if (prepare->prepare_cb) { - prepare->prepare_cb(prepare, 0); - } -} - - -int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare) { - uv__handle_init(loop, (uv_handle_t*)prepare, UV_PREPARE); - loop->counters.prepare_init++; - - ev_prepare_init(&prepare->prepare_watcher, uv__prepare); - prepare->prepare_cb = NULL; - - return 0; -} - - -int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb) { - int was_active = ev_is_active(&prepare->prepare_watcher); - - prepare->prepare_cb = cb; - - ev_prepare_start(prepare->loop->ev, &prepare->prepare_watcher); - - if (!was_active) { - ev_unref(prepare->loop->ev); - } - - return 0; -} - - -int uv_prepare_stop(uv_prepare_t* prepare) { - int was_active = ev_is_active(&prepare->prepare_watcher); - - ev_prepare_stop(prepare->loop->ev, &prepare->prepare_watcher); - - if (was_active) { - ev_ref(prepare->loop->ev); - } - return 0; -} - - - -static void uv__check(EV_P_ ev_check* w, int revents) { - uv_check_t* check = container_of(w, uv_check_t, check_watcher); - - if (check->check_cb) { - check->check_cb(check, 0); - } -} - - -int uv_check_init(uv_loop_t* loop, uv_check_t* check) { - uv__handle_init(loop, (uv_handle_t*)check, UV_CHECK); - loop->counters.check_init++; - - ev_check_init(&check->check_watcher, uv__check); - check->check_cb = NULL; - - return 0; -} - - -int uv_check_start(uv_check_t* check, uv_check_cb cb) { - int was_active = ev_is_active(&check->check_watcher); - - check->check_cb = cb; - - ev_check_start(check->loop->ev, &check->check_watcher); - - if (!was_active) { - ev_unref(check->loop->ev); - } - - return 0; -} - - -int uv_check_stop(uv_check_t* check) { - int was_active = ev_is_active(&check->check_watcher); - - ev_check_stop(check->loop->ev, &check->check_watcher); - - if (was_active) { - ev_ref(check->loop->ev); - } - - return 0; -} - - -static void uv__idle(EV_P_ ev_idle* w, int revents) { - uv_idle_t* idle = container_of(w, uv_idle_t, idle_watcher); - - if (idle->idle_cb) { - idle->idle_cb(idle, 0); - } -} - - - -int uv_idle_init(uv_loop_t* loop, uv_idle_t* idle) { - uv__handle_init(loop, (uv_handle_t*)idle, UV_IDLE); - loop->counters.idle_init++; - - ev_idle_init(&idle->idle_watcher, uv__idle); - idle->idle_cb = NULL; - - return 0; -} - - -int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) { - int was_active = ev_is_active(&idle->idle_watcher); - - idle->idle_cb = cb; - ev_idle_start(idle->loop->ev, &idle->idle_watcher); - - if (!was_active) { - ev_unref(idle->loop->ev); - } - - return 0; -} - - -int uv_idle_stop(uv_idle_t* idle) { - int was_active = ev_is_active(&idle->idle_watcher); - - ev_idle_stop(idle->loop->ev, &idle->idle_watcher); - - if (was_active) { - ev_ref(idle->loop->ev); - } - - return 0; -} - - int uv_is_active(uv_handle_t* handle) { switch (handle->type) { - case UV_TIMER: - return ev_is_active(&((uv_timer_t*)handle)->timer_watcher); - - case UV_PREPARE: - return ev_is_active(&((uv_prepare_t*)handle)->prepare_watcher); - - case UV_CHECK: - return ev_is_active(&((uv_check_t*)handle)->check_watcher); - - case UV_IDLE: - return ev_is_active(&((uv_idle_t*)handle)->idle_watcher); - - default: - return 1; + case UV_CHECK: + return uv__check_active((uv_check_t*)handle); + case UV_IDLE: + return uv__idle_active((uv_idle_t*)handle); + case UV_PREPARE: + return uv__prepare_active((uv_prepare_t*)handle); + case UV_TIMER: + return uv__timer_active((uv_timer_t*)handle); + default: + return 1; } } -static void uv__async(EV_P_ ev_async* w, int revents) { - uv_async_t* async = container_of(w, uv_async_t, async_watcher); - - if (async->async_cb) { - async->async_cb(async, 0); - } -} - - -int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb) { - uv__handle_init(loop, (uv_handle_t*)async, UV_ASYNC); - loop->counters.async_init++; - - ev_async_init(&async->async_watcher, uv__async); - async->async_cb = async_cb; - - /* Note: This does not have symmetry with the other libev wrappers. */ - ev_async_start(loop->ev, &async->async_watcher); - ev_unref(loop->ev); - - return 0; -} - - -int uv_async_send(uv_async_t* async) { - ev_async_send(async->loop->ev, &async->async_watcher); - return 0; -} - - -static int uv__timer_active(const uv_timer_t* timer) { - return timer->flags & UV_TIMER_ACTIVE; -} - - -static int uv__timer_repeating(const uv_timer_t* timer) { - return timer->flags & UV_TIMER_REPEAT; -} - - -static void uv__timer_cb(EV_P_ ev_timer* w, int revents) { - uv_timer_t* timer = container_of(w, uv_timer_t, timer_watcher); - - assert(uv__timer_active(timer)); - - if (!uv__timer_repeating(timer)) { - timer->flags &= ~UV_TIMER_ACTIVE; - ev_ref(EV_A); - } - - if (timer->timer_cb) { - timer->timer_cb(timer, 0); - } -} - - -int uv_timer_init(uv_loop_t* loop, uv_timer_t* timer) { - uv__handle_init(loop, (uv_handle_t*)timer, UV_TIMER); - loop->counters.timer_init++; - - ev_init(&timer->timer_watcher, uv__timer_cb); - - return 0; -} - - -int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout, - int64_t repeat) { - if (uv__timer_active(timer)) { - return -1; - } - - timer->timer_cb = cb; - timer->flags |= UV_TIMER_ACTIVE; - - if (repeat) - timer->flags |= UV_TIMER_REPEAT; - else - timer->flags &= ~UV_TIMER_REPEAT; - - ev_timer_set(&timer->timer_watcher, timeout / 1000.0, repeat / 1000.0); - ev_timer_start(timer->loop->ev, &timer->timer_watcher); - ev_unref(timer->loop->ev); - - return 0; -} - - -int uv_timer_stop(uv_timer_t* timer) { - if (uv__timer_active(timer)) { - ev_ref(timer->loop->ev); - } - - timer->flags &= ~(UV_TIMER_ACTIVE | UV_TIMER_REPEAT); - ev_timer_stop(timer->loop->ev, &timer->timer_watcher); - - return 0; -} - - -int uv_timer_again(uv_timer_t* timer) { - if (!uv__timer_active(timer)) { - uv__set_sys_error(timer->loop, EINVAL); - return -1; - } - - assert(uv__timer_repeating(timer)); - ev_timer_again(timer->loop->ev, &timer->timer_watcher); - return 0; -} - - -void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat) { - assert(timer->type == UV_TIMER); - timer->timer_watcher.repeat = repeat / 1000.0; - - if (repeat) - timer->flags |= UV_TIMER_REPEAT; - else - timer->flags &= ~UV_TIMER_REPEAT; -} - - -int64_t uv_timer_get_repeat(uv_timer_t* timer) { - assert(timer->type == UV_TIMER); - return (int64_t)(1000 * timer->timer_watcher.repeat); -} - - static int uv_getaddrinfo_done(eio_req* req) { uv_getaddrinfo_t* handle = req->data; struct addrinfo *res = handle->res; @@ -767,9 +446,8 @@ int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) { assert(sockfd >= 0); while (1) { -#if HAVE_SYS_ACCEPT4 - peerfd = sys_accept4(sockfd, saddr, &slen, SOCK_NONBLOCK | SOCK_CLOEXEC); - +#if __linux__ + peerfd = uv__accept4(sockfd, saddr, &slen, UV__SOCK_NONBLOCK|UV__SOCK_CLOEXEC); if (peerfd != -1) break; diff --git a/deps/uv/src/unix/cygwin.c b/deps/uv/src/unix/cygwin.c index aef8d7672e..31b069f9c4 100644 --- a/deps/uv/src/unix/cygwin.c +++ b/deps/uv/src/unix/cygwin.c @@ -79,6 +79,6 @@ int uv_fs_event_init(uv_loop_t* loop, } -void uv__fs_event_destroy(uv_fs_event_t* handle) { +void uv__fs_event_close(uv_fs_event_t* handle) { assert(0 && "implement me"); } diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c index 6b3705f6fb..e6deb3017b 100644 --- a/deps/uv/src/unix/darwin.c +++ b/deps/uv/src/unix/darwin.c @@ -73,6 +73,7 @@ uint64_t uv_hrtime() { int uv_exepath(char* buffer, size_t* size) { uint32_t usize; int result; + char* path; char* fullpath; if (!buffer || !size) { @@ -83,9 +84,11 @@ int uv_exepath(char* buffer, size_t* size) { result = _NSGetExecutablePath(buffer, &usize); if (result) return result; - fullpath = realpath(buffer, NULL); + path = (char*)malloc(2 * PATH_MAX); + fullpath = realpath(buffer, path); if (fullpath == NULL) { + free(path); return -1; } diff --git a/deps/uv/src/unix/ev/ev_kqueue.c b/deps/uv/src/unix/ev/ev_kqueue.c index f03cb8083d..871e771bc2 100644 --- a/deps/uv/src/unix/ev/ev_kqueue.c +++ b/deps/uv/src/unix/ev/ev_kqueue.c @@ -43,6 +43,30 @@ #include <string.h> #include <errno.h> +/* These are the same on OS X and the BSDs. */ +#ifndef NOTE_DELETE +# define NOTE_DELETE 0x01 +#endif +#ifndef NOTE_WRITE +# define NOTE_WRITE 0x02 +#endif +#ifndef NOTE_EXTEND +# define NOTE_EXTEND 0x04 +#endif +#ifndef NOTE_ATTRIB +# define NOTE_ATTRIB 0x08 +#endif +#ifndef NOTE_LINK +# define NOTE_LINK 0x10 +#endif +#ifndef NOTE_RENAME +# define NOTE_RENAME 0x20 +#endif +#ifndef NOTE_REVOKE +# define NOTE_REVOKE 0x40 +#endif + + extern void uv__kqueue_hack (EV_P_ int fflags, ev_io *w); diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index 6615516885..81dd8eaa8d 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -497,23 +497,27 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, #if HAVE_FUTIMES -static int _futime(const uv_file file, double atime, double mtime) { +static int _futime(const uv_file fd, double atime, double mtime) { +#if __linux__ + /* utimesat() has nanosecond resolution but we stick to microseconds + * for the sake of consistency with other platforms. + */ + struct timespec ts[2]; + ts[0].tv_sec = atime; + ts[0].tv_nsec = (unsigned long)(atime * 1000000) % 1000000 * 1000; + ts[1].tv_sec = mtime; + ts[1].tv_nsec = (unsigned long)(mtime * 1000000) % 1000000 * 1000; + return uv__utimesat(fd, NULL, ts, 0); +#else struct timeval tv[2]; - - /* FIXME possible loss of precision in floating-point arithmetic? */ tv[0].tv_sec = atime; tv[0].tv_usec = (unsigned long)(atime * 1000000) % 1000000; - tv[1].tv_sec = mtime; tv[1].tv_usec = (unsigned long)(mtime * 1000000) % 1000000; - -#ifdef __sun - return futimesat(file, NULL, tv); -#else - return futimes(file, tv); -#endif + return futimes(fd, tv); +#endif /* __linux__ */ } -#endif +#endif /* HAVE_FUTIMES */ int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, diff --git a/deps/uv/src/unix/idle.c b/deps/uv/src/unix/idle.c new file mode 100644 index 0000000000..5b4cf57747 --- /dev/null +++ b/deps/uv/src/unix/idle.c @@ -0,0 +1,79 @@ +/* Copyright Joyent, Inc. and other Node 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" + + +static void uv__idle(EV_P_ ev_idle* w, int revents) { + uv_idle_t* idle = container_of(w, uv_idle_t, idle_watcher); + + if (idle->idle_cb) { + idle->idle_cb(idle, 0); + } +} + + +int uv_idle_init(uv_loop_t* loop, uv_idle_t* idle) { + uv__handle_init(loop, (uv_handle_t*)idle, UV_IDLE); + loop->counters.idle_init++; + + ev_idle_init(&idle->idle_watcher, uv__idle); + idle->idle_cb = NULL; + + return 0; +} + + +int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) { + int was_active = ev_is_active(&idle->idle_watcher); + + idle->idle_cb = cb; + ev_idle_start(idle->loop->ev, &idle->idle_watcher); + + if (!was_active) { + ev_unref(idle->loop->ev); + } + + return 0; +} + + +int uv_idle_stop(uv_idle_t* idle) { + int was_active = ev_is_active(&idle->idle_watcher); + + ev_idle_stop(idle->loop->ev, &idle->idle_watcher); + + if (was_active) { + ev_ref(idle->loop->ev); + } + + return 0; +} + + +int uv__idle_active(const uv_idle_t* handle) { + return ev_is_active(&handle->idle_watcher); +} + + +void uv__idle_close(uv_idle_t* handle) { + uv_idle_stop(handle); +} diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 3cc086f265..379b99623b 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -37,79 +37,9 @@ #undef HAVE_KQUEUE #undef HAVE_PORTS_FS -#if defined(__linux__) - -# undef HAVE_SYS_UTIMESAT -# undef HAVE_SYS_PIPE2 -# undef HAVE_SYS_ACCEPT4 - -# undef _GNU_SOURCE -# define _GNU_SOURCE - -# include <linux/version.h> -# include <sys/syscall.h> -# include <features.h> -# include <unistd.h> - -# if __NR_utimensat -# define HAVE_SYS_UTIMESAT 1 -# endif -# if __NR_pipe2 -# define HAVE_SYS_PIPE2 1 -# endif -# if __NR_accept4 -# define HAVE_SYS_ACCEPT4 1 -# endif - -# ifndef O_CLOEXEC -# define O_CLOEXEC 02000000 -# endif - -# ifndef SOCK_CLOEXEC -# define SOCK_CLOEXEC O_CLOEXEC -# endif - -# ifndef SOCK_NONBLOCK -# define SOCK_NONBLOCK O_NONBLOCK -# endif - -# if HAVE_SYS_UTIMESAT -inline static int sys_utimesat(int dirfd, - const char* path, - const struct timespec times[2], - int flags) -{ - return syscall(__NR_utimensat, dirfd, path, times, flags); -} -inline static int sys_futimes(int fd, const struct timeval times[2]) -{ - struct timespec ts[2]; - ts[0].tv_sec = times[0].tv_sec, ts[0].tv_nsec = times[0].tv_usec * 1000; - ts[1].tv_sec = times[1].tv_sec, ts[1].tv_nsec = times[1].tv_usec * 1000; - return sys_utimesat(fd, NULL, ts, 0); -} -# undef HAVE_FUTIMES -# define HAVE_FUTIMES 1 -# define futimes(fd, times) sys_futimes(fd, times) -# endif /* HAVE_SYS_FUTIMESAT */ - -# if HAVE_SYS_PIPE2 -inline static int sys_pipe2(int pipefd[2], int flags) -{ - return syscall(__NR_pipe2, pipefd, flags); -} -# endif /* HAVE_SYS_PIPE2 */ - -# if HAVE_SYS_ACCEPT4 -inline static int sys_accept4(int fd, - struct sockaddr* addr, - socklen_t* addrlen, - int flags) -{ - return syscall(__NR_accept4, fd, addr, addrlen, flags); -} -# endif /* HAVE_SYS_ACCEPT4 */ - +#if __linux__ +# include "linux/syscalls.h" +# define HAVE_FUTIMES 1 /* emulated with utimesat() */ #endif /* __linux__ */ #if defined(__sun) @@ -118,6 +48,8 @@ inline static int sys_accept4(int fd, # ifdef PORT_SOURCE_FILE # define HAVE_PORTS_FS 1 # endif +# define HAVE_FUTIMES 1 +# define futimes(fd, tv) futimesat(fd, (void*)0, tv) #endif /* __sun */ #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun) @@ -125,7 +57,7 @@ inline static int sys_accept4(int fd, #endif /* FIXME exact copy of the #ifdef guard in uv-unix.h */ -#if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060) \ +#if defined(__APPLE__) \ || defined(__FreeBSD__) \ || defined(__OpenBSD__) \ || defined(__NetBSD__) @@ -172,6 +104,10 @@ int uv__cloexec(int fd, int set) __attribute__((unused)); int uv__socket(int domain, int type, int protocol); int uv__dup(int fd); +/* loop */ +int uv__loop_init(uv_loop_t* loop, int default_loop); +void uv__loop_delete(uv_loop_t* loop); + /* error */ uv_err_code uv_translate_sys_error(int sys_errno); void uv_fatal_error(const int errorno, const char* syscall); @@ -198,28 +134,28 @@ int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay); /* pipe */ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); void uv__pipe_accept(EV_P_ ev_io* watcher, int revents); -int uv_pipe_cleanup(uv_pipe_t* handle); -/* udp */ -void uv__udp_start_close(uv_udp_t* handle); +/* various */ +int uv__check_active(const uv_check_t* handle); +int uv__idle_active(const uv_idle_t* handle); +int uv__prepare_active(const uv_prepare_t* handle); +int uv__timer_active(const uv_timer_t* handle); + +void uv__async_close(uv_async_t* handle); +void uv__check_close(uv_check_t* handle); +void uv__fs_event_close(uv_fs_event_t* handle); +void uv__idle_close(uv_idle_t* handle); +void uv__pipe_close(uv_pipe_t* handle); +void uv__prepare_close(uv_prepare_t* handle); +void uv__process_close(uv_process_t* handle); +void uv__stream_close(uv_stream_t* handle); +void uv__timer_close(uv_timer_t* handle); +void uv__udp_close(uv_udp_t* handle); void uv__udp_finish_close(uv_udp_t* handle); -/* fs */ -void uv__fs_event_destroy(uv_fs_event_t* handle); - #define UV__F_IPC (1 << 0) #define UV__F_NONBLOCK (1 << 1) int uv__make_socketpair(int fds[2], int flags); int uv__make_pipe(int fds[2], int flags); -#if __linux__ -void uv__inotify_loop_init(uv_loop_t* loop); -void uv__inotify_loop_delete(uv_loop_t* loop); -# define uv__loop_platform_init(loop) uv__inotify_loop_init(loop) -# define uv__loop_platform_delete(loop) uv__inotify_loop_delete(loop) -#else -# define uv__loop_platform_init(loop) -# define uv__loop_platform_delete(loop) -#endif - #endif /* UV_UNIX_INTERNAL_H_ */ diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c index 58988f9d1b..1af2fbe34d 100644 --- a/deps/uv/src/unix/kqueue.c +++ b/deps/uv/src/unix/kqueue.c @@ -26,8 +26,6 @@ #include <string.h> #include <errno.h> -#if HAVE_KQUEUE - #include <sys/sysctl.h> #include <sys/types.h> #include <sys/event.h> @@ -121,34 +119,9 @@ int uv_fs_event_init(uv_loop_t* loop, } -void uv__fs_event_destroy(uv_fs_event_t* handle) { +void uv__fs_event_close(uv_fs_event_t* handle) { uv__fs_event_stop(handle); free(handle->filename); close(handle->fd); handle->fd = -1; } - -#else /* !HAVE_KQUEUE */ - -int uv_fs_event_init(uv_loop_t* loop, - uv_fs_event_t* handle, - const char* filename, - uv_fs_event_cb cb, - int flags) { - loop->counters.fs_event_init++; - uv__set_sys_error(loop, ENOSYS); - return -1; -} - - -void uv__fs_event_destroy(uv_fs_event_t* handle) { - UNREACHABLE(); -} - - -/* Called by libev, don't touch. */ -void uv__kqueue_hack(EV_P_ int fflags, ev_io *w) { - UNREACHABLE(); -} - -#endif /* HAVE_KQUEUE */ diff --git a/deps/uv/src/unix/linux/inotify.c b/deps/uv/src/unix/linux/inotify.c index 9819f5528c..04147833bf 100644 --- a/deps/uv/src/unix/linux/inotify.c +++ b/deps/uv/src/unix/linux/inotify.c @@ -21,6 +21,7 @@ #include "uv.h" #include "tree.h" #include "../internal.h" +#include "syscalls.h" #include <stdint.h> #include <stdio.h> @@ -31,91 +32,6 @@ #include <sys/types.h> #include <unistd.h> -#include <fcntl.h> - -#undef HAVE_INOTIFY_INIT -#undef HAVE_INOTIFY_INIT1 -#undef HAVE_INOTIFY_ADD_WATCH -#undef HAVE_INOTIFY_RM_WATCH - -#if __NR_inotify_init -# define HAVE_INOTIFY_INIT 1 -#endif -#if __NR_inotify_init1 -# define HAVE_INOTIFY_INIT1 1 -#endif -#if __NR_inotify_add_watch -# define HAVE_INOTIFY_ADD_WATCH 1 -#endif -#if __NR_inotify_rm_watch -# define HAVE_INOTIFY_RM_WATCH 1 -#endif - -#if HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1 -# undef IN_ACCESS -# undef IN_MODIFY -# undef IN_ATTRIB -# undef IN_CLOSE_WRITE -# undef IN_CLOSE_NOWRITE -# undef IN_OPEN -# undef IN_MOVED_FROM -# undef IN_MOVED_TO -# undef IN_CREATE -# undef IN_DELETE -# undef IN_DELETE_SELF -# undef IN_MOVE_SELF -# define IN_ACCESS 0x001 -# define IN_MODIFY 0x002 -# define IN_ATTRIB 0x004 -# define IN_CLOSE_WRITE 0x008 -# define IN_CLOSE_NOWRITE 0x010 -# define IN_OPEN 0x020 -# define IN_MOVED_FROM 0x040 -# define IN_MOVED_TO 0x080 -# define IN_CREATE 0x100 -# define IN_DELETE 0x200 -# define IN_DELETE_SELF 0x400 -# define IN_MOVE_SELF 0x800 -struct inotify_event { - int32_t wd; - uint32_t mask; - uint32_t cookie; - uint32_t len; - /* char name[0]; */ -}; -#endif /* HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1 */ - -#undef IN_CLOEXEC -#undef IN_NONBLOCK - -#if HAVE_INOTIFY_INIT1 -# define IN_CLOEXEC O_CLOEXEC -# define IN_NONBLOCK O_NONBLOCK -#endif /* HAVE_INOTIFY_INIT1 */ - -#if HAVE_INOTIFY_INIT -inline static int inotify_init(void) { - return syscall(__NR_inotify_init); -} -#endif /* HAVE_INOTIFY_INIT */ - -#if HAVE_INOTIFY_INIT1 -inline static int inotify_init1(int flags) { - return syscall(__NR_inotify_init1, flags); -} -#endif /* HAVE_INOTIFY_INIT1 */ - -#if HAVE_INOTIFY_ADD_WATCH -inline static int inotify_add_watch(int fd, const char* path, uint32_t mask) { - return syscall(__NR_inotify_add_watch, fd, path, mask); -} -#endif /* HAVE_INOTIFY_ADD_WATCH */ - -#if HAVE_INOTIFY_RM_WATCH -inline static int inotify_rm_watch(int fd, uint32_t wd) { - return syscall(__NR_inotify_rm_watch, fd, wd); -} -#endif /* HAVE_INOTIFY_RM_WATCH */ /* Don't look aghast, this is exactly how glibc's basename() works. */ @@ -135,37 +51,19 @@ static int compare_watchers(const uv_fs_event_t* a, const uv_fs_event_t* b) { RB_GENERATE_STATIC(uv__inotify_watchers, uv_fs_event_s, node, compare_watchers) -void uv__inotify_loop_init(uv_loop_t* loop) { - RB_INIT(&loop->inotify_watchers); - loop->inotify_fd = -1; -} - - -void uv__inotify_loop_delete(uv_loop_t* loop) { - if (loop->inotify_fd == -1) return; - ev_io_stop(loop->ev, &loop->inotify_read_watcher); - close(loop->inotify_fd); - loop->inotify_fd = -1; -} - - -#if HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1 - static void uv__inotify_read(EV_P_ ev_io* w, int revents); static int new_inotify_fd(void) { int fd; -#if HAVE_INOTIFY_INIT1 - fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); + fd = uv__inotify_init1(UV__IN_NONBLOCK | UV__IN_CLOEXEC); if (fd != -1) return fd; if (errno != ENOSYS) return -1; -#endif - if ((fd = inotify_init()) == -1) + if ((fd = uv__inotify_init()) == -1) return -1; if (uv__cloexec(fd, 1) || uv__nonblock(fd, 1)) { @@ -216,7 +114,7 @@ static void remove_watcher(uv_fs_event_t* handle) { static void uv__inotify_read(EV_P_ ev_io* w, int revents) { - const struct inotify_event* e; + const struct uv__inotify_event* e; uv_fs_event_t* handle; uv_loop_t* uv_loop; const char* filename; @@ -243,12 +141,12 @@ static void uv__inotify_read(EV_P_ ev_io* w, int revents) { /* Now we have one or more inotify_event structs. */ for (p = buf; p < buf + size; p += sizeof(*e) + e->len) { - e = (const struct inotify_event*)p; + e = (const struct uv__inotify_event*)p; events = 0; - if (e->mask & (IN_ATTRIB|IN_MODIFY)) + if (e->mask & (UV__IN_ATTRIB|UV__IN_MODIFY)) events |= UV_CHANGE; - if (e->mask & ~(IN_ATTRIB|IN_MODIFY)) + if (e->mask & ~(UV__IN_ATTRIB|UV__IN_MODIFY)) events |= UV_RENAME; handle = find_watcher(uv_loop, e->wd); @@ -282,15 +180,15 @@ int uv_fs_event_init(uv_loop_t* loop, if (init_inotify(loop)) return -1; - events = IN_ATTRIB - | IN_CREATE - | IN_MODIFY - | IN_DELETE - | IN_DELETE_SELF - | IN_MOVED_FROM - | IN_MOVED_TO; + events = UV__IN_ATTRIB + | UV__IN_CREATE + | UV__IN_MODIFY + | UV__IN_DELETE + | UV__IN_DELETE_SELF + | UV__IN_MOVED_FROM + | UV__IN_MOVED_TO; - wd = inotify_add_watch(loop->inotify_fd, filename, events); + wd = uv__inotify_add_watch(loop->inotify_fd, filename, events); if (wd == -1) return uv__set_sys_error(loop, errno); uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); @@ -303,30 +201,11 @@ int uv_fs_event_init(uv_loop_t* loop, } -void uv__fs_event_destroy(uv_fs_event_t* handle) { - inotify_rm_watch(handle->loop->inotify_fd, handle->fd); +void uv__fs_event_close(uv_fs_event_t* handle) { + uv__inotify_rm_watch(handle->loop->inotify_fd, handle->fd); remove_watcher(handle); handle->fd = -1; free(handle->filename); handle->filename = NULL; } - -#else /* !HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1 */ - -int uv_fs_event_init(uv_loop_t* loop, - uv_fs_event_t* handle, - const char* filename, - uv_fs_event_cb cb, - int flags) { - loop->counters.fs_event_init++; - uv__set_sys_error(loop, ENOSYS); - return -1; -} - - -void uv__fs_event_destroy(uv_fs_event_t* handle) { - UNREACHABLE(); -} - -#endif /* HAVE_INOTIFY_INIT || HAVE_INOTIFY_INIT1 */ diff --git a/deps/uv/src/unix/linux/syscalls.c b/deps/uv/src/unix/linux/syscalls.c new file mode 100644 index 0000000000..bdf90cf30d --- /dev/null +++ b/deps/uv/src/unix/linux/syscalls.c @@ -0,0 +1,230 @@ +/* Copyright Joyent, Inc. and other Node 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 "syscalls.h" +#include <unistd.h> +#include <sys/syscall.h> +#include <sys/types.h> +#include <errno.h> + +#if __i386__ +# ifndef __NR_socketcall +# define __NR_socketcall 102 +# endif +#endif + +#if __arm__ +# if __thumb__ || __ARM_EABI__ +# define UV_SYSCALL_BASE 0 +# else +# define UV_SYSCALL_BASE 0x900000 +# endif +#endif /* __arm__ */ + +#ifndef __NR_accept4 +# if __x86_64__ +# define __NR_accept4 288 +# elif __i386__ + /* Nothing. Handled through socketcall(). */ +# elif __arm__ +# define __NR_accept4 (UV_SYSCALL_BASE + 366) +# endif +#endif /* __NR_accept4 */ + +#ifndef __NR_inotify_init +# if __x86_64__ +# define __NR_inotify_init 253 +# elif __i386__ +# define __NR_inotify_init 291 +# elif __arm__ +# define __NR_inotify_init (UV_SYSCALL_BASE + 316) +# endif +#endif /* __NR_inotify_init */ + +#ifndef __NR_inotify_init1 +# if __x86_64__ +# define __NR_inotify_init1 294 +# elif __i386__ +# define __NR_inotify_init1 332 +# elif __arm__ +# define __NR_inotify_init1 (UV_SYSCALL_BASE + 360) +# endif +#endif /* __NR_inotify_init1 */ + +#ifndef __NR_inotify_add_watch +# if __x86_64__ +# define __NR_inotify_add_watch 254 +# elif __i386__ +# define __NR_inotify_add_watch 292 +# elif __arm__ +# define __NR_inotify_add_watch (UV_SYSCALL_BASE + 317) +# endif +#endif /* __NR_inotify_add_watch */ + +#ifndef __NR_inotify_rm_watch +# if __x86_64__ +# define __NR_inotify_rm_watch 255 +# elif __i386__ +# define __NR_inotify_rm_watch 293 +# elif __arm__ +# define __NR_inotify_rm_watch (UV_SYSCALL_BASE + 318) +# endif +#endif /* __NR_inotify_rm_watch */ + +#ifndef __NR_pipe2 +# if __x86_64__ +# define __NR_pipe2 293 +# elif __i386__ +# define __NR_pipe2 331 +# elif __arm__ +# define __NR_pipe2 (UV_SYSCALL_BASE + 359) +# endif +#endif /* __NR_pipe2 */ + +#ifndef __NR_recvmmsg +# if __x86_64__ +# define __NR_recvmmsg 299 +# elif __i386__ +# define __NR_recvmmsg 337 +# elif __arm__ +# define __NR_recvmmsg (UV_SYSCALL_BASE + 365) +# endif +#endif /* __NR_recvmsg */ + +#ifndef __NR_sendmmsg +# if __x86_64__ +# define __NR_sendmmsg 307 +# elif __i386__ +# define __NR_sendmmsg 345 +# elif __arm__ +# define __NR_recvmmsg (UV_SYSCALL_BASE + 374) +# endif +#endif /* __NR_sendmmsg */ + +#ifndef __NR_utimensat +# if __x86_64__ +# define __NR_utimensat 280 +# elif __i386__ +# define __NR_utimensat 320 +# elif __arm__ +# define __NR_utimensat (UV_SYSCALL_BASE + 348) +# endif +#endif /* __NR_utimensat */ + + +int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) { +#if __i386__ + unsigned long args[] = { + (unsigned long) fd, + (unsigned long) addr, + (unsigned long) addrlen, + (unsigned long) flags + }; + return syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args); +#elif __NR_accept4 + return syscall(__NR_accept4, fd, addr, addrlen, flags); +#else + return errno = ENOSYS, -1; +#endif +} + + +int uv__inotify_init(void) { +#if __NR_inotify_init + return syscall(__NR_inotify_init); +#else + return errno = ENOSYS, -1; +#endif +} + + +int uv__inotify_init1(int flags) { +#if __NR_inotify_init1 + return syscall(__NR_inotify_init1, flags); +#else + return errno = ENOSYS, -1; +#endif +} + + +int uv__inotify_add_watch(int fd, const char* path, __u32 mask) { +#if __NR_inotify_add_watch + return syscall(__NR_inotify_add_watch, fd, path, mask); +#else + return errno = ENOSYS, -1; +#endif +} + + +int uv__inotify_rm_watch(int fd, __s32 wd) { +#if __NR_inotify_rm_watch + return syscall(__NR_inotify_rm_watch, fd, wd); +#else + return errno = ENOSYS, -1; +#endif +} + + +int uv__pipe2(int pipefd[2], int flags) { +#if __NR_pipe2 + return syscall(__NR_pipe2, pipefd, flags); +#else + return errno = ENOSYS, -1; +#endif +} + + +int uv__sendmmsg(int fd, + struct uv__mmsghdr* mmsg, + unsigned int vlen, + unsigned int flags) { +#if __NR_sendmmsg + return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags); +#else + return errno = ENOSYS, -1; +#endif +} + + +int uv__recvmmsg(int fd, + struct uv__mmsghdr* mmsg, + unsigned int vlen, + unsigned int flags, + struct timespec* timeout) { +#if __NR_recvmmsg + return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout); +#else + return errno = ENOSYS, -1; +#endif +} + + +int uv__utimesat(int dirfd, + const char* path, + const struct timespec times[2], + int flags) +{ +#if __NR_utimensat + return syscall(__NR_utimensat, dirfd, path, times, flags); +#else + return errno = ENOSYS, -1; +#endif +} diff --git a/deps/uv/src/unix/linux/syscalls.h b/deps/uv/src/unix/linux/syscalls.h new file mode 100644 index 0000000000..5d42044a3b --- /dev/null +++ b/deps/uv/src/unix/linux/syscalls.h @@ -0,0 +1,87 @@ +/* Copyright Joyent, Inc. and other Node 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_LINUX_SYSCALL_H_ +#define UV_LINUX_SYSCALL_H_ + +#undef _GNU_SOURCE +#define _GNU_SOURCE + +#include <sys/types.h> +#include <sys/socket.h> +#include <linux/types.h> + +#define UV__O_NONBLOCK 0x800 +#define UV__O_CLOEXEC 0x80000 + +#define UV__SOCK_CLOEXEC UV__O_CLOEXEC +#define UV__SOCK_NONBLOCK UV__O_NONBLOCK + +#define UV__IN_CLOEXEC UV__O_CLOEXEC +#define UV__IN_NONBLOCK UV__O_NONBLOCK + +#define UV__IN_ACCESS 0x001 +#define UV__IN_MODIFY 0x002 +#define UV__IN_ATTRIB 0x004 +#define UV__IN_CLOSE_WRITE 0x008 +#define UV__IN_CLOSE_NOWRITE 0x010 +#define UV__IN_OPEN 0x020 +#define UV__IN_MOVED_FROM 0x040 +#define UV__IN_MOVED_TO 0x080 +#define UV__IN_CREATE 0x100 +#define UV__IN_DELETE 0x200 +#define UV__IN_DELETE_SELF 0x400 +#define UV__IN_MOVE_SELF 0x800 + +struct uv__inotify_event { + __s32 wd; + __u32 mask; + __u32 cookie; + __u32 len; + /* char name[0]; */ +}; + +struct uv__mmsghdr { + struct msghdr msg_hdr; + unsigned int msg_len; +}; + +int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags); +int uv__inotify_init(void); +int uv__inotify_init1(int flags); +int uv__inotify_add_watch(int fd, const char* path, __u32 mask); +int uv__inotify_rm_watch(int fd, __s32 wd); +int uv__pipe2(int pipefd[2], int flags); +int uv__recvmmsg(int fd, + struct uv__mmsghdr* mmsg, + unsigned int vlen, + unsigned int flags, + struct timespec* timeout); +int uv__sendmmsg(int fd, + struct uv__mmsghdr* mmsg, + unsigned int vlen, + unsigned int flags); +int uv__utimesat(int dirfd, + const char* path, + const struct timespec times[2], + int flags); + +#endif /* UV_LINUX_SYSCALL_H_ */ diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c new file mode 100644 index 0000000000..5580aba3fe --- /dev/null +++ b/deps/uv/src/unix/loop.c @@ -0,0 +1,58 @@ +/* Copyright Joyent, Inc. and other Node 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 "tree.h" +#include "internal.h" +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +int uv__loop_init(uv_loop_t* loop, int default_loop) { +#if HAVE_KQUEUE + int flags = EVBACKEND_KQUEUE; +#else + int flags = EVFLAG_AUTO; +#endif + RB_INIT(&loop->uv_ares_handles_); + loop->endgame_handles = NULL; + loop->ev = (default_loop ? ev_default_loop : ev_loop_new)(flags); + ev_set_userdata(loop->ev, loop); + eio_channel_init(&loop->uv_eio_channel, loop); +#if __linux__ + RB_INIT(&loop->inotify_watchers); + loop->inotify_fd = -1; +#endif + return 0; +} + + +void uv__loop_delete(uv_loop_t* loop) { + uv_ares_destroy(loop, loop->channel); + ev_loop_destroy(loop->ev); +#if __linux__ + if (loop->inotify_fd == -1) return; + ev_io_stop(loop->ev, &loop->inotify_read_watcher); + close(loop->inotify_fd); + loop->inotify_fd = -1; +#endif +} diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c index 3573a57105..d085304abe 100644 --- a/deps/uv/src/unix/pipe.c +++ b/deps/uv/src/unix/pipe.c @@ -146,29 +146,19 @@ out: } -int uv_pipe_cleanup(uv_pipe_t* handle) { - int saved_errno; - int status; - - saved_errno = errno; - status = -1; - +void uv__pipe_close(uv_pipe_t* handle) { if (handle->pipe_fname) { /* * Unlink the file system entity before closing the file descriptor. * Doing it the other way around introduces a race where our process * unlinks a socket with the same name that's just been created by * another thread or process. - * - * This is less of an issue now that we attach a file lock - * to the socket but it's still a best practice. */ unlink(handle->pipe_fname); free((void*)handle->pipe_fname); } - errno = saved_errno; - return status; + uv__stream_close((uv_stream_t*)handle); } diff --git a/deps/uv/src/unix/prepare.c b/deps/uv/src/unix/prepare.c new file mode 100644 index 0000000000..6c18fbd7fc --- /dev/null +++ b/deps/uv/src/unix/prepare.c @@ -0,0 +1,79 @@ +/* Copyright Joyent, Inc. and other Node 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" + + +static void uv__prepare(EV_P_ ev_prepare* w, int revents) { + uv_prepare_t* prepare = container_of(w, uv_prepare_t, prepare_watcher); + + if (prepare->prepare_cb) { + prepare->prepare_cb(prepare, 0); + } +} + + +int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare) { + uv__handle_init(loop, (uv_handle_t*)prepare, UV_PREPARE); + loop->counters.prepare_init++; + + ev_prepare_init(&prepare->prepare_watcher, uv__prepare); + prepare->prepare_cb = NULL; + + return 0; +} + + +int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb) { + int was_active = ev_is_active(&prepare->prepare_watcher); + + prepare->prepare_cb = cb; + + ev_prepare_start(prepare->loop->ev, &prepare->prepare_watcher); + + if (!was_active) { + ev_unref(prepare->loop->ev); + } + + return 0; +} + + +int uv_prepare_stop(uv_prepare_t* prepare) { + int was_active = ev_is_active(&prepare->prepare_watcher); + + ev_prepare_stop(prepare->loop->ev, &prepare->prepare_watcher); + + if (was_active) { + ev_ref(prepare->loop->ev); + } + return 0; +} + + +int uv__prepare_active(const uv_prepare_t* handle) { + return ev_is_active(&handle->prepare_watcher); +} + + +void uv__prepare_close(uv_prepare_t* handle) { + uv_prepare_stop(handle); +} diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index ffe014514b..9a5c76c78e 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -105,7 +105,7 @@ int uv__make_socketpair(int fds[2], int flags) { int uv__make_pipe(int fds[2], int flags) { -#if HAVE_SYS_PIPE2 +#if __linux__ int fl; fl = O_CLOEXEC; @@ -113,17 +113,11 @@ int uv__make_pipe(int fds[2], int flags) { if (flags & UV__F_NONBLOCK) fl |= O_NONBLOCK; - if (sys_pipe2(fds, fl) == 0) + if (uv__pipe2(fds, fl) == 0) return 0; if (errno != ENOSYS) return -1; - - /* errno == ENOSYS so maybe the kernel headers lied about - * the availability of pipe2(). This can happen if people - * build libuv against newer kernel headers than the kernel - * they actually run the software on. - */ #endif if (pipe(fds)) @@ -368,3 +362,8 @@ uv_err_t uv_kill(int pid, int signum) { return uv_ok_; } } + + +void uv__process_close(uv_process_t* handle) { + ev_child_stop(handle->loop->ev, &handle->child_watcher); +} diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index fd24caaa6b..ef71fc72ad 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -1005,3 +1005,20 @@ int uv_is_readable(uv_stream_t* stream) { int uv_is_writable(uv_stream_t* stream) { return stream->flags & UV_WRITABLE; } + + +void uv__stream_close(uv_stream_t* handle) { + uv_read_stop(handle); + ev_io_stop(handle->loop->ev, &handle->write_watcher); + + close(handle->fd); + handle->fd = -1; + + if (handle->accepted_fd >= 0) { + close(handle->accepted_fd); + handle->accepted_fd = -1; + } + + assert(!ev_is_active(&handle->read_watcher)); + assert(!ev_is_active(&handle->write_watcher)); +} diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c index 37fdd8982f..0057e68651 100644 --- a/deps/uv/src/unix/sunos.c +++ b/deps/uv/src/unix/sunos.c @@ -37,6 +37,7 @@ #include <sys/time.h> #include <unistd.h> #include <kstat.h> +#include <fcntl.h> #if HAVE_PORTS_FS # include <sys/port.h> @@ -190,7 +191,7 @@ int uv_fs_event_init(uv_loop_t* loop, } -void uv__fs_event_destroy(uv_fs_event_t* handle) { +void uv__fs_event_close(uv_fs_event_t* handle) { ev_ref(handle->loop->ev); ev_io_stop(handle->loop->ev, &handle->event_watcher); close(handle->fd); @@ -213,7 +214,7 @@ int uv_fs_event_init(uv_loop_t* loop, } -void uv__fs_event_destroy(uv_fs_event_t* handle) { +void uv__fs_event_close(uv_fs_event_t* handle) { UNREACHABLE(); } @@ -239,28 +240,24 @@ uv_err_t uv_get_process_title(char* buffer, size_t size) { uv_err_t uv_resident_set_memory(size_t* rss) { - pid_t pid = getpid(); psinfo_t psinfo; - char pidpath[1024]; - FILE *f; + uv_err_t err; + int fd; - sprintf(pidpath, "/proc/%d/psinfo", (int)pid); - - f = fopen(pidpath, "r"); - if (!f) return uv__new_sys_error(errno); - - if (fread(&psinfo, sizeof(psinfo_t), 1, f) != 1) { - fclose (f); + fd = open("/proc/self/psinfo", O_RDONLY); + if (fd == -1) return uv__new_sys_error(errno); - } - /* XXX correct? */ + err = uv_ok_; - *rss = (size_t) psinfo.pr_rssize * 1024; + if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) + *rss = (size_t)psinfo.pr_rssize * 1024; + else + err = uv__new_sys_error(EINVAL); - fclose (f); + close(fd); - return uv_ok_; + return err; } diff --git a/deps/uv/src/unix/timer.c b/deps/uv/src/unix/timer.c new file mode 100644 index 0000000000..6a002294c9 --- /dev/null +++ b/deps/uv/src/unix/timer.c @@ -0,0 +1,127 @@ +/* Copyright Joyent, Inc. and other Node 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 <assert.h> + + +static int uv__timer_repeating(const uv_timer_t* timer) { + return timer->flags & UV_TIMER_REPEAT; +} + + +static void uv__timer_cb(EV_P_ ev_timer* w, int revents) { + uv_timer_t* timer = container_of(w, uv_timer_t, timer_watcher); + + assert(uv__timer_active(timer)); + + if (!uv__timer_repeating(timer)) { + timer->flags &= ~UV_TIMER_ACTIVE; + ev_ref(EV_A); + } + + if (timer->timer_cb) { + timer->timer_cb(timer, 0); + } +} + + +int uv_timer_init(uv_loop_t* loop, uv_timer_t* timer) { + uv__handle_init(loop, (uv_handle_t*)timer, UV_TIMER); + loop->counters.timer_init++; + + ev_init(&timer->timer_watcher, uv__timer_cb); + + return 0; +} + + +int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout, + int64_t repeat) { + if (uv__timer_active(timer)) { + return -1; + } + + timer->timer_cb = cb; + timer->flags |= UV_TIMER_ACTIVE; + + if (repeat) + timer->flags |= UV_TIMER_REPEAT; + else + timer->flags &= ~UV_TIMER_REPEAT; + + ev_timer_set(&timer->timer_watcher, timeout / 1000.0, repeat / 1000.0); + ev_timer_start(timer->loop->ev, &timer->timer_watcher); + ev_unref(timer->loop->ev); + + return 0; +} + + +int uv_timer_stop(uv_timer_t* timer) { + if (uv__timer_active(timer)) { + ev_ref(timer->loop->ev); + } + + timer->flags &= ~(UV_TIMER_ACTIVE | UV_TIMER_REPEAT); + ev_timer_stop(timer->loop->ev, &timer->timer_watcher); + + return 0; +} + + +int uv_timer_again(uv_timer_t* timer) { + if (!uv__timer_active(timer)) { + uv__set_artificial_error(timer->loop, UV_EINVAL); + return -1; + } + + assert(uv__timer_repeating(timer)); + ev_timer_again(timer->loop->ev, &timer->timer_watcher); + return 0; +} + + +void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat) { + assert(timer->type == UV_TIMER); + timer->timer_watcher.repeat = repeat / 1000.0; + + if (repeat) + timer->flags |= UV_TIMER_REPEAT; + else + timer->flags &= ~UV_TIMER_REPEAT; +} + + +int64_t uv_timer_get_repeat(uv_timer_t* timer) { + assert(timer->type == UV_TIMER); + return (int64_t)(1000 * timer->timer_watcher.repeat); +} + + +int uv__timer_active(const uv_timer_t* timer) { + return timer->flags & UV_TIMER_ACTIVE; +} + + +void uv__timer_close(uv_timer_t* handle) { + uv_timer_stop(handle); +} diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index e1c7621cdd..9c84cef349 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -85,7 +85,7 @@ static void uv__udp_stop_write_watcher(uv_udp_t* handle) { } -void uv__udp_start_close(uv_udp_t* handle) { +void uv__udp_close(uv_udp_t* handle) { uv__udp_stop_write_watcher(handle); uv__udp_stop_read_watcher(handle); close(handle->fd); diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c index 2e424a9cd6..c8192bd7db 100644 --- a/deps/uv/src/uv-common.c +++ b/deps/uv/src/uv-common.c @@ -32,6 +32,25 @@ #include "ares/inet_net_pton.h" #include "ares/inet_ntop.h" +#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t); + +size_t uv_handle_size(uv_handle_type type) { + switch (type) { + UV_HANDLE_TYPE_MAP(XX) + default: + return -1; + } +} + +size_t uv_req_size(uv_req_type type) { + switch(type) { + UV_REQ_TYPE_MAP(XX) + default: + return -1; + } +} + +#undef XX size_t uv_strlcpy(char* dst, const char* src, size_t size) { size_t n; diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h index e1f16b6cd3..e82f584272 100644 --- a/deps/uv/src/uv-common.h +++ b/deps/uv/src/uv-common.h @@ -35,7 +35,17 @@ struct uv_ares_task_s { UV_HANDLE_FIELDS - UV_ARES_TASK_PRIVATE_FIELDS +#if _WIN32 + struct uv_req_s ares_req; + SOCKET sock; + HANDLE h_wait; + WSAEVENT h_event; + HANDLE h_close_event; +#else + int sock; + ev_io read_watcher; + ev_io write_watcher; +#endif RB_ENTRY(uv_ares_task_s) node; }; diff --git a/deps/uv/src/win/handle.c b/deps/uv/src/win/handle.c index 2e053b00d3..d19492c0e7 100644 --- a/deps/uv/src/win/handle.c +++ b/deps/uv/src/win/handle.c @@ -154,6 +154,11 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) { } +int uv_is_closing(uv_handle_t* handle) { + return handle->flags & (UV_HANDLE_CLOSING | UV_HANDLE_CLOSED); +} + + void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle) { if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) { handle->flags |= UV_HANDLE_ENDGAME_QUEUED; diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h index 470aed1c82..d79aa3da98 100644 --- a/deps/uv/src/win/internal.h +++ b/deps/uv/src/win/internal.h @@ -150,6 +150,8 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info, int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid, LPWSAPROTOCOL_INFOW protocol_info); +void uv_tcp_close(uv_tcp_t* tcp); + /* * UDP diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index 21409edea5..51ef604eb1 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -252,10 +252,9 @@ static int uv__bind(uv_tcp_t* handle, int addrsize) { DWORD err; int r; - SOCKET sock; if (handle->socket == INVALID_SOCKET) { - sock = socket(domain, SOCK_STREAM, 0); + SOCKET sock = socket(domain, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { uv__set_sys_error(handle->loop, WSAGetLastError()); return -1; diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 1964401e44..81523c3237 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -163,7 +163,6 @@ static int uv__bind(uv_udp_t* handle, int addrsize, unsigned int flags) { int r; - SOCKET sock; DWORD no = 0, yes = 1; if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) { @@ -173,7 +172,7 @@ static int uv__bind(uv_udp_t* handle, } if (handle->socket == INVALID_SOCKET) { - sock = socket(domain, SOCK_DGRAM, 0); + SOCKET sock = socket(domain, SOCK_DGRAM, 0); if (sock == INVALID_SOCKET) { uv__set_sys_error(handle->loop, WSAGetLastError()); return -1; @@ -192,14 +191,14 @@ static int uv__bind(uv_udp_t* handle, /* TODO: how to handle errors? This may fail if there is no ipv4 stack */ /* available, or when run on XP/2003 which have no support for dualstack */ /* sockets. For now we're silently ignoring the error. */ - setsockopt(sock, + setsockopt(handle->socket, IPPROTO_IPV6, IPV6_V6ONLY, (char*) &no, sizeof no); } - r = setsockopt(sock, + r = setsockopt(handle->socket, SOL_SOCKET, SO_REUSEADDR, (char*) &yes, diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c index 9f731ecfad..68b14fb0d0 100644 --- a/deps/uv/src/win/util.c +++ b/deps/uv/src/win/util.c @@ -385,8 +385,70 @@ uv_err_t uv_resident_set_memory(size_t* rss) { uv_err_t uv_uptime(double* uptime) { - *uptime = (double)GetTickCount()/1000.0; - return uv_ok_; + uv_err_t err; + PERF_DATA_BLOCK *dataBlock = NULL; + PERF_OBJECT_TYPE *objType; + PERF_COUNTER_DEFINITION *counterDef; + PERF_COUNTER_DEFINITION *counterDefUptime = NULL; + DWORD dataSize = 4096; + DWORD getSize; + LONG lError = ERROR_MORE_DATA; + uint64_t upsec; + unsigned int i; + BYTE *counterData; + + *uptime = 0; + + while (lError == ERROR_MORE_DATA) { + if (dataBlock) { + free(dataBlock); + } + dataBlock = (PERF_DATA_BLOCK*)malloc(dataSize); + if (!dataBlock) { + uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); + } + getSize = dataSize; + + lError = RegQueryValueExW(HKEY_PERFORMANCE_DATA, "2", NULL, NULL, + (BYTE*)dataBlock, &getSize); + if (lError != ERROR_SUCCESS && getSize > 0) { + if (wcsncmp(dataBlock->Signature, "PERF", 4) == 0) { + break; + } + } else if (lError != ERROR_SUCCESS && lError != ERROR_MORE_DATA) { + err = uv__new_sys_error(GetLastError()); + goto done; + } + + dataSize += 1024; + } + + RegCloseKey(HKEY_PERFORMANCE_DATA); + + objType = (PERF_OBJECT_TYPE*)((BYTE*)dataBlock + dataBlock->HeaderLength); + counterDef = (PERF_COUNTER_DEFINITION*)((BYTE*)objType + objType->HeaderLength); + + for (i = 0; i < objType->NumCounters; ++i) { + if (counterDef->CounterNameTitleIndex == 674) { + counterDefUptime = counterDef; + break; + } + counterDef = (PERF_COUNTER_DEFINITION*)((BYTE*)counterDef + counterDef->ByteLength); + } + + counterData = (BYTE*)objType + objType->DefinitionLength; + counterData += counterDefUptime->CounterOffset; + + upsec = *((uint64_t*)counterData); + *uptime = ((objType->PerfTime.QuadPart - upsec) / objType->PerfFreq.QuadPart); + err = uv_ok_; + +done: + if (dataBlock) { + free(dataBlock); + } + + return err; } diff --git a/deps/uv/test/test-ipc-send-recv.c b/deps/uv/test/test-ipc-send-recv.c index 96b47f0710..970bf1effe 100644 --- a/deps/uv/test/test-ipc-send-recv.c +++ b/deps/uv/test/test-ipc-send-recv.c @@ -197,6 +197,7 @@ int ipc_send_recv_helper(void) { uv_pipe_open(&ctx.channel, 0); ASSERT(uv_is_readable((uv_stream_t*)&ctx.channel)); ASSERT(uv_is_writable((uv_stream_t*)&ctx.channel)); + ASSERT(!uv_is_closing((uv_handle_t*)&ctx.channel)); r = uv_read2_start((uv_stream_t*)&ctx.channel, alloc_cb, read2_cb); ASSERT(r == 0); diff --git a/deps/uv/test/test-ipc.c b/deps/uv/test/test-ipc.c index d70d5b23a3..1ea0e7f963 100644 --- a/deps/uv/test/test-ipc.c +++ b/deps/uv/test/test-ipc.c @@ -535,6 +535,7 @@ int ipc_helper(int listen_after_write) { ASSERT(uv_is_readable((uv_stream_t*) &channel)); ASSERT(uv_is_writable((uv_stream_t*) &channel)); + ASSERT(!uv_is_closing((uv_handle_t*) &channel)); r = uv_tcp_init(uv_default_loop(), &tcp_server); ASSERT(r == 0); @@ -583,6 +584,7 @@ int ipc_helper_tcp_connection() { ASSERT(uv_is_readable((uv_stream_t*)&channel)); ASSERT(uv_is_writable((uv_stream_t*)&channel)); + ASSERT(!uv_is_closing((uv_handle_t*)&channel)); r = uv_tcp_init(uv_default_loop(), &tcp_server); ASSERT(r == 0); diff --git a/deps/uv/test/test-ping-pong.c b/deps/uv/test/test-ping-pong.c index 245a6014ec..1bdcc3bc24 100644 --- a/deps/uv/test/test-ping-pong.c +++ b/deps/uv/test/test-ping-pong.c @@ -140,6 +140,7 @@ static void pinger_on_connect(uv_connect_t *req, int status) { ASSERT(uv_is_readable(req->handle)); ASSERT(uv_is_writable(req->handle)); + ASSERT(!uv_is_closing((uv_handle_t *)req->handle)); pinger_write_ping(pinger); diff --git a/deps/uv/test/test-pipe-connect-error.c b/deps/uv/test/test-pipe-connect-error.c index 4a6c5110fa..cc06d4293a 100644 --- a/deps/uv/test/test-pipe-connect-error.c +++ b/deps/uv/test/test-pipe-connect-error.c @@ -93,4 +93,4 @@ TEST_IMPL(pipe_connect_to_file) { ASSERT(connect_cb_called == 1); return 0; -}
\ No newline at end of file +} diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c index 1e177296d8..fe7b306013 100644 --- a/deps/uv/test/test-platform-output.c +++ b/deps/uv/test/test-platform-output.c @@ -44,6 +44,7 @@ TEST_IMPL(platform_output) { err = uv_uptime(&uptime); ASSERT(UV_OK == err.code); + ASSERT(uptime > 0); fprintf(stderr, "uv_uptime: %f\n", uptime); err = uv_cpu_info(&cpus, &count); diff --git a/deps/uv/test/test-shutdown-close.c b/deps/uv/test/test-shutdown-close.c index 864f7cecae..eabbefc606 100644 --- a/deps/uv/test/test-shutdown-close.c +++ b/deps/uv/test/test-shutdown-close.c @@ -57,7 +57,9 @@ static void connect_cb(uv_connect_t* req, int status) { r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb); ASSERT(r == 0); + ASSERT(!uv_is_closing((uv_handle_t*) req->handle)); uv_close((uv_handle_t*) req->handle, close_cb); + ASSERT(uv_is_closing((uv_handle_t*) req->handle)); connect_cb_called++; } diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 0d6e3b9a18..d03ea56898 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -180,28 +180,34 @@ 'include/uv-private/ev.h', 'include/uv-private/ngx-queue.h', 'include/uv-private/uv-unix.h', - 'src/unix/core.c', - 'src/unix/uv-eio.c', - 'src/unix/uv-eio.h', - 'src/unix/fs.c', - 'src/unix/udp.c', - 'src/unix/tcp.c', - 'src/unix/pipe.c', - 'src/unix/tty.c', - 'src/unix/stream.c', + 'src/unix/async.c', 'src/unix/cares.c', + 'src/unix/check.c', + 'src/unix/core.c', 'src/unix/dl.c', - 'src/unix/error.c', - 'src/unix/thread.c', - 'src/unix/process.c', - 'src/unix/internal.h', 'src/unix/eio/ecb.h', 'src/unix/eio/eio.c', 'src/unix/eio/xthread.h', + 'src/unix/error.c', 'src/unix/ev/ev.c', 'src/unix/ev/ev_vars.h', 'src/unix/ev/ev_wrap.h', 'src/unix/ev/event.h', + 'src/unix/fs.c', + 'src/unix/idle.c', + 'src/unix/internal.h', + 'src/unix/loop.c', + 'src/unix/pipe.c', + 'src/unix/prepare.c', + 'src/unix/process.c', + 'src/unix/stream.c', + 'src/unix/tcp.c', + 'src/unix/thread.c', + 'src/unix/timer.c', + 'src/unix/tty.c', + 'src/unix/udp.c', + 'src/unix/uv-eio.c', + 'src/unix/uv-eio.h', ], 'include_dirs': [ 'src/unix/ev', ], 'libraries': [ '-lm' ] @@ -215,6 +221,7 @@ ], }, 'defines': [ + '_DARWIN_USE_64_BIT_INODE=1', 'EV_CONFIG_H="config_darwin.h"', 'EIO_CONFIG_H="config_darwin.h"', ] @@ -224,6 +231,8 @@ 'sources': [ 'src/unix/linux/core.c', 'src/unix/linux/inotify.c', + 'src/unix/linux/syscalls.c', + 'src/unix/linux/syscalls.h', ], 'defines': [ 'EV_CONFIG_H="config_linux.h"', |