Browse Source

Upgrade libuv to 1be48f12a0

and bindings for new req interface
v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
130be31cff
  1. 16
      deps/uv/include/uv-unix.h
  2. 45
      deps/uv/include/uv-win.h
  3. 99
      deps/uv/include/uv.h
  4. 132
      deps/uv/src/uv-unix.c
  5. 570
      deps/uv/src/uv-win.c
  6. 31
      deps/uv/test/benchmark-ping-pongs.c
  7. 32
      deps/uv/test/benchmark-pump.c
  8. 22
      deps/uv/test/dns-server.c
  9. 20
      deps/uv/test/echo-server.c
  10. 21
      deps/uv/test/test-callback-stack.c
  11. 14
      deps/uv/test/test-connection-fail.c
  12. 7
      deps/uv/test/test-delayed-accept.c
  13. 31
      deps/uv/test/test-getsockname.c
  14. 31
      deps/uv/test/test-ping-pong.c
  15. 17
      deps/uv/test/test-shutdown-eof.c
  16. 32
      deps/uv/test/test-tcp-writealot.c
  17. 71
      src/tcp_wrap.cc

16
deps/uv/include/uv-unix.h

@ -41,14 +41,20 @@ typedef struct {
#define UV_REQ_BUFSML_SIZE (4) #define UV_REQ_BUFSML_SIZE (4)
#define UV_REQ_PRIVATE_FIELDS \ #define UV_REQ_PRIVATE_FIELDS /* empty */
int write_index; \
ev_timer timer; \ #define UV_WRITE_PRIVATE_FIELDS \
ngx_queue_t queue; \ ngx_queue_t queue; \
int write_index; \
uv_buf_t* bufs; \ uv_buf_t* bufs; \
int bufcnt; \ int bufcnt; \
uv_buf_t bufsml[UV_REQ_BUFSML_SIZE]; uv_buf_t bufsml[UV_REQ_BUFSML_SIZE];
#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */
#define UV_CONNECT_PRIVATE_FIELDS \
ngx_queue_t queue;
/* TODO: union or classes please! */ /* TODO: union or classes please! */
#define UV_HANDLE_PRIVATE_FIELDS \ #define UV_HANDLE_PRIVATE_FIELDS \
@ -67,8 +73,8 @@ typedef struct {
int delayed_error; \ int delayed_error; \
uv_connection_cb connection_cb; \ uv_connection_cb connection_cb; \
int accepted_fd; \ int accepted_fd; \
uv_req_t *connect_req; \ uv_connect_t *connect_req; \
uv_req_t *shutdown_req; \ uv_shutdown_t *shutdown_req; \
ev_io read_watcher; \ ev_io read_watcher; \
ev_io write_watcher; \ ev_io write_watcher; \
ngx_queue_t write_queue; \ ngx_queue_t write_queue; \

45
deps/uv/include/uv-win.h

@ -42,22 +42,6 @@ typedef struct uv_buf_t {
char* base; char* base;
} uv_buf_t; } uv_buf_t;
/*
* Private uv_pipe_instance state.
*/
typedef enum {
UV_PIPEINSTANCE_CONNECTED = 0,
UV_PIPEINSTANCE_DISCONNECTED,
UV_PIPEINSTANCE_ACTIVE
} uv_pipeinstance_state;
/* Used to store active pipe instances inside a linked list. */
typedef struct uv_pipe_instance_s {
HANDLE handle;
uv_pipeinstance_state state;
struct uv_pipe_instance_s* next;
} uv_pipe_instance_t;
#define UV_REQ_PRIVATE_FIELDS \ #define UV_REQ_PRIVATE_FIELDS \
union { \ union { \
/* Used by I/O operations */ \ /* Used by I/O operations */ \
@ -66,13 +50,21 @@ typedef struct uv_pipe_instance_s {
size_t queued_bytes; \ size_t queued_bytes; \
}; \ }; \
}; \ }; \
int flags; \
uv_err_t error; \ uv_err_t error; \
struct uv_req_s* next_req; struct uv_req_s* next_req;
#define UV_WRITE_PRIVATE_FIELDS \
/* empty */
#define UV_CONNECT_PRIVATE_FIELDS \
/* empty */
#define UV_SHUTDOWN_PRIVATE_FIELDS \
/* empty */
#define uv_stream_connection_fields \ #define uv_stream_connection_fields \
unsigned int write_reqs_pending; \ unsigned int write_reqs_pending; \
uv_req_t* shutdown_req; uv_shutdown_t* shutdown_req;
#define uv_stream_server_fields \ #define uv_stream_server_fields \
uv_connection_cb connection_cb; uv_connection_cb connection_cb;
@ -81,7 +73,7 @@ typedef struct uv_pipe_instance_s {
unsigned int reqs_pending; \ unsigned int reqs_pending; \
uv_alloc_cb alloc_cb; \ uv_alloc_cb alloc_cb; \
uv_read_cb read_cb; \ uv_read_cb read_cb; \
struct uv_req_s read_req; \ uv_req_t read_req; \
union { \ union { \
struct { uv_stream_connection_fields }; \ struct { uv_stream_connection_fields }; \
struct { uv_stream_server_fields }; \ struct { uv_stream_server_fields }; \
@ -94,17 +86,19 @@ typedef struct uv_pipe_instance_s {
}; \ }; \
SOCKET accept_socket; \ SOCKET accept_socket; \
char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \ char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \
struct uv_req_s accept_req; struct uv_req_s accept_req; \
#define uv_pipe_server_fields \ #define uv_pipe_server_fields \
char* name; \ char* name; \
uv_pipe_instance_t* connections; \ struct uv_pipe_accept_s { \
struct uv_req_s accept_reqs[4]; UV_REQ_FIELDS \
HANDLE pipeHandle; \
struct uv_pipe_accept_s* next_pending; \
} accept_reqs[4]; \
struct uv_pipe_accept_s* pending_accepts;
#define uv_pipe_connection_fields \ #define uv_pipe_connection_fields \
uv_pipe_t* server; \ HANDLE handle;
uv_pipe_instance_t* connection; \
uv_pipe_instance_t clientConnection;
#define UV_PIPE_PRIVATE_FIELDS \ #define UV_PIPE_PRIVATE_FIELDS \
union { \ union { \
@ -120,6 +114,7 @@ typedef struct uv_pipe_instance_s {
#define UV_ASYNC_PRIVATE_FIELDS \ #define UV_ASYNC_PRIVATE_FIELDS \
struct uv_req_s async_req; \ struct uv_req_s async_req; \
uv_async_cb async_cb; \
/* char to avoid alignment issues */ \ /* char to avoid alignment issues */ \
char volatile async_sent; char volatile async_sent;

99
deps/uv/include/uv.h

@ -48,10 +48,13 @@ typedef struct uv_timer_s uv_timer_t;
typedef struct uv_prepare_s uv_prepare_t; typedef struct uv_prepare_s uv_prepare_t;
typedef struct uv_check_s uv_check_t; typedef struct uv_check_s uv_check_t;
typedef struct uv_idle_s uv_idle_t; typedef struct uv_idle_s uv_idle_t;
typedef struct uv_req_s uv_req_t;
typedef struct uv_async_s uv_async_t; typedef struct uv_async_s uv_async_t;
typedef struct uv_getaddrinfo_s uv_getaddrinfo_t; typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
/* Request types */
typedef struct uv_req_s uv_req_t;
typedef struct uv_shutdown_s uv_shutdown_t;
typedef struct uv_write_s uv_write_t;
typedef struct uv_connect_s uv_connect_t;
#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__) #if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__)
# include "uv-unix.h" # include "uv-unix.h"
@ -70,9 +73,9 @@ typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
*/ */
typedef uv_buf_t (*uv_alloc_cb)(uv_stream_t* tcp, size_t suggested_size); typedef uv_buf_t (*uv_alloc_cb)(uv_stream_t* tcp, size_t suggested_size);
typedef void (*uv_read_cb)(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf); typedef void (*uv_read_cb)(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf);
typedef void (*uv_write_cb)(uv_req_t* req, int status); typedef void (*uv_write_cb)(uv_write_t* req, int status);
typedef void (*uv_connect_cb)(uv_req_t* req, int status); typedef void (*uv_connect_cb)(uv_connect_t* req, int status);
typedef void (*uv_shutdown_cb)(uv_req_t* req, int status); typedef void (*uv_shutdown_cb)(uv_shutdown_t* req, int status);
typedef void (*uv_connection_cb)(uv_handle_t* server, int status); typedef void (*uv_connection_cb)(uv_handle_t* server, int status);
typedef void (*uv_close_cb)(uv_handle_t* handle); typedef void (*uv_close_cb)(uv_handle_t* handle);
typedef void (*uv_timer_cb)(uv_timer_t* handle, int status); typedef void (*uv_timer_cb)(uv_timer_t* handle, int status);
@ -168,23 +171,34 @@ struct uv_err_s {
}; };
struct uv_req_s { #define UV_REQ_FIELDS \
/* read-only */ /* read-only */ \
uv_req_type type; uv_req_type type; \
/* public */ /* public */ \
uv_handle_t* handle; void* data; \
void *(*cb)(void *); /* private */ \
void* data;
/* private */
UV_REQ_PRIVATE_FIELDS UV_REQ_PRIVATE_FIELDS
/* Abstract base class of all requests. */
struct uv_req_s {
UV_REQ_FIELDS
}; };
/* /*
* Initialize a request for use with uv_write, uv_shutdown, or uv_connect. * Shutdown the outgoing (write) side of a duplex stream. It waits for
* pending write requests to complete. The handle should refer to a
* initialized stream. req should be an uninitalized shutdown request
* struct. The cb is a called after shutdown is complete.
*/ */
void uv_req_init(uv_req_t* req, uv_handle_t* handle, void *(*cb)(void *)); struct uv_shutdown_s {
UV_REQ_FIELDS
uv_stream_t* handle;
uv_shutdown_cb cb;
UV_SHUTDOWN_PRIVATE_FIELDS
};
int uv_shutdown(uv_req_t* req); int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb);
#define UV_HANDLE_FIELDS \ #define UV_HANDLE_FIELDS \
@ -251,7 +265,8 @@ int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read_cb read_cb);
int uv_read_stop(uv_stream_t*); int uv_read_stop(uv_stream_t*);
/* Write data to stream. Buffers are written in order. Example: /*
* Write data to stream. Buffers are written in order. Example:
* *
* uv_buf_t a[] = { * uv_buf_t a[] = {
* { .base = "1", .len = 1 }, * { .base = "1", .len = 1 },
@ -268,7 +283,15 @@ int uv_read_stop(uv_stream_t*);
* uv_write(req, b, 2); * uv_write(req, b, 2);
* *
*/ */
int uv_write(uv_req_t* req, uv_buf_t bufs[], int bufcnt); struct uv_write_s {
UV_REQ_FIELDS
uv_write_cb cb;
uv_stream_t* handle;
UV_WRITE_PRIVATE_FIELDS
};
int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
uv_write_cb cb);
/* /*
@ -287,8 +310,23 @@ int uv_tcp_init(uv_tcp_t* handle);
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in); int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in);
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6); int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6);
int uv_tcp_connect(uv_req_t* req, struct sockaddr_in); /*
int uv_tcp_connect6(uv_req_t* req, struct sockaddr_in6); * uv_tcp_connect, uv_tcp_connect6
* These functions establish IPv4 and IPv6 TCP connections. Provide an
* initialized TCP handle and an uninitialized uv_connect_t*. The callback
* will be made when the connection is estabished.
*/
struct uv_connect_s {
UV_REQ_FIELDS
uv_connect_cb cb;
uv_stream_t* handle;
UV_CONNECT_PRIVATE_FIELDS
};
int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
struct sockaddr_in address, uv_connect_cb cb);
int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
struct sockaddr_in6 address, uv_connect_cb cb);
int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb); int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
@ -298,10 +336,10 @@ int uv_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen);
/* /*
* A subclass of uv_stream_t representing a pipe stream or pipe server. * A subclass of uv_stream_t representing a pipe stream or pipe server.
*/ */
struct uv_pipe_s { struct uv_pipe_s {
UV_HANDLE_FIELDS UV_HANDLE_FIELDS
UV_STREAM_FIELDS UV_STREAM_FIELDS
UV_PIPE_PRIVATE_FIELDS UV_PIPE_PRIVATE_FIELDS
}; };
int uv_pipe_init(uv_pipe_t* handle); int uv_pipe_init(uv_pipe_t* handle);
@ -310,7 +348,8 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name);
int uv_pipe_listen(uv_pipe_t* handle, uv_connection_cb cb); int uv_pipe_listen(uv_pipe_t* handle, uv_connection_cb cb);
int uv_pipe_connect(uv_req_t* req, const char* name); int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
const char* name, uv_connect_cb cb);
/* /*
@ -489,7 +528,7 @@ int uv_exepath(char* buffer, size_t* size);
extern uint64_t uv_hrtime(void); extern uint64_t uv_hrtime(void);
/* the presence of this union forces similar struct layout */ /* the presence of these unions force similar struct layout */
union uv_any_handle { union uv_any_handle {
uv_tcp_t tcp; uv_tcp_t tcp;
uv_pipe_t pipe; uv_pipe_t pipe;
@ -501,6 +540,14 @@ union uv_any_handle {
uv_getaddrinfo_t getaddrinfo; uv_getaddrinfo_t getaddrinfo;
}; };
union uv_any_req {
uv_req_t req;
uv_write_t write;
uv_connect_t connect;
uv_shutdown_t shutdown;
};
/* Diagnostic counters */ /* Diagnostic counters */
typedef struct { typedef struct {
uint64_t req_init; uint64_t req_init;

132
deps/uv/src/uv-unix.c

@ -59,6 +59,7 @@ struct uv_ares_data_s {
static struct uv_ares_data_s ares_data; static struct uv_ares_data_s ares_data;
void uv__req_init(uv_req_t*);
void uv__tcp_io(EV_P_ ev_io* watcher, int revents); void uv__tcp_io(EV_P_ ev_io* watcher, int revents);
void uv__next(EV_P_ ev_idle* watcher, int revents); void uv__next(EV_P_ ev_idle* watcher, int revents);
static void uv__tcp_connect(uv_tcp_t*); static void uv__tcp_connect(uv_tcp_t*);
@ -518,9 +519,9 @@ void uv__finish_close(uv_handle_t* handle) {
} }
uv_req_t* uv_write_queue_head(uv_tcp_t* tcp) { uv_write_t* uv_write_queue_head(uv_tcp_t* tcp) {
ngx_queue_t* q; ngx_queue_t* q;
uv_req_t* req; uv_write_t* req;
if (ngx_queue_empty(&tcp->write_queue)) { if (ngx_queue_empty(&tcp->write_queue)) {
return NULL; return NULL;
@ -531,7 +532,7 @@ uv_req_t* uv_write_queue_head(uv_tcp_t* tcp) {
return NULL; return NULL;
} }
req = ngx_queue_data(q, struct uv_req_s, queue); req = ngx_queue_data(q, struct uv_write_s, queue);
assert(req); assert(req);
return req; return req;
@ -552,8 +553,7 @@ void uv__next(EV_P_ ev_idle* watcher, int revents) {
static void uv__drain(uv_tcp_t* tcp) { static void uv__drain(uv_tcp_t* tcp) {
uv_req_t* req; uv_shutdown_t* req;
uv_shutdown_cb cb;
assert(!uv_write_queue_head(tcp)); assert(!uv_write_queue_head(tcp));
assert(tcp->write_queue_size == 0); assert(tcp->write_queue_size == 0);
@ -567,16 +567,19 @@ static void uv__drain(uv_tcp_t* tcp) {
assert(tcp->shutdown_req); assert(tcp->shutdown_req);
req = tcp->shutdown_req; req = tcp->shutdown_req;
cb = (uv_shutdown_cb)req->cb;
if (shutdown(tcp->fd, SHUT_WR)) { if (shutdown(tcp->fd, SHUT_WR)) {
/* Error. Report it. User should call uv_close(). */ /* Error. Report it. User should call uv_close(). */
uv_err_new((uv_handle_t*)tcp, errno); uv_err_new((uv_handle_t*)tcp, errno);
if (cb) cb(req, -1); if (req->cb) {
req->cb(req, -1);
}
} else { } else {
uv_err_new((uv_handle_t*)tcp, 0); uv_err_new((uv_handle_t*)tcp, 0);
uv_flag_set((uv_handle_t*)tcp, UV_SHUT); uv_flag_set((uv_handle_t*)tcp, UV_SHUT);
if (cb) cb(req, 0); if (req->cb) {
req->cb(req, 0);
}
} }
} }
} }
@ -585,8 +588,8 @@ static void uv__drain(uv_tcp_t* tcp) {
/* On success returns NULL. On error returns a pointer to the write request /* On success returns NULL. On error returns a pointer to the write request
* which had the error. * which had the error.
*/ */
static uv_req_t* uv__write(uv_tcp_t* tcp) { static uv_write_t* uv__write(uv_tcp_t* tcp) {
uv_req_t* req; uv_write_t* req;
struct iovec* iov; struct iovec* iov;
int iovcnt; int iovcnt;
ssize_t n; ssize_t n;
@ -602,7 +605,7 @@ static uv_req_t* uv__write(uv_tcp_t* tcp) {
return NULL; return NULL;
} }
assert(req->handle == (uv_handle_t*)tcp); assert(req->handle == (uv_stream_t*)tcp);
/* Cast to iovec. We had to have our own uv_buf_t instead of iovec /* Cast to iovec. We had to have our own uv_buf_t instead of iovec
* because Windows's WSABUF is not an iovec. * because Windows's WSABUF is not an iovec.
@ -691,23 +694,20 @@ static uv_req_t* uv__write(uv_tcp_t* tcp) {
static void uv__write_callbacks(uv_tcp_t* tcp) { static void uv__write_callbacks(uv_tcp_t* tcp) {
uv_write_cb cb;
int callbacks_made = 0; int callbacks_made = 0;
ngx_queue_t* q; ngx_queue_t* q;
uv_req_t* req; uv_write_t* req;
while (!ngx_queue_empty(&tcp->write_completed_queue)) { while (!ngx_queue_empty(&tcp->write_completed_queue)) {
/* Pop a req off write_completed_queue. */ /* Pop a req off write_completed_queue. */
q = ngx_queue_head(&tcp->write_completed_queue); q = ngx_queue_head(&tcp->write_completed_queue);
assert(q); assert(q);
req = ngx_queue_data(q, struct uv_req_s, queue); req = ngx_queue_data(q, struct uv_write_s, queue);
ngx_queue_remove(q); ngx_queue_remove(q);
cb = (uv_write_cb) req->cb;
/* NOTE: call callback AFTER freeing the request data. */ /* NOTE: call callback AFTER freeing the request data. */
if (cb) { if (req->cb) {
cb(req, 0); req->cb(req, 0);
} }
callbacks_made++; callbacks_made++;
@ -772,10 +772,16 @@ void uv__read(uv_tcp_t* tcp) {
} }
int uv_shutdown(uv_req_t* req) { int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
uv_tcp_t* tcp = (uv_tcp_t*)req->handle; uv_tcp_t* tcp = (uv_tcp_t*)handle;
assert(handle->type == UV_TCP &&
"uv_shutdown (unix) only supports uv_tcp_t right now");
assert(tcp->fd >= 0); assert(tcp->fd >= 0);
assert(tcp->type == UV_TCP);
/* Initialize request */
uv__req_init((uv_req_t*)req);
req->handle = handle;
req->cb = cb;
if (uv_flag_is_set((uv_handle_t*)tcp, UV_SHUT) || if (uv_flag_is_set((uv_handle_t*)tcp, UV_SHUT) ||
uv_flag_is_set((uv_handle_t*)tcp, UV_CLOSED) || uv_flag_is_set((uv_handle_t*)tcp, UV_CLOSED) ||
@ -796,11 +802,11 @@ int uv_shutdown(uv_req_t* req) {
void uv__tcp_io(EV_P_ ev_io* watcher, int revents) { void uv__tcp_io(EV_P_ ev_io* watcher, int revents) {
uv_tcp_t* tcp = watcher->data; uv_tcp_t* tcp = watcher->data;
assert(tcp->type == UV_TCP);
assert(watcher == &tcp->read_watcher || assert(watcher == &tcp->read_watcher ||
watcher == &tcp->write_watcher); watcher == &tcp->write_watcher);
assert(tcp->fd >= 0); assert(tcp->fd >= 0);
assert(!uv_flag_is_set((uv_handle_t*)tcp, UV_CLOSING)); assert(!uv_flag_is_set((uv_handle_t*)tcp, UV_CLOSING));
if (tcp->connect_req) { if (tcp->connect_req) {
@ -811,13 +817,11 @@ void uv__tcp_io(EV_P_ ev_io* watcher, int revents) {
} }
if (revents & EV_WRITE) { if (revents & EV_WRITE) {
uv_req_t* req = uv__write(tcp); uv_write_t* req = uv__write(tcp);
if (req) { if (req) {
/* Error. Notify the user. */ /* Error. Notify the user. */
uv_write_cb cb = (uv_write_cb) req->cb; if (req->cb) {
req->cb(req, -1);
if (cb) {
cb(req, -1);
} }
} else { } else {
uv__write_callbacks(tcp); uv__write_callbacks(tcp);
@ -834,13 +838,11 @@ void uv__tcp_io(EV_P_ ev_io* watcher, int revents) {
*/ */
static void uv__tcp_connect(uv_tcp_t* tcp) { static void uv__tcp_connect(uv_tcp_t* tcp) {
int error; int error;
uv_req_t* req; uv_connect_t* req = tcp->connect_req;
uv_connect_cb connect_cb;
socklen_t errorsize = sizeof(int); socklen_t errorsize = sizeof(int);
assert(tcp->type == UV_TCP);
assert(tcp->fd >= 0); assert(tcp->fd >= 0);
req = tcp->connect_req;
assert(req); assert(req);
if (tcp->delayed_error) { if (tcp->delayed_error) {
@ -860,9 +862,8 @@ static void uv__tcp_connect(uv_tcp_t* tcp) {
/* Successful connection */ /* Successful connection */
tcp->connect_req = NULL; tcp->connect_req = NULL;
connect_cb = (uv_connect_cb) req->cb; if (req->cb) {
if (connect_cb) { req->cb(req, 0);
connect_cb(req, 0);
} }
} else if (error == EINPROGRESS) { } else if (error == EINPROGRESS) {
@ -873,18 +874,15 @@ static void uv__tcp_connect(uv_tcp_t* tcp) {
uv_err_new((uv_handle_t*)tcp, error); uv_err_new((uv_handle_t*)tcp, error);
tcp->connect_req = NULL; tcp->connect_req = NULL;
if (req->cb) {
connect_cb = (uv_connect_cb) req->cb; req->cb(req, -1);
if (connect_cb) {
connect_cb(req, -1);
} }
} }
} }
static int uv__connect(uv_req_t* req, struct sockaddr* addr, static int uv__connect(uv_connect_t* req, uv_tcp_t* tcp, struct sockaddr* addr,
socklen_t addrlen) { socklen_t addrlen, uv_connect_cb cb) {
uv_tcp_t* tcp = (uv_tcp_t*)req->handle;
int r; int r;
if (tcp->fd <= 0) { if (tcp->fd <= 0) {
@ -901,6 +899,9 @@ static int uv__connect(uv_req_t* req, struct sockaddr* addr,
} }
} }
uv__req_init((uv_req_t*)req);
req->cb = cb;
req->handle = (uv_stream_t*)tcp;
req->type = UV_CONNECT; req->type = UV_CONNECT;
ngx_queue_init(&req->queue); ngx_queue_init(&req->queue);
@ -947,17 +948,21 @@ static int uv__connect(uv_req_t* req, struct sockaddr* addr,
} }
int uv_tcp_connect(uv_req_t* req, struct sockaddr_in addr) { int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
assert(addr.sin_family == AF_INET); struct sockaddr_in address, uv_connect_cb cb) {
return uv__connect(req, (struct sockaddr*) &addr, assert(handle->type == UV_TCP);
sizeof(struct sockaddr_in)); assert(address.sin_family == AF_INET);
return uv__connect(req, handle, (struct sockaddr*) &address,
sizeof(struct sockaddr_in), cb);
} }
int uv_tcp_connect6(uv_req_t* req, struct sockaddr_in6 addr) { int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
assert(addr.sin6_family == AF_INET6); struct sockaddr_in6 address, uv_connect_cb cb) {
return uv__connect(req, (struct sockaddr*) &addr, assert(handle->type == UV_TCP);
sizeof(struct sockaddr_in6)); assert(address.sin6_family == AF_INET6);
return uv__connect(req, handle, (struct sockaddr*) &address,
sizeof(struct sockaddr_in6), cb);
} }
@ -997,9 +1002,21 @@ static size_t uv__buf_count(uv_buf_t bufs[], int bufcnt) {
/* The buffers to be written must remain valid until the callback is called. /* The buffers to be written must remain valid until the callback is called.
* This is not required for the uv_buf_t array. * This is not required for the uv_buf_t array.
*/ */
int uv_write(uv_req_t* req, uv_buf_t bufs[], int bufcnt) { int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
uv_tcp_t* tcp = (uv_tcp_t*)req->handle; uv_write_cb cb) {
int empty_queue = (tcp->write_queue_size == 0); int empty_queue;
uv_tcp_t* tcp = (uv_tcp_t*)handle;
/* Initialize the req */
uv__req_init((uv_req_t*) req);
req->cb = cb;
req->handle = handle;
ngx_queue_init(&req->queue);
assert(handle->type == UV_TCP &&
"uv_write (unix) does not yet support other types of streams");
empty_queue = (tcp->write_queue_size == 0);
assert(tcp->fd >= 0); assert(tcp->fd >= 0);
ngx_queue_init(&req->queue); ngx_queue_init(&req->queue);
@ -1118,12 +1135,10 @@ int uv_read_stop(uv_stream_t* stream) {
} }
void uv_req_init(uv_req_t* req, uv_handle_t* handle, void *(*cb)(void *)) { void uv__req_init(uv_req_t* req) {
uv_counters()->req_init++; uv_counters()->req_init++;
req->type = UV_UNKNOWN_REQ; req->type = UV_UNKNOWN_REQ;
req->cb = cb; req->data = NULL;
req->handle = handle;
ngx_queue_init(&req->queue);
} }
@ -1634,6 +1649,7 @@ int uv_pipe_listen(uv_pipe_t* handle, uv_connection_cb cb) {
} }
int uv_pipe_connect(uv_req_t* req, const char* name) { int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
const char* name, uv_connect_cb cb) {
assert(0 && "implement me"); assert(0 && "implement me");
} }

570
deps/uv/src/uv-win.c

File diff suppressed because it is too large

31
deps/uv/test/benchmark-ping-pongs.c

@ -34,8 +34,8 @@ typedef struct {
int pongs; int pongs;
int state; int state;
uv_tcp_t tcp; uv_tcp_t tcp;
uv_req_t connect_req; uv_connect_t connect_req;
uv_req_t shutdown_req; uv_shutdown_t shutdown_req;
} pinger_t; } pinger_t;
typedef struct buf_s { typedef struct buf_s {
@ -90,7 +90,7 @@ static void pinger_close_cb(uv_handle_t* handle) {
} }
static void pinger_write_cb(uv_req_t *req, int status) { static void pinger_write_cb(uv_write_t* req, int status) {
ASSERT(status == 0); ASSERT(status == 0);
free(req); free(req);
@ -98,22 +98,20 @@ static void pinger_write_cb(uv_req_t *req, int status) {
static void pinger_write_ping(pinger_t* pinger) { static void pinger_write_ping(pinger_t* pinger) {
uv_req_t *req; uv_write_t* req;
uv_buf_t buf; uv_buf_t buf;
buf.base = (char*)&PING; buf.base = (char*)&PING;
buf.len = strlen(PING); buf.len = strlen(PING);
req = (uv_req_t*)malloc(sizeof(*req)); req = malloc(sizeof *req);
uv_req_init(req, (uv_handle_t*)(&pinger->tcp), pinger_write_cb); if (uv_write(req, (uv_stream_t*) &pinger->tcp, &buf, 1, pinger_write_cb)) {
if (uv_write(req, &buf, 1)) {
FATAL("uv_write failed"); FATAL("uv_write failed");
} }
} }
static void pinger_shutdown_cb(uv_handle_t* handle, int status) { static void pinger_shutdown_cb(uv_shutdown_t* req, int status) {
ASSERT(status == 0); ASSERT(status == 0);
pinger_shutdown_cb_called++; pinger_shutdown_cb_called++;
@ -151,8 +149,7 @@ static void pinger_read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
if (pinger->state == 0) { if (pinger->state == 0) {
pinger->pongs++; pinger->pongs++;
if (uv_now() - start_time > TIME) { if (uv_now() - start_time > TIME) {
uv_req_init(&pinger->shutdown_req, (uv_handle_t*)tcp, pinger_shutdown_cb); uv_shutdown(&pinger->shutdown_req, (uv_stream_t*) tcp, pinger_shutdown_cb);
uv_shutdown(&pinger->shutdown_req);
break; break;
} else { } else {
pinger_write_ping(pinger); pinger_write_ping(pinger);
@ -164,14 +161,14 @@ static void pinger_read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
} }
static void pinger_connect_cb(uv_req_t *req, int status) { static void pinger_connect_cb(uv_connect_t* req, int status) {
pinger_t *pinger = (pinger_t*)req->handle->data; pinger_t *pinger = (pinger_t*)req->handle->data;
ASSERT(status == 0); ASSERT(status == 0);
pinger_write_ping(pinger); pinger_write_ping(pinger);
if (uv_read_start((uv_stream_t*)(req->handle), buf_alloc, pinger_read_cb)) { if (uv_read_start(req->handle, buf_alloc, pinger_read_cb)) {
FATAL("uv_read_start failed"); FATAL("uv_read_start failed");
} }
} }
@ -193,13 +190,9 @@ static void pinger_new() {
pinger->tcp.data = pinger; pinger->tcp.data = pinger;
/* We are never doing multiple reads/connects at a time anyway. */
/* so these handles can be pre-initialized. */
uv_req_init(&pinger->connect_req, (uv_handle_t*)&pinger->tcp,
pinger_connect_cb);
uv_tcp_bind(&pinger->tcp, client_addr); uv_tcp_bind(&pinger->tcp, client_addr);
r = uv_tcp_connect(&pinger->connect_req, server_addr);
r = uv_tcp_connect(&pinger->connect_req, &pinger->tcp, server_addr, pinger_connect_cb);
ASSERT(!r); ASSERT(!r);
} }

32
deps/uv/test/benchmark-pump.c

@ -183,22 +183,22 @@ static void read_cb(uv_stream_t* stream, ssize_t bytes, uv_buf_t buf) {
} }
static void write_cb(uv_req_t *req, int status) { static void write_cb(uv_write_t* req, int status) {
uv_buf_t* buf = (uv_buf_t*) req->data; uv_buf_t* buf = (uv_buf_t*) req->data;
ASSERT(status == 0); ASSERT(status == 0);
req_free(req); req_free((uv_req_t*) req);
nsent += sizeof write_buffer; nsent += sizeof write_buffer;
nsent_total += sizeof write_buffer; nsent_total += sizeof write_buffer;
do_write((uv_stream_t*)req->handle); do_write((uv_stream_t*) req->handle);
} }
static void do_write(uv_stream_t* stream) { static void do_write(uv_stream_t* stream) {
uv_req_t* req; uv_write_t* req;
uv_buf_t buf; uv_buf_t buf;
int r; int r;
@ -206,23 +206,21 @@ static void do_write(uv_stream_t* stream) {
buf.len = sizeof write_buffer; buf.len = sizeof write_buffer;
while (stream->write_queue_size == 0) { while (stream->write_queue_size == 0) {
req = req_alloc(); req = (uv_write_t*) req_alloc();
uv_req_init(req, (uv_handle_t*)stream, write_cb); r = uv_write(req, stream, &buf, 1, write_cb);
r = uv_write(req, &buf, 1);
ASSERT(r == 0); ASSERT(r == 0);
} }
} }
static void connect_cb(uv_req_t* req, int status) { static void connect_cb(uv_connect_t* req, int status) {
int i; int i;
if (status) LOG(uv_strerror(uv_last_error())); if (status) LOG(uv_strerror(uv_last_error()));
ASSERT(status == 0); ASSERT(status == 0);
write_sockets++; write_sockets++;
req_free(req); req_free((uv_req_t*) req);
maybe_connect_some(); maybe_connect_some();
@ -238,7 +236,7 @@ static void connect_cb(uv_req_t* req, int status) {
static void maybe_connect_some() { static void maybe_connect_some() {
uv_req_t* req; uv_connect_t* req;
uv_tcp_t* tcp; uv_tcp_t* tcp;
uv_pipe_t* pipe; uv_pipe_t* pipe;
int r; int r;
@ -251,9 +249,8 @@ static void maybe_connect_some() {
r = uv_tcp_init(tcp); r = uv_tcp_init(tcp);
ASSERT(r == 0); ASSERT(r == 0);
req = req_alloc(); req = (uv_connect_t*) req_alloc();
uv_req_init(req, (uv_handle_t*)tcp, connect_cb); r = uv_tcp_connect(req, tcp, connect_addr, connect_cb);
r = uv_tcp_connect(req, connect_addr);
ASSERT(r == 0); ASSERT(r == 0);
} else { } else {
pipe = &pipe_write_handles[max_connect_socket++]; pipe = &pipe_write_handles[max_connect_socket++];
@ -261,9 +258,8 @@ static void maybe_connect_some() {
r = uv_pipe_init(pipe); r = uv_pipe_init(pipe);
ASSERT(r == 0); ASSERT(r == 0);
req = req_alloc(); req = (uv_connect_t*) req_alloc();
uv_req_init(req, (uv_handle_t*)pipe, connect_cb); r = uv_pipe_connect(req, pipe, TEST_PIPENAME, connect_cb);
r = uv_pipe_connect(req, TEST_PIPENAME);
ASSERT(r == 0); ASSERT(r == 0);
#ifdef _WIN32 #ifdef _WIN32
@ -308,7 +304,7 @@ static void connection_cb(uv_handle_t* s, int status) {
*/ */
typedef struct req_list_s { typedef struct req_list_s {
uv_req_t uv_req; union uv_any_req uv_req;
struct req_list_s* next; struct req_list_s* next;
} req_list_t; } req_list_t;

22
deps/uv/test/dns-server.c

@ -27,7 +27,7 @@
typedef struct { typedef struct {
uv_req_t req; uv_write_t req;
uv_buf_t buf; uv_buf_t buf;
} write_req_t; } write_req_t;
@ -51,7 +51,7 @@ static int server_closed;
static uv_tcp_t server; static uv_tcp_t server;
static void after_write(uv_req_t* req, int status); static void after_write(uv_write_t* req, int status);
static void after_read(uv_stream_t*, ssize_t nread, uv_buf_t buf); static void after_read(uv_stream_t*, ssize_t nread, uv_buf_t buf);
static void on_close(uv_handle_t* peer); static void on_close(uv_handle_t* peer);
static void on_server_close(uv_handle_t* handle); static void on_server_close(uv_handle_t* handle);
@ -67,7 +67,7 @@ unsigned char qrecord[] = {5, 'e', 'c', 'h', 'o', 's', 3, 's', 'r', 'v', 0, 0, 1
unsigned char arecord[] = {0xc0, 0x0c, 0, 1, 0, 1, 0, 0, 5, 0xbd, 0, 4, 10, 0, 1, 1 }; unsigned char arecord[] = {0xc0, 0x0c, 0, 1, 0, 1, 0, 0, 5, 0xbd, 0, 4, 10, 0, 1, 1 };
static void after_write(uv_req_t* req, int status) { static void after_write(uv_write_t* req, int status) {
write_req_t* wr; write_req_t* wr;
if (status) { if (status) {
@ -84,8 +84,8 @@ static void after_write(uv_req_t* req, int status) {
} }
static void after_shutdown(uv_req_t* req, int status) { static void after_shutdown(uv_shutdown_t* req, int status) {
uv_close(req->handle, on_close); uv_close((uv_handle_t*) req->handle, on_close);
free(req); free(req);
} }
@ -116,7 +116,7 @@ static void addrsp(write_req_t* wr, char* hdr) {
} }
static void process_req(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) { static void process_req(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
write_req_t *wr; write_req_t* wr;
dnshandle* dns = (dnshandle*)handle; dnshandle* dns = (dnshandle*)handle;
char hdrbuf[DNSREC_LEN]; char hdrbuf[DNSREC_LEN];
int hdrbuf_remaining = DNSREC_LEN; int hdrbuf_remaining = DNSREC_LEN;
@ -127,7 +127,6 @@ static void process_req(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
int usingprev = 0; int usingprev = 0;
wr = (write_req_t*) malloc(sizeof *wr); wr = (write_req_t*) malloc(sizeof *wr);
uv_req_init(&wr->req, (uv_handle_t*)handle, after_write);
wr->buf.base = (char*)malloc(WRITE_BUF_LEN); wr->buf.base = (char*)malloc(WRITE_BUF_LEN);
wr->buf.len = 0; wr->buf.len = 0;
@ -197,7 +196,7 @@ static void process_req(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
/* send write buffer */ /* send write buffer */
if (wr->buf.len > 0) { if (wr->buf.len > 0) {
if (uv_write(&wr->req, &wr->buf, 1)) { if (uv_write((uv_write_t*) &wr->req, handle, &wr->buf, 1, after_write)) {
FATAL("uv_write failed"); FATAL("uv_write failed");
} }
} }
@ -217,7 +216,7 @@ static void process_req(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
} }
static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) { static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
uv_req_t* req; uv_shutdown_t* req;
if (nread < 0) { if (nread < 0) {
/* Error or EOF */ /* Error or EOF */
@ -227,9 +226,8 @@ static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
free(buf.base); free(buf.base);
} }
req = (uv_req_t*) malloc(sizeof *req); req = malloc(sizeof *req);
uv_req_init(req, (uv_handle_t*)handle, after_shutdown); uv_shutdown(req, handle, after_shutdown);
uv_shutdown(req);
return; return;
} }

20
deps/uv/test/echo-server.c

@ -25,7 +25,7 @@
#include <stdlib.h> #include <stdlib.h>
typedef struct { typedef struct {
uv_req_t req; uv_write_t req;
uv_buf_t buf; uv_buf_t buf;
} write_req_t; } write_req_t;
@ -35,14 +35,14 @@ static uv_tcp_t tcpServer;
static uv_pipe_t pipeServer; static uv_pipe_t pipeServer;
static uv_handle_t* server; static uv_handle_t* server;
static void after_write(uv_req_t* req, int status); static void after_write(uv_write_t* req, int status);
static void after_read(uv_stream_t*, ssize_t nread, uv_buf_t buf); static void after_read(uv_stream_t*, ssize_t nread, uv_buf_t buf);
static void on_close(uv_handle_t* peer); static void on_close(uv_handle_t* peer);
static void on_server_close(uv_handle_t* handle); static void on_server_close(uv_handle_t* handle);
static void on_connection(uv_handle_t*, int status); static void on_connection(uv_handle_t*, int status);
static void after_write(uv_req_t* req, int status) { static void after_write(uv_write_t* req, int status) {
write_req_t* wr; write_req_t* wr;
if (status) { if (status) {
@ -59,8 +59,8 @@ static void after_write(uv_req_t* req, int status) {
} }
static void after_shutdown(uv_req_t* req, int status) { static void after_shutdown(uv_shutdown_t* req, int status) {
uv_close(req->handle, on_close); uv_close((uv_handle_t*)req->handle, on_close);
free(req); free(req);
} }
@ -68,7 +68,7 @@ static void after_shutdown(uv_req_t* req, int status) {
static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) { static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
int i; int i;
write_req_t *wr; write_req_t *wr;
uv_req_t* req; uv_shutdown_t* req;
if (nread < 0) { if (nread < 0) {
/* Error or EOF */ /* Error or EOF */
@ -78,9 +78,8 @@ static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
free(buf.base); free(buf.base);
} }
req = (uv_req_t*) malloc(sizeof *req); req = (uv_shutdown_t*) malloc(sizeof *req);
uv_req_init(req, (uv_handle_t*)handle, (void *(*)(void *))after_shutdown); uv_shutdown(req, handle, after_shutdown);
uv_shutdown(req);
return; return;
} }
@ -103,10 +102,9 @@ static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
wr = (write_req_t*) malloc(sizeof *wr); wr = (write_req_t*) malloc(sizeof *wr);
uv_req_init(&wr->req, (uv_handle_t*)handle, (void *(*)(void *))after_write);
wr->buf.base = buf.base; wr->buf.base = buf.base;
wr->buf.len = nread; wr->buf.len = nread;
if (uv_write(&wr->req, &wr->buf, 1)) { if (uv_write(&wr->req, handle, &wr->buf, 1, after_write)) {
FATAL("uv_write failed"); FATAL("uv_write failed");
} }
} }

21
deps/uv/test/test-callback-stack.c

@ -32,7 +32,9 @@ static const char MESSAGE[] = "Failure is for the weak. Everyone dies alone.";
static uv_tcp_t client; static uv_tcp_t client;
static uv_timer_t timer; static uv_timer_t timer;
static uv_req_t connect_req, write_req, shutdown_req; static uv_connect_t connect_req;
static uv_write_t write_req;
static uv_shutdown_t shutdown_req;
static int nested = 0; static int nested = 0;
static int close_cb_called = 0; static int close_cb_called = 0;
@ -59,7 +61,7 @@ static void close_cb(uv_handle_t* handle) {
} }
static void shutdown_cb(uv_req_t* req, int status) { static void shutdown_cb(uv_shutdown_t* req, int status) {
ASSERT(status == 0); ASSERT(status == 0);
ASSERT(nested == 0 && "shutdown_cb must be called from a fresh stack"); ASSERT(nested == 0 && "shutdown_cb must be called from a fresh stack");
@ -97,11 +99,10 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
/* from a fresh stack. */ /* from a fresh stack. */
if (bytes_received == sizeof MESSAGE) { if (bytes_received == sizeof MESSAGE) {
nested++; nested++;
uv_req_init(&shutdown_req, (uv_handle_t*)tcp, (void *(*)(void *))shutdown_cb);
puts("Shutdown"); puts("Shutdown");
if (uv_shutdown(&shutdown_req)) { if (uv_shutdown(&shutdown_req, (uv_stream_t*)tcp, shutdown_cb)) {
FATAL("uv_shutdown failed"); FATAL("uv_shutdown failed");
} }
nested--; nested--;
@ -131,7 +132,7 @@ static void timer_cb(uv_timer_t* handle, int status) {
} }
static void write_cb(uv_req_t* req, int status) { static void write_cb(uv_write_t* req, int status) {
int r; int r;
ASSERT(status == 0); ASSERT(status == 0);
@ -154,7 +155,7 @@ static void write_cb(uv_req_t* req, int status) {
} }
static void connect_cb(uv_req_t* req, int status) { static void connect_cb(uv_connect_t* req, int status) {
uv_buf_t buf; uv_buf_t buf;
puts("Connected. Write some data to echo server..."); puts("Connected. Write some data to echo server...");
@ -167,9 +168,7 @@ static void connect_cb(uv_req_t* req, int status) {
buf.base = (char*) &MESSAGE; buf.base = (char*) &MESSAGE;
buf.len = sizeof MESSAGE; buf.len = sizeof MESSAGE;
uv_req_init(&write_req, req->handle, (void *(*)(void *))write_cb); if (uv_write(&write_req, (uv_stream_t*)req->handle, &buf, 1, write_cb)) {
if (uv_write(&write_req, &buf, 1)) {
FATAL("uv_write failed"); FATAL("uv_write failed");
} }
@ -191,10 +190,8 @@ TEST_IMPL(callback_stack) {
puts("Connecting..."); puts("Connecting...");
nested++; nested++;
uv_req_init(&connect_req, (uv_handle_t*)&client,
(void *(*)(void *))connect_cb);
if (uv_tcp_connect(&connect_req, addr)) { if (uv_tcp_connect(&connect_req, &client, addr, connect_cb)) {
FATAL("uv_tcp_connect failed"); FATAL("uv_tcp_connect failed");
} }
nested--; nested--;

14
deps/uv/test/test-connection-fail.c

@ -27,7 +27,7 @@
static uv_tcp_t tcp; static uv_tcp_t tcp;
static uv_req_t req; static uv_connect_t req;
static int connect_cb_calls; static int connect_cb_calls;
static int close_cb_calls; static int close_cb_calls;
@ -66,18 +66,18 @@ static void timer_cb(uv_timer_t* handle, int status) {
} }
static void on_connect_with_close(uv_req_t *req, int status) { static void on_connect_with_close(uv_connect_t *req, int status) {
ASSERT(&tcp == (uv_tcp_t*) req->handle); ASSERT((uv_stream_t*) &tcp == req->handle);
ASSERT(status == -1); ASSERT(status == -1);
ASSERT(uv_last_error().code == UV_ECONNREFUSED); ASSERT(uv_last_error().code == UV_ECONNREFUSED);
connect_cb_calls++; connect_cb_calls++;
ASSERT(close_cb_calls == 0); ASSERT(close_cb_calls == 0);
uv_close(req->handle, on_close); uv_close((uv_handle_t*)req->handle, on_close);
} }
static void on_connect_without_close(uv_req_t *req, int status) { static void on_connect_without_close(uv_connect_t *req, int status) {
ASSERT(status == -1); ASSERT(status == -1);
ASSERT(uv_last_error().code == UV_ECONNREFUSED); ASSERT(uv_last_error().code == UV_ECONNREFUSED);
connect_cb_calls++; connect_cb_calls++;
@ -103,10 +103,8 @@ void connection_fail(uv_connect_cb connect_cb) {
/* We are never doing multiple reads/connects at a time anyway. */ /* We are never doing multiple reads/connects at a time anyway. */
/* so these handles can be pre-initialized. */ /* so these handles can be pre-initialized. */
uv_req_init(&req, (uv_handle_t*)&tcp, (void *(*)(void *))connect_cb);
uv_tcp_bind(&tcp, client_addr); uv_tcp_bind(&tcp, client_addr);
r = uv_tcp_connect(&req, server_addr); r = uv_tcp_connect(&req, &tcp, server_addr, connect_cb);
ASSERT(!r); ASSERT(!r);
uv_run(); uv_run();

7
deps/uv/test/test-delayed-accept.c

@ -147,7 +147,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
} }
static void connect_cb(uv_req_t* req, int status) { static void connect_cb(uv_connect_t* req, int status) {
int r; int r;
ASSERT(req != NULL); ASSERT(req != NULL);
@ -167,7 +167,7 @@ static void connect_cb(uv_req_t* req, int status) {
static void client_connect() { static void client_connect() {
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT); struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof *client); uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof *client);
uv_req_t* connect_req = (uv_req_t*)malloc(sizeof *connect_req); uv_connect_t* connect_req = malloc(sizeof *connect_req);
int r; int r;
ASSERT(client != NULL); ASSERT(client != NULL);
@ -176,8 +176,7 @@ static void client_connect() {
r = uv_tcp_init(client); r = uv_tcp_init(client);
ASSERT(r == 0); ASSERT(r == 0);
uv_req_init(connect_req, (uv_handle_t*)client, (void *(*)(void *))connect_cb); r = uv_tcp_connect(connect_req, client, addr, connect_cb);
r = uv_tcp_connect(connect_req, addr);
ASSERT(r == 0); ASSERT(r == 0);
} }

31
deps/uv/test/test-getsockname.c

@ -29,7 +29,7 @@ static int getsocknamecount = 0;
static uv_tcp_t tcp; static uv_tcp_t tcp;
static uv_req_t connect_req; static uv_connect_t connect_req;
static uv_tcp_t tcpServer; static uv_tcp_t tcpServer;
@ -47,22 +47,23 @@ static void on_close(uv_handle_t* peer) {
} }
static void after_shutdown(uv_req_t* req, int status) { static void after_shutdown(uv_shutdown_t* req, int status) {
uv_close(req->handle, on_close); uv_close((uv_handle_t*) req->handle, on_close);
free(req); free(req);
} }
static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) { static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
uv_req_t* req; uv_shutdown_t* req;
int r;
if (buf.base) { if (buf.base) {
free(buf.base); free(buf.base);
} }
req = (uv_req_t*) malloc(sizeof *req); req = (uv_shutdown_t*) malloc(sizeof *req);
uv_req_init(req, (uv_handle_t*)handle, (void *(*)(void *))after_shutdown); r = uv_shutdown(req, handle, after_shutdown);
uv_shutdown(req); ASSERT(r == 0);
} }
@ -102,16 +103,18 @@ static void on_connection(uv_handle_t* server, int status) {
} }
static void on_connect(void* req) { static void on_connect(uv_connect_t* req, int status) {
struct sockaddr sockname; struct sockaddr sockname;
int namelen = sizeof(sockname); int namelen = sizeof(sockname);
int status; int r;
status = uv_getsockname(&tcp, &sockname, &namelen); ASSERT(status == 0);
if (status != 0) {
r = uv_getsockname(&tcp, &sockname, &namelen);
if (r != 0) {
fprintf(stderr, "uv_getsockname error (connector) %d\n", uv_last_error().code); fprintf(stderr, "uv_getsockname error (connector) %d\n", uv_last_error().code);
} }
ASSERT(status == 0); ASSERT(r == 0);
getsocknamecount++; getsocknamecount++;
@ -162,9 +165,7 @@ static void tcp_connector() {
tcp.data = &connect_req; tcp.data = &connect_req;
ASSERT(!r); ASSERT(!r);
uv_req_init(&connect_req, (uv_handle_t*)(&tcp), (void *(*)(void *))on_connect); r = uv_tcp_connect(&connect_req, &tcp, server_addr, on_connect);
r = uv_tcp_connect(&connect_req, server_addr);
ASSERT(!r); ASSERT(!r);
} }

31
deps/uv/test/test-ping-pong.c

@ -43,8 +43,7 @@ typedef struct {
uv_tcp_t tcp; uv_tcp_t tcp;
uv_pipe_t pipe; uv_pipe_t pipe;
}; };
uv_req_t connect_req; uv_connect_t connect_req;
uv_req_t read_req;
char read_buffer[BUFSIZE]; char read_buffer[BUFSIZE];
} pinger_t; } pinger_t;
@ -70,25 +69,22 @@ static void pinger_on_close(uv_handle_t* handle) {
} }
static void pinger_after_write(uv_req_t *req, int status) { static void pinger_after_write(uv_write_t *req, int status) {
ASSERT(status == 0); ASSERT(status == 0);
free(req); free(req);
} }
static void pinger_write_ping(pinger_t* pinger) { static void pinger_write_ping(pinger_t* pinger) {
uv_req_t *req; uv_write_t *req;
uv_buf_t buf; uv_buf_t buf;
buf.base = (char*)&PING; buf.base = (char*)&PING;
buf.len = strlen(PING); buf.len = strlen(PING);
req = (uv_req_t*)malloc(sizeof(*req)); req = malloc(sizeof(uv_write_t));
uv_req_init(req, (uv_handle_t*)(&pinger->tcp),
(void *(*)(void *))pinger_after_write);
if (uv_write(req, &buf, 1)) { if (uv_write(req, (uv_stream_t*)&pinger->tcp, &buf, 1, pinger_after_write)) {
FATAL("uv_write failed"); FATAL("uv_write failed");
} }
@ -134,7 +130,7 @@ static void pinger_read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
} }
static void pinger_on_connect(uv_req_t *req, int status) { static void pinger_on_connect(uv_connect_t *req, int status) {
pinger_t *pinger = (pinger_t*)req->handle->data; pinger_t *pinger = (pinger_t*)req->handle->data;
ASSERT(status == 0); ASSERT(status == 0);
@ -162,10 +158,8 @@ static void tcp_pinger_v6_new() {
/* We are never doing multiple reads/connects at a time anyway. */ /* We are never doing multiple reads/connects at a time anyway. */
/* so these handles can be pre-initialized. */ /* so these handles can be pre-initialized. */
uv_req_init(&pinger->connect_req, (uv_handle_t*)(&pinger->tcp), r = uv_tcp_connect6(&pinger->connect_req, &pinger->tcp, server_addr,
(void *(*)(void *))pinger_on_connect); pinger_on_connect);
r = uv_tcp_connect6(&pinger->connect_req, server_addr);
ASSERT(!r); ASSERT(!r);
} }
@ -186,10 +180,7 @@ static void tcp_pinger_new() {
/* We are never doing multiple reads/connects at a time anyway. */ /* We are never doing multiple reads/connects at a time anyway. */
/* so these handles can be pre-initialized. */ /* so these handles can be pre-initialized. */
uv_req_init(&pinger->connect_req, (uv_handle_t*)(&pinger->tcp), r = uv_tcp_connect(&pinger->connect_req, &pinger->tcp, server_addr, pinger_on_connect);
(void *(*)(void *))pinger_on_connect);
r = uv_tcp_connect(&pinger->connect_req, server_addr);
ASSERT(!r); ASSERT(!r);
} }
@ -209,10 +200,8 @@ static void pipe_pinger_new() {
/* We are never doing multiple reads/connects at a time anyway. */ /* We are never doing multiple reads/connects at a time anyway. */
/* so these handles can be pre-initialized. */ /* so these handles can be pre-initialized. */
uv_req_init(&pinger->connect_req, (uv_handle_t*)(&pinger->pipe),
(void *(*)(void *))pinger_on_connect);
r = uv_pipe_connect(&pinger->connect_req, TEST_PIPENAME); r = uv_pipe_connect(&pinger->connect_req, &pinger->pipe, TEST_PIPENAME, pinger_on_connect);
ASSERT(!r); ASSERT(!r);
} }

17
deps/uv/test/test-shutdown-eof.c

@ -26,7 +26,9 @@
static uv_timer_t timer; static uv_timer_t timer;
static uv_tcp_t tcp; static uv_tcp_t tcp;
static uv_req_t connect_req, write_req, shutdown_req; static uv_connect_t connect_req;
static uv_write_t write_req;
static uv_shutdown_t shutdown_req;
static uv_buf_t qbuf; static uv_buf_t qbuf;
static int got_q; static int got_q;
static int got_eof; static int got_eof;
@ -74,7 +76,7 @@ static void read_cb(uv_stream_t* t, ssize_t nread, uv_buf_t buf) {
} }
static void shutdown_cb(uv_req_t *req, int status) { static void shutdown_cb(uv_shutdown_t *req, int status) {
ASSERT(req == &shutdown_req); ASSERT(req == &shutdown_req);
ASSERT(called_connect_cb == 1); ASSERT(called_connect_cb == 1);
@ -87,7 +89,7 @@ static void shutdown_cb(uv_req_t *req, int status) {
} }
static void connect_cb(uv_req_t *req, int status) { static void connect_cb(uv_connect_t *req, int status) {
ASSERT(status == 0); ASSERT(status == 0);
ASSERT(req == &connect_req); ASSERT(req == &connect_req);
@ -98,12 +100,10 @@ static void connect_cb(uv_req_t *req, int status) {
* Write the letter 'Q' to gracefully kill the echo-server. This will not * Write the letter 'Q' to gracefully kill the echo-server. This will not
* effect our connection. * effect our connection.
*/ */
uv_req_init(&write_req, (uv_handle_t*)&tcp, NULL); uv_write(&write_req, (uv_stream_t*) &tcp, &qbuf, 1, NULL);
uv_write(&write_req, &qbuf, 1);
/* Shutdown our end of the connection. */ /* Shutdown our end of the connection. */
uv_req_init(&shutdown_req, (uv_handle_t*)&tcp, (void *(*)(void *))shutdown_cb); uv_shutdown(&shutdown_req, (uv_stream_t*) &tcp, shutdown_cb);
uv_shutdown(&shutdown_req);
called_connect_cb++; called_connect_cb++;
ASSERT(called_shutdown_cb == 0); ASSERT(called_shutdown_cb == 0);
@ -165,8 +165,7 @@ TEST_IMPL(shutdown_eof) {
r = uv_tcp_init(&tcp); r = uv_tcp_init(&tcp);
ASSERT(!r); ASSERT(!r);
uv_req_init(&connect_req, (uv_handle_t*) &tcp, (void *(*)(void *))connect_cb); r = uv_tcp_connect(&connect_req, &tcp, server_addr, connect_cb);
r = uv_tcp_connect(&connect_req, server_addr);
ASSERT(!r); ASSERT(!r);
uv_run(); uv_run();

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

@ -62,7 +62,7 @@ static void close_cb(uv_handle_t* handle) {
} }
static void shutdown_cb(uv_req_t* req, int status) { static void shutdown_cb(uv_shutdown_t* req, int status) {
uv_tcp_t* tcp; uv_tcp_t* tcp;
ASSERT(req); ASSERT(req);
@ -104,7 +104,7 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
} }
static void write_cb(uv_req_t* req, int status) { static void write_cb(uv_write_t* req, int status) {
ASSERT(req != NULL); ASSERT(req != NULL);
if (status) { if (status) {
@ -120,9 +120,11 @@ static void write_cb(uv_req_t* req, int status) {
} }
static void connect_cb(uv_req_t* req, int status) { static void connect_cb(uv_connect_t* req, int status) {
uv_buf_t send_bufs[CHUNKS_PER_WRITE]; uv_buf_t send_bufs[CHUNKS_PER_WRITE];
uv_tcp_t* tcp; uv_tcp_t* tcp;
uv_write_t* write_req;
uv_shutdown_t* shutdown_req;
int i, j, r; int i, j, r;
ASSERT(req != NULL); ASSERT(req != NULL);
@ -141,26 +143,21 @@ static void connect_cb(uv_req_t* req, int status) {
bytes_sent += CHUNK_SIZE; bytes_sent += CHUNK_SIZE;
} }
req = (uv_req_t*)malloc(sizeof *req); write_req = malloc(sizeof(uv_write_t));
ASSERT(req != NULL); ASSERT(write_req != NULL);
uv_req_init(req, (uv_handle_t*)tcp, (void *(*)(void *))write_cb); r = uv_write(write_req, (uv_stream_t*) tcp, (uv_buf_t*)&send_bufs,
r = uv_write(req, (uv_buf_t*)&send_bufs, CHUNKS_PER_WRITE); CHUNKS_PER_WRITE, write_cb);
ASSERT(r == 0); ASSERT(r == 0);
} }
/* Shutdown on drain. FIXME: dealloc req? */ /* Shutdown on drain. FIXME: dealloc req? */
req = (uv_req_t*) malloc(sizeof(uv_req_t)); shutdown_req = malloc(sizeof(uv_shutdown_t));
ASSERT(req != NULL); ASSERT(shutdown_req != NULL);
uv_req_init(req, (uv_handle_t*)tcp, (void *(*)(void *))shutdown_cb); r = uv_shutdown(shutdown_req, (uv_stream_t*)tcp, shutdown_cb);
r = uv_shutdown(req);
ASSERT(r == 0); ASSERT(r == 0);
/* Start reading */ /* Start reading */
req = (uv_req_t*)malloc(sizeof *req);
ASSERT(req != NULL);
uv_req_init(req, (uv_handle_t*)tcp, (void *(*)(void *))read_cb);
r = uv_read_start((uv_stream_t*)tcp, alloc_cb, read_cb); r = uv_read_start((uv_stream_t*)tcp, alloc_cb, read_cb);
ASSERT(r == 0); ASSERT(r == 0);
} }
@ -169,7 +166,7 @@ static void connect_cb(uv_req_t* req, int status) {
TEST_IMPL(tcp_writealot) { TEST_IMPL(tcp_writealot) {
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT); struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof *client); uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof *client);
uv_req_t* connect_req = (uv_req_t*)malloc(sizeof *connect_req); uv_connect_t* connect_req = malloc(sizeof(uv_connect_t));
int r; int r;
ASSERT(client != NULL); ASSERT(client != NULL);
@ -184,8 +181,7 @@ TEST_IMPL(tcp_writealot) {
r = uv_tcp_init(client); r = uv_tcp_init(client);
ASSERT(r == 0); ASSERT(r == 0);
uv_req_init(connect_req, (uv_handle_t*)client, (void *(*)(void *))connect_cb); r = uv_tcp_connect(connect_req, client, addr, connect_cb);
r = uv_tcp_connect(connect_req, addr);
ASSERT(r == 0); ASSERT(r == 0);
uv_run(); uv_run();

71
src/tcp_wrap.cc

@ -61,25 +61,37 @@ static Persistent<String> write_queue_size_sym;
class TCPWrap; class TCPWrap;
template <typename T>
class ReqWrap { class ReqWrap {
public: public:
ReqWrap(uv_handle_t* handle, void* callback) { ReqWrap() {
HandleScope scope; HandleScope scope;
object_ = Persistent<Object>::New(Object::New()); object_ = Persistent<Object>::New(Object::New());
uv_req_init(&req_, handle, (void* (*)(void*))callback);
req_.data = this;
} }
~ReqWrap() { ~ReqWrap() {
// Assert that someone has called Dispatched()
assert(req_.data == this);
assert(!object_.IsEmpty()); assert(!object_.IsEmpty());
object_.Dispose(); object_.Dispose();
object_.Clear(); object_.Clear();
} }
// Call this after the req has been dispatched.
void Dispatched() {
req_.data = this;
}
Persistent<Object> object_; Persistent<Object> object_;
uv_req_t req_; T req_;
}; };
typedef class ReqWrap<uv_shutdown_t> ShutdownWrap;
typedef class ReqWrap<uv_write_t> WriteWrap;
typedef class ReqWrap<uv_connect_t> ConnectWrap;
class TCPWrap { class TCPWrap {
public: public:
@ -373,8 +385,8 @@ class TCPWrap {
return scope.Close(Integer::New(r)); return scope.Close(Integer::New(r));
} }
static void AfterWrite(uv_req_t* req, int status) { static void AfterWrite(uv_write_t* req, int status) {
ReqWrap* req_wrap = (ReqWrap*) req->data; WriteWrap* req_wrap = (WriteWrap*) req->data;
TCPWrap* wrap = (TCPWrap*) req->handle->data; TCPWrap* wrap = (TCPWrap*) req->handle->data;
HandleScope scope; HandleScope scope;
@ -420,11 +432,7 @@ class TCPWrap {
length = args[2]->IntegerValue(); length = args[2]->IntegerValue();
} }
// I hate when people program C++ like it was C, and yet I do it too. WriteWrap* req_wrap = new WriteWrap();
// I'm too lazy to come up with the perfect class hierarchy here. Let's
// just do some type munging.
ReqWrap* req_wrap = new ReqWrap((uv_handle_t*) &wrap->handle_,
(void*)AfterWrite);
req_wrap->object_->SetHiddenValue(buffer_sym, buffer_obj); req_wrap->object_->SetHiddenValue(buffer_sym, buffer_obj);
@ -432,7 +440,10 @@ class TCPWrap {
buf.base = Buffer::Data(buffer_obj) + offset; buf.base = Buffer::Data(buffer_obj) + offset;
buf.len = length; buf.len = length;
int r = uv_write(&req_wrap->req_, &buf, 1); int r = uv_write(&req_wrap->req_, (uv_stream_t*)&wrap->handle_, &buf, 1,
AfterWrite);
req_wrap->Dispatched();
wrap->UpdateWriteQueueSize(); wrap->UpdateWriteQueueSize();
@ -445,8 +456,8 @@ class TCPWrap {
} }
} }
static void AfterConnect(uv_req_t* req, int status) { static void AfterConnect(uv_connect_t* req, int status) {
ReqWrap* req_wrap = (ReqWrap*) req->data; ConnectWrap* req_wrap = (ConnectWrap*) req->data;
TCPWrap* wrap = (TCPWrap*) req->handle->data; TCPWrap* wrap = (TCPWrap*) req->handle->data;
HandleScope scope; HandleScope scope;
@ -482,10 +493,12 @@ class TCPWrap {
// I hate when people program C++ like it was C, and yet I do it too. // I hate when people program C++ like it was C, and yet I do it too.
// I'm too lazy to come up with the perfect class hierarchy here. Let's // I'm too lazy to come up with the perfect class hierarchy here. Let's
// just do some type munging. // just do some type munging.
ReqWrap* req_wrap = new ReqWrap((uv_handle_t*) &wrap->handle_, ConnectWrap* req_wrap = new ConnectWrap();
(void*)AfterConnect);
int r = uv_tcp_connect(&req_wrap->req_, &wrap->handle_, address,
AfterConnect);
int r = uv_tcp_connect(&req_wrap->req_, address); req_wrap->Dispatched();
if (r) { if (r) {
SetErrno(uv_last_error().code); SetErrno(uv_last_error().code);
@ -506,13 +519,12 @@ class TCPWrap {
struct sockaddr_in6 address = uv_ip6_addr(*ip_address, port); struct sockaddr_in6 address = uv_ip6_addr(*ip_address, port);
// I hate when people program C++ like it was C, and yet I do it too. ConnectWrap* req_wrap = new ConnectWrap();
// I'm too lazy to come up with the perfect class hierarchy here. Let's
// just do some type munging.
ReqWrap* req_wrap = new ReqWrap((uv_handle_t*) &wrap->handle_,
(void*)AfterConnect);
int r = uv_tcp_connect6(&req_wrap->req_, address); int r = uv_tcp_connect6(&req_wrap->req_, &wrap->handle_, address,
AfterConnect);
req_wrap->Dispatched();
if (r) { if (r) {
SetErrno(uv_last_error().code); SetErrno(uv_last_error().code);
@ -523,8 +535,8 @@ class TCPWrap {
} }
} }
static void AfterShutdown(uv_req_t* req, int status) { static void AfterShutdown(uv_shutdown_t* req, int status) {
ReqWrap* req_wrap = (ReqWrap*) req->data; ReqWrap<uv_shutdown_t>* req_wrap = (ReqWrap<uv_shutdown_t>*) req->data;
TCPWrap* wrap = (TCPWrap*) req->handle->data; TCPWrap* wrap = (TCPWrap*) req->handle->data;
// The request object should still be there. // The request object should still be there.
@ -552,10 +564,12 @@ class TCPWrap {
UNWRAP UNWRAP
ReqWrap* req_wrap = new ReqWrap((uv_handle_t*) &wrap->handle_, ShutdownWrap* req_wrap = new ShutdownWrap();
(void*)AfterShutdown);
int r = uv_shutdown(&req_wrap->req_, (uv_stream_t*) &wrap->handle_,
AfterShutdown);
int r = uv_shutdown(&req_wrap->req_); req_wrap->Dispatched();
if (r) { if (r) {
SetErrno(uv_last_error().code); SetErrno(uv_last_error().code);
@ -569,7 +583,6 @@ class TCPWrap {
uv_tcp_t handle_; uv_tcp_t handle_;
Persistent<Object> object_; Persistent<Object> object_;
size_t slab_offset_; size_t slab_offset_;
friend class ReqWrap;
}; };

Loading…
Cancel
Save