Upgrade libuv to ea4271f

Required adding uv_default_loop() in many places.
This commit is contained in:
Ryan Dahl committed 2011-08-31 01:53:30 -07:00
1 parent 6f60683802
commit 21cc4c4985
146 files changed
+2160 -1696

No files matched your search

+1 -1
View File
@@ -24,7 +24,7 @@ ifdef MSVC
uname_S := MINGW
endif
CPPFLAGS += -Iinclude
CPPFLAGS += -Iinclude -Iinclude/uv-private
CARES_OBJS =
CARES_OBJS += src/ares/ares__close_sockets.o
+26 -24
View File
@@ -23,7 +23,7 @@ AR = $(PREFIX)ar
E=
CSTDFLAG=--std=c89 -pedantic -Wall -Wextra -Wno-unused-parameter
CFLAGS=-g
CPPFLAGS += -Isrc/ev
CPPFLAGS += -Isrc/unix/ev
LINKFLAGS=-lm
CPPFLAGS += -D_LARGEFILE_SOURCE
@@ -34,7 +34,7 @@ EV_CONFIG=config_sunos.h
EIO_CONFIG=config_sunos.h
CPPFLAGS += -Isrc/ares/config_sunos -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
LINKFLAGS+=-lsocket -lnsl
UV_OS_FILE=uv-sunos.c
UV_OS_FILE=sunos.c
endif
ifeq (Darwin,$(uname_S))
@@ -42,7 +42,7 @@ EV_CONFIG=config_darwin.h
EIO_CONFIG=config_darwin.h
CPPFLAGS += -Isrc/ares/config_darwin
LINKFLAGS+=-framework CoreServices
UV_OS_FILE=uv-darwin.c
UV_OS_FILE=darwin.c
endif
ifeq (Linux,$(uname_S))
@@ -51,7 +51,7 @@ EIO_CONFIG=config_linux.h
CSTDFLAG += -D_XOPEN_SOURCE=600
CPPFLAGS += -Isrc/ares/config_linux
LINKFLAGS+=-lrt
UV_OS_FILE=uv-linux.c
UV_OS_FILE=linux.c
endif
ifeq (FreeBSD,$(uname_S))
@@ -59,7 +59,7 @@ EV_CONFIG=config_freebsd.h
EIO_CONFIG=config_freebsd.h
CPPFLAGS += -Isrc/ares/config_freebsd
LINKFLAGS+=
UV_OS_FILE=uv-freebsd.c
UV_OS_FILE=freebsd.c
endif
ifneq (,$(findstring CYGWIN,$(uname_S)))
@@ -69,7 +69,7 @@ EIO_CONFIG=config_cygwin.h
CSTDFLAG = -D_GNU_SOURCE
CPPFLAGS += -Isrc/ares/config_cygwin
LINKFLAGS+=
UV_OS_FILE=uv-cygwin.c
UV_OS_FILE=cygwin.c
endif
# Need _GNU_SOURCE for strdup?
@@ -85,24 +85,24 @@ endif
RUNNER_LIBS=
RUNNER_SRC=test/runner-unix.c
uv.a: src/uv-unix.o src/unix/fs.o src/uv-common.o src/uv-platform.o src/ev/ev.o src/uv-eio.o src/eio/eio.o $(CARES_OBJS)
$(AR) rcs uv.a src/uv-unix.o src/unix/fs.o src/uv-platform.o src/uv-common.o src/uv-eio.o src/ev/ev.o \
src/eio/eio.o $(CARES_OBJS)
uv.a: src/uv-unix.o src/unix/fs.o src/uv-common.o src/uv-platform.o src/unix/ev/ev.o src/unix/uv-eio.o src/unix/eio/eio.o $(CARES_OBJS)
$(AR) rcs uv.a src/uv-unix.o src/unix/fs.o src/uv-platform.o src/uv-common.o src/unix/uv-eio.o src/unix/ev/ev.o \
src/unix/eio/eio.o $(CARES_OBJS)
src/uv-platform.o: src/$(UV_OS_FILE) include/uv.h include/uv-unix.h
$(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c src/$(UV_OS_FILE) -o src/uv-platform.o
src/uv-platform.o: src/unix/$(UV_OS_FILE) include/uv.h include/uv-private/uv-unix.h
$(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c src/unix/$(UV_OS_FILE) -o src/uv-platform.o
src/uv-unix.o: src/uv-unix.c include/uv.h include/uv-unix.h src/unix/internal.h
src/uv-unix.o: src/uv-unix.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h
$(CC) $(CSTDFLAG) $(CPPFLAGS) -Isrc $(CFLAGS) -c src/uv-unix.c -o src/uv-unix.o
src/unix/fs.o: src/unix/fs.c include/uv.h include/uv-unix.h src/unix/internal.h
src/unix/fs.o: src/unix/fs.c include/uv.h include/uv-private/uv-unix.h src/unix/internal.h
$(CC) $(CSTDFLAG) $(CPPFLAGS) -Isrc/ $(CFLAGS) -c src/unix/fs.c -o src/unix/fs.o
src/uv-common.o: src/uv-common.c include/uv.h include/uv-unix.h
src/uv-common.o: src/uv-common.c include/uv.h include/uv-private/uv-unix.h
$(CC) $(CSTDFLAG) $(CPPFLAGS) $(CFLAGS) -c src/uv-common.c -o src/uv-common.o
src/ev/ev.o: src/ev/ev.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c src/ev/ev.c -o src/ev/ev.o -DEV_CONFIG_H=\"$(EV_CONFIG)\"
src/unix/ev/ev.o: src/unix/ev/ev.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c src/unix/ev/ev.c -o src/unix/ev/ev.o -DEV_CONFIG_H=\"$(EV_CONFIG)\"
EIO_CPPFLAGS += $(CPPFLAGS)
@@ -110,21 +110,23 @@ EIO_CPPFLAGS += -DEIO_CONFIG_H=\"$(EIO_CONFIG)\"
EIO_CPPFLAGS += -DEIO_STACKSIZE=262144
EIO_CPPFLAGS += -D_GNU_SOURCE
src/eio/eio.o: src/eio/eio.c
$(CC) $(EIO_CPPFLAGS) $(CFLAGS) -c src/eio/eio.c -o src/eio/eio.o
src/unix/eio/eio.o: src/unix/eio/eio.c
$(CC) $(EIO_CPPFLAGS) $(CFLAGS) -c src/unix/eio/eio.c -o src/unix/eio/eio.o
src/uv-eio.o: src/uv-eio.c
$(CC) $(CPPFLAGS) -Isrc/eio/ $(CSTDFLAG) $(CFLAGS) -c src/uv-eio.c -o src/uv-eio.o
src/unix/uv-eio.o: src/unix/uv-eio.c
$(CC) $(CPPFLAGS) -Isrc/unix/eio/ $(CSTDFLAG) $(CFLAGS) -c src/unix/uv-eio.c -o src/unix/uv-eio.o
clean-platform:
-rm -f src/ares/*.o
-rm -f src/ev/*.o
-rm -f src/eio/*.o
-rm -f src/unix/ev/*.o
-rm -f src/unix/eio/*.o
-rm -f src/unix/*.o
-rm -rf test/run-tests.dSYM run-benchmarks.dSYM
distclean-platform:
-rm -f src/ares/*.o
-rm -f src/ev/*.o
-rm -f src/eio/*.o
-rm -f src/unix/ev/*.o
-rm -f src/unix/*.o
-rm -f src/unix/eio/*.o
-rm -rf test/run-tests.dSYM run-benchmarks.dSYM
+2 -2
View File
@@ -195,7 +195,7 @@ enum
enum
{
EIO_MCL_CURRENT = 1,
EIO_MCL_FUTURE = 2,
EIO_MCL_FUTURE = 2
};
/* request priorities */
@@ -203,7 +203,7 @@ enum
enum {
EIO_PRI_MIN = -4,
EIO_PRI_MAX = 4,
EIO_PRI_DEFAULT = 0,
EIO_PRI_DEFAULT = 0
};
/* eio request structure */
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -42,6 +42,16 @@ typedef struct {
typedef int uv_file;
#define UV_LOOP_PRIVATE_FIELDS \
ares_channel channel; \
/* \
* While the channel is active this timer is called once per second to be \
* sure that we're always calling ares_process. See the warning above the \
* definition of ares_timeout(). \
*/ \
ev_timer timer; \
struct ev_loop* ev;
#define UV_REQ_BUFSML_SIZE (4)
#define UV_REQ_PRIVATE_FIELDS /* empty */
@@ -44,6 +44,40 @@ typedef struct uv_buf_t {
typedef int uv_file;
RB_HEAD(uv_timer_tree_s, uv_timer_s);
#define UV_LOOP_PRIVATE_FIELDS \
/* The loop's I/O completion port */ \
HANDLE iocp; \
/* Reference count that keeps the event loop alive */ \
int refs; \
/* The current time according to the event loop. in msecs. */ \
int64_t time; \
/* Tail of a single-linked circular queue of pending reqs. If the queue */ \
/* is empty, tail_ is NULL. If there is only one item, */ \
/* tail_->next_req == tail_ */ \
uv_req_t* pending_reqs_tail; \
/* Head of a single-linked list of closed handles */ \
uv_handle_t* endgame_handles; \
/* The head of the timers tree */ \
struct uv_timer_tree_s timers; \
/* Lists of active loop (prepare / check / idle) watchers */ \
uv_prepare_t* prepare_handles; \
uv_check_t* check_handles; \
uv_idle_t* idle_handles; \
/* This pointer will refer to the prepare/check/idle handle whose */ \
/* callback is scheduled to be called next. This is needed to allow */ \
/* safe removal from one of the lists above while that list being */ \
/* iterated over. */ \
uv_prepare_t* next_prepare_handle; \
uv_check_t* next_check_handle; \
uv_idle_t* next_idle_handle; \
ares_channel ares_channel; \
int ares_active_sockets; \
uv_timer_t ares_polling_timer; \
/* Last error code */ \
uv_err_t last_error;
#define UV_REQ_TYPE_PRIVATE \
/* TODO: remove the req suffix */ \
UV_ARES_EVENT_REQ, \
@@ -227,5 +261,7 @@ typedef int uv_file;
#define UV_WORK_PRIVATE_FIELDS \
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size, char* utf8Buffer, size_t utf8Size);
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer, size_t utf16Size);
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size);
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
size_t utf16Size);
+103 -57
View File
@@ -19,7 +19,7 @@
* IN THE SOFTWARE.
*/
/* See uv_init for an introduction. */
/* See uv_loop_new for an introduction. */
#ifndef UV_H
#define UV_H
@@ -41,6 +41,8 @@ extern "C" {
typedef intptr_t ssize_t;
#endif
typedef struct uv_loop_s uv_loop_t;
typedef struct uv_ares_task_s uv_ares_task_t;
typedef struct uv_err_s uv_err_t;
typedef struct uv_handle_s uv_handle_t;
typedef struct uv_stream_s uv_stream_t;
@@ -54,6 +56,7 @@ typedef struct uv_idle_s uv_idle_t;
typedef struct uv_async_s uv_async_t;
typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
typedef struct uv_process_s uv_process_t;
typedef struct uv_counters_s uv_counters_t;
/* Request types */
typedef struct uv_req_s uv_req_t;
typedef struct uv_shutdown_s uv_shutdown_t;
@@ -64,41 +67,45 @@ typedef struct uv_fs_s uv_fs_t;
typedef struct uv_work_s uv_work_t;
#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__)
# include "uv-unix.h"
# include "uv-private/uv-unix.h"
#else
# include "uv-win.h"
# include "uv-private/uv-win.h"
#endif
/*
* This function must be called before any other functions in libuv.
*
* At the moment libuv is single threaded but this will likely change in the
* near future. Basically it will change by uv_init() taking a 'loop'
* argument and all other _init having a first argument as the the 'loop'.
*
* All functions besides uv_run() are non-blocking.
*
* All callbacks in libuv are made asynchronously. That is they are never
* made by the function that takes them as a parameter.
*/
void uv_init();
uv_loop_t* uv_loop_new();
void uv_loop_delete(uv_loop_t*);
/*
* Returns the default loop.
*/
uv_loop_t* uv_default_loop();
/*
* This function starts the event loop. It blocks until the reference count
* of the loop drops to zero.
*/
int uv_run();
int uv_run(uv_loop_t*);
/*
* 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.
*/
void uv_ref();
void uv_unref();
void uv_ref(uv_loop_t*);
void uv_unref(uv_loop_t*);
void uv_update_time();
int64_t uv_now();
void uv_update_time(uv_loop_t*);
int64_t uv_now(uv_loop_t*);
/*
@@ -123,7 +130,8 @@ typedef void (*uv_async_cb)(uv_async_t* handle, int status);
typedef void (*uv_prepare_cb)(uv_prepare_t* handle, int status);
typedef void (*uv_check_cb)(uv_check_t* handle, int status);
typedef void (*uv_idle_cb)(uv_idle_t* handle, int status);
typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* handle, int status, struct addrinfo* res);
typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* handle, int status,
struct addrinfo* res);
typedef void (*uv_exit_cb)(uv_process_t*, int exit_status, int term_signal);
typedef void (*uv_fs_cb)(uv_fs_t* req);
typedef void (*uv_work_cb)(uv_work_t* req);
@@ -223,7 +231,7 @@ struct uv_err_s {
* On error the user should then call uv_last_error() to determine
* the error code.
*/
uv_err_t uv_last_error();
uv_err_t uv_last_error(uv_loop_t*);
char* uv_strerror(uv_err_t err);
const char* uv_err_name(uv_err_t err);
@@ -266,6 +274,7 @@ struct uv_shutdown_s {
#define UV_HANDLE_FIELDS \
/* read-only */ \
uv_loop_t* loop; \
uv_handle_type type; \
/* public */ \
uv_close_cb close_cb; \
@@ -358,7 +367,7 @@ typedef enum {
UV_STDERR
} uv_std_type;
uv_stream_t* uv_std_handle(uv_std_type type);
uv_stream_t* uv_std_handle(uv_loop_t*, uv_std_type type);
/*
* Write data to stream. Buffers are written in order. Example:
@@ -402,7 +411,7 @@ struct uv_tcp_s {
UV_TCP_PRIVATE_FIELDS
};
int uv_tcp_init(uv_tcp_t* handle);
int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in);
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6);
@@ -485,7 +494,7 @@ struct uv_udp_send_s {
* Initialize a new UDP handle. The actual socket is created lazily.
* Returns 0 on success.
*/
int uv_udp_init(uv_udp_t* handle);
int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
/*
* Bind to a IPv4 address and port.
@@ -590,7 +599,7 @@ struct uv_pipe_s {
UV_PIPE_PRIVATE_FIELDS
};
int uv_pipe_init(uv_pipe_t* handle);
int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle);
int uv_pipe_bind(uv_pipe_t* handle, const char* name);
@@ -610,7 +619,7 @@ struct uv_prepare_s {
UV_PREPARE_PRIVATE_FIELDS
};
int uv_prepare_init(uv_prepare_t* prepare);
int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare);
int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb);
@@ -628,7 +637,7 @@ struct uv_check_s {
UV_CHECK_PRIVATE_FIELDS
};
int uv_check_init(uv_check_t* check);
int uv_check_init(uv_loop_t*, uv_check_t* check);
int uv_check_start(uv_check_t* check, uv_check_cb cb);
@@ -648,7 +657,7 @@ struct uv_idle_s {
UV_IDLE_PRIVATE_FIELDS
};
int uv_idle_init(uv_idle_t* idle);
int uv_idle_init(uv_loop_t*, uv_idle_t* idle);
int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb);
@@ -670,7 +679,7 @@ struct uv_async_s {
UV_ASYNC_PRIVATE_FIELDS
};
int uv_async_init(uv_async_t* async, uv_async_cb async_cb);
int uv_async_init(uv_loop_t*, uv_async_t* async, uv_async_cb async_cb);
/*
* This can be called from other threads to wake up a libuv thread.
@@ -691,7 +700,7 @@ struct uv_timer_s {
UV_TIMER_PRIVATE_FIELDS
};
int uv_timer_init(uv_timer_t* timer);
int uv_timer_init(uv_loop_t*, uv_timer_t* timer);
int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout,
int64_t repeat);
@@ -717,11 +726,13 @@ int64_t uv_timer_get_repeat(uv_timer_t* timer);
/* c-ares integration initialize and terminate */
int uv_ares_init_options(ares_channel *channelptr,
int uv_ares_init_options(uv_loop_t*,
ares_channel *channelptr,
struct ares_options *options,
int optmask);
void uv_ares_destroy(ares_channel channel);
/* TODO remove the loop argument from this function? */
void uv_ares_destroy(uv_loop_t*, ares_channel channel);
/*
@@ -745,7 +756,8 @@ struct uv_getaddrinfo_s {
* Input arguments may be released after return from this call. Callback
* must not call freeaddrinfo.
*/
int uv_getaddrinfo(uv_getaddrinfo_t* handle,
int uv_getaddrinfo(uv_loop_t*,
uv_getaddrinfo_t* handle,
uv_getaddrinfo_cb getaddrinfo_cb,
const char* node,
const char* service,
@@ -799,7 +811,7 @@ struct uv_process_s {
};
/* Initializes uv_process_t and starts the process. */
int uv_spawn(uv_process_t*, uv_process_options_t options);
int uv_spawn(uv_loop_t*, uv_process_t*, uv_process_options_t options);
/*
* Kills the process with the specified signal. The user must still
@@ -813,13 +825,14 @@ int uv_process_kill(uv_process_t*, int signum);
*/
struct uv_work_s {
UV_REQ_FIELDS
uv_loop_t* loop;
uv_work_cb work_cb;
uv_after_work_cb after_work_cb;
UV_WORK_PRIVATE_FIELDS
};
/* Queues a work request to execute asynchronously on the thread pool. */
int uv_queue_work(uv_work_t* req, uv_work_cb work_cb,
int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
uv_after_work_cb after_work_cb);
@@ -858,6 +871,7 @@ typedef enum {
*/
struct uv_fs_s {
UV_REQ_FIELDS
uv_loop_t* loop;
uv_fs_type fs_type;
uv_fs_cb cb;
ssize_t result;
@@ -867,31 +881,48 @@ struct uv_fs_s {
};
void uv_fs_req_cleanup(uv_fs_t* req);
int uv_fs_close(uv_fs_t* req, uv_file file, uv_fs_cb cb);
int uv_fs_open(uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb);
int uv_fs_read(uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offset, uv_fs_cb cb);
int uv_fs_unlink(uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_write(uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offset, uv_fs_cb cb);
int uv_fs_mkdir(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb);
int uv_fs_rmdir(uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb);
int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_fstat(uv_fs_t* req, uv_file file, uv_fs_cb cb);
int uv_fs_rename(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb);
int uv_fs_fsync(uv_fs_t* req, uv_file file, uv_fs_cb cb);
int uv_fs_fdatasync(uv_fs_t* req, uv_file file, uv_fs_cb cb);
int uv_fs_ftruncate(uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb);
int uv_fs_sendfile(uv_fs_t* req, uv_file out_fd, uv_file in_fd, off_t in_offset, size_t length, uv_fs_cb cb);
int uv_fs_chmod(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb);
int uv_fs_utime(uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb);
int uv_fs_futime(uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb);
int uv_fs_lstat(uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_link(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb);
int uv_fs_symlink(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb);
int uv_fs_readlink(uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_fchmod(uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb);
int uv_fs_chown(uv_fs_t* req, const char* path, int uid, int gid, uv_fs_cb cb);
int uv_fs_fchown(uv_fs_t* req, uv_file file, int uid, int gid, uv_fs_cb cb);
int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb);
int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
int mode, uv_fs_cb cb);
int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
size_t length, off_t offset, uv_fs_cb cb);
int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
size_t length, off_t offset, uv_fs_cb cb);
int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb);
int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
uv_fs_cb cb);
int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb);
int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb);
int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb);
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb);
int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
off_t offset, uv_fs_cb cb);
int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
uv_file in_fd, off_t in_offset, size_t length, uv_fs_cb cb);
int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb);
int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
double mtime, uv_fs_cb cb);
int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
double mtime, uv_fs_cb cb);
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb);
int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb);
int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb);
int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode,
uv_fs_cb cb);
int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
int gid, uv_fs_cb cb);
int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid,
int gid, uv_fs_cb cb);
/* Utility */
@@ -941,8 +972,8 @@ union uv_any_req {
};
/* Diagnostic counters */
typedef struct {
struct uv_counters_s {
uint64_t eio_init;
uint64_t req_init;
uint64_t handle_init;
uint64_t stream_init;
@@ -955,9 +986,24 @@ typedef struct {
uint64_t async_init;
uint64_t timer_init;
uint64_t process_init;
} uv_counters_t;
};
uv_counters_t* uv_counters();
struct uv_loop_s {
UV_LOOP_PRIVATE_FIELDS
/* list used for ares task handles */
uv_ares_task_t* uv_ares_handles_;
/* Various thing for libeio. */
uv_async_t uv_eio_want_poll_notifier;
uv_async_t uv_eio_done_poll_notifier;
uv_idle_t uv_eio_poller;
/* Diagnostic counters */
uv_counters_t counters;
/* The last error */
uv_err_t last_err;
/* User data - use this for whatever. */
void* data;
};
/* Don't export the private CPP symbols. */
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
View File
File renamed without changes.
View File
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+121 -107
View File
@@ -33,12 +33,14 @@
#include <unistd.h>
static void uv_fs_req_init(uv_fs_t* req, uv_fs_type fs_type, uv_fs_cb cb) {
static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type,
uv_fs_cb cb) {
/* Make sure the thread pool is initialized. */
uv_eio_init();
uv_eio_init(loop);
uv__req_init((uv_req_t*) req);
req->type = UV_FS;
req->loop = loop;
req->fs_type = fs_type;
req->cb = cb;
req->result = 0;
@@ -103,7 +105,7 @@ static int uv__fs_after(eio_req* eio) {
req->ptr = req->eio->ptr2;
}
uv_unref();
uv_unref(req->loop);
req->eio = NULL; /* Freed by libeio */
req->cb(req);
@@ -111,20 +113,20 @@ static int uv__fs_after(eio_req* eio) {
}
int uv_fs_close(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_CLOSE, cb);
int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_CLOSE, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_close(file, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
} else {
/* sync */
if ((req->result = uv__close(file))) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
}
@@ -133,16 +135,16 @@ int uv_fs_close(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
}
int uv_fs_open(uv_fs_t* req, const char* path, int flags, int mode,
uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_OPEN, cb);
int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
int mode, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_OPEN, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_open(path, flags, mode, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -150,7 +152,7 @@ int uv_fs_open(uv_fs_t* req, const char* path, int flags, int mode,
/* sync */
req->result = open(path, flags, mode);
if (req->result < 0) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
@@ -161,18 +163,18 @@ int uv_fs_open(uv_fs_t* req, const char* path, int flags, int mode,
}
int uv_fs_read(uv_fs_t* req, uv_file fd, void* buf, size_t length,
off_t offset, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_READ, cb);
int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
size_t length, off_t offset, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_READ, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_read(fd, buf, length, offset, EIO_PRI_DEFAULT,
uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -183,7 +185,7 @@ int uv_fs_read(uv_fs_t* req, uv_file fd, void* buf, size_t length,
pread(fd, buf, length, offset);
if (req->result < 0) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
}
@@ -192,15 +194,15 @@ int uv_fs_read(uv_fs_t* req, uv_file fd, void* buf, size_t length,
}
int uv_fs_unlink(uv_fs_t* req, const char* path, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_UNLINK, cb);
int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_UNLINK, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_unlink(path, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -209,7 +211,7 @@ int uv_fs_unlink(uv_fs_t* req, const char* path, uv_fs_cb cb) {
req->result = unlink(path);
if (req->result) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
}
@@ -218,17 +220,17 @@ int uv_fs_unlink(uv_fs_t* req, const char* path, uv_fs_cb cb) {
}
int uv_fs_write(uv_fs_t* req, uv_file file, void* buf, size_t length,
off_t offset, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_WRITE, cb);
int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
size_t length, off_t offset, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_write(file, buf, length, offset, EIO_PRI_DEFAULT,
uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -239,7 +241,7 @@ int uv_fs_write(uv_fs_t* req, uv_file file, void* buf, size_t length,
pwrite(file, buf, length, offset);
if (req->result < 0) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
}
@@ -248,15 +250,16 @@ int uv_fs_write(uv_fs_t* req, uv_file file, void* buf, size_t length,
}
int uv_fs_mkdir(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_MKDIR, cb);
int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_MKDIR, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_mkdir(path, mode, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -265,7 +268,7 @@ int uv_fs_mkdir(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
req->result = mkdir(path, mode);
if (req->result < 0) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
}
@@ -274,15 +277,15 @@ int uv_fs_mkdir(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
}
int uv_fs_rmdir(uv_fs_t* req, const char* path, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_RMDIR, cb);
int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_RMDIR, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_rmdir(path, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -291,7 +294,7 @@ int uv_fs_rmdir(uv_fs_t* req, const char* path, uv_fs_cb cb) {
req->result = rmdir(path);
if (req->result < 0) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
}
@@ -300,20 +303,21 @@ int uv_fs_rmdir(uv_fs_t* req, const char* path, uv_fs_cb cb) {
}
int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) {
int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
uv_fs_cb cb) {
int r;
struct dirent* entry;
size_t size = 0;
size_t d_namlen = 0;
uv_fs_req_init(req, UV_FS_READDIR, cb);
uv_fs_req_init(loop, req, UV_FS_READDIR, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_readdir(path, flags, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -321,7 +325,7 @@ int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) {
/* sync */
DIR* dir = opendir(path);
if (!dir) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
@@ -338,7 +342,7 @@ int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) {
r = closedir(dir);
if (r) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
}
@@ -347,11 +351,11 @@ int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) {
}
int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
char* pathdup = path;
int pathlen;
uv_fs_req_init(req, UV_FS_STAT, cb);
uv_fs_req_init(loop, req, UV_FS_STAT, cb);
/* TODO do this without duplicating the string. */
/* TODO security */
@@ -365,13 +369,13 @@ int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_stat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req);
free(pathdup);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -382,7 +386,7 @@ int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
free(pathdup);
if (req->result < 0) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
@@ -393,22 +397,22 @@ int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
}
int uv_fs_fstat(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_rename(uv_fs_t* req, const char* path, const char* new_path,
int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path,
uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_RENAME, cb);
uv_fs_req_init(loop, req, UV_FS_RENAME, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_rename(path, new_path, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -417,7 +421,7 @@ int uv_fs_rename(uv_fs_t* req, const char* path, const char* new_path,
req->result = rename(path, new_path);
if (req->result) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
}
@@ -426,15 +430,15 @@ int uv_fs_rename(uv_fs_t* req, const char* path, const char* new_path,
}
int uv_fs_fsync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_FSYNC, cb);
int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FSYNC, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_fsync(file, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -443,7 +447,7 @@ int uv_fs_fsync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
req->result = fsync(file);
if (req->result) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
}
@@ -452,15 +456,15 @@ int uv_fs_fsync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
}
int uv_fs_fdatasync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_FDATASYNC, cb);
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_fdatasync(file, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -469,7 +473,7 @@ int uv_fs_fdatasync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
req->result = fdatasync(file);
if (req->result) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
}
@@ -478,15 +482,16 @@ int uv_fs_fdatasync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
}
int uv_fs_ftruncate(uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_FTRUNCATE, cb);
int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, off_t offset,
uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_ftruncate(file, offset, EIO_PRI_DEFAULT, uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -495,7 +500,7 @@ int uv_fs_ftruncate(uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb) {
req->result = ftruncate(file, offset);
if (req->result) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
}
@@ -504,17 +509,17 @@ int uv_fs_ftruncate(uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb) {
}
int uv_fs_sendfile(uv_fs_t* req, uv_file out_fd, uv_file in_fd,
int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd,
off_t in_offset, size_t length, uv_fs_cb cb) {
uv_fs_req_init(req, UV_FS_SENDFILE, cb);
uv_fs_req_init(loop, req, UV_FS_SENDFILE, cb);
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_sendfile(out_fd, in_fd, in_offset, length, EIO_PRI_DEFAULT,
uv__fs_after, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -523,7 +528,7 @@ int uv_fs_sendfile(uv_fs_t* req, uv_file out_fd, uv_file in_fd,
req->result = eio_sendfile_sync(out_fd, in_fd, in_offset, length);
if (req->result) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
}
@@ -532,29 +537,32 @@ int uv_fs_sendfile(uv_fs_t* req, uv_file out_fd, uv_file in_fd,
}
int uv_fs_chmod(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_utime(uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb) {
int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
double mtime, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_futime(uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb) {
int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
double mtime, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_lstat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
char* pathdup = path;
int pathlen;
uv_fs_req_init(req, UV_FS_LSTAT, cb);
uv_fs_req_init(loop, req, UV_FS_LSTAT, cb);
/* TODO do this without duplicating the string. */
/* TODO security */
@@ -568,13 +576,13 @@ int uv_fs_lstat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
if (cb) {
/* async */
uv_ref();
uv_ref(loop);
req->eio = eio_lstat(pathdup, EIO_PRI_DEFAULT, uv__fs_after, req);
free(pathdup);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
@@ -585,7 +593,7 @@ int uv_fs_lstat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
free(pathdup);
if (req->result < 0) {
uv_err_new(NULL, errno);
uv_err_new(loop, errno);
return -1;
}
@@ -596,38 +604,43 @@ int uv_fs_lstat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
}
int uv_fs_link(uv_fs_t* req, const char* path, const char* new_path,
int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_symlink(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) {
int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode,
uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_readlink(uv_fs_t* req, const char* path, uv_fs_cb cb) {
int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
int gid, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_fchmod(uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_chown(uv_fs_t* req, const char* path, int uid, int gid, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_fchown(uv_fs_t* req, uv_file file, int uid, int gid, uv_fs_cb cb) {
int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid, int gid,
uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
@@ -643,7 +656,7 @@ static void uv__work(eio_req* eio) {
static int uv__after_work(eio_req *eio) {
uv_work_t* req = eio->data;
uv_unref();
uv_unref(req->loop);
if (req->after_work_cb) {
req->after_work_cb(req);
}
@@ -651,14 +664,15 @@ static int uv__after_work(eio_req *eio) {
}
int uv_queue_work(uv_work_t* req, uv_work_cb work_cb,
int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
uv_after_work_cb after_work_cb) {
void* data = req->data;
uv_eio_init();
uv_eio_init(loop);
uv__req_init((uv_req_t*) req);
uv_ref();
uv_ref(loop);
req->loop = loop;
req->data = data;
req->work_cb = work_cb;
req->after_work_cb = after_work_cb;
@@ -666,7 +680,7 @@ int uv_queue_work(uv_work_t* req, uv_work_cb work_cb,
req->eio = eio_custom(uv__work, EIO_PRI_DEFAULT, uv__after_work, req);
if (!req->eio) {
uv_err_new(NULL, ENOMEM);
uv_err_new(loop, ENOMEM);
return -1;
}
+1 -1
View File
@@ -27,7 +27,7 @@
int uv__close(int fd);
void uv__req_init(uv_req_t*);
uv_err_t uv_err_new(uv_handle_t* handle, int sys_error);
uv_err_t uv_err_new(uv_loop_t* loop, int sys_error);
int uv__nonblock(int fd, int set) __attribute__((unused));
int uv__cloexec(int fd, int set) __attribute__((unused));
File renamed without changes.
File renamed without changes.
+48 -27
View File
@@ -22,51 +22,55 @@
#include "uv.h"
#include "eio.h"
#include <assert.h>
#include <stdio.h>
static uv_async_t uv_eio_want_poll_notifier;
static uv_async_t uv_eio_done_poll_notifier;
static uv_idle_t uv_eio_poller;
static int uv_eio_init_count;
/* TODO remove me! */
static uv_loop_t* main_loop;
static void uv_eio_do_poll(uv_idle_t* watcher, int status) {
assert(watcher == &uv_eio_poller);
assert(watcher == &(watcher->loop->uv_eio_poller));
/* printf("uv_eio_poller\n"); */
if (eio_poll() != -1 && uv_is_active((uv_handle_t*) &uv_eio_poller)) {
if (eio_poll() != -1 && uv_is_active((uv_handle_t*) watcher)) {
/* printf("uv_eio_poller stop\n"); */
uv_idle_stop(&uv_eio_poller);
uv_unref();
uv_idle_stop(watcher);
uv_unref(watcher->loop);
}
}
/* Called from the main thread. */
static void uv_eio_want_poll_notifier_cb(uv_async_t* watcher, int status) {
assert(watcher == &uv_eio_want_poll_notifier);
uv_loop_t* loop = watcher->loop;
assert(watcher == &loop->uv_eio_want_poll_notifier);
/* printf("want poll notifier\n"); */
if (eio_poll() == -1 && !uv_is_active((uv_handle_t*) &uv_eio_poller)) {
if (eio_poll() == -1 && !uv_is_active((uv_handle_t*) &loop->uv_eio_poller)) {
/* printf("uv_eio_poller start\n"); */
uv_idle_start(&uv_eio_poller, uv_eio_do_poll);
uv_ref();
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) {
assert(watcher == &uv_eio_done_poll_notifier);
uv_loop_t* loop = watcher->loop;
assert(watcher == &loop->uv_eio_done_poll_notifier);
/* printf("done poll notifier\n"); */
if (eio_poll() != -1 && uv_is_active((uv_handle_t*) &uv_eio_poller)) {
if (eio_poll() != -1 && uv_is_active((uv_handle_t*) &loop->uv_eio_poller)) {
/* printf("uv_eio_poller stop\n"); */
uv_idle_stop(&uv_eio_poller);
uv_unref();
uv_idle_stop(&loop->uv_eio_poller);
uv_unref(loop);
}
}
@@ -77,7 +81,13 @@ static void uv_eio_done_poll_notifier_cb(uv_async_t* watcher, int revents) {
*/
static void uv_eio_want_poll(void) {
/* Signal the main thread that eio_poll need to be processed. */
uv_async_send(&uv_eio_want_poll_notifier);
/*
* TODO need to select the correct uv_loop_t and async_send to
* uv_eio_want_poll_notifier.
*/
uv_async_send(&main_loop->uv_eio_want_poll_notifier);
}
@@ -86,22 +96,27 @@ static void uv_eio_done_poll(void) {
* Signal the main thread that we should stop calling eio_poll().
* from the idle watcher.
*/
uv_async_send(&uv_eio_done_poll_notifier);
uv_async_send(&main_loop->uv_eio_done_poll_notifier);
}
void uv_eio_init() {
if (uv_eio_init_count == 0) {
uv_eio_init_count++;
void uv_eio_init(uv_loop_t* loop) {
if (loop->counters.eio_init == 0) {
loop->counters.eio_init++;
uv_idle_init(&uv_eio_poller);
uv_idle_start(&uv_eio_poller, uv_eio_do_poll);
main_loop = loop;
uv_async_init(&uv_eio_want_poll_notifier, uv_eio_want_poll_notifier_cb);
uv_unref();
uv_idle_init(loop, &loop->uv_eio_poller);
uv_idle_start(&loop->uv_eio_poller, uv_eio_do_poll);
uv_async_init(&uv_eio_done_poll_notifier, uv_eio_done_poll_notifier_cb);
uv_unref();
loop->uv_eio_want_poll_notifier.data = loop;
uv_async_init(loop, &loop->uv_eio_want_poll_notifier,
uv_eio_want_poll_notifier_cb);
uv_unref(loop);
uv_async_init(loop, &loop->uv_eio_done_poll_notifier,
uv_eio_done_poll_notifier_cb);
uv_unref(loop);
eio_init(uv_eio_want_poll, uv_eio_done_poll);
/*
@@ -109,5 +124,11 @@ void uv_eio_init() {
* race conditions. See Node's test/simple/test-eio-race.js
*/
eio_set_max_poll_reqs(10);
} else {
/*
* If this assertion breaks then Ryan hasn't implemented support for
* receiving thread pool requests back to multiple threads.
*/
assert(main_loop == loop);
}
}
+1 -1
View File
@@ -9,5 +9,5 @@
* safe to call more than once.
* TODO: uv_eio_deinit
*/
void uv_eio_init(void);
void uv_eio_init(uv_loop_t*);
#endif
+16 -14
View File
@@ -31,9 +31,6 @@
#include "ares/inet_net_pton.h"
#include "ares/inet_ntop.h"
/* list used for ares task handles */
static uv_ares_task_t* uv_ares_handles_ = NULL;
static uv_counters_t counters;
@@ -135,20 +132,23 @@ int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
/* find matching ares handle in list */
void uv_add_ares_handle(uv_ares_task_t* handle) {
handle->ares_next = uv_ares_handles_;
void uv_add_ares_handle(uv_loop_t* loop, uv_ares_task_t* handle) {
handle->loop = loop;
handle->ares_next = loop->uv_ares_handles_;
handle->ares_prev = NULL;
if (uv_ares_handles_) {
uv_ares_handles_->ares_prev = handle;
if (loop->uv_ares_handles_) {
loop->uv_ares_handles_->ares_prev = handle;
}
uv_ares_handles_ = handle;
loop->uv_ares_handles_ = handle;
}
/* find matching ares handle in list */
/* TODO: faster lookup */
uv_ares_task_t* uv_find_ares_handle(ares_socket_t sock) {
uv_ares_task_t* handle = uv_ares_handles_;
uv_ares_task_t* uv_find_ares_handle(uv_loop_t* loop, ares_socket_t sock) {
uv_ares_task_t* handle = loop->uv_ares_handles_;
while (handle != NULL) {
if (handle->sock == sock) {
break;
@@ -161,8 +161,10 @@ uv_ares_task_t* uv_find_ares_handle(ares_socket_t sock) {
/* remove ares handle in list */
void uv_remove_ares_handle(uv_ares_task_t* handle) {
if (handle == uv_ares_handles_) {
uv_ares_handles_ = handle->ares_next;
uv_loop_t* loop = handle->loop;
if (handle == loop->uv_ares_handles_) {
loop->uv_ares_handles_ = handle->ares_next;
}
if (handle->ares_next) {
@@ -176,6 +178,6 @@ void uv_remove_ares_handle(uv_ares_task_t* handle) {
/* Returns 1 if the uv_ares_handles_ list is empty. 0 otherwise. */
int uv_ares_handles_empty() {
return uv_ares_handles_ ? 0 : 1;
int uv_ares_handles_empty(uv_loop_t* loop) {
return loop->uv_ares_handles_ ? 0 : 1;
}
+6 -8
View File
@@ -38,11 +38,6 @@
req->errorno = errno; \
}
/*
* Subclass of uv_handle_t. Used for integration of c-ares.
*/
typedef struct uv_ares_task_s uv_ares_task_t;
struct uv_ares_task_s {
UV_HANDLE_FIELDS
UV_ARES_TASK_PRIVATE_FIELDS
@@ -52,9 +47,12 @@ struct uv_ares_task_s {
void uv_remove_ares_handle(uv_ares_task_t* handle);
uv_ares_task_t* uv_find_ares_handle(ares_socket_t sock);
void uv_add_ares_handle(uv_ares_task_t* handle);
int uv_ares_handles_empty();
uv_ares_task_t* uv_find_ares_handle(uv_loop_t*, ares_socket_t sock);
/* TODO Rename to uv_ares_task_init? */
void uv_add_ares_handle(uv_loop_t* loop, uv_ares_task_t* handle);
int uv_ares_handles_empty(uv_loop_t* loop);
#endif /* UV_COMMON_H_ */
+249 -219
View File
File diff suppressed because it is too large. Load diff
+14 -10
View File
@@ -54,7 +54,7 @@ static inline char uv_atomic_exchange_set(char volatile* target) {
#endif
void uv_async_endgame(uv_async_t* handle) {
void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) {
if (handle->flags & UV_HANDLE_CLOSING &&
!handle->async_sent) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
@@ -64,34 +64,37 @@ void uv_async_endgame(uv_async_t* handle) {
handle->close_cb((uv_handle_t*)handle);
}
uv_unref();
uv_unref(loop);
}
}
int uv_async_init(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_counters()->handle_init++;
uv_counters()->async_init++;
loop->counters.handle_init++;
loop->counters.async_init++;
handle->type = UV_ASYNC;
handle->loop = loop;
handle->flags = 0;
handle->async_sent = 0;
handle->async_cb = async_cb;
req = &handle->async_req;
uv_req_init(req);
uv_req_init(loop, req);
req->type = UV_WAKEUP;
req->data = handle;
uv_ref();
uv_ref(loop);
return 0;
}
int uv_async_send(uv_async_t* handle) {
uv_loop_t* loop = handle->loop;
if (handle->type != UV_ASYNC) {
/* Can't set errno because that's not thread-safe. */
return -1;
@@ -102,14 +105,15 @@ int uv_async_send(uv_async_t* handle) {
assert(!(handle->flags & UV_HANDLE_CLOSING));
if (!uv_atomic_exchange_set(&handle->async_sent)) {
POST_COMPLETION_FOR_REQ(&handle->async_req);
POST_COMPLETION_FOR_REQ(loop, &handle->async_req);
}
return 0;
}
void uv_process_async_wakeup_req(uv_async_t* handle, uv_req_t* req) {
void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
uv_req_t* req) {
assert(handle->type == UV_ASYNC);
assert(req->type == UV_WAKEUP);
@@ -118,6 +122,6 @@ void uv_process_async_wakeup_req(uv_async_t* handle, uv_req_t* req) {
handle->async_cb((uv_async_t*) handle, 0);
}
if (handle->flags & UV_HANDLE_CLOSING) {
uv_want_endgame((uv_handle_t*)handle);
uv_want_endgame(loop, (uv_handle_t*)handle);
}
}
+64 -64
View File
@@ -38,41 +38,34 @@ struct uv_ares_action_s {
};
/* memory used per ares_channel */
typedef struct uv_ares_channel_s {
ares_channel channel;
int activesockets;
uv_timer_t pollingtimer;
} uv_ares_channel_t;
/* static data to hold single ares_channel */
static uv_ares_channel_t uv_ares_data = { NULL, 0 };
/* default timeout per socket request if ares does not specify value */
/* use 20 sec */
#define ARES_TIMEOUT_MS 20000
/* thread pool callback when socket is signalled */
static void CALLBACK uv_ares_socksignal_tp(void* parameter, BOOLEAN timerfired) {
static void CALLBACK uv_ares_socksignal_tp(void* parameter,
BOOLEAN timerfired) {
WSANETWORKEVENTS network_events;
uv_ares_task_t* sockhandle;
uv_ares_action_t* selhandle;
uv_req_t* uv_ares_req;
uv_loop_t* loop;
assert(parameter != NULL);
if (parameter != NULL) {
sockhandle = (uv_ares_task_t*)parameter;
sockhandle = (uv_ares_task_t*) parameter;
loop = sockhandle->loop;
/* clear socket status for this event */
/* do not fail if error, thread may run after socket close */
/* The code assumes that c-ares will write all pending data in the callback,
unless the socket would block. We can clear the state here to avoid unecessary
signals. */
WSAEnumNetworkEvents(sockhandle->sock, sockhandle->h_event, &network_events);
/* The code assumes that c-ares will write all pending data in the */
/* callback, unless the socket would block. We can clear the state here */
/* to avoid unecessary signals. */
WSAEnumNetworkEvents(sockhandle->sock,
sockhandle->h_event,
&network_events);
/* setup new handle */
selhandle = (uv_ares_action_t*)malloc(sizeof(uv_ares_action_t));
@@ -83,47 +76,53 @@ static void CALLBACK uv_ares_socksignal_tp(void* parameter, BOOLEAN timerfired)
selhandle->close_cb = NULL;
selhandle->data = sockhandle->data;
selhandle->sock = sockhandle->sock;
selhandle->read = (network_events.lNetworkEvents & (FD_READ | FD_CONNECT)) ? 1 : 0;
selhandle->write = (network_events.lNetworkEvents & (FD_WRITE | FD_CONNECT)) ? 1 : 0;
selhandle->read =
(network_events.lNetworkEvents & (FD_READ | FD_CONNECT)) ? 1 : 0;
selhandle->write =
(network_events.lNetworkEvents & (FD_WRITE | FD_CONNECT)) ? 1 : 0;
uv_ares_req = &selhandle->ares_req;
uv_req_init(uv_ares_req);
uv_req_init(loop, uv_ares_req);
uv_ares_req->type = UV_ARES_EVENT_REQ;
uv_ares_req->data = selhandle;
/* post ares needs to called */
POST_COMPLETION_FOR_REQ(uv_ares_req);
POST_COMPLETION_FOR_REQ(loop, uv_ares_req);
}
}
/* periodically call ares to check for timeouts */
static void uv_ares_poll(uv_timer_t* handle, int status) {
if (uv_ares_data.channel != NULL && uv_ares_data.activesockets > 0) {
ares_process_fd(uv_ares_data.channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
uv_loop_t* loop = handle->loop;
if (loop->ares_channel != NULL && loop->ares_active_sockets > 0) {
ares_process_fd(loop->ares_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
}
}
/* callback from ares when socket operation is started */
static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int write) {
static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read,
int write) {
/* look to see if we have a handle for this socket in our list */
uv_ares_task_t* uv_handle_ares = uv_find_ares_handle(sock);
uv_ares_channel_t* uv_ares_data_ptr = (uv_ares_channel_t*)data;
uv_loop_t* loop = (uv_loop_t*) data;
uv_ares_task_t* uv_handle_ares = uv_find_ares_handle(loop, sock);
int timeoutms = 0;
if (read == 0 && write == 0) {
/* if read and write are 0, cleanup existing data */
/* The code assumes that c-ares does a callback with read = 0 and write = 0
when the socket is closed. After we recieve this we stop monitoring the socket. */
/* The code assumes that c-ares does a callback with read = 0 and */
/* write = 0 when the socket is closed. After we recieve this we stop */
/* monitoring the socket. */
if (uv_handle_ares != NULL) {
uv_req_t* uv_ares_req;
uv_handle_ares->h_close_event = CreateEvent(NULL, FALSE, FALSE, NULL);
/* remove Wait */
if (uv_handle_ares->h_wait) {
UnregisterWaitEx(uv_handle_ares->h_wait, uv_handle_ares->h_close_event);
UnregisterWaitEx(uv_handle_ares->h_wait,
uv_handle_ares->h_close_event);
uv_handle_ares->h_wait = NULL;
}
@@ -138,12 +137,12 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int w
/* Post request to cleanup the Task */
uv_ares_req = &uv_handle_ares->ares_req;
uv_req_init(uv_ares_req);
uv_req_init(loop, uv_ares_req);
uv_ares_req->type = UV_ARES_CLEANUP_REQ;
uv_ares_req->data = uv_handle_ares;
/* post ares done with socket - finish cleanup when all threads done. */
POST_COMPLETION_FOR_REQ(uv_ares_req);
POST_COMPLETION_FOR_REQ(loop, uv_ares_req);
} else {
assert(0);
uv_fatal_error(ERROR_INVALID_DATA, "ares_SockStateCB");
@@ -160,7 +159,7 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int w
}
uv_handle_ares->type = UV_ARES_TASK;
uv_handle_ares->close_cb = NULL;
uv_handle_ares->data = uv_ares_data_ptr;
uv_handle_ares->data = loop;
uv_handle_ares->sock = sock;
uv_handle_ares->h_wait = NULL;
uv_handle_ares->flags = 0;
@@ -172,24 +171,26 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int w
}
/* tie event to socket */
if (SOCKET_ERROR == WSAEventSelect(sock, uv_handle_ares->h_event, FD_READ | FD_WRITE | FD_CONNECT)) {
if (SOCKET_ERROR == WSAEventSelect(sock,
uv_handle_ares->h_event,
FD_READ | FD_WRITE | FD_CONNECT)) {
uv_fatal_error(WSAGetLastError(), "WSAEventSelect");
}
/* add handle to list */
uv_add_ares_handle(uv_handle_ares);
uv_ref();
uv_add_ares_handle(loop, uv_handle_ares);
uv_ref(loop);
/*
* we have a single polling timer for all ares sockets.
* This is preferred to using ares_timeout. See ares_timeout.c warning.
* if timer is not running start it, and keep socket count
*/
if (uv_ares_data_ptr->activesockets == 0) {
uv_timer_init(&uv_ares_data_ptr->pollingtimer);
uv_timer_start(&uv_ares_data_ptr->pollingtimer, uv_ares_poll, 1000L, 1000L);
if (loop->ares_active_sockets == 0) {
uv_timer_init(loop, &loop->ares_polling_timer);
uv_timer_start(&loop->ares_polling_timer, uv_ares_poll, 1000L, 1000L);
}
uv_ares_data_ptr->activesockets++;
loop->ares_active_sockets++;
/* specify thread pool function to call when event is signaled */
if (RegisterWaitForSingleObject(&uv_handle_ares->h_wait,
@@ -211,12 +212,11 @@ static void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int w
/* called via uv_poll when ares completion port signaled */
void uv_process_ares_event_req(uv_ares_action_t* handle, uv_req_t* req) {
uv_ares_channel_t* uv_ares_data_ptr = (uv_ares_channel_t*)handle->data;
ares_process_fd(uv_ares_data_ptr->channel,
handle->read ? handle->sock : INVALID_SOCKET,
handle->write ? handle->sock : INVALID_SOCKET);
void uv_process_ares_event_req(uv_loop_t* loop, uv_ares_action_t* handle,
uv_req_t* req) {
ares_process_fd(loop->ares_channel,
handle->read ? handle->sock : INVALID_SOCKET,
handle->write ? handle->sock : INVALID_SOCKET);
/* release handle for select here */
free(handle);
@@ -224,47 +224,47 @@ void uv_process_ares_event_req(uv_ares_action_t* handle, uv_req_t* req) {
/* called via uv_poll when ares is finished with socket */
void uv_process_ares_cleanup_req(uv_ares_task_t* handle, uv_req_t* req) {
void uv_process_ares_cleanup_req(uv_loop_t* loop, uv_ares_task_t* handle,
uv_req_t* req) {
/* check for event complete without waiting */
unsigned int signaled = WaitForSingleObject(handle->h_close_event, 0);
if (signaled != WAIT_TIMEOUT) {
uv_ares_channel_t* uv_ares_data_ptr = (uv_ares_channel_t*)handle->data;
uv_unref();
uv_unref(loop);
/* close event handle and free uv handle memory */
CloseHandle(handle->h_close_event);
free(handle);
/* decrement active count. if it becomes 0 stop polling */
if (uv_ares_data_ptr->activesockets > 0) {
uv_ares_data_ptr->activesockets--;
if (uv_ares_data_ptr->activesockets == 0) {
uv_close((uv_handle_t*)&uv_ares_data_ptr->pollingtimer, NULL);
if (loop->ares_active_sockets > 0) {
loop->ares_active_sockets--;
if (loop->ares_active_sockets == 0) {
uv_close((uv_handle_t*) &loop->ares_polling_timer, NULL);
}
}
} else {
/* stil busy - repost and try again */
POST_COMPLETION_FOR_REQ(req);
POST_COMPLETION_FOR_REQ(loop, req);
}
}
/* set ares SOCK_STATE callback to our handler */
int uv_ares_init_options(ares_channel *channelptr,
struct ares_options *options,
int optmask) {
int uv_ares_init_options(uv_loop_t* loop,
ares_channel *channelptr,
struct ares_options *options,
int optmask) {
int rc;
/* only allow single init at a time */
if (uv_ares_data.channel != NULL) {
if (loop->ares_channel != NULL) {
return UV_EALREADY;
}
/* set our callback as an option */
options->sock_state_cb = uv_ares_sockstate_cb;
options->sock_state_cb_data = &uv_ares_data;
options->sock_state_cb_data = loop;
optmask |= ARES_OPT_SOCK_STATE_CB;
/* We do the call to ares_init_option for caller. */
@@ -272,7 +272,7 @@ int uv_ares_init_options(ares_channel *channelptr,
/* if success, save channel */
if (rc == ARES_SUCCESS) {
uv_ares_data.channel = *channelptr;
loop->ares_channel = *channelptr;
}
return rc;
@@ -280,10 +280,10 @@ int uv_ares_init_options(ares_channel *channelptr,
/* release memory */
void uv_ares_destroy(ares_channel channel) {
void uv_ares_destroy(uv_loop_t* loop, ares_channel channel) {
/* only allow destroy if did init */
if (uv_ares_data.channel != NULL) {
if (loop->ares_channel != NULL) {
ares_destroy(channel);
uv_ares_data.channel = NULL;
loop->ares_channel = NULL;
}
}
+59 -49
View File
@@ -32,37 +32,49 @@
/* The only event loop we support right now */
uv_loop_t uv_main_loop_;
static uv_loop_t uv_default_loop_;
static int uv_default_loop_initialized_ = 0;
static void uv_loop_init() {
static void uv_loop_init(uv_loop_t* loop) {
/* Create an I/O completion port */
LOOP->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
if (LOOP->iocp == NULL) {
loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
if (loop->iocp == NULL) {
uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
}
LOOP->refs = 0;
loop->refs = 0;
uv_update_time();
uv_update_time(loop);
LOOP->pending_reqs_tail = NULL;
loop->pending_reqs_tail = NULL;
LOOP->endgame_handles = NULL;
loop->endgame_handles = NULL;
RB_INIT(&LOOP->timers);
RB_INIT(&loop->timers);
LOOP->check_handles = NULL;
LOOP->prepare_handles = NULL;
LOOP->idle_handles = NULL;
loop->check_handles = NULL;
loop->prepare_handles = NULL;
loop->idle_handles = NULL;
LOOP->next_prepare_handle = NULL;
LOOP->next_check_handle = NULL;
LOOP->next_idle_handle = NULL;
loop->next_prepare_handle = NULL;
loop->next_check_handle = NULL;
loop->next_idle_handle = NULL;
LOOP->last_error = uv_ok_;
loop->ares_active_sockets = 0;
loop->ares_channel = NULL;
LOOP->err_str = NULL;
loop->last_error = uv_ok_;
}
uv_loop_t* uv_default_loop() {
if (!uv_default_loop_initialized_) {
uv_loop_init(&uv_default_loop_);
uv_default_loop_initialized_ = 1;
}
return &uv_default_loop_;
}
@@ -75,23 +87,20 @@ void uv_init() {
/* Initialize FS */
uv_fs_init();
/* Intialize event loop */
uv_loop_init();
}
void uv_ref() {
LOOP->refs++;
void uv_ref(uv_loop_t* loop) {
loop->refs++;
}
void uv_unref() {
LOOP->refs--;
void uv_unref(uv_loop_t* loop) {
loop->refs--;
}
static void uv_poll(int block) {
static void uv_poll(uv_loop_t* loop, int block) {
BOOL success;
DWORD bytes, timeout;
ULONG_PTR key;
@@ -99,12 +108,12 @@ static void uv_poll(int block) {
uv_req_t* req;
if (block) {
timeout = uv_get_poll_timeout();
timeout = uv_get_poll_timeout(loop);
} else {
timeout = 0;
}
success = GetQueuedCompletionStatus(LOOP->iocp,
success = GetQueuedCompletionStatus(loop->iocp,
&bytes,
&key,
&overlapped,
@@ -114,7 +123,7 @@ static void uv_poll(int block) {
/* Package was dequeued */
req = uv_overlapped_to_req(overlapped);
uv_insert_pending_req(req);
uv_insert_pending_req(loop, req);
} else if (GetLastError() != WAIT_TIMEOUT) {
/* Serious error */
@@ -123,7 +132,7 @@ static void uv_poll(int block) {
}
static void uv_poll_ex(int block) {
static void uv_poll_ex(uv_loop_t* loop, int block) {
BOOL success;
DWORD timeout;
uv_req_t* req;
@@ -132,14 +141,14 @@ static void uv_poll_ex(int block) {
ULONG i;
if (block) {
timeout = uv_get_poll_timeout();
timeout = uv_get_poll_timeout(loop);
} else {
timeout = 0;
}
assert(pGetQueuedCompletionStatusEx);
success = pGetQueuedCompletionStatusEx(LOOP->iocp,
success = pGetQueuedCompletionStatusEx(loop->iocp,
overlappeds,
COUNTOF(overlappeds),
&count,
@@ -149,7 +158,7 @@ static void uv_poll_ex(int block) {
for (i = 0; i < count; i++) {
/* Package was dequeued */
req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
uv_insert_pending_req(req);
uv_insert_pending_req(loop, req);
}
} else if (GetLastError() != WAIT_TIMEOUT) {
/* Serious error */
@@ -158,43 +167,44 @@ static void uv_poll_ex(int block) {
}
#define UV_LOOP(poll) \
while (LOOP->refs > 0) { \
uv_update_time(); \
uv_process_timers(); \
#define UV_LOOP(loop, poll) \
while ((loop)->refs > 0) { \
uv_update_time((loop)); \
uv_process_timers((loop)); \
\
/* Call idle callbacks if nothing to do. */ \
if (LOOP->pending_reqs_tail == NULL && LOOP->endgame_handles == NULL) { \
uv_idle_invoke(); \
if ((loop)->pending_reqs_tail == NULL && \
(loop)->endgame_handles == NULL) { \
uv_idle_invoke((loop)); \
} \
\
/* Completely flush all pending reqs and endgames. */ \
/* We do even when we just called the idle callbacks because those may */ \
/* have closed handles or started requests that short-circuited. */ \
while (LOOP->pending_reqs_tail || LOOP->endgame_handles) { \
uv_process_endgames(); \
uv_process_reqs(); \
while ((loop)->pending_reqs_tail || (loop)->endgame_handles) { \
uv_process_endgames((loop)); \
uv_process_reqs((loop)); \
} \
\
if (LOOP->refs <= 0) { \
if ((loop)->refs <= 0) { \
break; \
} \
\
uv_prepare_invoke(); \
uv_prepare_invoke((loop)); \
\
poll(LOOP->idle_handles == NULL && LOOP->refs > 0); \
poll((loop), (loop)->idle_handles == NULL && (loop)->refs > 0); \
\
uv_check_invoke(); \
uv_check_invoke((loop)); \
}
int uv_run() {
int uv_run(uv_loop_t* loop) {
if (pGetQueuedCompletionStatusEx) {
UV_LOOP(uv_poll_ex);
UV_LOOP(loop, uv_poll_ex);
} else {
UV_LOOP(uv_poll);
UV_LOOP(loop, uv_poll);
}
assert(LOOP->refs == 0);
assert(loop->refs == 0);
return 0;
}
+17 -13
View File
@@ -67,22 +67,26 @@ void uv_fatal_error(const int errorno, const char* syscall) {
}
uv_err_t uv_last_error() {
return LOOP->last_error;
uv_err_t uv_last_error(uv_loop_t* loop) {
return loop->last_error;
}
/* TODO: thread safety */
static char* last_err_str_ = NULL;
char* uv_strerror(uv_err_t err) {
if (LOOP->err_str != NULL) {
LocalFree(LOOP->err_str);
if (last_err_str_ != NULL) {
LocalFree(last_err_str_);
}
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err.sys_errno_,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&LOOP->err_str, 0, NULL);
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &last_err_str_, 0,
NULL);
if (LOOP->err_str) {
return LOOP->err_str;
if (last_err_str_) {
return last_err_str_;
} else {
return "Unknown error";
}
@@ -134,13 +138,13 @@ uv_err_t uv_new_sys_error(int sys_errno) {
}
void uv_set_sys_error(int sys_errno) {
LOOP->last_error.code = uv_translate_sys_error(sys_errno);
LOOP->last_error.sys_errno_ = sys_errno;
void uv_set_sys_error(uv_loop_t* loop, int sys_errno) {
loop->last_error.code = uv_translate_sys_error(sys_errno);
loop->last_error.sys_errno_ = sys_errno;
}
void uv_set_error(uv_err_code code, int sys_errno) {
LOOP->last_error.code = code;
LOOP->last_error.sys_errno_ = sys_errno;
void uv_set_error(uv_loop_t* loop, uv_err_code code, int sys_errno) {
loop->last_error.code = code;
loop->last_error.sys_errno_ = sys_errno;
}
+141 -99
View File
@@ -59,13 +59,15 @@
WRAP_REQ_ARGS3(req, a0, a1, a2) \
req->arg3 = (void*)a3;
#define QUEUE_FS_TP_JOB(req) \
if (!QueueUserWorkItem(&uv_fs_thread_proc, req, WT_EXECUTELONGFUNCTION)) {\
uv_set_sys_error(GetLastError()); \
#define QUEUE_FS_TP_JOB(loop, req) \
if (!QueueUserWorkItem(&uv_fs_thread_proc, \
req, \
WT_EXECUTELONGFUNCTION)) { \
uv_set_sys_error((loop), GetLastError()); \
return -1; \
} \
req->flags |= UV_FS_ASYNC_QUEUED; \
uv_ref();
uv_ref((loop));
void uv_fs_init() {
@@ -73,9 +75,11 @@ void uv_fs_init() {
}
static void uv_fs_req_init_async(uv_fs_t* req, uv_fs_type fs_type, uv_fs_cb cb) {
uv_req_init((uv_req_t*) req);
static void uv_fs_req_init_async(uv_loop_t* loop, uv_fs_t* req,
uv_fs_type fs_type, uv_fs_cb cb) {
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_FS;
req->loop = loop;
req->flags = 0;
req->fs_type = fs_type;
req->cb = cb;
@@ -86,9 +90,11 @@ static void uv_fs_req_init_async(uv_fs_t* req, uv_fs_type fs_type, uv_fs_cb cb)
}
static void uv_fs_req_init_sync(uv_fs_t* req, uv_fs_type fs_type) {
uv_req_init((uv_req_t*) req);
static void uv_fs_req_init_sync(uv_loop_t* loop, uv_fs_t* req,
uv_fs_type fs_type) {
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_FS;
req->loop = loop;
req->flags = 0;
req->fs_type = fs_type;
req->result = 0;
@@ -109,7 +115,8 @@ void fs__close(uv_fs_t* req, uv_file file) {
}
void fs__read(uv_fs_t* req, uv_file file, void *buf, size_t length, off_t offset) {
void fs__read(uv_fs_t* req, uv_file file, void *buf, size_t length,
off_t offset) {
int result = 0;
if (offset != -1) {
@@ -124,7 +131,8 @@ void fs__read(uv_fs_t* req, uv_file file, void *buf, size_t length, off_t offset
}
void fs__write(uv_fs_t* req, uv_file file, void *buf, size_t length, off_t offset) {
void fs__write(uv_fs_t* req, uv_file file, void *buf, size_t length,
off_t offset) {
int result = 0;
if (offset != -1) {
@@ -281,7 +289,8 @@ void fs__ftruncate(uv_fs_t* req, uv_file file, off_t offset) {
}
void fs__sendfile(uv_fs_t* req, uv_file out_file, uv_file in_file, off_t in_offset, size_t length) {
void fs__sendfile(uv_fs_t* req, uv_file out_file, uv_file in_file,
off_t in_offset, size_t length) {
const size_t max_buf_size = 65536;
size_t buf_size = length < max_buf_size ? length : max_buf_size;
int n, result = 0;
@@ -293,7 +302,7 @@ void fs__sendfile(uv_fs_t* req, uv_file out_file, uv_file in_file, off_t in_offs
if (in_offset != -1) {
result = _lseek(in_file, in_offset, SEEK_SET);
}
if (result != -1) {
while (length > 0) {
n = _read(in_file, buf, length < buf_size ? length : buf_size);
@@ -343,7 +352,8 @@ void fs__futime(uv_fs_t* req, uv_file file, double atime, double mtime) {
static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
uv_fs_t* req = (uv_fs_t*)parameter;
uv_fs_t* req = (uv_fs_t*) parameter;
uv_loop_t* loop = req->loop;
assert(req != NULL);
assert(req->type == UV_FS);
@@ -356,10 +366,18 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
fs__close(req, (uv_file)req->arg0);
break;
case UV_FS_READ:
fs__read(req, (uv_file)req->arg0, req->arg1, (size_t)req->arg2, (off_t)req->arg3);
fs__read(req,
(uv_file) req->arg0,
req->arg1,
(size_t) req->arg2,
(off_t) req->arg3);
break;
case UV_FS_WRITE:
fs__write(req, (uv_file)req->arg0, req->arg1, (size_t)req->arg2, (off_t)req->arg3);
fs__write(req,
(uv_file)req->arg0,
req->arg1,
(size_t) req->arg2,
(off_t) req->arg3);
break;
case UV_FS_UNLINK:
fs__unlink(req, (const char*)req->arg0);
@@ -390,7 +408,11 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
fs__ftruncate(req, (uv_file)req->arg0, (off_t)req->arg1);
break;
case UV_FS_SENDFILE:
fs__sendfile(req, (uv_file)req->arg0, (uv_file)req->arg1, (off_t)req->arg2, (size_t)req->arg3);
fs__sendfile(req,
(uv_file) req->arg0,
(uv_file) req->arg1,
(off_t) req->arg2,
(size_t) req->arg3);
break;
case UV_FS_CHMOD:
fs__chmod(req, (const char*)req->arg0, (int)req->arg1);
@@ -405,20 +427,21 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
assert(!"bad uv_fs_type");
}
POST_COMPLETION_FOR_REQ(req);
POST_COMPLETION_FOR_REQ(loop, req);
return 0;
}
int uv_fs_open(uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb) {
int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
int mode, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_OPEN, cb);
uv_fs_req_init_async(loop, req, UV_FS_OPEN, cb);
WRAP_REQ_ARGS3(req, path, flags, mode);
STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_OPEN);
uv_fs_req_init_sync(loop, req, UV_FS_OPEN);
fs__open(req, path, flags, mode);
}
@@ -426,13 +449,13 @@ int uv_fs_open(uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb)
}
int uv_fs_close(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_CLOSE, cb);
uv_fs_req_init_async(loop, req, UV_FS_CLOSE, cb);
WRAP_REQ_ARGS1(req, file);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_CLOSE);
uv_fs_req_init_sync(loop, req, UV_FS_CLOSE);
fs__close(req, file);
}
@@ -440,13 +463,14 @@ int uv_fs_close(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
}
int uv_fs_read(uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offset, uv_fs_cb cb) {
int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
size_t length, off_t offset, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_READ, cb);
uv_fs_req_init_async(loop, req, UV_FS_READ, cb);
WRAP_REQ_ARGS4(req, file, buf, length, offset);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_READ);
uv_fs_req_init_sync(loop, req, UV_FS_READ);
fs__read(req, file, buf, length, offset);
}
@@ -454,13 +478,14 @@ int uv_fs_read(uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offse
}
int uv_fs_write(uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offset, uv_fs_cb cb) {
int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
size_t length, off_t offset, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_WRITE, cb);
uv_fs_req_init_async(loop, req, UV_FS_WRITE, cb);
WRAP_REQ_ARGS4(req, file, buf, length, offset);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_WRITE);
uv_fs_req_init_sync(loop, req, UV_FS_WRITE);
fs__write(req, file, buf, length, offset);
}
@@ -468,14 +493,15 @@ int uv_fs_write(uv_fs_t* req, uv_file file, void* buf, size_t length, off_t offs
}
int uv_fs_unlink(uv_fs_t* req, const char* path, uv_fs_cb cb) {
int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_UNLINK, cb);
uv_fs_req_init_async(loop, req, UV_FS_UNLINK, cb);
WRAP_REQ_ARGS1(req, path);
STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_UNLINK);
uv_fs_req_init_sync(loop, req, UV_FS_UNLINK);
fs__unlink(req, path);
}
@@ -483,14 +509,15 @@ int uv_fs_unlink(uv_fs_t* req, const char* path, uv_fs_cb cb) {
}
int uv_fs_mkdir(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_MKDIR, cb);
uv_fs_req_init_async(loop, req, UV_FS_MKDIR, cb);
WRAP_REQ_ARGS2(req, path, mode);
STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_MKDIR);
uv_fs_req_init_sync(loop, req, UV_FS_MKDIR);
fs__mkdir(req, path, mode);
}
@@ -498,14 +525,14 @@ int uv_fs_mkdir(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
}
int uv_fs_rmdir(uv_fs_t* req, const char* path, uv_fs_cb cb) {
int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_RMDIR, cb);
uv_fs_req_init_async(loop, req, UV_FS_RMDIR, cb);
WRAP_REQ_ARGS1(req, path);
STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_RMDIR);
uv_fs_req_init_sync(loop, req, UV_FS_RMDIR);
fs__rmdir(req, path);
}
@@ -513,14 +540,15 @@ int uv_fs_rmdir(uv_fs_t* req, const char* path, uv_fs_cb cb) {
}
int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) {
int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_READDIR, cb);
uv_fs_req_init_async(loop, req, UV_FS_READDIR, cb);
WRAP_REQ_ARGS2(req, path, flags);
STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_READDIR);
uv_fs_req_init_sync(loop, req, UV_FS_READDIR);
fs__readdir(req, path, flags);
}
@@ -528,50 +556,56 @@ int uv_fs_readdir(uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) {
}
int uv_fs_lstat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
// uv_fs_readlink, uv_fs_fchmod, uv_fs_chown, uv_fs_fchown
int uv_fs_link(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) {
int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_symlink(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) {
int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_readlink(uv_fs_t* req, const char* path, uv_fs_cb cb) {
int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_fchmod(uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb) {
int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode,
uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_chown(uv_fs_t* req, const char* path, int uid, int gid, uv_fs_cb cb) {
int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
int gid, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_fchown(uv_fs_t* req, uv_file file, int uid, int gid, uv_fs_cb cb) {
int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid,
int gid, uv_fs_cb cb) {
assert(0 && "implement me");
return -1;
}
int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int len = strlen(path);
char* path2 = NULL;
int has_backslash = (path[len - 1] == '\\' || path[len - 1] == '/');
@@ -586,7 +620,7 @@ int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
}
if (cb) {
uv_fs_req_init_async(req, UV_FS_STAT, cb);
uv_fs_req_init_async(loop, req, UV_FS_STAT, cb);
if (path2) {
WRAP_REQ_ARGS1(req, path2);
req->flags |= UV_FS_FREE_ARG0;
@@ -594,10 +628,10 @@ int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
WRAP_REQ_ARGS1(req, path);
STRDUP_ARG(req, 0);
}
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_STAT);
uv_fs_req_init_sync(loop, req, UV_FS_STAT);
fs__stat(req, path2 ? path2 : path);
if (path2) {
free(path2);
@@ -608,13 +642,13 @@ int uv_fs_stat(uv_fs_t* req, const char* path, uv_fs_cb cb) {
}
int uv_fs_fstat(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_FSTAT, cb);
uv_fs_req_init_async(loop, req, UV_FS_FSTAT, cb);
WRAP_REQ_ARGS1(req, file);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_FSTAT);
uv_fs_req_init_sync(loop, req, UV_FS_FSTAT);
fs__fstat(req, file);
}
@@ -622,15 +656,16 @@ int uv_fs_fstat(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
}
int uv_fs_rename(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) {
int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_RENAME, cb);
uv_fs_req_init_async(loop, req, UV_FS_RENAME, cb);
WRAP_REQ_ARGS2(req, path, new_path);
STRDUP_ARG(req, 0);
STRDUP_ARG(req, 1);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_RENAME);
uv_fs_req_init_sync(loop, req, UV_FS_RENAME);
fs__rename(req, path, new_path);
}
@@ -638,13 +673,13 @@ int uv_fs_rename(uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb
}
int uv_fs_fdatasync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_FDATASYNC, cb);
uv_fs_req_init_async(loop, req, UV_FS_FDATASYNC, cb);
WRAP_REQ_ARGS1(req, file);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_FDATASYNC);
uv_fs_req_init_sync(loop, req, UV_FS_FDATASYNC);
fs__fsync(req, file);
}
@@ -652,13 +687,13 @@ int uv_fs_fdatasync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
}
int uv_fs_fsync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_FSYNC, cb);
uv_fs_req_init_async(loop, req, UV_FS_FSYNC, cb);
WRAP_REQ_ARGS1(req, file);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_FSYNC);
uv_fs_req_init_sync(loop, req, UV_FS_FSYNC);
fs__fsync(req, file);
}
@@ -666,13 +701,14 @@ int uv_fs_fsync(uv_fs_t* req, uv_file file, uv_fs_cb cb) {
}
int uv_fs_ftruncate(uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb) {
int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
off_t offset, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_FTRUNCATE, cb);
uv_fs_req_init_async(loop, req, UV_FS_FTRUNCATE, cb);
WRAP_REQ_ARGS2(req, file, offset);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_FTRUNCATE);
uv_fs_req_init_sync(loop, req, UV_FS_FTRUNCATE);
fs__ftruncate(req, file, offset);
}
@@ -680,13 +716,14 @@ int uv_fs_ftruncate(uv_fs_t* req, uv_file file, off_t offset, uv_fs_cb cb) {
}
int uv_fs_sendfile(uv_fs_t* req, uv_file out_fd, uv_file in_fd, off_t in_offset, size_t length, uv_fs_cb cb) {
int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
uv_file in_fd, off_t in_offset, size_t length, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_SENDFILE, cb);
uv_fs_req_init_async(loop, req, UV_FS_SENDFILE, cb);
WRAP_REQ_ARGS4(req, out_fd, in_fd, in_offset, length);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_SENDFILE);
uv_fs_req_init_sync(loop, req, UV_FS_SENDFILE);
fs__sendfile(req, out_fd, in_fd, in_offset, length);
}
@@ -694,14 +731,15 @@ int uv_fs_sendfile(uv_fs_t* req, uv_file out_fd, uv_file in_fd, off_t in_offset,
}
int uv_fs_chmod(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_CHMOD, cb);
uv_fs_req_init_async(loop, req, UV_FS_CHMOD, cb);
WRAP_REQ_ARGS2(req, path, mode);
STRDUP_ARG(req, 0);
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_CHMOD);
uv_fs_req_init_sync(loop, req, UV_FS_CHMOD);
fs__chmod(req, path, mode);
}
@@ -709,16 +747,17 @@ int uv_fs_chmod(uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) {
}
int uv_fs_utime(uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb) {
int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
double mtime, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_UTIME, cb);
uv_fs_req_init_async(loop, req, UV_FS_UTIME, cb);
WRAP_REQ_ARGS1(req, path);
STRDUP_ARG(req, 0);
req->arg4 = (ssize_t)atime;
req->arg5 = (ssize_t)mtime;
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_UTIME);
uv_fs_req_init_sync(loop, req, UV_FS_UTIME);
fs__utime(req, path, atime, mtime);
}
@@ -726,15 +765,16 @@ int uv_fs_utime(uv_fs_t* req, const char* path, double atime, double mtime, uv_f
}
int uv_fs_futime(uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb) {
int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
double mtime, uv_fs_cb cb) {
if (cb) {
uv_fs_req_init_async(req, UV_FS_FUTIME, cb);
uv_fs_req_init_async(loop, req, UV_FS_FUTIME, cb);
WRAP_REQ_ARGS1(req, file);
req->arg4 = (ssize_t)atime;
req->arg5 = (ssize_t)mtime;
QUEUE_FS_TP_JOB(req);
QUEUE_FS_TP_JOB(loop, req);
} else {
uv_fs_req_init_sync(req, UV_FS_FUTIME);
uv_fs_req_init_sync(loop, req, UV_FS_FUTIME);
fs__futime(req, file, atime, mtime);
}
@@ -742,13 +782,15 @@ int uv_fs_futime(uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_c
}
void uv_process_fs_req(uv_fs_t* req) {
void uv_process_fs_req(uv_loop_t* loop, uv_fs_t* req) {
assert(req->cb);
req->cb(req);
}
void uv_fs_req_cleanup(uv_fs_t* req) {
uv_loop_t* loop = req->loop;
if (req->flags & UV_FS_CLEANEDUP) {
return;
}
@@ -769,7 +811,7 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
}
if (req->flags & UV_FS_ASYNC_QUEUED) {
uv_unref();
uv_unref(loop);
}
req->flags |= UV_FS_CLEANEDUP;
+61 -36
View File
@@ -61,34 +61,38 @@
*/
static uv_err_code uv_translate_eai_error(int eai_errno) {
switch (eai_errno) {
case ERROR_SUCCESS: return UV_OK;
case EAI_BADFLAGS: return UV_EBADF;
case EAI_FAIL: return UV_EFAULT;
case EAI_FAMILY: return UV_EAIFAMNOSUPPORT;
case EAI_MEMORY: return UV_ENOMEM;
case EAI_NONAME: return UV_EAINONAME;
case EAI_AGAIN: return UV_EAGAIN;
case EAI_SERVICE: return UV_EAISERVICE;
case EAI_SOCKTYPE: return UV_EAISOCKTYPE;
default: return uv_translate_sys_error(eai_errno);
case ERROR_SUCCESS: return UV_OK;
case EAI_BADFLAGS: return UV_EBADF;
case EAI_FAIL: return UV_EFAULT;
case EAI_FAMILY: return UV_EAIFAMNOSUPPORT;
case EAI_MEMORY: return UV_ENOMEM;
case EAI_NONAME: return UV_EAINONAME;
case EAI_AGAIN: return UV_EAGAIN;
case EAI_SERVICE: return UV_EAISERVICE;
case EAI_SOCKTYPE: return UV_EAISOCKTYPE;
default: return uv_translate_sys_error(eai_errno);
}
}
/* getaddrinfo worker thread implementation */
static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) {
uv_getaddrinfo_t* handle = (uv_getaddrinfo_t*)parameter;
uv_getaddrinfo_t* handle = (uv_getaddrinfo_t*) parameter;
uv_loop_t* loop = handle->loop;
int ret;
assert(handle != NULL);
if (handle != NULL) {
/* call OS function on this thread */
ret = GetAddrInfoW(handle->node, handle->service, handle->hints, &handle->res);
ret = GetAddrInfoW(handle->node,
handle->service,
handle->hints,
&handle->res);
handle->retcode = ret;
/* post getaddrinfo completed */
POST_COMPLETION_FOR_REQ(&handle->getadddrinfo_req);
POST_COMPLETION_FOR_REQ(loop, &handle->getadddrinfo_req);
}
return 0;
@@ -104,7 +108,8 @@ static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) {
* and copy all structs and referenced strings into the one block.
* Each size calculation is adjusted to avoid unaligned pointers.
*/
void uv_process_getaddrinfo_req(uv_getaddrinfo_t* handle, uv_req_t* req) {
void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* handle,
uv_req_t* req) {
int addrinfo_len = 0;
int name_len = 0;
size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo));
@@ -126,7 +131,8 @@ void uv_process_getaddrinfo_req(uv_getaddrinfo_t* handle, uv_req_t* req) {
/* first calculate required length */
addrinfow_ptr = handle->res;
while (addrinfow_ptr != NULL) {
addrinfo_len += addrinfo_struct_len + ALIGNED_SIZE(addrinfow_ptr->ai_addrlen);
addrinfo_len += addrinfo_struct_len +
ALIGNED_SIZE(addrinfow_ptr->ai_addrlen);
if (addrinfow_ptr->ai_canonname != NULL) {
name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0);
if (name_len == 0) {
@@ -163,7 +169,8 @@ void uv_process_getaddrinfo_req(uv_getaddrinfo_t* handle, uv_req_t* req) {
/* copy sockaddr */
if (addrinfo_ptr->ai_addrlen > 0) {
assert(cur_ptr + addrinfo_ptr->ai_addrlen <= alloc_ptr + addrinfo_len);
assert(cur_ptr + addrinfo_ptr->ai_addrlen <=
alloc_ptr + addrinfo_len);
memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen);
addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr;
cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen);
@@ -171,10 +178,16 @@ void uv_process_getaddrinfo_req(uv_getaddrinfo_t* handle, uv_req_t* req) {
/* convert canonical name to UTF-8 */
if (addrinfow_ptr->ai_canonname != NULL) {
name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0);
name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
-1,
NULL,
0);
assert(name_len > 0);
assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len);
name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, cur_ptr, name_len);
name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
-1,
cur_ptr,
name_len);
assert(name_len > 0);
addrinfo_ptr->ai_canonname = cur_ptr;
cur_ptr += ALIGNED_SIZE(name_len);
@@ -208,7 +221,7 @@ complete:
free(alloc_ptr);
}
uv_unref();
uv_unref(loop);
}
@@ -216,7 +229,8 @@ complete:
* Entry point for getaddrinfo
* we convert the UTF-8 strings to UNICODE
* and save the UNICODE string pointers in the handle
* We also copy hints so that caller does not need to keep memory until the callback.
* We also copy hints so that caller does not need to keep memory until the
* callback.
* return UV_OK if a callback will be made
* return error code if validation fails
*
@@ -224,7 +238,8 @@ complete:
* and copy all structs and referenced strings into the one block.
* Each size calculation is adjusted to avoid unaligned pointers.
*/
int uv_getaddrinfo(uv_getaddrinfo_t* handle,
int uv_getaddrinfo(uv_loop_t* loop,
uv_getaddrinfo_t* handle,
uv_getaddrinfo_cb getaddrinfo_cb,
const char* node,
const char* service,
@@ -236,27 +251,29 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle,
if (handle == NULL || getaddrinfo_cb == NULL ||
(node == NULL && service == NULL)) {
uv_set_sys_error(WSAEINVAL);
uv_set_sys_error(loop, WSAEINVAL);
goto error;
}
handle->getaddrinfo_cb = getaddrinfo_cb;
handle->res = NULL;
handle->type = UV_GETADDRINFO;
handle->loop = loop;
/* calculate required memory size for all input values */
if (node != NULL) {
nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(wchar_t));
if (nodesize == 0) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
goto error;
}
}
if (service != NULL) {
servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) * sizeof(wchar_t));
servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) *
sizeof(wchar_t));
if (servicesize == 0) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
goto error;
}
}
@@ -267,18 +284,21 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle,
/* allocate memory for inputs, and partition it as needed */
alloc_ptr = (char*)malloc(nodesize + servicesize + hintssize);
if (!alloc_ptr) {
uv_set_sys_error(WSAENOBUFS);
uv_set_sys_error(loop, WSAENOBUFS);
goto error;
}
/* save alloc_ptr now so we can free if error */
handle->alloc = (void*)alloc_ptr;
/* convert node string to UTF16 into allocated memory and save pointer in handle */
/* convert node string to UTF16 into allocated memory and save pointer in */
/* handle */
if (node != NULL) {
handle->node = (wchar_t*)alloc_ptr;
if (uv_utf8_to_utf16(node, (wchar_t*)alloc_ptr, nodesize / sizeof(wchar_t)) == 0) {
uv_set_sys_error(GetLastError());
if (uv_utf8_to_utf16(node,
(wchar_t*) alloc_ptr,
nodesize / sizeof(wchar_t)) == 0) {
uv_set_sys_error(loop, GetLastError());
goto error;
}
alloc_ptr += nodesize;
@@ -286,11 +306,14 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle,
handle->node = NULL;
}
/* convert service string to UTF16 into allocated memory and save pointer in handle */
/* convert service string to UTF16 into allocated memory and save pointer */
/* in handle */
if (service != NULL) {
handle->service = (wchar_t*)alloc_ptr;
if (uv_utf8_to_utf16(service, (wchar_t*)alloc_ptr, servicesize / sizeof(wchar_t)) == 0) {
uv_set_sys_error(GetLastError());
if (uv_utf8_to_utf16(service,
(wchar_t*) alloc_ptr,
servicesize / sizeof(wchar_t)) == 0) {
uv_set_sys_error(loop, GetLastError());
goto error;
}
alloc_ptr += servicesize;
@@ -314,17 +337,19 @@ int uv_getaddrinfo(uv_getaddrinfo_t* handle,
}
/* init request for Post handling */
uv_req_init(&handle->getadddrinfo_req);
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 */
if (QueueUserWorkItem(&getaddrinfo_thread_proc, handle, WT_EXECUTELONGFUNCTION) == 0) {
uv_set_sys_error(GetLastError());
if (QueueUserWorkItem(&getaddrinfo_thread_proc,
handle,
WT_EXECUTELONGFUNCTION) == 0) {
uv_set_sys_error(loop, GetLastError());
goto error;
}
uv_ref();
uv_ref(loop);
return 0;
+30 -26
View File
@@ -40,15 +40,17 @@ int uv_is_active(uv_handle_t* handle) {
int uv_getsockname(uv_handle_t* handle, struct sockaddr* name, int* namelen) {
uv_loop_t* loop = handle->loop;
switch (handle->type) {
case UV_TCP:
return uv_tcp_getsockname((uv_tcp_t*) handle, name, namelen);
return uv_tcp_getsockname(loop, (uv_tcp_t*) handle, name, namelen);
case UV_UDP:
return uv_udp_getsockname((uv_udp_t*) handle, name, namelen);
return uv_udp_getsockname(loop, (uv_udp_t*) handle, name, namelen);
default:
uv_set_sys_error(WSAENOTSOCK);
uv_set_sys_error(loop, WSAENOTSOCK);
return -1;
}
}
@@ -60,6 +62,8 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
uv_udp_t* udp;
uv_process_t* process;
uv_loop_t* loop = handle->loop;
if (handle->flags & UV_HANDLE_CLOSING) {
return;
}
@@ -80,7 +84,7 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
tcp->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING);
closesocket(tcp->socket);
if (tcp->reqs_pending == 0) {
uv_want_endgame(handle);
uv_want_endgame(loop, handle);
}
return;
@@ -89,7 +93,7 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
pipe->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING);
close_pipe(pipe, NULL, NULL);
if (pipe->reqs_pending == 0) {
uv_want_endgame(handle);
uv_want_endgame(loop, handle);
}
return;
@@ -98,39 +102,39 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
uv_udp_recv_stop(udp);
closesocket(udp->socket);
if (udp->reqs_pending == 0) {
uv_want_endgame(handle);
uv_want_endgame(loop, handle);
}
return;
case UV_TIMER:
uv_timer_stop((uv_timer_t*)handle);
uv_want_endgame(handle);
uv_want_endgame(loop, handle);
return;
case UV_PREPARE:
uv_prepare_stop((uv_prepare_t*)handle);
uv_want_endgame(handle);
uv_want_endgame(loop, handle);
return;
case UV_CHECK:
uv_check_stop((uv_check_t*)handle);
uv_want_endgame(handle);
uv_want_endgame(loop, handle);
return;
case UV_IDLE:
uv_idle_stop((uv_idle_t*)handle);
uv_want_endgame(handle);
uv_want_endgame(loop, handle);
return;
case UV_ASYNC:
if (!((uv_async_t*)handle)->async_sent) {
uv_want_endgame(handle);
uv_want_endgame(loop, handle);
}
return;
case UV_PROCESS:
process = (uv_process_t*)handle;
uv_process_close(process);
uv_process_close(loop, process);
return;
default:
@@ -140,54 +144,54 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
}
void uv_want_endgame(uv_handle_t* handle) {
void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle) {
if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) {
handle->flags |= UV_HANDLE_ENDGAME_QUEUED;
handle->endgame_next = LOOP->endgame_handles;
LOOP->endgame_handles = handle;
handle->endgame_next = loop->endgame_handles;
loop->endgame_handles = handle;
}
}
void uv_process_endgames() {
void uv_process_endgames(uv_loop_t* loop) {
uv_handle_t* handle;
while (LOOP->endgame_handles) {
handle = LOOP->endgame_handles;
LOOP->endgame_handles = handle->endgame_next;
while (loop->endgame_handles) {
handle = loop->endgame_handles;
loop->endgame_handles = handle->endgame_next;
handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
switch (handle->type) {
case UV_TCP:
uv_tcp_endgame((uv_tcp_t*)handle);
uv_tcp_endgame(loop, (uv_tcp_t*) handle);
break;
case UV_NAMED_PIPE:
uv_pipe_endgame((uv_pipe_t*)handle);
uv_pipe_endgame(loop, (uv_pipe_t*) handle);
break;
case UV_UDP:
uv_udp_endgame((uv_udp_t*) handle);
uv_udp_endgame(loop, (uv_udp_t*) handle);
break;
case UV_TIMER:
uv_timer_endgame((uv_timer_t*)handle);
uv_timer_endgame(loop, (uv_timer_t*) handle);
break;
case UV_PREPARE:
case UV_CHECK:
case UV_IDLE:
uv_loop_watcher_endgame(handle);
uv_loop_watcher_endgame(loop, handle);
break;
case UV_ASYNC:
uv_async_endgame((uv_async_t*)handle);
uv_async_endgame(loop, (uv_async_t*) handle);
break;
case UV_PROCESS:
uv_process_endgame((uv_process_t*)handle);
uv_process_endgame(loop, (uv_process_t*) handle);
break;
default:
+68 -96
View File
@@ -33,55 +33,10 @@
/*
* Timers
*/
RB_HEAD(uv_timer_tree_s, uv_timer_s);
void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle);
void uv_timer_endgame(uv_timer_t* handle);
DWORD uv_get_poll_timeout();
void uv_process_timers();
/*
* Core
*/
/* Loop state struct. We don't support multiplicity right now, but this */
/* should help when we get to that. */
typedef struct uv_loop_s {
/* The loop's I/O completion port */
HANDLE iocp;
/* Reference count that keeps the event loop alive */
int refs;
/* The current time according to the event loop. in msecs. */
int64_t time;
/* Tail of a single-linked circular queue of pending reqs. If the queue */
/* is empty, tail_ is NULL. If there is only one item, */
/* tail_->next_req == tail_ */
uv_req_t* pending_reqs_tail;
/* Head of a single-linked list of closed handles */
uv_handle_t* endgame_handles;
/* The head of the timers tree */
struct uv_timer_tree_s timers;
/* Lists of active loop (prepare / check / idle) watchers */
uv_prepare_t* prepare_handles;
uv_check_t* check_handles;
uv_idle_t* idle_handles;
/* This pointer will refer to the prepare/check/idle handle whose */
/* callback is scheduled to be called next. This is needed to allow */
/* safe removal from one of the lists above while that list being */
/* iterated over. */
uv_prepare_t* next_prepare_handle;
uv_check_t* next_check_handle;
uv_idle_t* next_idle_handle;
/* Last error code */
uv_err_t last_error;
/* Error string most recently returned by uv_strerror() */
char* err_str;
} uv_loop_t;
extern uv_loop_t uv_main_loop_;
#define LOOP (&uv_main_loop_)
DWORD uv_get_poll_timeout(uv_loop_t* loop);
void uv_process_timers(uv_loop_t* loop);
/*
@@ -110,8 +65,8 @@ extern uv_loop_t uv_main_loop_;
#define UV_HANDLE_SYNC_BYPASS_IOCP 0x40000
#define UV_HANDLE_ZERO_READ 0x80000
void uv_want_endgame(uv_handle_t* handle);
void uv_process_endgames();
void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle);
void uv_process_endgames(uv_loop_t* loop);
#define DECREASE_PENDING_REQ_COUNT(handle) \
do { \
@@ -120,7 +75,7 @@ void uv_process_endgames();
\
if (handle->flags & UV_HANDLE_CLOSING && \
handle->reqs_pending == 0) { \
uv_want_endgame((uv_handle_t*)handle); \
uv_want_endgame(loop, (uv_handle_t*)handle); \
} \
} while (0)
@@ -134,15 +89,15 @@ void uv_process_endgames();
/*
* Requests
*/
void uv_req_init(uv_req_t* req);
void uv_req_init(uv_loop_t* loop, uv_req_t* req);
uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped);
void uv_insert_pending_req(uv_req_t* req);
void uv_process_reqs();
void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req);
void uv_process_reqs(uv_loop_t* loop);
#define POST_COMPLETION_FOR_REQ(req) \
if (!PostQueuedCompletionStatus(LOOP->iocp, \
#define POST_COMPLETION_FOR_REQ(loop, req) \
if (!PostQueuedCompletionStatus((loop)->iocp, \
0, \
0, \
&((req)->overlapped))) { \
@@ -153,7 +108,7 @@ void uv_process_reqs();
/*
* Streams
*/
void uv_stream_init(uv_stream_t* handle);
void uv_stream_init(uv_loop_t* loop, uv_stream_t* handle);
void uv_connection_init(uv_stream_t* handle);
size_t uv_count_bufs(uv_buf_t bufs[], int count);
@@ -166,75 +121,89 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client);
int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb);
int uv_tcp_write(uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[],
int bufcnt, uv_write_cb cb);
int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen);
int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
uv_buf_t bufs[], int bufcnt, uv_write_cb cb);
int uv_tcp_getsockname(uv_loop_t* loop, uv_tcp_t* handle,
struct sockaddr* name, int* namelen);
void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req);
void uv_process_tcp_write_req(uv_tcp_t* handle, uv_write_t* req);
void uv_process_tcp_accept_req(uv_tcp_t* handle, uv_req_t* req);
void uv_process_tcp_connect_req(uv_tcp_t* handle, uv_connect_t* req);
void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req);
void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_write_t* req);
void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_req_t* req);
void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_connect_t* req);
void uv_tcp_endgame(uv_tcp_t* handle);
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
/*
* UDP
*/
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen);
int uv_udp_getsockname(uv_loop_t* loop, uv_udp_t* handle,
struct sockaddr* name, int* namelen);
void uv_process_udp_recv_req(uv_udp_t* handle, uv_req_t* req);
void uv_process_udp_send_req(uv_udp_t* handle, uv_udp_send_t* req);
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,
uv_udp_send_t* req);
void uv_udp_endgame(uv_udp_t* handle);
void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle);
/*
* Pipes
*/
int uv_pipe_init_with_handle(uv_pipe_t* handle, HANDLE pipeHandle);
int uv_stdio_pipe_server(uv_pipe_t* handle, DWORD access, char* name, size_t nameSize);
int uv_pipe_init_with_handle(uv_loop_t* loop, uv_pipe_t* handle,
HANDLE pipeHandle);
int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
char* name, size_t nameSize);
void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err);
void uv_pipe_endgame(uv_pipe_t* handle);
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_accept(uv_pipe_t* server, uv_pipe_t* client);
int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb);
int uv_pipe_write(uv_write_t* req, uv_pipe_t* handle, uv_buf_t bufs[],
int bufcnt, uv_write_cb cb);
int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
uv_buf_t bufs[], int bufcnt, uv_write_cb cb);
void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req);
void uv_process_pipe_write_req(uv_pipe_t* handle, uv_write_t* req);
void uv_process_pipe_accept_req(uv_pipe_t* handle, uv_req_t* raw_req);
void uv_process_pipe_connect_req(uv_pipe_t* handle, uv_connect_t* req);
void uv_process_pipe_shutdown_req(uv_pipe_t* handle, uv_shutdown_t* req);
void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_req_t* req);
void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_write_t* req);
void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_req_t* raw_req);
void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_connect_t* req);
void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_shutdown_t* req);
/*
* Loop watchers
*/
void uv_loop_watcher_endgame(uv_handle_t* handle);
void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle);
void uv_prepare_invoke();
void uv_check_invoke();
void uv_idle_invoke();
void uv_prepare_invoke(uv_loop_t* loop);
void uv_check_invoke(uv_loop_t* loop);
void uv_idle_invoke(uv_loop_t* loop);
/*
* Async watcher
*/
void uv_async_endgame(uv_async_t* handle);
void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle);
void uv_process_async_wakeup_req(uv_async_t* handle, uv_req_t* req);
void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
uv_req_t* req);
/*
* Spawn
*/
void uv_process_proc_exit(uv_process_t* handle);
void uv_process_proc_close(uv_process_t* handle);
void uv_process_close(uv_process_t* handle);
void uv_process_endgame(uv_process_t* handle);
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle);
void uv_process_proc_close(uv_loop_t* loop, uv_process_t* handle);
void uv_process_close(uv_loop_t* loop, uv_process_t* handle);
void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle);
/*
@@ -242,26 +211,29 @@ void uv_process_endgame(uv_process_t* handle);
*/
typedef struct uv_ares_action_s uv_ares_action_t;
void uv_process_ares_event_req(uv_ares_action_t* handle, uv_req_t* req);
void uv_process_ares_cleanup_req(uv_ares_task_t* handle, uv_req_t* req);
void uv_process_ares_event_req(uv_loop_t* loop, uv_ares_action_t* handle,
uv_req_t* req);
void uv_process_ares_cleanup_req(uv_loop_t* loop, uv_ares_task_t* handle,
uv_req_t* req);
/*
* Getaddrinfo
*/
void uv_process_getaddrinfo_req(uv_getaddrinfo_t* handle, uv_req_t* req);
void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* handle,
uv_req_t* req);
/*
* FS
*/
void uv_fs_init();
void uv_process_fs_req(uv_fs_t* req);
void uv_process_fs_req(uv_loop_t* loop, uv_fs_t* req);
/*
* Threadpool
*/
void uv_process_work_req(uv_work_t* req);
void uv_process_work_req(uv_loop_t* loop, uv_work_t* req);
/*
@@ -273,8 +245,8 @@ void uv_fatal_error(const int errorno, const char* syscall);
uv_err_code uv_translate_sys_error(int sys_errno);
uv_err_t uv_new_sys_error(int sys_errno);
void uv_set_sys_error(int sys_errno);
void uv_set_error(uv_err_code code, int sys_errno);
void uv_set_sys_error(uv_loop_t* loop, int sys_errno);
void uv_set_error(uv_loop_t* loop, uv_err_code code, int sys_errno);
#define SET_REQ_STATUS(req, status) \
(req)->overlapped.Internal = (ULONG_PTR) (status)
+21 -17
View File
@@ -26,7 +26,7 @@
#include "internal.h"
void uv_loop_watcher_endgame(uv_handle_t* handle) {
void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
if (handle->flags & UV_HANDLE_CLOSING) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
handle->flags |= UV_HANDLE_CLOSED;
@@ -35,26 +35,28 @@ void uv_loop_watcher_endgame(uv_handle_t* handle) {
handle->close_cb(handle);
}
uv_unref();
uv_unref(loop);
}
}
#define UV_LOOP_WATCHER_DEFINE(name, NAME) \
int uv_##name##_init(uv_##name##_t* handle) { \
int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
handle->type = UV_##NAME; \
handle->loop = loop; \
handle->flags = 0; \
\
uv_ref(); \
uv_ref(loop); \
\
uv_counters()->handle_init++; \
uv_counters()->prepare_init++; \
loop->counters.handle_init++; \
loop->counters.##name##_init++; \
\
return 0; \
} \
\
\
int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \
uv_loop_t* loop = handle->loop; \
uv_##name##_t* old_head; \
\
assert(handle->type == UV_##NAME); \
@@ -62,7 +64,7 @@ void uv_loop_watcher_endgame(uv_handle_t* handle) {
if (handle->flags & UV_HANDLE_ACTIVE) \
return 0; \
\
old_head = LOOP->name##_handles; \
old_head = loop->name##_handles; \
\
handle->name##_next = old_head; \
handle->name##_prev = NULL; \
@@ -71,7 +73,7 @@ void uv_loop_watcher_endgame(uv_handle_t* handle) {
old_head->name##_prev = handle; \
} \
\
LOOP->name##_handles = handle; \
loop->name##_handles = handle; \
\
handle->name##_cb = cb; \
handle->flags |= UV_HANDLE_ACTIVE; \
@@ -81,19 +83,21 @@ void uv_loop_watcher_endgame(uv_handle_t* handle) {
\
\
int uv_##name##_stop(uv_##name##_t* handle) { \
uv_loop_t* loop = handle->loop; \
\
assert(handle->type == UV_##NAME); \
\
if (!(handle->flags & UV_HANDLE_ACTIVE)) \
return 0; \
\
/* Update loop head if needed */ \
if (LOOP->name##_handles == handle) { \
LOOP->name##_handles = handle->name##_next; \
if (loop->name##_handles == handle) { \
loop->name##_handles = handle->name##_next; \
} \
\
/* Update the iterator-next pointer of needed */ \
if (LOOP->next_##name##_handle == handle) { \
LOOP->next_##name##_handle = handle->name##_next; \
if (loop->next_##name##_handle == handle) { \
loop->next_##name##_handle = handle->name##_next; \
} \
\
if (handle->name##_prev) { \
@@ -109,14 +113,14 @@ void uv_loop_watcher_endgame(uv_handle_t* handle) {
} \
\
\
void uv_##name##_invoke() { \
void uv_##name##_invoke(uv_loop_t* loop) { \
uv_##name##_t* handle; \
\
LOOP->next_##name##_handle = LOOP->name##_handles; \
(loop)->next_##name##_handle = (loop)->name##_handles; \
\
while (LOOP->next_##name##_handle != NULL) { \
handle = LOOP->next_##name##_handle; \
LOOP->next_##name##_handle = handle->name##_next; \
while ((loop)->next_##name##_handle != NULL) { \
handle = (loop)->next_##name##_handle; \
(loop)->next_##name##_handle = handle->name##_next; \
\
handle->name##_cb(handle, 0); \
} \
+137 -111
View File
@@ -51,22 +51,23 @@ static void uv_unique_pipe_name(char* ptr, char* name, size_t size) {
}
int uv_pipe_init(uv_pipe_t* handle) {
uv_stream_init((uv_stream_t*)handle);
int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle) {
uv_stream_init(loop, (uv_stream_t*)handle);
handle->type = UV_NAMED_PIPE;
handle->reqs_pending = 0;
handle->handle = INVALID_HANDLE_VALUE;
handle->name = NULL;
uv_counters()->pipe_init++;
loop->counters.pipe_init++;
return 0;
}
int uv_pipe_init_with_handle(uv_pipe_t* handle, HANDLE pipeHandle) {
int err = uv_pipe_init(handle);
int uv_pipe_init_with_handle(uv_loop_t* loop, uv_pipe_t* handle,
HANDLE pipeHandle) {
int err = uv_pipe_init(loop, handle);
if (!err) {
/*
@@ -88,7 +89,8 @@ static void uv_pipe_connection_init(uv_pipe_t* handle) {
}
int uv_stdio_pipe_server(uv_pipe_t* handle, DWORD access, char* name, size_t nameSize) {
int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
char* name, size_t nameSize) {
HANDLE pipeHandle;
int errno;
int err;
@@ -98,13 +100,9 @@ int uv_stdio_pipe_server(uv_pipe_t* handle, DWORD access, char* name, size_t nam
uv_unique_pipe_name(ptr, name, nameSize);
pipeHandle = CreateNamedPipeA(name,
access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
1,
65536,
65536,
0,
NULL);
access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 65536, 65536, 0,
NULL);
if (pipeHandle != INVALID_HANDLE_VALUE) {
/* No name collisions. We're done. */
@@ -113,7 +111,7 @@ int uv_stdio_pipe_server(uv_pipe_t* handle, DWORD access, char* name, size_t nam
errno = GetLastError();
if (errno != ERROR_PIPE_BUSY && errno != ERROR_ACCESS_DENIED) {
uv_set_sys_error(errno);
uv_set_sys_error(loop, errno);
err = -1;
goto done;
}
@@ -123,10 +121,10 @@ int uv_stdio_pipe_server(uv_pipe_t* handle, DWORD access, char* name, size_t nam
}
if (CreateIoCompletionPort(pipeHandle,
LOOP->iocp,
loop->iocp,
(ULONG_PTR)handle,
0) == NULL) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
err = -1;
goto done;
}
@@ -145,7 +143,8 @@ done:
}
static int uv_set_pipe_handle(uv_pipe_t* handle, HANDLE pipeHandle) {
static int uv_set_pipe_handle(uv_loop_t* loop, uv_pipe_t* handle,
HANDLE pipeHandle) {
DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) {
@@ -153,7 +152,7 @@ static int uv_set_pipe_handle(uv_pipe_t* handle, HANDLE pipeHandle) {
}
if (CreateIoCompletionPort(pipeHandle,
LOOP->iocp,
loop->iocp,
(ULONG_PTR)handle,
0) == NULL) {
return -1;
@@ -165,6 +164,7 @@ static int uv_set_pipe_handle(uv_pipe_t* handle, HANDLE pipeHandle) {
static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) {
int errno;
uv_loop_t* loop;
uv_pipe_t* handle;
uv_shutdown_t* req;
@@ -172,17 +172,19 @@ static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) {
assert(req);
handle = (uv_pipe_t*) req->handle;
assert(handle);
loop = handle->loop;
assert(loop);
FlushFileBuffers(handle->handle);
/* Post completed */
POST_COMPLETION_FOR_REQ(req);
POST_COMPLETION_FOR_REQ(loop, req);
return 0;
}
void uv_pipe_endgame(uv_pipe_t* handle) {
void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
unsigned int uv_alloced;
DWORD result;
uv_shutdown_t* req;
@@ -207,7 +209,7 @@ void uv_pipe_endgame(uv_pipe_t* handle) {
/* Failure */
handle->flags &= ~UV_HANDLE_SHUTTING;
if (req->cb) {
uv_set_sys_error(pRtlNtStatusToDosError(nt_status));
uv_set_sys_error(loop, pRtlNtStatusToDosError(nt_status));
req->cb(req, -1);
}
DECREASE_PENDING_REQ_COUNT(handle);
@@ -218,7 +220,7 @@ void uv_pipe_endgame(uv_pipe_t* handle) {
handle->flags |= UV_HANDLE_SHUT;
/* Short-circuit, no need to call FlushFileBuffers. */
uv_insert_pending_req((uv_req_t*) req);
uv_insert_pending_req(loop, (uv_req_t*) req);
return;
}
@@ -234,7 +236,7 @@ void uv_pipe_endgame(uv_pipe_t* handle) {
/* Failure. */
handle->flags &= ~UV_HANDLE_SHUTTING;
if (req->cb) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
req->cb(req, -1);
}
DECREASE_PENDING_REQ_COUNT(handle);
@@ -259,29 +261,30 @@ void uv_pipe_endgame(uv_pipe_t* handle) {
free(handle);
}
uv_unref();
uv_unref(loop);
}
}
/* Creates a pipe server. */
int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
uv_loop_t* loop = handle->loop;
int i, errno, nameSize;
uv_pipe_accept_t* req;
if (handle->flags & UV_HANDLE_BOUND) {
uv_set_sys_error(WSAEINVAL);
uv_set_sys_error(loop, WSAEINVAL);
return -1;
}
if (!name) {
uv_set_sys_error(WSAEINVAL);
uv_set_sys_error(loop, WSAEINVAL);
return -1;
}
for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
req = &handle->accept_reqs[i];
uv_req_init((uv_req_t*) req);
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_ACCEPT;
req->data = handle;
req->pipeHandle = INVALID_HANDLE_VALUE;
@@ -296,7 +299,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
}
if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
return -1;
}
@@ -305,28 +308,25 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
* If this fails then there's already a pipe server for the given pipe name.
*/
handle->accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
65536,
65536,
0,
NULL);
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
if (handle->accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) {
errno = GetLastError();
if (errno == ERROR_ACCESS_DENIED) {
uv_set_error(UV_EADDRINUSE, errno);
uv_set_error(loop, UV_EADDRINUSE, errno);
} else if (errno == ERROR_PATH_NOT_FOUND || errno == ERROR_INVALID_NAME) {
uv_set_error(UV_EACCESS, errno);
uv_set_error(loop, UV_EACCESS, errno);
} else {
uv_set_sys_error(errno);
uv_set_sys_error(loop, errno);
}
goto error;
}
if (uv_set_pipe_handle(handle, handle->accept_reqs[0].pipeHandle)) {
uv_set_sys_error(GetLastError());
if (uv_set_pipe_handle(loop, handle, handle->accept_reqs[0].pipeHandle)) {
uv_set_sys_error(loop, GetLastError());
goto error;
}
@@ -354,15 +354,19 @@ error:
static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
HANDLE pipeHandle = INVALID_HANDLE_VALUE;
int errno;
uv_loop_t* loop;
uv_pipe_t* handle;
uv_connect_t* req;
req = (uv_connect_t*)parameter;
req = (uv_connect_t*) parameter;
assert(req);
handle = (uv_pipe_t*)req->handle;
handle = (uv_pipe_t*) req->handle;
assert(handle);
loop = handle->loop;
assert(loop);
/* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. We wait for the pipe to become available with WaitNamedPipe. */
/* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. */
/* We wait for the pipe to become available with WaitNamedPipe. */
while (WaitNamedPipeW(handle->name, 30000)) {
/* The pipe is now available, try to connect. */
pipeHandle = CreateFileW(handle->name,
@@ -380,7 +384,8 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
SwitchToThread();
}
if (pipeHandle != INVALID_HANDLE_VALUE && !uv_set_pipe_handle(handle, pipeHandle)) {
if (pipeHandle != INVALID_HANDLE_VALUE &&
!uv_set_pipe_handle(loop, handle, pipeHandle)) {
handle->handle = pipeHandle;
SET_REQ_SUCCESS(req);
} else {
@@ -388,7 +393,7 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
}
/* Post completed */
POST_COMPLETION_FOR_REQ(req);
POST_COMPLETION_FOR_REQ(loop, req);
return 0;
}
@@ -396,12 +401,13 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
const char* name, uv_connect_cb cb) {
uv_loop_t* loop = handle->loop;
int errno, nameSize;
HANDLE pipeHandle;
handle->handle = INVALID_HANDLE_VALUE;
uv_req_init((uv_req_t*) req);
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_CONNECT;
req->handle = (uv_stream_t*) handle;
req->cb = cb;
@@ -429,7 +435,9 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
if (pipeHandle == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_PIPE_BUSY) {
/* Wait for the server to make a pipe instance available. */
if (!QueueUserWorkItem(&pipe_connect_thread_proc, req, WT_EXECUTELONGFUNCTION)) {
if (!QueueUserWorkItem(&pipe_connect_thread_proc,
req,
WT_EXECUTELONGFUNCTION)) {
errno = GetLastError();
goto error;
}
@@ -443,7 +451,7 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
goto error;
}
if (uv_set_pipe_handle((uv_pipe_t*)req->handle, pipeHandle)) {
if (uv_set_pipe_handle(loop, (uv_pipe_t*)req->handle, pipeHandle)) {
errno = GetLastError();
goto error;
}
@@ -451,7 +459,7 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
handle->handle = pipeHandle;
SET_REQ_SUCCESS(req);
uv_insert_pending_req((uv_req_t*) req);
uv_insert_pending_req(loop, (uv_req_t*) req);
handle->reqs_pending++;
return 0;
@@ -464,12 +472,13 @@ error:
if (pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(pipeHandle);
}
uv_set_sys_error(errno);
uv_set_sys_error(loop, errno);
return -1;
}
/* Cleans up uv_pipe_t (server or connection) and all resources associated with it */
/* Cleans up uv_pipe_t (server or connection) and all resources associated */
/* with it. */
void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) {
int i;
HANDLE pipeHandle;
@@ -504,33 +513,30 @@ void close_pipe(uv_pipe_t* handle, int* status, uv_err_t* err) {
}
static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL firstInstance) {
static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
uv_pipe_accept_t* req, BOOL firstInstance) {
assert(handle->flags & UV_HANDLE_LISTENING);
if (!firstInstance) {
assert(req->pipeHandle == INVALID_HANDLE_VALUE);
req->pipeHandle = CreateNamedPipeW(handle->name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
65536,
65536,
0,
NULL);
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
if (req->pipeHandle == INVALID_HANDLE_VALUE) {
SET_REQ_ERROR(req, GetLastError());
uv_insert_pending_req((uv_req_t*) req);
uv_insert_pending_req(loop, (uv_req_t*) req);
handle->reqs_pending++;
return;
}
if (uv_set_pipe_handle(handle, req->pipeHandle)) {
if (uv_set_pipe_handle(loop, handle, req->pipeHandle)) {
CloseHandle(req->pipeHandle);
req->pipeHandle = INVALID_HANDLE_VALUE;
SET_REQ_ERROR(req, GetLastError());
uv_insert_pending_req((uv_req_t*) req);
uv_insert_pending_req(loop, (uv_req_t*) req);
handle->reqs_pending++;
return;
}
@@ -541,7 +547,8 @@ static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL
/* Prepare the overlapped structure. */
memset(&(req->overlapped), 0, sizeof(req->overlapped));
if (!ConnectNamedPipe(req->pipeHandle, &req->overlapped) && GetLastError() != ERROR_IO_PENDING) {
if (!ConnectNamedPipe(req->pipeHandle, &req->overlapped) &&
GetLastError() != ERROR_IO_PENDING) {
if (GetLastError() == ERROR_PIPE_CONNECTED) {
SET_REQ_SUCCESS(req);
} else {
@@ -550,7 +557,7 @@ static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL
/* Make this req pending reporting an error. */
SET_REQ_ERROR(req, GetLastError());
}
uv_insert_pending_req((uv_req_t*) req);
uv_insert_pending_req(loop, (uv_req_t*) req);
handle->reqs_pending++;
return;
}
@@ -560,12 +567,14 @@ static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL
int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client) {
/* Find a connection instance that has been connected, but not yet accepted. */
uv_loop_t* loop = server->loop;
/* Find a connection instance that has been connected, but not yet */
/* accepted. */
uv_pipe_accept_t* req = server->pending_accepts;
if (!req) {
/* No valid connections found, so we error out. */
uv_set_sys_error(WSAEWOULDBLOCK);
uv_set_sys_error(loop, WSAEWOULDBLOCK);
return -1;
}
@@ -580,7 +589,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client) {
if (!(server->flags & UV_HANDLE_CLOSING) &&
!(server->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
uv_pipe_queue_accept(server, req, FALSE);
uv_pipe_queue_accept(loop, server, req, FALSE);
}
return 0;
@@ -589,25 +598,27 @@ int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client) {
/* Starts listening for connections for the given pipe. */
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
uv_loop_t* loop = handle->loop;
int i, errno;
uv_pipe_accept_t* req;
HANDLE pipeHandle;
if (!(handle->flags & UV_HANDLE_BOUND) &&
!(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
uv_set_error(UV_EINVAL, 0);
uv_set_error(loop, UV_EINVAL, 0);
return -1;
}
if (handle->flags & UV_HANDLE_LISTENING ||
handle->flags & UV_HANDLE_READING) {
uv_set_error(UV_EALREADY, 0);
uv_set_error(loop, UV_EALREADY, 0);
return -1;
}
if (!(handle->flags & UV_HANDLE_PIPESERVER) &&
!(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
uv_set_error(UV_ENOTSUP, 0);
uv_set_error(loop, UV_ENOTSUP, 0);
return -1;
}
@@ -619,24 +630,24 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
pipeHandle = handle->handle;
assert(pipeHandle != INVALID_HANDLE_VALUE);
req = &handle->accept_reqs[0];
uv_req_init((uv_req_t*) req);
uv_req_init(loop, (uv_req_t*) req);
req->pipeHandle = pipeHandle;
req->type = UV_ACCEPT;
req->data = handle;
req->next_pending = NULL;
if (uv_set_pipe_handle(handle, pipeHandle)) {
uv_set_sys_error(GetLastError());
if (uv_set_pipe_handle(loop, handle, pipeHandle)) {
uv_set_sys_error(loop, GetLastError());
return -1;
}
uv_pipe_queue_accept(handle, req, TRUE);
uv_pipe_queue_accept(loop, handle, req, TRUE);
} else {
/* First pipe handle should have already been created in uv_pipe_bind */
assert(handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE);
for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
uv_pipe_queue_accept(handle, &handle->accept_reqs[i], i == 0);
uv_pipe_queue_accept(loop, handle, &handle->accept_reqs[i], i == 0);
}
}
@@ -644,7 +655,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
}
static void uv_pipe_queue_read(uv_pipe_t* handle) {
static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
uv_req_t* req;
int result;
@@ -666,7 +677,7 @@ static void uv_pipe_queue_read(uv_pipe_t* handle) {
if (!result && GetLastError() != ERROR_IO_PENDING) {
/* Make this req pending reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req(req);
uv_insert_pending_req(loop, req);
handle->reqs_pending++;
return;
}
@@ -679,19 +690,22 @@ static void uv_pipe_queue_read(uv_pipe_t* handle) {
}
int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv_set_error(UV_EINVAL, 0);
uv_set_error(loop, UV_EINVAL, 0);
return -1;
}
if (handle->flags & UV_HANDLE_READING) {
uv_set_error(UV_EALREADY, 0);
uv_set_error(loop, UV_EALREADY, 0);
return -1;
}
if (handle->flags & UV_HANDLE_EOF) {
uv_set_error(UV_EOF, 0);
uv_set_error(loop, UV_EOF, 0);
return -1;
}
@@ -702,34 +716,34 @@ int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_
/* If reading was stopped and then started again, there could stell be a */
/* read request pending. */
if (!(handle->flags & UV_HANDLE_READ_PENDING))
uv_pipe_queue_read(handle);
uv_pipe_queue_read(loop, handle);
return 0;
}
int uv_pipe_write(uv_write_t* req, uv_pipe_t* handle, uv_buf_t bufs[], int bufcnt,
uv_write_cb cb) {
int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
uv_buf_t bufs[], int bufcnt, uv_write_cb cb) {
int result;
if (bufcnt != 1) {
uv_set_error(UV_ENOTSUP, 0);
uv_set_error(loop, UV_ENOTSUP, 0);
return -1;
}
assert(handle->handle != INVALID_HANDLE_VALUE);
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv_set_error(UV_EINVAL, 0);
uv_set_error(loop, UV_EINVAL, 0);
return -1;
}
if (handle->flags & UV_HANDLE_SHUTTING) {
uv_set_error(UV_EOF, 0);
uv_set_error(loop, UV_EOF, 0);
return -1;
}
uv_req_init((uv_req_t*) req);
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_WRITE;
req->handle = (uv_stream_t*) handle;
req->cb = cb;
@@ -742,7 +756,7 @@ int uv_pipe_write(uv_write_t* req, uv_pipe_t* handle, uv_buf_t bufs[], int bufcn
&req->overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
return -1;
}
@@ -762,7 +776,8 @@ int uv_pipe_write(uv_write_t* req, uv_pipe_t* handle, uv_buf_t bufs[], int bufcn
}
static void uv_pipe_read_eof(uv_pipe_t* handle, uv_buf_t buf) {
static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle,
uv_buf_t buf) {
/* If there is an eof timer running, we don't need it any more, */
/* so discard it. */
eof_timer_destroy(handle);
@@ -770,33 +785,36 @@ static void uv_pipe_read_eof(uv_pipe_t* handle, uv_buf_t buf) {
handle->flags |= UV_HANDLE_EOF;
uv_read_stop((uv_stream_t*) handle);
uv_set_error(UV_EOF, 0);
uv_set_error(loop, UV_EOF, 0);
handle->read_cb((uv_stream_t*) handle, -1, uv_null_buf_);
}
static void uv_pipe_read_error(uv_pipe_t* handle, int error, uv_buf_t buf) {
static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error,
uv_buf_t buf) {
/* If there is an eof timer running, we don't need it any more, */
/* so discard it. */
eof_timer_destroy(handle);
uv_read_stop((uv_stream_t*) handle);
uv_set_sys_error(error);
uv_set_sys_error(loop, error);
handle->read_cb((uv_stream_t*)handle, -1, buf);
}
static void uv_pipe_read_error_or_eof(uv_pipe_t* handle, int error, uv_buf_t buf) {
static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle,
int error, uv_buf_t buf) {
if (error == ERROR_BROKEN_PIPE) {
uv_pipe_read_eof(handle, buf);
uv_pipe_read_eof(loop, handle, buf);
} else {
uv_pipe_read_error(handle, error, buf);
uv_pipe_read_error(loop, handle, error, buf);
}
}
void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_req_t* req) {
DWORD bytes, avail;
uv_buf_t buf;
@@ -808,7 +826,10 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
if (!REQ_SUCCESS(req)) {
/* An error occurred doing the 0-read. */
if (handle->flags & UV_HANDLE_READING) {
uv_pipe_read_error_or_eof(handle, GET_REQ_ERROR(req), uv_null_buf_);
uv_pipe_read_error_or_eof(loop,
handle,
GET_REQ_ERROR(req),
uv_null_buf_);
}
} else {
/* Do non-blocking reads until the buffer is empty */
@@ -819,7 +840,7 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
NULL,
&avail,
NULL)) {
uv_pipe_read_error_or_eof(handle, GetLastError(), uv_null_buf_);
uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_);
break;
}
@@ -843,7 +864,7 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
break;
}
} else {
uv_pipe_read_error_or_eof(handle, GetLastError(), uv_null_buf_);
uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_);
break;
}
}
@@ -851,7 +872,7 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
/* Post another 0-read if still reading and not closing. */
if ((handle->flags & UV_HANDLE_READING) &&
!(handle->flags & UV_HANDLE_READ_PENDING)) {
uv_pipe_queue_read(handle);
uv_pipe_queue_read(loop, handle);
}
}
@@ -859,14 +880,15 @@ void uv_process_pipe_read_req(uv_pipe_t* handle, uv_req_t* req) {
}
void uv_process_pipe_write_req(uv_pipe_t* handle, uv_write_t* req) {
void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_write_t* req) {
assert(handle->type == UV_NAMED_PIPE);
handle->write_queue_size -= req->queued_bytes;
if (req->cb) {
if (!REQ_SUCCESS(req)) {
LOOP->last_error = GET_REQ_UV_ERROR(req);
loop->last_error = GET_REQ_UV_ERROR(req);
((uv_write_cb)req->cb)(req, -1);
} else {
((uv_write_cb)req->cb)(req, 0);
@@ -876,14 +898,15 @@ void uv_process_pipe_write_req(uv_pipe_t* handle, uv_write_t* req) {
handle->write_reqs_pending--;
if (handle->write_reqs_pending == 0 &&
handle->flags & UV_HANDLE_SHUTTING) {
uv_want_endgame((uv_handle_t*)handle);
uv_want_endgame(loop, (uv_handle_t*)handle);
}
DECREASE_PENDING_REQ_COUNT(handle);
}
void uv_process_pipe_accept_req(uv_pipe_t* handle, uv_req_t* raw_req) {
void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_req_t* raw_req) {
uv_pipe_accept_t* req = (uv_pipe_accept_t*) raw_req;
assert(handle->type == UV_NAMED_PIPE);
@@ -903,7 +926,7 @@ void uv_process_pipe_accept_req(uv_pipe_t* handle, uv_req_t* raw_req) {
}
if (!(handle->flags & UV_HANDLE_CLOSING) &&
!(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
uv_pipe_queue_accept(handle, req, FALSE);
uv_pipe_queue_accept(loop, handle, req, FALSE);
}
}
@@ -911,7 +934,8 @@ void uv_process_pipe_accept_req(uv_pipe_t* handle, uv_req_t* raw_req) {
}
void uv_process_pipe_connect_req(uv_pipe_t* handle, uv_connect_t* req) {
void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_connect_t* req) {
assert(handle->type == UV_NAMED_PIPE);
if (req->cb) {
@@ -919,7 +943,7 @@ void uv_process_pipe_connect_req(uv_pipe_t* handle, uv_connect_t* req) {
uv_pipe_connection_init(handle);
((uv_connect_cb)req->cb)(req, 0);
} else {
LOOP->last_error = GET_REQ_UV_ERROR(req);
loop->last_error = GET_REQ_UV_ERROR(req);
((uv_connect_cb)req->cb)(req, -1);
}
}
@@ -928,7 +952,8 @@ void uv_process_pipe_connect_req(uv_pipe_t* handle, uv_connect_t* req) {
}
void uv_process_pipe_shutdown_req(uv_pipe_t* handle, uv_shutdown_t* req) {
void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_shutdown_t* req) {
assert(handle->type == UV_NAMED_PIPE);
/* Initialize and optionally start the eof timer. */
@@ -959,7 +984,7 @@ static void eof_timer_init(uv_pipe_t* pipe) {
pipe->eof_timer = (uv_timer_t*) malloc(sizeof *pipe->eof_timer);
r = uv_timer_init(pipe->eof_timer);
r = uv_timer_init(pipe->loop, pipe->eof_timer);
assert(r == 0); /* timers can't fail */
pipe->eof_timer->data = pipe;
}
@@ -985,6 +1010,7 @@ static void eof_timer_stop(uv_pipe_t* pipe) {
static void eof_timer_cb(uv_timer_t* timer, int status) {
uv_pipe_t* pipe = (uv_pipe_t*) timer->data;
uv_loop_t* loop = timer->loop;
assert(status == 0); /* timers can't fail */
assert(pipe->type == UV_NAMED_PIPE);
@@ -1015,7 +1041,7 @@ static void eof_timer_cb(uv_timer_t* timer, int status) {
/* Report the eof and update flags. This will get reported even if the */
/* user stopped reading in the meantime. TODO: is that okay? */
uv_pipe_read_eof(pipe, uv_null_buf_);
uv_pipe_read_eof(loop, pipe, uv_null_buf_);
}
+72 -39
View File
@@ -45,14 +45,15 @@ typedef struct env_var {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); \
} \
if (!uv_utf8_to_utf16(s, t, size / sizeof(wchar_t))) { \
uv_set_sys_error(GetLastError()); \
uv_set_sys_error(loop, GetLastError()); \
err = -1; \
goto done; \
}
static void uv_process_init(uv_process_t* handle) {
static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
handle->type = UV_PROCESS;
handle->loop = loop;
handle->flags = 0;
handle->exit_cb = NULL;
handle->pid = 0;
@@ -67,17 +68,17 @@ static void uv_process_init(uv_process_t* handle) {
handle->stdio_pipes[2].server_pipe = NULL;
handle->stdio_pipes[2].child_pipe = INVALID_HANDLE_VALUE;
uv_req_init((uv_req_t*)&handle->exit_req);
uv_req_init(loop, (uv_req_t*)&handle->exit_req);
handle->exit_req.type = UV_PROCESS_EXIT;
handle->exit_req.data = handle;
uv_req_init((uv_req_t*)&handle->close_req);
uv_req_init(loop, (uv_req_t*)&handle->close_req);
handle->close_req.type = UV_PROCESS_CLOSE;
handle->close_req.data = handle;
uv_counters()->handle_init++;
uv_counters()->process_init++;
loop->counters.handle_init++;
loop->counters.process_init++;
uv_ref();
uv_ref(loop);
}
@@ -122,8 +123,8 @@ static wchar_t* search_path_join_test(const wchar_t* dir,
}
/* Allocate buffer for output */
result = result_pos =
(wchar_t*)malloc(sizeof(wchar_t) * (cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1));
result = result_pos = (wchar_t*)malloc(sizeof(wchar_t) *
(cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1));
/* Copy cwd */
wcsncpy(result_pos, cwd, cwd_len);
@@ -280,7 +281,8 @@ static wchar_t* search_path(const wchar_t *file,
return NULL;
}
/* Find the start of the filename so we can split the directory from the name */
/* Find the start of the filename so we can split the directory from the */
/* name. */
for (file_name_start = (wchar_t*)file + file_len;
file_name_start > file
&& file_name_start[-1] != L'\\'
@@ -489,7 +491,8 @@ error:
* issues associated with that solution; this is the caller's
* char**, and modifying it is rude.
*/
static void check_required_vars_contains_var(env_var_t* required, int size, const char* var) {
static void check_required_vars_contains_var(env_var_t* required, int size,
const char* var) {
int i;
for (i = 0; i < size; ++i) {
if (_strnicmp(required[i].narrow, var, required[i].len) == 0) {
@@ -527,7 +530,9 @@ wchar_t* make_program_env(char** env_block) {
};
for (env = env_block; *env; env++) {
check_required_vars_contains_var(required_vars, COUNTOF(required_vars), *env);
check_required_vars_contains_var(required_vars,
COUNTOF(required_vars),
*env);
env_len += (uv_utf8_to_utf16(*env, NULL, 0) * sizeof(wchar_t));
}
@@ -563,7 +568,9 @@ wchar_t* make_program_env(char** env_block) {
wcscpy(ptr, required_vars[i].wide);
ptr += required_vars[i].len - 1;
*ptr++ = L'=';
var_size = GetEnvironmentVariableW(required_vars[i].wide, ptr, required_vars[i].value_len);
var_size = GetEnvironmentVariableW(required_vars[i].wide,
ptr,
required_vars[i].value_len);
if (var_size == 0) {
uv_fatal_error(GetLastError(), "GetEnvironmentVariableW");
}
@@ -582,12 +589,13 @@ wchar_t* make_program_env(char** env_block) {
*/
static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) {
uv_process_t* process = (uv_process_t*)data;
uv_loop_t* loop = process->loop;
assert(didTimeout == FALSE);
assert(process);
/* Post completed */
POST_COMPLETION_FOR_REQ(&process->exit_req);
POST_COMPLETION_FOR_REQ(loop, &process->exit_req);
}
@@ -597,12 +605,13 @@ static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) {
*/
static void CALLBACK close_wait_callback(void* data, BOOLEAN didTimeout) {
uv_process_t* process = (uv_process_t*)data;
uv_loop_t* loop = process->loop;
assert(didTimeout == FALSE);
assert(process);
/* Post completed */
POST_COMPLETION_FOR_REQ(&process->close_req);
POST_COMPLETION_FOR_REQ(loop, &process->close_req);
}
@@ -615,6 +624,7 @@ static DWORD WINAPI spawn_failure(void* data) {
char syscall[] = "CreateProcessW: ";
char unknown[] = "unknown error\n";
uv_process_t* process = (uv_process_t*) data;
uv_loop_t* loop = process->loop;
HANDLE child_stderr = process->stdio_pipes[2].child_pipe;
char* buf = NULL;
DWORD count, written;
@@ -641,14 +651,14 @@ static DWORD WINAPI spawn_failure(void* data) {
FlushFileBuffers(child_stderr);
/* Post completed */
POST_COMPLETION_FOR_REQ(&process->exit_req);
POST_COMPLETION_FOR_REQ(loop, &process->exit_req);
return 0;
}
/* Called on main thread after a child process has exited. */
void uv_process_proc_exit(uv_process_t* handle) {
void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
int i;
DWORD exit_code;
@@ -688,12 +698,12 @@ void uv_process_proc_exit(uv_process_t* handle) {
/* Called on main thread after UnregisterWaitEx finishes. */
void uv_process_proc_close(uv_process_t* handle) {
uv_want_endgame((uv_handle_t*)handle);
void uv_process_proc_close(uv_loop_t* loop, uv_process_t* handle) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
void uv_process_endgame(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;
@@ -702,12 +712,12 @@ void uv_process_endgame(uv_process_t* handle) {
handle->close_cb((uv_handle_t*)handle);
}
uv_unref();
uv_unref(loop);
}
}
void uv_process_close(uv_process_t* handle) {
void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
if (handle->wait_handle != INVALID_HANDLE_VALUE) {
handle->close_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
UnregisterWaitEx(handle->wait_handle, handle->close_handle);
@@ -717,25 +727,30 @@ void uv_process_close(uv_process_t* handle) {
close_wait_callback, (void*)handle, INFINITE,
WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
} else {
uv_want_endgame((uv_handle_t*)handle);
uv_want_endgame(loop, (uv_handle_t*)handle);
}
}
static int uv_create_stdio_pipe_pair(uv_pipe_t* server_pipe, HANDLE* child_pipe, DWORD server_access, DWORD child_access) {
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) {
int err;
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
char pipe_name[64];
DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
if (server_pipe->type != UV_NAMED_PIPE) {
uv_set_error(UV_EINVAL, 0);
uv_set_error(loop, UV_EINVAL, 0);
err = -1;
goto done;
}
/* Create server pipe handle. */
err = uv_stdio_pipe_server(server_pipe, server_access, pipe_name, sizeof(pipe_name));
err = uv_stdio_pipe_server(loop,
server_pipe,
server_access,
pipe_name,
sizeof(pipe_name));
if (err) {
goto done;
}
@@ -750,13 +765,13 @@ static int uv_create_stdio_pipe_pair(uv_pipe_t* server_pipe, HANDLE* child_pipe,
NULL);
if (*child_pipe == INVALID_HANDLE_VALUE) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
err = -1;
goto done;
}
if (!SetNamedPipeHandleState(*child_pipe, &mode, NULL, NULL)) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
err = -1;
goto done;
}
@@ -766,7 +781,7 @@ static int uv_create_stdio_pipe_pair(uv_pipe_t* server_pipe, HANDLE* child_pipe,
*/
if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
if (GetLastError() != ERROR_PIPE_CONNECTED) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
err = -1;
goto done;
}
@@ -790,19 +805,22 @@ done:
}
int uv_spawn(uv_process_t* process, uv_process_options_t options) {
int uv_spawn(uv_loop_t* loop, uv_process_t* process,
uv_process_options_t options) {
int err = 0, i;
wchar_t* path;
int size;
BOOL result;
wchar_t* application_path, *application, *arguments, *env, *cwd;
STARTUPINFOW startup;
PROCESS_INFORMATION info;
uv_process_init(process);
uv_process_init(loop, process);
process->exit_cb = options.exit_cb;
UTF8_TO_UTF16(options.file, application);
arguments = options.args ? make_program_args(options.args, options.windows_verbatim_arguments) : NULL;
arguments = options.args ? make_program_args(options.args,
options.windows_verbatim_arguments) : NULL;
env = options.env ? make_program_env(options.env) : NULL;
if (options.cwd) {
@@ -816,7 +834,7 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
}
GetCurrentDirectoryW(size, cwd);
} else {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
err = -1;
goto done;
}
@@ -843,7 +861,12 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
/* Create stdio pipes. */
if (options.stdin_stream) {
err = uv_create_stdio_pipe_pair(options.stdin_stream, &process->stdio_pipes[0].child_pipe, PIPE_ACCESS_OUTBOUND, GENERIC_READ | FILE_WRITE_ATTRIBUTES);
err = uv_create_stdio_pipe_pair(
loop,
options.stdin_stream,
&process->stdio_pipes[0].child_pipe,
PIPE_ACCESS_OUTBOUND,
GENERIC_READ | FILE_WRITE_ATTRIBUTES);
if (err) {
goto done;
}
@@ -852,7 +875,11 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
}
if (options.stdout_stream) {
err = uv_create_stdio_pipe_pair(options.stdout_stream, &process->stdio_pipes[1].child_pipe, PIPE_ACCESS_INBOUND, GENERIC_WRITE);
err = uv_create_stdio_pipe_pair(
loop, options.stdout_stream,
&process->stdio_pipes[1].child_pipe,
PIPE_ACCESS_INBOUND,
GENERIC_WRITE);
if (err) {
goto done;
}
@@ -861,7 +888,12 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
}
if (options.stderr_stream) {
err = uv_create_stdio_pipe_pair(options.stderr_stream, &process->stdio_pipes[2].child_pipe, PIPE_ACCESS_INBOUND, GENERIC_WRITE);
err = uv_create_stdio_pipe_pair(
loop,
options.stderr_stream,
&process->stdio_pipes[2].child_pipe,
PIPE_ACCESS_INBOUND,
GENERIC_WRITE);
if (err) {
goto done;
}
@@ -895,9 +927,10 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
process->pid = info.dwProcessId;
/* Setup notifications for when the child process exits. */
if (!RegisterWaitForSingleObject(&process->wait_handle, process->process_handle,
exit_wait_callback, (void*)process, INFINITE,
WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) {
result = RegisterWaitForSingleObject(&process->wait_handle,
process->process_handle, exit_wait_callback, (void*)process, INFINITE,
WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
if (!result) {
uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
}
+41 -34
View File
@@ -26,8 +26,8 @@
#include "internal.h"
void uv_req_init(uv_req_t* req) {
uv_counters()->req_init++;
void uv_req_init(uv_loop_t* loop, uv_req_t* req) {
loop->counters.req_init++;
req->type = UV_UNKNOWN_REQ;
SET_REQ_SUCCESS(req);
}
@@ -38,29 +38,29 @@ uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) {
}
void uv_insert_pending_req(uv_req_t* req) {
void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
req->next_req = NULL;
if (LOOP->pending_reqs_tail) {
req->next_req = LOOP->pending_reqs_tail->next_req;
LOOP->pending_reqs_tail->next_req = req;
LOOP->pending_reqs_tail = req;
if (loop->pending_reqs_tail) {
req->next_req = loop->pending_reqs_tail->next_req;
loop->pending_reqs_tail->next_req = req;
loop->pending_reqs_tail = req;
} else {
req->next_req = req;
LOOP->pending_reqs_tail = req;
loop->pending_reqs_tail = req;
}
}
static uv_req_t* uv_remove_pending_req() {
static uv_req_t* uv_remove_pending_req(uv_loop_t* loop) {
uv_req_t* req;
if (LOOP->pending_reqs_tail) {
req = LOOP->pending_reqs_tail->next_req;
if (loop->pending_reqs_tail) {
req = loop->pending_reqs_tail->next_req;
if (req == LOOP->pending_reqs_tail) {
LOOP->pending_reqs_tail = NULL;
if (req == loop->pending_reqs_tail) {
loop->pending_reqs_tail = NULL;
} else {
LOOP->pending_reqs_tail->next_req = req->next_req;
loop->pending_reqs_tail->next_req = req->next_req;
}
return req;
@@ -72,15 +72,19 @@ static uv_req_t* uv_remove_pending_req() {
}
#define DELEGATE_STREAM_REQ(req, method, handle_at) \
#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \
do { \
switch (((uv_handle_t*) (req)->handle_at)->type) { \
case UV_TCP: \
uv_process_tcp_##method##_req((uv_tcp_t*) ((req)->handle_at), req); \
uv_process_tcp_##method##_req(loop, \
(uv_tcp_t*) ((req)->handle_at), \
req); \
break; \
\
case UV_NAMED_PIPE: \
uv_process_pipe_##method##_req((uv_pipe_t*) ((req)->handle_at), req); \
uv_process_pipe_##method##_req(loop, \
(uv_pipe_t*) ((req)->handle_at), \
req); \
break; \
\
default: \
@@ -89,73 +93,76 @@ static uv_req_t* uv_remove_pending_req() {
} while (0)
void uv_process_reqs() {
void uv_process_reqs(uv_loop_t* loop) {
uv_req_t* req;
while (req = uv_remove_pending_req()) {
while (req = uv_remove_pending_req(loop)) {
switch (req->type) {
case UV_READ:
DELEGATE_STREAM_REQ(req, read, data);
DELEGATE_STREAM_REQ(loop, req, read, data);
break;
case UV_WRITE:
DELEGATE_STREAM_REQ((uv_write_t*) req, write, handle);
DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle);
break;
case UV_ACCEPT:
DELEGATE_STREAM_REQ(req, accept, data);
DELEGATE_STREAM_REQ(loop, req, accept, data);
break;
case UV_CONNECT:
DELEGATE_STREAM_REQ((uv_connect_t*) req, connect, handle);
DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle);
break;
case UV_SHUTDOWN:
/* Tcp shutdown requests don't come here. */
assert(((uv_shutdown_t*) req)->handle->type == UV_NAMED_PIPE);
uv_process_pipe_shutdown_req(
(uv_pipe_t*) ((uv_shutdown_t*) req)->handle, (uv_shutdown_t*) req);
loop,
(uv_pipe_t*) ((uv_shutdown_t*) req)->handle,
(uv_shutdown_t*) req);
break;
case UV_UDP_RECV:
uv_process_udp_recv_req((uv_udp_t*) req->data, req);
uv_process_udp_recv_req(loop, (uv_udp_t*) req->data, req);
break;
case UV_UDP_SEND:
uv_process_udp_send_req(((uv_udp_send_t*) req)->handle,
uv_process_udp_send_req(loop,
((uv_udp_send_t*) req)->handle,
(uv_udp_send_t*) req);
break;
case UV_WAKEUP:
uv_process_async_wakeup_req((uv_async_t*) req->data, req);
uv_process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
break;
case UV_ARES_EVENT_REQ:
uv_process_ares_event_req((uv_ares_action_t*) req->data, req);
uv_process_ares_event_req(loop, (uv_ares_action_t*) req->data, req);
break;
case UV_ARES_CLEANUP_REQ:
uv_process_ares_cleanup_req((uv_ares_task_t*) req->data, req);
uv_process_ares_cleanup_req(loop, (uv_ares_task_t*) req->data, req);
break;
case UV_GETADDRINFO_REQ:
uv_process_getaddrinfo_req((uv_getaddrinfo_t*) req->data, req);
uv_process_getaddrinfo_req(loop, (uv_getaddrinfo_t*) req->data, req);
break;
case UV_PROCESS_EXIT:
uv_process_proc_exit((uv_process_t*) req->data);
uv_process_proc_exit(loop, (uv_process_t*) req->data);
break;
case UV_PROCESS_CLOSE:
uv_process_proc_close((uv_process_t*) req->data);
uv_process_proc_close(loop, (uv_process_t*) req->data);
break;
case UV_FS:
uv_process_fs_req((uv_fs_t*) req);
uv_process_fs_req(loop, (uv_fs_t*) req);
break;
case UV_WORK:
uv_process_work_req((uv_work_t*) req);
uv_process_work_req(loop, (uv_work_t*) req);
break;
default:
+5 -5
View File
@@ -27,7 +27,7 @@
#include "internal.h"
static uv_pipe_t* uv_make_pipe_for_std_handle(HANDLE handle) {
static uv_pipe_t* uv_make_pipe_for_std_handle(uv_loop_t* loop, HANDLE handle) {
uv_pipe_t* pipe = NULL;
pipe = (uv_pipe_t*)malloc(sizeof(uv_pipe_t));
@@ -35,7 +35,7 @@ static uv_pipe_t* uv_make_pipe_for_std_handle(HANDLE handle) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
if (uv_pipe_init_with_handle(pipe, handle)) {
if (uv_pipe_init_with_handle(loop, pipe, handle)) {
free(pipe);
return NULL;
}
@@ -45,7 +45,7 @@ static uv_pipe_t* uv_make_pipe_for_std_handle(HANDLE handle) {
}
uv_stream_t* uv_std_handle(uv_std_type type) {
uv_stream_t* uv_std_handle(uv_loop_t* loop, uv_std_type type) {
HANDLE handle;
switch (type) {
@@ -56,7 +56,7 @@ uv_stream_t* uv_std_handle(uv_std_type type) {
}
/* Assume only named pipes for now. */
return (uv_stream_t*)uv_make_pipe_for_std_handle(handle);
return (uv_stream_t*)uv_make_pipe_for_std_handle(loop, handle);
break;
case UV_STDOUT:
@@ -69,7 +69,7 @@ uv_stream_t* uv_std_handle(uv_std_type type) {
default:
assert(0);
uv_set_error(UV_EINVAL, 0);
uv_set_error(loop, UV_EINVAL, 0);
return NULL;
}
}
+19 -13
View File
@@ -26,14 +26,15 @@
#include "internal.h"
void uv_stream_init(uv_stream_t* handle) {
void uv_stream_init(uv_loop_t* loop, uv_stream_t* handle) {
handle->write_queue_size = 0;
handle->loop = loop;
handle->flags = 0;
uv_counters()->handle_init++;
uv_counters()->stream_init++;
loop->counters.handle_init++;
loop->counters.stream_init++;
uv_ref();
uv_ref(loop);
}
@@ -41,7 +42,7 @@ void uv_connection_init(uv_stream_t* handle) {
handle->flags |= UV_HANDLE_CONNECTION;
handle->write_reqs_pending = 0;
uv_req_init((uv_req_t*) &(handle->read_req));
uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req));
handle->read_req.type = UV_READ;
handle->read_req.data = handle;
}
@@ -75,7 +76,8 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
}
int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb) {
switch (handle->type) {
case UV_TCP:
return uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb);
@@ -97,31 +99,35 @@ int uv_read_stop(uv_stream_t* handle) {
int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
uv_write_cb cb) {
uv_loop_t* loop = handle->loop;
switch (handle->type) {
case UV_TCP:
return uv_tcp_write(req, (uv_tcp_t*) handle, bufs, bufcnt, cb);
return uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, bufcnt, cb);
case UV_NAMED_PIPE:
return uv_pipe_write(req, (uv_pipe_t*) handle, bufs, bufcnt, cb);
return uv_pipe_write(loop, req, (uv_pipe_t*) handle, bufs, bufcnt, cb);
default:
assert(0);
uv_set_sys_error(WSAEINVAL);
uv_set_sys_error(loop, WSAEINVAL);
return -1;
}
}
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv_set_sys_error(WSAEINVAL);
uv_set_sys_error(loop, WSAEINVAL);
return -1;
}
if (handle->flags & UV_HANDLE_SHUTTING) {
uv_set_sys_error(WSAESHUTDOWN);
uv_set_sys_error(loop, WSAESHUTDOWN);
return -1;
}
uv_req_init((uv_req_t*) req);
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_SHUTDOWN;
req->handle = handle;
req->cb = cb;
@@ -130,7 +136,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
handle->shutdown_req = req;
handle->reqs_pending++;
uv_want_endgame((uv_handle_t*)handle);
uv_want_endgame(loop, (uv_handle_t*)handle);
return 0;
}
+113 -81
View File
@@ -46,37 +46,39 @@ static char uv_zero_[] = "";
static unsigned int active_tcp_streams = 0;
static int uv_tcp_set_socket(uv_tcp_t* handle, SOCKET socket) {
static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
SOCKET socket) {
DWORD yes = 1;
assert(handle->socket == INVALID_SOCKET);
/* Set the socket to nonblocking mode */
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
/* Make the socket non-inheritable */
if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
return -1;
}
/* Associate it with the I/O completion port. */
/* Use uv_handle_t pointer as completion key. */
if (CreateIoCompletionPort((HANDLE)socket,
LOOP->iocp,
loop->iocp,
(ULONG_PTR)socket,
0) == NULL) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
return -1;
}
if (pSetFileCompletionNotificationModes) {
if (!pSetFileCompletionNotificationModes((HANDLE)socket, FILE_SKIP_SET_EVENT_ON_HANDLE |
FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
uv_set_sys_error(GetLastError());
if (!pSetFileCompletionNotificationModes((HANDLE) socket,
FILE_SKIP_SET_EVENT_ON_HANDLE |
FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
uv_set_sys_error(loop, GetLastError());
return -1;
}
@@ -89,8 +91,8 @@ static int uv_tcp_set_socket(uv_tcp_t* handle, SOCKET socket) {
}
int uv_tcp_init(uv_tcp_t* handle) {
uv_stream_init((uv_stream_t*)handle);
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
uv_stream_init(loop, (uv_stream_t*)handle);
handle->accept_reqs = NULL;
handle->pending_accepts = NULL;
@@ -98,13 +100,13 @@ int uv_tcp_init(uv_tcp_t* handle) {
handle->type = UV_TCP;
handle->reqs_pending = 0;
uv_counters()->tcp_init++;
loop->counters.tcp_init++;
return 0;
}
void uv_tcp_endgame(uv_tcp_t* handle) {
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
uv_err_t err;
int status;
@@ -122,7 +124,7 @@ void uv_tcp_endgame(uv_tcp_t* handle) {
}
if (handle->shutdown_req->cb) {
if (status == -1) {
LOOP->last_error = err;
loop->last_error = err;
}
handle->shutdown_req->cb(handle->shutdown_req, status);
}
@@ -145,12 +147,13 @@ void uv_tcp_endgame(uv_tcp_t* handle) {
active_tcp_streams--;
uv_unref();
uv_unref(loop);
}
}
static int uv__bind(uv_tcp_t* handle, int domain, struct sockaddr* addr, int addrsize) {
static int uv__bind(uv_loop_t* loop, uv_tcp_t* handle, int domain,
struct sockaddr* addr, int addrsize) {
DWORD err;
int r;
SOCKET sock;
@@ -158,11 +161,11 @@ static int uv__bind(uv_tcp_t* handle, int domain, struct sockaddr* addr, int add
if (handle->socket == INVALID_SOCKET) {
sock = socket(domain, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
if (uv_tcp_set_socket(handle, sock) == -1) {
if (uv_tcp_set_socket(loop, handle, sock) == -1) {
closesocket(sock);
return -1;
}
@@ -177,7 +180,7 @@ static int uv__bind(uv_tcp_t* handle, int domain, struct sockaddr* addr, int add
handle->bind_error = uv_new_sys_error(err);
handle->flags |= UV_HANDLE_BIND_ERROR;
} else {
uv_set_sys_error(err);
uv_set_sys_error(loop, err);
return -1;
}
}
@@ -189,31 +192,46 @@ static int uv__bind(uv_tcp_t* handle, int domain, struct sockaddr* addr, int add
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) {
uv_loop_t* loop = handle->loop;
if (addr.sin_family != AF_INET) {
uv_set_sys_error(WSAEFAULT);
uv_set_sys_error(loop, WSAEFAULT);
return -1;
}
return uv__bind(handle, AF_INET, (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
return uv__bind(loop,
handle,
AF_INET,
(struct sockaddr*)&addr,
sizeof(struct sockaddr_in));
}
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
uv_loop_t* loop = handle->loop;
if (addr.sin6_family != AF_INET6) {
uv_set_sys_error(WSAEFAULT);
uv_set_sys_error(loop, WSAEFAULT);
return -1;
}
if (uv_allow_ipv6) {
handle->flags |= UV_HANDLE_IPV6;
return uv__bind(handle, AF_INET6, (struct sockaddr*)&addr, sizeof(struct sockaddr_in6));
return uv__bind(loop,
handle,
AF_INET6,
(struct sockaddr*)&addr,
sizeof(struct sockaddr_in6));
} else {
uv_new_sys_error(WSAEAFNOSUPPORT);
uv_set_sys_error(loop, WSAEAFNOSUPPORT);
return -1;
}
}
static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
uv_loop_t* loop = handle->loop;
BOOL success;
DWORD bytes;
SOCKET accept_socket;
@@ -236,7 +254,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
accept_socket = socket(family, SOCK_STREAM, 0);
if (accept_socket == INVALID_SOCKET) {
SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req((uv_req_t*)req);
uv_insert_pending_req(loop, (uv_req_t*)req);
handle->reqs_pending++;
return;
}
@@ -257,7 +275,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
/* Process the req without IOCP. */
req->accept_socket = accept_socket;
handle->reqs_pending++;
uv_insert_pending_req((uv_req_t*)req);
uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(success)) {
/* The req will be processed with IOCP. */
req->accept_socket = accept_socket;
@@ -265,7 +283,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
} else {
/* Make this req pending reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req((uv_req_t*)req);
uv_insert_pending_req(loop, (uv_req_t*)req);
handle->reqs_pending++;
/* Destroy the preallocated client socket. */
closesocket(accept_socket);
@@ -273,7 +291,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
}
static void uv_tcp_queue_read(uv_tcp_t* handle) {
static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
uv_req_t* req;
uv_buf_t buf;
int result;
@@ -314,7 +332,7 @@ static void uv_tcp_queue_read(uv_tcp_t* handle) {
handle->flags |= UV_HANDLE_READ_PENDING;
req->overlapped.InternalHigh = bytes;
handle->reqs_pending++;
uv_insert_pending_req(req);
uv_insert_pending_req(loop, req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* The req will be processed with IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING;
@@ -322,27 +340,28 @@ static void uv_tcp_queue_read(uv_tcp_t* handle) {
} else {
/* Make this req pending reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req(req);
uv_insert_pending_req(loop, req);
handle->reqs_pending++;
}
}
int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
uv_loop_t* loop = handle->loop;
unsigned int i;
uv_tcp_accept_t* req;
assert(backlog > 0);
if (handle->flags & UV_HANDLE_BIND_ERROR) {
LOOP->last_error = handle->bind_error;
loop->last_error = handle->bind_error;
return -1;
}
if (handle->flags & UV_HANDLE_LISTENING ||
handle->flags & UV_HANDLE_READING) {
/* Already listening. */
uv_set_sys_error(WSAEALREADY);
uv_set_sys_error(loop, WSAEALREADY);
return -1;
}
@@ -351,7 +370,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
return -1;
if (listen(handle->socket, backlog) == SOCKET_ERROR) {
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
@@ -367,7 +386,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
for (i = 0; i < uv_simultaneous_server_accepts; i++) {
req = &handle->accept_reqs[i];
uv_req_init((uv_req_t*)req);
uv_req_init(loop, (uv_req_t*)req);
req->type = UV_ACCEPT;
req->accept_socket = INVALID_SOCKET;
req->data = handle;
@@ -379,26 +398,27 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
uv_loop_t* loop = server->loop;
int rv = 0;
uv_tcp_accept_t* req = server->pending_accepts;
if (!req) {
/* No valid connections found, so we error out. */
uv_set_sys_error(WSAEWOULDBLOCK);
uv_set_sys_error(loop, WSAEWOULDBLOCK);
return -1;
}
if (req->accept_socket == INVALID_SOCKET) {
uv_set_sys_error(WSAENOTCONN);
uv_set_sys_error(loop, WSAENOTCONN);
return -1;
}
if (uv_tcp_set_socket(client, req->accept_socket) == -1) {
if (uv_tcp_set_socket(client->loop, client, req->accept_socket) == -1) {
closesocket(req->accept_socket);
rv = -1;
} else {
uv_connection_init((uv_stream_t*)client);
uv_connection_init((uv_stream_t*) client);
}
/* Prepare the req to pick up a new connection */
@@ -416,19 +436,22 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
}
int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv_set_sys_error(WSAEINVAL);
uv_set_sys_error(loop, WSAEINVAL);
return -1;
}
if (handle->flags & UV_HANDLE_READING) {
uv_set_sys_error(WSAEALREADY);
uv_set_sys_error(loop, WSAEALREADY);
return -1;
}
if (handle->flags & UV_HANDLE_EOF) {
uv_set_sys_error(WSAESHUTDOWN);
uv_set_sys_error(loop, WSAESHUTDOWN);
return -1;
}
@@ -439,7 +462,7 @@ int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb
/* If reading was stopped and then started again, there could stell be a */
/* read request pending. */
if (!(handle->flags & UV_HANDLE_READ_PENDING))
uv_tcp_queue_read(handle);
uv_tcp_queue_read(loop, handle);
return 0;
}
@@ -447,17 +470,18 @@ int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb
int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
struct sockaddr_in address, uv_connect_cb cb) {
uv_loop_t* loop = handle->loop;
int addrsize = sizeof(struct sockaddr_in);
BOOL success;
DWORD bytes;
if (handle->flags & UV_HANDLE_BIND_ERROR) {
LOOP->last_error = handle->bind_error;
loop->last_error = handle->bind_error;
return -1;
}
if (address.sin_family != AF_INET) {
uv_set_sys_error(WSAEFAULT);
uv_set_sys_error(loop, WSAEFAULT);
return -1;
}
@@ -465,7 +489,7 @@ int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
uv_tcp_bind(handle, uv_addr_ip4_any_) < 0)
return -1;
uv_req_init((uv_req_t*) req);
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_CONNECT;
req->handle = (uv_stream_t*) handle;
req->cb = cb;
@@ -482,12 +506,12 @@ int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
/* Process the req without IOCP. */
handle->reqs_pending++;
uv_insert_pending_req((uv_req_t*)req);
uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(success)) {
/* The req will be processed with IOCP. */
handle->reqs_pending++;
} else {
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
@@ -497,6 +521,7 @@ int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
struct sockaddr_in6 address, uv_connect_cb cb) {
uv_loop_t* loop = handle->loop;
int addrsize = sizeof(struct sockaddr_in6);
BOOL success;
DWORD bytes;
@@ -507,12 +532,12 @@ int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
}
if (handle->flags & UV_HANDLE_BIND_ERROR) {
LOOP->last_error = handle->bind_error;
loop->last_error = handle->bind_error;
return -1;
}
if (address.sin6_family != AF_INET6) {
uv_set_sys_error(WSAEFAULT);
uv_set_sys_error(loop, WSAEFAULT);
return -1;
}
@@ -520,7 +545,7 @@ int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
uv_tcp_bind6(handle, uv_addr_ip6_any_) < 0)
return -1;
uv_req_init((uv_req_t*) req);
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_CONNECT;
req->handle = (uv_stream_t*) handle;
req->cb = cb;
@@ -536,11 +561,11 @@ int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
handle->reqs_pending++;
uv_insert_pending_req((uv_req_t*)req);
uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(success)) {
handle->reqs_pending++;
} else {
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
@@ -548,17 +573,18 @@ int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
}
int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen) {
int uv_tcp_getsockname(uv_loop_t* loop, uv_tcp_t* handle,
struct sockaddr* name, int* namelen) {
int result;
if (handle->flags & UV_HANDLE_SHUTTING) {
uv_set_sys_error(WSAESHUTDOWN);
uv_set_sys_error(loop, WSAESHUTDOWN);
return -1;
}
result = getsockname(handle->socket, name, namelen);
if (result != 0) {
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
@@ -566,22 +592,22 @@ int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen) {
}
int uv_tcp_write(uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[], int bufcnt,
uv_write_cb cb) {
int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
uv_buf_t bufs[], int bufcnt, uv_write_cb cb) {
int result;
DWORD bytes;
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
uv_set_sys_error(WSAEINVAL);
uv_set_sys_error(loop, WSAEINVAL);
return -1;
}
if (handle->flags & UV_HANDLE_SHUTTING) {
uv_set_sys_error(WSAESHUTDOWN);
uv_set_sys_error(loop, WSAESHUTDOWN);
return -1;
}
uv_req_init((uv_req_t*) req);
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_WRITE;
req->handle = (uv_stream_t*) handle;
req->cb = cb;
@@ -600,7 +626,7 @@ int uv_tcp_write(uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[], int bufcnt,
req->queued_bytes = 0;
handle->reqs_pending++;
handle->write_reqs_pending++;
uv_insert_pending_req((uv_req_t*)req);
uv_insert_pending_req(loop, (uv_req_t*) req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* Request queued by the kernel. */
req->queued_bytes = uv_count_bufs(bufs, bufcnt);
@@ -609,7 +635,7 @@ int uv_tcp_write(uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[], int bufcnt,
handle->write_queue_size += req->queued_bytes;
} else {
/* Send failed due to an error. */
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
@@ -617,7 +643,8 @@ int uv_tcp_write(uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[], int bufcnt,
}
void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) {
void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_req_t* req) {
DWORD bytes, flags, err;
uv_buf_t buf;
@@ -629,7 +656,7 @@ void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) {
/* An error occurred doing the read. */
if ((handle->flags & UV_HANDLE_READING)) {
handle->flags &= ~UV_HANDLE_READING;
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req);
loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
uv_buf_init(NULL, 0) : handle->read_buffer;
handle->read_cb((uv_stream_t*)handle, -1, buf);
@@ -639,7 +666,9 @@ void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) {
/* The read was done with a non-zero buffer length. */
if (req->overlapped.InternalHigh > 0) {
/* Successful read */
handle->read_cb((uv_stream_t*)handle, req->overlapped.InternalHigh, handle->read_buffer);
handle->read_cb((uv_stream_t*)handle,
req->overlapped.InternalHigh,
handle->read_buffer);
/* Read again only if bytes == buf.len */
if (req->overlapped.InternalHigh < handle->read_buffer.len) {
goto done;
@@ -648,8 +677,8 @@ void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) {
/* Connection closed */
handle->flags &= ~UV_HANDLE_READING;
handle->flags |= UV_HANDLE_EOF;
LOOP->last_error.code = UV_EOF;
LOOP->last_error.sys_errno_ = ERROR_SUCCESS;
loop->last_error.code = UV_EOF;
loop->last_error.sys_errno_ = ERROR_SUCCESS;
buf.base = 0;
buf.len = 0;
handle->read_cb((uv_stream_t*)handle, -1, handle->read_buffer);
@@ -680,8 +709,8 @@ void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) {
/* Connection closed */
handle->flags &= ~UV_HANDLE_READING;
handle->flags |= UV_HANDLE_EOF;
LOOP->last_error.code = UV_EOF;
LOOP->last_error.sys_errno_ = ERROR_SUCCESS;
loop->last_error.code = UV_EOF;
loop->last_error.sys_errno_ = ERROR_SUCCESS;
handle->read_cb((uv_stream_t*)handle, -1, buf);
break;
}
@@ -689,11 +718,11 @@ void uv_process_tcp_read_req(uv_tcp_t* handle, uv_req_t* req) {
err = WSAGetLastError();
if (err == WSAEWOULDBLOCK) {
/* Read buffer was completely empty, report a 0-byte read. */
uv_set_sys_error(WSAEWOULDBLOCK);
uv_set_sys_error(loop, WSAEWOULDBLOCK);
handle->read_cb((uv_stream_t*)handle, 0, buf);
} else {
/* Ouch! serious error. */
uv_set_sys_error(err);
uv_set_sys_error(loop, err);
handle->flags &= ~UV_HANDLE_READING;
handle->read_cb((uv_stream_t*)handle, -1, buf);
}
@@ -705,7 +734,7 @@ done:
/* Post another read if still reading and not closing. */
if ((handle->flags & UV_HANDLE_READING) &&
!(handle->flags & UV_HANDLE_READ_PENDING)) {
uv_tcp_queue_read(handle);
uv_tcp_queue_read(loop, handle);
}
}
@@ -713,27 +742,29 @@ done:
}
void uv_process_tcp_write_req(uv_tcp_t* handle, uv_write_t* req) {
void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_write_t* req) {
assert(handle->type == UV_TCP);
handle->write_queue_size -= req->queued_bytes;
if (req->cb) {
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req);
((uv_write_cb)req->cb)(req, LOOP->last_error.code == UV_OK ? 0 : -1);
loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
((uv_write_cb)req->cb)(req, loop->last_error.code == UV_OK ? 0 : -1);
}
handle->write_reqs_pending--;
if (handle->flags & UV_HANDLE_SHUTTING &&
handle->write_reqs_pending == 0) {
uv_want_endgame((uv_handle_t*)handle);
uv_want_endgame(loop, (uv_handle_t*)handle);
}
DECREASE_PENDING_REQ_COUNT(handle);
}
void uv_process_tcp_accept_req(uv_tcp_t* handle, uv_req_t* raw_req) {
void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_req_t* raw_req) {
uv_tcp_accept_t* req = (uv_tcp_accept_t*) raw_req;
assert(handle->type == UV_TCP);
@@ -746,7 +777,7 @@ void uv_process_tcp_accept_req(uv_tcp_t* handle, uv_req_t* raw_req) {
if (handle->flags & UV_HANDLE_LISTENING) {
handle->flags &= ~UV_HANDLE_LISTENING;
if (handle->connection_cb) {
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req);
loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
handle->connection_cb((uv_stream_t*)handle, -1);
}
}
@@ -778,7 +809,8 @@ void uv_process_tcp_accept_req(uv_tcp_t* handle, uv_req_t* raw_req) {
}
void uv_process_tcp_connect_req(uv_tcp_t* handle, uv_connect_t* req) {
void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
uv_connect_t* req) {
assert(handle->type == UV_TCP);
if (req->cb) {
@@ -792,11 +824,11 @@ void uv_process_tcp_connect_req(uv_tcp_t* handle, uv_connect_t* req) {
active_tcp_streams++;
((uv_connect_cb)req->cb)(req, 0);
} else {
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
((uv_connect_cb)req->cb)(req, -1);
}
} else {
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req);
loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
((uv_connect_cb)req->cb)(req, -1);
}
}
+13 -9
View File
@@ -25,9 +25,11 @@
#include "internal.h"
static void uv_work_req_init(uv_work_t* req, uv_work_cb work_cb, uv_after_work_cb after_work_cb) {
uv_req_init((uv_req_t*) req);
static void uv_work_req_init(uv_loop_t* loop, uv_work_t* req,
uv_work_cb work_cb, uv_after_work_cb after_work_cb) {
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_WORK;
req->loop = loop;
req->work_cb = work_cb;
req->after_work_cb = after_work_cb;
memset(&req->overlapped, 0, sizeof(req->overlapped));
@@ -36,6 +38,7 @@ static void uv_work_req_init(uv_work_t* req, uv_work_cb work_cb, uv_after_work_c
static DWORD WINAPI uv_work_thread_proc(void* parameter) {
uv_work_t* req = (uv_work_t*)parameter;
uv_loop_t* loop = req->loop;
assert(req != NULL);
assert(req->type == UV_WORK);
@@ -43,27 +46,28 @@ static DWORD WINAPI uv_work_thread_proc(void* parameter) {
req->work_cb(req);
POST_COMPLETION_FOR_REQ(req);
POST_COMPLETION_FOR_REQ(loop, req);
return 0;
}
int uv_queue_work(uv_work_t* req, uv_work_cb work_cb, uv_after_work_cb after_work_cb) {
uv_work_req_init(req, work_cb, after_work_cb);
int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
uv_after_work_cb after_work_cb) {
uv_work_req_init(loop, req, work_cb, after_work_cb);
if (!QueueUserWorkItem(&uv_work_thread_proc, req, WT_EXECUTELONGFUNCTION)) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
return -1;
}
uv_ref();
uv_ref(loop);
return 0;
}
void uv_process_work_req(uv_work_t* req) {
void uv_process_work_req(uv_loop_t* loop, uv_work_t* req) {
assert(req->after_work_cb);
req->after_work_cb(req);
uv_unref();
uv_unref(loop);
}
+44 -36
View File
@@ -36,12 +36,12 @@ static uint64_t uv_hrtime_frequency_ = 0;
static char uv_hrtime_initialized_ = 0;
void uv_update_time() {
void uv_update_time(uv_loop_t* loop) {
DWORD ticks = GetTickCount();
/* The assumption is made that LARGE_INTEGER.QuadPart has the same type */
/* LOOP->time, which happens to be. Is there any way to assert this? */
LARGE_INTEGER* time = (LARGE_INTEGER*) &LOOP->time;
/* loop->time, which happens to be. Is there any way to assert this? */
LARGE_INTEGER* time = (LARGE_INTEGER*) &loop->time;
/* If the timer has wrapped, add 1 to it's high-order dword. */
/* uv_poll must make sure that the timer can never overflow more than */
@@ -53,11 +53,11 @@ void uv_update_time() {
}
int64_t uv_now() {
return LOOP->time;
int64_t uv_now(uv_loop_t* loop) {
return loop->time;
}
/* TODO: thread safety */
uint64_t uv_hrtime(void) {
LARGE_INTEGER counter;
@@ -68,7 +68,7 @@ uint64_t uv_hrtime(void) {
if (!QueryPerformanceFrequency(&counter)) {
uv_hrtime_frequency_ = 0;
uv_set_sys_error(GetLastError());
/* uv_set_sys_error(loop, GetLastError()); */
return 0;
}
@@ -77,12 +77,12 @@ uint64_t uv_hrtime(void) {
/* If the performance frequency is zero, there's no support. */
if (!uv_hrtime_frequency_) {
uv_set_sys_error(ERROR_NOT_SUPPORTED);
/* uv_set_sys_error(loop, ERROR_NOT_SUPPORTED); */
return 0;
}
if (!QueryPerformanceCounter(&counter)) {
uv_set_sys_error(GetLastError());
/* uv_set_sys_error(loop, GetLastError()); */
return 0;
}
@@ -111,22 +111,23 @@ static int uv_timer_compare(uv_timer_t* a, uv_timer_t* b) {
RB_GENERATE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare);
int uv_timer_init(uv_timer_t* handle) {
uv_counters()->handle_init++;
uv_counters()->timer_init++;
int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
loop->counters.handle_init++;
loop->counters.timer_init++;
handle->type = UV_TIMER;
handle->loop = loop;
handle->flags = 0;
handle->timer_cb = NULL;
handle->repeat = 0;
uv_ref();
uv_ref(loop);
return 0;
}
void uv_timer_endgame(uv_timer_t* handle) {
void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle) {
if (handle->flags & UV_HANDLE_CLOSING) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
handle->flags |= UV_HANDLE_CLOSED;
@@ -135,22 +136,25 @@ void uv_timer_endgame(uv_timer_t* handle) {
handle->close_cb((uv_handle_t*)handle);
}
uv_unref();
uv_unref(loop);
}
}
int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, int64_t timeout, int64_t repeat) {
int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, int64_t timeout,
int64_t repeat) {
uv_loop_t* loop = handle->loop;
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->timer_cb = timer_cb;
handle->due = LOOP->time + timeout;
handle->due = loop->time + timeout;
handle->repeat = repeat;
handle->flags |= UV_HANDLE_ACTIVE;
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");
}
@@ -159,10 +163,12 @@ int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, int64_t timeout, in
int uv_timer_stop(uv_timer_t* handle) {
uv_loop_t* loop = handle->loop;
if (!(handle->flags & UV_HANDLE_ACTIVE))
return 0;
RB_REMOVE(uv_timer_tree_s, &LOOP->timers, handle);
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
handle->flags &= ~UV_HANDLE_ACTIVE;
@@ -171,21 +177,23 @@ int uv_timer_stop(uv_timer_t* handle) {
int uv_timer_again(uv_timer_t* handle) {
uv_loop_t* loop = handle->loop;
/* If timer_cb is NULL that means that the timer was never started. */
if (!handle->timer_cb) {
uv_set_sys_error(ERROR_INVALID_DATA);
uv_set_sys_error(loop, ERROR_INVALID_DATA);
return -1;
}
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;
}
if (handle->repeat) {
handle->due = LOOP->time + handle->repeat;
handle->due = loop->time + handle->repeat;
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");
}
@@ -208,16 +216,16 @@ int64_t uv_timer_get_repeat(uv_timer_t* handle) {
}
DWORD uv_get_poll_timeout() {
DWORD uv_get_poll_timeout(uv_loop_t* loop) {
uv_timer_t* timer;
int64_t delta;
/* Check if there are any running timers */
timer = RB_MIN(uv_timer_tree_s, &LOOP->timers);
timer = RB_MIN(uv_timer_tree_s, &loop->timers);
if (timer) {
uv_update_time();
uv_update_time(loop);
delta = timer->due - LOOP->time;
delta = timer->due - loop->time;
if (delta >= UINT_MAX >> 1) {
/* A timeout value of UINT_MAX means infinite, so that's no good. But */
/* more importantly, there's always the risk that GetTickCount wraps. */
@@ -240,22 +248,22 @@ DWORD uv_get_poll_timeout() {
}
void uv_process_timers() {
void uv_process_timers(uv_loop_t* loop) {
uv_timer_t* timer;
/* Call timer callbacks */
for (timer = RB_MIN(uv_timer_tree_s, &LOOP->timers);
timer != NULL && timer->due <= LOOP->time;
timer = RB_MIN(uv_timer_tree_s, &LOOP->timers)) {
RB_REMOVE(uv_timer_tree_s, &LOOP->timers, timer);
for (timer = RB_MIN(uv_timer_tree_s, &loop->timers);
timer != NULL && timer->due <= loop->time;
timer = RB_MIN(uv_timer_tree_s, &loop->timers)) {
RB_REMOVE(uv_timer_tree_s, &loop->timers, timer);
if (timer->repeat != 0) {
/* If it is a repeating timer, reschedule with repeat timeout. */
timer->due += timer->repeat;
if (timer->due < LOOP->time) {
timer->due = LOOP->time;
if (timer->due < loop->time) {
timer->due = loop->time;
}
if (RB_INSERT(uv_timer_tree_s, &LOOP->timers, timer) != NULL) {
if (RB_INSERT(uv_timer_tree_s, &loop->timers, timer) != NULL) {
uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
}
} else {
+69 -48
View File
@@ -40,12 +40,13 @@ static char uv_zero_[] = "";
static unsigned int active_udp_streams = 0;
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) {
int uv_udp_getsockname(uv_loop_t* loop, uv_udp_t* handle,
struct sockaddr* name, int* namelen) {
int result;
result = getsockname(handle->socket, name, namelen);
if (result != 0) {
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
@@ -53,37 +54,38 @@ int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) {
}
static int uv_udp_set_socket(uv_udp_t* handle, SOCKET socket) {
static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle,
SOCKET socket) {
DWORD yes = 1;
assert(handle->socket == INVALID_SOCKET);
/* Set the socket to nonblocking mode */
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
/* Make the socket non-inheritable */
if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
return -1;
}
/* Associate it with the I/O completion port. */
/* Use uv_handle_t pointer as completion key. */
if (CreateIoCompletionPort((HANDLE)socket,
LOOP->iocp,
loop->iocp,
(ULONG_PTR)socket,
0) == NULL) {
uv_set_sys_error(GetLastError());
uv_set_sys_error(loop, GetLastError());
return -1;
}
if (pSetFileCompletionNotificationModes) {
if (!pSetFileCompletionNotificationModes((HANDLE)socket, FILE_SKIP_SET_EVENT_ON_HANDLE |
FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
uv_set_sys_error(GetLastError());
if (!pSetFileCompletionNotificationModes((HANDLE)socket,
FILE_SKIP_SET_EVENT_ON_HANDLE | FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
uv_set_sys_error(loop, GetLastError());
return -1;
}
@@ -96,26 +98,27 @@ static int uv_udp_set_socket(uv_udp_t* handle, SOCKET socket) {
}
int uv_udp_init(uv_udp_t* handle) {
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
handle->type = UV_UDP;
handle->socket = INVALID_SOCKET;
handle->reqs_pending = 0;
handle->loop = loop;
handle->flags = 0;
uv_req_init((uv_req_t*) &(handle->recv_req));
uv_req_init(loop, (uv_req_t*) &(handle->recv_req));
handle->recv_req.type = UV_UDP_RECV;
handle->recv_req.data = handle;
uv_ref();
uv_ref(loop);
uv_counters()->handle_init++;
uv_counters()->udp_init++;
loop->counters.handle_init++;
loop->counters.udp_init++;
return 0;
}
void uv_udp_endgame(uv_udp_t* handle) {
void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
if (handle->flags & UV_HANDLE_CLOSING &&
handle->reqs_pending == 0) {
assert(!(handle->flags & UV_HANDLE_CLOSED));
@@ -125,30 +128,31 @@ void uv_udp_endgame(uv_udp_t* handle) {
handle->close_cb((uv_handle_t*)handle);
}
uv_unref();
uv_unref(loop);
}
}
static int uv__bind(uv_udp_t* handle, int domain, struct sockaddr* addr,
int addrsize, unsigned int flags) {
uv_loop_t* loop = handle->loop;
DWORD err;
int r;
SOCKET sock;
if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) {
/* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
uv_set_sys_error(UV_EINVAL);
uv_set_sys_error(loop, UV_EINVAL);
}
if (handle->socket == INVALID_SOCKET) {
sock = socket(domain, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) {
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
if (uv_udp_set_socket(handle, sock) == -1) {
if (uv_udp_set_socket(loop, handle, sock) == -1) {
closesocket(sock);
return -1;
}
@@ -162,14 +166,18 @@ static int uv__bind(uv_udp_t* handle, int domain, struct sockaddr* addr,
/* TODO: how to handle errors? This may fail if there is no ipv4 stack */
/* available, or when run on XP/2003 which have no support for dualstack */
/* sockets. For now we're silently ignoring the error. */
setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (const char*) &off, sizeof off);
setsockopt(sock,
IPPROTO_IPV6,
IPV6_V6ONLY,
(const char*) &off,
sizeof off);
}
r = bind(handle->socket, addr, addrsize);
if (r == SOCKET_ERROR) {
err = WSAGetLastError();
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
@@ -179,9 +187,12 @@ static int uv__bind(uv_udp_t* handle, int domain, struct sockaddr* addr,
}
int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr, unsigned int flags) {
int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr,
unsigned int flags) {
uv_loop_t* loop = handle->loop;
if (addr.sin_family != AF_INET) {
uv_set_sys_error(WSAEFAULT);
uv_set_sys_error(loop, WSAEFAULT);
return -1;
}
@@ -193,9 +204,12 @@ int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr, unsigned int flags) {
}
int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned int flags) {
int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr,
unsigned int flags) {
uv_loop_t* loop = handle->loop;
if (addr.sin6_family != AF_INET6) {
uv_set_sys_error(WSAEFAULT);
uv_set_sys_error(loop, WSAEFAULT);
return -1;
}
@@ -213,7 +227,7 @@ int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned int flags)
}
static void uv_udp_queue_recv(uv_udp_t* handle) {
static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
uv_req_t* req;
uv_buf_t buf;
DWORD bytes, flags;
@@ -256,7 +270,7 @@ static void uv_udp_queue_recv(uv_udp_t* handle) {
handle->flags |= UV_HANDLE_READ_PENDING;
req->overlapped.InternalHigh = bytes;
handle->reqs_pending++;
uv_insert_pending_req(req);
uv_insert_pending_req(loop, req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* The req will be processed with IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING;
@@ -264,7 +278,7 @@ static void uv_udp_queue_recv(uv_udp_t* handle) {
} else {
/* Make this req pending reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req(req);
uv_insert_pending_req(loop, req);
handle->reqs_pending++;
}
#if 0
@@ -288,7 +302,7 @@ static void uv_udp_queue_recv(uv_udp_t* handle) {
handle->flags |= UV_HANDLE_READ_PENDING;
req->overlapped.InternalHigh = bytes;
handle->reqs_pending++;
uv_insert_pending_req(req);
uv_insert_pending_req(loop, req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* The req will be processed with IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING;
@@ -296,7 +310,7 @@ static void uv_udp_queue_recv(uv_udp_t* handle) {
} else {
/* Make this req pending reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req(req);
uv_insert_pending_req(loop, req);
handle->reqs_pending++;
}
}
@@ -304,9 +318,12 @@ static void uv_udp_queue_recv(uv_udp_t* handle) {
}
int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb) {
int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb) {
uv_loop_t* loop = handle->loop;
if (handle->flags & UV_HANDLE_READING) {
uv_set_sys_error(WSAEALREADY);
uv_set_sys_error(loop, WSAEALREADY);
return -1;
}
@@ -324,7 +341,7 @@ int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb rec
/* If reading was stopped and then started again, there could stell be a */
/* recv request pending. */
if (!(handle->flags & UV_HANDLE_READ_PENDING))
uv_udp_queue_recv(handle);
uv_udp_queue_recv(loop, handle);
return 0;
}
@@ -342,6 +359,7 @@ int uv_udp_recv_stop(uv_udp_t* handle) {
int uv_udp_connect6(uv_connect_t* req, uv_udp_t* handle,
struct sockaddr_in6 address, uv_connect_cb cb) {
uv_loop_t* loop = handle->loop;
int addrsize = sizeof(struct sockaddr_in6);
BOOL success;
DWORD bytes;
@@ -352,7 +370,7 @@ int uv_udp_connect6(uv_connect_t* req, uv_udp_t* handle,
}
if (address.sin6_family != AF_INET6) {
uv_set_sys_error(WSAEFAULT);
uv_set_sys_error(loop, WSAEFAULT);
return -1;
}
@@ -360,7 +378,7 @@ int uv_udp_connect6(uv_connect_t* req, uv_udp_t* handle,
uv_udp_bind6(handle, uv_addr_ip6_any_, 0) < 0)
return -1;
uv_req_init((uv_req_t*) req);
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_CONNECT;
req->handle = (uv_stream_t*) handle;
req->cb = cb;
@@ -376,11 +394,11 @@ int uv_udp_connect6(uv_connect_t* req, uv_udp_t* handle,
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
handle->reqs_pending++;
uv_insert_pending_req((uv_req_t*)req);
uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(success)) {
handle->reqs_pending++;
} else {
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
@@ -390,9 +408,10 @@ int uv_udp_connect6(uv_connect_t* req, uv_udp_t* handle,
static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
int bufcnt, struct sockaddr* addr, int addr_len, uv_udp_send_cb cb) {
uv_loop_t* loop = handle->loop;
DWORD result, bytes;
uv_req_init((uv_req_t*) req);
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_UDP_SEND;
req->handle = handle;
req->cb = cb;
@@ -412,14 +431,14 @@ static int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
/* Request completed immediately. */
req->queued_bytes = 0;
handle->reqs_pending++;
uv_insert_pending_req((uv_req_t*)req);
uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* Request queued by the kernel. */
req->queued_bytes = uv_count_bufs(bufs, bufcnt);
handle->reqs_pending++;
} else {
/* Send failed due to an error. */
uv_set_sys_error(WSAGetLastError());
uv_set_sys_error(loop, WSAGetLastError());
return -1;
}
@@ -463,7 +482,8 @@ int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
}
void uv_process_udp_recv_req(uv_udp_t* handle, uv_req_t* req) {
void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
uv_req_t* req) {
uv_buf_t buf;
int partial;
@@ -475,7 +495,7 @@ void uv_process_udp_recv_req(uv_udp_t* handle, uv_req_t* req) {
GET_REQ_STATUS(req) != STATUS_RECEIVE_EXPEDITED) {
/* An error occurred doing the read. */
if ((handle->flags & UV_HANDLE_READING)) {
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req);
loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
uv_udp_recv_stop(handle);
#if 0
buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
@@ -532,11 +552,11 @@ void uv_process_udp_recv_req(uv_udp_t* handle, uv_req_t* req) {
} else {
err = WSAGetLastError();
if (err == WSAEWOULDBLOCK) {
uv_set_sys_error(WSAEWOULDBLOCK);
uv_set_sys_error(loop, WSAEWOULDBLOCK);
handle->recv_cb(handle, 0, buf, NULL, 0);
} else {
/* Ouch! serious error. */
uv_set_sys_error(err);
uv_set_sys_error(loop, err);
handle->recv_cb(handle, -1, buf, NULL, 0);
}
}
@@ -547,21 +567,22 @@ done:
/* Post another read if still reading and not closing. */
if ((handle->flags & UV_HANDLE_READING) &&
!(handle->flags & UV_HANDLE_READ_PENDING)) {
uv_udp_queue_recv(handle);
uv_udp_queue_recv(loop, handle);
}
DECREASE_PENDING_REQ_COUNT(handle);
}
void uv_process_udp_send_req(uv_udp_t* handle, uv_udp_send_t* req) {
void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
uv_udp_send_t* req) {
assert(handle->type == UV_UDP);
if (req->cb) {
if (REQ_SUCCESS(req)) {
req->cb(req, 0);
} else {
LOOP->last_error = GET_REQ_UV_SOCK_ERROR(req);
loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
req->cb(req, -1);
}
}
+20 -6
View File
@@ -27,13 +27,27 @@
#include "internal.h"
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size, char* utf8Buffer, size_t utf8Size) {
return WideCharToMultiByte(CP_UTF8, 0, utf16Buffer, utf16Size, utf8Buffer, utf8Size, NULL, NULL);
int uv_utf16_to_utf8(const wchar_t* utf16Buffer, size_t utf16Size,
char* utf8Buffer, size_t utf8Size) {
return WideCharToMultiByte(CP_UTF8,
0,
utf16Buffer,
utf16Size,
utf8Buffer,
utf8Size,
NULL,
NULL);
}
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer, size_t utf16Size) {
return MultiByteToWideChar(CP_UTF8, 0, utf8Buffer, -1, utf16Buffer, utf16Size);
int uv_utf8_to_utf16(const char* utf8Buffer, wchar_t* utf16Buffer,
size_t utf16Size) {
return MultiByteToWideChar(CP_UTF8,
0,
utf8Buffer,
-1,
utf16Buffer,
utf16Size);
}
@@ -55,7 +69,7 @@ int uv_exepath(char* buffer, size_t* size) {
/* Get the path as UTF-16 */
utf16Size = GetModuleFileNameW(NULL, utf16Buffer, *size - 1);
if (utf16Size <= 0) {
uv_set_sys_error(GetLastError());
/* uv_set_sys_error(loop, GetLastError()); */
retVal = -1;
goto done;
}
@@ -65,7 +79,7 @@ int uv_exepath(char* buffer, size_t* size) {
/* Convert to UTF-8 */
*size = uv_utf16_to_utf8(utf16Buffer, utf16Size, buffer, *size);
if (!*size) {
uv_set_sys_error(GetLastError());
/* uv_set_sys_error(loop, GetLastError()); */
retVal = -1;
goto done;
}
+10 -6
View File
@@ -26,6 +26,8 @@
#include <stdio.h>
#include <string.h> /* strlen */
static uv_loop_t* loop;
ares_channel channel;
struct ares_options options;
int optmask;
@@ -67,7 +69,7 @@ static void prep_tcploopback()
options.tcp_port = htons(TEST_PORT_2);
options.flags = ARES_FLAG_USEVC;
rc = uv_ares_init_options(&channel, &options, optmask);
rc = uv_ares_init_options(loop, &channel, &options, optmask);
ASSERT(rc == ARES_SUCCESS);
}
@@ -85,11 +87,13 @@ BENCHMARK_IMPL(gethostbyname) {
}
uv_init();
loop = uv_default_loop();
ares_callbacks = 0;
ares_errors = 0;
uv_update_time();
start_time = uv_now();
uv_update_time(loop);
start_time = uv_now(loop);
prep_tcploopback();
@@ -101,11 +105,11 @@ BENCHMARK_IMPL(gethostbyname) {
&argument);
}
uv_run();
uv_run(loop);
uv_ares_destroy(channel);
uv_ares_destroy(loop, channel);
end_time = uv_now();
end_time = uv_now(loop);
if (ares_errors > 0) {
printf("There were %d failures\n", ares_errors);
+10 -7
View File
@@ -32,6 +32,8 @@
const char* name = "localhost";
static uv_loop_t* loop;
static uv_getaddrinfo_t handles[CONCURRENT_CALLS];
static int calls_initiated = 0;
@@ -58,7 +60,7 @@ static void getaddrinfo_initiate(uv_getaddrinfo_t* handle) {
calls_initiated++;
r = uv_getaddrinfo(handle, &getaddrinfo_cb, name, NULL, NULL);
r = uv_getaddrinfo(loop, handle, &getaddrinfo_cb, name, NULL, NULL);
ASSERT(r == 0);
}
@@ -66,19 +68,20 @@ static void getaddrinfo_initiate(uv_getaddrinfo_t* handle) {
BENCHMARK_IMPL(getaddrinfo) {
int i;
uv_init();
uv_init(loop);
loop = uv_default_loop();
uv_update_time();
start_time = uv_now();
uv_update_time(loop);
start_time = uv_now(loop);
for (i = 0; i < CONCURRENT_CALLS; i++) {
getaddrinfo_initiate(&handles[i]);
}
uv_run();
uv_run(loop);
uv_update_time();
end_time = uv_now();
uv_update_time(loop);
end_time = uv_now(loop);
ASSERT(calls_initiated == TOTAL_CALLS);
ASSERT(calls_completed == TOTAL_CALLS);
+9 -5
View File
@@ -46,6 +46,8 @@ typedef struct buf_s {
static char PING[] = "PING\n";
static uv_loop_t* loop;
static buf_t* buf_freelist = NULL;
static int pinger_shutdown_cb_called;
static int completed_pingers = 0;
@@ -130,7 +132,7 @@ static void pinger_read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
pinger = (pinger_t*)tcp->data;
if (nread < 0) {
ASSERT(uv_last_error().code == UV_EOF);
ASSERT(uv_last_error(loop).code == UV_EOF);
if (buf.base) {
buf_free(buf);
@@ -148,7 +150,7 @@ static void pinger_read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
pinger->state = (pinger->state + 1) % (sizeof(PING) - 1);
if (pinger->state == 0) {
pinger->pongs++;
if (uv_now() - start_time > TIME) {
if (uv_now(loop) - start_time > TIME) {
uv_shutdown(&pinger->shutdown_req, (uv_stream_t*) tcp, pinger_shutdown_cb);
break;
} else {
@@ -185,7 +187,7 @@ static void pinger_new() {
pinger->pongs = 0;
/* Try to connec to the server and do NUM_PINGS ping-pongs. */
r = uv_tcp_init(&pinger->tcp);
r = uv_tcp_init(loop, &pinger->tcp);
ASSERT(!r);
pinger->tcp.data = pinger;
@@ -199,10 +201,12 @@ static void pinger_new() {
BENCHMARK_IMPL(ping_pongs) {
uv_init();
start_time = uv_now();
loop = uv_default_loop();
start_time = uv_now(loop);
pinger_new();
uv_run();
uv_run(loop);
ASSERT(completed_pingers == 1);
+14 -11
View File
@@ -65,6 +65,8 @@ typedef struct {
static char buffer[] = "QS";
static uv_loop_t* loop;
static tcp_conn_rec tcp_conns[MAX_CONNS];
static pipe_conn_rec pipe_conns[MAX_CONNS];
@@ -89,7 +91,7 @@ static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) {
static void after_write(uv_write_t* req, int status) {
if (status != 0) {
fprintf(stderr, "write error %s\n", uv_err_name(uv_last_error()));
fprintf(stderr, "write error %s\n", uv_err_name(uv_last_error(loop)));
uv_close((uv_handle_t*)req->handle, close_cb);
conns_failed++;
return;
@@ -134,7 +136,7 @@ static void connect_cb(uv_connect_t* req, int status) {
static void read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
conn_rec* p = (conn_rec*)stream->data;
uv_err_t err = uv_last_error();
uv_err_t err = uv_last_error(loop);
ASSERT(stream != NULL);
@@ -150,7 +152,7 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
} else if (err.code == UV_ECONNRESET) {
conns_failed++;
} else {
fprintf(stderr, "read error %s\n", uv_err_name(uv_last_error()));
fprintf(stderr, "read error %s\n", uv_err_name(uv_last_error(loop)));
ASSERT(0);
}
}
@@ -167,7 +169,7 @@ static void close_cb(uv_handle_t* handle) {
printf("close_cb %d\n", p->i);
#endif
if (uv_now() - start < 10000) {
if (uv_now(loop) - start < 10000) {
p->make_connect(p);
}
}
@@ -195,7 +197,7 @@ static void tcp_make_connect(conn_rec* p) {
struct sockaddr_in addr;
int r;
r = uv_tcp_init((uv_tcp_t*)&p->stream);
r = uv_tcp_init(loop, (uv_tcp_t*)&p->stream);
ASSERT(r == 0);
addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
@@ -203,7 +205,7 @@ static void tcp_make_connect(conn_rec* p) {
r = uv_tcp_connect(&((tcp_conn_rec*)p)->conn_req, (uv_tcp_t*)&p->stream, addr, connect_cb);
if (r) {
fprintf(stderr, "uv_tcp_connect error %s\n",
uv_err_name(uv_last_error()));
uv_err_name(uv_last_error(loop)));
ASSERT(0);
}
@@ -220,13 +222,13 @@ static void tcp_make_connect(conn_rec* p) {
static void pipe_make_connect(conn_rec* p) {
int r;
r = uv_pipe_init((uv_pipe_t*)&p->stream);
r = uv_pipe_init(loop, (uv_pipe_t*)&p->stream);
ASSERT(r == 0);
r = uv_pipe_connect(&((pipe_conn_rec*)p)->conn_req, (uv_pipe_t*)&p->stream, TEST_PIPENAME, connect_cb);
if (r) {
fprintf(stderr, "uv_tcp_connect error %s\n",
uv_err_name(uv_last_error()));
uv_err_name(uv_last_error(loop)));
ASSERT(0);
}
@@ -276,9 +278,10 @@ static int pound_it(int concurrency,
uint64_t end_time;
uv_init();
loop = uv_default_loop();
uv_update_time();
start = uv_now();
uv_update_time(loop);
start = uv_now(loop);
/* Run benchmark for at least five seconds. */
start_time = uv_hrtime();
@@ -288,7 +291,7 @@ static int pound_it(int concurrency,
r = do_connect(concurrency, make_connect, arg);
ASSERT(!r);
uv_run();
uv_run(loop);
end_time = uv_hrtime();
Loaded 100 of 146 files, more files were not shown because too many files have changed in this diff. Show more