diff --git a/deps/uv/include/uv-private/uv-unix.h b/deps/uv/include/uv-private/uv-unix.h index 1c33684aab..46b549fbe9 100644 --- a/deps/uv/include/uv-private/uv-unix.h +++ b/deps/uv/include/uv-private/uv-unix.h @@ -36,6 +36,11 @@ #include #include +#if __sun +# include +# include +#endif + /* Note: May be cast to struct iovec. See writev(2). */ typedef struct { char* base; @@ -52,6 +57,14 @@ typedef uid_t uv_uid_t; typedef void* uv_lib_t; #define UV_DYNAMIC /* empty */ +#if defined(PORT_SOURCE_FILE) +# define UV_LOOP_PRIVATE_PLATFORM_FIELDS \ + ev_io fs_event_watcher; \ + int fs_fd; +#else +# define UV_LOOP_PRIVATE_PLATFORM_FIELDS +#endif + #define UV_LOOP_PRIVATE_FIELDS \ ares_channel channel; \ /* \ @@ -60,7 +73,8 @@ typedef void* uv_lib_t; * definition of ares_timeout(). \ */ \ ev_timer timer; \ - struct ev_loop* ev; + struct ev_loop* ev; \ + UV_LOOP_PRIVATE_PLATFORM_FIELDS #define UV_REQ_BUFSML_SIZE (4) @@ -206,12 +220,8 @@ typedef void* uv_lib_t; #elif defined(__sun) -#include -#include - #ifdef PORT_SOURCE_FILE # define UV_FS_EVENT_PRIVATE_FIELDS \ - ev_io event_watcher; \ uv_fs_event_cb cb; \ file_obj_t fo; #else /* !PORT_SOURCE_FILE */ diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 28a82a3aa9..d9e43ba07e 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -19,7 +19,7 @@ */ #include "uv.h" -#include "unix/internal.h" +#include "internal.h" #include /* NULL */ #include /* printf */ @@ -151,6 +151,9 @@ uv_loop_t* uv_loop_new(void) { uv_loop_t* loop = calloc(1, sizeof(uv_loop_t)); loop->ev = ev_loop_new(0); ev_set_userdata(loop->ev, loop); +#if HAVE_PORTS_FS + loop->fs_fd = -1; +#endif return loop; } @@ -163,6 +166,12 @@ void uv_loop_delete(uv_loop_t* loop) { memset(loop, 0, sizeof *loop); #endif +#if HAVE_PORTS_FS + if (loop->fs_fd != -1) { + uv__close(loop->fs_fd); + } +#endif + if (loop == default_loop_ptr) default_loop_ptr = NULL; else @@ -182,6 +191,9 @@ uv_loop_t* uv_default_loop(void) { default_loop_struct.ev = ev_default_loop(EVBACKEND_KQUEUE); #else default_loop_struct.ev = ev_default_loop(EVFLAG_AUTO); +#endif +#if HAVE_PORTS_FS + default_loop_struct.fs_fd = -1; #endif ev_set_userdata(default_loop_struct.ev, default_loop_ptr); } diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c index dbdad3ce7b..e4f48c7a57 100644 --- a/deps/uv/src/unix/sunos.c +++ b/deps/uv/src/unix/sunos.c @@ -36,6 +36,11 @@ #if HAVE_PORTS_FS # include # include + +# define PORT_FIRED 0x69 +# define PORT_UNUSED 0x0 +# define PORT_LOADED 0x99 +# define PORT_DELETED -1 #endif @@ -90,36 +95,41 @@ void uv_loadavg(double avg[3]) { #if HAVE_PORTS_FS static void uv__fs_event_rearm(uv_fs_event_t *handle) { - if (port_associate(handle->fd, + if (handle->fd == -1) + return; + + if (port_associate(handle->loop->fs_fd, PORT_SOURCE_FILE, (uintptr_t) &handle->fo, FILE_ATTRIB | FILE_MODIFIED, - NULL) == -1) { + handle) == -1) { uv__set_sys_error(handle->loop, errno); } + handle->fd = PORT_LOADED; } static void uv__fs_event_read(EV_P_ ev_io* w, int revents) { uv_fs_event_t *handle; + uv_loop_t *loop_; timespec_t timeout; port_event_t pe; int events; int r; - handle = container_of(w, uv_fs_event_t, event_watcher); + loop_ = container_of(w, uv_loop_t, fs_event_watcher); do { /* TODO use port_getn() */ do { memset(&timeout, 0, sizeof timeout); - r = port_get(handle->fd, &pe, &timeout); + r = port_get(loop_->fs_fd, &pe, &timeout); } while (r == -1 && errno == EINTR); if (r == -1 && errno == ETIME) break; - + handle = (uv_fs_event_t *)pe.portev_user; assert((r == 0) && "unexpected port_get() error"); events = 0; @@ -128,12 +138,12 @@ static void uv__fs_event_read(EV_P_ ev_io* w, int revents) { if (pe.portev_events & ~(FILE_ATTRIB | FILE_MODIFIED)) events |= UV_RENAME; assert(events != 0); - + handle->fd = PORT_FIRED; handle->cb(handle, NULL, events, 0); } - while (handle->fd != -1); + while (handle->fd != PORT_DELETED); - if (handle->fd != -1) + if (handle->fd != PORT_DELETED) uv__fs_event_rearm(handle); } @@ -144,39 +154,45 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_cb cb, int flags) { int portfd; + int first_run = 0; loop->counters.fs_event_init++; /* We don't support any flags yet. */ assert(!flags); - - if ((portfd = port_create()) == -1) { - uv__set_sys_error(loop, errno); - return -1; + if (loop->fs_fd == -1) { + if ((portfd = port_create()) == -1) { + uv__set_sys_error(loop, errno); + return -1; + } + loop->fs_fd = portfd; + first_run = 1; } uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); handle->filename = strdup(filename); - handle->fd = portfd; + handle->fd = PORT_UNUSED; handle->cb = cb; memset(&handle->fo, 0, sizeof handle->fo); handle->fo.fo_name = handle->filename; uv__fs_event_rearm(handle); - ev_io_init(&handle->event_watcher, uv__fs_event_read, portfd, EV_READ); - ev_io_start(loop->ev, &handle->event_watcher); - ev_unref(loop->ev); + if (first_run) { + ev_io_init(&loop->fs_event_watcher, uv__fs_event_read, portfd, EV_READ); + ev_io_start(loop->ev, &loop->fs_event_watcher); + ev_unref(loop->ev); + } return 0; } void uv__fs_event_destroy(uv_fs_event_t* handle) { - ev_ref(handle->loop->ev); - ev_io_stop(handle->loop->ev, &handle->event_watcher); - uv__close(handle->fd); - handle->fd = -1; + if (handle->fd == PORT_FIRED) { + port_dissociate(handle->loop->fs_fd, PORT_SOURCE_FILE, (uintptr_t)&handle->fo); + } + handle->fd = PORT_DELETED; free(handle->filename); handle->filename = NULL; handle->fo.fo_name = NULL; diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 9e8a99515b..68bb210c9a 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -248,10 +248,8 @@ void fs__open(uv_fs_t* req, const wchar_t* path, int flags, int mode) { goto end; } - /* Figure out whether path is a file or a directory. */ - if (GetFileAttributesW(path) & FILE_ATTRIBUTE_DIRECTORY) { - attributes |= FILE_FLAG_BACKUP_SEMANTICS; - } + /* Setting this flag makes it possible to open a directory. */ + attributes |= FILE_FLAG_BACKUP_SEMANTICS; file = CreateFileW(path, access,