unix, windows: rework reference counting scheme
This commit changes how the event loop determines if it needs to stay alive. Previously, an internal counter was increased whenever a handle got created and decreased again when the handle was closed. While conceptually simple, it turned out hard to work with: you often want to keep the event loop alive only if the handle is actually doing something. Stopped or inactive handles were a frequent source of hanging event loops. That's why this commit changes the reference counting scheme to a model where a handle only references the event loop when it's active. 'Active' means different things for different handle types, e.g.: * timers: ticking * sockets: reading, writing or listening * processes: always active (for now, subject to change) * idle, check, prepare: only active when started This commit also changes how the uv_ref() and uv_unref() functions work: they now operate on the level of individual handles, not the whole event loop. The Windows implementation was done by Bert Belder.
This commit is contained in:
parent
07622e767d
commit
9efa8b3571
@ -29,16 +29,13 @@ CPPFLAGS += -D_FILE_OFFSET_BITS=64
|
|||||||
|
|
||||||
OBJS += src/unix/async.o
|
OBJS += src/unix/async.o
|
||||||
OBJS += src/unix/cares.o
|
OBJS += src/unix/cares.o
|
||||||
OBJS += src/unix/check.o
|
|
||||||
OBJS += src/unix/core.o
|
OBJS += src/unix/core.o
|
||||||
OBJS += src/unix/dl.o
|
OBJS += src/unix/dl.o
|
||||||
OBJS += src/unix/error.o
|
OBJS += src/unix/error.o
|
||||||
OBJS += src/unix/fs.o
|
OBJS += src/unix/fs.o
|
||||||
OBJS += src/unix/idle.o
|
|
||||||
OBJS += src/unix/loop.o
|
OBJS += src/unix/loop.o
|
||||||
OBJS += src/unix/pipe.o
|
OBJS += src/unix/pipe.o
|
||||||
OBJS += src/unix/poll.o
|
OBJS += src/unix/poll.o
|
||||||
OBJS += src/unix/prepare.o
|
|
||||||
OBJS += src/unix/process.o
|
OBJS += src/unix/process.o
|
||||||
OBJS += src/unix/stream.o
|
OBJS += src/unix/stream.o
|
||||||
OBJS += src/unix/tcp.o
|
OBJS += src/unix/tcp.o
|
||||||
|
|||||||
@ -104,7 +104,10 @@ typedef struct {
|
|||||||
uv_async_t uv_eio_want_poll_notifier; \
|
uv_async_t uv_eio_want_poll_notifier; \
|
||||||
uv_async_t uv_eio_done_poll_notifier; \
|
uv_async_t uv_eio_done_poll_notifier; \
|
||||||
uv_idle_t uv_eio_poller; \
|
uv_idle_t uv_eio_poller; \
|
||||||
uv_handle_t* endgame_handles; \
|
uv_handle_t* pending_handles; \
|
||||||
|
ngx_queue_t prepare_handles; \
|
||||||
|
ngx_queue_t check_handles; \
|
||||||
|
ngx_queue_t idle_handles; \
|
||||||
UV_LOOP_PRIVATE_PLATFORM_FIELDS
|
UV_LOOP_PRIVATE_PLATFORM_FIELDS
|
||||||
|
|
||||||
#define UV_REQ_BUFSML_SIZE (4)
|
#define UV_REQ_BUFSML_SIZE (4)
|
||||||
@ -141,7 +144,7 @@ typedef struct {
|
|||||||
#define UV_HANDLE_PRIVATE_FIELDS \
|
#define UV_HANDLE_PRIVATE_FIELDS \
|
||||||
int fd; \
|
int fd; \
|
||||||
int flags; \
|
int flags; \
|
||||||
uv_handle_t* endgame_next; /* that's what uv-win calls it */ \
|
uv_handle_t* next_pending; \
|
||||||
|
|
||||||
|
|
||||||
#define UV_STREAM_PRIVATE_FIELDS \
|
#define UV_STREAM_PRIVATE_FIELDS \
|
||||||
@ -183,20 +186,20 @@ typedef struct {
|
|||||||
|
|
||||||
/* UV_PREPARE */ \
|
/* UV_PREPARE */ \
|
||||||
#define UV_PREPARE_PRIVATE_FIELDS \
|
#define UV_PREPARE_PRIVATE_FIELDS \
|
||||||
ev_prepare prepare_watcher; \
|
uv_prepare_cb prepare_cb; \
|
||||||
uv_prepare_cb prepare_cb;
|
ngx_queue_t queue;
|
||||||
|
|
||||||
|
|
||||||
/* UV_CHECK */
|
/* UV_CHECK */
|
||||||
#define UV_CHECK_PRIVATE_FIELDS \
|
#define UV_CHECK_PRIVATE_FIELDS \
|
||||||
ev_check check_watcher; \
|
uv_check_cb check_cb; \
|
||||||
uv_check_cb check_cb;
|
ngx_queue_t queue;
|
||||||
|
|
||||||
|
|
||||||
/* UV_IDLE */
|
/* UV_IDLE */
|
||||||
#define UV_IDLE_PRIVATE_FIELDS \
|
#define UV_IDLE_PRIVATE_FIELDS \
|
||||||
ev_idle idle_watcher; \
|
uv_idle_cb idle_cb; \
|
||||||
uv_idle_cb idle_cb;
|
ngx_queue_t queue;
|
||||||
|
|
||||||
|
|
||||||
/* UV_ASYNC */
|
/* UV_ASYNC */
|
||||||
|
|||||||
@ -32,6 +32,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
#include "ngx-queue.h"
|
||||||
|
|
||||||
#define MAX_PIPENAME_LEN 256
|
#define MAX_PIPENAME_LEN 256
|
||||||
|
|
||||||
@ -203,8 +204,6 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
|||||||
#define UV_LOOP_PRIVATE_FIELDS \
|
#define UV_LOOP_PRIVATE_FIELDS \
|
||||||
/* The loop's I/O completion port */ \
|
/* The loop's I/O completion port */ \
|
||||||
HANDLE iocp; \
|
HANDLE iocp; \
|
||||||
/* Reference count that keeps the event loop alive */ \
|
|
||||||
int refs; \
|
|
||||||
/* The current time according to the event loop. in msecs. */ \
|
/* The current time according to the event loop. in msecs. */ \
|
||||||
int64_t time; \
|
int64_t time; \
|
||||||
/* Tail of a single-linked circular queue of pending reqs. If the queue */ \
|
/* Tail of a single-linked circular queue of pending reqs. If the queue */ \
|
||||||
@ -246,7 +245,6 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
|||||||
UV_ARES_EVENT_REQ, \
|
UV_ARES_EVENT_REQ, \
|
||||||
UV_ARES_CLEANUP_REQ, \
|
UV_ARES_CLEANUP_REQ, \
|
||||||
UV_FS_EVENT_REQ, \
|
UV_FS_EVENT_REQ, \
|
||||||
UV_GETADDRINFO_REQ, \
|
|
||||||
UV_POLL_REQ, \
|
UV_POLL_REQ, \
|
||||||
UV_PROCESS_EXIT, \
|
UV_PROCESS_EXIT, \
|
||||||
UV_PROCESS_CLOSE, \
|
UV_PROCESS_CLOSE, \
|
||||||
@ -310,6 +308,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
|||||||
|
|
||||||
#define UV_STREAM_PRIVATE_FIELDS \
|
#define UV_STREAM_PRIVATE_FIELDS \
|
||||||
unsigned int reqs_pending; \
|
unsigned int reqs_pending; \
|
||||||
|
int activecnt; \
|
||||||
uv_read_t read_req; \
|
uv_read_t read_req; \
|
||||||
union { \
|
union { \
|
||||||
struct { uv_stream_connection_fields }; \
|
struct { uv_stream_connection_fields }; \
|
||||||
@ -337,6 +336,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
|||||||
#define UV_UDP_PRIVATE_FIELDS \
|
#define UV_UDP_PRIVATE_FIELDS \
|
||||||
SOCKET socket; \
|
SOCKET socket; \
|
||||||
unsigned int reqs_pending; \
|
unsigned int reqs_pending; \
|
||||||
|
int activecnt; \
|
||||||
uv_req_t recv_req; \
|
uv_req_t recv_req; \
|
||||||
uv_buf_t recv_buffer; \
|
uv_buf_t recv_buffer; \
|
||||||
struct sockaddr_storage recv_from; \
|
struct sockaddr_storage recv_from; \
|
||||||
@ -444,7 +444,6 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
|||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
|
||||||
#define UV_GETADDRINFO_PRIVATE_FIELDS \
|
#define UV_GETADDRINFO_PRIVATE_FIELDS \
|
||||||
struct uv_req_s getadddrinfo_req; \
|
|
||||||
uv_getaddrinfo_cb getaddrinfo_cb; \
|
uv_getaddrinfo_cb getaddrinfo_cb; \
|
||||||
void* alloc; \
|
void* alloc; \
|
||||||
wchar_t* node; \
|
wchar_t* node; \
|
||||||
|
|||||||
28
include/uv.h
28
include/uv.h
@ -224,10 +224,6 @@ typedef struct uv_work_s uv_work_t;
|
|||||||
UV_EXTERN uv_loop_t* uv_loop_new(void);
|
UV_EXTERN uv_loop_t* uv_loop_new(void);
|
||||||
UV_EXTERN void uv_loop_delete(uv_loop_t*);
|
UV_EXTERN void uv_loop_delete(uv_loop_t*);
|
||||||
|
|
||||||
/* This is a debugging tool. It's NOT part of the official API. */
|
|
||||||
UV_EXTERN int uv_loop_refcount(const uv_loop_t*);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the default loop.
|
* Returns the default loop.
|
||||||
*/
|
*/
|
||||||
@ -248,8 +244,8 @@ UV_EXTERN int uv_run_once (uv_loop_t*);
|
|||||||
* Manually modify the event loop's reference count. Useful if the user wants
|
* Manually modify the event loop's reference count. Useful if the user wants
|
||||||
* to have a handle or timeout that doesn't keep the loop alive.
|
* to have a handle or timeout that doesn't keep the loop alive.
|
||||||
*/
|
*/
|
||||||
UV_EXTERN void uv_ref(uv_loop_t*);
|
UV_EXTERN void uv_ref(uv_handle_t*);
|
||||||
UV_EXTERN void uv_unref(uv_loop_t*);
|
UV_EXTERN void uv_unref(uv_handle_t*);
|
||||||
|
|
||||||
UV_EXTERN void uv_update_time(uv_loop_t*);
|
UV_EXTERN void uv_update_time(uv_loop_t*);
|
||||||
UV_EXTERN int64_t uv_now(uv_loop_t*);
|
UV_EXTERN int64_t uv_now(uv_loop_t*);
|
||||||
@ -336,12 +332,18 @@ UV_EXTERN uv_err_t uv_last_error(uv_loop_t*);
|
|||||||
UV_EXTERN const char* uv_strerror(uv_err_t err);
|
UV_EXTERN const char* uv_strerror(uv_err_t err);
|
||||||
UV_EXTERN const char* uv_err_name(uv_err_t err);
|
UV_EXTERN const char* uv_err_name(uv_err_t err);
|
||||||
|
|
||||||
|
#ifndef UV_LEAN_AND_MEAN
|
||||||
|
# define UV_REQ_EXTRA_FIELDS ngx_queue_t active_queue;
|
||||||
|
#else
|
||||||
|
# define UV_REQ_EXTRA_FIELDS
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UV_REQ_FIELDS \
|
#define UV_REQ_FIELDS \
|
||||||
/* read-only */ \
|
/* read-only */ \
|
||||||
uv_req_type type; \
|
uv_req_type type; \
|
||||||
/* public */ \
|
/* public */ \
|
||||||
void* data; \
|
void* data; \
|
||||||
|
UV_REQ_EXTRA_FIELDS \
|
||||||
/* private */ \
|
/* private */ \
|
||||||
UV_REQ_PRIVATE_FIELDS
|
UV_REQ_PRIVATE_FIELDS
|
||||||
|
|
||||||
@ -374,6 +376,12 @@ struct uv_shutdown_s {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UV_LEAN_AND_MEAN
|
||||||
|
# define UV_HANDLE_EXTRA_FIELDS ngx_queue_t active_queue;
|
||||||
|
#else
|
||||||
|
# define UV_HANDLE_EXTRA_FIELDS
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UV_HANDLE_FIELDS \
|
#define UV_HANDLE_FIELDS \
|
||||||
/* read-only */ \
|
/* read-only */ \
|
||||||
uv_loop_t* loop; \
|
uv_loop_t* loop; \
|
||||||
@ -381,6 +389,7 @@ struct uv_shutdown_s {
|
|||||||
/* public */ \
|
/* public */ \
|
||||||
uv_close_cb close_cb; \
|
uv_close_cb close_cb; \
|
||||||
void* data; \
|
void* data; \
|
||||||
|
UV_HANDLE_EXTRA_FIELDS \
|
||||||
/* private */ \
|
/* private */ \
|
||||||
UV_HANDLE_PRIVATE_FIELDS
|
UV_HANDLE_PRIVATE_FIELDS
|
||||||
|
|
||||||
@ -1638,6 +1647,13 @@ struct uv_loop_s {
|
|||||||
uv_err_t last_err;
|
uv_err_t last_err;
|
||||||
/* User data - use this for whatever. */
|
/* User data - use this for whatever. */
|
||||||
void* data;
|
void* data;
|
||||||
|
#ifndef UV_LEAN_AND_MEAN
|
||||||
|
ngx_queue_t active_reqs;
|
||||||
|
ngx_queue_t active_handles;
|
||||||
|
#else
|
||||||
|
unsigned int active_reqs;
|
||||||
|
unsigned int active_handles;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -40,7 +40,8 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb) {
|
|||||||
|
|
||||||
/* Note: This does not have symmetry with the other libev wrappers. */
|
/* Note: This does not have symmetry with the other libev wrappers. */
|
||||||
ev_async_start(loop->ev, &async->async_watcher);
|
ev_async_start(loop->ev, &async->async_watcher);
|
||||||
ev_unref(loop->ev);
|
uv__handle_unref(async);
|
||||||
|
uv__handle_start(async);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -54,5 +55,6 @@ int uv_async_send(uv_async_t* async) {
|
|||||||
|
|
||||||
void uv__async_close(uv_async_t* handle) {
|
void uv__async_close(uv_async_t* handle) {
|
||||||
ev_async_stop(handle->loop->ev, &handle->async_watcher);
|
ev_async_stop(handle->loop->ev, &handle->async_watcher);
|
||||||
ev_ref(handle->loop->ev);
|
uv__handle_ref(handle);
|
||||||
|
uv__handle_stop(handle);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,20 +37,6 @@ static void uv__ares_timeout(uv_timer_t* handle, int status) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void uv__ares_timer_start(uv_loop_t* loop) {
|
|
||||||
if (uv_is_active((uv_handle_t*)&loop->timer)) return;
|
|
||||||
uv_timer_start(&loop->timer, uv__ares_timeout, 1000, 1000);
|
|
||||||
uv_ref(loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__ares_timer_stop(uv_loop_t* loop) {
|
|
||||||
if (!uv_is_active((uv_handle_t*)&loop->timer)) return;
|
|
||||||
uv_timer_stop(&loop->timer);
|
|
||||||
uv_unref(loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__ares_io(struct ev_loop* ev, struct ev_io* watcher,
|
static void uv__ares_io(struct ev_loop* ev, struct ev_io* watcher,
|
||||||
int revents) {
|
int revents) {
|
||||||
uv_loop_t* loop = ev_userdata(ev);
|
uv_loop_t* loop = ev_userdata(ev);
|
||||||
@ -104,9 +90,9 @@ static void uv__ares_sockstate_cb(void* data, ares_socket_t sock,
|
|||||||
/* New socket */
|
/* New socket */
|
||||||
|
|
||||||
/* If this is the first socket then start the timer. */
|
/* If this is the first socket then start the timer. */
|
||||||
if (!uv_is_active((uv_handle_t*)&loop->timer)) {
|
if (!uv__is_active(&loop->timer)) {
|
||||||
assert(uv_ares_handles_empty(loop));
|
assert(uv_ares_handles_empty(loop));
|
||||||
uv__ares_timer_start(loop);
|
uv_timer_start(&loop->timer, uv__ares_timeout, 1000, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
h = uv__ares_task_create(loop, sock);
|
h = uv__ares_task_create(loop, sock);
|
||||||
@ -140,7 +126,7 @@ static void uv__ares_sockstate_cb(void* data, ares_socket_t sock,
|
|||||||
free(h);
|
free(h);
|
||||||
|
|
||||||
if (uv_ares_handles_empty(loop)) {
|
if (uv_ares_handles_empty(loop)) {
|
||||||
uv__ares_timer_stop(loop);
|
uv_timer_stop(&loop->timer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,7 +162,6 @@ int uv_ares_init_options(uv_loop_t* loop, ares_channel *channelptr,
|
|||||||
* first socket is opened.
|
* first socket is opened.
|
||||||
*/
|
*/
|
||||||
uv_timer_init(loop, &loop->timer);
|
uv_timer_init(loop, &loop->timer);
|
||||||
uv_unref(loop);
|
|
||||||
loop->timer.data = loop;
|
loop->timer.data = loop;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@ -187,7 +172,7 @@ int uv_ares_init_options(uv_loop_t* loop, ares_channel *channelptr,
|
|||||||
void uv_ares_destroy(uv_loop_t* loop, ares_channel channel) {
|
void uv_ares_destroy(uv_loop_t* loop, ares_channel channel) {
|
||||||
/* only allow destroy if did init */
|
/* only allow destroy if did init */
|
||||||
if (loop->channel) {
|
if (loop->channel) {
|
||||||
uv__ares_timer_stop(loop);
|
uv_timer_stop(&loop->timer);
|
||||||
ares_destroy(channel);
|
ares_destroy(channel);
|
||||||
loop->channel = NULL;
|
loop->channel = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,80 +0,0 @@
|
|||||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to
|
|
||||||
* deal in the Software without restriction, including without limitation the
|
|
||||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
* sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
* IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uv.h"
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__check(EV_P_ ev_check* w, int revents) {
|
|
||||||
uv_check_t* check = container_of(w, uv_check_t, check_watcher);
|
|
||||||
|
|
||||||
if (check->check_cb) {
|
|
||||||
check->check_cb(check, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv_check_init(uv_loop_t* loop, uv_check_t* check) {
|
|
||||||
uv__handle_init(loop, (uv_handle_t*)check, UV_CHECK);
|
|
||||||
loop->counters.check_init++;
|
|
||||||
|
|
||||||
ev_check_init(&check->check_watcher, uv__check);
|
|
||||||
check->check_cb = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv_check_start(uv_check_t* check, uv_check_cb cb) {
|
|
||||||
int was_active = ev_is_active(&check->check_watcher);
|
|
||||||
|
|
||||||
check->check_cb = cb;
|
|
||||||
|
|
||||||
ev_check_start(check->loop->ev, &check->check_watcher);
|
|
||||||
|
|
||||||
if (!was_active) {
|
|
||||||
ev_unref(check->loop->ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv_check_stop(uv_check_t* check) {
|
|
||||||
int was_active = ev_is_active(&check->check_watcher);
|
|
||||||
|
|
||||||
ev_check_stop(check->loop->ev, &check->check_watcher);
|
|
||||||
|
|
||||||
if (was_active) {
|
|
||||||
ev_ref(check->loop->ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv__check_active(const uv_check_t* handle) {
|
|
||||||
return ev_is_active(&handle->check_watcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv__check_close(uv_check_t* handle) {
|
|
||||||
uv_check_stop(handle);
|
|
||||||
}
|
|
||||||
159
src/unix/core.c
159
src/unix/core.c
@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "unix/internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <stddef.h> /* NULL */
|
#include <stddef.h> /* NULL */
|
||||||
#include <stdio.h> /* printf */
|
#include <stdio.h> /* printf */
|
||||||
@ -116,9 +116,7 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handle->flags |= UV_CLOSING;
|
handle->flags |= UV_CLOSING;
|
||||||
handle->endgame_next = handle->loop->endgame_handles;
|
uv__make_pending(handle);
|
||||||
handle->loop->endgame_handles = handle;
|
|
||||||
uv_unref(handle->loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -165,24 +163,66 @@ void uv_loop_delete(uv_loop_t* loop) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv_loop_refcount(const uv_loop_t* loop) {
|
static void uv__run_pending(uv_loop_t* loop) {
|
||||||
return ev_loop_refcount(loop->ev);
|
uv_handle_t* p;
|
||||||
|
uv_handle_t* q;
|
||||||
|
|
||||||
|
if (!loop->pending_handles)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (p = loop->pending_handles, loop->pending_handles = NULL; p; p = q) {
|
||||||
|
q = p->next_pending;
|
||||||
|
p->next_pending = NULL;
|
||||||
|
p->flags &= ~UV__PENDING;
|
||||||
|
|
||||||
|
if (p->flags & UV_CLOSING) {
|
||||||
|
uv__finish_close(p);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (p->type) {
|
||||||
|
case UV_NAMED_PIPE:
|
||||||
|
case UV_TCP:
|
||||||
|
case UV_TTY:
|
||||||
|
uv__stream_pending((uv_stream_t*)p);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv__run(uv_loop_t* loop) {
|
static void uv__poll(uv_loop_t* loop, int block) {
|
||||||
ev_run(loop->ev, EVRUN_ONCE);
|
/* bump the loop's refcount, otherwise libev does
|
||||||
|
* a zero timeout poll and we end up busy looping
|
||||||
|
*/
|
||||||
|
ev_ref(loop->ev);
|
||||||
|
ev_run(loop->ev, block ? EVRUN_ONCE : EVRUN_NOWAIT);
|
||||||
|
ev_unref(loop->ev);
|
||||||
|
}
|
||||||
|
|
||||||
while (loop->endgame_handles)
|
|
||||||
uv__finish_close(loop->endgame_handles);
|
static int uv__run(uv_loop_t* loop) {
|
||||||
|
if (!uv__has_pending_handles(loop) && !uv__has_active_reqs(loop))
|
||||||
|
uv__run_idle(loop);
|
||||||
|
|
||||||
|
uv__run_pending(loop);
|
||||||
|
uv__run_prepare(loop);
|
||||||
|
|
||||||
|
if (uv__has_active_handles(loop) || uv__has_active_reqs(loop))
|
||||||
|
uv__poll(loop, 0);
|
||||||
|
|
||||||
|
uv__run_check(loop);
|
||||||
|
|
||||||
|
return uv__has_pending_handles(loop)
|
||||||
|
|| uv__has_active_handles(loop)
|
||||||
|
|| uv__has_active_reqs(loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv_run(uv_loop_t* loop) {
|
int uv_run(uv_loop_t* loop) {
|
||||||
do
|
while (uv__run(loop));
|
||||||
uv__run(loop);
|
|
||||||
while (uv_loop_refcount(loop) > 0);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,38 +239,24 @@ void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle,
|
|||||||
|
|
||||||
handle->loop = loop;
|
handle->loop = loop;
|
||||||
handle->type = type;
|
handle->type = type;
|
||||||
handle->flags = 0;
|
handle->flags = UV__REF; /* ref the loop when active */
|
||||||
handle->endgame_next = NULL;
|
handle->next_pending = NULL;
|
||||||
uv_ref(loop); /* unref'd in uv_close() */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv__finish_close(uv_handle_t* handle) {
|
void uv__finish_close(uv_handle_t* handle) {
|
||||||
uv_loop_t* loop = handle->loop;
|
assert(!uv__is_active(handle));
|
||||||
|
|
||||||
assert(handle->flags & UV_CLOSING);
|
assert(handle->flags & UV_CLOSING);
|
||||||
assert(!(handle->flags & UV_CLOSED));
|
assert(!(handle->flags & UV_CLOSED));
|
||||||
handle->flags |= UV_CLOSED;
|
handle->flags |= UV_CLOSED;
|
||||||
|
|
||||||
switch (handle->type) {
|
switch (handle->type) {
|
||||||
case UV_PREPARE:
|
case UV_PREPARE:
|
||||||
assert(!ev_is_active(&((uv_prepare_t*)handle)->prepare_watcher));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UV_CHECK:
|
case UV_CHECK:
|
||||||
assert(!ev_is_active(&((uv_check_t*)handle)->check_watcher));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UV_IDLE:
|
case UV_IDLE:
|
||||||
assert(!ev_is_active(&((uv_idle_t*)handle)->idle_watcher));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UV_ASYNC:
|
case UV_ASYNC:
|
||||||
assert(!ev_is_active(&((uv_async_t*)handle)->async_watcher));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UV_TIMER:
|
case UV_TIMER:
|
||||||
assert(!ev_is_active(&((uv_timer_t*)handle)->timer_watcher));
|
case UV_PROCESS:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UV_NAMED_PIPE:
|
case UV_NAMED_PIPE:
|
||||||
@ -246,10 +272,6 @@ void uv__finish_close(uv_handle_t* handle) {
|
|||||||
uv__udp_finish_close((uv_udp_t*)handle);
|
uv__udp_finish_close((uv_udp_t*)handle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UV_PROCESS:
|
|
||||||
assert(!ev_is_active(&((uv_process_t*)handle)->child_watcher));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UV_FS_EVENT:
|
case UV_FS_EVENT:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -262,21 +284,11 @@ void uv__finish_close(uv_handle_t* handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
loop->endgame_handles = handle->endgame_next;
|
|
||||||
|
|
||||||
if (handle->close_cb) {
|
if (handle->close_cb) {
|
||||||
handle->close_cb(handle);
|
handle->close_cb(handle);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
uv__handle_unref(handle);
|
||||||
void uv_ref(uv_loop_t* loop) {
|
|
||||||
ev_ref(loop->ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv_unref(uv_loop_t* loop) {
|
|
||||||
ev_unref(loop->ev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -291,56 +303,43 @@ int64_t uv_now(uv_loop_t* loop) {
|
|||||||
|
|
||||||
|
|
||||||
int uv_is_active(const uv_handle_t* handle) {
|
int uv_is_active(const uv_handle_t* handle) {
|
||||||
switch (handle->type) {
|
return uv__is_active(handle);
|
||||||
case UV_POLL:
|
|
||||||
return uv__poll_active((const uv_poll_t*)handle);
|
|
||||||
case UV_CHECK:
|
|
||||||
return uv__check_active((const uv_check_t*)handle);
|
|
||||||
case UV_IDLE:
|
|
||||||
return uv__idle_active((const uv_idle_t*)handle);
|
|
||||||
case UV_PREPARE:
|
|
||||||
return uv__prepare_active((const uv_prepare_t*)handle);
|
|
||||||
case UV_TIMER:
|
|
||||||
return uv__timer_active((const uv_timer_t*)handle);
|
|
||||||
default:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int uv_getaddrinfo_done(eio_req* req) {
|
static int uv_getaddrinfo_done(eio_req* req_) {
|
||||||
uv_getaddrinfo_t* handle = req->data;
|
uv_getaddrinfo_t* req = req_->data;
|
||||||
struct addrinfo *res = handle->res;
|
struct addrinfo *res = req->res;
|
||||||
#if __sun
|
#if __sun
|
||||||
size_t hostlen = strlen(handle->hostname);
|
size_t hostlen = strlen(handle->hostname);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
handle->res = NULL;
|
req->res = NULL;
|
||||||
|
|
||||||
uv_unref(handle->loop);
|
uv__req_unregister(req->loop, req);
|
||||||
|
|
||||||
free(handle->hints);
|
free(req->hints);
|
||||||
free(handle->service);
|
free(req->service);
|
||||||
free(handle->hostname);
|
free(req->hostname);
|
||||||
|
|
||||||
if (handle->retcode == 0) {
|
if (req->retcode == 0) {
|
||||||
/* OK */
|
/* OK */
|
||||||
#if EAI_NODATA /* FreeBSD deprecated EAI_NODATA */
|
#if EAI_NODATA /* FreeBSD deprecated EAI_NODATA */
|
||||||
} else if (handle->retcode == EAI_NONAME || handle->retcode == EAI_NODATA) {
|
} else if (req->retcode == EAI_NONAME || req->retcode == EAI_NODATA) {
|
||||||
#else
|
#else
|
||||||
} else if (handle->retcode == EAI_NONAME) {
|
} else if (req->retcode == EAI_NONAME) {
|
||||||
#endif
|
#endif
|
||||||
uv__set_sys_error(handle->loop, ENOENT); /* FIXME compatibility hack */
|
uv__set_sys_error(req->loop, ENOENT); /* FIXME compatibility hack */
|
||||||
#if __sun
|
#if __sun
|
||||||
} else if (handle->retcode == EAI_MEMORY && hostlen >= MAXHOSTNAMELEN) {
|
} else if (req->retcode == EAI_MEMORY && hostlen >= MAXHOSTNAMELEN) {
|
||||||
uv__set_sys_error(handle->loop, ENOENT);
|
uv__set_sys_error(req->loop, ENOENT);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
handle->loop->last_err.code = UV_EADDRINFO;
|
req->loop->last_err.code = UV_EADDRINFO;
|
||||||
handle->loop->last_err.sys_errno_ = handle->retcode;
|
req->loop->last_err.sys_errno_ = req->retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->cb(handle, handle->retcode, res);
|
req->cb(req, req->retcode, res);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -396,8 +395,6 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
|||||||
/* TODO check handle->hostname == NULL */
|
/* TODO check handle->hostname == NULL */
|
||||||
/* TODO check handle->service == NULL */
|
/* TODO check handle->service == NULL */
|
||||||
|
|
||||||
uv_ref(loop);
|
|
||||||
|
|
||||||
req = eio_custom(getaddrinfo_thread_proc, EIO_PRI_DEFAULT,
|
req = eio_custom(getaddrinfo_thread_proc, EIO_PRI_DEFAULT,
|
||||||
uv_getaddrinfo_done, handle, &loop->uv_eio_channel);
|
uv_getaddrinfo_done, handle, &loop->uv_eio_channel);
|
||||||
assert(req);
|
assert(req);
|
||||||
@ -480,7 +477,7 @@ int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) {
|
|||||||
|
|
||||||
|
|
||||||
int uv__nonblock(int fd, int set) {
|
int uv__nonblock(int fd, int set) {
|
||||||
#ifdef FIONBIO
|
#if FIONBIO
|
||||||
return ioctl(fd, FIONBIO, &set);
|
return ioctl(fd, FIONBIO, &set);
|
||||||
#else
|
#else
|
||||||
int flags;
|
int flags;
|
||||||
|
|||||||
@ -49,7 +49,6 @@
|
|||||||
uv__set_sys_error(loop, ENOMEM); \
|
uv__set_sys_error(loop, ENOMEM); \
|
||||||
return -1; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
uv_ref(loop); \
|
|
||||||
} else { \
|
} else { \
|
||||||
/* sync */ \
|
/* sync */ \
|
||||||
req->result = func(args); \
|
req->result = func(args); \
|
||||||
@ -75,10 +74,17 @@ static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type,
|
|||||||
req->path = path ? strdup(path) : NULL;
|
req->path = path ? strdup(path) : NULL;
|
||||||
req->errorno = 0;
|
req->errorno = 0;
|
||||||
req->eio = NULL;
|
req->eio = NULL;
|
||||||
|
|
||||||
|
/* synchronous requests don't increase the reference count */
|
||||||
|
if (!req->cb)
|
||||||
|
uv__req_unregister(req->loop, req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv_fs_req_cleanup(uv_fs_t* req) {
|
void uv_fs_req_cleanup(uv_fs_t* req) {
|
||||||
|
if (req->cb)
|
||||||
|
uv__req_unregister(req->loop, req);
|
||||||
|
|
||||||
free(req->path);
|
free(req->path);
|
||||||
req->path = NULL;
|
req->path = NULL;
|
||||||
|
|
||||||
@ -169,10 +175,9 @@ static int uv__fs_after(eio_req* eio) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_unref(req->loop);
|
|
||||||
req->eio = NULL; /* Freed by libeio */
|
req->eio = NULL; /* Freed by libeio */
|
||||||
|
|
||||||
req->cb(req);
|
req->cb(req);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +194,6 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
|
|||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
/* async */
|
/* async */
|
||||||
uv_ref(loop);
|
|
||||||
req->eio = eio_open(path, flags, mode, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
|
req->eio = eio_open(path, flags, mode, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
|
||||||
if (!req->eio) {
|
if (!req->eio) {
|
||||||
uv__set_sys_error(loop, ENOMEM);
|
uv__set_sys_error(loop, ENOMEM);
|
||||||
@ -219,7 +223,6 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
|
|||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
/* async */
|
/* async */
|
||||||
uv_ref(loop);
|
|
||||||
req->eio = eio_read(fd, buf, length, offset, EIO_PRI_DEFAULT,
|
req->eio = eio_read(fd, buf, length, offset, EIO_PRI_DEFAULT,
|
||||||
uv__fs_after, req, &loop->uv_eio_channel);
|
uv__fs_after, req, &loop->uv_eio_channel);
|
||||||
|
|
||||||
@ -257,7 +260,6 @@ int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
|
|||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
/* async */
|
/* async */
|
||||||
uv_ref(loop);
|
|
||||||
req->eio = eio_write(file, buf, length, offset, EIO_PRI_DEFAULT,
|
req->eio = eio_write(file, buf, length, offset, EIO_PRI_DEFAULT,
|
||||||
uv__fs_after, req, &loop->uv_eio_channel);
|
uv__fs_after, req, &loop->uv_eio_channel);
|
||||||
if (!req->eio) {
|
if (!req->eio) {
|
||||||
@ -305,7 +307,6 @@ int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
|
|||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
/* async */
|
/* async */
|
||||||
uv_ref(loop);
|
|
||||||
req->eio = eio_readdir(path, flags, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
|
req->eio = eio_readdir(path, flags, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
|
||||||
if (!req->eio) {
|
if (!req->eio) {
|
||||||
uv__set_sys_error(loop, ENOMEM);
|
uv__set_sys_error(loop, ENOMEM);
|
||||||
@ -375,7 +376,6 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
|||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
/* async */
|
/* async */
|
||||||
uv_ref(loop);
|
|
||||||
req->eio = eio_stat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
|
req->eio = eio_stat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
|
||||||
|
|
||||||
free(pathdup);
|
free(pathdup);
|
||||||
@ -409,7 +409,6 @@ int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
|||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
/* async */
|
/* async */
|
||||||
uv_ref(loop);
|
|
||||||
req->eio = eio_fstat(file, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
|
req->eio = eio_fstat(file, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
|
||||||
|
|
||||||
if (!req->eio) {
|
if (!req->eio) {
|
||||||
@ -495,7 +494,6 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if HAVE_FUTIMES
|
|
||||||
static int _futime(const uv_file fd, double atime, double mtime) {
|
static int _futime(const uv_file fd, double atime, double mtime) {
|
||||||
#if __linux__
|
#if __linux__
|
||||||
/* utimesat() has nanosecond resolution but we stick to microseconds
|
/* utimesat() has nanosecond resolution but we stick to microseconds
|
||||||
@ -507,30 +505,24 @@ static int _futime(const uv_file fd, double atime, double mtime) {
|
|||||||
ts[1].tv_sec = mtime;
|
ts[1].tv_sec = mtime;
|
||||||
ts[1].tv_nsec = (unsigned long)(mtime * 1000000) % 1000000 * 1000;
|
ts[1].tv_nsec = (unsigned long)(mtime * 1000000) % 1000000 * 1000;
|
||||||
return uv__utimesat(fd, NULL, ts, 0);
|
return uv__utimesat(fd, NULL, ts, 0);
|
||||||
#else
|
#elif HAVE_FUTIMES
|
||||||
struct timeval tv[2];
|
struct timeval tv[2];
|
||||||
tv[0].tv_sec = atime;
|
tv[0].tv_sec = atime;
|
||||||
tv[0].tv_usec = (unsigned long)(atime * 1000000) % 1000000;
|
tv[0].tv_usec = (unsigned long)(atime * 1000000) % 1000000;
|
||||||
tv[1].tv_sec = mtime;
|
tv[1].tv_sec = mtime;
|
||||||
tv[1].tv_usec = (unsigned long)(mtime * 1000000) % 1000000;
|
tv[1].tv_usec = (unsigned long)(mtime * 1000000) % 1000000;
|
||||||
return futimes(fd, tv);
|
return futimes(fd, tv);
|
||||||
#endif /* __linux__ */
|
#else /* !HAVE_FUTIMES */
|
||||||
|
errno = ENOSYS;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* HAVE_FUTIMES */
|
|
||||||
|
|
||||||
|
|
||||||
int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
|
int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
|
||||||
double mtime, uv_fs_cb cb) {
|
double mtime, uv_fs_cb cb) {
|
||||||
const char* path = NULL;
|
const char* path = NULL;
|
||||||
|
|
||||||
uv_fs_req_init(loop, req, UV_FS_FUTIME, path, cb);
|
|
||||||
|
|
||||||
#if HAVE_FUTIMES
|
|
||||||
WRAP_EIO(UV_FS_FUTIME, eio_futime, _futime, ARGS3(file, atime, mtime))
|
WRAP_EIO(UV_FS_FUTIME, eio_futime, _futime, ARGS3(file, atime, mtime))
|
||||||
#else
|
|
||||||
uv__set_sys_error(loop, ENOSYS);
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -552,7 +544,6 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
|||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
/* async */
|
/* async */
|
||||||
uv_ref(loop);
|
|
||||||
req->eio = eio_lstat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
|
req->eio = eio_lstat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel);
|
||||||
|
|
||||||
free(pathdup);
|
free(pathdup);
|
||||||
@ -602,7 +593,6 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
|||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
if ((req->eio = eio_readlink(path, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel))) {
|
if ((req->eio = eio_readlink(path, EIO_PRI_DEFAULT, uv__fs_after, req, &loop->uv_eio_channel))) {
|
||||||
uv_ref(loop);
|
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
uv__set_sys_error(loop, ENOMEM);
|
uv__set_sys_error(loop, ENOMEM);
|
||||||
@ -674,7 +664,7 @@ static void uv__work(eio_req* eio) {
|
|||||||
|
|
||||||
static int uv__after_work(eio_req *eio) {
|
static int uv__after_work(eio_req *eio) {
|
||||||
uv_work_t* req = eio->data;
|
uv_work_t* req = eio->data;
|
||||||
uv_unref(req->loop);
|
uv__req_unregister(req->loop, req);
|
||||||
if (req->after_work_cb) {
|
if (req->after_work_cb) {
|
||||||
req->after_work_cb(req);
|
req->after_work_cb(req);
|
||||||
}
|
}
|
||||||
@ -689,13 +679,16 @@ int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
|
|||||||
uv_eio_init(loop);
|
uv_eio_init(loop);
|
||||||
|
|
||||||
uv__req_init(loop, req, UV_WORK);
|
uv__req_init(loop, req, UV_WORK);
|
||||||
uv_ref(loop);
|
|
||||||
req->loop = loop;
|
req->loop = loop;
|
||||||
req->data = data;
|
req->data = data;
|
||||||
req->work_cb = work_cb;
|
req->work_cb = work_cb;
|
||||||
req->after_work_cb = after_work_cb;
|
req->after_work_cb = after_work_cb;
|
||||||
|
|
||||||
req->eio = eio_custom(uv__work, EIO_PRI_DEFAULT, uv__after_work, req, &loop->uv_eio_channel);
|
req->eio = eio_custom(uv__work,
|
||||||
|
EIO_PRI_DEFAULT,
|
||||||
|
uv__after_work,
|
||||||
|
req,
|
||||||
|
&loop->uv_eio_channel);
|
||||||
|
|
||||||
if (!req->eio) {
|
if (!req->eio) {
|
||||||
uv__set_sys_error(loop, ENOMEM);
|
uv__set_sys_error(loop, ENOMEM);
|
||||||
|
|||||||
@ -1,79 +0,0 @@
|
|||||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to
|
|
||||||
* deal in the Software without restriction, including without limitation the
|
|
||||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
* sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
* IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uv.h"
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__idle(EV_P_ ev_idle* w, int revents) {
|
|
||||||
uv_idle_t* idle = container_of(w, uv_idle_t, idle_watcher);
|
|
||||||
|
|
||||||
if (idle->idle_cb) {
|
|
||||||
idle->idle_cb(idle, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv_idle_init(uv_loop_t* loop, uv_idle_t* idle) {
|
|
||||||
uv__handle_init(loop, (uv_handle_t*)idle, UV_IDLE);
|
|
||||||
loop->counters.idle_init++;
|
|
||||||
|
|
||||||
ev_idle_init(&idle->idle_watcher, uv__idle);
|
|
||||||
idle->idle_cb = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) {
|
|
||||||
int was_active = ev_is_active(&idle->idle_watcher);
|
|
||||||
|
|
||||||
idle->idle_cb = cb;
|
|
||||||
ev_idle_start(idle->loop->ev, &idle->idle_watcher);
|
|
||||||
|
|
||||||
if (!was_active) {
|
|
||||||
ev_unref(idle->loop->ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv_idle_stop(uv_idle_t* idle) {
|
|
||||||
int was_active = ev_is_active(&idle->idle_watcher);
|
|
||||||
|
|
||||||
ev_idle_stop(idle->loop->ev, &idle->idle_watcher);
|
|
||||||
|
|
||||||
if (was_active) {
|
|
||||||
ev_ref(idle->loop->ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv__idle_active(const uv_idle_t* handle) {
|
|
||||||
return ev_is_active(&handle->idle_watcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv__idle_close(uv_idle_t* handle) {
|
|
||||||
uv_idle_stop(handle);
|
|
||||||
}
|
|
||||||
@ -84,24 +84,41 @@
|
|||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
enum {
|
enum {
|
||||||
UV_CLOSING = 0x01, /* uv_close() called but not finished. */
|
UV_CLOSING = 0x01, /* uv_close() called but not finished. */
|
||||||
UV_CLOSED = 0x02, /* close(2) finished. */
|
UV_CLOSED = 0x02, /* close(2) finished. */
|
||||||
UV_STREAM_READING = 0x04, /* uv_read_start() called. */
|
UV_STREAM_READING = 0x04, /* uv_read_start() called. */
|
||||||
UV_STREAM_SHUTTING = 0x08, /* uv_shutdown() called but not complete. */
|
UV_STREAM_SHUTTING = 0x08, /* uv_shutdown() called but not complete. */
|
||||||
UV_STREAM_SHUT = 0x10, /* Write side closed. */
|
UV_STREAM_SHUT = 0x10, /* Write side closed. */
|
||||||
UV_STREAM_READABLE = 0x20, /* The stream is readable */
|
UV_STREAM_READABLE = 0x20, /* The stream is readable */
|
||||||
UV_STREAM_WRITABLE = 0x40, /* The stream is writable */
|
UV_STREAM_WRITABLE = 0x40, /* The stream is writable */
|
||||||
UV_TCP_NODELAY = 0x080, /* Disable Nagle. */
|
UV_TCP_NODELAY = 0x080, /* Disable Nagle. */
|
||||||
UV_TCP_KEEPALIVE = 0x100, /* Turn on keep-alive. */
|
UV_TCP_KEEPALIVE = 0x100, /* Turn on keep-alive. */
|
||||||
UV_TIMER_ACTIVE = 0x080,
|
UV_TIMER_REPEAT = 0x100,
|
||||||
UV_TIMER_REPEAT = 0x100
|
UV__PENDING = 0x800
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline static int uv__has_pending_handles(const uv_loop_t* loop) {
|
||||||
|
return loop->pending_handles != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void uv__make_pending(uv_handle_t* h) {
|
||||||
|
if (h->flags & UV__PENDING) return;
|
||||||
|
h->next_pending = h->loop->pending_handles;
|
||||||
|
h->loop->pending_handles = h;
|
||||||
|
h->flags |= UV__PENDING;
|
||||||
|
}
|
||||||
|
#define uv__make_pending(h) uv__make_pending((uv_handle_t*)(h))
|
||||||
|
|
||||||
inline static void uv__req_init(uv_loop_t* loop,
|
inline static void uv__req_init(uv_loop_t* loop,
|
||||||
uv_req_t* req,
|
uv_req_t* req,
|
||||||
uv_req_type type) {
|
uv_req_type type) {
|
||||||
loop->counters.req_init++;
|
loop->counters.req_init++;
|
||||||
req->type = type;
|
req->type = type;
|
||||||
|
#ifndef UV_LEAN_AND_MEAN
|
||||||
|
ngx_queue_insert_tail(&loop->active_reqs, &req->active_queue);
|
||||||
|
#else
|
||||||
|
loop->active_reqs++;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#define uv__req_init(loop, req, type) \
|
#define uv__req_init(loop, req, type) \
|
||||||
uv__req_init((loop), (uv_req_t*)(req), (type))
|
uv__req_init((loop), (uv_req_t*)(req), (type))
|
||||||
@ -112,10 +129,14 @@ int uv__nonblock(int fd, int set) __attribute__((unused));
|
|||||||
int uv__cloexec(int fd, int set) __attribute__((unused));
|
int uv__cloexec(int fd, int set) __attribute__((unused));
|
||||||
int uv__socket(int domain, int type, int protocol);
|
int uv__socket(int domain, int type, int protocol);
|
||||||
int uv__dup(int fd);
|
int uv__dup(int fd);
|
||||||
|
int uv_async_stop(uv_async_t* handle);
|
||||||
|
|
||||||
/* loop */
|
/* loop */
|
||||||
int uv__loop_init(uv_loop_t* loop, int default_loop);
|
int uv__loop_init(uv_loop_t* loop, int default_loop);
|
||||||
void uv__loop_delete(uv_loop_t* loop);
|
void uv__loop_delete(uv_loop_t* loop);
|
||||||
|
void uv__run_idle(uv_loop_t* loop);
|
||||||
|
void uv__run_check(uv_loop_t* loop);
|
||||||
|
void uv__run_prepare(uv_loop_t* loop);
|
||||||
|
|
||||||
/* error */
|
/* error */
|
||||||
uv_err_code uv_translate_sys_error(int sys_errno);
|
uv_err_code uv_translate_sys_error(int sys_errno);
|
||||||
@ -146,11 +167,6 @@ void uv__poll_close(uv_poll_t* handle);
|
|||||||
int uv__poll_active(const uv_poll_t* handle);
|
int uv__poll_active(const uv_poll_t* handle);
|
||||||
|
|
||||||
/* various */
|
/* various */
|
||||||
int uv__check_active(const uv_check_t* handle);
|
|
||||||
int uv__idle_active(const uv_idle_t* handle);
|
|
||||||
int uv__prepare_active(const uv_prepare_t* handle);
|
|
||||||
int uv__timer_active(const uv_timer_t* handle);
|
|
||||||
|
|
||||||
void uv__async_close(uv_async_t* handle);
|
void uv__async_close(uv_async_t* handle);
|
||||||
void uv__check_close(uv_check_t* handle);
|
void uv__check_close(uv_check_t* handle);
|
||||||
void uv__fs_event_close(uv_fs_event_t* handle);
|
void uv__fs_event_close(uv_fs_event_t* handle);
|
||||||
@ -163,6 +179,8 @@ void uv__timer_close(uv_timer_t* handle);
|
|||||||
void uv__udp_close(uv_udp_t* handle);
|
void uv__udp_close(uv_udp_t* handle);
|
||||||
void uv__udp_finish_close(uv_udp_t* handle);
|
void uv__udp_finish_close(uv_udp_t* handle);
|
||||||
|
|
||||||
|
void uv__stream_pending(uv_stream_t* handle);
|
||||||
|
|
||||||
#define UV__F_IPC (1 << 0)
|
#define UV__F_IPC (1 << 0)
|
||||||
#define UV__F_NONBLOCK (1 << 1)
|
#define UV__F_NONBLOCK (1 << 1)
|
||||||
int uv__make_socketpair(int fds[2], int flags);
|
int uv__make_socketpair(int fds[2], int flags);
|
||||||
|
|||||||
@ -42,12 +42,10 @@ static void uv__fs_event_start(uv_fs_event_t* handle) {
|
|||||||
handle->fd,
|
handle->fd,
|
||||||
EV_LIBUV_KQUEUE_HACK);
|
EV_LIBUV_KQUEUE_HACK);
|
||||||
ev_io_start(handle->loop->ev, &handle->event_watcher);
|
ev_io_start(handle->loop->ev, &handle->event_watcher);
|
||||||
ev_unref(handle->loop->ev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void uv__fs_event_stop(uv_fs_event_t* handle) {
|
static void uv__fs_event_stop(uv_fs_event_t* handle) {
|
||||||
ev_ref(handle->loop->ev);
|
|
||||||
ev_io_stop(handle->loop->ev, &handle->event_watcher);
|
ev_io_stop(handle->loop->ev, &handle->event_watcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +102,7 @@ int uv_fs_event_init(uv_loop_t* loop,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
|
uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
|
||||||
|
uv__handle_start(handle); /* FIXME shouldn't start automatically */
|
||||||
handle->filename = strdup(filename);
|
handle->filename = strdup(filename);
|
||||||
handle->fflags = 0;
|
handle->fflags = 0;
|
||||||
handle->cb = cb;
|
handle->cb = cb;
|
||||||
@ -116,6 +115,7 @@ int uv_fs_event_init(uv_loop_t* loop,
|
|||||||
|
|
||||||
void uv__fs_event_close(uv_fs_event_t* handle) {
|
void uv__fs_event_close(uv_fs_event_t* handle) {
|
||||||
uv__fs_event_stop(handle);
|
uv__fs_event_stop(handle);
|
||||||
|
uv__handle_stop(handle);
|
||||||
free(handle->filename);
|
free(handle->filename);
|
||||||
close(handle->fd);
|
close(handle->fd);
|
||||||
handle->fd = -1;
|
handle->fd = -1;
|
||||||
|
|||||||
@ -90,7 +90,6 @@ static int init_inotify(uv_loop_t* loop) {
|
|||||||
loop->inotify_fd,
|
loop->inotify_fd,
|
||||||
EV_READ);
|
EV_READ);
|
||||||
ev_io_start(loop->ev, &loop->inotify_read_watcher);
|
ev_io_start(loop->ev, &loop->inotify_read_watcher);
|
||||||
ev_unref(loop->ev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -193,6 +192,7 @@ int uv_fs_event_init(uv_loop_t* loop,
|
|||||||
if (wd == -1) return uv__set_sys_error(loop, errno);
|
if (wd == -1) return uv__set_sys_error(loop, errno);
|
||||||
|
|
||||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
|
uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
|
||||||
|
uv__handle_start(handle); /* FIXME shouldn't start automatically */
|
||||||
handle->filename = strdup(filename);
|
handle->filename = strdup(filename);
|
||||||
handle->cb = cb;
|
handle->cb = cb;
|
||||||
handle->fd = wd;
|
handle->fd = wd;
|
||||||
@ -209,4 +209,5 @@ void uv__fs_event_close(uv_fs_event_t* handle) {
|
|||||||
|
|
||||||
free(handle->filename);
|
free(handle->filename);
|
||||||
handle->filename = NULL;
|
handle->filename = NULL;
|
||||||
|
uv__handle_stop(handle);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,13 +33,24 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) {
|
|||||||
#else
|
#else
|
||||||
int flags = EVFLAG_AUTO;
|
int flags = EVFLAG_AUTO;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memset(loop, 0, sizeof(*loop));
|
memset(loop, 0, sizeof(*loop));
|
||||||
|
|
||||||
|
#ifndef UV_LEAN_AND_MEAN
|
||||||
|
ngx_queue_init(&loop->active_handles);
|
||||||
|
ngx_queue_init(&loop->active_reqs);
|
||||||
|
#endif
|
||||||
|
|
||||||
RB_INIT(&loop->uv_ares_handles_);
|
RB_INIT(&loop->uv_ares_handles_);
|
||||||
loop->endgame_handles = NULL;
|
ngx_queue_init(&loop->idle_handles);
|
||||||
|
ngx_queue_init(&loop->check_handles);
|
||||||
|
ngx_queue_init(&loop->prepare_handles);
|
||||||
|
loop->pending_handles = NULL;
|
||||||
loop->channel = NULL;
|
loop->channel = NULL;
|
||||||
loop->ev = (default_loop ? ev_default_loop : ev_loop_new)(flags);
|
loop->ev = (default_loop ? ev_default_loop : ev_loop_new)(flags);
|
||||||
ev_set_userdata(loop->ev, loop);
|
ev_set_userdata(loop->ev, loop);
|
||||||
eio_channel_init(&loop->uv_eio_channel, loop);
|
eio_channel_init(&loop->uv_eio_channel, loop);
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
RB_INIT(&loop->inotify_watchers);
|
RB_INIT(&loop->inotify_watchers);
|
||||||
loop->inotify_fd = -1;
|
loop->inotify_fd = -1;
|
||||||
@ -65,3 +76,40 @@ void uv__loop_delete(uv_loop_t* loop) {
|
|||||||
close(loop->fs_fd);
|
close(loop->fs_fd);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define X(name, type) \
|
||||||
|
int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
|
||||||
|
uv__handle_init(loop, (uv_handle_t*)handle, type); \
|
||||||
|
loop->counters.name##_init++; \
|
||||||
|
handle->name##_cb = NULL; \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \
|
||||||
|
if (uv__is_active(handle)) return 0; \
|
||||||
|
ngx_queue_insert_head(&handle->loop->name##_handles, &handle->queue); \
|
||||||
|
handle->name##_cb = cb; \
|
||||||
|
uv__handle_start(handle); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
int uv_##name##_stop(uv_##name##_t* handle) { \
|
||||||
|
if (!uv__is_active(handle)) return 0; \
|
||||||
|
ngx_queue_remove(&handle->queue); \
|
||||||
|
uv__handle_stop(handle); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
void uv__run_##name(uv_loop_t* loop) { \
|
||||||
|
uv_##name##_t* h; \
|
||||||
|
ngx_queue_t* q; \
|
||||||
|
ngx_queue_foreach(q, &loop->name##_handles) { \
|
||||||
|
h = ngx_queue_data(q, uv_##name##_t, queue); \
|
||||||
|
if (h->name##_cb) h->name##_cb(h, 0); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
void uv__##name##_close(uv_##name##_t* handle) { \
|
||||||
|
uv_##name##_stop(handle); \
|
||||||
|
}
|
||||||
|
X(idle, UV_IDLE)
|
||||||
|
X(check, UV_CHECK)
|
||||||
|
X(prepare, UV_PREPARE)
|
||||||
|
#undef X
|
||||||
|
|||||||
@ -33,6 +33,8 @@
|
|||||||
int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
|
int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
|
||||||
uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);
|
uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);
|
||||||
loop->counters.pipe_init++;
|
loop->counters.pipe_init++;
|
||||||
|
handle->shutdown_req = NULL;
|
||||||
|
handle->connect_req = NULL;
|
||||||
handle->pipe_fname = NULL;
|
handle->pipe_fname = NULL;
|
||||||
handle->ipc = ipc;
|
handle->ipc = ipc;
|
||||||
return 0;
|
return 0;
|
||||||
@ -209,23 +211,21 @@ void uv_pipe_connect(uv_connect_t* req,
|
|||||||
uv__stream_open((uv_stream_t*)handle,
|
uv__stream_open((uv_stream_t*)handle,
|
||||||
sockfd,
|
sockfd,
|
||||||
UV_STREAM_READABLE | UV_STREAM_WRITABLE);
|
UV_STREAM_READABLE | UV_STREAM_WRITABLE);
|
||||||
|
|
||||||
ev_io_start(handle->loop->ev, &handle->read_watcher);
|
ev_io_start(handle->loop->ev, &handle->read_watcher);
|
||||||
ev_io_start(handle->loop->ev, &handle->write_watcher);
|
ev_io_start(handle->loop->ev, &handle->write_watcher);
|
||||||
|
|
||||||
status = 0;
|
status = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
handle->delayed_error = status; /* Passed to callback. */
|
handle->delayed_error = status; /* Passed to callback. */
|
||||||
handle->connect_req = req;
|
handle->connect_req = req;
|
||||||
|
|
||||||
|
uv__req_init(handle->loop, req, UV_CONNECT);
|
||||||
req->handle = (uv_stream_t*)handle;
|
req->handle = (uv_stream_t*)handle;
|
||||||
req->type = UV_CONNECT;
|
|
||||||
req->cb = cb;
|
req->cb = cb;
|
||||||
ngx_queue_init(&req->queue);
|
ngx_queue_init(&req->queue);
|
||||||
|
|
||||||
/* Run callback on next tick. */
|
/* Run callback on next tick. */
|
||||||
ev_feed_event(handle->loop->ev, &handle->read_watcher, EV_CUSTOM);
|
uv__make_pending(handle);
|
||||||
assert(ev_is_pending(&handle->read_watcher));
|
|
||||||
|
|
||||||
/* Mimic the Windows pipe implementation, always
|
/* Mimic the Windows pipe implementation, always
|
||||||
* return 0 and let the callback handle errors.
|
* return 0 and let the callback handle errors.
|
||||||
|
|||||||
@ -34,7 +34,7 @@ static void uv__poll_io(EV_P_ ev_io* watcher, int ev_events) {
|
|||||||
if (ev_events & EV_ERROR) {
|
if (ev_events & EV_ERROR) {
|
||||||
/* An error happened. Libev has implicitly stopped the watcher, but we */
|
/* An error happened. Libev has implicitly stopped the watcher, but we */
|
||||||
/* need to fix the refcount. */
|
/* need to fix the refcount. */
|
||||||
uv_ref(handle->loop);
|
uv__handle_stop(handle);
|
||||||
uv__set_sys_error(handle->loop, EBADF);
|
uv__set_sys_error(handle->loop, EBADF);
|
||||||
handle->poll_cb(handle, -1, 0);
|
handle->poll_cb(handle, -1, 0);
|
||||||
return;
|
return;
|
||||||
@ -74,10 +74,8 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
|
|||||||
|
|
||||||
|
|
||||||
static void uv__poll_stop(uv_poll_t* handle) {
|
static void uv__poll_stop(uv_poll_t* handle) {
|
||||||
if (ev_is_active(&handle->io_watcher)) {
|
ev_io_stop(handle->loop->ev, &handle->io_watcher);
|
||||||
ev_io_stop(handle->loop->ev, &handle->io_watcher);
|
uv__handle_stop(handle);
|
||||||
uv_ref(handle->loop);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -111,10 +109,8 @@ int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb poll_cb) {
|
|||||||
ev_io_set(&handle->io_watcher, handle->fd, ev_events);
|
ev_io_set(&handle->io_watcher, handle->fd, ev_events);
|
||||||
ev_io_start(handle->loop->ev, &handle->io_watcher);
|
ev_io_start(handle->loop->ev, &handle->io_watcher);
|
||||||
|
|
||||||
if (!was_active)
|
|
||||||
uv_unref(handle->loop);
|
|
||||||
|
|
||||||
handle->poll_cb = poll_cb;
|
handle->poll_cb = poll_cb;
|
||||||
|
uv__handle_start(handle);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,79 +0,0 @@
|
|||||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to
|
|
||||||
* deal in the Software without restriction, including without limitation the
|
|
||||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
* sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
* IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "uv.h"
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__prepare(EV_P_ ev_prepare* w, int revents) {
|
|
||||||
uv_prepare_t* prepare = container_of(w, uv_prepare_t, prepare_watcher);
|
|
||||||
|
|
||||||
if (prepare->prepare_cb) {
|
|
||||||
prepare->prepare_cb(prepare, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare) {
|
|
||||||
uv__handle_init(loop, (uv_handle_t*)prepare, UV_PREPARE);
|
|
||||||
loop->counters.prepare_init++;
|
|
||||||
|
|
||||||
ev_prepare_init(&prepare->prepare_watcher, uv__prepare);
|
|
||||||
prepare->prepare_cb = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb) {
|
|
||||||
int was_active = ev_is_active(&prepare->prepare_watcher);
|
|
||||||
|
|
||||||
prepare->prepare_cb = cb;
|
|
||||||
|
|
||||||
ev_prepare_start(prepare->loop->ev, &prepare->prepare_watcher);
|
|
||||||
|
|
||||||
if (!was_active) {
|
|
||||||
ev_unref(prepare->loop->ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv_prepare_stop(uv_prepare_t* prepare) {
|
|
||||||
int was_active = ev_is_active(&prepare->prepare_watcher);
|
|
||||||
|
|
||||||
ev_prepare_stop(prepare->loop->ev, &prepare->prepare_watcher);
|
|
||||||
|
|
||||||
if (was_active) {
|
|
||||||
ev_ref(prepare->loop->ev);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int uv__prepare_active(const uv_prepare_t* handle) {
|
|
||||||
return ev_is_active(&handle->prepare_watcher);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv__prepare_close(uv_prepare_t* handle) {
|
|
||||||
uv_prepare_stop(handle);
|
|
||||||
}
|
|
||||||
@ -181,6 +181,7 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
|||||||
|
|
||||||
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
|
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
|
||||||
loop->counters.process_init++;
|
loop->counters.process_init++;
|
||||||
|
uv__handle_start(process);
|
||||||
|
|
||||||
process->exit_cb = options.exit_cb;
|
process->exit_cb = options.exit_cb;
|
||||||
|
|
||||||
@ -384,4 +385,5 @@ uv_err_t uv_kill(int pid, int signum) {
|
|||||||
|
|
||||||
void uv__process_close(uv_process_t* handle) {
|
void uv__process_close(uv_process_t* handle) {
|
||||||
ev_child_stop(handle->loop->ev, &handle->child_watcher);
|
ev_child_stop(handle->loop->ev, &handle->child_watcher);
|
||||||
|
uv__handle_stop(handle);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -123,6 +123,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
|
|||||||
|
|
||||||
|
|
||||||
void uv__stream_destroy(uv_stream_t* stream) {
|
void uv__stream_destroy(uv_stream_t* stream) {
|
||||||
|
uv_shutdown_t* shutdown_req;
|
||||||
uv_write_t* req;
|
uv_write_t* req;
|
||||||
ngx_queue_t* q;
|
ngx_queue_t* q;
|
||||||
|
|
||||||
@ -133,6 +134,8 @@ void uv__stream_destroy(uv_stream_t* stream) {
|
|||||||
ngx_queue_remove(q);
|
ngx_queue_remove(q);
|
||||||
|
|
||||||
req = ngx_queue_data(q, uv_write_t, queue);
|
req = ngx_queue_data(q, uv_write_t, queue);
|
||||||
|
uv__req_unregister(stream->loop, req);
|
||||||
|
|
||||||
if (req->bufs != req->bufsml)
|
if (req->bufs != req->bufsml)
|
||||||
free(req->bufs);
|
free(req->bufs);
|
||||||
|
|
||||||
@ -147,18 +150,27 @@ void uv__stream_destroy(uv_stream_t* stream) {
|
|||||||
ngx_queue_remove(q);
|
ngx_queue_remove(q);
|
||||||
|
|
||||||
req = ngx_queue_data(q, uv_write_t, queue);
|
req = ngx_queue_data(q, uv_write_t, queue);
|
||||||
|
uv__req_unregister(stream->loop, req);
|
||||||
|
|
||||||
if (req->cb) {
|
if (req->cb) {
|
||||||
uv__set_sys_error(stream->loop, req->error);
|
uv__set_sys_error(stream->loop, req->error);
|
||||||
req->cb(req, req->error ? -1 : 0);
|
req->cb(req, req->error ? -1 : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream->flags & UV_STREAM_SHUTTING) {
|
if (!(stream->flags & UV_STREAM_SHUTTING))
|
||||||
uv_shutdown_t* req = stream->shutdown_req;
|
return;
|
||||||
if (req && req->cb) {
|
|
||||||
uv__set_artificial_error(stream->loop, UV_EINTR);
|
if (!stream->shutdown_req)
|
||||||
req->cb(req, -1);
|
return;
|
||||||
}
|
|
||||||
|
shutdown_req = stream->shutdown_req;
|
||||||
|
stream->shutdown_req = NULL;
|
||||||
|
uv__req_unregister(stream->loop, shutdown_req);
|
||||||
|
|
||||||
|
if (shutdown_req->cb) {
|
||||||
|
uv__set_artificial_error(stream->loop, UV_EINTR);
|
||||||
|
shutdown_req->cb(shutdown_req, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,15 +264,26 @@ out:
|
|||||||
|
|
||||||
|
|
||||||
int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
||||||
|
int r;
|
||||||
|
|
||||||
switch (stream->type) {
|
switch (stream->type) {
|
||||||
case UV_TCP:
|
case UV_TCP:
|
||||||
return uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
|
r = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
|
||||||
|
break;
|
||||||
|
|
||||||
case UV_NAMED_PIPE:
|
case UV_NAMED_PIPE:
|
||||||
return uv_pipe_listen((uv_pipe_t*)stream, backlog, cb);
|
r = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r == 0)
|
||||||
|
uv__handle_start(stream);
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -300,6 +323,7 @@ static void uv__drain(uv_stream_t* stream) {
|
|||||||
|
|
||||||
req = stream->shutdown_req;
|
req = stream->shutdown_req;
|
||||||
stream->shutdown_req = NULL;
|
stream->shutdown_req = NULL;
|
||||||
|
uv__req_unregister(stream->loop, req);
|
||||||
|
|
||||||
if (shutdown(stream->fd, SHUT_WR)) {
|
if (shutdown(stream->fd, SHUT_WR)) {
|
||||||
/* Error. Report it. User should call uv_close(). */
|
/* Error. Report it. User should call uv_close(). */
|
||||||
@ -499,24 +523,21 @@ start:
|
|||||||
|
|
||||||
|
|
||||||
static void uv__write_callbacks(uv_stream_t* stream) {
|
static void uv__write_callbacks(uv_stream_t* stream) {
|
||||||
int callbacks_made = 0;
|
|
||||||
ngx_queue_t* q;
|
|
||||||
uv_write_t* req;
|
uv_write_t* req;
|
||||||
|
ngx_queue_t* q;
|
||||||
|
|
||||||
while (!ngx_queue_empty(&stream->write_completed_queue)) {
|
while (!ngx_queue_empty(&stream->write_completed_queue)) {
|
||||||
/* Pop a req off write_completed_queue. */
|
/* Pop a req off write_completed_queue. */
|
||||||
q = ngx_queue_head(&stream->write_completed_queue);
|
q = ngx_queue_head(&stream->write_completed_queue);
|
||||||
assert(q);
|
req = ngx_queue_data(q, uv_write_t, queue);
|
||||||
req = ngx_queue_data(q, struct uv_write_s, queue);
|
|
||||||
ngx_queue_remove(q);
|
ngx_queue_remove(q);
|
||||||
|
uv__req_unregister(stream->loop, req);
|
||||||
|
|
||||||
/* NOTE: call callback AFTER freeing the request data. */
|
/* NOTE: call callback AFTER freeing the request data. */
|
||||||
if (req->cb) {
|
if (req->cb) {
|
||||||
uv__set_sys_error(stream->loop, req->error);
|
uv__set_sys_error(stream->loop, req->error);
|
||||||
req->cb(req, req->error ? -1 : 0);
|
req->cb(req, req->error ? -1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
callbacks_made++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(ngx_queue_empty(&stream->write_completed_queue));
|
assert(ngx_queue_empty(&stream->write_completed_queue));
|
||||||
@ -628,6 +649,8 @@ static void uv__read(uv_stream_t* stream) {
|
|||||||
/* EOF */
|
/* EOF */
|
||||||
uv__set_artificial_error(stream->loop, UV_EOF);
|
uv__set_artificial_error(stream->loop, UV_EOF);
|
||||||
ev_io_stop(ev, &stream->read_watcher);
|
ev_io_stop(ev, &stream->read_watcher);
|
||||||
|
if (!ev_is_active(&stream->write_watcher))
|
||||||
|
uv__handle_stop(stream);
|
||||||
|
|
||||||
if (stream->read_cb) {
|
if (stream->read_cb) {
|
||||||
stream->read_cb(stream, -1, buf);
|
stream->read_cb(stream, -1, buf);
|
||||||
@ -704,9 +727,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
|
|||||||
req->handle = stream;
|
req->handle = stream;
|
||||||
req->cb = cb;
|
req->cb = cb;
|
||||||
stream->shutdown_req = req;
|
stream->shutdown_req = req;
|
||||||
|
stream->flags |= UV_STREAM_SHUTTING;
|
||||||
((uv_handle_t*)stream)->flags |= UV_STREAM_SHUTTING;
|
|
||||||
|
|
||||||
|
|
||||||
ev_io_start(stream->loop->ev, &stream->write_watcher);
|
ev_io_start(stream->loop->ev, &stream->write_watcher);
|
||||||
|
|
||||||
@ -714,6 +735,11 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv__stream_pending(uv_stream_t* handle) {
|
||||||
|
uv__stream_io(handle->loop->ev, &handle->write_watcher, EV_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv__stream_io(EV_P_ ev_io* watcher, int revents) {
|
void uv__stream_io(EV_P_ ev_io* watcher, int revents) {
|
||||||
uv_stream_t* stream = watcher->data;
|
uv_stream_t* stream = watcher->data;
|
||||||
|
|
||||||
@ -767,26 +793,18 @@ static void uv__stream_connect(uv_stream_t* stream) {
|
|||||||
getsockopt(stream->fd, SOL_SOCKET, SO_ERROR, &error, &errorsize);
|
getsockopt(stream->fd, SOL_SOCKET, SO_ERROR, &error, &errorsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error) {
|
if (error == EINPROGRESS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (error == 0)
|
||||||
ev_io_start(stream->loop->ev, &stream->read_watcher);
|
ev_io_start(stream->loop->ev, &stream->read_watcher);
|
||||||
|
|
||||||
/* Successful connection */
|
stream->connect_req = NULL;
|
||||||
stream->connect_req = NULL;
|
uv__req_unregister(stream->loop, req);
|
||||||
if (req->cb) {
|
|
||||||
req->cb(req, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (error == EINPROGRESS) {
|
if (req->cb) {
|
||||||
/* Still connecting. */
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
/* Error */
|
|
||||||
uv__set_sys_error(stream->loop, error);
|
uv__set_sys_error(stream->loop, error);
|
||||||
|
req->cb(req, error ? -1 : 0);
|
||||||
stream->connect_req = NULL;
|
|
||||||
if (req->cb) {
|
|
||||||
req->cb(req, -1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -855,9 +873,8 @@ int uv__connect(uv_connect_t* req, uv_stream_t* stream, struct sockaddr* addr,
|
|||||||
assert(stream->write_watcher.data == stream);
|
assert(stream->write_watcher.data == stream);
|
||||||
ev_io_start(stream->loop->ev, &stream->write_watcher);
|
ev_io_start(stream->loop->ev, &stream->write_watcher);
|
||||||
|
|
||||||
if (stream->delayed_error) {
|
if (stream->delayed_error)
|
||||||
ev_feed_event(stream->loop->ev, &stream->write_watcher, EV_WRITE);
|
uv__make_pending(stream);
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -961,7 +978,7 @@ int uv__read_start_common(uv_stream_t* stream, uv_alloc_cb alloc_cb,
|
|||||||
/* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just
|
/* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just
|
||||||
* expresses the desired state of the user.
|
* expresses the desired state of the user.
|
||||||
*/
|
*/
|
||||||
((uv_handle_t*)stream)->flags |= UV_STREAM_READING;
|
stream->flags |= UV_STREAM_READING;
|
||||||
|
|
||||||
/* TODO: try to do the read inline? */
|
/* TODO: try to do the read inline? */
|
||||||
/* TODO: keep track of tcp state. If we've gotten a EOF then we should
|
/* TODO: keep track of tcp state. If we've gotten a EOF then we should
|
||||||
@ -978,6 +995,8 @@ int uv__read_start_common(uv_stream_t* stream, uv_alloc_cb alloc_cb,
|
|||||||
assert(stream->read_watcher.cb == uv__stream_io);
|
assert(stream->read_watcher.cb == uv__stream_io);
|
||||||
|
|
||||||
ev_io_start(stream->loop->ev, &stream->read_watcher);
|
ev_io_start(stream->loop->ev, &stream->read_watcher);
|
||||||
|
uv__handle_start(stream);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -996,6 +1015,7 @@ int uv_read2_start(uv_stream_t* stream, uv_alloc_cb alloc_cb,
|
|||||||
|
|
||||||
int uv_read_stop(uv_stream_t* stream) {
|
int uv_read_stop(uv_stream_t* stream) {
|
||||||
ev_io_stop(stream->loop->ev, &stream->read_watcher);
|
ev_io_stop(stream->loop->ev, &stream->read_watcher);
|
||||||
|
uv__handle_stop(stream);
|
||||||
stream->flags &= ~UV_STREAM_READING;
|
stream->flags &= ~UV_STREAM_READING;
|
||||||
stream->read_cb = NULL;
|
stream->read_cb = NULL;
|
||||||
stream->read2_cb = NULL;
|
stream->read2_cb = NULL;
|
||||||
|
|||||||
@ -180,15 +180,16 @@ int uv_fs_event_init(uv_loop_t* loop,
|
|||||||
/* We don't support any flags yet. */
|
/* We don't support any flags yet. */
|
||||||
assert(!flags);
|
assert(!flags);
|
||||||
if (loop->fs_fd == -1) {
|
if (loop->fs_fd == -1) {
|
||||||
if ((portfd = port_create()) == -1) {
|
if ((portfd = port_create()) == -1) {
|
||||||
uv__set_sys_error(loop, errno);
|
uv__set_sys_error(loop, errno);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
loop->fs_fd = portfd;
|
loop->fs_fd = portfd;
|
||||||
first_run = 1;
|
first_run = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
|
uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
|
||||||
|
uv__handle_start(handle); /* FIXME shouldn't start automatically */
|
||||||
handle->filename = strdup(filename);
|
handle->filename = strdup(filename);
|
||||||
handle->fd = PORT_UNUSED;
|
handle->fd = PORT_UNUSED;
|
||||||
handle->cb = cb;
|
handle->cb = cb;
|
||||||
@ -200,7 +201,6 @@ int uv_fs_event_init(uv_loop_t* loop,
|
|||||||
if (first_run) {
|
if (first_run) {
|
||||||
ev_io_init(&loop->fs_event_watcher, uv__fs_event_read, portfd, EV_READ);
|
ev_io_init(&loop->fs_event_watcher, uv__fs_event_read, portfd, EV_READ);
|
||||||
ev_io_start(loop->ev, &loop->fs_event_watcher);
|
ev_io_start(loop->ev, &loop->fs_event_watcher);
|
||||||
ev_unref(loop->ev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -31,16 +31,14 @@ static int uv__timer_repeating(const uv_timer_t* timer) {
|
|||||||
static void uv__timer_cb(EV_P_ ev_timer* w, int revents) {
|
static void uv__timer_cb(EV_P_ ev_timer* w, int revents) {
|
||||||
uv_timer_t* timer = container_of(w, uv_timer_t, timer_watcher);
|
uv_timer_t* timer = container_of(w, uv_timer_t, timer_watcher);
|
||||||
|
|
||||||
assert(uv__timer_active(timer));
|
if (!uv__is_active(timer))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!uv__timer_repeating(timer)) {
|
if (!uv__timer_repeating(timer))
|
||||||
timer->flags &= ~UV_TIMER_ACTIVE;
|
uv__handle_stop(timer);
|
||||||
ev_ref(EV_A);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (timer->timer_cb) {
|
if (timer->timer_cb)
|
||||||
timer->timer_cb(timer, 0);
|
timer->timer_cb(timer, 0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -56,12 +54,11 @@ int uv_timer_init(uv_loop_t* loop, uv_timer_t* timer) {
|
|||||||
|
|
||||||
int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout,
|
int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout,
|
||||||
int64_t repeat) {
|
int64_t repeat) {
|
||||||
if (uv__timer_active(timer)) {
|
if (uv__is_active(timer)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer->timer_cb = cb;
|
timer->timer_cb = cb;
|
||||||
timer->flags |= UV_TIMER_ACTIVE;
|
|
||||||
|
|
||||||
if (repeat)
|
if (repeat)
|
||||||
timer->flags |= UV_TIMER_REPEAT;
|
timer->flags |= UV_TIMER_REPEAT;
|
||||||
@ -70,26 +67,22 @@ int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout,
|
|||||||
|
|
||||||
ev_timer_set(&timer->timer_watcher, timeout / 1000.0, repeat / 1000.0);
|
ev_timer_set(&timer->timer_watcher, timeout / 1000.0, repeat / 1000.0);
|
||||||
ev_timer_start(timer->loop->ev, &timer->timer_watcher);
|
ev_timer_start(timer->loop->ev, &timer->timer_watcher);
|
||||||
ev_unref(timer->loop->ev);
|
uv__handle_start(timer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv_timer_stop(uv_timer_t* timer) {
|
int uv_timer_stop(uv_timer_t* timer) {
|
||||||
if (uv__timer_active(timer)) {
|
timer->flags &= ~UV_TIMER_REPEAT;
|
||||||
ev_ref(timer->loop->ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
timer->flags &= ~(UV_TIMER_ACTIVE | UV_TIMER_REPEAT);
|
|
||||||
ev_timer_stop(timer->loop->ev, &timer->timer_watcher);
|
ev_timer_stop(timer->loop->ev, &timer->timer_watcher);
|
||||||
|
uv__handle_stop(timer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv_timer_again(uv_timer_t* timer) {
|
int uv_timer_again(uv_timer_t* timer) {
|
||||||
if (!uv__timer_active(timer)) {
|
if (!uv__is_active(timer)) {
|
||||||
uv__set_artificial_error(timer->loop, UV_EINVAL);
|
uv__set_artificial_error(timer->loop, UV_EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -117,11 +110,6 @@ int64_t uv_timer_get_repeat(uv_timer_t* timer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv__timer_active(const uv_timer_t* timer) {
|
|
||||||
return timer->flags & UV_TIMER_ACTIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv__timer_close(uv_timer_t* handle) {
|
void uv__timer_close(uv_timer_t* handle) {
|
||||||
uv_timer_stop(handle);
|
uv_timer_stop(handle);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,16 +46,20 @@ static void uv__udp_start_watcher(uv_udp_t* handle,
|
|||||||
ev_set_cb(w, cb);
|
ev_set_cb(w, cb);
|
||||||
ev_io_set(w, handle->fd, flags);
|
ev_io_set(w, handle->fd, flags);
|
||||||
ev_io_start(handle->loop->ev, w);
|
ev_io_start(handle->loop->ev, w);
|
||||||
ev_unref(handle->loop->ev);
|
uv__handle_start(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void uv__udp_stop_watcher(uv_udp_t* handle, ev_io* w) {
|
static void uv__udp_stop_watcher(uv_udp_t* handle, ev_io* w) {
|
||||||
if (!ev_is_active(w)) return;
|
if (!ev_is_active(w)) return;
|
||||||
ev_ref(handle->loop->ev);
|
|
||||||
ev_io_stop(handle->loop->ev, w);
|
ev_io_stop(handle->loop->ev, w);
|
||||||
ev_io_set(w, -1, 0);
|
ev_io_set(w, -1, 0);
|
||||||
ev_set_cb(w, NULL);
|
ev_set_cb(w, NULL);
|
||||||
|
|
||||||
|
if (!ev_is_active(&handle->read_watcher) &&
|
||||||
|
!ev_is_active(&handle->write_watcher)) {
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -108,6 +112,8 @@ void uv__udp_finish_close(uv_udp_t* handle) {
|
|||||||
ngx_queue_remove(q);
|
ngx_queue_remove(q);
|
||||||
|
|
||||||
req = ngx_queue_data(q, uv_udp_send_t, queue);
|
req = ngx_queue_data(q, uv_udp_send_t, queue);
|
||||||
|
uv__req_unregister(handle->loop, req);
|
||||||
|
|
||||||
if (req->send_cb) {
|
if (req->send_cb) {
|
||||||
/* FIXME proper error code like UV_EABORTED */
|
/* FIXME proper error code like UV_EABORTED */
|
||||||
uv__set_artificial_error(handle->loop, UV_EINTR);
|
uv__set_artificial_error(handle->loop, UV_EINTR);
|
||||||
@ -185,12 +191,10 @@ static void uv__udp_run_completed(uv_udp_t* handle) {
|
|||||||
|
|
||||||
while (!ngx_queue_empty(&handle->write_completed_queue)) {
|
while (!ngx_queue_empty(&handle->write_completed_queue)) {
|
||||||
q = ngx_queue_head(&handle->write_completed_queue);
|
q = ngx_queue_head(&handle->write_completed_queue);
|
||||||
assert(q != NULL);
|
|
||||||
|
|
||||||
ngx_queue_remove(q);
|
ngx_queue_remove(q);
|
||||||
|
|
||||||
req = ngx_queue_data(q, uv_udp_send_t, queue);
|
req = ngx_queue_data(q, uv_udp_send_t, queue);
|
||||||
assert(req != NULL);
|
uv__req_unregister(handle->loop, req);
|
||||||
|
|
||||||
if (req->bufs != req->bufsml)
|
if (req->bufs != req->bufsml)
|
||||||
free(req->bufs);
|
free(req->bufs);
|
||||||
|
|||||||
@ -27,47 +27,31 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
static uv_once_t uv__eio_init_once_guard = UV_ONCE_INIT;
|
||||||
|
|
||||||
|
|
||||||
static void uv_eio_do_poll(uv_idle_t* watcher, int status) {
|
static void uv_eio_do_poll(uv_idle_t* watcher, int status) {
|
||||||
assert(watcher == &(watcher->loop->uv_eio_poller));
|
uv_loop_t* loop = watcher->loop;
|
||||||
|
assert(watcher == &loop->uv_eio_poller);
|
||||||
/* printf("uv_eio_poller\n"); */
|
if (eio_poll(&loop->uv_eio_channel) != -1)
|
||||||
|
|
||||||
if (eio_poll(&watcher->loop->uv_eio_channel) != -1 && uv_is_active((uv_handle_t*) watcher)) {
|
|
||||||
/* printf("uv_eio_poller stop\n"); */
|
|
||||||
uv_idle_stop(watcher);
|
uv_idle_stop(watcher);
|
||||||
uv_unref(watcher->loop);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Called from the main thread. */
|
/* Called from the main thread. */
|
||||||
static void uv_eio_want_poll_notifier_cb(uv_async_t* watcher, int status) {
|
static void uv_eio_want_poll_notifier_cb(uv_async_t* watcher, int status) {
|
||||||
uv_loop_t* loop = watcher->loop;
|
uv_loop_t* loop = watcher->loop;
|
||||||
|
|
||||||
assert(watcher == &loop->uv_eio_want_poll_notifier);
|
assert(watcher == &loop->uv_eio_want_poll_notifier);
|
||||||
|
if (eio_poll(&loop->uv_eio_channel) == -1)
|
||||||
/* printf("want poll notifier\n"); */
|
|
||||||
|
|
||||||
if (eio_poll(&watcher->loop->uv_eio_channel) == -1 && !uv_is_active((uv_handle_t*) &loop->uv_eio_poller)) {
|
|
||||||
/* printf("uv_eio_poller start\n"); */
|
|
||||||
uv_idle_start(&loop->uv_eio_poller, uv_eio_do_poll);
|
uv_idle_start(&loop->uv_eio_poller, uv_eio_do_poll);
|
||||||
uv_ref(loop);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void uv_eio_done_poll_notifier_cb(uv_async_t* watcher, int revents) {
|
static void uv_eio_done_poll_notifier_cb(uv_async_t* watcher, int revents) {
|
||||||
uv_loop_t* loop = watcher->loop;
|
uv_loop_t* loop = watcher->loop;
|
||||||
|
|
||||||
assert(watcher == &loop->uv_eio_done_poll_notifier);
|
assert(watcher == &loop->uv_eio_done_poll_notifier);
|
||||||
|
if (eio_poll(&loop->uv_eio_channel) != -1)
|
||||||
/* printf("done poll notifier\n"); */
|
|
||||||
|
|
||||||
if (eio_poll(&watcher->loop->uv_eio_channel) != -1 && uv_is_active((uv_handle_t*) &loop->uv_eio_poller)) {
|
|
||||||
/* printf("uv_eio_poller stop\n"); */
|
|
||||||
uv_idle_stop(&loop->uv_eio_poller);
|
uv_idle_stop(&loop->uv_eio_poller);
|
||||||
uv_unref(loop);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -100,25 +84,20 @@ static void uv__eio_init(void) {
|
|||||||
eio_init(uv_eio_want_poll, uv_eio_done_poll);
|
eio_init(uv_eio_want_poll, uv_eio_done_poll);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uv_once_t uv__eio_init_once_guard = UV_ONCE_INIT;
|
|
||||||
|
|
||||||
|
|
||||||
void uv_eio_init(uv_loop_t* loop) {
|
void uv_eio_init(uv_loop_t* loop) {
|
||||||
if (loop->counters.eio_init == 0) {
|
if (loop->counters.eio_init) return;
|
||||||
loop->counters.eio_init++;
|
loop->counters.eio_init = 1;
|
||||||
|
|
||||||
uv_idle_init(loop, &loop->uv_eio_poller);
|
uv_idle_init(loop, &loop->uv_eio_poller);
|
||||||
uv_idle_start(&loop->uv_eio_poller, uv_eio_do_poll);
|
uv_idle_start(&loop->uv_eio_poller, uv_eio_do_poll);
|
||||||
|
|
||||||
loop->uv_eio_want_poll_notifier.data = loop;
|
loop->uv_eio_want_poll_notifier.data = loop;
|
||||||
uv_async_init(loop, &loop->uv_eio_want_poll_notifier,
|
uv_async_init(loop, &loop->uv_eio_want_poll_notifier,
|
||||||
uv_eio_want_poll_notifier_cb);
|
uv_eio_want_poll_notifier_cb);
|
||||||
uv_unref(loop);
|
|
||||||
|
|
||||||
uv_async_init(loop, &loop->uv_eio_done_poll_notifier,
|
uv_async_init(loop, &loop->uv_eio_done_poll_notifier,
|
||||||
uv_eio_done_poll_notifier_cb);
|
uv_eio_done_poll_notifier_cb);
|
||||||
uv_unref(loop);
|
|
||||||
|
|
||||||
uv_once(&uv__eio_init_once_guard, uv__eio_init);
|
uv_once(&uv__eio_init_once_guard, uv__eio_init);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -352,3 +352,13 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv_ref(uv_handle_t* handle) {
|
||||||
|
uv__handle_ref(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv_unref(uv_handle_t* handle) {
|
||||||
|
uv__handle_unref(handle);
|
||||||
|
}
|
||||||
|
|||||||
119
src/uv-common.h
119
src/uv-common.h
@ -27,11 +27,30 @@
|
|||||||
#ifndef UV_COMMON_H_
|
#ifndef UV_COMMON_H_
|
||||||
#define UV_COMMON_H_
|
#define UV_COMMON_H_
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
|
||||||
|
|
||||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
# define UNUSED /* empty */
|
||||||
|
#else
|
||||||
|
# define UNUSED __attribute__((unused))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
enum {
|
||||||
|
UV__ACTIVE = 0x4000,
|
||||||
|
UV__REF = 0x8000
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
# define UV__REF 0x00000020
|
||||||
|
# define UV__ACTIVE 0x00000040
|
||||||
|
#endif
|
||||||
|
|
||||||
struct uv_ares_task_s {
|
struct uv_ares_task_s {
|
||||||
UV_HANDLE_FIELDS
|
UV_HANDLE_FIELDS
|
||||||
@ -83,5 +102,105 @@ int uv__tcp_connect6(uv_connect_t* req,
|
|||||||
struct sockaddr_in6 address,
|
struct sockaddr_in6 address,
|
||||||
uv_connect_cb cb);
|
uv_connect_cb cb);
|
||||||
|
|
||||||
|
#ifndef UV_LEAN_AND_MEAN
|
||||||
|
|
||||||
|
UNUSED static int uv__has_active_handles(const uv_loop_t* loop) {
|
||||||
|
return !ngx_queue_empty(&loop->active_handles);
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED static int uv__has_active_reqs(const uv_loop_t* loop) {
|
||||||
|
return !ngx_queue_empty(&loop->active_reqs);
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED static void uv__active_handle_add(uv_handle_t* h) {
|
||||||
|
ngx_queue_insert_tail(&h->loop->active_handles, &h->active_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED static void uv__active_handle_rm(uv_handle_t* h) {
|
||||||
|
assert(uv__has_active_handles(h->loop));
|
||||||
|
ngx_queue_remove(&h->active_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED static void uv__req_register(uv_loop_t* loop, uv_req_t* req) {
|
||||||
|
ngx_queue_insert_tail(&loop->active_reqs, &req->active_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED static void uv__req_unregister(uv_loop_t* loop, uv_req_t* req) {
|
||||||
|
assert(uv__has_active_reqs(loop));
|
||||||
|
ngx_queue_remove(&req->active_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* UV_LEAN_AND_MEAN */
|
||||||
|
|
||||||
|
UNUSED static int uv__has_active_handles(const uv_loop_t* loop) {
|
||||||
|
return loop->active_handles > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED static int uv__has_active_reqs(const uv_loop_t* loop) {
|
||||||
|
return loop->active_reqs > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED static void uv__active_handle_add(uv_handle_t* h) {
|
||||||
|
h->loop->active_handles++;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED static void uv__active_handle_rm(uv_handle_t* h) {
|
||||||
|
assert(h->loop->active_handles > 0);
|
||||||
|
h->loop->active_handles--;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED static void uv__req_register(uv_loop_t* loop, uv_req_t* req) {
|
||||||
|
loop->active_reqs++;
|
||||||
|
(void) req;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNUSED static void uv__req_unregister(uv_loop_t* loop, uv_req_t* req) {
|
||||||
|
assert(loop->active_reqs > 0);
|
||||||
|
loop->active_reqs--;
|
||||||
|
(void) req;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* UV_LEAN_AND_MEAN */
|
||||||
|
|
||||||
|
#define uv__active_handle_add(h) uv__active_handle_add((uv_handle_t*)(h))
|
||||||
|
#define uv__active_handle_rm(h) uv__active_handle_rm((uv_handle_t*)(h))
|
||||||
|
|
||||||
|
#define uv__req_register(loop, req) uv__req_register((loop), (uv_req_t*)(req))
|
||||||
|
#define uv__req_unregister(loop, req) uv__req_unregister((loop), (uv_req_t*)(req))
|
||||||
|
|
||||||
|
UNUSED static int uv__is_active(const uv_handle_t* h) {
|
||||||
|
return !!(h->flags & UV__ACTIVE);
|
||||||
|
}
|
||||||
|
#define uv__is_active(h) uv__is_active((const uv_handle_t*)(h))
|
||||||
|
|
||||||
|
UNUSED static void uv__handle_start(uv_handle_t* h) {
|
||||||
|
if (h->flags & UV__ACTIVE) return;
|
||||||
|
if (!(h->flags & UV__REF)) return;
|
||||||
|
h->flags |= UV__ACTIVE;
|
||||||
|
uv__active_handle_add(h);
|
||||||
|
}
|
||||||
|
#define uv__handle_start(h) uv__handle_start((uv_handle_t*)(h))
|
||||||
|
|
||||||
|
UNUSED static void uv__handle_stop(uv_handle_t* h) {
|
||||||
|
if (!(h->flags & UV__ACTIVE)) return;
|
||||||
|
if (!(h->flags & UV__REF)) return;
|
||||||
|
uv__active_handle_rm(h);
|
||||||
|
h->flags &= ~UV__ACTIVE;
|
||||||
|
}
|
||||||
|
#define uv__handle_stop(h) uv__handle_stop((uv_handle_t*)(h))
|
||||||
|
|
||||||
|
UNUSED static void uv__handle_ref(uv_handle_t* h) {
|
||||||
|
if (h->flags & UV__REF) return;
|
||||||
|
if (h->flags & UV__ACTIVE) uv__active_handle_add(h);
|
||||||
|
h->flags |= UV__REF;
|
||||||
|
}
|
||||||
|
#define uv__handle_ref(h) uv__handle_ref((uv_handle_t*)(h))
|
||||||
|
|
||||||
|
UNUSED static void uv__handle_unref(uv_handle_t* h) {
|
||||||
|
if (!(h->flags & UV__REF)) return;
|
||||||
|
if (h->flags & UV__ACTIVE) uv__active_handle_rm(h);
|
||||||
|
h->flags &= ~UV__REF;
|
||||||
|
}
|
||||||
|
#define uv__handle_unref(h) uv__handle_unref((uv_handle_t*)(h))
|
||||||
|
|
||||||
#endif /* UV_COMMON_H_ */
|
#endif /* UV_COMMON_H_ */
|
||||||
|
|||||||
@ -59,12 +59,11 @@ void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) {
|
|||||||
!handle->async_sent) {
|
!handle->async_sent) {
|
||||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||||
handle->flags |= UV_HANDLE_CLOSED;
|
handle->flags |= UV_HANDLE_CLOSED;
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
if (handle->close_cb) {
|
if (handle->close_cb) {
|
||||||
handle->close_cb((uv_handle_t*)handle);
|
handle->close_cb((uv_handle_t*)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,12 +71,8 @@ void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) {
|
|||||||
int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
|
int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
|
||||||
uv_req_t* req;
|
uv_req_t* req;
|
||||||
|
|
||||||
loop->counters.handle_init++;
|
uv_handle_init(loop, (uv_handle_t*) handle);
|
||||||
loop->counters.async_init++;
|
|
||||||
|
|
||||||
handle->type = UV_ASYNC;
|
handle->type = UV_ASYNC;
|
||||||
handle->loop = loop;
|
|
||||||
handle->flags = 0;
|
|
||||||
handle->async_sent = 0;
|
handle->async_sent = 0;
|
||||||
handle->async_cb = async_cb;
|
handle->async_cb = async_cb;
|
||||||
|
|
||||||
@ -86,12 +81,23 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
|
|||||||
req->type = UV_WAKEUP;
|
req->type = UV_WAKEUP;
|
||||||
req->data = handle;
|
req->data = handle;
|
||||||
|
|
||||||
uv_ref(loop);
|
loop->counters.async_init++;
|
||||||
|
|
||||||
|
uv__handle_start(handle);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv_async_close(uv_loop_t* loop, uv_async_t* handle) {
|
||||||
|
if (!((uv_async_t*)handle)->async_sent) {
|
||||||
|
uv_want_endgame(loop, (uv_handle_t*) handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
uv__handle_start(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv_async_send(uv_async_t* handle) {
|
int uv_async_send(uv_async_t* handle) {
|
||||||
uv_loop_t* loop = handle->loop;
|
uv_loop_t* loop = handle->loop;
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
@ -132,6 +131,7 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read,
|
|||||||
}
|
}
|
||||||
/* remove handle from list */
|
/* remove handle from list */
|
||||||
uv_remove_ares_handle(uv_handle_ares);
|
uv_remove_ares_handle(uv_handle_ares);
|
||||||
|
uv__handle_stop(uv_handle_ares);
|
||||||
|
|
||||||
/* Post request to cleanup the Task */
|
/* Post request to cleanup the Task */
|
||||||
uv_ares_req = &uv_handle_ares->ares_req;
|
uv_ares_req = &uv_handle_ares->ares_req;
|
||||||
@ -178,7 +178,7 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read,
|
|||||||
|
|
||||||
/* add handle to list */
|
/* add handle to list */
|
||||||
uv_add_ares_handle(loop, uv_handle_ares);
|
uv_add_ares_handle(loop, uv_handle_ares);
|
||||||
uv_ref(loop);
|
uv__handle_start(uv_handle_ares);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we have a single polling timer for all ares sockets.
|
* we have a single polling timer for all ares sockets.
|
||||||
@ -229,7 +229,7 @@ void uv_process_ares_cleanup_req(uv_loop_t* loop, uv_ares_task_t* handle,
|
|||||||
unsigned int signaled = WaitForSingleObject(handle->h_close_event, 0);
|
unsigned int signaled = WaitForSingleObject(handle->h_close_event, 0);
|
||||||
|
|
||||||
if (signaled != WAIT_TIMEOUT) {
|
if (signaled != WAIT_TIMEOUT) {
|
||||||
uv_unref(loop);
|
uv__handle_stop(loop);
|
||||||
|
|
||||||
/* close event handle and free uv handle memory */
|
/* close event handle and free uv handle memory */
|
||||||
CloseHandle(handle->h_close_event);
|
CloseHandle(handle->h_close_event);
|
||||||
|
|||||||
@ -27,7 +27,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
@ -65,10 +64,16 @@ static void uv_loop_init(uv_loop_t* loop) {
|
|||||||
uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
|
uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
|
||||||
}
|
}
|
||||||
|
|
||||||
loop->refs = 0;
|
|
||||||
|
|
||||||
uv_update_time(loop);
|
uv_update_time(loop);
|
||||||
|
|
||||||
|
#ifndef UV_LEAN_AND_MEAN
|
||||||
|
ngx_queue_init(&loop->active_handles);
|
||||||
|
ngx_queue_init(&loop->active_reqs);
|
||||||
|
#else
|
||||||
|
loop->active_handles = 0;
|
||||||
|
loop->active_reqs = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
loop->pending_reqs_tail = NULL;
|
loop->pending_reqs_tail = NULL;
|
||||||
|
|
||||||
loop->endgame_handles = NULL;
|
loop->endgame_handles = NULL;
|
||||||
@ -145,21 +150,6 @@ void uv_loop_delete(uv_loop_t* loop) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv_loop_refcount(const uv_loop_t* loop) {
|
|
||||||
return loop->refs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv_ref(uv_loop_t* loop) {
|
|
||||||
loop->refs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv_unref(uv_loop_t* loop) {
|
|
||||||
loop->refs--;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv_poll(uv_loop_t* loop, int block) {
|
static void uv_poll(uv_loop_t* loop, int block) {
|
||||||
BOOL success;
|
BOOL success;
|
||||||
DWORD bytes, timeout;
|
DWORD bytes, timeout;
|
||||||
@ -226,6 +216,19 @@ static void uv_poll_ex(uv_loop_t* loop, int block) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UV_LEAN_AND_MEAN
|
||||||
|
# define UV_LOOP_ALIVE(loop) \
|
||||||
|
(!ngx_queue_empty(&(loop)->active_handles) || \
|
||||||
|
!ngx_queue_empty(&(loop)->active_reqs) || \
|
||||||
|
(loop)->endgame_handles != NULL)
|
||||||
|
#else
|
||||||
|
# define UV_LOOP_ALIVE(loop) \
|
||||||
|
((loop)->active_handles > 0 && \
|
||||||
|
(loop)->active_reqs > 0 && \
|
||||||
|
(loop)->endgame_handles != NULL)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define UV_LOOP_ONCE(loop, poll) \
|
#define UV_LOOP_ONCE(loop, poll) \
|
||||||
do { \
|
do { \
|
||||||
uv_update_time((loop)); \
|
uv_update_time((loop)); \
|
||||||
@ -240,7 +243,7 @@ static void uv_poll_ex(uv_loop_t* loop, int block) {
|
|||||||
uv_process_reqs((loop)); \
|
uv_process_reqs((loop)); \
|
||||||
uv_process_endgames((loop)); \
|
uv_process_endgames((loop)); \
|
||||||
\
|
\
|
||||||
if ((loop)->refs <= 0) { \
|
if (!UV_LOOP_ALIVE((loop))) { \
|
||||||
break; \
|
break; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@ -249,13 +252,13 @@ static void uv_poll_ex(uv_loop_t* loop, int block) {
|
|||||||
poll((loop), (loop)->idle_handles == NULL && \
|
poll((loop), (loop)->idle_handles == NULL && \
|
||||||
(loop)->pending_reqs_tail == NULL && \
|
(loop)->pending_reqs_tail == NULL && \
|
||||||
(loop)->endgame_handles == NULL && \
|
(loop)->endgame_handles == NULL && \
|
||||||
(loop)->refs > 0); \
|
UV_LOOP_ALIVE((loop))); \
|
||||||
\
|
\
|
||||||
uv_check_invoke((loop)); \
|
uv_check_invoke((loop)); \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
#define UV_LOOP(loop, poll) \
|
#define UV_LOOP(loop, poll) \
|
||||||
while ((loop)->refs > 0) { \
|
while (UV_LOOP_ALIVE((loop))) { \
|
||||||
UV_LOOP_ONCE(loop, poll) \
|
UV_LOOP_ONCE(loop, poll) \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,6 +280,6 @@ int uv_run(uv_loop_t* loop) {
|
|||||||
UV_LOOP(loop, uv_poll);
|
UV_LOOP(loop, uv_poll);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(loop->refs == 0);
|
assert(!UV_LOOP_ALIVE((loop)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -19,13 +19,14 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "uv.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "uv.h"
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
|
|
||||||
const unsigned int uv_directory_watcher_buffer_size = 4096;
|
const unsigned int uv_directory_watcher_buffer_size = 4096;
|
||||||
@ -33,9 +34,8 @@ const unsigned int uv_directory_watcher_buffer_size = 4096;
|
|||||||
|
|
||||||
static void uv_fs_event_init_handle(uv_loop_t* loop, uv_fs_event_t* handle,
|
static void uv_fs_event_init_handle(uv_loop_t* loop, uv_fs_event_t* handle,
|
||||||
const char* filename, uv_fs_event_cb cb) {
|
const char* filename, uv_fs_event_cb cb) {
|
||||||
|
uv_handle_init(loop, (uv_handle_t*) handle);
|
||||||
handle->type = UV_FS_EVENT;
|
handle->type = UV_FS_EVENT;
|
||||||
handle->loop = loop;
|
|
||||||
handle->flags = 0;
|
|
||||||
handle->cb = cb;
|
handle->cb = cb;
|
||||||
handle->dir_handle = INVALID_HANDLE_VALUE;
|
handle->dir_handle = INVALID_HANDLE_VALUE;
|
||||||
handle->buffer = NULL;
|
handle->buffer = NULL;
|
||||||
@ -53,10 +53,9 @@ static void uv_fs_event_init_handle(uv_loop_t* loop, uv_fs_event_t* handle,
|
|||||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||||
}
|
}
|
||||||
|
|
||||||
loop->counters.handle_init++;
|
uv__handle_start(handle);
|
||||||
loop->counters.fs_event_init++;
|
|
||||||
|
|
||||||
uv_ref(loop);
|
loop->counters.fs_event_init++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,7 +108,7 @@ static int uv_split_path(const wchar_t* filename, wchar_t** dir,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*file = wcsdup(filename);
|
*file = wcsdup(filename);
|
||||||
} else {
|
} else {
|
||||||
if (dir) {
|
if (dir) {
|
||||||
@ -152,7 +151,7 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
|
|||||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!uv_utf8_to_utf16(filename, filenamew,
|
if (!uv_utf8_to_utf16(filename, filenamew,
|
||||||
name_size / sizeof(wchar_t))) {
|
name_size / sizeof(wchar_t))) {
|
||||||
uv__set_sys_error(loop, GetLastError());
|
uv__set_sys_error(loop, GetLastError());
|
||||||
return -1;
|
return -1;
|
||||||
@ -172,11 +171,11 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
|
|||||||
handle->dirw = filenamew;
|
handle->dirw = filenamew;
|
||||||
dir_to_watch = filenamew;
|
dir_to_watch = filenamew;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* filename is a file. So we split filename into dir & file parts, and
|
* filename is a file. So we split filename into dir & file parts, and
|
||||||
* watch the dir directory.
|
* watch the dir directory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Convert to short path. */
|
/* Convert to short path. */
|
||||||
if (!GetShortPathNameW(filenamew, short_path, ARRAY_SIZE(short_path))) {
|
if (!GetShortPathNameW(filenamew, short_path, ARRAY_SIZE(short_path))) {
|
||||||
last_error = GetLastError();
|
last_error = GetLastError();
|
||||||
@ -226,7 +225,7 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->buffer = (char*)_aligned_malloc(uv_directory_watcher_buffer_size,
|
handle->buffer = (char*)_aligned_malloc(uv_directory_watcher_buffer_size,
|
||||||
sizeof(DWORD));
|
sizeof(DWORD));
|
||||||
if (!handle->buffer) {
|
if (!handle->buffer) {
|
||||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||||
@ -317,7 +316,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
|
|||||||
assert(!filename);
|
assert(!filename);
|
||||||
assert(!long_filenamew);
|
assert(!long_filenamew);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fire the event only if we were asked to watch a directory,
|
* Fire the event only if we were asked to watch a directory,
|
||||||
* or if the filename filter matches.
|
* or if the filename filter matches.
|
||||||
*/
|
*/
|
||||||
@ -328,8 +327,8 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
|
|||||||
file_info->FileNameLength / sizeof(wchar_t)) == 0) {
|
file_info->FileNameLength / sizeof(wchar_t)) == 0) {
|
||||||
|
|
||||||
if (handle->dirw) {
|
if (handle->dirw) {
|
||||||
/*
|
/*
|
||||||
* We attempt to convert the file name to its long form for
|
* We attempt to convert the file name to its long form for
|
||||||
* events that still point to valid files on disk.
|
* events that still point to valid files on disk.
|
||||||
* For removed and renamed events, we do not provide the file name.
|
* For removed and renamed events, we do not provide the file name.
|
||||||
*/
|
*/
|
||||||
@ -382,7 +381,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we couldn't get the long name - just use the name
|
* If we couldn't get the long name - just use the name
|
||||||
* provided by ReadDirectoryChangesW.
|
* provided by ReadDirectoryChangesW.
|
||||||
*/
|
*/
|
||||||
@ -471,6 +470,8 @@ void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) {
|
|||||||
if (!handle->req_pending) {
|
if (!handle->req_pending) {
|
||||||
uv_want_endgame(loop, (uv_handle_t*)handle);
|
uv_want_endgame(loop, (uv_handle_t*)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uv__handle_start(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -479,6 +480,7 @@ void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) {
|
|||||||
!handle->req_pending) {
|
!handle->req_pending) {
|
||||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||||
handle->flags |= UV_HANDLE_CLOSED;
|
handle->flags |= UV_HANDLE_CLOSED;
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
if (handle->buffer) {
|
if (handle->buffer) {
|
||||||
_aligned_free(handle->buffer);
|
_aligned_free(handle->buffer);
|
||||||
@ -508,7 +510,5 @@ void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) {
|
|||||||
if (handle->close_cb) {
|
if (handle->close_cb) {
|
||||||
handle->close_cb((uv_handle_t*)handle);
|
handle->close_cb((uv_handle_t*)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,7 +59,7 @@
|
|||||||
return -1; \
|
return -1; \
|
||||||
} \
|
} \
|
||||||
req->flags |= UV_FS_ASYNC_QUEUED; \
|
req->flags |= UV_FS_ASYNC_QUEUED; \
|
||||||
uv_ref((loop));
|
uv__req_register(loop, req);
|
||||||
|
|
||||||
#define SET_UV_LAST_ERROR_FROM_REQ(req) \
|
#define SET_UV_LAST_ERROR_FROM_REQ(req) \
|
||||||
uv__set_error(req->loop, req->errorno, req->sys_errno_);
|
uv__set_error(req->loop, req->errorno, req->sys_errno_);
|
||||||
@ -1519,6 +1519,7 @@ int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
|
|||||||
|
|
||||||
void uv_process_fs_req(uv_loop_t* loop, uv_fs_t* req) {
|
void uv_process_fs_req(uv_loop_t* loop, uv_fs_t* req) {
|
||||||
assert(req->cb);
|
assert(req->cb);
|
||||||
|
uv__req_unregister(loop, req);
|
||||||
SET_UV_LAST_ERROR_FROM_REQ(req);
|
SET_UV_LAST_ERROR_FROM_REQ(req);
|
||||||
req->cb(req);
|
req->cb(req);
|
||||||
}
|
}
|
||||||
@ -1552,10 +1553,6 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
|
|||||||
req->path = NULL;
|
req->path = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->flags & UV_FS_ASYNC_QUEUED) {
|
|
||||||
uv_unref(loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
req->flags |= UV_FS_CLEANEDUP;
|
req->flags |= UV_FS_CLEANEDUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -77,23 +77,21 @@ static uv_err_code uv_translate_eai_error(int eai_errno) {
|
|||||||
|
|
||||||
/* getaddrinfo worker thread implementation */
|
/* getaddrinfo worker thread implementation */
|
||||||
static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) {
|
static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) {
|
||||||
uv_getaddrinfo_t* handle = (uv_getaddrinfo_t*) parameter;
|
uv_getaddrinfo_t* req = (uv_getaddrinfo_t*) parameter;
|
||||||
uv_loop_t* loop = handle->loop;
|
uv_loop_t* loop = req->loop;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
assert(handle != NULL);
|
assert(req != NULL);
|
||||||
|
|
||||||
if (handle != NULL) {
|
/* call OS function on this thread */
|
||||||
/* call OS function on this thread */
|
ret = GetAddrInfoW(req->node,
|
||||||
ret = GetAddrInfoW(handle->node,
|
req->service,
|
||||||
handle->service,
|
req->hints,
|
||||||
handle->hints,
|
&req->res);
|
||||||
&handle->res);
|
req->retcode = ret;
|
||||||
handle->retcode = ret;
|
|
||||||
|
|
||||||
/* post getaddrinfo completed */
|
/* post getaddrinfo completed */
|
||||||
POST_COMPLETION_FOR_REQ(loop, &handle->getadddrinfo_req);
|
POST_COMPLETION_FOR_REQ(loop, req);
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -108,8 +106,7 @@ static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) {
|
|||||||
* and copy all structs and referenced strings into the one block.
|
* and copy all structs and referenced strings into the one block.
|
||||||
* Each size calculation is adjusted to avoid unaligned pointers.
|
* Each size calculation is adjusted to avoid unaligned pointers.
|
||||||
*/
|
*/
|
||||||
void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* handle,
|
void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* req) {
|
||||||
uv_req_t* req) {
|
|
||||||
int addrinfo_len = 0;
|
int addrinfo_len = 0;
|
||||||
int name_len = 0;
|
int name_len = 0;
|
||||||
size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo));
|
size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo));
|
||||||
@ -120,15 +117,15 @@ void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* handle,
|
|||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
/* release input parameter memory */
|
/* release input parameter memory */
|
||||||
if (handle->alloc != NULL) {
|
if (req->alloc != NULL) {
|
||||||
free(handle->alloc);
|
free(req->alloc);
|
||||||
handle->alloc = NULL;
|
req->alloc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->retcode == 0) {
|
if (req->retcode == 0) {
|
||||||
/* convert addrinfoW to addrinfo */
|
/* convert addrinfoW to addrinfo */
|
||||||
/* first calculate required length */
|
/* first calculate required length */
|
||||||
addrinfow_ptr = handle->res;
|
addrinfow_ptr = req->res;
|
||||||
while (addrinfow_ptr != NULL) {
|
while (addrinfow_ptr != NULL) {
|
||||||
addrinfo_len += addrinfo_struct_len +
|
addrinfo_len += addrinfo_struct_len +
|
||||||
ALIGNED_SIZE(addrinfow_ptr->ai_addrlen);
|
ALIGNED_SIZE(addrinfow_ptr->ai_addrlen);
|
||||||
@ -150,7 +147,7 @@ void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* handle,
|
|||||||
/* do conversions */
|
/* do conversions */
|
||||||
if (alloc_ptr != NULL) {
|
if (alloc_ptr != NULL) {
|
||||||
cur_ptr = alloc_ptr;
|
cur_ptr = alloc_ptr;
|
||||||
addrinfow_ptr = handle->res;
|
addrinfow_ptr = req->res;
|
||||||
|
|
||||||
while (addrinfow_ptr != NULL) {
|
while (addrinfow_ptr != NULL) {
|
||||||
/* copy addrinfo struct data */
|
/* copy addrinfo struct data */
|
||||||
@ -206,21 +203,21 @@ void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* handle,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* GetAddrInfo failed */
|
/* GetAddrInfo failed */
|
||||||
uv__set_artificial_error(loop, uv_translate_eai_error(handle->retcode));
|
uv__set_artificial_error(loop, uv_translate_eai_error(req->retcode));
|
||||||
status = -1;
|
status = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return memory to system */
|
/* return memory to system */
|
||||||
if (handle->res != NULL) {
|
if (req->res != NULL) {
|
||||||
FreeAddrInfoW(handle->res);
|
FreeAddrInfoW(req->res);
|
||||||
handle->res = NULL;
|
req->res = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
complete:
|
complete:
|
||||||
/* finally do callback with converted result */
|
uv__req_unregister(loop, req);
|
||||||
handle->getaddrinfo_cb(handle, status, (struct addrinfo*)alloc_ptr);
|
|
||||||
|
|
||||||
uv_unref(loop);
|
/* finally do callback with converted result */
|
||||||
|
req->getaddrinfo_cb(req, status, (struct addrinfo*)alloc_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -237,7 +234,7 @@ void uv_freeaddrinfo(struct addrinfo* ai) {
|
|||||||
/*
|
/*
|
||||||
* Entry point for getaddrinfo
|
* Entry point for getaddrinfo
|
||||||
* we convert the UTF-8 strings to UNICODE
|
* we convert the UTF-8 strings to UNICODE
|
||||||
* and save the UNICODE string pointers in the handle
|
* and save the UNICODE string pointers in the req
|
||||||
* We also copy hints so that caller does not need to keep memory until the
|
* We also copy hints so that caller does not need to keep memory until the
|
||||||
* callback.
|
* callback.
|
||||||
* return UV_OK if a callback will be made
|
* return UV_OK if a callback will be made
|
||||||
@ -248,7 +245,7 @@ void uv_freeaddrinfo(struct addrinfo* ai) {
|
|||||||
* Each size calculation is adjusted to avoid unaligned pointers.
|
* Each size calculation is adjusted to avoid unaligned pointers.
|
||||||
*/
|
*/
|
||||||
int uv_getaddrinfo(uv_loop_t* loop,
|
int uv_getaddrinfo(uv_loop_t* loop,
|
||||||
uv_getaddrinfo_t* handle,
|
uv_getaddrinfo_t* req,
|
||||||
uv_getaddrinfo_cb getaddrinfo_cb,
|
uv_getaddrinfo_cb getaddrinfo_cb,
|
||||||
const char* node,
|
const char* node,
|
||||||
const char* service,
|
const char* service,
|
||||||
@ -258,18 +255,18 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
|||||||
int hintssize = 0;
|
int hintssize = 0;
|
||||||
char* alloc_ptr = NULL;
|
char* alloc_ptr = NULL;
|
||||||
|
|
||||||
if (handle == NULL || getaddrinfo_cb == NULL ||
|
if (req == NULL || getaddrinfo_cb == NULL ||
|
||||||
(node == NULL && service == NULL)) {
|
(node == NULL && service == NULL)) {
|
||||||
uv__set_sys_error(loop, WSAEINVAL);
|
uv__set_sys_error(loop, WSAEINVAL);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_req_init(loop, (uv_req_t*)handle);
|
uv_req_init(loop, (uv_req_t*)req);
|
||||||
|
|
||||||
handle->getaddrinfo_cb = getaddrinfo_cb;
|
req->getaddrinfo_cb = getaddrinfo_cb;
|
||||||
handle->res = NULL;
|
req->res = NULL;
|
||||||
handle->type = UV_GETADDRINFO;
|
req->type = UV_GETADDRINFO;
|
||||||
handle->loop = loop;
|
req->loop = loop;
|
||||||
|
|
||||||
/* calculate required memory size for all input values */
|
/* calculate required memory size for all input values */
|
||||||
if (node != NULL) {
|
if (node != NULL) {
|
||||||
@ -300,12 +297,12 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* save alloc_ptr now so we can free if error */
|
/* save alloc_ptr now so we can free if error */
|
||||||
handle->alloc = (void*)alloc_ptr;
|
req->alloc = (void*)alloc_ptr;
|
||||||
|
|
||||||
/* convert node string to UTF16 into allocated memory and save pointer in */
|
/* convert node string to UTF16 into allocated memory and save pointer in */
|
||||||
/* handle */
|
/* the reques. */
|
||||||
if (node != NULL) {
|
if (node != NULL) {
|
||||||
handle->node = (wchar_t*)alloc_ptr;
|
req->node = (wchar_t*)alloc_ptr;
|
||||||
if (uv_utf8_to_utf16(node,
|
if (uv_utf8_to_utf16(node,
|
||||||
(wchar_t*) alloc_ptr,
|
(wchar_t*) alloc_ptr,
|
||||||
nodesize / sizeof(wchar_t)) == 0) {
|
nodesize / sizeof(wchar_t)) == 0) {
|
||||||
@ -314,13 +311,13 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
|||||||
}
|
}
|
||||||
alloc_ptr += nodesize;
|
alloc_ptr += nodesize;
|
||||||
} else {
|
} else {
|
||||||
handle->node = NULL;
|
req->node = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert service string to UTF16 into allocated memory and save pointer */
|
/* convert service string to UTF16 into allocated memory and save pointer */
|
||||||
/* in handle */
|
/* in the req. */
|
||||||
if (service != NULL) {
|
if (service != NULL) {
|
||||||
handle->service = (wchar_t*)alloc_ptr;
|
req->service = (wchar_t*)alloc_ptr;
|
||||||
if (uv_utf8_to_utf16(service,
|
if (uv_utf8_to_utf16(service,
|
||||||
(wchar_t*) alloc_ptr,
|
(wchar_t*) alloc_ptr,
|
||||||
servicesize / sizeof(wchar_t)) == 0) {
|
servicesize / sizeof(wchar_t)) == 0) {
|
||||||
@ -329,44 +326,39 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
|||||||
}
|
}
|
||||||
alloc_ptr += servicesize;
|
alloc_ptr += servicesize;
|
||||||
} else {
|
} else {
|
||||||
handle->service = NULL;
|
req->service = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy hints to allocated memory and save pointer in handle */
|
/* copy hints to allocated memory and save pointer in req */
|
||||||
if (hints != NULL) {
|
if (hints != NULL) {
|
||||||
handle->hints = (struct addrinfoW*)alloc_ptr;
|
req->hints = (struct addrinfoW*)alloc_ptr;
|
||||||
handle->hints->ai_family = hints->ai_family;
|
req->hints->ai_family = hints->ai_family;
|
||||||
handle->hints->ai_socktype = hints->ai_socktype;
|
req->hints->ai_socktype = hints->ai_socktype;
|
||||||
handle->hints->ai_protocol = hints->ai_protocol;
|
req->hints->ai_protocol = hints->ai_protocol;
|
||||||
handle->hints->ai_flags = hints->ai_flags;
|
req->hints->ai_flags = hints->ai_flags;
|
||||||
handle->hints->ai_addrlen = 0;
|
req->hints->ai_addrlen = 0;
|
||||||
handle->hints->ai_canonname = NULL;
|
req->hints->ai_canonname = NULL;
|
||||||
handle->hints->ai_addr = NULL;
|
req->hints->ai_addr = NULL;
|
||||||
handle->hints->ai_next = NULL;
|
req->hints->ai_next = NULL;
|
||||||
} else {
|
} else {
|
||||||
handle->hints = NULL;
|
req->hints = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init request for Post handling */
|
|
||||||
uv_req_init(loop, &handle->getadddrinfo_req);
|
|
||||||
handle->getadddrinfo_req.data = handle;
|
|
||||||
handle->getadddrinfo_req.type = UV_GETADDRINFO_REQ;
|
|
||||||
|
|
||||||
/* Ask thread to run. Treat this as a long operation */
|
/* Ask thread to run. Treat this as a long operation */
|
||||||
if (QueueUserWorkItem(&getaddrinfo_thread_proc,
|
if (QueueUserWorkItem(&getaddrinfo_thread_proc,
|
||||||
handle,
|
req,
|
||||||
WT_EXECUTELONGFUNCTION) == 0) {
|
WT_EXECUTELONGFUNCTION) == 0) {
|
||||||
uv__set_sys_error(loop, GetLastError());
|
uv__set_sys_error(loop, GetLastError());
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_ref(loop);
|
uv__req_register(loop, req);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (handle != NULL && handle->alloc != NULL) {
|
if (req != NULL && req->alloc != NULL) {
|
||||||
free(handle->alloc);
|
free(req->alloc);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,30 +57,23 @@ uv_handle_type uv_guess_handle(uv_file file) {
|
|||||||
|
|
||||||
|
|
||||||
int uv_is_active(const uv_handle_t* handle) {
|
int uv_is_active(const uv_handle_t* handle) {
|
||||||
switch (handle->type) {
|
return (handle->flags & UV__ACTIVE) && !(handle->flags & UV_HANDLE_CLOSING);
|
||||||
case UV_TIMER:
|
}
|
||||||
case UV_IDLE:
|
|
||||||
case UV_PREPARE:
|
|
||||||
case UV_CHECK:
|
|
||||||
return (handle->flags & UV_HANDLE_ACTIVE) ? 1 : 0;
|
|
||||||
|
|
||||||
case UV_POLL:
|
|
||||||
return ((uv_poll_t*) handle)->events != 0;
|
|
||||||
|
|
||||||
default:
|
void uv_handle_init(uv_loop_t* loop, uv_handle_t* handle) {
|
||||||
return 1;
|
handle->loop = loop;
|
||||||
}
|
handle->flags = UV__REF;
|
||||||
|
|
||||||
|
loop->counters.handle_init++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv_close(uv_handle_t* handle, uv_close_cb cb) {
|
void uv_close(uv_handle_t* handle, uv_close_cb cb) {
|
||||||
uv_pipe_t* pipe;
|
|
||||||
uv_udp_t* udp;
|
|
||||||
uv_process_t* process;
|
|
||||||
|
|
||||||
uv_loop_t* loop = handle->loop;
|
uv_loop_t* loop = handle->loop;
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||||
|
assert(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,16 +83,11 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
|
|||||||
/* Handle-specific close actions */
|
/* Handle-specific close actions */
|
||||||
switch (handle->type) {
|
switch (handle->type) {
|
||||||
case UV_TCP:
|
case UV_TCP:
|
||||||
uv_tcp_close((uv_tcp_t*)handle);
|
uv_tcp_close(loop, (uv_tcp_t*)handle);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case UV_NAMED_PIPE:
|
case UV_NAMED_PIPE:
|
||||||
pipe = (uv_pipe_t*)handle;
|
uv_pipe_close(loop, (uv_pipe_t*) handle);
|
||||||
pipe->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING);
|
|
||||||
close_pipe(pipe, NULL, NULL);
|
|
||||||
if (pipe->reqs_pending == 0) {
|
|
||||||
uv_want_endgame(loop, handle);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case UV_TTY:
|
case UV_TTY:
|
||||||
@ -107,51 +95,47 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case UV_UDP:
|
case UV_UDP:
|
||||||
udp = (uv_udp_t*) handle;
|
uv_udp_close(loop, (uv_udp_t*) handle);
|
||||||
uv_udp_recv_stop(udp);
|
|
||||||
closesocket(udp->socket);
|
|
||||||
if (udp->reqs_pending == 0) {
|
|
||||||
uv_want_endgame(loop, handle);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case UV_POLL:
|
case UV_POLL:
|
||||||
uv_poll_close(handle->loop, (uv_poll_t*) handle);
|
uv_poll_close(loop, (uv_poll_t*) handle);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case UV_TIMER:
|
case UV_TIMER:
|
||||||
uv_timer_stop((uv_timer_t*)handle);
|
uv_timer_stop((uv_timer_t*)handle);
|
||||||
|
uv__handle_start(handle);
|
||||||
uv_want_endgame(loop, handle);
|
uv_want_endgame(loop, handle);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case UV_PREPARE:
|
case UV_PREPARE:
|
||||||
uv_prepare_stop((uv_prepare_t*)handle);
|
uv_prepare_stop((uv_prepare_t*)handle);
|
||||||
|
uv__handle_start(handle);
|
||||||
uv_want_endgame(loop, handle);
|
uv_want_endgame(loop, handle);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case UV_CHECK:
|
case UV_CHECK:
|
||||||
uv_check_stop((uv_check_t*)handle);
|
uv_check_stop((uv_check_t*)handle);
|
||||||
|
uv__handle_start(handle);
|
||||||
uv_want_endgame(loop, handle);
|
uv_want_endgame(loop, handle);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case UV_IDLE:
|
case UV_IDLE:
|
||||||
uv_idle_stop((uv_idle_t*)handle);
|
uv_idle_stop((uv_idle_t*)handle);
|
||||||
|
uv__handle_start(handle);
|
||||||
uv_want_endgame(loop, handle);
|
uv_want_endgame(loop, handle);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case UV_ASYNC:
|
case UV_ASYNC:
|
||||||
if (!((uv_async_t*)handle)->async_sent) {
|
uv_async_close(loop, (uv_async_t*) handle);
|
||||||
uv_want_endgame(loop, handle);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case UV_PROCESS:
|
case UV_PROCESS:
|
||||||
process = (uv_process_t*)handle;
|
uv_process_close(loop, (uv_process_t*) handle);
|
||||||
uv_process_close(loop, process);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case UV_FS_EVENT:
|
case UV_FS_EVENT:
|
||||||
uv_fs_event_close(loop, (uv_fs_event_t*)handle);
|
uv_fs_event_close(loop, (uv_fs_event_t*) handle);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -179,7 +163,7 @@ void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
|||||||
void uv_process_endgames(uv_loop_t* loop) {
|
void uv_process_endgames(uv_loop_t* loop) {
|
||||||
uv_handle_t* handle;
|
uv_handle_t* handle;
|
||||||
|
|
||||||
while (loop->endgame_handles && loop->refs > 0) {
|
while (loop->endgame_handles) {
|
||||||
handle = loop->endgame_handles;
|
handle = loop->endgame_handles;
|
||||||
loop->endgame_handles = handle->endgame_next;
|
loop->endgame_handles = handle->endgame_next;
|
||||||
|
|
||||||
|
|||||||
@ -30,15 +30,6 @@
|
|||||||
#include "winsock.h"
|
#include "winsock.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Timers
|
|
||||||
*/
|
|
||||||
void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle);
|
|
||||||
|
|
||||||
DWORD uv_get_poll_timeout(uv_loop_t* loop);
|
|
||||||
void uv_process_timers(uv_loop_t* loop);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handles
|
* Handles
|
||||||
*/
|
*/
|
||||||
@ -47,10 +38,14 @@ void uv_process_timers(uv_loop_t* loop);
|
|||||||
#define UV_HANDLE_CLOSING 0x00000001
|
#define UV_HANDLE_CLOSING 0x00000001
|
||||||
#define UV_HANDLE_CLOSED 0x00000002
|
#define UV_HANDLE_CLOSED 0x00000002
|
||||||
#define UV_HANDLE_ENDGAME_QUEUED 0x00000004
|
#define UV_HANDLE_ENDGAME_QUEUED 0x00000004
|
||||||
#define UV_HANDLE_UV_ALLOCED 0x00000008
|
|
||||||
#define UV_HANDLE_ACTIVE 0x00000010
|
#define UV_HANDLE_ACTIVE 0x00000010
|
||||||
|
|
||||||
/* Used by streams. */
|
/* Keep in sync with uv-common.h: */
|
||||||
|
#define UV__REF 0x00000020
|
||||||
|
#define UV__ACTIVE 0x00000040
|
||||||
|
/* reserved: #define UV_HANDLE_INTERNAL 0x00000080 */
|
||||||
|
|
||||||
|
/* Used by streams and UDP handles. */
|
||||||
#define UV_HANDLE_READING 0x00000100
|
#define UV_HANDLE_READING 0x00000100
|
||||||
#define UV_HANDLE_BOUND 0x00000200
|
#define UV_HANDLE_BOUND 0x00000200
|
||||||
#define UV_HANDLE_BIND_ERROR 0x00000400
|
#define UV_HANDLE_BIND_ERROR 0x00000400
|
||||||
@ -72,8 +67,7 @@ void uv_process_timers(uv_loop_t* loop);
|
|||||||
#define UV_HANDLE_TCP_SINGLE_ACCEPT 0x08000000
|
#define UV_HANDLE_TCP_SINGLE_ACCEPT 0x08000000
|
||||||
#define UV_HANDLE_TCP_ACCEPT_STATE_CHANGING 0x10000000
|
#define UV_HANDLE_TCP_ACCEPT_STATE_CHANGING 0x10000000
|
||||||
#define UV_HANDLE_TCP_SOCKET_CLOSED 0x20000000
|
#define UV_HANDLE_TCP_SOCKET_CLOSED 0x20000000
|
||||||
#define UV_HANDLE_SHARED_TCP_SERVER 0x40000000
|
#define UV_HANDLE_SHARED_TCP_SOCKET 0x40000000
|
||||||
#define UV_HANDLE_SHARED_TCP_SOCKET 0x80000000
|
|
||||||
|
|
||||||
/* Only used by uv_pipe_t handles. */
|
/* Only used by uv_pipe_t handles. */
|
||||||
#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000
|
#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000
|
||||||
@ -108,6 +102,41 @@ void uv_process_endgames(uv_loop_t* loop);
|
|||||||
#define UV_SUCCEEDED_WITH_IOCP(result) \
|
#define UV_SUCCEEDED_WITH_IOCP(result) \
|
||||||
((result) || (GetLastError() == ERROR_IO_PENDING))
|
((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)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handles
|
||||||
|
*/
|
||||||
|
void uv_handle_init(uv_loop_t* loop, uv_handle_t* handle);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Requests
|
* Requests
|
||||||
@ -155,6 +184,7 @@ void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|||||||
void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
|
void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
|
||||||
uv_connect_t* req);
|
uv_connect_t* req);
|
||||||
|
|
||||||
|
void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp);
|
||||||
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
|
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
|
||||||
|
|
||||||
int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
|
int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
|
||||||
@ -163,8 +193,6 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
|
|||||||
int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
|
int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
|
||||||
LPWSAPROTOCOL_INFOW protocol_info);
|
LPWSAPROTOCOL_INFOW protocol_info);
|
||||||
|
|
||||||
void uv_tcp_close(uv_tcp_t* tcp);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UDP
|
* UDP
|
||||||
@ -173,6 +201,7 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req);
|
|||||||
void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
|
void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
|
||||||
uv_udp_send_t* req);
|
uv_udp_send_t* req);
|
||||||
|
|
||||||
|
void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle);
|
||||||
void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle);
|
void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle);
|
||||||
|
|
||||||
|
|
||||||
@ -181,8 +210,6 @@ void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle);
|
|||||||
*/
|
*/
|
||||||
int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
|
int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
|
||||||
char* name, size_t nameSize);
|
char* name, size_t nameSize);
|
||||||
void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err);
|
|
||||||
void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle);
|
|
||||||
|
|
||||||
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
|
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
|
||||||
int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client);
|
int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client);
|
||||||
@ -206,6 +233,10 @@ void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
|
|||||||
void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
|
void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
|
||||||
uv_shutdown_t* req);
|
uv_shutdown_t* req);
|
||||||
|
|
||||||
|
void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle);
|
||||||
|
void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle);
|
||||||
|
void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TTY
|
* TTY
|
||||||
@ -243,6 +274,15 @@ void uv_poll_close(uv_loop_t* loop, uv_poll_t* handle);
|
|||||||
void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle);
|
void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timers
|
||||||
|
*/
|
||||||
|
void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle);
|
||||||
|
|
||||||
|
DWORD uv_get_poll_timeout(uv_loop_t* loop);
|
||||||
|
void uv_process_timers(uv_loop_t* loop);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Loop watchers
|
* Loop watchers
|
||||||
*/
|
*/
|
||||||
@ -256,6 +296,7 @@ void uv_idle_invoke(uv_loop_t* loop);
|
|||||||
/*
|
/*
|
||||||
* Async watcher
|
* Async watcher
|
||||||
*/
|
*/
|
||||||
|
void uv_async_close(uv_loop_t* loop, uv_async_t* handle);
|
||||||
void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle);
|
void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle);
|
||||||
|
|
||||||
void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
|
void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
|
||||||
@ -284,8 +325,7 @@ void uv_process_ares_cleanup_req(uv_loop_t* loop, uv_ares_task_t* handle,
|
|||||||
/*
|
/*
|
||||||
* Getaddrinfo
|
* Getaddrinfo
|
||||||
*/
|
*/
|
||||||
void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* handle,
|
void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* req);
|
||||||
uv_req_t* req);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -22,7 +22,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
@ -30,25 +29,19 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
|||||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||||
handle->flags |= UV_HANDLE_CLOSED;
|
handle->flags |= UV_HANDLE_CLOSED;
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
if (handle->close_cb) {
|
if (handle->close_cb) {
|
||||||
handle->close_cb(handle);
|
handle->close_cb(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define UV_LOOP_WATCHER_DEFINE(name, NAME) \
|
#define UV_LOOP_WATCHER_DEFINE(name, NAME) \
|
||||||
int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
|
int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
|
||||||
|
uv_handle_init(loop, (uv_handle_t*) handle); \
|
||||||
handle->type = UV_##NAME; \
|
handle->type = UV_##NAME; \
|
||||||
handle->loop = loop; \
|
|
||||||
handle->flags = 0; \
|
|
||||||
\
|
|
||||||
uv_ref(loop); \
|
|
||||||
\
|
|
||||||
loop->counters.handle_init++; \
|
|
||||||
loop->counters.name##_init++; \
|
loop->counters.name##_init++; \
|
||||||
\
|
\
|
||||||
return 0; \
|
return 0; \
|
||||||
@ -77,6 +70,7 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
|||||||
\
|
\
|
||||||
handle->name##_cb = cb; \
|
handle->name##_cb = cb; \
|
||||||
handle->flags |= UV_HANDLE_ACTIVE; \
|
handle->flags |= UV_HANDLE_ACTIVE; \
|
||||||
|
uv__handle_start(handle); \
|
||||||
\
|
\
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
@ -108,6 +102,7 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
|
|||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
handle->flags &= ~UV_HANDLE_ACTIVE; \
|
handle->flags &= ~UV_HANDLE_ACTIVE; \
|
||||||
|
uv__handle_stop(handle); \
|
||||||
\
|
\
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
|
|||||||
@ -25,7 +25,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
@ -280,7 +279,6 @@ static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) {
|
|||||||
|
|
||||||
|
|
||||||
void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
|
void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
|
||||||
unsigned int uv_alloced;
|
|
||||||
DWORD result;
|
DWORD result;
|
||||||
uv_shutdown_t* req;
|
uv_shutdown_t* req;
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
@ -296,12 +294,14 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
|
|||||||
handle->shutdown_req = NULL;
|
handle->shutdown_req = NULL;
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||||
|
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
|
|
||||||
/* Already closing. Cancel the shutdown. */
|
/* Already closing. Cancel the shutdown. */
|
||||||
if (req->cb) {
|
if (req->cb) {
|
||||||
uv__set_sys_error(loop, WSAEINTR);
|
uv__set_sys_error(loop, WSAEINTR);
|
||||||
req->cb(req, -1);
|
req->cb(req, -1);
|
||||||
}
|
}
|
||||||
uv_unref(loop);
|
|
||||||
DECREASE_PENDING_REQ_COUNT(handle);
|
DECREASE_PENDING_REQ_COUNT(handle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -315,12 +315,14 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
|
|||||||
|
|
||||||
if (nt_status != STATUS_SUCCESS) {
|
if (nt_status != STATUS_SUCCESS) {
|
||||||
/* Failure */
|
/* Failure */
|
||||||
|
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
|
|
||||||
handle->flags &= ~UV_HANDLE_SHUTTING;
|
handle->flags &= ~UV_HANDLE_SHUTTING;
|
||||||
if (req->cb) {
|
if (req->cb) {
|
||||||
uv__set_sys_error(loop, pRtlNtStatusToDosError(nt_status));
|
uv__set_sys_error(loop, pRtlNtStatusToDosError(nt_status));
|
||||||
req->cb(req, -1);
|
req->cb(req, -1);
|
||||||
}
|
}
|
||||||
uv_unref(loop);
|
|
||||||
DECREASE_PENDING_REQ_COUNT(handle);
|
DECREASE_PENDING_REQ_COUNT(handle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -340,12 +342,14 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* Failure. */
|
/* Failure. */
|
||||||
|
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
|
|
||||||
handle->flags &= ~UV_HANDLE_SHUTTING;
|
handle->flags &= ~UV_HANDLE_SHUTTING;
|
||||||
if (req->cb) {
|
if (req->cb) {
|
||||||
uv__set_sys_error(loop, GetLastError());
|
uv__set_sys_error(loop, GetLastError());
|
||||||
req->cb(req, -1);
|
req->cb(req, -1);
|
||||||
}
|
}
|
||||||
uv_unref(loop);
|
|
||||||
DECREASE_PENDING_REQ_COUNT(handle);
|
DECREASE_PENDING_REQ_COUNT(handle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -355,6 +359,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
|
|||||||
handle->reqs_pending == 0) {
|
handle->reqs_pending == 0) {
|
||||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||||
handle->flags |= UV_HANDLE_CLOSED;
|
handle->flags |= UV_HANDLE_CLOSED;
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_CONNECTION) {
|
if (handle->flags & UV_HANDLE_CONNECTION) {
|
||||||
if (handle->pending_ipc_info.socket_info) {
|
if (handle->pending_ipc_info.socket_info) {
|
||||||
@ -380,19 +385,9 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
|
|||||||
handle->accept_reqs = NULL;
|
handle->accept_reqs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember the state of this flag because the close callback is */
|
|
||||||
/* allowed to clobber or free the handle's memory */
|
|
||||||
uv_alloced = handle->flags & UV_HANDLE_UV_ALLOCED;
|
|
||||||
|
|
||||||
if (handle->close_cb) {
|
if (handle->close_cb) {
|
||||||
handle->close_cb((uv_handle_t*)handle);
|
handle->close_cb((uv_handle_t*)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uv_alloced) {
|
|
||||||
free(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,7 +568,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -596,7 +591,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
|
|||||||
SET_REQ_SUCCESS(req);
|
SET_REQ_SUCCESS(req);
|
||||||
uv_insert_pending_req(loop, (uv_req_t*) req);
|
uv_insert_pending_req(loop, (uv_req_t*) req);
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -613,14 +608,14 @@ error:
|
|||||||
SET_REQ_ERROR(req, errorno);
|
SET_REQ_ERROR(req, errorno);
|
||||||
uv_insert_pending_req(loop, (uv_req_t*) req);
|
uv_insert_pending_req(loop, (uv_req_t*) req);
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Cleans up uv_pipe_t (server or connection) and all resources associated */
|
/* Cleans up uv_pipe_t (server or connection) and all resources associated */
|
||||||
/* with it. */
|
/* with it. */
|
||||||
void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) {
|
void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
|
||||||
int i;
|
int i;
|
||||||
HANDLE pipeHandle;
|
HANDLE pipeHandle;
|
||||||
|
|
||||||
@ -652,6 +647,27 @@ void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle) {
|
||||||
|
if (handle->flags & UV_HANDLE_READING) {
|
||||||
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle->flags & UV_HANDLE_LISTENING) {
|
||||||
|
handle->flags &= ~UV_HANDLE_LISTENING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
uv_pipe_cleanup(loop, handle);
|
||||||
|
|
||||||
|
if (handle->reqs_pending == 0) {
|
||||||
|
uv_want_endgame(loop, (uv_handle_t*) handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
uv__handle_start(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
|
static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
|
||||||
uv_pipe_accept_t* req, BOOL firstInstance) {
|
uv_pipe_accept_t* req, BOOL firstInstance) {
|
||||||
assert(handle->flags & UV_HANDLE_LISTENING);
|
assert(handle->flags & UV_HANDLE_LISTENING);
|
||||||
@ -717,7 +733,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return uv_tcp_import((uv_tcp_t*)client, server->pending_ipc_info.socket_info,
|
return uv_tcp_import((uv_tcp_t*)client, server->pending_ipc_info.socket_info,
|
||||||
server->pending_ipc_info.tcp_connection);
|
server->pending_ipc_info.tcp_connection);
|
||||||
} else {
|
} else {
|
||||||
pipe_client = (uv_pipe_t*)client;
|
pipe_client = (uv_pipe_t*)client;
|
||||||
@ -753,17 +769,19 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
|
|||||||
/* Starts listening for connections for the given pipe. */
|
/* Starts listening for connections for the given pipe. */
|
||||||
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
|
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
|
||||||
uv_loop_t* loop = handle->loop;
|
uv_loop_t* loop = handle->loop;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (handle->flags & UV_HANDLE_LISTENING) {
|
||||||
|
handle->connection_cb = cb;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(handle->flags & UV_HANDLE_BOUND)) {
|
if (!(handle->flags & UV_HANDLE_BOUND)) {
|
||||||
uv__set_artificial_error(loop, UV_EINVAL);
|
uv__set_artificial_error(loop, UV_EINVAL);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_LISTENING ||
|
if (handle->flags & UV_HANDLE_READING) {
|
||||||
handle->flags & UV_HANDLE_READING) {
|
uv__set_artificial_error(loop, UV_EISCONN);
|
||||||
uv__set_artificial_error(loop, UV_EALREADY);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -773,6 +791,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handle->flags |= UV_HANDLE_LISTENING;
|
handle->flags |= UV_HANDLE_LISTENING;
|
||||||
|
INCREASE_ACTIVE_COUNT(loop, handle);
|
||||||
handle->connection_cb = cb;
|
handle->connection_cb = cb;
|
||||||
|
|
||||||
/* First pipe handle should have already been created in uv_pipe_bind */
|
/* First pipe handle should have already been created in uv_pipe_bind */
|
||||||
@ -955,17 +974,13 @@ static int uv_pipe_read_start_impl(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_READING) {
|
|
||||||
uv__set_artificial_error(loop, UV_EALREADY);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_EOF) {
|
if (handle->flags & UV_HANDLE_EOF) {
|
||||||
uv__set_artificial_error(loop, UV_EOF);
|
uv__set_artificial_error(loop, UV_EOF);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle->flags |= UV_HANDLE_READING;
|
handle->flags |= UV_HANDLE_READING;
|
||||||
|
INCREASE_ACTIVE_COUNT(loop, handle);
|
||||||
handle->read_cb = read_cb;
|
handle->read_cb = read_cb;
|
||||||
handle->read2_cb = read2_cb;
|
handle->read2_cb = read2_cb;
|
||||||
handle->alloc_cb = alloc_cb;
|
handle->alloc_cb = alloc_cb;
|
||||||
@ -1154,10 +1169,10 @@ static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
|
|||||||
/* Request queued by the kernel. */
|
/* Request queued by the kernel. */
|
||||||
ipc_header_req->queued_bytes = ipc_frame.header.flags & UV_IPC_TCP_SERVER ?
|
ipc_header_req->queued_bytes = ipc_frame.header.flags & UV_IPC_TCP_SERVER ?
|
||||||
sizeof(ipc_frame) : sizeof(ipc_frame.header);
|
sizeof(ipc_frame) : sizeof(ipc_frame.header);
|
||||||
handle->write_queue_size += req->queued_bytes;
|
handle->write_queue_size += ipc_header_req->queued_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, ipc_header_req);
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
handle->write_reqs_pending++;
|
handle->write_reqs_pending++;
|
||||||
|
|
||||||
@ -1212,7 +1227,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
handle->write_reqs_pending++;
|
handle->write_reqs_pending++;
|
||||||
|
|
||||||
@ -1435,6 +1450,8 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
|
|||||||
assert(handle->write_queue_size >= req->queued_bytes);
|
assert(handle->write_queue_size >= req->queued_bytes);
|
||||||
handle->write_queue_size -= req->queued_bytes;
|
handle->write_queue_size -= req->queued_bytes;
|
||||||
|
|
||||||
|
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
|
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
|
||||||
if (req->wait_handle != INVALID_HANDLE_VALUE) {
|
if (req->wait_handle != INVALID_HANDLE_VALUE) {
|
||||||
UnregisterWait(req->wait_handle);
|
UnregisterWait(req->wait_handle);
|
||||||
@ -1476,7 +1493,6 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
|
|||||||
uv_want_endgame(loop, (uv_handle_t*)handle);
|
uv_want_endgame(loop, (uv_handle_t*)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
DECREASE_PENDING_REQ_COUNT(handle);
|
DECREASE_PENDING_REQ_COUNT(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1513,6 +1529,8 @@ void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
|
|||||||
uv_connect_t* req) {
|
uv_connect_t* req) {
|
||||||
assert(handle->type == UV_NAMED_PIPE);
|
assert(handle->type == UV_NAMED_PIPE);
|
||||||
|
|
||||||
|
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
|
|
||||||
if (req->cb) {
|
if (req->cb) {
|
||||||
if (REQ_SUCCESS(req)) {
|
if (REQ_SUCCESS(req)) {
|
||||||
uv_pipe_connection_init(handle);
|
uv_pipe_connection_init(handle);
|
||||||
@ -1523,7 +1541,6 @@ void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
DECREASE_PENDING_REQ_COUNT(handle);
|
DECREASE_PENDING_REQ_COUNT(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1532,6 +1549,8 @@ void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
|
|||||||
uv_shutdown_t* req) {
|
uv_shutdown_t* req) {
|
||||||
assert(handle->type == UV_NAMED_PIPE);
|
assert(handle->type == UV_NAMED_PIPE);
|
||||||
|
|
||||||
|
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
|
|
||||||
/* Initialize and optionally start the eof timer. */
|
/* Initialize and optionally start the eof timer. */
|
||||||
/* This makes no sense if we've already seen EOF. */
|
/* This makes no sense if we've already seen EOF. */
|
||||||
if (!(handle->flags & UV_HANDLE_EOF)) {
|
if (!(handle->flags & UV_HANDLE_EOF)) {
|
||||||
@ -1548,7 +1567,6 @@ void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
|
|||||||
req->cb(req, 0);
|
req->cb(req, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
DECREASE_PENDING_REQ_COUNT(handle);
|
DECREASE_PENDING_REQ_COUNT(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1564,7 +1582,7 @@ static void eof_timer_init(uv_pipe_t* pipe) {
|
|||||||
r = uv_timer_init(pipe->loop, pipe->eof_timer);
|
r = uv_timer_init(pipe->loop, pipe->eof_timer);
|
||||||
assert(r == 0); /* timers can't fail */
|
assert(r == 0); /* timers can't fail */
|
||||||
pipe->eof_timer->data = pipe;
|
pipe->eof_timer->data = pipe;
|
||||||
uv_unref(pipe->loop);
|
uv_unref((uv_handle_t*) pipe->eof_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1598,7 +1616,7 @@ static void eof_timer_cb(uv_timer_t* timer, int status) {
|
|||||||
/* or in uv_process_pipe_shutdown_req if a read is pending, */
|
/* or in uv_process_pipe_shutdown_req if a read is pending, */
|
||||||
/* and we always immediately stop the timer in */
|
/* and we always immediately stop the timer in */
|
||||||
/* uv_process_pipe_read_req. */
|
/* uv_process_pipe_read_req. */
|
||||||
assert(pipe->flags & UV_HANDLE_READ_PENDING) ;
|
assert(pipe->flags & UV_HANDLE_READ_PENDING);
|
||||||
|
|
||||||
/* If there are many packets coming off the iocp then the timer callback */
|
/* If there are many packets coming off the iocp then the timer callback */
|
||||||
/* may be called before the read request is coming off the queue. */
|
/* may be called before the read request is coming off the queue. */
|
||||||
@ -1627,7 +1645,6 @@ static void eof_timer_destroy(uv_pipe_t* pipe) {
|
|||||||
assert(pipe->flags && UV_HANDLE_CONNECTION);
|
assert(pipe->flags && UV_HANDLE_CONNECTION);
|
||||||
|
|
||||||
if (pipe->eof_timer) {
|
if (pipe->eof_timer) {
|
||||||
uv_ref(pipe->loop);
|
|
||||||
uv_close((uv_handle_t*) pipe->eof_timer, eof_timer_close_cb);
|
uv_close((uv_handle_t*) pipe->eof_timer, eof_timer_close_cb);
|
||||||
pipe->eof_timer = NULL;
|
pipe->eof_timer = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,13 +20,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "uv.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
|
||||||
#include "uv.h"
|
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
|
|
||||||
static const GUID uv_msafd_provider_ids[UV_MSAFD_PROVIDER_COUNT] = {
|
static const GUID uv_msafd_provider_ids[UV_MSAFD_PROVIDER_COUNT] = {
|
||||||
{0xe70f1aa0, 0xab8b, 0x11cf,
|
{0xe70f1aa0, 0xab8b, 0x11cf,
|
||||||
@ -202,6 +201,13 @@ static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
|
|||||||
assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
|
assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
|
||||||
|
|
||||||
handle->events = events;
|
handle->events = events;
|
||||||
|
|
||||||
|
if (handle->events != 0) {
|
||||||
|
uv__handle_start(handle);
|
||||||
|
} else {
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
}
|
||||||
|
|
||||||
if ((handle->events & ~(handle->submitted_events_1 |
|
if ((handle->events & ~(handle->submitted_events_1 |
|
||||||
handle->submitted_events_2)) != 0) {
|
handle->submitted_events_2)) != 0) {
|
||||||
uv__fast_poll_submit_poll_req(handle->loop, handle);
|
uv__fast_poll_submit_poll_req(handle->loop, handle);
|
||||||
@ -213,6 +219,7 @@ static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
|
|||||||
|
|
||||||
static void uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
|
static void uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
|
||||||
handle->events = 0;
|
handle->events = 0;
|
||||||
|
uv__handle_start(handle);
|
||||||
|
|
||||||
if (handle->submitted_events_1 == 0 &&
|
if (handle->submitted_events_1 == 0 &&
|
||||||
handle->submitted_events_2 == 0) {
|
handle->submitted_events_2 == 0) {
|
||||||
@ -449,6 +456,13 @@ static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
|
|||||||
assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
|
assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
|
||||||
|
|
||||||
handle->events = events;
|
handle->events = events;
|
||||||
|
|
||||||
|
if (handle->events != 0) {
|
||||||
|
uv__handle_start(handle);
|
||||||
|
} else {
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
}
|
||||||
|
|
||||||
if ((handle->events &
|
if ((handle->events &
|
||||||
~(handle->submitted_events_1 | handle->submitted_events_2)) != 0) {
|
~(handle->submitted_events_1 | handle->submitted_events_2)) != 0) {
|
||||||
uv__slow_poll_submit_poll_req(handle->loop, handle);
|
uv__slow_poll_submit_poll_req(handle->loop, handle);
|
||||||
@ -460,6 +474,7 @@ static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
|
|||||||
|
|
||||||
static void uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
|
static void uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
|
||||||
handle->events = 0;
|
handle->events = 0;
|
||||||
|
uv__handle_start(handle);
|
||||||
|
|
||||||
if (handle->submitted_events_1 == 0 &&
|
if (handle->submitted_events_1 == 0 &&
|
||||||
handle->submitted_events_2 == 0) {
|
handle->submitted_events_2 == 0) {
|
||||||
@ -501,10 +516,9 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
|
|||||||
socket = base_socket;
|
socket = base_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uv_handle_init(loop, (uv_handle_t*) handle);
|
||||||
handle->type = UV_POLL;
|
handle->type = UV_POLL;
|
||||||
handle->socket = socket;
|
handle->socket = socket;
|
||||||
handle->loop = loop;
|
|
||||||
handle->flags = 0;
|
|
||||||
handle->events = 0;
|
handle->events = 0;
|
||||||
|
|
||||||
/* Obtain protocol information about the socket. */
|
/* Obtain protocol information about the socket. */
|
||||||
@ -542,9 +556,6 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
|
|||||||
handle->poll_req_2.type = UV_POLL_REQ;
|
handle->poll_req_2.type = UV_POLL_REQ;
|
||||||
handle->poll_req_2.data = handle;
|
handle->poll_req_2.data = handle;
|
||||||
|
|
||||||
uv_ref(loop);
|
|
||||||
|
|
||||||
loop->counters.handle_init++;
|
|
||||||
loop->counters.poll_init++;
|
loop->counters.poll_init++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -561,6 +572,7 @@ int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handle->poll_cb = cb;
|
handle->poll_cb = cb;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,10 +612,9 @@ void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle) {
|
|||||||
assert(handle->submitted_events_2 == 0);
|
assert(handle->submitted_events_2 == 0);
|
||||||
|
|
||||||
handle->flags |= UV_HANDLE_CLOSED;
|
handle->flags |= UV_HANDLE_CLOSED;
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
if (handle->close_cb) {
|
if (handle->close_cb) {
|
||||||
handle->close_cb((uv_handle_t*)handle);
|
handle->close_cb((uv_handle_t*)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -55,9 +54,8 @@ typedef struct env_var {
|
|||||||
|
|
||||||
|
|
||||||
static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
|
static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
|
||||||
|
uv_handle_init(loop, (uv_handle_t*) handle);
|
||||||
handle->type = UV_PROCESS;
|
handle->type = UV_PROCESS;
|
||||||
handle->loop = loop;
|
|
||||||
handle->flags = 0;
|
|
||||||
handle->exit_cb = NULL;
|
handle->exit_cb = NULL;
|
||||||
handle->pid = 0;
|
handle->pid = 0;
|
||||||
handle->exit_signal = 0;
|
handle->exit_signal = 0;
|
||||||
@ -77,8 +75,6 @@ static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
|
|||||||
|
|
||||||
loop->counters.handle_init++;
|
loop->counters.handle_init++;
|
||||||
loop->counters.process_init++;
|
loop->counters.process_init++;
|
||||||
|
|
||||||
uv_ref(loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -689,30 +685,28 @@ static void close_child_stdio(uv_process_t* process) {
|
|||||||
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
|
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
|
||||||
DWORD exit_code;
|
DWORD exit_code;
|
||||||
|
|
||||||
|
/* FIXME: race condition. */
|
||||||
|
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Unregister from process notification. */
|
/* Unregister from process notification. */
|
||||||
if (handle->wait_handle != INVALID_HANDLE_VALUE) {
|
if (handle->wait_handle != INVALID_HANDLE_VALUE) {
|
||||||
UnregisterWait(handle->wait_handle);
|
UnregisterWait(handle->wait_handle);
|
||||||
handle->wait_handle = INVALID_HANDLE_VALUE;
|
handle->wait_handle = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->process_handle != INVALID_HANDLE_VALUE) {
|
if (handle->process_handle == INVALID_HANDLE_VALUE ||
|
||||||
/* Get the exit code. */
|
!GetExitCodeProcess(handle->process_handle, &exit_code)) {
|
||||||
if (!GetExitCodeProcess(handle->process_handle, &exit_code)) {
|
/* The process never even started in the first place, or we were unable */
|
||||||
exit_code = 127;
|
/* to obtain the exit code. */
|
||||||
}
|
|
||||||
|
|
||||||
/* Clean-up the process handle. */
|
|
||||||
CloseHandle(handle->process_handle);
|
|
||||||
handle->process_handle = INVALID_HANDLE_VALUE;
|
|
||||||
} else {
|
|
||||||
/* We probably left the child stdio handles open to report the error */
|
|
||||||
/* asynchronously, so close them now. */
|
|
||||||
close_child_stdio(handle);
|
|
||||||
|
|
||||||
/* The process never even started in the first place. */
|
|
||||||
exit_code = 127;
|
exit_code = 127;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the handle to inactive: no callbacks will be made after the exit */
|
||||||
|
/* callback.*/
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
/* Fire the exit callback. */
|
/* Fire the exit callback. */
|
||||||
if (handle->exit_cb) {
|
if (handle->exit_cb) {
|
||||||
handle->exit_cb(handle, exit_code, handle->exit_signal);
|
handle->exit_cb(handle, exit_code, handle->exit_signal);
|
||||||
@ -726,21 +720,9 @@ void uv_process_proc_close(uv_loop_t* loop, uv_process_t* handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) {
|
|
||||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
|
||||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
|
||||||
handle->flags |= UV_HANDLE_CLOSED;
|
|
||||||
|
|
||||||
if (handle->close_cb) {
|
|
||||||
handle->close_cb((uv_handle_t*)handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
|
void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
|
||||||
|
uv__handle_start(handle);
|
||||||
|
|
||||||
if (handle->wait_handle != INVALID_HANDLE_VALUE) {
|
if (handle->wait_handle != INVALID_HANDLE_VALUE) {
|
||||||
handle->close_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
|
handle->close_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
UnregisterWaitEx(handle->wait_handle, handle->close_handle);
|
UnregisterWaitEx(handle->wait_handle, handle->close_handle);
|
||||||
@ -755,6 +737,25 @@ void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) {
|
||||||
|
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||||
|
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||||
|
handle->flags |= UV_HANDLE_CLOSED;
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
|
/* Clean-up the process handle. */
|
||||||
|
CloseHandle(handle->process_handle);
|
||||||
|
|
||||||
|
/* Clean up the child stdio ends that may have been left open. */
|
||||||
|
close_child_stdio(handle);
|
||||||
|
|
||||||
|
if (handle->close_cb) {
|
||||||
|
handle->close_cb((uv_handle_t*)handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int uv_create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
|
static int uv_create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
|
||||||
HANDLE* child_pipe, DWORD server_access, DWORD child_access,
|
HANDLE* child_pipe, DWORD server_access, DWORD child_access,
|
||||||
int overlapped) {
|
int overlapped) {
|
||||||
@ -816,7 +817,7 @@ static int uv_create_stdio_pipe_pair(uv_loop_t* loop, uv_pipe_t* server_pipe,
|
|||||||
done:
|
done:
|
||||||
if (err) {
|
if (err) {
|
||||||
if (server_pipe->handle != INVALID_HANDLE_VALUE) {
|
if (server_pipe->handle != INVALID_HANDLE_VALUE) {
|
||||||
close_pipe(server_pipe, NULL, NULL);
|
uv_pipe_cleanup(loop, server_pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*child_pipe != INVALID_HANDLE_VALUE) {
|
if (*child_pipe != INVALID_HANDLE_VALUE) {
|
||||||
@ -1058,7 +1059,12 @@ done:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
if (err == 0) {
|
||||||
|
/* Spawn was succesful. The handle will be active until the exit */
|
||||||
|
/* is made or the handle is closed, whichever happens first. */
|
||||||
|
uv__handle_start(process);
|
||||||
|
} else {
|
||||||
|
/* Spawn was not successful. Clean up. */
|
||||||
if (process->wait_handle != INVALID_HANDLE_VALUE) {
|
if (process->wait_handle != INVALID_HANDLE_VALUE) {
|
||||||
UnregisterWait(process->wait_handle);
|
UnregisterWait(process->wait_handle);
|
||||||
process->wait_handle = INVALID_HANDLE_VALUE;
|
process->wait_handle = INVALID_HANDLE_VALUE;
|
||||||
|
|||||||
@ -22,7 +22,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
@ -147,8 +146,8 @@ void uv_process_reqs(uv_loop_t* loop) {
|
|||||||
uv_process_ares_cleanup_req(loop, (uv_ares_task_t*) req->data, req);
|
uv_process_ares_cleanup_req(loop, (uv_ares_task_t*) req->data, req);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UV_GETADDRINFO_REQ:
|
case UV_GETADDRINFO:
|
||||||
uv_process_getaddrinfo_req(loop, (uv_getaddrinfo_t*) req->data, req);
|
uv_process_getaddrinfo_req(loop, (uv_getaddrinfo_t*) req);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UV_PROCESS_EXIT:
|
case UV_PROCESS_EXIT:
|
||||||
|
|||||||
@ -22,19 +22,15 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
void uv_stream_init(uv_loop_t* loop, uv_stream_t* handle) {
|
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->write_queue_size = 0;
|
||||||
handle->loop = loop;
|
handle->activecnt = 0;
|
||||||
handle->flags = 0;
|
|
||||||
|
|
||||||
loop->counters.handle_init++;
|
|
||||||
loop->counters.stream_init++;
|
loop->counters.stream_init++;
|
||||||
|
|
||||||
uv_ref(loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,8 +105,11 @@ int uv_read2_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
|
|||||||
int uv_read_stop(uv_stream_t* handle) {
|
int uv_read_stop(uv_stream_t* handle) {
|
||||||
if (handle->type == UV_TTY) {
|
if (handle->type == UV_TTY) {
|
||||||
return uv_tty_read_stop((uv_tty_t*) handle);
|
return uv_tty_read_stop((uv_tty_t*) handle);
|
||||||
} else {
|
} else if (handle->flags & UV_HANDLE_READING) {
|
||||||
handle->flags &= ~UV_HANDLE_READING;
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
DECREASE_ACTIVE_COUNT(handle->loop, handle);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,7 +170,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
|
|||||||
handle->flags |= UV_HANDLE_SHUTTING;
|
handle->flags |= UV_HANDLE_SHUTTING;
|
||||||
handle->shutdown_req = req;
|
handle->shutdown_req = req;
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
|
|
||||||
uv_want_endgame(loop, (uv_handle_t*)handle);
|
uv_want_endgame(loop, (uv_handle_t*)handle);
|
||||||
|
|
||||||
|
|||||||
113
src/win/tcp.c
113
src/win/tcp.c
@ -22,7 +22,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
@ -143,12 +142,12 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
|
|||||||
|
|
||||||
|
|
||||||
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
|
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
|
||||||
uv_stream_init(loop, (uv_stream_t*)handle);
|
uv_stream_init(loop, (uv_stream_t*) handle);
|
||||||
|
|
||||||
|
handle->type = UV_TCP;
|
||||||
handle->accept_reqs = NULL;
|
handle->accept_reqs = NULL;
|
||||||
handle->pending_accepts = NULL;
|
handle->pending_accepts = NULL;
|
||||||
handle->socket = INVALID_SOCKET;
|
handle->socket = INVALID_SOCKET;
|
||||||
handle->type = UV_TCP;
|
|
||||||
handle->reqs_pending = 0;
|
handle->reqs_pending = 0;
|
||||||
handle->func_acceptex = NULL;
|
handle->func_acceptex = NULL;
|
||||||
handle->func_connectex = NULL;
|
handle->func_connectex = NULL;
|
||||||
@ -170,6 +169,8 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
|||||||
handle->shutdown_req != NULL &&
|
handle->shutdown_req != NULL &&
|
||||||
handle->write_reqs_pending == 0) {
|
handle->write_reqs_pending == 0) {
|
||||||
|
|
||||||
|
UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||||
status = -1;
|
status = -1;
|
||||||
sys_error = WSAEINTR;
|
sys_error = WSAEINTR;
|
||||||
@ -180,6 +181,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
|||||||
status = -1;
|
status = -1;
|
||||||
sys_error = WSAGetLastError();
|
sys_error = WSAGetLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->shutdown_req->cb) {
|
if (handle->shutdown_req->cb) {
|
||||||
if (status == -1) {
|
if (status == -1) {
|
||||||
uv__set_sys_error(loop, sys_error);
|
uv__set_sys_error(loop, sys_error);
|
||||||
@ -188,8 +190,6 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handle->shutdown_req = NULL;
|
handle->shutdown_req = NULL;
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
DECREASE_PENDING_REQ_COUNT(handle);
|
DECREASE_PENDING_REQ_COUNT(handle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -198,6 +198,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
|||||||
handle->reqs_pending == 0) {
|
handle->reqs_pending == 0) {
|
||||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||||
handle->flags |= UV_HANDLE_CLOSED;
|
handle->flags |= UV_HANDLE_CLOSED;
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
|
if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
|
||||||
closesocket(handle->socket);
|
closesocket(handle->socket);
|
||||||
@ -240,8 +241,6 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loop->active_tcp_streams--;
|
loop->active_tcp_streams--;
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -500,6 +499,15 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
|||||||
|
|
||||||
assert(backlog > 0);
|
assert(backlog > 0);
|
||||||
|
|
||||||
|
if (handle->flags & UV_HANDLE_LISTENING) {
|
||||||
|
handle->connection_cb = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handle->flags & UV_HANDLE_READING) {
|
||||||
|
uv__set_artificial_error(loop, UV_EISCONN);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_BIND_ERROR) {
|
if (handle->flags & UV_HANDLE_BIND_ERROR) {
|
||||||
uv__set_sys_error(loop, handle->bind_error);
|
uv__set_sys_error(loop, handle->bind_error);
|
||||||
return -1;
|
return -1;
|
||||||
@ -524,6 +532,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
|||||||
|
|
||||||
handle->flags |= UV_HANDLE_LISTENING;
|
handle->flags |= UV_HANDLE_LISTENING;
|
||||||
handle->connection_cb = cb;
|
handle->connection_cb = cb;
|
||||||
|
INCREASE_ACTIVE_COUNT(loop, handle);
|
||||||
|
|
||||||
simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1
|
simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1
|
||||||
: uv_simultaneous_server_accepts;
|
: uv_simultaneous_server_accepts;
|
||||||
@ -642,6 +651,7 @@ int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
|
|||||||
handle->flags |= UV_HANDLE_READING;
|
handle->flags |= UV_HANDLE_READING;
|
||||||
handle->read_cb = read_cb;
|
handle->read_cb = read_cb;
|
||||||
handle->alloc_cb = alloc_cb;
|
handle->alloc_cb = alloc_cb;
|
||||||
|
INCREASE_ACTIVE_COUNT(loop, handle);
|
||||||
|
|
||||||
/* If reading was stopped and then started again, there could still be a */
|
/* If reading was stopped and then started again, there could still be a */
|
||||||
/* read request pending. */
|
/* read request pending. */
|
||||||
@ -702,12 +712,12 @@ int uv__tcp_connect(uv_connect_t* req,
|
|||||||
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
|
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
|
||||||
/* Process the req without IOCP. */
|
/* Process the req without IOCP. */
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
uv_insert_pending_req(loop, (uv_req_t*)req);
|
uv_insert_pending_req(loop, (uv_req_t*)req);
|
||||||
} else if (UV_SUCCEEDED_WITH_IOCP(success)) {
|
} else if (UV_SUCCEEDED_WITH_IOCP(success)) {
|
||||||
/* The req will be processed with IOCP. */
|
/* The req will be processed with IOCP. */
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
} else {
|
} else {
|
||||||
uv__set_sys_error(loop, WSAGetLastError());
|
uv__set_sys_error(loop, WSAGetLastError());
|
||||||
return -1;
|
return -1;
|
||||||
@ -763,11 +773,11 @@ int uv__tcp_connect6(uv_connect_t* req,
|
|||||||
|
|
||||||
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
|
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
uv_insert_pending_req(loop, (uv_req_t*)req);
|
uv_insert_pending_req(loop, (uv_req_t*)req);
|
||||||
} else if (UV_SUCCEEDED_WITH_IOCP(success)) {
|
} else if (UV_SUCCEEDED_WITH_IOCP(success)) {
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
} else {
|
} else {
|
||||||
uv__set_sys_error(loop, WSAGetLastError());
|
uv__set_sys_error(loop, WSAGetLastError());
|
||||||
return -1;
|
return -1;
|
||||||
@ -872,15 +882,15 @@ int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
|
|||||||
req->queued_bytes = 0;
|
req->queued_bytes = 0;
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
handle->write_reqs_pending++;
|
handle->write_reqs_pending++;
|
||||||
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
uv_insert_pending_req(loop, (uv_req_t*) req);
|
uv_insert_pending_req(loop, (uv_req_t*) req);
|
||||||
uv_ref(loop);
|
|
||||||
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
|
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
|
||||||
/* Request queued by the kernel. */
|
/* Request queued by the kernel. */
|
||||||
req->queued_bytes = uv_count_bufs(bufs, bufcnt);
|
req->queued_bytes = uv_count_bufs(bufs, bufcnt);
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
handle->write_reqs_pending++;
|
handle->write_reqs_pending++;
|
||||||
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
handle->write_queue_size += req->queued_bytes;
|
handle->write_queue_size += req->queued_bytes;
|
||||||
uv_ref(loop);
|
|
||||||
if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
|
if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
|
||||||
!RegisterWaitForSingleObject(&req->wait_handle,
|
!RegisterWaitForSingleObject(&req->wait_handle,
|
||||||
req->event_handle, post_write_completion, (void*) req,
|
req->event_handle, post_write_completion, (void*) req,
|
||||||
@ -912,6 +922,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|||||||
if ((handle->flags & UV_HANDLE_READING) ||
|
if ((handle->flags & UV_HANDLE_READING) ||
|
||||||
!(handle->flags & UV_HANDLE_ZERO_READ)) {
|
!(handle->flags & UV_HANDLE_ZERO_READ)) {
|
||||||
handle->flags &= ~UV_HANDLE_READING;
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
|
buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
|
||||||
uv_buf_init(NULL, 0) : handle->read_buffer;
|
uv_buf_init(NULL, 0) : handle->read_buffer;
|
||||||
|
|
||||||
@ -942,8 +953,12 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Connection closed */
|
/* Connection closed */
|
||||||
handle->flags &= ~UV_HANDLE_READING;
|
if (handle->flags & UV_HANDLE_READING) {
|
||||||
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
|
}
|
||||||
handle->flags |= UV_HANDLE_EOF;
|
handle->flags |= UV_HANDLE_EOF;
|
||||||
|
|
||||||
uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
|
uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
|
||||||
buf.base = 0;
|
buf.base = 0;
|
||||||
buf.len = 0;
|
buf.len = 0;
|
||||||
@ -974,7 +989,9 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|||||||
} else {
|
} else {
|
||||||
/* Connection closed */
|
/* Connection closed */
|
||||||
handle->flags &= ~UV_HANDLE_READING;
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
handle->flags |= UV_HANDLE_EOF;
|
handle->flags |= UV_HANDLE_EOF;
|
||||||
|
|
||||||
uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
|
uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
|
||||||
handle->read_cb((uv_stream_t*)handle, -1, buf);
|
handle->read_cb((uv_stream_t*)handle, -1, buf);
|
||||||
break;
|
break;
|
||||||
@ -986,16 +1003,18 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|||||||
uv__set_sys_error(loop, WSAEWOULDBLOCK);
|
uv__set_sys_error(loop, WSAEWOULDBLOCK);
|
||||||
handle->read_cb((uv_stream_t*)handle, 0, buf);
|
handle->read_cb((uv_stream_t*)handle, 0, buf);
|
||||||
} else {
|
} else {
|
||||||
|
/* Ouch! serious error. */
|
||||||
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
|
|
||||||
if (err == WSAECONNABORTED) {
|
if (err == WSAECONNABORTED) {
|
||||||
/*
|
/* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with */
|
||||||
* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix.
|
/* Unix. */
|
||||||
*/
|
|
||||||
uv__set_error(loop, UV_ECONNRESET, err);
|
uv__set_error(loop, UV_ECONNRESET, err);
|
||||||
} else {
|
} else {
|
||||||
/* Ouch! serious error. */
|
|
||||||
uv__set_sys_error(loop, err);
|
uv__set_sys_error(loop, err);
|
||||||
}
|
}
|
||||||
handle->flags &= ~UV_HANDLE_READING;
|
|
||||||
handle->read_cb((uv_stream_t*)handle, -1, buf);
|
handle->read_cb((uv_stream_t*)handle, -1, buf);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1021,6 +1040,8 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|||||||
assert(handle->write_queue_size >= req->queued_bytes);
|
assert(handle->write_queue_size >= req->queued_bytes);
|
||||||
handle->write_queue_size -= req->queued_bytes;
|
handle->write_queue_size -= req->queued_bytes;
|
||||||
|
|
||||||
|
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
|
|
||||||
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
|
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
|
||||||
if (req->wait_handle != INVALID_HANDLE_VALUE) {
|
if (req->wait_handle != INVALID_HANDLE_VALUE) {
|
||||||
UnregisterWait(req->wait_handle);
|
UnregisterWait(req->wait_handle);
|
||||||
@ -1042,7 +1063,6 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DECREASE_PENDING_REQ_COUNT(handle);
|
DECREASE_PENDING_REQ_COUNT(handle);
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1059,6 +1079,7 @@ void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|||||||
if (req->accept_socket == INVALID_SOCKET) {
|
if (req->accept_socket == INVALID_SOCKET) {
|
||||||
if (handle->flags & UV_HANDLE_LISTENING) {
|
if (handle->flags & UV_HANDLE_LISTENING) {
|
||||||
handle->flags &= ~UV_HANDLE_LISTENING;
|
handle->flags &= ~UV_HANDLE_LISTENING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
if (handle->connection_cb) {
|
if (handle->connection_cb) {
|
||||||
uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req));
|
uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req));
|
||||||
handle->connection_cb((uv_stream_t*)handle, -1);
|
handle->connection_cb((uv_stream_t*)handle, -1);
|
||||||
@ -1096,28 +1117,27 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|||||||
uv_connect_t* req) {
|
uv_connect_t* req) {
|
||||||
assert(handle->type == UV_TCP);
|
assert(handle->type == UV_TCP);
|
||||||
|
|
||||||
if (req->cb) {
|
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
if (REQ_SUCCESS(req)) {
|
|
||||||
if (setsockopt(handle->socket,
|
if (REQ_SUCCESS(req)) {
|
||||||
SOL_SOCKET,
|
if (setsockopt(handle->socket,
|
||||||
SO_UPDATE_CONNECT_CONTEXT,
|
SOL_SOCKET,
|
||||||
NULL,
|
SO_UPDATE_CONNECT_CONTEXT,
|
||||||
0) == 0) {
|
NULL,
|
||||||
uv_connection_init((uv_stream_t*)handle);
|
0) == 0) {
|
||||||
loop->active_tcp_streams++;
|
uv_connection_init((uv_stream_t*)handle);
|
||||||
((uv_connect_cb)req->cb)(req, 0);
|
loop->active_tcp_streams++;
|
||||||
} else {
|
((uv_connect_cb)req->cb)(req, 0);
|
||||||
uv__set_sys_error(loop, WSAGetLastError());
|
|
||||||
((uv_connect_cb)req->cb)(req, -1);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req));
|
uv__set_sys_error(loop, WSAGetLastError());
|
||||||
((uv_connect_cb)req->cb)(req, -1);
|
((uv_connect_cb)req->cb)(req, -1);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req));
|
||||||
|
((uv_connect_cb)req->cb)(req, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
DECREASE_PENDING_REQ_COUNT(handle);
|
DECREASE_PENDING_REQ_COUNT(handle);
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1149,7 +1169,7 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
|
|||||||
if (uv_tcp_set_socket(tcp->loop, tcp, socket, 1) != 0) {
|
if (uv_tcp_set_socket(tcp->loop, tcp, socket, 1) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tcp->loop->active_tcp_streams++;
|
tcp->loop->active_tcp_streams++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1189,11 +1209,10 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
|
int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
|
||||||
LPWSAPROTOCOL_INFOW protocol_info) {
|
LPWSAPROTOCOL_INFOW protocol_info) {
|
||||||
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
|
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
|
||||||
/*
|
/*
|
||||||
* We're about to share the socket with another process. Because
|
* We're about to share the socket with another process. Because
|
||||||
* this is a listening socket, we assume that the other process will
|
* this is a listening socket, we assume that the other process will
|
||||||
* be accepting connections on it. So, before sharing the socket
|
* be accepting connections on it. So, before sharing the socket
|
||||||
@ -1257,7 +1276,7 @@ int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv_tcp_close(uv_tcp_t* tcp) {
|
void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
|
||||||
int non_ifs_lsp;
|
int non_ifs_lsp;
|
||||||
int close_socket = 1;
|
int close_socket = 1;
|
||||||
|
|
||||||
@ -1276,7 +1295,7 @@ void uv_tcp_close(uv_tcp_t* tcp) {
|
|||||||
uv_tcp_non_ifs_lsp_ipv4;
|
uv_tcp_non_ifs_lsp_ipv4;
|
||||||
|
|
||||||
if (!non_ifs_lsp) {
|
if (!non_ifs_lsp) {
|
||||||
/*
|
/*
|
||||||
* Shared socket with no non-IFS LSPs, request to cancel pending I/O.
|
* Shared socket with no non-IFS LSPs, request to cancel pending I/O.
|
||||||
* The socket will be closed inside endgame.
|
* The socket will be closed inside endgame.
|
||||||
*/
|
*/
|
||||||
@ -1286,13 +1305,23 @@ void uv_tcp_close(uv_tcp_t* tcp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tcp->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING);
|
if (tcp->flags & UV_HANDLE_READING) {
|
||||||
|
tcp->flags &= ~UV_HANDLE_READING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, tcp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tcp->flags & UV_HANDLE_LISTENING) {
|
||||||
|
tcp->flags &= ~UV_HANDLE_LISTENING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, tcp);
|
||||||
|
}
|
||||||
|
|
||||||
if (close_socket) {
|
if (close_socket) {
|
||||||
closesocket(tcp->socket);
|
closesocket(tcp->socket);
|
||||||
tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uv__handle_start(tcp);
|
||||||
|
|
||||||
if (tcp->reqs_pending == 0) {
|
if (tcp->reqs_pending == 0) {
|
||||||
uv_want_endgame(tcp->loop, (uv_handle_t*)tcp);
|
uv_want_endgame(tcp->loop, (uv_handle_t*)tcp);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,11 +19,12 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uv.h"
|
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "uv.h"
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
#define HAVE_SRWLOCK_API() (pTryAcquireSRWLockShared != NULL)
|
#define HAVE_SRWLOCK_API() (pTryAcquireSRWLockShared != NULL)
|
||||||
|
|
||||||
#ifdef _MSC_VER /* msvc */
|
#ifdef _MSC_VER /* msvc */
|
||||||
|
|||||||
@ -61,13 +61,13 @@ int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_ref(loop);
|
uv__req_register(loop, req);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv_process_work_req(uv_loop_t* loop, uv_work_t* req) {
|
void uv_process_work_req(uv_loop_t* loop, uv_work_t* req) {
|
||||||
assert(req->after_work_cb);
|
assert(req->after_work_cb);
|
||||||
|
uv__req_unregister(loop, req);
|
||||||
req->after_work_cb(req);
|
req->after_work_cb(req);
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
|
||||||
|
|
||||||
#undef NANOSEC
|
#undef NANOSEC
|
||||||
#define NANOSEC 1000000000
|
#define NANOSEC 1000000000
|
||||||
|
|
||||||
@ -111,16 +112,12 @@ RB_GENERATE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare);
|
|||||||
|
|
||||||
|
|
||||||
int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
|
int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
|
||||||
loop->counters.handle_init++;
|
uv_handle_init(loop, (uv_handle_t*) handle);
|
||||||
loop->counters.timer_init++;
|
|
||||||
|
|
||||||
handle->type = UV_TIMER;
|
handle->type = UV_TIMER;
|
||||||
handle->loop = loop;
|
|
||||||
handle->flags = 0;
|
|
||||||
handle->timer_cb = NULL;
|
handle->timer_cb = NULL;
|
||||||
handle->repeat = 0;
|
handle->repeat = 0;
|
||||||
|
|
||||||
uv_ref(loop);
|
loop->counters.timer_init++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -130,12 +127,11 @@ void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle) {
|
|||||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||||
handle->flags |= UV_HANDLE_CLOSED;
|
handle->flags |= UV_HANDLE_CLOSED;
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
if (handle->close_cb) {
|
if (handle->close_cb) {
|
||||||
handle->close_cb((uv_handle_t*)handle);
|
handle->close_cb((uv_handle_t*)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +148,7 @@ int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, int64_t timeout,
|
|||||||
handle->due = loop->time + timeout;
|
handle->due = loop->time + timeout;
|
||||||
handle->repeat = repeat;
|
handle->repeat = repeat;
|
||||||
handle->flags |= UV_HANDLE_ACTIVE;
|
handle->flags |= UV_HANDLE_ACTIVE;
|
||||||
|
uv__handle_start(handle);
|
||||||
|
|
||||||
if (RB_INSERT(uv_timer_tree_s, &loop->timers, handle) != NULL) {
|
if (RB_INSERT(uv_timer_tree_s, &loop->timers, handle) != NULL) {
|
||||||
uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
|
uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
|
||||||
@ -170,6 +167,7 @@ int uv_timer_stop(uv_timer_t* handle) {
|
|||||||
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
|
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
|
||||||
|
|
||||||
handle->flags &= ~UV_HANDLE_ACTIVE;
|
handle->flags &= ~UV_HANDLE_ACTIVE;
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -187,6 +185,7 @@ int uv_timer_again(uv_timer_t* handle) {
|
|||||||
if (handle->flags & UV_HANDLE_ACTIVE) {
|
if (handle->flags & UV_HANDLE_ACTIVE) {
|
||||||
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
|
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
|
||||||
handle->flags &= ~UV_HANDLE_ACTIVE;
|
handle->flags &= ~UV_HANDLE_ACTIVE;
|
||||||
|
uv__handle_stop(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle->repeat) {
|
if (handle->repeat) {
|
||||||
@ -197,6 +196,7 @@ int uv_timer_again(uv_timer_t* handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handle->flags |= UV_HANDLE_ACTIVE;
|
handle->flags |= UV_HANDLE_ACTIVE;
|
||||||
|
uv__handle_start(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -268,6 +268,7 @@ void uv_process_timers(uv_loop_t* loop) {
|
|||||||
} else {
|
} else {
|
||||||
/* If non-repeating, mark the timer as inactive. */
|
/* If non-repeating, mark the timer as inactive. */
|
||||||
timer->flags &= ~UV_HANDLE_ACTIVE;
|
timer->flags &= ~UV_HANDLE_ACTIVE;
|
||||||
|
uv__handle_stop(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
timer->timer_cb((uv_timer_t*) timer, 0);
|
timer->timer_cb((uv_timer_t*) timer, 0);
|
||||||
|
|||||||
@ -25,7 +25,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
@ -462,8 +461,9 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
|
|||||||
|
|
||||||
/* Fetch the number of events */
|
/* Fetch the number of events */
|
||||||
if (!GetNumberOfConsoleInputEvents(handle->handle, &records_left)) {
|
if (!GetNumberOfConsoleInputEvents(handle->handle, &records_left)) {
|
||||||
handle->flags &= ~UV_HANDLE_READING;
|
|
||||||
uv__set_sys_error(loop, GetLastError());
|
uv__set_sys_error(loop, GetLastError());
|
||||||
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
handle->read_cb((uv_stream_t*)handle, -1, uv_null_buf_);
|
handle->read_cb((uv_stream_t*)handle, -1, uv_null_buf_);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -483,6 +483,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
|
|||||||
&records_read)) {
|
&records_read)) {
|
||||||
uv__set_sys_error(loop, GetLastError());
|
uv__set_sys_error(loop, GetLastError());
|
||||||
handle->flags &= ~UV_HANDLE_READING;
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
handle->read_cb((uv_stream_t*) handle, -1, buf);
|
handle->read_cb((uv_stream_t*) handle, -1, buf);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -583,6 +584,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
|
|||||||
if (!char_len) {
|
if (!char_len) {
|
||||||
uv__set_sys_error(loop, GetLastError());
|
uv__set_sys_error(loop, GetLastError());
|
||||||
handle->flags &= ~UV_HANDLE_READING;
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
handle->read_cb((uv_stream_t*) handle, -1, buf);
|
handle->read_cb((uv_stream_t*) handle, -1, buf);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -691,6 +693,7 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
|
|||||||
!(handle->flags & UV_HANDLE_TTY_RAW)) {
|
!(handle->flags & UV_HANDLE_TTY_RAW)) {
|
||||||
/* Real error */
|
/* Real error */
|
||||||
handle->flags &= ~UV_HANDLE_READING;
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
uv__set_sys_error(loop, GET_REQ_ERROR(req));
|
uv__set_sys_error(loop, GET_REQ_ERROR(req));
|
||||||
handle->read_cb((uv_stream_t*) handle, -1, buf);
|
handle->read_cb((uv_stream_t*) handle, -1, buf);
|
||||||
} else {
|
} else {
|
||||||
@ -738,6 +741,7 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
|
|||||||
uv_loop_t* loop = handle->loop;
|
uv_loop_t* loop = handle->loop;
|
||||||
|
|
||||||
handle->flags |= UV_HANDLE_READING;
|
handle->flags |= UV_HANDLE_READING;
|
||||||
|
INCREASE_ACTIVE_COUNT(loop, handle);
|
||||||
handle->read_cb = read_cb;
|
handle->read_cb = read_cb;
|
||||||
handle->alloc_cb = alloc_cb;
|
handle->alloc_cb = alloc_cb;
|
||||||
|
|
||||||
@ -762,7 +766,12 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
|
|||||||
|
|
||||||
|
|
||||||
int uv_tty_read_stop(uv_tty_t* handle) {
|
int uv_tty_read_stop(uv_tty_t* handle) {
|
||||||
handle->flags &= ~UV_HANDLE_READING;
|
uv_loop_t* loop = handle->loop;
|
||||||
|
|
||||||
|
if (handle->flags & UV_HANDLE_READING) {
|
||||||
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
|
}
|
||||||
|
|
||||||
/* Cancel raw read */
|
/* Cancel raw read */
|
||||||
if ((handle->flags & UV_HANDLE_READ_PENDING) &&
|
if ((handle->flags & UV_HANDLE_READ_PENDING) &&
|
||||||
@ -772,7 +781,7 @@ int uv_tty_read_stop(uv_tty_t* handle) {
|
|||||||
DWORD written;
|
DWORD written;
|
||||||
memset(&record, 0, sizeof record);
|
memset(&record, 0, sizeof record);
|
||||||
if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) {
|
if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) {
|
||||||
uv__set_sys_error(handle->loop, GetLastError());
|
uv__set_sys_error(loop, GetLastError());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1680,7 +1689,7 @@ int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle,
|
|||||||
|
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
handle->write_reqs_pending++;
|
handle->write_reqs_pending++;
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
|
|
||||||
req->queued_bytes = 0;
|
req->queued_bytes = 0;
|
||||||
|
|
||||||
@ -1700,6 +1709,7 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
|
|||||||
uv_write_t* req) {
|
uv_write_t* req) {
|
||||||
|
|
||||||
handle->write_queue_size -= req->queued_bytes;
|
handle->write_queue_size -= req->queued_bytes;
|
||||||
|
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
|
|
||||||
if (req->cb) {
|
if (req->cb) {
|
||||||
uv__set_sys_error(loop, GET_REQ_ERROR(req));
|
uv__set_sys_error(loop, GET_REQ_ERROR(req));
|
||||||
@ -1713,7 +1723,6 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DECREASE_PENDING_REQ_COUNT(handle);
|
DECREASE_PENDING_REQ_COUNT(handle);
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1723,6 +1732,8 @@ void uv_tty_close(uv_tty_t* handle) {
|
|||||||
uv_tty_read_stop(handle);
|
uv_tty_read_stop(handle);
|
||||||
CloseHandle(handle->handle);
|
CloseHandle(handle->handle);
|
||||||
|
|
||||||
|
uv__handle_start(handle);
|
||||||
|
|
||||||
if (handle->reqs_pending == 0) {
|
if (handle->reqs_pending == 0) {
|
||||||
uv_want_endgame(handle->loop, (uv_handle_t*) handle);
|
uv_want_endgame(handle->loop, (uv_handle_t*) handle);
|
||||||
}
|
}
|
||||||
@ -1733,6 +1744,8 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
|
|||||||
if ((handle->flags && UV_HANDLE_CONNECTION) &&
|
if ((handle->flags && UV_HANDLE_CONNECTION) &&
|
||||||
handle->shutdown_req != NULL &&
|
handle->shutdown_req != NULL &&
|
||||||
handle->write_reqs_pending == 0) {
|
handle->write_reqs_pending == 0) {
|
||||||
|
UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);
|
||||||
|
|
||||||
/* TTY shutdown is really just a no-op */
|
/* TTY shutdown is really just a no-op */
|
||||||
if (handle->shutdown_req->cb) {
|
if (handle->shutdown_req->cb) {
|
||||||
if (handle->flags & UV_HANDLE_CLOSING) {
|
if (handle->flags & UV_HANDLE_CLOSING) {
|
||||||
@ -1745,7 +1758,6 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
|
|||||||
|
|
||||||
handle->shutdown_req = NULL;
|
handle->shutdown_req = NULL;
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
DECREASE_PENDING_REQ_COUNT(handle);
|
DECREASE_PENDING_REQ_COUNT(handle);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1762,12 +1774,11 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
|
|||||||
|
|
||||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||||
handle->flags |= UV_HANDLE_CLOSED;
|
handle->flags |= UV_HANDLE_CLOSED;
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
if (handle->close_cb) {
|
if (handle->close_cb) {
|
||||||
handle->close_cb((uv_handle_t*)handle);
|
handle->close_cb((uv_handle_t*)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
@ -121,11 +120,12 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle,
|
|||||||
|
|
||||||
|
|
||||||
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
|
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
|
||||||
|
uv_handle_init(loop, (uv_handle_t*) handle);
|
||||||
|
|
||||||
handle->type = UV_UDP;
|
handle->type = UV_UDP;
|
||||||
handle->socket = INVALID_SOCKET;
|
handle->socket = INVALID_SOCKET;
|
||||||
handle->reqs_pending = 0;
|
handle->reqs_pending = 0;
|
||||||
handle->loop = loop;
|
handle->activecnt = 0;
|
||||||
handle->flags = 0;
|
|
||||||
handle->func_wsarecv = WSARecv;
|
handle->func_wsarecv = WSARecv;
|
||||||
handle->func_wsarecvfrom = WSARecvFrom;
|
handle->func_wsarecvfrom = WSARecvFrom;
|
||||||
|
|
||||||
@ -133,26 +133,34 @@ int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
|
|||||||
handle->recv_req.type = UV_UDP_RECV;
|
handle->recv_req.type = UV_UDP_RECV;
|
||||||
handle->recv_req.data = handle;
|
handle->recv_req.data = handle;
|
||||||
|
|
||||||
uv_ref(loop);
|
|
||||||
|
|
||||||
loop->counters.handle_init++;
|
|
||||||
loop->counters.udp_init++;
|
loop->counters.udp_init++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
|
||||||
|
uv_udp_recv_stop(handle);
|
||||||
|
closesocket(handle->socket);
|
||||||
|
|
||||||
|
uv__handle_start(handle);
|
||||||
|
|
||||||
|
if (handle->reqs_pending == 0) {
|
||||||
|
uv_want_endgame(loop, (uv_handle_t*) handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
|
void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
|
||||||
if (handle->flags & UV_HANDLE_CLOSING &&
|
if (handle->flags & UV_HANDLE_CLOSING &&
|
||||||
handle->reqs_pending == 0) {
|
handle->reqs_pending == 0) {
|
||||||
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
||||||
handle->flags |= UV_HANDLE_CLOSED;
|
handle->flags |= UV_HANDLE_CLOSED;
|
||||||
|
uv__handle_stop(handle);
|
||||||
|
|
||||||
if (handle->close_cb) {
|
if (handle->close_cb) {
|
||||||
handle->close_cb((uv_handle_t*)handle);
|
handle->close_cb((uv_handle_t*)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,6 +358,7 @@ int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
|
|||||||
}
|
}
|
||||||
|
|
||||||
handle->flags |= UV_HANDLE_READING;
|
handle->flags |= UV_HANDLE_READING;
|
||||||
|
INCREASE_ACTIVE_COUNT(loop, handle);
|
||||||
loop->active_udp_streams++;
|
loop->active_udp_streams++;
|
||||||
|
|
||||||
handle->recv_cb = recv_cb;
|
handle->recv_cb = recv_cb;
|
||||||
@ -368,6 +377,7 @@ int uv_udp_recv_stop(uv_udp_t* handle) {
|
|||||||
if (handle->flags & UV_HANDLE_READING) {
|
if (handle->flags & UV_HANDLE_READING) {
|
||||||
handle->flags &= ~UV_HANDLE_READING;
|
handle->flags &= ~UV_HANDLE_READING;
|
||||||
handle->loop->active_udp_streams--;
|
handle->loop->active_udp_streams--;
|
||||||
|
DECREASE_ACTIVE_COUNT(loop, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -399,13 +409,13 @@ static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
|
|||||||
/* Request completed immediately. */
|
/* Request completed immediately. */
|
||||||
req->queued_bytes = 0;
|
req->queued_bytes = 0;
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
uv_insert_pending_req(loop, (uv_req_t*)req);
|
uv_insert_pending_req(loop, (uv_req_t*)req);
|
||||||
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
|
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
|
||||||
/* Request queued by the kernel. */
|
/* Request queued by the kernel. */
|
||||||
req->queued_bytes = uv_count_bufs(bufs, bufcnt);
|
req->queued_bytes = uv_count_bufs(bufs, bufcnt);
|
||||||
handle->reqs_pending++;
|
handle->reqs_pending++;
|
||||||
uv_ref(loop);
|
REGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
} else {
|
} else {
|
||||||
/* Send failed due to an error. */
|
/* Send failed due to an error. */
|
||||||
uv__set_sys_error(loop, WSAGetLastError());
|
uv__set_sys_error(loop, WSAGetLastError());
|
||||||
@ -561,6 +571,8 @@ void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
|
|||||||
uv_udp_send_t* req) {
|
uv_udp_send_t* req) {
|
||||||
assert(handle->type == UV_UDP);
|
assert(handle->type == UV_UDP);
|
||||||
|
|
||||||
|
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
||||||
|
|
||||||
if (req->cb) {
|
if (req->cb) {
|
||||||
if (REQ_SUCCESS(req)) {
|
if (REQ_SUCCESS(req)) {
|
||||||
req->cb(req, 0);
|
req->cb(req, 0);
|
||||||
@ -570,7 +582,6 @@ void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_unref(loop);
|
|
||||||
DECREASE_PENDING_REQ_COUNT(handle);
|
DECREASE_PENDING_REQ_COUNT(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,9 +29,10 @@
|
|||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "tlhelp32.h"
|
|
||||||
#include "psapi.h"
|
#include <iphlpapi.h>
|
||||||
#include "iphlpapi.h"
|
#include <psapi.h>
|
||||||
|
#include <tlhelp32.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -22,7 +22,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -22,9 +22,9 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
#include "../uv-common.h"
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
/* Whether ipv6 is supported */
|
/* Whether ipv6 is supported */
|
||||||
int uv_allow_ipv6;
|
int uv_allow_ipv6;
|
||||||
|
|
||||||
|
|||||||
@ -144,7 +144,7 @@ static int do_packet_storm(int n_senders, int n_receivers) {
|
|||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
|
|
||||||
/* Timer should not keep loop alive. */
|
/* Timer should not keep loop alive. */
|
||||||
uv_unref(loop);
|
uv_unref((uv_handle_t*)&timeout);
|
||||||
|
|
||||||
for (i = 0; i < n_receivers; i++) {
|
for (i = 0; i < n_receivers; i++) {
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|||||||
@ -68,7 +68,6 @@ void idle_cb(uv_idle_t* idle, int status) {
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = uv_idle_stop(idle);
|
r = uv_idle_stop(idle);
|
||||||
uv_unref(uv_default_loop());
|
|
||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,7 +89,6 @@ TEST_DECLARE (tcp_ref)
|
|||||||
TEST_DECLARE (tcp_ref2)
|
TEST_DECLARE (tcp_ref2)
|
||||||
TEST_DECLARE (tcp_ref3)
|
TEST_DECLARE (tcp_ref3)
|
||||||
TEST_DECLARE (tcp_ref4)
|
TEST_DECLARE (tcp_ref4)
|
||||||
TEST_DECLARE (tcp_ref5)
|
|
||||||
TEST_DECLARE (udp_ref)
|
TEST_DECLARE (udp_ref)
|
||||||
TEST_DECLARE (udp_ref2)
|
TEST_DECLARE (udp_ref2)
|
||||||
TEST_DECLARE (udp_ref3)
|
TEST_DECLARE (udp_ref3)
|
||||||
@ -97,7 +96,6 @@ TEST_DECLARE (pipe_ref)
|
|||||||
TEST_DECLARE (pipe_ref2)
|
TEST_DECLARE (pipe_ref2)
|
||||||
TEST_DECLARE (pipe_ref3)
|
TEST_DECLARE (pipe_ref3)
|
||||||
TEST_DECLARE (pipe_ref4)
|
TEST_DECLARE (pipe_ref4)
|
||||||
TEST_DECLARE (pipe_ref5)
|
|
||||||
TEST_DECLARE (process_ref)
|
TEST_DECLARE (process_ref)
|
||||||
TEST_DECLARE (async)
|
TEST_DECLARE (async)
|
||||||
TEST_DECLARE (get_currentexe)
|
TEST_DECLARE (get_currentexe)
|
||||||
@ -275,8 +273,6 @@ TASK_LIST_START
|
|||||||
TEST_HELPER (tcp_ref3, tcp4_echo_server)
|
TEST_HELPER (tcp_ref3, tcp4_echo_server)
|
||||||
TEST_ENTRY (tcp_ref4)
|
TEST_ENTRY (tcp_ref4)
|
||||||
TEST_HELPER (tcp_ref4, tcp4_echo_server)
|
TEST_HELPER (tcp_ref4, tcp4_echo_server)
|
||||||
TEST_ENTRY (tcp_ref5)
|
|
||||||
TEST_HELPER (tcp_ref5, tcp4_echo_server)
|
|
||||||
TEST_ENTRY (udp_ref)
|
TEST_ENTRY (udp_ref)
|
||||||
TEST_ENTRY (udp_ref2)
|
TEST_ENTRY (udp_ref2)
|
||||||
TEST_ENTRY (udp_ref3)
|
TEST_ENTRY (udp_ref3)
|
||||||
@ -287,8 +283,6 @@ TASK_LIST_START
|
|||||||
TEST_HELPER (pipe_ref3, pipe_echo_server)
|
TEST_HELPER (pipe_ref3, pipe_echo_server)
|
||||||
TEST_ENTRY (pipe_ref4)
|
TEST_ENTRY (pipe_ref4)
|
||||||
TEST_HELPER (pipe_ref4, pipe_echo_server)
|
TEST_HELPER (pipe_ref4, pipe_echo_server)
|
||||||
TEST_ENTRY (pipe_ref5)
|
|
||||||
TEST_HELPER (pipe_ref5, pipe_echo_server)
|
|
||||||
TEST_ENTRY (process_ref)
|
TEST_ENTRY (process_ref)
|
||||||
|
|
||||||
TEST_ENTRY (loop_handles)
|
TEST_ENTRY (loop_handles)
|
||||||
|
|||||||
@ -323,7 +323,7 @@ TEST_IMPL(loop_handles) {
|
|||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
r = uv_timer_start(&timer_handle, timer_cb, TIMEOUT, TIMEOUT);
|
r = uv_timer_start(&timer_handle, timer_cb, TIMEOUT, TIMEOUT);
|
||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&timer_handle);
|
||||||
|
|
||||||
r = uv_run(uv_default_loop());
|
r = uv_run(uv_default_loop());
|
||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
|
|||||||
132
test/test-ref.c
132
test/test-ref.c
@ -32,30 +32,50 @@ static uv_connect_t connect_req;
|
|||||||
|
|
||||||
static char buffer[32767];
|
static char buffer[32767];
|
||||||
|
|
||||||
|
static int req_cb_called;
|
||||||
|
static int connect_cb_called;
|
||||||
|
static int write_cb_called;
|
||||||
|
static int shutdown_cb_called;
|
||||||
|
|
||||||
|
|
||||||
static void fail_cb(void) {
|
static void fail_cb(void) {
|
||||||
FATAL("fail_cb should not have been called");
|
FATAL("fail_cb should not have been called");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void write_unref_cb(uv_connect_t* req, int status) {
|
static void req_cb(uv_handle_t* req, int status) {
|
||||||
uv_buf_t buf = uv_buf_init(buffer, sizeof buffer);
|
req_cb_called++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void shutdown_cb(uv_shutdown_t* req, int status) {
|
||||||
|
ASSERT(req == &shutdown_req);
|
||||||
|
shutdown_cb_called++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void write_cb(uv_write_t* req, int status) {
|
||||||
|
ASSERT(req == &write_req);
|
||||||
|
uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
|
||||||
|
write_cb_called++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void connect_and_write(uv_connect_t* req, int status) {
|
||||||
|
uv_buf_t buf = uv_buf_init(buffer, sizeof buffer);
|
||||||
ASSERT(req == &connect_req);
|
ASSERT(req == &connect_req);
|
||||||
ASSERT(status == 0);
|
ASSERT(status == 0);
|
||||||
|
uv_write(&write_req, req->handle, &buf, 1, write_cb);
|
||||||
uv_write(&write_req, req->handle, &buf, 1, (uv_write_cb) fail_cb);
|
connect_cb_called++;
|
||||||
uv_unref(uv_default_loop()); /* uv_write refs the loop */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void shutdown_unref_cb(uv_connect_t* req, int status) {
|
static void connect_and_shutdown(uv_connect_t* req, int status) {
|
||||||
ASSERT(req == &connect_req);
|
ASSERT(req == &connect_req);
|
||||||
ASSERT(status == 0);
|
ASSERT(status == 0);
|
||||||
|
uv_shutdown(&shutdown_req, req->handle, shutdown_cb);
|
||||||
uv_shutdown(&shutdown_req, req->handle, (uv_shutdown_cb) fail_cb);
|
connect_cb_called++;
|
||||||
uv_unref(uv_default_loop()); /* uv_shutdown refs the loop */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -69,7 +89,7 @@ TEST_IMPL(idle_ref) {
|
|||||||
uv_idle_t h;
|
uv_idle_t h;
|
||||||
uv_idle_init(uv_default_loop(), &h);
|
uv_idle_init(uv_default_loop(), &h);
|
||||||
uv_idle_start(&h, NULL);
|
uv_idle_start(&h, NULL);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -78,7 +98,7 @@ TEST_IMPL(idle_ref) {
|
|||||||
TEST_IMPL(async_ref) {
|
TEST_IMPL(async_ref) {
|
||||||
uv_async_t h;
|
uv_async_t h;
|
||||||
uv_async_init(uv_default_loop(), &h, NULL);
|
uv_async_init(uv_default_loop(), &h, NULL);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -88,7 +108,7 @@ TEST_IMPL(prepare_ref) {
|
|||||||
uv_prepare_t h;
|
uv_prepare_t h;
|
||||||
uv_prepare_init(uv_default_loop(), &h);
|
uv_prepare_init(uv_default_loop(), &h);
|
||||||
uv_prepare_start(&h, NULL);
|
uv_prepare_start(&h, NULL);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -98,17 +118,16 @@ TEST_IMPL(check_ref) {
|
|||||||
uv_check_t h;
|
uv_check_t h;
|
||||||
uv_check_init(uv_default_loop(), &h);
|
uv_check_init(uv_default_loop(), &h);
|
||||||
uv_check_start(&h, NULL);
|
uv_check_start(&h, NULL);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void prepare_cb(uv_prepare_t* handle, int status) {
|
static void prepare_cb(uv_prepare_t* h, int status) {
|
||||||
ASSERT(handle != NULL);
|
ASSERT(h != NULL);
|
||||||
ASSERT(status == 0);
|
ASSERT(status == 0);
|
||||||
|
uv_unref((uv_handle_t*)h);
|
||||||
uv_unref(uv_default_loop());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -124,7 +143,7 @@ TEST_IMPL(unref_in_prepare_cb) {
|
|||||||
TEST_IMPL(timer_ref) {
|
TEST_IMPL(timer_ref) {
|
||||||
uv_timer_t h;
|
uv_timer_t h;
|
||||||
uv_timer_init(uv_default_loop(), &h);
|
uv_timer_init(uv_default_loop(), &h);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -133,8 +152,8 @@ TEST_IMPL(timer_ref) {
|
|||||||
TEST_IMPL(timer_ref2) {
|
TEST_IMPL(timer_ref2) {
|
||||||
uv_timer_t h;
|
uv_timer_t h;
|
||||||
uv_timer_init(uv_default_loop(), &h);
|
uv_timer_init(uv_default_loop(), &h);
|
||||||
uv_timer_start(&h, (uv_timer_cb) fail_cb, 42, 42);
|
uv_timer_start(&h, (uv_timer_cb)fail_cb, 42, 42);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -142,8 +161,8 @@ TEST_IMPL(timer_ref2) {
|
|||||||
|
|
||||||
TEST_IMPL(fs_event_ref) {
|
TEST_IMPL(fs_event_ref) {
|
||||||
uv_fs_event_t h;
|
uv_fs_event_t h;
|
||||||
uv_fs_event_init(uv_default_loop(), &h, ".", (uv_fs_event_cb) fail_cb, 0);
|
uv_fs_event_init(uv_default_loop(), &h, ".", (uv_fs_event_cb)fail_cb, 0);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -152,7 +171,7 @@ TEST_IMPL(fs_event_ref) {
|
|||||||
TEST_IMPL(tcp_ref) {
|
TEST_IMPL(tcp_ref) {
|
||||||
uv_tcp_t h;
|
uv_tcp_t h;
|
||||||
uv_tcp_init(uv_default_loop(), &h);
|
uv_tcp_init(uv_default_loop(), &h);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -162,7 +181,7 @@ TEST_IMPL(tcp_ref2) {
|
|||||||
uv_tcp_t h;
|
uv_tcp_t h;
|
||||||
uv_tcp_init(uv_default_loop(), &h);
|
uv_tcp_init(uv_default_loop(), &h);
|
||||||
uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
|
uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -172,10 +191,11 @@ TEST_IMPL(tcp_ref3) {
|
|||||||
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 h;
|
uv_tcp_t h;
|
||||||
uv_tcp_init(uv_default_loop(), &h);
|
uv_tcp_init(uv_default_loop(), &h);
|
||||||
uv_tcp_connect(&connect_req, &h, addr, (uv_connect_cb)fail_cb);
|
uv_tcp_connect(&connect_req, &h, addr, connect_and_shutdown);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_unref(uv_default_loop()); /* connect req refs the loop */
|
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
|
ASSERT(connect_cb_called == 1);
|
||||||
|
ASSERT(shutdown_cb_called == 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,20 +204,12 @@ TEST_IMPL(tcp_ref4) {
|
|||||||
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 h;
|
uv_tcp_t h;
|
||||||
uv_tcp_init(uv_default_loop(), &h);
|
uv_tcp_init(uv_default_loop(), &h);
|
||||||
uv_tcp_connect(&connect_req, &h, addr, write_unref_cb);
|
uv_tcp_connect(&connect_req, &h, addr, connect_and_write);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST_IMPL(tcp_ref5) {
|
|
||||||
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
|
|
||||||
uv_tcp_t h;
|
|
||||||
uv_tcp_init(uv_default_loop(), &h);
|
|
||||||
uv_tcp_connect(&connect_req, &h, addr, shutdown_unref_cb);
|
|
||||||
uv_unref(uv_default_loop());
|
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
|
ASSERT(connect_cb_called == 1);
|
||||||
|
ASSERT(write_cb_called == 1);
|
||||||
|
ASSERT(shutdown_cb_called == 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +217,7 @@ TEST_IMPL(tcp_ref5) {
|
|||||||
TEST_IMPL(udp_ref) {
|
TEST_IMPL(udp_ref) {
|
||||||
uv_udp_t h;
|
uv_udp_t h;
|
||||||
uv_udp_init(uv_default_loop(), &h);
|
uv_udp_init(uv_default_loop(), &h);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -217,7 +229,7 @@ TEST_IMPL(udp_ref2) {
|
|||||||
uv_udp_init(uv_default_loop(), &h);
|
uv_udp_init(uv_default_loop(), &h);
|
||||||
uv_udp_bind(&h, addr, 0);
|
uv_udp_bind(&h, addr, 0);
|
||||||
uv_udp_recv_start(&h, (uv_alloc_cb)fail_cb, (uv_udp_recv_cb)fail_cb);
|
uv_udp_recv_start(&h, (uv_alloc_cb)fail_cb, (uv_udp_recv_cb)fail_cb);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -230,10 +242,10 @@ TEST_IMPL(udp_ref3) {
|
|||||||
uv_udp_t h;
|
uv_udp_t h;
|
||||||
|
|
||||||
uv_udp_init(uv_default_loop(), &h);
|
uv_udp_init(uv_default_loop(), &h);
|
||||||
uv_udp_send(&req, &h, &buf, 1, addr, (uv_udp_send_cb)fail_cb);
|
uv_udp_send(&req, &h, &buf, 1, addr, (uv_udp_send_cb)req_cb);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_unref(uv_default_loop()); /* send req refs the loop */
|
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
|
ASSERT(req_cb_called == 1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -242,7 +254,7 @@ TEST_IMPL(udp_ref3) {
|
|||||||
TEST_IMPL(pipe_ref) {
|
TEST_IMPL(pipe_ref) {
|
||||||
uv_pipe_t h;
|
uv_pipe_t h;
|
||||||
uv_pipe_init(uv_default_loop(), &h, 0);
|
uv_pipe_init(uv_default_loop(), &h, 0);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -252,7 +264,7 @@ TEST_IMPL(pipe_ref2) {
|
|||||||
uv_pipe_t h;
|
uv_pipe_t h;
|
||||||
uv_pipe_init(uv_default_loop(), &h, 0);
|
uv_pipe_init(uv_default_loop(), &h, 0);
|
||||||
uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
|
uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -261,10 +273,11 @@ TEST_IMPL(pipe_ref2) {
|
|||||||
TEST_IMPL(pipe_ref3) {
|
TEST_IMPL(pipe_ref3) {
|
||||||
uv_pipe_t h;
|
uv_pipe_t h;
|
||||||
uv_pipe_init(uv_default_loop(), &h, 0);
|
uv_pipe_init(uv_default_loop(), &h, 0);
|
||||||
uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, (uv_connect_cb)fail_cb);
|
uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_shutdown);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_unref(uv_default_loop()); /* connect req refs the loop */
|
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
|
ASSERT(connect_cb_called == 1);
|
||||||
|
ASSERT(shutdown_cb_called == 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,19 +285,12 @@ TEST_IMPL(pipe_ref3) {
|
|||||||
TEST_IMPL(pipe_ref4) {
|
TEST_IMPL(pipe_ref4) {
|
||||||
uv_pipe_t h;
|
uv_pipe_t h;
|
||||||
uv_pipe_init(uv_default_loop(), &h, 0);
|
uv_pipe_init(uv_default_loop(), &h, 0);
|
||||||
uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, write_unref_cb);
|
uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_write);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST_IMPL(pipe_ref5) {
|
|
||||||
uv_pipe_t h;
|
|
||||||
uv_pipe_init(uv_default_loop(), &h, 0);
|
|
||||||
uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, shutdown_unref_cb);
|
|
||||||
uv_unref(uv_default_loop());
|
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
|
ASSERT(connect_cb_called == 1);
|
||||||
|
ASSERT(write_cb_called == 1);
|
||||||
|
ASSERT(shutdown_cb_called == 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +318,7 @@ TEST_IMPL(process_ref) {
|
|||||||
r = uv_spawn(uv_default_loop(), &h, options);
|
r = uv_spawn(uv_default_loop(), &h, options);
|
||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
|
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&h);
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
|
|
||||||
r = uv_process_kill(&h, /* SIGTERM */ 15);
|
r = uv_process_kill(&h, /* SIGTERM */ 15);
|
||||||
|
|||||||
@ -203,8 +203,8 @@ int stdio_over_pipes_helper() {
|
|||||||
uv_pipe_open(&stdout_pipe, 1);
|
uv_pipe_open(&stdout_pipe, 1);
|
||||||
|
|
||||||
/* Unref both stdio handles to make sure that all writes complete. */
|
/* Unref both stdio handles to make sure that all writes complete. */
|
||||||
uv_unref(loop);
|
uv_unref((uv_handle_t*)&stdin_pipe);
|
||||||
uv_unref(loop);
|
uv_unref((uv_handle_t*)&stdout_pipe);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(buffers); i++) {
|
for (i = 0; i < ARRAY_SIZE(buffers); i++) {
|
||||||
buf[i] = uv_buf_init((char*)buffers[i], strlen(buffers[i]));
|
buf[i] = uv_buf_init((char*)buffers[i], strlen(buffers[i]));
|
||||||
@ -222,8 +222,8 @@ int stdio_over_pipes_helper() {
|
|||||||
ASSERT(on_pipe_read_called == 0);
|
ASSERT(on_pipe_read_called == 0);
|
||||||
ASSERT(close_cb_called == 0);
|
ASSERT(close_cb_called == 0);
|
||||||
|
|
||||||
uv_ref(loop);
|
uv_ref((uv_handle_t*)&stdout_pipe);
|
||||||
uv_ref(loop);
|
uv_ref((uv_handle_t*)&stdin_pipe);
|
||||||
|
|
||||||
r = uv_read_start((uv_stream_t*)&stdin_pipe, on_read_alloc,
|
r = uv_read_start((uv_stream_t*)&stdin_pipe, on_read_alloc,
|
||||||
on_pipe_read);
|
on_pipe_read);
|
||||||
|
|||||||
@ -88,7 +88,7 @@ static void start_server(uv_loop_t* loop, uv_tcp_t* handle) {
|
|||||||
r = uv_listen((uv_stream_t*)handle, 128, connection_cb);
|
r = uv_listen((uv_stream_t*)handle, 128, connection_cb);
|
||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
|
|
||||||
uv_unref(loop);
|
uv_unref((uv_handle_t*)handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -104,7 +104,7 @@ TEST_IMPL(timer_again) {
|
|||||||
r = uv_timer_again(&dummy);
|
r = uv_timer_again(&dummy);
|
||||||
ASSERT(r == -1);
|
ASSERT(r == -1);
|
||||||
ASSERT(uv_last_error(uv_default_loop()).code == UV_EINVAL);
|
ASSERT(uv_last_error(uv_default_loop()).code == UV_EINVAL);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&dummy);
|
||||||
|
|
||||||
/* Start timer repeat_1. */
|
/* Start timer repeat_1. */
|
||||||
r = uv_timer_init(uv_default_loop(), &repeat_1);
|
r = uv_timer_init(uv_default_loop(), &repeat_1);
|
||||||
|
|||||||
@ -114,7 +114,7 @@ TEST_IMPL(timer) {
|
|||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
r = uv_timer_stop(&never);
|
r = uv_timer_stop(&never);
|
||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
uv_unref(uv_default_loop());
|
uv_unref((uv_handle_t*)&never);
|
||||||
|
|
||||||
uv_run(uv_default_loop());
|
uv_run(uv_default_loop());
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,7 @@ TEST_IMPL(udp_options) {
|
|||||||
r = uv_udp_init(loop, &h);
|
r = uv_udp_init(loop, &h);
|
||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
|
|
||||||
uv_unref(loop); /* don't keep the loop alive */
|
uv_unref((uv_handle_t*)&h); /* don't keep the loop alive */
|
||||||
|
|
||||||
r = uv_udp_bind(&h, uv_ip4_addr("0.0.0.0", TEST_PORT), 0);
|
r = uv_udp_bind(&h, uv_ip4_addr("0.0.0.0", TEST_PORT), 0);
|
||||||
ASSERT(r == 0);
|
ASSERT(r == 0);
|
||||||
|
|||||||
7
uv.gyp
7
uv.gyp
@ -47,6 +47,8 @@
|
|||||||
'include/ares.h',
|
'include/ares.h',
|
||||||
'include/ares_version.h',
|
'include/ares_version.h',
|
||||||
'include/uv.h',
|
'include/uv.h',
|
||||||
|
'include/uv-private/ngx-queue.h',
|
||||||
|
'include/uv-private/tree.h',
|
||||||
'src/uv-common.c',
|
'src/uv-common.c',
|
||||||
'src/uv-common.h',
|
'src/uv-common.h',
|
||||||
'src/ares/ares_cancel.c',
|
'src/ares/ares_cancel.c',
|
||||||
@ -125,7 +127,6 @@
|
|||||||
'_GNU_SOURCE',
|
'_GNU_SOURCE',
|
||||||
],
|
],
|
||||||
'sources': [
|
'sources': [
|
||||||
'include/uv-private/tree.h',
|
|
||||||
'include/uv-private/uv-win.h',
|
'include/uv-private/uv-win.h',
|
||||||
'src/ares/config_win32/ares_config.h',
|
'src/ares/config_win32/ares_config.h',
|
||||||
'src/ares/windows_port.c',
|
'src/ares/windows_port.c',
|
||||||
@ -179,11 +180,9 @@
|
|||||||
'sources': [
|
'sources': [
|
||||||
'include/uv-private/eio.h',
|
'include/uv-private/eio.h',
|
||||||
'include/uv-private/ev.h',
|
'include/uv-private/ev.h',
|
||||||
'include/uv-private/ngx-queue.h',
|
|
||||||
'include/uv-private/uv-unix.h',
|
'include/uv-private/uv-unix.h',
|
||||||
'src/unix/async.c',
|
'src/unix/async.c',
|
||||||
'src/unix/cares.c',
|
'src/unix/cares.c',
|
||||||
'src/unix/check.c',
|
|
||||||
'src/unix/core.c',
|
'src/unix/core.c',
|
||||||
'src/unix/dl.c',
|
'src/unix/dl.c',
|
||||||
'src/unix/eio/ecb.h',
|
'src/unix/eio/ecb.h',
|
||||||
@ -195,12 +194,10 @@
|
|||||||
'src/unix/ev/ev_wrap.h',
|
'src/unix/ev/ev_wrap.h',
|
||||||
'src/unix/ev/event.h',
|
'src/unix/ev/event.h',
|
||||||
'src/unix/fs.c',
|
'src/unix/fs.c',
|
||||||
'src/unix/idle.c',
|
|
||||||
'src/unix/internal.h',
|
'src/unix/internal.h',
|
||||||
'src/unix/loop.c',
|
'src/unix/loop.c',
|
||||||
'src/unix/pipe.c',
|
'src/unix/pipe.c',
|
||||||
'src/unix/poll.c',
|
'src/unix/poll.c',
|
||||||
'src/unix/prepare.c',
|
|
||||||
'src/unix/process.c',
|
'src/unix/process.c',
|
||||||
'src/unix/stream.c',
|
'src/unix/stream.c',
|
||||||
'src/unix/tcp.c',
|
'src/unix/tcp.c',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user