Browse Source

deps: upgrade libuv to 1f9bd99

v0.9.2-release
Ben Noordhuis 12 years ago
parent
commit
dd1b947706
  1. 3
      deps/uv/README.md
  2. 3
      deps/uv/config-unix.mk
  3. 8
      deps/uv/gyp_uv
  4. 13
      deps/uv/include/uv-private/uv-darwin.h
  5. 1
      deps/uv/include/uv-private/uv-unix.h
  6. 1
      deps/uv/include/uv.h
  7. 2
      deps/uv/src/unix/async.c
  8. 2
      deps/uv/src/unix/core.c
  9. 124
      deps/uv/src/unix/darwin.c
  10. 225
      deps/uv/src/unix/fsevents.c
  11. 40
      deps/uv/src/unix/internal.h
  12. 25
      deps/uv/src/unix/kqueue.c
  13. 6
      deps/uv/src/unix/loop.c
  14. 244
      deps/uv/src/unix/netbsd.c
  15. 4
      deps/uv/src/unix/process.c
  16. 135
      deps/uv/src/unix/stream.c
  17. 6
      deps/uv/src/unix/tcp.c
  18. 9
      deps/uv/src/uv-common.c
  19. 1
      deps/uv/src/win/error.c
  20. 5
      deps/uv/src/win/internal.h
  21. 43
      deps/uv/src/win/pipe.c
  22. 3
      deps/uv/src/win/process-stdio.c
  23. 51
      deps/uv/src/win/stream.c
  24. 39
      deps/uv/src/win/tcp.c
  25. 35
      deps/uv/src/win/tty.c
  26. 3
      deps/uv/test/test-fs-event.c
  27. 14
      deps/uv/uv.gyp

3
deps/uv/README.md

@ -77,6 +77,9 @@ Macintosh users run
./gyp_uv -f xcode
xcodebuild -project uv.xcodeproj -configuration Release -target All
Note for Linux users: compile your project with `-D_GNU_SOURCE` when you
include `uv.h`. GYP builds take care of that automatically. If you use
autotools, add a `AC_GNU_SOURCE` declaration to your `configure.ac`.
## Supported Platforms

3
deps/uv/config-unix.mk

@ -60,6 +60,7 @@ CPPFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
LINKFLAGS+=-framework CoreServices
OBJS += src/unix/darwin.o
OBJS += src/unix/kqueue.o
OBJS += src/unix/fsevents.o
endif
ifeq (Linux,$(uname_S))
@ -91,7 +92,7 @@ endif
ifeq (NetBSD,$(uname_S))
EV_CONFIG=config_netbsd.h
EIO_CONFIG=config_netbsd.h
LINKFLAGS+=
LINKFLAGS+=-lkvm
OBJS += src/unix/netbsd.o
OBJS += src/unix/kqueue.o
endif

8
deps/uv/gyp_uv

@ -60,9 +60,11 @@ if __name__ == '__main__':
# There's a bug with windows which doesn't allow this feature.
if sys.platform != 'win32':
args.extend(['--generator-output', output_dir])
args.extend(['-Goutput_dir=' + output_dir])
args.extend('-f make'.split())
if '-f' not in args:
args.extend('-f make'.split())
if 'ninja' not in args:
args.extend(['-Goutput_dir=' + output_dir])
args.extend(['--generator-output', output_dir])
(major, minor), is_clang = compiler_version()
args.append('-Dgcc_version=%d' % (10 * major + minor))
args.append('-Dclang=%d' % int(is_clang))

13
deps/uv/include/uv-private/uv-darwin.h

@ -29,10 +29,23 @@
# define UV_PLATFORM_SEM_T semaphore_t
#endif
#define UV_PLATFORM_LOOP_FIELDS \
uv_thread_t cf_thread; \
void* cf_cb; \
void* cf_loop; \
uv_mutex_t cf_mutex; \
uv_sem_t cf_sem; \
ngx_queue_t cf_signals; \
#define UV_PLATFORM_FS_EVENT_FIELDS \
ev_io event_watcher; \
int fflags; \
int fd; \
void* cf_eventstream; \
uv_async_t* cf_cb; \
ngx_queue_t cf_events; \
uv_sem_t cf_sem; \
uv_mutex_t cf_mutex; \
#define UV_STREAM_PRIVATE_PLATFORM_FIELDS \
void* select; \

1
deps/uv/include/uv-private/uv-unix.h

@ -137,6 +137,7 @@ typedef struct {
uint64_t time; \
void* signal_ctx; \
uv_signal_t child_watcher; \
int emfile_fd; \
UV_PLATFORM_LOOP_FIELDS \
#define UV_REQ_TYPE_PRIVATE /* empty */

1
deps/uv/include/uv.h

@ -1789,6 +1789,7 @@ UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void));
UV_EXTERN int uv_thread_create(uv_thread_t *tid,
void (*entry)(void *arg), void *arg);
UV_EXTERN unsigned long uv_thread_self(void);
UV_EXTERN int uv_thread_join(uv_thread_t *tid);
/* the presence of these unions force similar struct layout */

2
deps/uv/src/unix/async.c

@ -31,7 +31,7 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* handle, int events);
__attribute__((always_inline))
inline static int uv__async_make_pending(volatile sig_atomic_t* ptr) {
static int uv__async_make_pending(volatile sig_atomic_t* ptr) {
/* Do a cheap read first. */
if (*ptr)
return 1;

2
deps/uv/src/unix/core.c

@ -463,7 +463,7 @@ int uv__accept(int sockfd) {
while (1) {
#if __linux__
static __read_mostly int no_accept4;
static int no_accept4;
if (no_accept4)
goto skip;

124
deps/uv/src/unix/darwin.c

@ -43,13 +43,137 @@
static char *process_title;
/* Forward declarations */
void uv__cf_loop_runner(void* arg);
void uv__cf_loop_cb(void* arg);
typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
struct uv__cf_loop_signal_s {
void* arg;
cf_loop_signal_cb cb;
ngx_queue_t member;
};
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
CFRunLoopSourceContext ctx;
int r;
loop->cf_loop = NULL;
if ((r = uv_mutex_init(&loop->cf_mutex)))
return r;
if ((r = uv_sem_init(&loop->cf_sem, 0)))
return r;
ngx_queue_init(&loop->cf_signals);
memset(&ctx, 0, sizeof(ctx));
ctx.info = loop;
ctx.perform = uv__cf_loop_cb;
loop->cf_cb = CFRunLoopSourceCreate(NULL, 0, &ctx);
if ((r = uv_thread_create(&loop->cf_thread, uv__cf_loop_runner, loop)))
return r;
/* Synchronize threads */
uv_sem_wait(&loop->cf_sem);
assert(((volatile CFRunLoopRef) loop->cf_loop) != NULL);
return 0;
}
void uv__platform_loop_delete(uv_loop_t* loop) {
ngx_queue_t* item;
uv__cf_loop_signal_t* s;
assert(loop->cf_loop != NULL);
CFRunLoopStop(loop->cf_loop);
uv_thread_join(&loop->cf_thread);
loop->cf_loop = NULL;
uv_sem_destroy(&loop->cf_sem);
uv_mutex_destroy(&loop->cf_mutex);
/* Free any remaining data */
while (!ngx_queue_empty(&loop->cf_signals)) {
item = ngx_queue_head(&loop->cf_signals);
s = ngx_queue_data(item, uv__cf_loop_signal_t, member);
ngx_queue_remove(item);
free(s);
}
}
void uv__cf_loop_runner(void* arg) {
uv_loop_t* loop;
loop = arg;
/* Get thread's loop */
*((volatile CFRunLoopRef*)&loop->cf_loop) = CFRunLoopGetCurrent();
CFRunLoopAddSource(loop->cf_loop,
loop->cf_cb,
kCFRunLoopDefaultMode);
uv_sem_post(&loop->cf_sem);
CFRunLoopRun();
CFRunLoopRemoveSource(loop->cf_loop,
loop->cf_cb,
kCFRunLoopDefaultMode);
}
void uv__cf_loop_cb(void* arg) {
uv_loop_t* loop;
ngx_queue_t* item;
ngx_queue_t split_head;
uv__cf_loop_signal_t* s;
loop = arg;
uv_mutex_lock(&loop->cf_mutex);
ngx_queue_init(&split_head);
if (!ngx_queue_empty(&loop->cf_signals)) {
ngx_queue_t* split_pos = ngx_queue_next(&loop->cf_signals);
ngx_queue_split(&loop->cf_signals, split_pos, &split_head);
}
uv_mutex_unlock(&loop->cf_mutex);
while (!ngx_queue_empty(&split_head)) {
item = ngx_queue_head(&split_head);
s = ngx_queue_data(item, uv__cf_loop_signal_t, member);
s->cb(s->arg);
ngx_queue_remove(item);
free(s);
}
}
void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg) {
uv__cf_loop_signal_t* item;
item = malloc(sizeof(*item));
/* XXX: Fail */
if (item == NULL)
abort();
item->arg = arg;
item->cb = cb;
uv_mutex_lock(&loop->cf_mutex);
ngx_queue_insert_tail(&loop->cf_signals, &item->member);
uv_mutex_unlock(&loop->cf_mutex);
assert(loop->cf_loop != NULL);
CFRunLoopSourceSignal(loop->cf_cb);
CFRunLoopWakeUp(loop->cf_loop);
}

225
deps/uv/src/unix/fsevents.c

@ -0,0 +1,225 @@
/* 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>
#include <stdlib.h>
#include <CoreServices/CoreServices.h>
typedef struct uv__fsevents_event_s uv__fsevents_event_t;
struct uv__fsevents_event_s {
int events;
ngx_queue_t member;
char path[1];
};
#define UV__FSEVENTS_WALK(handle, block) \
{ \
ngx_queue_t* curr; \
ngx_queue_t split_head; \
uv__fsevents_event_t* event; \
uv_mutex_lock(&(handle)->cf_mutex); \
ngx_queue_init(&split_head); \
if (!ngx_queue_empty(&(handle)->cf_events)) { \
ngx_queue_t* split_pos = ngx_queue_next(&(handle)->cf_events); \
ngx_queue_split(&(handle)->cf_events, split_pos, &split_head); \
} \
uv_mutex_unlock(&(handle)->cf_mutex); \
while (!ngx_queue_empty(&split_head)) { \
curr = ngx_queue_head(&split_head); \
/* Invoke callback */ \
event = ngx_queue_data(curr, uv__fsevents_event_t, member); \
ngx_queue_remove(curr); \
/* Invoke block code, but only if handle wasn't closed */ \
if (((handle)->flags & (UV_CLOSING | UV_CLOSED)) == 0) \
block \
/* Free allocated data */ \
free(event); \
} \
}
void uv__fsevents_cb(uv_async_t* cb, int status) {
uv_fs_event_t* handle;
handle = cb->data;
UV__FSEVENTS_WALK(handle, {
if (handle->fd != -1)
handle->cb(handle, event->path, event->events, 0);
})
if ((handle->flags & (UV_CLOSING | UV_CLOSED)) == 0 && handle->fd == -1)
uv__fsevents_close(handle);
}
void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
void* info,
size_t numEvents,
void* eventPaths,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[]) {
size_t i;
int len;
char** paths;
uv_fs_event_t* handle;
uv__fsevents_event_t* event;
ngx_queue_t add_list;
handle = info;
paths = eventPaths;
ngx_queue_init(&add_list);
for (i = 0; i < numEvents; i++) {
/* Ignore system events */
if (eventFlags[i] & (kFSEventStreamEventFlagUserDropped |
kFSEventStreamEventFlagKernelDropped |
kFSEventStreamEventFlagEventIdsWrapped |
kFSEventStreamEventFlagHistoryDone |
kFSEventStreamEventFlagMount |
kFSEventStreamEventFlagUnmount)) {
continue;
}
/* TODO: Report errors */
len = strlen(paths[i]);
event = malloc(sizeof(*event) + len);
if (event == NULL)
break;
memcpy(event->path, paths[i], len + 1);
if (eventFlags[i] & kFSEventStreamEventFlagItemModified)
event->events = UV_CHANGE;
else
event->events = UV_RENAME;
ngx_queue_insert_tail(&add_list, &event->member);
}
uv_mutex_lock(&handle->cf_mutex);
ngx_queue_add(&handle->cf_events, &add_list);
uv_mutex_unlock(&handle->cf_mutex);
uv_async_send(handle->cf_cb);
}
void uv__fsevents_schedule(void* arg) {
uv_fs_event_t* handle;
handle = arg;
FSEventStreamScheduleWithRunLoop(handle->cf_eventstream,
handle->loop->cf_loop,
kCFRunLoopDefaultMode);
FSEventStreamStart(handle->cf_eventstream);
uv_sem_post(&handle->cf_sem);
}
int uv__fsevents_init(uv_fs_event_t* handle) {
FSEventStreamContext ctx;
FSEventStreamRef ref;
CFStringRef path;
CFArrayRef paths;
CFAbsoluteTime latency;
FSEventStreamCreateFlags flags;
/* Initialize context */
ctx.version = 0;
ctx.info = handle;
ctx.retain = NULL;
ctx.release = NULL;
ctx.copyDescription = NULL;
/* Initialize paths array */
path = CFStringCreateWithCString(NULL,
handle->filename,
CFStringGetSystemEncoding());
paths = CFArrayCreate(NULL, (const void**)&path, 1, NULL);
latency = 0.15;
/* Set appropriate flags */
flags = kFSEventStreamCreateFlagFileEvents;
ref = FSEventStreamCreate(NULL,
&uv__fsevents_event_cb,
&ctx,
paths,
kFSEventStreamEventIdSinceNow,
latency,
flags);
handle->cf_eventstream = ref;
/*
* Events will occur in other thread.
* Initialize callback for getting them back into event loop's thread
*/
handle->cf_cb = malloc(sizeof(*handle->cf_cb));
if (handle->cf_cb == NULL)
return uv__set_sys_error(handle->loop, ENOMEM);
handle->cf_cb->data = handle;
uv_async_init(handle->loop, handle->cf_cb, uv__fsevents_cb);
handle->cf_cb->flags |= UV__HANDLE_INTERNAL;
uv_unref((uv_handle_t*) handle->cf_cb);
uv_mutex_init(&handle->cf_mutex);
uv_sem_init(&handle->cf_sem, 0);
ngx_queue_init(&handle->cf_events);
uv__cf_loop_signal(handle->loop, uv__fsevents_schedule, handle);
return 0;
}
int uv__fsevents_close(uv_fs_event_t* handle) {
if (handle->cf_eventstream == NULL)
return -1;
/* Ensure that event stream was scheduled */
uv_sem_wait(&handle->cf_sem);
/* Stop emitting events */
FSEventStreamStop(handle->cf_eventstream);
/* Release stream */
FSEventStreamInvalidate(handle->cf_eventstream);
FSEventStreamRelease(handle->cf_eventstream);
handle->cf_eventstream = NULL;
uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) free);
/* Free data in queue */
UV__FSEVENTS_WALK(handle, {
/* NOP */
})
uv_mutex_destroy(&handle->cf_mutex);
uv_sem_destroy(&handle->cf_sem);
return 0;
}

40
deps/uv/src/unix/internal.h

@ -28,12 +28,6 @@
#include <assert.h>
#include <stdlib.h> /* abort */
#if defined(__GNUC__)
# define __read_mostly __attribute__((__section__(".data.read_mostly")))
#else
# define __read_mostly
#endif
#if defined(__STRICT_ANSI__)
# define inline __inline
#endif
@ -108,9 +102,9 @@ enum {
UV_LOOP_EIO_INITIALIZED = 1
};
inline static void uv__req_init(uv_loop_t* loop,
uv_req_t* req,
uv_req_type type) {
__attribute__((unused))
__attribute__((always_inline))
static void uv__req_init(uv_loop_t* loop, uv_req_t* req, uv_req_type type) {
req->type = type;
uv__req_register(loop, req);
}
@ -195,4 +189,32 @@ void uv__udp_finish_close(uv_udp_t* handle);
int uv__make_socketpair(int fds[2], int flags);
int uv__make_pipe(int fds[2], int flags);
#if defined(__APPLE__)
typedef void (*cf_loop_signal_cb)(void*);
void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg);
int uv__fsevents_init(uv_fs_event_t* handle);
int uv__fsevents_close(uv_fs_event_t* handle);
/* OSX < 10.7 has no file events, polyfill them */
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070
static const int kFSEventStreamCreateFlagFileEvents = 0x00000010;
static const int kFSEventStreamEventFlagItemCreated = 0x00000100;
static const int kFSEventStreamEventFlagItemRemoved = 0x00000200;
static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400;
static const int kFSEventStreamEventFlagItemRenamed = 0x00000800;
static const int kFSEventStreamEventFlagItemModified = 0x00001000;
static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000;
static const int kFSEventStreamEventFlagItemChangeOwner = 0x00004000;
static const int kFSEventStreamEventFlagItemXattrMod = 0x00008000;
static const int kFSEventStreamEventFlagItemIsFile = 0x00010000;
static const int kFSEventStreamEventFlagItemIsDir = 0x00020000;
static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
#endif /* __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070 */
#endif /* defined(__APPLE__) */
#endif /* UV_UNIX_INTERNAL_H_ */

25
deps/uv/src/unix/kqueue.c

@ -89,6 +89,9 @@ int uv_fs_event_init(uv_loop_t* loop,
uv_fs_event_cb cb,
int flags) {
int fd;
#if defined(__APPLE__)
struct stat statbuf;
#endif /* defined(__APPLE__) */
/* We don't support any flags yet. */
assert(!flags);
@ -105,6 +108,22 @@ int uv_fs_event_init(uv_loop_t* loop,
handle->fflags = 0;
handle->cb = cb;
handle->fd = fd;
#if defined(__APPLE__)
/* Nullify field to perform checks later */
handle->cf_eventstream = NULL;
if (fstat(fd, &statbuf))
goto fallback;
/* FSEvents works only with directories */
if (!(statbuf.st_mode & S_IFDIR))
goto fallback;
return uv__fsevents_init(handle);
fallback:
#endif /* defined(__APPLE__) */
uv__fs_event_start(handle);
return 0;
@ -112,7 +131,13 @@ int uv_fs_event_init(uv_loop_t* loop,
void uv__fs_event_close(uv_fs_event_t* handle) {
#if defined(__APPLE__)
if (uv__fsevents_close(handle))
uv__fs_event_stop(handle);
#else
uv__fs_event_stop(handle);
#endif /* defined(__APPLE__) */
uv__handle_stop(handle);
free(handle->filename);
close(handle->fd);

6
deps/uv/src/unix/loop.c

@ -51,6 +51,7 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) {
loop->time = uv_hrtime() / 1000000;
loop->async_pipefd[0] = -1;
loop->async_pipefd[1] = -1;
loop->emfile_fd = -1;
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);
@ -73,4 +74,9 @@ void uv__loop_delete(uv_loop_t* loop) {
uv__platform_loop_delete(loop);
uv__signal_unregister(loop);
ev_loop_destroy(loop->ev);
if (loop->emfile_fd != -1) {
close(loop->emfile_fd);
loop->emfile_fd = -1;
}
}

244
deps/uv/src/unix/netbsd.c

@ -19,11 +19,21 @@
*/
#include "uv.h"
#include "internal.h"
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <kvm.h>
#include <paths.h>
#include <ifaddrs.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <fcntl.h>
#include <net/if.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/sysctl.h>
@ -34,6 +44,8 @@
#undef NANOSEC
#define NANOSEC ((uint64_t) 1e9)
static char *process_title;
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
return 0;
@ -50,18 +62,20 @@ uint64_t uv_hrtime(void) {
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
}
void uv_loadavg(double avg[3]) {
struct loadavg info;
size_t size = sizeof(info);
int which[] = {CTL_VM, VM_LOADAVG};
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
if (sysctl(which, 2, &info, &size, NULL, 0) == -1) return;
avg[0] = (double) info.ldavg[0] / info.fscale;
avg[1] = (double) info.ldavg[1] / info.fscale;
avg[2] = (double) info.ldavg[2] / info.fscale;
}
int uv_exepath(char* buffer, size_t* size) {
int mib[4];
size_t cb;
@ -78,7 +92,7 @@ int uv_exepath(char* buffer, size_t* size) {
mib[3] = KERN_PROC_ARGV;
cb = *size;
if (sysctl(mib, 4, buffer, &cb, NULL, 0) < 0) {
if (sysctl(mib, 4, buffer, &cb, NULL, 0) == -1) {
*size = 0;
return -1;
}
@ -87,18 +101,20 @@ int uv_exepath(char* buffer, size_t* size) {
return 0;
}
uint64_t uv_get_free_memory(void) {
struct uvmexp info;
size_t size = sizeof(info);
int which[] = {CTL_VM, VM_UVMEXP};
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
if (sysctl(which, 2, &info, &size, NULL, 0) == -1) {
return -1;
}
return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
}
uint64_t uv_get_total_memory(void) {
#if defined(HW_PHYSMEM64)
uint64_t info;
@ -109,9 +125,229 @@ uint64_t uv_get_total_memory(void) {
#endif
size_t size = sizeof(info);
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
if (sysctl(which, 2, &info, &size, NULL, 0) == -1) {
return -1;
}
return (uint64_t) info;
}
char** uv_setup_args(int argc, char** argv) {
process_title = argc ? strdup(argv[0]) : NULL;
return argv;
}
uv_err_t uv_set_process_title(const char* title) {
if (process_title) free(process_title);
process_title = strdup(title);
setproctitle("%s", title);
return uv_ok_;
}
uv_err_t uv_get_process_title(char* buffer, size_t size) {
if (process_title) {
strncpy(buffer, process_title, size);
} else {
if (size > 0) {
buffer[0] = '\0';
}
}
return uv_ok_;
}
uv_err_t uv_resident_set_memory(size_t* rss) {
kvm_t *kd = NULL;
struct kinfo_proc2 *kinfo = NULL;
pid_t pid;
int nprocs;
int max_size = sizeof(struct kinfo_proc2);
int page_size;
page_size = getpagesize();
pid = getpid();
kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open");
if (kd == NULL) goto error;
kinfo = kvm_getproc2(kd, KERN_PROC_PID, pid, max_size, &nprocs);
if (kinfo == NULL) goto error;
*rss = kinfo->p_vm_rssize * page_size;
kvm_close(kd);
return uv_ok_;
error:
if (kd) kvm_close(kd);
return uv__new_sys_error(errno);
}
uv_err_t uv_uptime(double* uptime) {
time_t now;
struct timeval info;
size_t size = sizeof(info);
static int which[] = {CTL_KERN, KERN_BOOTTIME};
if (sysctl(which, 2, &info, &size, NULL, 0) == -1) {
return uv__new_sys_error(errno);
}
now = time(NULL);
*uptime = (double)(now - info.tv_sec);
return uv_ok_;
}
uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK);
unsigned int multiplier = ((uint64_t)1000L / ticks);
unsigned int cur = 0;
uv_cpu_info_t* cpu_info;
u_int64_t* cp_times;
char model[512];
u_int64_t cpuspeed;
int numcpus;
size_t size;
int i;
size = sizeof(model);
if (sysctlbyname("machdep.cpu_brand", &model, &size, NULL, 0) == -1 &&
sysctlbyname("hw.model", &model, &size, NULL, 0) == -1) {
return uv__new_sys_error(errno);
}
size = sizeof(numcpus);
if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0) == -1) {
return uv__new_sys_error(errno);
}
*count = numcpus;
/* Only i386 and amd64 have machdep.tsc_freq */
size = sizeof(cpuspeed);
if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &size, NULL, 0) == -1) {
cpuspeed = 0;
}
size = numcpus * CPUSTATES * sizeof(*cp_times);
cp_times = malloc(size);
if (cp_times == NULL) {
return uv__new_artificial_error(UV_ENOMEM);
}
if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0) == -1) {
return uv__new_sys_error(errno);
}
*cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
if (!(*cpu_infos)) {
free(cp_times);
free(*cpu_infos);
return uv__new_artificial_error(UV_ENOMEM);
}
for (i = 0; i < numcpus; i++) {
cpu_info = &(*cpu_infos)[i];
cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier;
cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier;
cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier;
cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier;
cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier;
cpu_info->model = strdup(model);
cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6);
cur += CPUSTATES;
}
free(cp_times);
return uv_ok_;
}
void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
int i;
for (i = 0; i < count; i++) {
free(cpu_infos[i].model);
}
free(cpu_infos);
}
uv_err_t uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
struct ifaddrs *addrs;
struct ifaddrs *ent;
uv_interface_address_t* address;
if (getifaddrs(&addrs) != 0) {
return uv__new_sys_error(errno);
}
*count = 0;
/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING) ||
(ent->ifa_addr == NULL) ||
(ent->ifa_addr->sa_family != PF_INET)) {
continue;
}
(*count)++;
}
*addresses = malloc(*count * sizeof(**addresses));
if (!(*addresses)) {
return uv__new_artificial_error(UV_ENOMEM);
}
address = *addresses;
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (!(ent->ifa_flags & IFF_UP && ent->ifa_flags & IFF_RUNNING)) {
continue;
}
if (ent->ifa_addr == NULL) {
continue;
}
if (ent->ifa_addr->sa_family != PF_INET) {
continue;
}
address->name = strdup(ent->ifa_name);
if (ent->ifa_addr->sa_family == AF_INET6) {
address->address.address6 = *((struct sockaddr_in6 *)ent->ifa_addr);
} else {
address->address.address4 = *((struct sockaddr_in *)ent->ifa_addr);
}
address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK) ? 1 : 0;
address++;
}
freeifaddrs(addrs);
return uv_ok_;
}
void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
int i;
for (i = 0; i < count; i++) {
free(addresses[i].name);
}
free(addresses);
}

4
deps/uv/src/unix/process.c

@ -117,7 +117,7 @@ static void uv__chld(uv_signal_t* handle, int signum) {
int uv__make_socketpair(int fds[2], int flags) {
#if __linux__
static __read_mostly int no_cloexec;
static int no_cloexec;
if (no_cloexec)
goto skip;
@ -153,7 +153,7 @@ skip:
int uv__make_pipe(int fds[2], int flags) {
#if __linux__
static __read_mostly int no_pipe2;
static int no_pipe2;
if (no_pipe2)
goto skip;

135
deps/uv/src/unix/stream.c

@ -62,6 +62,29 @@ static void uv__read(uv_stream_t* stream);
static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, int events);
/* Used by the accept() EMFILE party trick. */
static int uv__open_cloexec(const char* path, int flags) {
int fd;
#if defined(__linux__)
fd = open(path, flags | UV__O_CLOEXEC);
if (fd != -1)
return fd;
if (errno != EINVAL)
return -1;
/* O_CLOEXEC not supported. */
#endif
fd = open(path, flags);
if (fd != -1)
uv__cloexec(fd, 1);
return fd;
}
static size_t uv__buf_count(uv_buf_t bufs[], int bufcnt) {
size_t total = 0;
int i;
@ -90,6 +113,9 @@ void uv__stream_init(uv_loop_t* loop,
ngx_queue_init(&stream->write_completed_queue);
stream->write_queue_size = 0;
if (loop->emfile_fd == -1)
loop->emfile_fd = uv__open_cloexec("/", O_RDONLY);
#if defined(__APPLE__)
stream->select = NULL;
#endif /* defined(__APPLE_) */
@ -370,10 +396,56 @@ static void uv__next_accept(uv_idle_t* idle, int status) {
}
/* Implements a best effort approach to mitigating accept() EMFILE errors.
* We have a spare file descriptor stashed away that we close to get below
* the EMFILE limit. Next, we accept all pending connections and close them
* immediately to signal the clients that we're overloaded - and we are, but
* we still keep on trucking.
*
* There is one caveat: it's not reliable in a multi-threaded environment.
* The file descriptor limit is per process. Our party trick fails if another
* thread opens a file or creates a socket in the time window between us
* calling close() and accept().
*/
static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
int fd;
int r;
if (loop->emfile_fd == -1)
return -1;
close(loop->emfile_fd);
for (;;) {
fd = uv__accept(accept_fd);
if (fd != -1) {
close(fd);
continue;
}
if (errno == EINTR)
continue;
if (errno == EAGAIN || errno == EWOULDBLOCK)
r = 0;
else
r = -1;
loop->emfile_fd = uv__open_cloexec("/", O_RDONLY);
return r;
}
}
void uv__server_io(uv_loop_t* loop, uv__io_t* w, int events) {
static int use_emfile_trick = -1;
uv_stream_t* stream;
int fd;
uv_stream_t* stream = container_of(w, uv_stream_t, read_watcher);
int r;
stream = container_of(w, uv_stream_t, read_watcher);
assert(events == UV__IO_READ);
assert(!(stream->flags & UV_CLOSING));
@ -389,31 +461,48 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, int events) {
assert(stream->accepted_fd < 0);
fd = uv__accept(stream->fd);
if (fd < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
/* No problem. */
return;
} else if (errno == EMFILE) {
/* TODO special trick. unlock reserved socket, accept, close. */
return;
} else if (errno == ECONNABORTED) {
/* ignore */
if (fd == -1) {
switch (errno) {
#if EWOULDBLOCK != EAGAIN
case EWOULDBLOCK:
#endif
case EAGAIN:
return; /* Not an error. */
case ECONNABORTED:
continue; /* Ignore. */
case EMFILE:
case ENFILE:
if (use_emfile_trick == -1) {
const char* val = getenv("UV_ACCEPT_EMFILE_TRICK");
use_emfile_trick = (val == NULL || atoi(val) != 0);
}
if (use_emfile_trick) {
SAVE_ERRNO(r = uv__emfile_trick(loop, stream->fd));
if (r == 0)
continue;
}
/* Fall through. */
default:
uv__set_sys_error(loop, errno);
stream->connection_cb(stream, -1);
continue;
} else {
uv__set_sys_error(stream->loop, errno);
stream->connection_cb((uv_stream_t*)stream, -1);
}
} else {
stream->accepted_fd = fd;
stream->connection_cb(stream, 0);
if (stream->accepted_fd != -1 ||
(stream->type == UV_TCP && stream->flags == UV_TCP_SINGLE_ACCEPT)) {
/* The user hasn't yet accepted called uv_accept() */
uv__io_stop(stream->loop, &stream->read_watcher);
break;
}
}
stream->accepted_fd = fd;
stream->connection_cb(stream, 0);
if (stream->accepted_fd != -1 ||
(stream->type == UV_TCP && stream->flags == UV_TCP_SINGLE_ACCEPT)) {
/* The user hasn't yet accepted called uv_accept() */
uv__io_stop(loop, &stream->read_watcher);
break;
}
}
if (stream->fd != -1 &&

6
deps/uv/src/unix/tcp.c

@ -247,6 +247,7 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
if (uv_idle_init(tcp->loop, tcp->idle_handle))
abort();
tcp->idle_handle->flags |= UV__HANDLE_INTERNAL;
tcp->flags |= UV_TCP_SINGLE_ACCEPT;
@ -331,7 +332,10 @@ int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
}
#endif
#ifdef TCP_KEEPALIVE
/* Solaris/SmartOS, if you don't support keep-alive,
* then don't advertise it in your system headers...
*/
#if defined(TCP_KEEPALIVE) && !defined(__sun)
if (enable && setsockopt(handle->fd,
IPPROTO_TCP,
TCP_KEEPALIVE,

9
deps/uv/src/uv-common.c

@ -314,6 +314,15 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
}
unsigned long uv_thread_self(void) {
#ifdef _WIN32
return (unsigned long) GetCurrentThreadId();
#else
return (unsigned long) pthread_self();
#endif
}
void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
ngx_queue_t* q;
uv_handle_t* h;

1
deps/uv/src/win/error.c

@ -144,6 +144,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case ERROR_BAD_PIPE: return UV_EPIPE;
case ERROR_NO_DATA: return UV_EPIPE;
case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE;
case WSAESHUTDOWN: return UV_EPIPE;
case ERROR_PIPE_BUSY: return UV_EBUSY;
case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT;
case WSAETIMEDOUT: return UV_ETIMEDOUT;

5
deps/uv/src/win/internal.h

@ -52,9 +52,8 @@
#define UV_HANDLE_LISTENING 0x00000800
#define UV_HANDLE_CONNECTION 0x00001000
#define UV_HANDLE_CONNECTED 0x00002000
#define UV_HANDLE_EOF 0x00004000
#define UV_HANDLE_SHUTTING 0x00008000
#define UV_HANDLE_SHUT 0x00010000
#define UV_HANDLE_READABLE 0x00008000
#define UV_HANDLE_WRITABLE 0x00010000
#define UV_HANDLE_READ_PENDING 0x00020000
#define UV_HANDLE_SYNC_BYPASS_IOCP 0x00040000
#define UV_HANDLE_ZERO_READ 0x00080000

43
deps/uv/src/win/pipe.c

@ -114,7 +114,7 @@ static HANDLE open_named_pipe(WCHAR* name, DWORD* duplex_flags) {
FILE_FLAG_OVERLAPPED,
NULL);
if (pipeHandle != INVALID_HANDLE_VALUE) {
*duplex_flags = 0;
*duplex_flags = UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
return pipeHandle;
}
@ -133,7 +133,7 @@ static HANDLE open_named_pipe(WCHAR* name, DWORD* duplex_flags) {
NULL);
if (pipeHandle != INVALID_HANDLE_VALUE) {
*duplex_flags = UV_HANDLE_SHUTTING;
*duplex_flags = UV_HANDLE_READABLE;
return pipeHandle;
}
}
@ -148,7 +148,7 @@ static HANDLE open_named_pipe(WCHAR* name, DWORD* duplex_flags) {
NULL);
if (pipeHandle != INVALID_HANDLE_VALUE) {
*duplex_flags = UV_HANDLE_EOF;
*duplex_flags = UV_HANDLE_WRITABLE;
return pipeHandle;
}
}
@ -316,7 +316,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
/* Failure */
UNREGISTER_HANDLE_REQ(loop, handle, req);
handle->flags &= ~UV_HANDLE_SHUTTING;
handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */
if (req->cb) {
uv__set_sys_error(loop, pRtlNtStatusToDosError(nt_status));
req->cb(req, -1);
@ -343,7 +343,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
/* Failure. */
UNREGISTER_HANDLE_REQ(loop, handle, req);
handle->flags &= ~UV_HANDLE_SHUTTING;
handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */
if (req->cb) {
uv__set_sys_error(loop, GetLastError());
req->cb(req, -1);
@ -630,7 +630,7 @@ void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
}
if (handle->flags & UV_HANDLE_CONNECTION) {
handle->flags |= UV_HANDLE_SHUTTING;
handle->flags &= ~UV_HANDLE_WRITABLE;
eof_timer_destroy(handle);
}
@ -659,6 +659,7 @@ void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle) {
uv_want_endgame(loop, (uv_handle_t*) handle);
}
handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
uv__handle_closing(handle);
}
@ -746,6 +747,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
/* Initialize the client handle and copy the pipeHandle to the client */
uv_pipe_connection_init(pipe_client);
pipe_client->handle = req->pipeHandle;
pipe_client->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
/* Prepare the req to pick up a new connection */
server->pending_accepts = req->next_pending;
@ -964,16 +966,6 @@ static int uv_pipe_read_start_impl(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb, uv_read2_cb read2_cb) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv__set_artificial_error(loop, UV_EINVAL);
return -1;
}
if (handle->flags & UV_HANDLE_EOF) {
uv__set_artificial_error(loop, UV_EOF);
return -1;
}
handle->flags |= UV_HANDLE_READING;
INCREASE_ACTIVE_COUNT(loop, handle);
handle->read_cb = read_cb;
@ -1072,16 +1064,6 @@ static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
assert(handle->handle != INVALID_HANDLE_VALUE);
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv__set_artificial_error(loop, UV_EINVAL);
return -1;
}
if (handle->flags & UV_HANDLE_SHUTTING) {
uv__set_artificial_error(loop, UV_EOF);
return -1;
}
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_WRITE;
req->handle = (uv_stream_t*) handle;
@ -1253,7 +1235,7 @@ static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle,
/* so discard it. */
eof_timer_destroy(handle);
handle->flags |= UV_HANDLE_EOF;
handle->flags &= ~UV_HANDLE_READABLE;
uv_read_stop((uv_stream_t*) handle);
uv__set_artificial_error(loop, UV_EOF);
@ -1483,8 +1465,8 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_queue_non_overlapped_write(handle);
}
if (handle->write_reqs_pending == 0 &&
handle->flags & UV_HANDLE_SHUTTING) {
if (handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
@ -1548,7 +1530,7 @@ void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
/* Initialize and optionally start the eof timer. */
/* This makes no sense if we've already seen EOF. */
if (!(handle->flags & UV_HANDLE_EOF)) {
if (handle->flags & UV_HANDLE_READABLE) {
eof_timer_init(handle);
/* If reading start the timer right now. */
@ -1662,6 +1644,7 @@ void uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
uv_pipe_connection_init(pipe);
pipe->handle = os_handle;
pipe->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
if (pipe->ipc) {
assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));

3
deps/uv/src/win/process-stdio.c

@ -163,6 +163,9 @@ static uv_err_t uv__create_stdio_pipe_pair(uv_loop_t* loop,
}
}
/* The server end is now readable and writable. */
server_pipe->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
*child_pipe_ptr = child_pipe;
return uv_ok_;

51
deps/uv/src/win/stream.c

@ -55,6 +55,16 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb) {
if (handle->flags & UV_HANDLE_READING) {
uv__set_sys_error(handle->loop, UV_EALREADY);
return -1;
}
if (!(handle->flags & UV_HANDLE_READABLE)) {
uv__set_artificial_error(handle->loop, UV_ENOTCONN);
return -1;
}
switch (handle->type) {
case UV_TCP:
return uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb);
@ -71,6 +81,16 @@ int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
int uv_read2_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
uv_read2_cb read_cb) {
if (handle->flags & UV_HANDLE_READING) {
uv__set_sys_error(handle->loop, UV_EALREADY);
return -1;
}
if (!(handle->flags & UV_HANDLE_READABLE)) {
uv__set_artificial_error(handle->loop, UV_ENOTCONN);
return -1;
}
switch (handle->type) {
case UV_NAMED_PIPE:
return uv_pipe_read2_start((uv_pipe_t*)handle, alloc_cb, read_cb);
@ -82,14 +102,15 @@ int uv_read2_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
int uv_read_stop(uv_stream_t* handle) {
if (!(handle->flags & UV_HANDLE_READING))
return 0;
if (handle->type == UV_TTY) {
return uv_tty_read_stop((uv_tty_t*) handle);
} else if (handle->flags & UV_HANDLE_READING) {
} else {
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(handle->loop, handle);
return 0;
} else {
return 0;
}
}
@ -98,6 +119,11 @@ int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
uv_write_cb cb) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_WRITABLE)) {
uv__set_artificial_error(loop, UV_EPIPE);
return -1;
}
switch (handle->type) {
case UV_TCP:
return uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, bufcnt, cb);
@ -117,6 +143,11 @@ int uv_write2(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
uv_stream_t* send_handle, uv_write_cb cb) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_WRITABLE)) {
uv__set_artificial_error(loop, UV_EPIPE);
return -1;
}
switch (handle->type) {
case UV_NAMED_PIPE:
return uv_pipe_write2(loop, req, (uv_pipe_t*) handle, bufs, bufcnt, send_handle, cb);
@ -131,13 +162,13 @@ int uv_write2(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv__set_sys_error(loop, WSAEINVAL);
if (!(handle->flags & UV_HANDLE_WRITABLE)) {
uv__set_artificial_error(loop, UV_EPIPE);
return -1;
}
if (handle->flags & UV_HANDLE_SHUTTING) {
uv__set_sys_error(loop, WSAESHUTDOWN);
if (!(handle->flags & UV_HANDLE_WRITABLE)) {
uv__set_artificial_error(loop, UV_EPIPE);
return -1;
}
@ -146,7 +177,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
req->handle = handle;
req->cb = cb;
handle->flags |= UV_HANDLE_SHUTTING;
handle->flags &= ~UV_HANDLE_WRITABLE;
handle->shutdown_req = req;
handle->reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req);
@ -158,10 +189,10 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
int uv_is_readable(const uv_stream_t* handle) {
return !(handle->flags & UV_HANDLE_EOF);
return !!(handle->flags & UV_HANDLE_READABLE);
}
int uv_is_writable(const uv_stream_t* handle) {
return !(handle->flags & UV_HANDLE_SHUTTING);
return !!(handle->flags & UV_HANDLE_WRITABLE);
}

39
deps/uv/src/win/tcp.c

@ -169,7 +169,6 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
uv__set_artificial_error(loop, UV_ECANCELED);
} else if (shutdown(handle->socket, SD_SEND) != SOCKET_ERROR) {
status = 0;
handle->flags |= UV_HANDLE_SHUT;
} else {
status = -1;
uv__set_sys_error(loop, WSAGetLastError());
@ -605,7 +604,7 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
} else {
uv_connection_init((uv_stream_t*) client);
/* AcceptEx() implicitly binds the accepted socket. */
client->flags |= UV_HANDLE_BOUND;
client->flags |= UV_HANDLE_BOUND | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
}
/* Prepare the req to pick up a new connection */
@ -646,21 +645,6 @@ int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv__set_sys_error(loop, WSAEINVAL);
return -1;
}
if (handle->flags & UV_HANDLE_READING) {
uv__set_sys_error(loop, WSAEALREADY);
return -1;
}
if (handle->flags & UV_HANDLE_EOF) {
uv__set_sys_error(loop, WSAESHUTDOWN);
return -1;
}
handle->flags |= UV_HANDLE_READING;
handle->read_cb = read_cb;
handle->alloc_cb = alloc_cb;
@ -855,16 +839,6 @@ int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
int result;
DWORD bytes;
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv__set_sys_error(loop, WSAEINVAL);
return -1;
}
if (handle->flags & UV_HANDLE_SHUTTING) {
uv__set_sys_error(loop, WSAESHUTDOWN);
return -1;
}
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_WRITE;
req->handle = (uv_stream_t*) handle;
@ -970,7 +944,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(loop, handle);
}
handle->flags |= UV_HANDLE_EOF;
handle->flags &= ~UV_HANDLE_READABLE;
uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
buf.base = 0;
@ -1001,9 +975,8 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
}
} else {
/* Connection closed */
handle->flags &= ~UV_HANDLE_READING;
handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE);
DECREASE_ACTIVE_COUNT(loop, handle);
handle->flags |= UV_HANDLE_EOF;
uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
handle->read_cb((uv_stream_t*)handle, -1, buf);
@ -1070,7 +1043,7 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
}
handle->write_reqs_pending--;
if (handle->flags & UV_HANDLE_SHUTTING &&
if (handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
@ -1139,6 +1112,7 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
NULL,
0) == 0) {
uv_connection_init((uv_stream_t*)handle);
handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
loop->active_tcp_streams++;
((uv_connect_cb)req->cb)(req, 0);
} else {
@ -1181,6 +1155,7 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
if (tcp_connection) {
uv_connection_init((uv_stream_t*)tcp);
tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
}
tcp->flags |= UV_HANDLE_BOUND;
@ -1342,7 +1317,6 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) {
/* Just do shutdown on non-shared sockets, which ensures graceful close. */
shutdown(tcp->socket, SD_SEND);
tcp->flags |= UV_HANDLE_SHUT;
} else if (uv_tcp_try_cancel_io(tcp) == 0) {
/* In case of a shared socket, we try to cancel all outstanding I/O, */
@ -1397,6 +1371,7 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
}
tcp->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
uv__handle_closing(tcp);
if (tcp->reqs_pending == 0) {

35
deps/uv/src/win/tty.c

@ -140,7 +140,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
if (readable) {
/* Initialize TTY input specific fields. */
tty->original_console_mode = original_console_mode;
tty->flags |= UV_HANDLE_TTY_READABLE;
tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE;
tty->read_line_handle = NULL;
tty->read_line_buffer = uv_null_buf_;
tty->read_raw_wait = NULL;
@ -152,6 +152,8 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
memset(&tty->last_input_record, 0, sizeof tty->last_input_record);
} else {
/* TTY output specific fields. */
tty->flags |= UV_HANDLE_READABLE;
/* Init utf8-to-utf16 conversion state. */
tty->utf8_bytes_left = 0;
tty->utf8_codepoint = 0;
@ -826,15 +828,9 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
int uv_tty_read_stop(uv_tty_t* handle) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_TTY_READABLE)) {
uv__set_artificial_error(handle->loop, UV_EINVAL);
return -1;
}
if (handle->flags & UV_HANDLE_READING) {
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(loop, handle);
}
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(loop, handle);
/* Cancel raw read */
if ((handle->flags & UV_HANDLE_READ_PENDING) &&
@ -1750,17 +1746,6 @@ int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle,
uv_buf_t bufs[], int bufcnt, uv_write_cb cb) {
DWORD error;
if (handle->flags & UV_HANDLE_TTY_READABLE) {
uv__set_artificial_error(handle->loop, UV_EINVAL);
return -1;
}
if ((handle->flags & UV_HANDLE_SHUTTING) ||
(handle->flags & UV_HANDLE_CLOSING)) {
uv__set_sys_error(loop, WSAESHUTDOWN);
return -1;
}
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_WRITE;
req->handle = (uv_stream_t*) handle;
@ -1796,7 +1781,7 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
}
handle->write_reqs_pending--;
if (handle->flags & UV_HANDLE_SHUTTING &&
if (handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
@ -1808,14 +1793,10 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
void uv_tty_close(uv_tty_t* handle) {
CloseHandle(handle->handle);
if (handle->flags & UV_HANDLE_TTY_READABLE) {
/* Readable TTY handle */
if (handle->flags & UV_HANDLE_READING)
uv_tty_read_stop(handle);
} else {
/* Writable TTY handle */
handle->flags |= UV_HANDLE_SHUTTING;
}
handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
uv__handle_closing(handle);
if (handle->reqs_pending == 0) {

3
deps/uv/test/test-fs-event.c

@ -98,7 +98,8 @@ static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename,
ASSERT(handle == &fs_event);
ASSERT(status == 0);
ASSERT(events == UV_RENAME);
ASSERT(filename == NULL || strcmp(filename, "file1") == 0);
ASSERT(filename == NULL || strcmp(filename, "file1") == 0 ||
strstr(filename, "watch_dir") != NULL);
uv_close((uv_handle_t*)handle, close_cb);
}

14
deps/uv/uv.gyp

@ -147,7 +147,7 @@
'libraries': [ '-lm' ]
}],
[ 'OS=="mac"', {
'sources': [ 'src/unix/darwin.c' ],
'sources': [ 'src/unix/darwin.c', 'src/unix/fsevents.c' ],
'direct_dependent_settings': {
'libraries': [
'$(SDKROOT)/System/Library/Frameworks/CoreServices.framework',
@ -209,6 +209,18 @@
'EIO_CONFIG_H="config_openbsd.h"',
],
}],
[ 'OS=="netbsd"', {
'sources': [ 'src/unix/netbsd.c' ],
'defines': [
'EV_CONFIG_H="config_netbsd.h"',
'EIO_CONFIG_H="config_netbsd.h"',
],
'direct_dependent_settings': {
'libraries': [
'-lkvm',
],
},
}],
[ 'OS=="mac" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
'sources': [ 'src/unix/kqueue.c' ],
}],

Loading…
Cancel
Save