Browse Source

deps: upgrade libuv to c8c9fe1

v0.9.1-release
Ben Noordhuis 13 years ago
parent
commit
0a2076b26a
  1. 3
      deps/uv/include/uv-private/uv-unix.h
  2. 2
      deps/uv/include/uv-private/uv-win.h
  3. 11
      deps/uv/include/uv.h
  4. 7
      deps/uv/src/unix/core.c
  5. 113
      deps/uv/src/unix/process.c
  6. 35
      deps/uv/src/unix/stream.c
  7. 107
      deps/uv/src/unix/thread.c
  8. 15
      deps/uv/src/unix/udp.c
  9. 2
      deps/uv/src/uv-common.c
  10. 2
      deps/uv/src/uv-common.h
  11. 2
      deps/uv/src/win/async.c
  12. 21
      deps/uv/src/win/core.c
  13. 8
      deps/uv/src/win/fs-event.c
  14. 2
      deps/uv/src/win/fs.c
  15. 1
      deps/uv/src/win/getaddrinfo.c
  16. 150
      deps/uv/src/win/handle-inl.h
  17. 80
      deps/uv/src/win/handle.c
  18. 116
      deps/uv/src/win/internal.h
  19. 1
      deps/uv/src/win/loop-watcher.c
  20. 3
      deps/uv/src/win/pipe.c
  21. 67
      deps/uv/src/win/poll.c
  22. 68
      deps/uv/src/win/process.c
  23. 225
      deps/uv/src/win/req-inl.h
  24. 144
      deps/uv/src/win/req.c
  25. 67
      deps/uv/src/win/stream-inl.h
  26. 37
      deps/uv/src/win/stream.c
  27. 4
      deps/uv/src/win/tcp.c
  28. 39
      deps/uv/src/win/thread.c
  29. 1
      deps/uv/src/win/threadpool.c
  30. 47
      deps/uv/src/win/timer.c
  31. 5
      deps/uv/src/win/tty.c
  32. 3
      deps/uv/src/win/udp.c
  33. 340
      deps/uv/src/win/util.c
  34. 8
      deps/uv/src/win/winapi.c
  35. 25
      deps/uv/src/win/winapi.h
  36. 14
      deps/uv/test/run-tests.c
  37. 16
      deps/uv/test/test-list.h
  38. 77
      deps/uv/test/test-poll-close.c
  39. 6
      deps/uv/test/test-poll.c
  40. 111
      deps/uv/test/test-semaphore.c
  41. 21
      deps/uv/test/test-spawn.c
  42. 95
      deps/uv/test/test-tcp-connect-error-after-write.c
  43. 129
      deps/uv/test/test-tcp-shutdown-after-write.c
  44. 6
      deps/uv/test/test-tcp-writealot.c
  45. 7
      deps/uv/uv.gyp

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

@ -35,6 +35,8 @@
#include <netdb.h>
#include <pwd.h>
#include <termios.h>
#include <semaphore.h>
#include <pthread.h>
#if __sun
@ -58,6 +60,7 @@ typedef pthread_once_t uv_once_t;
typedef pthread_t uv_thread_t;
typedef pthread_mutex_t uv_mutex_t;
typedef pthread_rwlock_t uv_rwlock_t;
typedef sem_t uv_sem_t;
/* Platform-specific definitions for uv_spawn support. */
typedef gid_t uv_gid_t;

2
deps/uv/include/uv-private/uv-win.h

@ -169,6 +169,8 @@ typedef SOCKET uv_os_sock_t;
typedef HANDLE uv_thread_t;
typedef HANDLE uv_sem_t;
typedef CRITICAL_SECTION uv_mutex_t;
typedef union {

11
deps/uv/include/uv.h

@ -432,7 +432,7 @@ UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb);
* base and len members of the uv_buf_t struct. The user is responsible for
* freeing base after the uv_buf_t is done. Return struct passed by value.
*/
UV_EXTERN uv_buf_t uv_buf_init(char* base, size_t len);
UV_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len);
/*
@ -1624,6 +1624,15 @@ UV_EXTERN void uv_rwlock_wrlock(uv_rwlock_t* rwlock);
UV_EXTERN int uv_rwlock_trywrlock(uv_rwlock_t* rwlock);
UV_EXTERN void uv_rwlock_wrunlock(uv_rwlock_t* rwlock);
/*
* Same goes for the semaphore functions.
*/
UV_EXTERN int uv_sem_init(uv_sem_t* sem, unsigned int value);
UV_EXTERN void uv_sem_destroy(uv_sem_t* sem);
UV_EXTERN void uv_sem_post(uv_sem_t* sem);
UV_EXTERN void uv_sem_wait(uv_sem_t* sem);
UV_EXTERN int uv_sem_trywait(uv_sem_t* sem);
/* Runs a function once and only once. Concurrent calls to uv_once() with the
* same guard will block all callers except one (it's unspecified which one).
* The guard should be initialized statically with the UV_ONCE_INIT macro.

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

@ -604,6 +604,13 @@ static void uv__io_rw(struct ev_loop* ev, ev_io* w, int events) {
uv__io_t* handle = container_of(w, uv__io_t, io_watcher);
u.data = handle->io_watcher.data;
u.cb(loop, handle, events & (EV_READ|EV_WRITE|EV_ERROR));
/* The callback may have closed all active handles. Stop libev from entering
* the epoll_wait/kevent/port_getn/etc. syscall if that's the case, it would
* hang indefinitely.
*/
if (loop->active_handles == 0)
ev_break(loop->ev, EVBREAK_ONE);
}

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

@ -28,6 +28,7 @@
#include <poll.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#ifdef __APPLE__
# include <TargetConditionals.h>
@ -217,6 +218,68 @@ static void uv__process_close_stream(uv_stdio_container_t* container) {
uv__stream_close((uv_stream_t*)container->data.stream);
}
static void uv__process_child_init(uv_process_options_t options,
int stdio_count,
int* pipes) {
int i;
if (options.flags & UV_PROCESS_DETACHED) {
setsid();
}
/* Dup fds */
for (i = 0; i < stdio_count; i++) {
/*
* stdin has swapped ends of pipe
* (it's the only one readable stream)
*/
int close_fd = i == 0 ? pipes[i * 2 + 1] : pipes[i * 2];
int use_fd = i == 0 ? pipes[i * 2] : pipes[i * 2 + 1];
if (use_fd >= 0) {
close(close_fd);
} else if (i < 3) {
/* `/dev/null` stdin, stdout, stderr even if they've flag UV_IGNORE */
use_fd = open("/dev/null", i == 0 ? O_RDONLY : O_RDWR);
if (use_fd < 0) {
perror("failed to open stdio");
_exit(127);
}
} else {
continue;
}
if (i != use_fd) {
dup2(use_fd, i);
close(use_fd);
}
}
if (options.cwd && chdir(options.cwd)) {
perror("chdir()");
_exit(127);
}
if ((options.flags & UV_PROCESS_SETGID) && setgid(options.gid)) {
perror("setgid()");
_exit(127);
}
if ((options.flags & UV_PROCESS_SETUID) && setuid(options.uid)) {
perror("setuid()");
_exit(127);
}
environ = options.env;
execvp(options.file, options.args);
perror("execvp()");
_exit(127);
}
#ifndef SPAWN_WAIT_EXEC
# define SPAWN_WAIT_EXEC 1
#endif
@ -229,7 +292,8 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
*/
char** save_our_env = environ;
int* pipes = malloc(2 * options.stdio_count * sizeof(int));
int stdio_count = options.stdio_count < 3 ? 3 : options.stdio_count;
int* pipes = malloc(2 * stdio_count * sizeof(int));
#if SPAWN_WAIT_EXEC
int signal_pipe[2] = { -1, -1 };
@ -258,7 +322,7 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
process->exit_cb = options.exit_cb;
/* Init pipe pairs */
for (i = 0; i < options.stdio_count; i++) {
for (i = 0; i < stdio_count; i++) {
pipes[i * 2] = -1;
pipes[i * 2 + 1] = -1;
}
@ -308,49 +372,8 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
if (pid == 0) {
/* Child */
if (options.flags & UV_PROCESS_DETACHED) {
setsid();
}
/* Dup fds */
for (i = 0; i < options.stdio_count; i++) {
/*
* stdin has swapped ends of pipe
* (it's the only one readable stream)
*/
int close_fd = i == 0 ? pipes[i * 2 + 1] : pipes[i * 2];
int use_fd = i == 0 ? pipes[i * 2] : pipes[i * 2 + 1];
if (use_fd >= 0) {
close(close_fd);
dup2(use_fd, i);
} else {
/* Reset flags that might be set by Node */
uv__cloexec(i, 0);
uv__nonblock(i, 0);
}
}
uv__process_child_init(options, stdio_count, pipes);
if (options.cwd && chdir(options.cwd)) {
perror("chdir()");
_exit(127);
}
if ((options.flags & UV_PROCESS_SETGID) && setgid(options.gid)) {
perror("setgid()");
_exit(127);
}
if ((options.flags & UV_PROCESS_SETUID) && setuid(options.uid)) {
perror("setuid()");
_exit(127);
}
environ = options.env;
execvp(options.file, options.args);
perror("execvp()");
_exit(127);
/* Execution never reaches here. */
}
@ -399,7 +422,7 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
error:
uv__set_sys_error(process->loop, errno);
for (i = 0; i < options.stdio_count; i++) {
for (i = 0; i < stdio_count; i++) {
close(pipes[i * 2]);
close(pipes[i * 2 + 1]);
}

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

@ -561,12 +561,19 @@ static void uv__read(uv_stream_t* stream) {
struct msghdr msg;
struct cmsghdr* cmsg;
char cmsg_space[64];
int count;
/* Prevent loop starvation when the data comes in as fast as (or faster than)
* we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O.
*/
count = 32;
/* XXX: Maybe instead of having UV_STREAM_READING we just test if
* tcp->read_cb is NULL or not?
*/
while ((stream->read_cb || stream->read2_cb) &&
stream->flags & UV_STREAM_READING) {
while ((stream->read_cb || stream->read2_cb)
&& (stream->flags & UV_STREAM_READING)
&& (count-- > 0)) {
assert(stream->alloc_cb);
buf = stream->alloc_cb((uv_handle_t*)stream, 64 * 1024);
@ -890,42 +897,36 @@ int uv_write2(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
req->send_handle = send_handle;
ngx_queue_init(&req->queue);
if (bufcnt <= UV_REQ_BUFSML_SIZE) {
if (bufcnt <= UV_REQ_BUFSML_SIZE)
req->bufs = req->bufsml;
}
else {
else
req->bufs = malloc(sizeof(uv_buf_t) * bufcnt);
}
memcpy(req->bufs, bufs, bufcnt * sizeof(uv_buf_t));
req->bufcnt = bufcnt;
/*
* fprintf(stderr, "cnt: %d bufs: %p bufsml: %p\n", bufcnt, req->bufs, req->bufsml);
*/
req->write_index = 0;
stream->write_queue_size += uv__buf_count(bufs, bufcnt);
/* Append the request to write_queue. */
ngx_queue_insert_tail(&stream->write_queue, &req->queue);
assert(!ngx_queue_empty(&stream->write_queue));
/* If the queue was empty when this function began, we should attempt to
* do the write immediately. Otherwise start the write_watcher and wait
* for the fd to become writable.
*/
if (empty_queue) {
if (stream->connect_req) {
/* Still connecting, do nothing. */
}
else if (empty_queue) {
uv__write(stream);
} else {
}
else {
/*
* blocking streams should never have anything in the queue.
* if this assert fires then somehow the blocking stream isn't being
* sufficently flushed in uv__write.
* sufficiently flushed in uv__write.
*/
assert(!(stream->flags & UV_STREAM_BLOCKING));
uv__io_start(stream->loop, &stream->write_watcher);
}

107
deps/uv/src/unix/thread.c

@ -26,19 +26,6 @@
#include <assert.h>
#include <errno.h>
#ifdef NDEBUG
# define CHECK(r) ((void) (r))
#else
# include <stdio.h>
# include <stdlib.h>
# define CHECK(r) \
do { \
int __r = (r); \
if (__r) errno = __r, perror(#r), abort(); \
} \
while (0)
#endif
int uv_thread_join(uv_thread_t *tid) {
if (pthread_join(*tid, NULL))
@ -49,20 +36,40 @@ int uv_thread_join(uv_thread_t *tid) {
int uv_mutex_init(uv_mutex_t* mutex) {
#ifdef NDEBUG
if (pthread_mutex_init(mutex, NULL))
return -1;
else
return 0;
#else
pthread_mutexattr_t attr;
int r;
if (pthread_mutexattr_init(&attr))
abort();
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK))
abort();
r = pthread_mutex_init(mutex, &attr);
if (pthread_mutexattr_destroy(&attr))
abort();
return r ? -1 : 0;
#endif
}
void uv_mutex_destroy(uv_mutex_t* mutex) {
CHECK(pthread_mutex_destroy(mutex));
if (pthread_mutex_destroy(mutex))
abort();
}
void uv_mutex_lock(uv_mutex_t* mutex) {
CHECK(pthread_mutex_lock(mutex));
if (pthread_mutex_lock(mutex))
abort();
}
@ -72,7 +79,7 @@ int uv_mutex_trylock(uv_mutex_t* mutex) {
r = pthread_mutex_trylock(mutex);
if (r && r != EAGAIN)
CHECK(r);
abort();
if (r)
return -1;
@ -82,7 +89,8 @@ int uv_mutex_trylock(uv_mutex_t* mutex) {
void uv_mutex_unlock(uv_mutex_t* mutex) {
CHECK(pthread_mutex_unlock(mutex));
if (pthread_mutex_unlock(mutex))
abort();
}
@ -95,12 +103,14 @@ int uv_rwlock_init(uv_rwlock_t* rwlock) {
void uv_rwlock_destroy(uv_rwlock_t* rwlock) {
CHECK(pthread_rwlock_destroy(rwlock));
if (pthread_rwlock_destroy(rwlock))
abort();
}
void uv_rwlock_rdlock(uv_rwlock_t* rwlock) {
CHECK(pthread_rwlock_rdlock(rwlock));
if (pthread_rwlock_rdlock(rwlock))
abort();
}
@ -110,7 +120,7 @@ int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) {
r = pthread_rwlock_tryrdlock(rwlock);
if (r && r != EAGAIN)
CHECK(r);
abort();
if (r)
return -1;
@ -120,12 +130,14 @@ int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) {
void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) {
CHECK(pthread_rwlock_unlock(rwlock));
if (pthread_rwlock_unlock(rwlock))
abort();
}
void uv_rwlock_wrlock(uv_rwlock_t* rwlock) {
CHECK(pthread_rwlock_wrlock(rwlock));
if (pthread_rwlock_wrlock(rwlock))
abort();
}
@ -135,7 +147,7 @@ int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) {
r = pthread_rwlock_trywrlock(rwlock);
if (r && r != EAGAIN)
CHECK(r);
abort();
if (r)
return -1;
@ -145,10 +157,55 @@ int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) {
void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) {
CHECK(pthread_rwlock_unlock(rwlock));
if (pthread_rwlock_unlock(rwlock))
abort();
}
void uv_once(uv_once_t* guard, void (*callback)(void)) {
CHECK(pthread_once(guard, callback));
if (pthread_once(guard, callback))
abort();
}
int uv_sem_init(uv_sem_t* sem, unsigned int value) {
return sem_init(sem, 0, value);
}
void uv_sem_destroy(uv_sem_t* sem) {
if (sem_destroy(sem))
abort();
}
void uv_sem_post(uv_sem_t* sem) {
if (sem_post(sem))
abort();
}
void uv_sem_wait(uv_sem_t* sem) {
int r;
do
r = sem_wait(sem);
while (r == -1 && errno == EINTR);
if (r)
abort();
}
int uv_sem_trywait(uv_sem_t* sem) {
int r;
do
r = sem_trywait(sem);
while (r == -1 && errno == EINTR);
if (r && errno != EAGAIN)
abort();
return r;
}

15
deps/uv/src/unix/udp.c

@ -196,6 +196,7 @@ static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, int revents) {
ssize_t nread;
uv_buf_t buf;
int flags;
int count;
handle = container_of(w, uv_udp_t, read_watcher);
assert(handle->type == UV_UDP);
@ -204,15 +205,20 @@ static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, int revents) {
assert(handle->recv_cb != NULL);
assert(handle->alloc_cb != NULL);
/* Prevent loop starvation when the data comes in as fast as (or faster than)
* we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O.
*/
count = 32;
memset(&h, 0, sizeof(h));
h.msg_name = &peer;
do {
/* FIXME: hoist alloc_cb out the loop but for now follow uv__read() */
buf = handle->alloc_cb((uv_handle_t*)handle, 64 * 1024);
assert(buf.len > 0);
assert(buf.base != NULL);
memset(&h, 0, sizeof h);
h.msg_name = &peer;
h.msg_namelen = sizeof peer;
h.msg_namelen = sizeof(peer);
h.msg_iov = (struct iovec*)&buf;
h.msg_iovlen = 1;
@ -246,6 +252,7 @@ static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, int revents) {
}
/* recv_cb callback may decide to pause or close the handle */
while (nread != -1
&& count-- > 0
&& handle->fd != -1
&& handle->recv_cb != NULL);
}

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

@ -87,7 +87,7 @@ size_t uv_strlcat(char* dst, const char* src, size_t size) {
}
uv_buf_t uv_buf_init(char* base, size_t len) {
uv_buf_t uv_buf_init(char* base, unsigned int len) {
uv_buf_t buf;
buf.base = base;
buf.len = len;

2
deps/uv/src/uv-common.h

@ -42,8 +42,10 @@
#ifdef _MSC_VER
# define UNUSED /* empty */
# define INLINE __inline
#else
# define UNUSED __attribute__((unused))
# define INLINE inline
#endif

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

@ -23,6 +23,8 @@
#include "uv.h"
#include "internal.h"
#include "handle-inl.h"
#include "req-inl.h"
/* Atomic set operation on char */

21
deps/uv/src/win/core.c

@ -28,6 +28,8 @@
#include "uv.h"
#include "internal.h"
#include "handle-inl.h"
#include "req-inl.h"
/* The only event loop we support right now */
@ -43,17 +45,21 @@ static void uv_init(void) {
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
SEM_NOOPENFILEERRORBOX);
/* Fetch winapi function pointers. This must be done first because other */
/* intialization code might need these function pointers to be loaded. */
uv_winapi_init();
/* Initialize winsock */
uv_winsock_init();
/* Fetch winapi function pointers */
uv_winapi_init();
/* Initialize FS */
uv_fs_init();
/* Initialize console */
uv_console_init();
/* Initialize utilities */
uv__util_init();
}
@ -100,13 +106,18 @@ static void uv_loop_init(uv_loop_t* loop) {
static void uv_default_loop_init(void) {
/* Initialize libuv itself first */
uv_once(&uv_init_guard_, uv_init);
uv__once_init();
/* Initialize the main loop */
uv_loop_init(&uv_default_loop_);
}
void uv__once_init(void) {
uv_once(&uv_init_guard_, uv_init);
}
uv_loop_t* uv_default_loop(void) {
uv_once(&uv_default_loop_init_guard_, uv_default_loop_init);
return &uv_default_loop_;
@ -117,7 +128,7 @@ uv_loop_t* uv_loop_new(void) {
uv_loop_t* loop;
/* Initialize libuv itself first */
uv_once(&uv_init_guard_, uv_init);
uv__once_init();
loop = (uv_loop_t*)malloc(sizeof(uv_loop_t));

8
deps/uv/src/win/fs-event.c

@ -19,15 +19,17 @@
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "internal.h"
#include <assert.h>
#include <malloc.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "uv.h"
#include "internal.h"
#include "handle-inl.h"
#include "req-inl.h"
const unsigned int uv_directory_watcher_buffer_size = 4096;

2
deps/uv/src/win/fs.c

@ -32,6 +32,8 @@
#include "uv.h"
#include "internal.h"
#include "req-inl.h"
#define UV_FS_ASYNC_QUEUED 0x0001
#define UV_FS_FREE_PATH 0x0002

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

@ -24,6 +24,7 @@
#include "uv.h"
#include "internal.h"
#include "req-inl.h"
/*

150
deps/uv/src/win/handle-inl.h

@ -0,0 +1,150 @@
/* 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_WIN_HANDLE_INL_H_
#define UV_WIN_HANDLE_INL_H_
#include <assert.h>
#include "uv.h"
#include "internal.h"
#define DECREASE_ACTIVE_COUNT(loop, handle) \
do { \
if (--(handle)->activecnt == 0 && \
!((handle)->flags & UV_HANDLE_CLOSING)) { \
uv__handle_stop((handle)); \
} \
assert((handle)->activecnt >= 0); \
} while (0)
#define INCREASE_ACTIVE_COUNT(loop, handle) \
do { \
if ((handle)->activecnt++ == 0) { \
uv__handle_start((handle)); \
} \
assert((handle)->activecnt > 0); \
} while (0)
#define DECREASE_PENDING_REQ_COUNT(handle) \
do { \
assert(handle->reqs_pending > 0); \
handle->reqs_pending--; \
\
if (handle->flags & UV_HANDLE_CLOSING && \
handle->reqs_pending == 0) { \
uv_want_endgame(loop, (uv_handle_t*)handle); \
} \
} while (0)
#define uv__handle_close(handle) \
do { \
ngx_queue_remove(&(handle)->handle_queue); \
(handle)->flags |= UV_HANDLE_CLOSED; \
if ((handle)->close_cb) { \
(handle)->close_cb((uv_handle_t*)(handle)); \
} \
} while (0)
INLINE static void uv_handle_init(uv_loop_t* loop, uv_handle_t* handle) {
handle->loop = loop;
handle->flags = UV__HANDLE_REF;
ngx_queue_insert_tail(&loop->handle_queue, &handle->handle_queue);
loop->counters.handle_init++;
}
INLINE static 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;
handle->endgame_next = loop->endgame_handles;
loop->endgame_handles = handle;
}
}
INLINE static void uv_process_endgames(uv_loop_t* loop) {
uv_handle_t* handle;
while (loop->endgame_handles) {
handle = loop->endgame_handles;
loop->endgame_handles = handle->endgame_next;
handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
switch (handle->type) {
case UV_TCP:
uv_tcp_endgame(loop, (uv_tcp_t*) handle);
break;
case UV_NAMED_PIPE:
uv_pipe_endgame(loop, (uv_pipe_t*) handle);
break;
case UV_TTY:
uv_tty_endgame(loop, (uv_tty_t*) handle);
break;
case UV_UDP:
uv_udp_endgame(loop, (uv_udp_t*) handle);
break;
case UV_POLL:
uv_poll_endgame(loop, (uv_poll_t*) handle);
break;
case UV_TIMER:
uv_timer_endgame(loop, (uv_timer_t*) handle);
break;
case UV_PREPARE:
case UV_CHECK:
case UV_IDLE:
uv_loop_watcher_endgame(loop, handle);
break;
case UV_ASYNC:
uv_async_endgame(loop, (uv_async_t*) handle);
break;
case UV_PROCESS:
uv_process_endgame(loop, (uv_process_t*) handle);
break;
case UV_FS_EVENT:
uv_fs_event_endgame(loop, (uv_fs_event_t*) handle);
break;
default:
assert(0);
break;
}
}
}
#endif /* UV_WIN_HANDLE_INL_H_ */

80
deps/uv/src/win/handle.c

@ -24,6 +24,7 @@
#include "uv.h"
#include "internal.h"
#include "handle-inl.h"
uv_handle_type uv_guess_handle(uv_file file) {
@ -62,15 +63,6 @@ int uv_is_active(const uv_handle_t* handle) {
}
void uv_handle_init(uv_loop_t* loop, uv_handle_t* handle) {
handle->loop = loop;
handle->flags = UV__HANDLE_REF;
ngx_queue_insert_tail(&loop->handle_queue, &handle->handle_queue);
loop->counters.handle_init++;
}
void uv_close(uv_handle_t* handle, uv_close_cb cb) {
uv_loop_t* loop = handle->loop;
@ -150,73 +142,3 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
int uv_is_closing(const 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;
handle->endgame_next = loop->endgame_handles;
loop->endgame_handles = handle;
}
}
void uv_process_endgames(uv_loop_t* loop) {
uv_handle_t* handle;
while (loop->endgame_handles) {
handle = loop->endgame_handles;
loop->endgame_handles = handle->endgame_next;
handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
switch (handle->type) {
case UV_TCP:
uv_tcp_endgame(loop, (uv_tcp_t*) handle);
break;
case UV_NAMED_PIPE:
uv_pipe_endgame(loop, (uv_pipe_t*) handle);
break;
case UV_TTY:
uv_tty_endgame(loop, (uv_tty_t*) handle);
break;
case UV_UDP:
uv_udp_endgame(loop, (uv_udp_t*) handle);
break;
case UV_POLL:
uv_poll_endgame(loop, (uv_poll_t*) handle);
break;
case UV_TIMER:
uv_timer_endgame(loop, (uv_timer_t*) handle);
break;
case UV_PREPARE:
case UV_CHECK:
case UV_IDLE:
uv_loop_watcher_endgame(loop, handle);
break;
case UV_ASYNC:
uv_async_endgame(loop, (uv_async_t*) handle);
break;
case UV_PROCESS:
uv_process_endgame(loop, (uv_process_t*) handle);
break;
case UV_FS_EVENT:
uv_fs_event_endgame(loop, (uv_fs_event_t*) handle);
break;
default:
assert(0);
break;
}
}
}

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

@ -32,6 +32,7 @@
/*
* Handles
* (also see handle-inl.h)
*/
/* Used by all handles. */
@ -81,96 +82,14 @@
#define UV_HANDLE_POLL_SLOW 0x02000000
void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle);
void uv_process_endgames(uv_loop_t* loop);
#define DECREASE_PENDING_REQ_COUNT(handle) \
do { \
assert(handle->reqs_pending > 0); \
handle->reqs_pending--; \
\
if (handle->flags & UV_HANDLE_CLOSING && \
handle->reqs_pending == 0) { \
uv_want_endgame(loop, (uv_handle_t*)handle); \
} \
} while (0)
#define UV_SUCCEEDED_WITHOUT_IOCP(result) \
((result) && (handle->flags & UV_HANDLE_SYNC_BYPASS_IOCP))
#define UV_SUCCEEDED_WITH_IOCP(result) \
((result) || (GetLastError() == ERROR_IO_PENDING))
#define DECREASE_ACTIVE_COUNT(loop, handle) \
do { \
if (--(handle)->activecnt == 0 && \
!((handle)->flags & UV_HANDLE_CLOSING)) { \
uv__handle_stop((handle)); \
} \
assert((handle)->activecnt >= 0); \
} while (0)
#define INCREASE_ACTIVE_COUNT(loop, handle) \
do { \
if ((handle)->activecnt++ == 0) { \
uv__handle_start((handle)); \
} \
assert((handle)->activecnt > 0); \
} while (0)
#define REGISTER_HANDLE_REQ(loop, handle, req) \
do { \
INCREASE_ACTIVE_COUNT((loop), (handle)); \
uv__req_register((loop), (req)); \
} while (0)
#define UNREGISTER_HANDLE_REQ(loop, handle, req) \
do { \
DECREASE_ACTIVE_COUNT((loop), (handle)); \
uv__req_unregister((loop), (req)); \
} while (0)
#define uv__handle_close(handle) \
do { \
ngx_queue_remove(&(handle)->handle_queue); \
(handle)->flags |= UV_HANDLE_CLOSED; \
if ((handle)->close_cb) { \
(handle)->close_cb((uv_handle_t*)(handle)); \
} \
} while (0)
/*
* Handles
* Requests: see req-inl.h
*/
void uv_handle_init(uv_loop_t* loop, uv_handle_t* handle);
/*
* Requests
* Streams: see stream-inl.h
*/
void uv_req_init(uv_loop_t* loop, uv_req_t* req);
uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped);
void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req);
void uv_process_reqs(uv_loop_t* loop);
#define POST_COMPLETION_FOR_REQ(loop, req) \
if (!PostQueuedCompletionStatus((loop)->iocp, \
0, \
0, \
&((req)->overlapped))) { \
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \
}
/*
* Streams
*/
void uv_stream_init(uv_loop_t* loop, uv_stream_t* handle);
void uv_connection_init(uv_stream_t* handle);
size_t uv_count_bufs(uv_buf_t bufs[], int count);
/*
@ -299,6 +218,8 @@ void uv_prepare_invoke(uv_loop_t* loop);
void uv_check_invoke(uv_loop_t* loop);
void uv_idle_invoke(uv_loop_t* loop);
void uv__once_init();
/*
* Async watcher
@ -347,33 +268,16 @@ void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle);
void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle);
/* Utils */
/*
* Utilities.
*/
void uv__util_init();
int uv_parent_pid();
void uv_filetime_to_time_t(FILETIME* file_time, time_t* stat_time);
void uv_fatal_error(const int errorno, const char* syscall);
uv_err_code uv_translate_sys_error(int sys_errno);
#define SET_REQ_STATUS(req, status) \
(req)->overlapped.Internal = (ULONG_PTR) (status)
#define SET_REQ_ERROR(req, error) \
SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error)))
#define SET_REQ_SUCCESS(req) \
SET_REQ_STATUS((req), STATUS_SUCCESS)
#define GET_REQ_STATUS(req) \
((req)->overlapped.Internal)
#define REQ_SUCCESS(req) \
(NT_SUCCESS(GET_REQ_STATUS((req))))
#define GET_REQ_ERROR(req) \
(pRtlNtStatusToDosError(GET_REQ_STATUS((req))))
#define GET_REQ_SOCK_ERROR(req) \
(uv_ntstatus_to_winsock_error(GET_REQ_STATUS((req))))
/*
* Winapi and ntapi utility functions

1
deps/uv/src/win/loop-watcher.c

@ -23,6 +23,7 @@
#include "uv.h"
#include "internal.h"
#include "handle-inl.h"
void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {

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

@ -26,6 +26,9 @@
#include "uv.h"
#include "internal.h"
#include "handle-inl.h"
#include "stream-inl.h"
#include "req-inl.h"
/* A zero-size buffer for use by uv_pipe_read */

67
deps/uv/src/win/poll.c

@ -19,12 +19,13 @@
* IN THE SOFTWARE.
*/
#include <assert.h>
#include <io.h>
#include "uv.h"
#include "internal.h"
#include <assert.h>
#include <io.h>
#include "handle-inl.h"
#include "req-inl.h"
static const GUID uv_msafd_provider_ids[UV_MSAFD_PROVIDER_COUNT] = {
@ -42,6 +43,28 @@ typedef struct uv_single_fd_set_s {
} uv_single_fd_set_t;
static OVERLAPPED overlapped_dummy_;
static uv_once_t overlapped_dummy_init_guard_ = UV_ONCE_INIT;
static void uv__init_overlapped_dummy(void) {
HANDLE event;
event = CreateEvent(NULL, TRUE, TRUE, NULL);
if (event == NULL)
uv_fatal_error(GetLastError(), "CreateEvent");
memset(&overlapped_dummy_, 0, sizeof overlapped_dummy_);
overlapped_dummy_.hEvent = (HANDLE) ((uintptr_t) event | 1);
}
static OVERLAPPED* uv__get_overlapped_dummy() {
uv_once(&overlapped_dummy_init_guard_, uv__init_overlapped_dummy);
return &overlapped_dummy_;
}
static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
uv_req_t* req;
AFD_POLL_INFO* afd_poll_info;
@ -97,43 +120,26 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
AFD_POLL_INFO afd_poll_info;
DWORD result;
HANDLE event;
OVERLAPPED overlapped;
event = CreateEvent(NULL, TRUE, FALSE, NULL);
if (event == NULL) {
uv__set_sys_error(loop, GetLastError());
return -1;
}
afd_poll_info.Exclusive = FALSE;
afd_poll_info.Exclusive = TRUE;
afd_poll_info.NumberOfHandles = 1;
afd_poll_info.Timeout.QuadPart = 0;
afd_poll_info.Timeout.QuadPart = INT64_MAX;
afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket;
afd_poll_info.Handles[0].Status = 0;
afd_poll_info.Handles[0].Events = AFD_POLL_ALL;
memset(&overlapped, 0, sizeof overlapped);
overlapped.hEvent = (HANDLE) ((uintptr_t) event | 1);
result = uv_msafd_poll(handle->socket,
&afd_poll_info,
&overlapped);
uv__get_overlapped_dummy());
if (result == SOCKET_ERROR) {
DWORD error = WSAGetLastError();
if (error != WSA_IO_PENDING) {
uv__set_sys_error(loop, WSAGetLastError());
CloseHandle(event);
return -1;
}
}
if (WaitForSingleObject(event, INFINITE) != WAIT_OBJECT_0) {
uv_fatal_error(GetLastError(), "WaitForSingleObject");
}
CloseHandle(event);
return 0;
}
@ -181,6 +187,7 @@ static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
if (afd_poll_info->Handles[0].Events & AFD_POLL_LOCAL_CLOSE) {
/* Stop polling. */
handle->events = 0;
uv__handle_stop(handle);
}
if (events != 0) {
@ -229,17 +236,9 @@ static void uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
handle->submitted_events_2 == 0) {
uv_want_endgame(loop, (uv_handle_t*) handle);
} else {
/* Try to cancel outstanding poll requests. */
if (pCancelIoEx) {
/* Use CancelIoEx to cancel poll requests if available. */
if (handle->submitted_events_1)
pCancelIoEx((HANDLE) handle->socket, &handle->poll_req_1.overlapped);
if (handle->submitted_events_2)
pCancelIoEx((HANDLE) handle->socket, &handle->poll_req_2.overlapped);
} else if (handle->submitted_events_1 | handle->submitted_events_2) {
/* Execute another unique poll to force the others to return. */
uv__fast_poll_cancel_poll_req(loop, handle);
}
/* Cancel outstanding poll requests by executing another, unique poll */
/* request that forces the outstanding ones to return. */
uv__fast_poll_cancel_poll_req(loop, handle);
}
}

68
deps/uv/src/win/process.c

@ -19,15 +19,16 @@
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "internal.h"
#include <assert.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <windows.h>
#include "uv.h"
#include "internal.h"
#include "handle-inl.h"
#include "req-inl.h"
#define SIGKILL 9
@ -86,7 +87,7 @@ typedef struct env_var {
((LPBYTE) (buffer))
#define CHILD_STDIO_CBRESERVED2(buffer) \
CHILD_STDIO_SIZE(CHILD_STDIO_COUNT((buffer)))
((WORD) CHILD_STDIO_SIZE(CHILD_STDIO_COUNT((buffer))))
#define CHILD_STDIO_CRT_FLAGS(buffer, fd) \
*((unsigned char*) (buffer) + sizeof(int) + fd)
@ -756,6 +757,32 @@ static int duplicate_fd(uv_loop_t* loop, int fd, HANDLE* dup) {
}
static int create_nul_handle(uv_loop_t* loop, HANDLE* handle_ptr,
DWORD access) {
HANDLE handle;
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof sa;
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
handle = CreateFileW(L"NUL",
access,
FILE_SHARE_READ | FILE_SHARE_WRITE,
&sa,
OPEN_EXISTING,
0,
NULL);
if (handle == INVALID_HANDLE_VALUE) {
uv__set_sys_error(loop, GetLastError());
return -1;
}
*handle_ptr = handle;
return 0;
}
static void set_child_stdio_noinherit(void* buffer) {
int i, count;
@ -965,16 +992,34 @@ static int init_child_stdio(uv_loop_t* loop, uv_process_options_t* options,
CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE;
}
for (i = 0; i < options->stdio_count; i++) {
uv_stdio_container_t fdopt = options->stdio[i];
for (i = 0; i < count; i++) {
uv_stdio_container_t fdopt;
if (i < options->stdio_count) {
fdopt = options->stdio[i];
} else {
fdopt.flags = UV_IGNORE;
}
switch (fdopt.flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
UV_INHERIT_STREAM)) {
case UV_IGNORE:
/* The child is not supposed to inherit this handle. It has already */
/* been initialized to INVALID_HANDLE_VALUE, so just keep it like */
/* that. */
continue;
/* Starting a process with no stdin/stout/stderr can confuse it. */
/* So no matter what the user specified, we make sure the first */
/* three FDs are always open in their typical modes, e.g. stdin */
/* be readable and stdout/err should be writable. For FDs > 2, don't */
/* do anything - all handles in the stdio buffer are initialized with */
/* INVALID_HANDLE_VALUE, which should be okay. */
if (i <= 2) {
DWORD access = (i == 0) ? FILE_GENERIC_READ :
FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES;
if (create_nul_handle(loop,
&CHILD_STDIO_HANDLE(buffer, i),
access) < 0) {
goto error;
}
CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV;
}
break;
case UV_CREATE_PIPE: {
/* Create a pair of two connected pipe ends; one end is turned into */
@ -1077,6 +1122,7 @@ static int init_child_stdio(uv_loop_t* loop, uv_process_options_t* options,
CHILD_STDIO_HANDLE(buffer, i) = child_handle;
CHILD_STDIO_CRT_FLAGS(buffer, i) = crt_flags;
break;
}
default:

225
deps/uv/src/win/req-inl.h

@ -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.
*/
#ifndef UV_WIN_REQ_INL_H_
#define UV_WIN_REQ_INL_H_
#include <assert.h>
#include "uv.h"
#include "internal.h"
#define SET_REQ_STATUS(req, status) \
(req)->overlapped.Internal = (ULONG_PTR) (status)
#define SET_REQ_ERROR(req, error) \
SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error)))
#define SET_REQ_SUCCESS(req) \
SET_REQ_STATUS((req), STATUS_SUCCESS)
#define GET_REQ_STATUS(req) \
((NTSTATUS) (req)->overlapped.Internal)
#define REQ_SUCCESS(req) \
(NT_SUCCESS(GET_REQ_STATUS((req))))
#define GET_REQ_ERROR(req) \
(pRtlNtStatusToDosError(GET_REQ_STATUS((req))))
#define GET_REQ_SOCK_ERROR(req) \
(uv_ntstatus_to_winsock_error(GET_REQ_STATUS((req))))
#define REGISTER_HANDLE_REQ(loop, handle, req) \
do { \
INCREASE_ACTIVE_COUNT((loop), (handle)); \
uv__req_register((loop), (req)); \
} while (0)
#define UNREGISTER_HANDLE_REQ(loop, handle, req) \
do { \
DECREASE_ACTIVE_COUNT((loop), (handle)); \
uv__req_unregister((loop), (req)); \
} while (0)
#define UV_SUCCEEDED_WITHOUT_IOCP(result) \
((result) && (handle->flags & UV_HANDLE_SYNC_BYPASS_IOCP))
#define UV_SUCCEEDED_WITH_IOCP(result) \
((result) || (GetLastError() == ERROR_IO_PENDING))
#define POST_COMPLETION_FOR_REQ(loop, req) \
if (!PostQueuedCompletionStatus((loop)->iocp, \
0, \
0, \
&((req)->overlapped))) { \
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \
}
INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) {
loop->counters.req_init++;
req->type = UV_UNKNOWN_REQ;
SET_REQ_SUCCESS(req);
}
INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) {
return CONTAINING_RECORD(overlapped, uv_req_t, overlapped);
}
INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
req->next_req = NULL;
if (loop->pending_reqs_tail) {
req->next_req = loop->pending_reqs_tail->next_req;
loop->pending_reqs_tail->next_req = req;
loop->pending_reqs_tail = req;
} else {
req->next_req = req;
loop->pending_reqs_tail = req;
}
}
#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \
do { \
switch (((uv_handle_t*) (req)->handle_at)->type) { \
case UV_TCP: \
uv_process_tcp_##method##_req(loop, \
(uv_tcp_t*) ((req)->handle_at), \
req); \
break; \
\
case UV_NAMED_PIPE: \
uv_process_pipe_##method##_req(loop, \
(uv_pipe_t*) ((req)->handle_at), \
req); \
break; \
\
case UV_TTY: \
uv_process_tty_##method##_req(loop, \
(uv_tty_t*) ((req)->handle_at), \
req); \
break; \
\
default: \
assert(0); \
} \
} while (0)
INLINE static void uv_process_reqs(uv_loop_t* loop) {
uv_req_t* req;
uv_req_t* first;
uv_req_t* next;
if (loop->pending_reqs_tail == NULL) {
return;
}
first = loop->pending_reqs_tail->next_req;
next = first;
loop->pending_reqs_tail = NULL;
while (next != NULL) {
req = next;
next = req->next_req != first ? req->next_req : NULL;
switch (req->type) {
case UV_READ:
DELEGATE_STREAM_REQ(loop, req, read, data);
break;
case UV_WRITE:
DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle);
break;
case UV_ACCEPT:
DELEGATE_STREAM_REQ(loop, req, accept, data);
break;
case UV_CONNECT:
DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle);
break;
case UV_SHUTDOWN:
/* Tcp shutdown requests don't come here. */
assert(((uv_shutdown_t*) req)->handle->type == UV_NAMED_PIPE);
uv_process_pipe_shutdown_req(
loop,
(uv_pipe_t*) ((uv_shutdown_t*) req)->handle,
(uv_shutdown_t*) req);
break;
case UV_UDP_RECV:
uv_process_udp_recv_req(loop, (uv_udp_t*) req->data, req);
break;
case UV_UDP_SEND:
uv_process_udp_send_req(loop,
((uv_udp_send_t*) req)->handle,
(uv_udp_send_t*) req);
break;
case UV_WAKEUP:
uv_process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
break;
case UV_POLL_REQ:
uv_process_poll_req(loop, (uv_poll_t*) req->data, req);
break;
case UV_GETADDRINFO:
uv_process_getaddrinfo_req(loop, (uv_getaddrinfo_t*) req);
break;
case UV_PROCESS_EXIT:
uv_process_proc_exit(loop, (uv_process_t*) req->data);
break;
case UV_PROCESS_CLOSE:
uv_process_proc_close(loop, (uv_process_t*) req->data);
break;
case UV_FS:
uv_process_fs_req(loop, (uv_fs_t*) req);
break;
case UV_WORK:
uv_process_work_req(loop, (uv_work_t*) req);
break;
case UV_FS_EVENT_REQ:
uv_process_fs_event_req(loop, req, (uv_fs_event_t*) req->data);
break;
default:
assert(0);
}
}
}
#endif /* UV_WIN_REQ_INL_H_ */

144
deps/uv/src/win/req.c

@ -23,147 +23,3 @@
#include "uv.h"
#include "internal.h"
void uv_req_init(uv_loop_t* loop, uv_req_t* req) {
loop->counters.req_init++;
req->type = UV_UNKNOWN_REQ;
SET_REQ_SUCCESS(req);
}
uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) {
return CONTAINING_RECORD(overlapped, uv_req_t, overlapped);
}
void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
req->next_req = NULL;
if (loop->pending_reqs_tail) {
req->next_req = loop->pending_reqs_tail->next_req;
loop->pending_reqs_tail->next_req = req;
loop->pending_reqs_tail = req;
} else {
req->next_req = req;
loop->pending_reqs_tail = req;
}
}
#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \
do { \
switch (((uv_handle_t*) (req)->handle_at)->type) { \
case UV_TCP: \
uv_process_tcp_##method##_req(loop, \
(uv_tcp_t*) ((req)->handle_at), \
req); \
break; \
\
case UV_NAMED_PIPE: \
uv_process_pipe_##method##_req(loop, \
(uv_pipe_t*) ((req)->handle_at), \
req); \
break; \
\
case UV_TTY: \
uv_process_tty_##method##_req(loop, \
(uv_tty_t*) ((req)->handle_at), \
req); \
break; \
\
default: \
assert(0); \
} \
} while (0)
void uv_process_reqs(uv_loop_t* loop) {
uv_req_t* req;
uv_req_t* first;
uv_req_t* next;
if (loop->pending_reqs_tail == NULL) {
return;
}
first = loop->pending_reqs_tail->next_req;
next = first;
loop->pending_reqs_tail = NULL;
while (next != NULL) {
req = next;
next = req->next_req != first ? req->next_req : NULL;
switch (req->type) {
case UV_READ:
DELEGATE_STREAM_REQ(loop, req, read, data);
break;
case UV_WRITE:
DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle);
break;
case UV_ACCEPT:
DELEGATE_STREAM_REQ(loop, req, accept, data);
break;
case UV_CONNECT:
DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle);
break;
case UV_SHUTDOWN:
/* Tcp shutdown requests don't come here. */
assert(((uv_shutdown_t*) req)->handle->type == UV_NAMED_PIPE);
uv_process_pipe_shutdown_req(
loop,
(uv_pipe_t*) ((uv_shutdown_t*) req)->handle,
(uv_shutdown_t*) req);
break;
case UV_UDP_RECV:
uv_process_udp_recv_req(loop, (uv_udp_t*) req->data, req);
break;
case UV_UDP_SEND:
uv_process_udp_send_req(loop,
((uv_udp_send_t*) req)->handle,
(uv_udp_send_t*) req);
break;
case UV_WAKEUP:
uv_process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
break;
case UV_POLL_REQ:
uv_process_poll_req(loop, (uv_poll_t*) req->data, req);
break;
case UV_GETADDRINFO:
uv_process_getaddrinfo_req(loop, (uv_getaddrinfo_t*) req);
break;
case UV_PROCESS_EXIT:
uv_process_proc_exit(loop, (uv_process_t*) req->data);
break;
case UV_PROCESS_CLOSE:
uv_process_proc_close(loop, (uv_process_t*) req->data);
break;
case UV_FS:
uv_process_fs_req(loop, (uv_fs_t*) req);
break;
case UV_WORK:
uv_process_work_req(loop, (uv_work_t*) req);
break;
case UV_FS_EVENT_REQ:
uv_process_fs_event_req(loop, req, (uv_fs_event_t*) req->data);
break;
default:
assert(0);
}
}
}

67
deps/uv/src/win/stream-inl.h

@ -0,0 +1,67 @@
/* 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_WIN_STREAM_INL_H_
#define UV_WIN_STREAM_INL_H_
#include <assert.h>
#include "uv.h"
#include "internal.h"
#include "handle-inl.h"
#include "req-inl.h"
INLINE static void uv_stream_init(uv_loop_t* loop, uv_stream_t* handle) {
uv_handle_init(loop, (uv_handle_t*) handle);
handle->write_queue_size = 0;
handle->activecnt = 0;
loop->counters.stream_init++;
}
INLINE static void uv_connection_init(uv_stream_t* handle) {
handle->flags |= UV_HANDLE_CONNECTION;
handle->write_reqs_pending = 0;
uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req));
handle->read_req.event_handle = NULL;
handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
handle->read_req.type = UV_READ;
handle->read_req.data = handle;
handle->shutdown_req = NULL;
}
INLINE static size_t uv_count_bufs(uv_buf_t bufs[], int count) {
size_t bytes = 0;
int i;
for (i = 0; i < count; i++) {
bytes += (size_t)bufs[i].len;
}
return bytes;
}
#endif /* UV_WIN_STREAM_INL_H_ */

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

@ -23,29 +23,8 @@
#include "uv.h"
#include "internal.h"
void uv_stream_init(uv_loop_t* loop, uv_stream_t* handle) {
uv_handle_init(loop, (uv_handle_t*) handle);
handle->write_queue_size = 0;
handle->activecnt = 0;
loop->counters.stream_init++;
}
void uv_connection_init(uv_stream_t* handle) {
handle->flags |= UV_HANDLE_CONNECTION;
handle->write_reqs_pending = 0;
uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req));
handle->read_req.event_handle = NULL;
handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
handle->read_req.type = UV_READ;
handle->read_req.data = handle;
handle->shutdown_req = NULL;
}
#include "handle-inl.h"
#include "req-inl.h"
int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
@ -178,18 +157,6 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
}
size_t uv_count_bufs(uv_buf_t bufs[], int count) {
size_t bytes = 0;
int i;
for (i = 0; i < count; i++) {
bytes += (size_t)bufs[i].len;
}
return bytes;
}
int uv_is_readable(const uv_stream_t* handle) {
return !(handle->flags & UV_HANDLE_EOF);
}

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

@ -23,6 +23,10 @@
#include "uv.h"
#include "internal.h"
#include "handle-inl.h"
#include "stream-inl.h"
#include "req-inl.h"
/*

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

@ -20,6 +20,7 @@
*/
#include <assert.h>
#include <limits.h>
#include "uv.h"
#include "internal.h"
@ -207,6 +208,44 @@ void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) {
}
int uv_sem_init(uv_sem_t* sem, unsigned int value) {
*sem = CreateSemaphore(NULL, value, INT_MAX, NULL);
return *sem ? 0 : -1;
}
void uv_sem_destroy(uv_sem_t* sem) {
if (!CloseHandle(*sem))
abort();
}
void uv_sem_post(uv_sem_t* sem) {
if (!ReleaseSemaphore(*sem, 1, NULL))
abort();
}
void uv_sem_wait(uv_sem_t* sem) {
if (WaitForSingleObject(*sem, INFINITE) != WAIT_OBJECT_0)
abort();
}
int uv_sem_trywait(uv_sem_t* sem) {
DWORD r = WaitForSingleObject(*sem, 0);
if (r == WAIT_OBJECT_0)
return 0;
if (r == WAIT_TIMEOUT)
return -1;
abort();
return -1; /* Satisfy the compiler. */
}
inline static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock) {
pInitializeSRWLock(&rwlock->srwlock_);
return 0;

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

@ -23,6 +23,7 @@
#include "uv.h"
#include "internal.h"
#include "req-inl.h"
static void uv_work_req_init(uv_loop_t* loop, uv_work_t* req,

47
deps/uv/src/win/timer.c

@ -25,15 +25,7 @@
#include "uv.h"
#include "internal.h"
#include "tree.h"
#undef NANOSEC
#define NANOSEC 1000000000
/* The resolution of the high-resolution clock. */
static uint64_t uv_hrtime_frequency_ = 0;
static uv_once_t uv_hrtime_init_guard_ = UV_ONCE_INIT;
#include "handle-inl.h"
void uv_update_time(uv_loop_t* loop) {
@ -58,43 +50,6 @@ int64_t uv_now(uv_loop_t* loop) {
}
static void uv_hrtime_init(void) {
LARGE_INTEGER frequency;
if (!QueryPerformanceFrequency(&frequency)) {
uv_hrtime_frequency_ = 0;
return;
}
uv_hrtime_frequency_ = frequency.QuadPart;
}
uint64_t uv_hrtime(void) {
LARGE_INTEGER counter;
uv_once(&uv_hrtime_init_guard_, uv_hrtime_init);
/* If the performance frequency is zero, there's no support. */
if (!uv_hrtime_frequency_) {
/* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */
return 0;
}
if (!QueryPerformanceCounter(&counter)) {
/* uv__set_sys_error(loop, GetLastError()); */
return 0;
}
/* Because we have no guarantee about the order of magnitude of the */
/* performance counter frequency, and there may not be much headroom to */
/* multiply by NANOSEC without overflowing, we use 128-bit math instead. */
return ((uint64_t) counter.LowPart * NANOSEC / uv_hrtime_frequency_) +
(((uint64_t) counter.HighPart * NANOSEC / uv_hrtime_frequency_)
<< 32);
}
static int uv_timer_compare(uv_timer_t* a, uv_timer_t* b) {
if (a->due < b->due)
return -1;

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

@ -26,6 +26,9 @@
#include "uv.h"
#include "internal.h"
#include "handle-inl.h"
#include "stream-inl.h"
#include "req-inl.h"
#define UNICODE_REPLACEMENT_CHARACTER (0xfffd)
@ -690,7 +693,7 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
if (!REQ_SUCCESS(req)) {
/* Read was not successful */
if ((handle->flags & UV_HANDLE_READING) &&
!(handle->flags & UV_HANDLE_TTY_RAW)) {
handle->read_line_handle != NULL) {
/* Real error */
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(loop, handle);

3
deps/uv/src/win/udp.c

@ -23,6 +23,9 @@
#include "uv.h"
#include "internal.h"
#include "handle-inl.h"
#include "stream-inl.h"
#include "req-inl.h"
/*

340
deps/uv/src/win/util.c

@ -47,11 +47,32 @@
*/
#define MAX_TITLE_LENGTH 8192
/* The number of nanoseconds in one second. */
#undef NANOSEC
#define NANOSEC 1000000000
/* Cached copy of the process title, plus a mutex guarding it. */
static char *process_title;
static uv_once_t uv_process_title_init_guard_ = UV_ONCE_INIT;
static CRITICAL_SECTION process_title_lock;
/* The tick frequency of the high-resolution clock. */
static uint64_t hrtime_frequency_ = 0;
/*
* One-time intialization code for functionality defined in util.c.
*/
void uv__util_init() {
/* Initialize process title access mutex. */
InitializeCriticalSection(&process_title_lock);
/* Retrieve high-resolution timer frequency. */
if (!QueryPerformanceFrequency((LARGE_INTEGER*) &hrtime_frequency_))
hrtime_frequency_ = 0;
}
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size) {
return WideCharToMultiByte(CP_UTF8,
@ -76,90 +97,100 @@ int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
}
int uv_exepath(char* buffer, size_t* size) {
int retVal;
size_t utf16Size;
wchar_t* utf16Buffer;
int uv_exepath(char* buffer, size_t* size_ptr) {
int utf8_len, utf16_buffer_len, utf16_len;
WCHAR* utf16_buffer;
if (!buffer || !size) {
if (buffer == NULL || size_ptr == NULL || *size_ptr == 0) {
return -1;
}
utf16Buffer = (wchar_t*)malloc(sizeof(wchar_t) * *size);
if (!utf16Buffer) {
retVal = -1;
goto done;
if (*size_ptr > 32768) {
/* Windows paths can never be longer than this. */
utf16_buffer_len = 32768;
} else {
utf16_buffer_len = (int) *size_ptr;
}
/* Get the path as UTF-16 */
utf16Size = GetModuleFileNameW(NULL, utf16Buffer, *size - 1);
if (utf16Size <= 0) {
/* uv__set_sys_error(loop, GetLastError()); */
retVal = -1;
goto done;
utf16_buffer = (wchar_t*) malloc(sizeof(WCHAR) * utf16_buffer_len);
if (!utf16_buffer) {
return -1;
}
utf16Buffer[utf16Size] = L'\0';
/* Convert to UTF-8 */
*size = uv_utf16_to_utf8(utf16Buffer, utf16Size, buffer, *size);
if (!*size) {
/* uv__set_sys_error(loop, GetLastError()); */
retVal = -1;
goto done;
/* Get the path as UTF-16. */
utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len);
if (utf16_len <= 0) {
goto error;
}
buffer[*size] = '\0';
retVal = 0;
/* utf16_len contains the length, *not* including the terminating null. */
utf16_buffer[utf16_len] = L'\0';
done:
if (utf16Buffer) {
free(utf16Buffer);
}
/* Convert to UTF-8 */
utf8_len = WideCharToMultiByte(CP_UTF8,
0,
utf16_buffer,
-1,
buffer,
*size_ptr > INT_MAX ? INT_MAX : (int) *size_ptr,
NULL,
NULL);
if (utf8_len == 0) {
goto error;
}
free(utf16_buffer);
/* utf8_len *does* include the terminating null at this point, but the */
/* returned size shouldn't. */
*size_ptr = utf8_len - 1;
return 0;
return retVal;
error:
free(utf16_buffer);
return -1;
}
uv_err_t uv_cwd(char* buffer, size_t size) {
uv_err_t err;
size_t utf8Size;
wchar_t* utf16Buffer = NULL;
if (!buffer || !size) {
err.code = UV_EINVAL;
goto done;
}
DWORD utf16_len;
WCHAR utf16_buffer[MAX_PATH + 1];
int r;
utf16Buffer = (wchar_t*)malloc(sizeof(wchar_t) * size);
if (!utf16Buffer) {
err.code = UV_ENOMEM;
goto done;
if (buffer == NULL || size == 0) {
return uv__new_artificial_error(UV_EINVAL);
}
if (!_wgetcwd(utf16Buffer, size - 1)) {
err = uv__new_sys_error(_doserrno);
goto done;
utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
if (utf16_len == 0) {
return uv__new_sys_error(GetLastError());
}
utf16Buffer[size - 1] = L'\0';
/* utf16_len contains the length, *not* including the terminating null. */
utf16_buffer[utf16_len] = L'\0';
/* Convert to UTF-8 */
utf8Size = uv_utf16_to_utf8(utf16Buffer, -1, buffer, size);
if (utf8Size == 0) {
err = uv__new_sys_error(GetLastError());
goto done;
/* The returned directory should not have a trailing slash, unless it */
/* points at a drive root, like c:\. Remove it if needed.*/
if (utf16_buffer[utf16_len - 1] == L'\\' &&
!(utf16_len == 3 && utf16_buffer[1] == L':')) {
utf16_len--;
utf16_buffer[utf16_len] = L'\0';
}
buffer[utf8Size] = '\0';
err = uv_ok_;
done:
if (utf16Buffer) {
free(utf16Buffer);
/* Convert to UTF-8 */
r = WideCharToMultiByte(CP_UTF8,
0,
utf16_buffer,
-1,
buffer,
size > INT_MAX ? INT_MAX : (int) size,
NULL,
NULL);
if (r == 0) {
return uv__new_sys_error(GetLastError());
}
return err;
return uv_ok_;
}
@ -266,17 +297,12 @@ char** uv_setup_args(int argc, char** argv) {
}
static void uv_process_title_init(void) {
InitializeCriticalSection(&process_title_lock);
}
uv_err_t uv_set_process_title(const char* title) {
uv_err_t err;
int length;
wchar_t* title_w = NULL;
uv_once(&uv_process_title_init_guard_, uv_process_title_init);
uv__once_init();
/* Find out how big the buffer for the wide-char title must be */
length = uv_utf8_to_utf16(title, NULL, 0);
@ -351,7 +377,7 @@ static int uv__get_process_title() {
uv_err_t uv_get_process_title(char* buffer, size_t size) {
uv_once(&uv_process_title_init_guard_, uv_process_title_init);
uv__once_init();
EnterCriticalSection(&process_title_lock);
/*
@ -370,6 +396,31 @@ uv_err_t uv_get_process_title(char* buffer, size_t size) {
}
uint64_t uv_hrtime(void) {
LARGE_INTEGER counter;
uv__once_init();
/* If the performance frequency is zero, there's no support. */
if (!hrtime_frequency_) {
/* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */
return 0;
}
if (!QueryPerformanceCounter(&counter)) {
/* uv__set_sys_error(loop, GetLastError()); */
return 0;
}
/* Because we have no guarantee about the order of magnitude of the */
/* performance counter frequency, and there may not be much headroom to */
/* multiply by NANOSEC without overflowing, we use 128-bit math instead. */
return ((uint64_t) counter.LowPart * NANOSEC / hrtime_frequency_) +
(((uint64_t) counter.HighPart * NANOSEC / hrtime_frequency_)
<< 32);
}
uv_err_t uv_resident_set_memory(size_t* rss) {
HANDLE current_process;
PROCESS_MEMORY_COUNTERS pmc;
@ -488,81 +539,148 @@ uv_err_t uv_uptime(double* uptime) {
uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
uv_err_t err;
char key[128];
HKEY processor_key = NULL;
DWORD cpu_speed = 0;
DWORD cpu_speed_length = sizeof(cpu_speed);
char cpu_brand[256];
DWORD cpu_brand_length = sizeof(cpu_brand);
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi;
DWORD sppi_size;
SYSTEM_INFO system_info;
DWORD cpu_count, i, r;
ULONG result_size;
size_t size;
uv_err_t err;
uv_cpu_info_t* cpu_info;
unsigned int i;
GetSystemInfo(&system_info);
*cpu_infos = NULL;
*count = 0;
*cpu_infos = (uv_cpu_info_t*)malloc(system_info.dwNumberOfProcessors *
sizeof(uv_cpu_info_t));
if (!(*cpu_infos)) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
uv__once_init();
*count = 0;
GetSystemInfo(&system_info);
cpu_count = system_info.dwNumberOfProcessors;
for (i = 0; i < system_info.dwNumberOfProcessors; i++) {
_snprintf(key, sizeof(key), "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", i);
size = cpu_count * sizeof(uv_cpu_info_t);
*cpu_infos = (uv_cpu_info_t*) malloc(size);
if (*cpu_infos == NULL) {
err = uv__new_artificial_error(UV_ENOMEM);
goto out;
}
memset(*cpu_infos, 0, size);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_QUERY_VALUE,
&processor_key) != ERROR_SUCCESS) {
if (i == 0) {
err = uv__new_sys_error(GetLastError());
goto done;
}
sppi_size = sizeof(*sppi) * cpu_count;
sppi = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*) malloc(sppi_size);
if (!sppi) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
continue;
r = pNtQuerySystemInformation(SystemProcessorPerformanceInformation,
sppi,
sppi_size,
&result_size);
if (r != ERROR_SUCCESS || result_size != sppi_size) {
err = uv__new_sys_error(GetLastError());
goto out;
}
for (i = 0; i < cpu_count; i++) {
WCHAR key_name[128];
HKEY processor_key;
DWORD cpu_speed;
DWORD cpu_speed_size = sizeof(cpu_speed);
WCHAR cpu_brand[256];
DWORD cpu_brand_size = sizeof(cpu_brand);
_snwprintf(key_name,
ARRAY_SIZE(key_name),
L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d",
i);
r = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
key_name,
0,
KEY_QUERY_VALUE,
&processor_key);
if (r != ERROR_SUCCESS) {
err = uv__new_sys_error(GetLastError());
goto out;
}
if (RegQueryValueEx(processor_key, "~MHz", NULL, NULL,
(LPBYTE)&cpu_speed, &cpu_speed_length)
!= ERROR_SUCCESS) {
if (RegQueryValueExW(processor_key,
L"~MHz",
NULL, NULL,
(BYTE*) &cpu_speed,
&cpu_speed_size) != ERROR_SUCCESS) {
err = uv__new_sys_error(GetLastError());
goto done;
RegCloseKey(processor_key);
goto out;
}
if (RegQueryValueEx(processor_key, "ProcessorNameString", NULL, NULL,
(LPBYTE)&cpu_brand, &cpu_brand_length)
!= ERROR_SUCCESS) {
if (RegQueryValueExW(processor_key,
L"ProcessorNameString",
NULL, NULL,
(BYTE*) &cpu_brand,
&cpu_brand_size) != ERROR_SUCCESS) {
err = uv__new_sys_error(GetLastError());
goto done;
RegCloseKey(processor_key);
goto out;
}
RegCloseKey(processor_key);
processor_key = NULL;
cpu_info = &(*cpu_infos)[i];
/* $TODO: find times on windows */
cpu_info->cpu_times.user = 0;
cpu_info->speed = cpu_speed;
cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000;
cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart -
sppi[i].IdleTime.QuadPart) / 10000;
cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000;
cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000;
cpu_info->cpu_times.nice = 0;
cpu_info->cpu_times.sys = 0;
cpu_info->cpu_times.idle = 0;
cpu_info->cpu_times.irq = 0;
cpu_info->model = strdup(cpu_brand);
cpu_info->speed = cpu_speed;
size = uv_utf16_to_utf8(cpu_brand,
cpu_brand_size / sizeof(WCHAR),
NULL,
0);
if (size == 0) {
err = uv__new_sys_error(GetLastError());
goto out;
}
/* Allocate 1 extra byte for the null terminator. */
cpu_info->model = (char*) malloc(size + 1);
if (cpu_info->model == NULL) {
err = uv__new_artificial_error(UV_ENOMEM);
goto out;
}
if (uv_utf16_to_utf8(cpu_brand,
cpu_brand_size / sizeof(WCHAR),
cpu_info->model,
size) == 0) {
err = uv__new_sys_error(GetLastError());
goto out;
}
/* Ensure that cpu_info->model is null terminated. */
cpu_info->model[size] = '\0';
(*count)++;
}
err = uv_ok_;
done:
if (processor_key) {
RegCloseKey(processor_key);
out:
if (sppi) {
free(sppi);
}
if (err.code != UV_OK) {
if (err.code != UV_OK &&
*cpu_infos != NULL) {
int i;
for (i = 0; i < *count; i++) {
/* This is safe because the cpu_infos memory area is zeroed out */
/* immediately after allocating it. */
free((*cpu_infos)[i].model);
}
free(*cpu_infos);
*cpu_infos = NULL;
*count = 0;
}

8
deps/uv/src/win/winapi.c

@ -29,6 +29,7 @@ sRtlNtStatusToDosError pRtlNtStatusToDosError;
sNtDeviceIoControlFile pNtDeviceIoControlFile;
sNtQueryInformationFile pNtQueryInformationFile;
sNtSetInformationFile pNtSetInformationFile;
sNtQuerySystemInformation pNtQuerySystemInformation;
sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
sCreateSymbolicLinkW pCreateSymbolicLinkW;
@ -79,6 +80,13 @@ void uv_winapi_init() {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress(
ntdll_module,
"NtQuerySystemInformation");
if (pNtQuerySystemInformation == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
kernel32_module = GetModuleHandleA("kernel32.dll");
if (kernel32_module == NULL) {
uv_fatal_error(GetLastError(), "GetModuleHandleA");

25
deps/uv/src/win/winapi.h

@ -28,11 +28,6 @@
/*
* Ntdll headers
*/
#ifndef _NTDEF_
typedef LONG NTSTATUS;
typedef NTSTATUS *PNTSTATUS;
#endif
#ifndef STATUS_SEVERITY_SUCCESS
# define STATUS_SEVERITY_SUCCESS 0x0
#endif
@ -4207,6 +4202,19 @@ typedef enum _FILE_INFORMATION_CLASS {
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER DpcTime;
LARGE_INTEGER InterruptTime;
ULONG InterruptCount;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
#ifndef SystemProcessorPerformanceInformation
# define SystemProcessorPerformanceInformation 8
#endif
#ifndef DEVICE_TYPE
# define DEVICE_TYPE DWORD
#endif
@ -4323,6 +4331,12 @@ typedef NTSTATUS (NTAPI *sNtSetInformationFile)
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass);
typedef NTSTATUS (NTAPI *sNtQuerySystemInformation)
(UINT SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength);
/*
* Kernel32 headers
@ -4410,6 +4424,7 @@ extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
extern sNtDeviceIoControlFile pNtDeviceIoControlFile;
extern sNtQueryInformationFile pNtQueryInformationFile;
extern sNtSetInformationFile pNtSetInformationFile;
extern sNtQuerySystemInformation pNtQuerySystemInformation;
/* Kernel32 function pointers */

14
deps/uv/test/run-tests.c

@ -24,6 +24,8 @@
#ifdef _WIN32
# include <io.h>
#else
# include <unistd.h>
#endif
#include "uv.h"
@ -120,5 +122,17 @@ static int maybe_run_test(int argc, char **argv) {
return 1;
}
if (strcmp(argv[1], "spawn_helper6") == 0) {
int r;
r = fprintf(stdout, "hello world\n");
ASSERT(r > 0);
r = fprintf(stderr, "hello errworld\n");
ASSERT(r > 0);
return 1;
}
return run_test(argv[1], TEST_TIMEOUT, 0);
}

16
deps/uv/test/test-list.h

@ -22,6 +22,9 @@
TEST_DECLARE (platform_output)
TEST_DECLARE (callback_order)
TEST_DECLARE (run_once)
TEST_DECLARE (semaphore_1)
TEST_DECLARE (semaphore_2)
TEST_DECLARE (semaphore_3)
TEST_DECLARE (tty)
TEST_DECLARE (stdio_over_pipes)
TEST_DECLARE (ipc_listen_before_write)
@ -37,6 +40,8 @@ TEST_DECLARE (pipe_ping_pong)
TEST_DECLARE (delayed_accept)
TEST_DECLARE (multiple_listen)
TEST_DECLARE (tcp_writealot)
TEST_DECLARE (tcp_connect_error_after_write)
TEST_DECLARE (tcp_shutdown_after_write)
TEST_DECLARE (tcp_bind_error_addrinuse)
TEST_DECLARE (tcp_bind_error_addrnotavail_1)
TEST_DECLARE (tcp_bind_error_addrnotavail_2)
@ -120,6 +125,7 @@ TEST_DECLARE (spawn_exit_code)
TEST_DECLARE (spawn_stdout)
TEST_DECLARE (spawn_stdin)
TEST_DECLARE (spawn_stdio_greater_than_3)
TEST_DECLARE (spawn_ignored_stdio)
TEST_DECLARE (spawn_and_kill)
TEST_DECLARE (spawn_detached)
TEST_DECLARE (spawn_and_kill_with_std)
@ -168,6 +174,7 @@ TEST_DECLARE (counters_init)
TEST_DECLARE (dlerror)
TEST_DECLARE (poll_duplex)
TEST_DECLARE (poll_unidirectional)
TEST_DECLARE (poll_close)
#ifdef _WIN32
TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows)
TEST_DECLARE (argument_escaping)
@ -191,6 +198,9 @@ TASK_LIST_START
TEST_ENTRY (callback_order)
#endif
TEST_ENTRY (run_once)
TEST_ENTRY (semaphore_1)
TEST_ENTRY (semaphore_2)
TEST_ENTRY (semaphore_3)
TEST_ENTRY (pipe_connect_bad_name)
TEST_ENTRY (pipe_connect_to_file)
@ -220,6 +230,10 @@ TASK_LIST_START
TEST_ENTRY (tcp_writealot)
TEST_HELPER (tcp_writealot, tcp4_echo_server)
TEST_ENTRY (tcp_shutdown_after_write)
TEST_HELPER (tcp_shutdown_after_write, tcp4_echo_server)
TEST_ENTRY (tcp_connect_error_after_write)
TEST_ENTRY (tcp_bind_error_addrinuse)
TEST_ENTRY (tcp_bind_error_addrnotavail_1)
TEST_ENTRY (tcp_bind_error_addrnotavail_2)
@ -330,11 +344,13 @@ TASK_LIST_START
TEST_ENTRY (poll_duplex)
TEST_ENTRY (poll_unidirectional)
TEST_ENTRY (poll_close)
TEST_ENTRY (spawn_exit_code)
TEST_ENTRY (spawn_stdout)
TEST_ENTRY (spawn_stdin)
TEST_ENTRY (spawn_stdio_greater_than_3)
TEST_ENTRY (spawn_ignored_stdio)
TEST_ENTRY (spawn_and_kill)
TEST_ENTRY (spawn_detached)
TEST_ENTRY (spawn_and_kill_with_std)

77
deps/uv/test/test-poll-close.c

@ -0,0 +1,77 @@
/* 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 <errno.h>
#ifndef _WIN32
# include <fcntl.h>
# include <sys/socket.h>
# include <unistd.h>
#endif
#include "uv.h"
#include "task.h"
#define NUM_SOCKETS 64
static int close_cb_called = 0;
static void poll_cb_fail(uv_poll_t* handle, int status, int events) {
ASSERT(0 && "poll_fail_cb should never be called");
}
static void close_cb(uv_handle_t* handle) {
close_cb_called++;
}
TEST_IMPL(poll_close) {
uv_os_sock_t sockets[NUM_SOCKETS];
uv_poll_t poll_handles[NUM_SOCKETS];
int i;
#ifdef _WIN32
{
struct WSAData wsa_data;
int r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
ASSERT(r == 0);
}
#endif
for (i = 0; i < NUM_SOCKETS; i++) {
sockets[i] = socket(AF_INET, SOCK_STREAM, 0);
uv_poll_init_socket(uv_default_loop(), &poll_handles[i], sockets[i]);
uv_poll_start(&poll_handles[i], UV_READABLE | UV_WRITABLE, NULL);
}
for (i = 0; i < NUM_SOCKETS; i++) {
uv_close((uv_handle_t*) &poll_handles[i], close_cb);
}
uv_run(uv_default_loop());
ASSERT(close_cb_called == NUM_SOCKETS);
return 0;
}

6
deps/uv/test/test-poll.c

@ -537,7 +537,7 @@ static void start_poll_test() {
#ifdef _WIN32
{
struct WSAData wsa_data;
r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
int r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
ASSERT(r == 0);
}
#endif
@ -550,10 +550,10 @@ static void start_poll_test() {
r = uv_run(uv_default_loop());
ASSERT(r == 0);
/* Assert that at most one percent of the writable wakeups was spurious. */
/* Assert that at most five percent of the writable wakeups was spurious. */
ASSERT(spurious_writable_wakeups == 0 ||
(valid_writable_wakeups + spurious_writable_wakeups) /
spurious_writable_wakeups > 100);
spurious_writable_wakeups > 20);
ASSERT(closed_connections == NUM_CLIENTS * 2);
}

111
deps/uv/test/test-semaphore.c

@ -0,0 +1,111 @@
/* 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 "task.h"
#include <stdlib.h>
#include <string.h>
typedef struct {
uv_mutex_t mutex;
uv_sem_t sem;
int delay;
volatile int posted;
} worker_config;
static void worker(void* arg) {
worker_config* c = arg;
if (c->delay)
uv_sleep(c->delay);
uv_mutex_lock(&c->mutex);
ASSERT(c->posted == 0);
uv_sem_post(&c->sem);
c->posted = 1;
uv_mutex_unlock(&c->mutex);
}
TEST_IMPL(semaphore_1) {
uv_thread_t thread;
worker_config wc;
memset(&wc, 0, sizeof(wc));
ASSERT(0 == uv_sem_init(&wc.sem, 0));
ASSERT(0 == uv_mutex_init(&wc.mutex));
ASSERT(0 == uv_thread_create(&thread, worker, &wc));
uv_sleep(100);
uv_mutex_lock(&wc.mutex);
ASSERT(wc.posted == 1);
uv_sem_wait(&wc.sem); /* should not block */
uv_mutex_unlock(&wc.mutex); /* ergo, it should be ok to unlock after wait */
ASSERT(0 == uv_thread_join(&thread));
uv_mutex_destroy(&wc.mutex);
uv_sem_destroy(&wc.sem);
return 0;
}
TEST_IMPL(semaphore_2) {
uv_thread_t thread;
worker_config wc;
memset(&wc, 0, sizeof(wc));
wc.delay = 100;
ASSERT(0 == uv_sem_init(&wc.sem, 0));
ASSERT(0 == uv_mutex_init(&wc.mutex));
ASSERT(0 == uv_thread_create(&thread, worker, &wc));
uv_sem_wait(&wc.sem);
ASSERT(0 == uv_thread_join(&thread));
uv_mutex_destroy(&wc.mutex);
uv_sem_destroy(&wc.sem);
return 0;
}
TEST_IMPL(semaphore_3) {
uv_sem_t sem;
ASSERT(0 == uv_sem_init(&sem, 3));
uv_sem_wait(&sem); /* should not block */
uv_sem_wait(&sem); /* should not block */
ASSERT(0 == uv_sem_trywait(&sem));
ASSERT(-1 == uv_sem_trywait(&sem));
uv_sem_post(&sem);
ASSERT(0 == uv_sem_trywait(&sem));
ASSERT(-1 == uv_sem_trywait(&sem));
uv_sem_destroy(&sem);
return 0;
}

21
deps/uv/test/test-spawn.c

@ -329,6 +329,27 @@ TEST_IMPL(spawn_stdio_greater_than_3) {
}
TEST_IMPL(spawn_ignored_stdio) {
int r;
init_process_options("spawn_helper6", exit_cb);
options.stdio = NULL;
options.stdio_count = 0;
r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == 0);
r = uv_run(uv_default_loop());
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);
return 0;
}
TEST_IMPL(spawn_and_kill) {
int r;

95
deps/uv/test/test-tcp-connect-error-after-write.c

@ -0,0 +1,95 @@
/* 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 "task.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int connect_cb_called;
static int write_cb_called;
static int close_cb_called;
static void close_cb(uv_handle_t* handle) {
close_cb_called++;
}
static void connect_cb(uv_connect_t* req, int status) {
ASSERT(status == -1);
connect_cb_called++;
uv_close((uv_handle_t*)req->handle, close_cb);
}
static void write_cb(uv_write_t* req, int status) {
ASSERT(status == -1);
write_cb_called++;
}
/*
* Try to connect to an address on which nothing listens, get ECONNREFUSED
* (uv errno 12) and get connect_cb() called once with status != 0.
* Related issue: https://github.com/joyent/libuv/issues/443
*/
TEST_IMPL(tcp_connect_error_after_write) {
uv_connect_t connect_req;
struct sockaddr_in addr;
uv_write_t write_req;
uv_tcp_t conn;
uv_buf_t buf;
int r;
#ifdef _WIN32
fprintf(stderr, "This test is disabled on Windows for now.\n");
fprintf(stderr, "See https://github.com/joyent/libuv/issues/444\n");
return 0; /* windows slackers... */
#endif
addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
buf = uv_buf_init("TEST", 4);
r = uv_tcp_init(uv_default_loop(), &conn);
ASSERT(r == 0);
r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb);
ASSERT(r == -1);
ASSERT(uv_last_error(uv_default_loop()).code == UV_EBADF);
r = uv_tcp_connect(&connect_req, &conn, addr, connect_cb);
ASSERT(r == 0);
r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb);
ASSERT(r == 0);
r = uv_run(uv_default_loop());
ASSERT(r == 0);
ASSERT(connect_cb_called == 1);
ASSERT(write_cb_called == 1);
ASSERT(close_cb_called == 1);
return 0;
}

129
deps/uv/test/test-tcp-shutdown-after-write.c

@ -0,0 +1,129 @@
/* 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 "task.h"
static void write_cb(uv_write_t* req, int status);
static void shutdown_cb(uv_shutdown_t* req, int status);
static uv_tcp_t conn;
static uv_timer_t timer;
static uv_connect_t connect_req;
static uv_write_t write_req;
static uv_shutdown_t shutdown_req;
static int connect_cb_called;
static int write_cb_called;
static int shutdown_cb_called;
static int conn_close_cb_called;
static int timer_close_cb_called;
static void close_cb(uv_handle_t* handle) {
if (handle == (uv_handle_t*)&conn)
conn_close_cb_called++;
else if (handle == (uv_handle_t*)&timer)
timer_close_cb_called++;
else
ASSERT(0 && "bad handle in close_cb");
}
static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) {
static char slab[64];
return uv_buf_init(slab, sizeof(slab));
}
static void timer_cb(uv_timer_t* handle, int status) {
uv_buf_t buf;
int r;
uv_close((uv_handle_t*)handle, close_cb);
buf = uv_buf_init("TEST", 4);
r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb);
ASSERT(r == 0);
r = uv_shutdown(&shutdown_req, (uv_stream_t*)&conn, shutdown_cb);
ASSERT(r == 0);
}
static void connect_cb(uv_connect_t* req, int status) {
ASSERT(status == 0);
connect_cb_called++;
}
static void read_cb(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
}
static void write_cb(uv_write_t* req, int status) {
ASSERT(status == 0);
write_cb_called++;
}
static void shutdown_cb(uv_shutdown_t* req, int status) {
ASSERT(status == 0);
shutdown_cb_called++;
uv_close((uv_handle_t*)&conn, close_cb);
}
TEST_IMPL(tcp_shutdown_after_write) {
struct sockaddr_in addr;
uv_loop_t* loop;
int r;
addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
loop = uv_default_loop();
r = uv_timer_init(loop, &timer);
ASSERT(r == 0);
r = uv_timer_start(&timer, timer_cb, 125, 0);
ASSERT(r == 0);
r = uv_tcp_init(loop, &conn);
ASSERT(r == 0);
r = uv_tcp_connect(&connect_req, &conn, addr, connect_cb);
ASSERT(r == 0);
r = uv_read_start((uv_stream_t*)&conn, alloc_cb, read_cb);
ASSERT(r == 0);
r = uv_run(loop);
ASSERT(r == 0);
ASSERT(connect_cb_called == 1);
ASSERT(write_cb_called == 1);
ASSERT(shutdown_cb_called == 1);
ASSERT(conn_close_cb_called == 1);
ASSERT(timer_close_cb_called == 1);
return 0;
}

6
deps/uv/test/test-tcp-writealot.c

@ -37,9 +37,9 @@ static int shutdown_cb_called = 0;
static int connect_cb_called = 0;
static int write_cb_called = 0;
static int close_cb_called = 0;
static int bytes_sent = 0;
static int bytes_sent_done = 0;
static int bytes_received_done = 0;
static size_t bytes_sent = 0;
static size_t bytes_sent_done = 0;
static size_t bytes_received_done = 0;
static uv_connect_t connect_req;
static uv_shutdown_t shutdown_req;

7
deps/uv/uv.gyp

@ -142,6 +142,7 @@
'src/win/fs-event.c',
'src/win/getaddrinfo.c',
'src/win/handle.c',
'src/win/handle-inl.h',
'src/win/internal.h',
'src/win/loop-watcher.c',
'src/win/pipe.c',
@ -149,7 +150,9 @@
'src/win/poll.c',
'src/win/process.c',
'src/win/req.c',
'src/win/req-inl.h',
'src/win/stream.c',
'src/win/stream-inl.h',
'src/win/tcp.c',
'src/win/tty.c',
'src/win/threadpool.c',
@ -327,9 +330,11 @@
'test/test-pipe-connect-error.c',
'test/test-platform-output.c',
'test/test-poll.c',
'test/test-poll-close.c',
'test/test-process-title.c',
'test/test-ref.c',
'test/test-run-once.c',
'test/test-semaphore.c',
'test/test-shutdown-close.c',
'test/test-shutdown-eof.c',
'test/test-spawn.c',
@ -337,6 +342,8 @@
'test/test-tcp-bind-error.c',
'test/test-tcp-bind6-error.c',
'test/test-tcp-close.c',
'test/test-tcp-connect-error-after-write.c',
'test/test-tcp-shutdown-after-write.c',
'test/test-tcp-flags.c',
'test/test-tcp-connect-error.c',
'test/test-tcp-connect-timeout.c',

Loading…
Cancel
Save