asyncengine 0.0.1.testing1 → 0.0.2.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +3 -0
- data/Rakefile +38 -0
- data/asyncengine.gemspec +8 -4
- data/ext/asyncengine/ae_call_from_other_thread.c +106 -0
- data/ext/asyncengine/ae_call_from_other_thread.h +12 -0
- data/ext/asyncengine/ae_handle_common.c +193 -48
- data/ext/asyncengine/ae_handle_common.h +40 -13
- data/ext/asyncengine/ae_ip_utils.c +246 -0
- data/ext/asyncengine/ae_ip_utils.h +25 -0
- data/ext/asyncengine/ae_next_tick.c +81 -21
- data/ext/asyncengine/ae_next_tick.h +4 -2
- data/ext/asyncengine/ae_resolver.c +156 -0
- data/ext/asyncengine/ae_resolver.h +10 -0
- data/ext/asyncengine/ae_tcp.c +908 -0
- data/ext/asyncengine/ae_tcp.h +20 -0
- data/ext/asyncengine/ae_timer.c +355 -81
- data/ext/asyncengine/ae_timer.h +11 -4
- data/ext/asyncengine/ae_udp.c +579 -13
- data/ext/asyncengine/ae_udp.h +15 -2
- data/ext/asyncengine/ae_utils.c +192 -0
- data/ext/asyncengine/ae_utils.h +16 -0
- data/ext/asyncengine/asyncengine_ruby.c +469 -26
- data/ext/asyncengine/asyncengine_ruby.h +49 -11
- data/ext/asyncengine/debug.h +68 -0
- data/ext/asyncengine/extconf.rb +26 -2
- data/ext/asyncengine/ip_parser.c +5954 -0
- data/ext/asyncengine/ip_parser.h +16 -0
- data/ext/asyncengine/libuv/AUTHORS +16 -0
- data/ext/asyncengine/libuv/common.gypi +4 -4
- data/ext/asyncengine/libuv/config-mingw.mk +6 -6
- data/ext/asyncengine/libuv/config-unix.mk +13 -13
- data/ext/asyncengine/libuv/gyp_uv +5 -1
- data/ext/asyncengine/libuv/ibc_tests/exec_test.sh +8 -0
- data/ext/asyncengine/libuv/ibc_tests/uv_shutdown_write_issue.c +171 -0
- data/ext/asyncengine/libuv/ibc_tests/uv_tcp_close_while_connecting.c +102 -0
- data/ext/asyncengine/libuv/include/uv-private/ngx-queue.h +3 -1
- data/ext/asyncengine/libuv/include/uv-private/uv-unix.h +103 -50
- data/ext/asyncengine/libuv/include/uv-private/uv-win.h +76 -24
- data/ext/asyncengine/libuv/include/uv.h +353 -88
- data/ext/asyncengine/libuv/src/ares/ares__close_sockets.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares__get_hostent.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares__read_line.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares__timeval.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_cancel.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_data.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_destroy.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_expand_name.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_expand_string.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_fds.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_free_hostent.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_free_string.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_gethostbyaddr.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_gethostbyname.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_getnameinfo.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_getopt.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_getsock.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_init.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_library_init.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_llist.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_mkquery.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_nowarn.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_options.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_a_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_aaaa_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_mx_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_ns_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_ptr_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_srv_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_txt_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_process.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_query.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_search.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_send.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_strcasecmp.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_strdup.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_strerror.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_timeout.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_version.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_writev.o +0 -0
- data/ext/asyncengine/libuv/src/ares/bitncmp.o +0 -0
- data/ext/asyncengine/libuv/src/ares/inet_net_pton.o +0 -0
- data/ext/asyncengine/libuv/src/ares/inet_ntop.o +0 -0
- data/ext/asyncengine/libuv/src/cares.c +225 -0
- data/ext/asyncengine/libuv/src/cares.o +0 -0
- data/ext/asyncengine/libuv/src/fs-poll.c +237 -0
- data/ext/asyncengine/libuv/src/fs-poll.o +0 -0
- data/ext/asyncengine/libuv/src/unix/async.c +78 -17
- data/ext/asyncengine/libuv/src/unix/async.o +0 -0
- data/ext/asyncengine/libuv/src/unix/core.c +305 -213
- data/ext/asyncengine/libuv/src/unix/core.o +0 -0
- data/ext/asyncengine/libuv/src/unix/cygwin.c +1 -1
- data/ext/asyncengine/libuv/src/unix/darwin.c +2 -1
- data/ext/asyncengine/libuv/src/unix/dl.c +36 -44
- data/ext/asyncengine/libuv/src/unix/dl.o +0 -0
- data/ext/asyncengine/libuv/src/unix/eio/eio.o +0 -0
- data/ext/asyncengine/libuv/src/unix/error.c +6 -0
- data/ext/asyncengine/libuv/src/unix/error.o +0 -0
- data/ext/asyncengine/libuv/src/unix/ev/ev.c +8 -4
- data/ext/asyncengine/libuv/src/unix/ev/ev.o +0 -0
- data/ext/asyncengine/libuv/src/unix/freebsd.c +1 -1
- data/ext/asyncengine/libuv/src/unix/fs.c +25 -33
- data/ext/asyncengine/libuv/src/unix/fs.o +0 -0
- data/ext/asyncengine/libuv/src/unix/internal.h +50 -31
- data/ext/asyncengine/libuv/src/unix/kqueue.c +2 -7
- data/ext/asyncengine/libuv/src/unix/linux/core.o +0 -0
- data/ext/asyncengine/libuv/src/unix/linux/inotify.c +12 -14
- data/ext/asyncengine/libuv/src/unix/linux/inotify.o +0 -0
- data/ext/asyncengine/libuv/src/unix/linux/{core.c → linux-core.c} +1 -1
- data/ext/asyncengine/libuv/src/unix/linux/linux-core.o +0 -0
- data/ext/asyncengine/libuv/src/unix/linux/syscalls.c +147 -1
- data/ext/asyncengine/libuv/src/unix/linux/syscalls.h +39 -2
- data/ext/asyncengine/libuv/src/unix/linux/syscalls.o +0 -0
- data/ext/asyncengine/libuv/src/unix/loop-watcher.c +63 -0
- data/ext/asyncengine/libuv/src/unix/loop-watcher.o +0 -0
- data/ext/asyncengine/libuv/src/unix/loop.c +29 -6
- data/ext/asyncengine/libuv/src/unix/loop.o +0 -0
- data/ext/asyncengine/libuv/src/unix/netbsd.c +1 -1
- data/ext/asyncengine/libuv/src/unix/openbsd.c +1 -1
- data/ext/asyncengine/libuv/src/unix/pipe.c +31 -36
- data/ext/asyncengine/libuv/src/unix/pipe.o +0 -0
- data/ext/asyncengine/libuv/src/unix/poll.c +116 -0
- data/ext/asyncengine/libuv/src/unix/poll.o +0 -0
- data/ext/asyncengine/libuv/src/unix/process.c +193 -115
- data/ext/asyncengine/libuv/src/unix/process.o +0 -0
- data/ext/asyncengine/libuv/src/unix/stream.c +146 -153
- data/ext/asyncengine/libuv/src/unix/stream.o +0 -0
- data/ext/asyncengine/libuv/src/unix/sunos.c +45 -36
- data/ext/asyncengine/libuv/src/unix/tcp.c +6 -5
- data/ext/asyncengine/libuv/src/unix/tcp.o +0 -0
- data/ext/asyncengine/libuv/src/unix/thread.c +82 -25
- data/ext/asyncengine/libuv/src/unix/thread.o +0 -0
- data/ext/asyncengine/libuv/src/unix/timer.c +69 -58
- data/ext/asyncengine/libuv/src/unix/timer.o +0 -0
- data/ext/asyncengine/libuv/src/unix/tty.c +3 -3
- data/ext/asyncengine/libuv/src/unix/tty.o +0 -0
- data/ext/asyncengine/libuv/src/unix/udp.c +57 -66
- data/ext/asyncengine/libuv/src/unix/udp.o +0 -0
- data/ext/asyncengine/libuv/src/unix/uv-eio.c +33 -50
- data/ext/asyncengine/libuv/src/unix/uv-eio.o +0 -0
- data/ext/asyncengine/libuv/src/uv-common.c +68 -38
- data/ext/asyncengine/libuv/src/uv-common.h +104 -20
- data/ext/asyncengine/libuv/src/uv-common.o +0 -0
- data/ext/asyncengine/libuv/src/win/async.c +20 -17
- data/ext/asyncengine/libuv/src/win/core.c +44 -31
- data/ext/asyncengine/libuv/src/win/dl.c +40 -36
- data/ext/asyncengine/libuv/src/win/error.c +21 -1
- data/ext/asyncengine/libuv/src/win/fs-event.c +19 -21
- data/ext/asyncengine/libuv/src/win/fs.c +541 -189
- data/ext/asyncengine/libuv/src/win/getaddrinfo.c +56 -63
- data/ext/asyncengine/libuv/src/win/handle-inl.h +145 -0
- data/ext/asyncengine/libuv/src/win/handle.c +26 -101
- data/ext/asyncengine/libuv/src/win/internal.h +92 -107
- data/ext/asyncengine/libuv/src/win/loop-watcher.c +6 -14
- data/ext/asyncengine/libuv/src/win/pipe.c +78 -64
- data/ext/asyncengine/libuv/src/win/poll.c +618 -0
- data/ext/asyncengine/libuv/src/win/process-stdio.c +479 -0
- data/ext/asyncengine/libuv/src/win/process.c +147 -274
- data/ext/asyncengine/libuv/src/win/req-inl.h +225 -0
- data/ext/asyncengine/libuv/src/win/req.c +0 -149
- data/ext/asyncengine/libuv/src/{unix/check.c → win/stream-inl.h} +31 -42
- data/ext/asyncengine/libuv/src/win/stream.c +9 -43
- data/ext/asyncengine/libuv/src/win/tcp.c +200 -82
- data/ext/asyncengine/libuv/src/win/thread.c +42 -2
- data/ext/asyncengine/libuv/src/win/threadpool.c +3 -2
- data/ext/asyncengine/libuv/src/win/timer.c +13 -63
- data/ext/asyncengine/libuv/src/win/tty.c +26 -20
- data/ext/asyncengine/libuv/src/win/udp.c +26 -17
- data/ext/asyncengine/libuv/src/win/util.c +312 -167
- data/ext/asyncengine/libuv/src/win/winapi.c +16 -1
- data/ext/asyncengine/libuv/src/win/winapi.h +33 -9
- data/ext/asyncengine/libuv/src/win/winsock.c +88 -1
- data/ext/asyncengine/libuv/src/win/winsock.h +36 -3
- data/ext/asyncengine/libuv/test/benchmark-ares.c +16 -17
- data/ext/asyncengine/libuv/test/benchmark-fs-stat.c +164 -0
- data/ext/asyncengine/libuv/test/benchmark-list.h +9 -0
- data/ext/asyncengine/libuv/{src/unix/prepare.c → test/benchmark-loop-count.c} +42 -33
- data/ext/asyncengine/libuv/test/benchmark-million-timers.c +65 -0
- data/ext/asyncengine/libuv/test/benchmark-pound.c +1 -1
- data/ext/asyncengine/libuv/test/benchmark-sizes.c +2 -0
- data/ext/asyncengine/libuv/test/benchmark-spawn.c +7 -1
- data/ext/asyncengine/libuv/test/benchmark-udp-packet-storm.c +1 -1
- data/ext/asyncengine/libuv/test/echo-server.c +8 -0
- data/ext/asyncengine/libuv/test/run-tests.c +30 -0
- data/ext/asyncengine/libuv/test/runner-unix.c +6 -26
- data/ext/asyncengine/libuv/test/runner-win.c +5 -63
- data/ext/asyncengine/libuv/test/runner.c +10 -1
- data/ext/asyncengine/libuv/test/task.h +0 -8
- data/ext/asyncengine/libuv/test/test-async.c +43 -141
- data/ext/asyncengine/libuv/test/test-callback-order.c +76 -0
- data/ext/asyncengine/libuv/test/test-counters-init.c +2 -3
- data/ext/asyncengine/libuv/test/test-dlerror.c +17 -8
- data/ext/asyncengine/libuv/test/test-fs-event.c +31 -39
- data/ext/asyncengine/libuv/test/test-fs-poll.c +146 -0
- data/ext/asyncengine/libuv/test/test-fs.c +114 -2
- data/ext/asyncengine/libuv/test/test-gethostbyname.c +8 -8
- data/ext/asyncengine/libuv/test/test-hrtime.c +18 -15
- data/ext/asyncengine/libuv/test/test-ipc.c +8 -2
- data/ext/asyncengine/libuv/test/test-list.h +59 -9
- data/ext/asyncengine/libuv/test/test-loop-handles.c +2 -25
- data/ext/asyncengine/libuv/{src/unix/idle.c → test/test-poll-close.c} +37 -39
- data/ext/asyncengine/libuv/test/test-poll.c +573 -0
- data/ext/asyncengine/libuv/test/test-ref.c +79 -63
- data/ext/asyncengine/libuv/test/test-run-once.c +15 -11
- data/ext/asyncengine/libuv/test/test-semaphore.c +111 -0
- data/ext/asyncengine/libuv/test/test-spawn.c +368 -20
- data/ext/asyncengine/libuv/test/test-stdio-over-pipes.c +25 -35
- data/ext/asyncengine/libuv/test/test-tcp-close-while-connecting.c +80 -0
- data/ext/asyncengine/libuv/test/test-tcp-close.c +1 -1
- data/ext/asyncengine/libuv/test/test-tcp-connect-error-after-write.c +95 -0
- data/ext/asyncengine/libuv/test/test-tcp-connect-timeout.c +85 -0
- data/ext/asyncengine/libuv/test/test-tcp-shutdown-after-write.c +131 -0
- data/ext/asyncengine/libuv/test/test-tcp-write-error.c +2 -2
- data/ext/asyncengine/libuv/test/test-tcp-writealot.c +29 -54
- data/ext/asyncengine/libuv/test/test-timer-again.c +1 -1
- data/ext/asyncengine/libuv/test/test-timer.c +23 -1
- data/ext/asyncengine/libuv/test/test-udp-options.c +1 -1
- data/ext/asyncengine/libuv/test/{test-eio-overflow.c → test-walk-handles.c} +31 -44
- data/ext/asyncengine/libuv/uv.gyp +26 -9
- data/ext/asyncengine/rb_utilities.c +54 -0
- data/ext/asyncengine/rb_utilities.h +63 -0
- data/lib/asyncengine.rb +45 -38
- data/lib/asyncengine/asyncengine_ext.so +0 -0
- data/lib/asyncengine/debug.rb +37 -0
- data/lib/asyncengine/handle.rb +9 -0
- data/lib/asyncengine/tcp.rb +28 -0
- data/lib/asyncengine/timer.rb +18 -28
- data/lib/asyncengine/udp.rb +29 -0
- data/lib/asyncengine/utils.rb +32 -0
- data/lib/asyncengine/uv_error.rb +17 -0
- data/lib/asyncengine/version.rb +9 -1
- data/test/ae_test_helper.rb +62 -0
- data/test/test_basic.rb +169 -0
- data/test/test_call_from_other_thread.rb +55 -0
- data/test/test_error.rb +92 -0
- data/test/test_ip_utils.rb +44 -0
- data/test/test_next_tick.rb +37 -0
- data/test/test_resolver.rb +51 -0
- data/test/test_threads.rb +69 -0
- data/test/test_timer.rb +95 -0
- data/test/test_udp.rb +216 -0
- data/test/test_utils.rb +49 -0
- metadata +84 -57
- data/ext/asyncengine/libuv/mkmf.log +0 -24
- data/ext/asyncengine/libuv/src/unix/cares.c +0 -194
- data/ext/asyncengine/libuv/src/unix/cares.o +0 -0
- data/ext/asyncengine/libuv/src/unix/check.o +0 -0
- data/ext/asyncengine/libuv/src/unix/idle.o +0 -0
- data/ext/asyncengine/libuv/src/unix/prepare.o +0 -0
- data/ext/asyncengine/libuv/src/win/cares.c +0 -290
- data/lib/asyncengine/errors.rb +0 -5
- data/lib/asyncengine/next_tick.rb +0 -24
|
@@ -22,34 +22,9 @@
|
|
|
22
22
|
#include <assert.h>
|
|
23
23
|
|
|
24
24
|
#include "uv.h"
|
|
25
|
-
#include "../uv-common.h"
|
|
26
25
|
#include "internal.h"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
void uv_stream_init(uv_loop_t* loop, uv_stream_t* handle) {
|
|
30
|
-
handle->write_queue_size = 0;
|
|
31
|
-
handle->loop = loop;
|
|
32
|
-
handle->flags = 0;
|
|
33
|
-
|
|
34
|
-
loop->counters.handle_init++;
|
|
35
|
-
loop->counters.stream_init++;
|
|
36
|
-
|
|
37
|
-
uv_ref(loop);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
void uv_connection_init(uv_stream_t* handle) {
|
|
42
|
-
handle->flags |= UV_HANDLE_CONNECTION;
|
|
43
|
-
handle->write_reqs_pending = 0;
|
|
44
|
-
|
|
45
|
-
uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req));
|
|
46
|
-
handle->read_req.event_handle = NULL;
|
|
47
|
-
handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
|
|
48
|
-
handle->read_req.type = UV_READ;
|
|
49
|
-
handle->read_req.data = handle;
|
|
50
|
-
|
|
51
|
-
handle->shutdown_req = NULL;
|
|
52
|
-
}
|
|
26
|
+
#include "handle-inl.h"
|
|
27
|
+
#include "req-inl.h"
|
|
53
28
|
|
|
54
29
|
|
|
55
30
|
int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
|
@@ -109,8 +84,11 @@ int uv_read2_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
|
|
|
109
84
|
int uv_read_stop(uv_stream_t* handle) {
|
|
110
85
|
if (handle->type == UV_TTY) {
|
|
111
86
|
return uv_tty_read_stop((uv_tty_t*) handle);
|
|
112
|
-
} else {
|
|
87
|
+
} else if (handle->flags & UV_HANDLE_READING) {
|
|
113
88
|
handle->flags &= ~UV_HANDLE_READING;
|
|
89
|
+
DECREASE_ACTIVE_COUNT(handle->loop, handle);
|
|
90
|
+
return 0;
|
|
91
|
+
} else {
|
|
114
92
|
return 0;
|
|
115
93
|
}
|
|
116
94
|
}
|
|
@@ -171,7 +149,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
|
|
|
171
149
|
handle->flags |= UV_HANDLE_SHUTTING;
|
|
172
150
|
handle->shutdown_req = req;
|
|
173
151
|
handle->reqs_pending++;
|
|
174
|
-
|
|
152
|
+
REGISTER_HANDLE_REQ(loop, handle, req);
|
|
175
153
|
|
|
176
154
|
uv_want_endgame(loop, (uv_handle_t*)handle);
|
|
177
155
|
|
|
@@ -179,23 +157,11 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
|
|
|
179
157
|
}
|
|
180
158
|
|
|
181
159
|
|
|
182
|
-
|
|
183
|
-
size_t bytes = 0;
|
|
184
|
-
int i;
|
|
185
|
-
|
|
186
|
-
for (i = 0; i < count; i++) {
|
|
187
|
-
bytes += (size_t)bufs[i].len;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return bytes;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
int uv_is_readable(uv_stream_t* handle) {
|
|
160
|
+
int uv_is_readable(const uv_stream_t* handle) {
|
|
195
161
|
return !(handle->flags & UV_HANDLE_EOF);
|
|
196
162
|
}
|
|
197
163
|
|
|
198
164
|
|
|
199
|
-
int uv_is_writable(uv_stream_t* handle) {
|
|
165
|
+
int uv_is_writable(const uv_stream_t* handle) {
|
|
200
166
|
return !(handle->flags & UV_HANDLE_SHUTTING);
|
|
201
167
|
}
|
|
@@ -22,8 +22,10 @@
|
|
|
22
22
|
#include <assert.h>
|
|
23
23
|
|
|
24
24
|
#include "uv.h"
|
|
25
|
-
#include "../uv-common.h"
|
|
26
25
|
#include "internal.h"
|
|
26
|
+
#include "handle-inl.h"
|
|
27
|
+
#include "stream-inl.h"
|
|
28
|
+
#include "req-inl.h"
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
/*
|
|
@@ -91,12 +93,6 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
|
|
|
91
93
|
return -1;
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
/* Make the socket non-inheritable */
|
|
95
|
-
if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) {
|
|
96
|
-
uv__set_sys_error(loop, GetLastError());
|
|
97
|
-
return -1;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
96
|
/* Associate it with the I/O completion port. */
|
|
101
97
|
/* Use uv_handle_t pointer as completion key. */
|
|
102
98
|
if (CreateIoCompletionPort((HANDLE)socket,
|
|
@@ -143,12 +139,11 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
|
|
|
143
139
|
|
|
144
140
|
|
|
145
141
|
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
|
|
146
|
-
uv_stream_init(loop, (uv_stream_t*)handle);
|
|
142
|
+
uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP);
|
|
147
143
|
|
|
148
144
|
handle->accept_reqs = NULL;
|
|
149
145
|
handle->pending_accepts = NULL;
|
|
150
146
|
handle->socket = INVALID_SOCKET;
|
|
151
|
-
handle->type = UV_TCP;
|
|
152
147
|
handle->reqs_pending = 0;
|
|
153
148
|
handle->func_acceptex = NULL;
|
|
154
149
|
handle->func_connectex = NULL;
|
|
@@ -170,6 +165,8 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
|
|
170
165
|
handle->shutdown_req != NULL &&
|
|
171
166
|
handle->write_reqs_pending == 0) {
|
|
172
167
|
|
|
168
|
+
UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);
|
|
169
|
+
|
|
173
170
|
if (handle->flags & UV_HANDLE_CLOSING) {
|
|
174
171
|
status = -1;
|
|
175
172
|
sys_error = WSAEINTR;
|
|
@@ -180,6 +177,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
|
|
180
177
|
status = -1;
|
|
181
178
|
sys_error = WSAGetLastError();
|
|
182
179
|
}
|
|
180
|
+
|
|
183
181
|
if (handle->shutdown_req->cb) {
|
|
184
182
|
if (status == -1) {
|
|
185
183
|
uv__set_sys_error(loop, sys_error);
|
|
@@ -188,8 +186,6 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
|
|
188
186
|
}
|
|
189
187
|
|
|
190
188
|
handle->shutdown_req = NULL;
|
|
191
|
-
|
|
192
|
-
uv_unref(loop);
|
|
193
189
|
DECREASE_PENDING_REQ_COUNT(handle);
|
|
194
190
|
return;
|
|
195
191
|
}
|
|
@@ -197,7 +193,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
|
|
197
193
|
if (handle->flags & UV_HANDLE_CLOSING &&
|
|
198
194
|
handle->reqs_pending == 0) {
|
|
199
195
|
assert(!(handle->flags & UV_HANDLE_CLOSED));
|
|
200
|
-
handle
|
|
196
|
+
uv__handle_stop(handle);
|
|
201
197
|
|
|
202
198
|
if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
|
|
203
199
|
closesocket(handle->socket);
|
|
@@ -235,13 +231,8 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
|
|
|
235
231
|
}
|
|
236
232
|
}
|
|
237
233
|
|
|
238
|
-
|
|
239
|
-
handle->close_cb((uv_handle_t*)handle);
|
|
240
|
-
}
|
|
241
|
-
|
|
234
|
+
uv__handle_close(handle);
|
|
242
235
|
loop->active_tcp_streams--;
|
|
243
|
-
|
|
244
|
-
uv_unref(loop);
|
|
245
236
|
}
|
|
246
237
|
}
|
|
247
238
|
|
|
@@ -260,6 +251,13 @@ static int uv__bind(uv_tcp_t* handle,
|
|
|
260
251
|
return -1;
|
|
261
252
|
}
|
|
262
253
|
|
|
254
|
+
/* Make the socket non-inheritable */
|
|
255
|
+
if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) {
|
|
256
|
+
uv__set_sys_error(handle->loop, GetLastError());
|
|
257
|
+
closesocket(sock);
|
|
258
|
+
return -1;
|
|
259
|
+
}
|
|
260
|
+
|
|
263
261
|
if (uv_tcp_set_socket(handle->loop, handle, sock, 0) == -1) {
|
|
264
262
|
closesocket(sock);
|
|
265
263
|
return -1;
|
|
@@ -310,10 +308,10 @@ int uv__tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
|
|
|
310
308
|
|
|
311
309
|
|
|
312
310
|
static void CALLBACK post_completion(void* context, BOOLEAN timed_out) {
|
|
313
|
-
|
|
311
|
+
uv_req_t* req;
|
|
314
312
|
uv_tcp_t* handle;
|
|
315
313
|
|
|
316
|
-
req = (
|
|
314
|
+
req = (uv_req_t*) context;
|
|
317
315
|
assert(req != NULL);
|
|
318
316
|
handle = (uv_tcp_t*)req->data;
|
|
319
317
|
assert(handle != NULL);
|
|
@@ -328,6 +326,25 @@ static void CALLBACK post_completion(void* context, BOOLEAN timed_out) {
|
|
|
328
326
|
}
|
|
329
327
|
|
|
330
328
|
|
|
329
|
+
static void CALLBACK post_write_completion(void* context, BOOLEAN timed_out) {
|
|
330
|
+
uv_write_t* req;
|
|
331
|
+
uv_tcp_t* handle;
|
|
332
|
+
|
|
333
|
+
req = (uv_write_t*) context;
|
|
334
|
+
assert(req != NULL);
|
|
335
|
+
handle = (uv_tcp_t*)req->handle;
|
|
336
|
+
assert(handle != NULL);
|
|
337
|
+
assert(!timed_out);
|
|
338
|
+
|
|
339
|
+
if (!PostQueuedCompletionStatus(handle->loop->iocp,
|
|
340
|
+
req->overlapped.InternalHigh,
|
|
341
|
+
0,
|
|
342
|
+
&req->overlapped)) {
|
|
343
|
+
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
|
|
331
348
|
static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
|
|
332
349
|
uv_loop_t* loop = handle->loop;
|
|
333
350
|
BOOL success;
|
|
@@ -354,6 +371,15 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
|
|
|
354
371
|
return;
|
|
355
372
|
}
|
|
356
373
|
|
|
374
|
+
/* Make the socket non-inheritable */
|
|
375
|
+
if (!SetHandleInformation((HANDLE) accept_socket, HANDLE_FLAG_INHERIT, 0)) {
|
|
376
|
+
SET_REQ_ERROR(req, GetLastError());
|
|
377
|
+
uv_insert_pending_req(loop, (uv_req_t*)req);
|
|
378
|
+
handle->reqs_pending++;
|
|
379
|
+
closesocket(accept_socket);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
|
|
357
383
|
/* Prepare the overlapped structure. */
|
|
358
384
|
memset(&(req->overlapped), 0, sizeof(req->overlapped));
|
|
359
385
|
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
|
|
@@ -381,7 +407,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
|
|
|
381
407
|
if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
|
|
382
408
|
req->wait_handle == INVALID_HANDLE_VALUE &&
|
|
383
409
|
!RegisterWaitForSingleObject(&req->wait_handle,
|
|
384
|
-
req->
|
|
410
|
+
req->event_handle, post_completion, (void*) req,
|
|
385
411
|
INFINITE, WT_EXECUTEINWAITTHREAD)) {
|
|
386
412
|
SET_REQ_ERROR(req, GetLastError());
|
|
387
413
|
uv_insert_pending_req(loop, (uv_req_t*)req);
|
|
@@ -460,7 +486,7 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
|
|
|
460
486
|
if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
|
|
461
487
|
req->wait_handle == INVALID_HANDLE_VALUE &&
|
|
462
488
|
!RegisterWaitForSingleObject(&req->wait_handle,
|
|
463
|
-
req->
|
|
489
|
+
req->event_handle, post_completion, (void*) req,
|
|
464
490
|
INFINITE, WT_EXECUTEINWAITTHREAD)) {
|
|
465
491
|
SET_REQ_ERROR(req, GetLastError());
|
|
466
492
|
uv_insert_pending_req(loop, (uv_req_t*)req);
|
|
@@ -481,6 +507,15 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
|
|
481
507
|
|
|
482
508
|
assert(backlog > 0);
|
|
483
509
|
|
|
510
|
+
if (handle->flags & UV_HANDLE_LISTENING) {
|
|
511
|
+
handle->connection_cb = cb;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
if (handle->flags & UV_HANDLE_READING) {
|
|
515
|
+
uv__set_artificial_error(loop, UV_EISCONN);
|
|
516
|
+
return -1;
|
|
517
|
+
}
|
|
518
|
+
|
|
484
519
|
if (handle->flags & UV_HANDLE_BIND_ERROR) {
|
|
485
520
|
uv__set_sys_error(loop, handle->bind_error);
|
|
486
521
|
return -1;
|
|
@@ -505,6 +540,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
|
|
505
540
|
|
|
506
541
|
handle->flags |= UV_HANDLE_LISTENING;
|
|
507
542
|
handle->connection_cb = cb;
|
|
543
|
+
INCREASE_ACTIVE_COUNT(loop, handle);
|
|
508
544
|
|
|
509
545
|
simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1
|
|
510
546
|
: uv_simultaneous_server_accepts;
|
|
@@ -623,6 +659,7 @@ int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
|
|
|
623
659
|
handle->flags |= UV_HANDLE_READING;
|
|
624
660
|
handle->read_cb = read_cb;
|
|
625
661
|
handle->alloc_cb = alloc_cb;
|
|
662
|
+
INCREASE_ACTIVE_COUNT(loop, handle);
|
|
626
663
|
|
|
627
664
|
/* If reading was stopped and then started again, there could still be a */
|
|
628
665
|
/* read request pending. */
|
|
@@ -683,12 +720,12 @@ int uv__tcp_connect(uv_connect_t* req,
|
|
|
683
720
|
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
|
|
684
721
|
/* Process the req without IOCP. */
|
|
685
722
|
handle->reqs_pending++;
|
|
686
|
-
|
|
723
|
+
REGISTER_HANDLE_REQ(loop, handle, req);
|
|
687
724
|
uv_insert_pending_req(loop, (uv_req_t*)req);
|
|
688
725
|
} else if (UV_SUCCEEDED_WITH_IOCP(success)) {
|
|
689
726
|
/* The req will be processed with IOCP. */
|
|
690
727
|
handle->reqs_pending++;
|
|
691
|
-
|
|
728
|
+
REGISTER_HANDLE_REQ(loop, handle, req);
|
|
692
729
|
} else {
|
|
693
730
|
uv__set_sys_error(loop, WSAGetLastError());
|
|
694
731
|
return -1;
|
|
@@ -744,11 +781,11 @@ int uv__tcp_connect6(uv_connect_t* req,
|
|
|
744
781
|
|
|
745
782
|
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
|
|
746
783
|
handle->reqs_pending++;
|
|
747
|
-
|
|
784
|
+
REGISTER_HANDLE_REQ(loop, handle, req);
|
|
748
785
|
uv_insert_pending_req(loop, (uv_req_t*)req);
|
|
749
786
|
} else if (UV_SUCCEEDED_WITH_IOCP(success)) {
|
|
750
787
|
handle->reqs_pending++;
|
|
751
|
-
|
|
788
|
+
REGISTER_HANDLE_REQ(loop, handle, req);
|
|
752
789
|
} else {
|
|
753
790
|
uv__set_sys_error(loop, WSAGetLastError());
|
|
754
791
|
return -1;
|
|
@@ -837,6 +874,7 @@ int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
|
|
|
837
874
|
uv_fatal_error(GetLastError(), "CreateEvent");
|
|
838
875
|
}
|
|
839
876
|
req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
|
|
877
|
+
req->wait_handle = INVALID_HANDLE_VALUE;
|
|
840
878
|
}
|
|
841
879
|
|
|
842
880
|
result = WSASend(handle->socket,
|
|
@@ -852,20 +890,19 @@ int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
|
|
|
852
890
|
req->queued_bytes = 0;
|
|
853
891
|
handle->reqs_pending++;
|
|
854
892
|
handle->write_reqs_pending++;
|
|
893
|
+
REGISTER_HANDLE_REQ(loop, handle, req);
|
|
855
894
|
uv_insert_pending_req(loop, (uv_req_t*) req);
|
|
856
|
-
uv_ref(loop);
|
|
857
895
|
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
|
|
858
896
|
/* Request queued by the kernel. */
|
|
859
897
|
req->queued_bytes = uv_count_bufs(bufs, bufcnt);
|
|
860
898
|
handle->reqs_pending++;
|
|
861
899
|
handle->write_reqs_pending++;
|
|
900
|
+
REGISTER_HANDLE_REQ(loop, handle, req);
|
|
862
901
|
handle->write_queue_size += req->queued_bytes;
|
|
863
|
-
uv_ref(loop);
|
|
864
902
|
if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
|
|
865
|
-
req->wait_handle == INVALID_HANDLE_VALUE &&
|
|
866
903
|
!RegisterWaitForSingleObject(&req->wait_handle,
|
|
867
|
-
req->
|
|
868
|
-
INFINITE, WT_EXECUTEINWAITTHREAD)) {
|
|
904
|
+
req->event_handle, post_write_completion, (void*) req,
|
|
905
|
+
INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) {
|
|
869
906
|
SET_REQ_ERROR(req, GetLastError());
|
|
870
907
|
uv_insert_pending_req(loop, (uv_req_t*)req);
|
|
871
908
|
}
|
|
@@ -893,6 +930,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|
|
893
930
|
if ((handle->flags & UV_HANDLE_READING) ||
|
|
894
931
|
!(handle->flags & UV_HANDLE_ZERO_READ)) {
|
|
895
932
|
handle->flags &= ~UV_HANDLE_READING;
|
|
933
|
+
DECREASE_ACTIVE_COUNT(loop, handle);
|
|
896
934
|
buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
|
|
897
935
|
uv_buf_init(NULL, 0) : handle->read_buffer;
|
|
898
936
|
|
|
@@ -923,8 +961,12 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|
|
923
961
|
}
|
|
924
962
|
} else {
|
|
925
963
|
/* Connection closed */
|
|
926
|
-
handle->flags
|
|
964
|
+
if (handle->flags & UV_HANDLE_READING) {
|
|
965
|
+
handle->flags &= ~UV_HANDLE_READING;
|
|
966
|
+
DECREASE_ACTIVE_COUNT(loop, handle);
|
|
967
|
+
}
|
|
927
968
|
handle->flags |= UV_HANDLE_EOF;
|
|
969
|
+
|
|
928
970
|
uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
|
|
929
971
|
buf.base = 0;
|
|
930
972
|
buf.len = 0;
|
|
@@ -955,7 +997,9 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|
|
955
997
|
} else {
|
|
956
998
|
/* Connection closed */
|
|
957
999
|
handle->flags &= ~UV_HANDLE_READING;
|
|
1000
|
+
DECREASE_ACTIVE_COUNT(loop, handle);
|
|
958
1001
|
handle->flags |= UV_HANDLE_EOF;
|
|
1002
|
+
|
|
959
1003
|
uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
|
|
960
1004
|
handle->read_cb((uv_stream_t*)handle, -1, buf);
|
|
961
1005
|
break;
|
|
@@ -967,16 +1011,18 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|
|
967
1011
|
uv__set_sys_error(loop, WSAEWOULDBLOCK);
|
|
968
1012
|
handle->read_cb((uv_stream_t*)handle, 0, buf);
|
|
969
1013
|
} else {
|
|
1014
|
+
/* Ouch! serious error. */
|
|
1015
|
+
handle->flags &= ~UV_HANDLE_READING;
|
|
1016
|
+
DECREASE_ACTIVE_COUNT(loop, handle);
|
|
1017
|
+
|
|
970
1018
|
if (err == WSAECONNABORTED) {
|
|
971
|
-
/*
|
|
972
|
-
|
|
973
|
-
*/
|
|
1019
|
+
/* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with */
|
|
1020
|
+
/* Unix. */
|
|
974
1021
|
uv__set_error(loop, UV_ECONNRESET, err);
|
|
975
1022
|
} else {
|
|
976
|
-
/* Ouch! serious error. */
|
|
977
1023
|
uv__set_sys_error(loop, err);
|
|
978
1024
|
}
|
|
979
|
-
|
|
1025
|
+
|
|
980
1026
|
handle->read_cb((uv_stream_t*)handle, -1, buf);
|
|
981
1027
|
}
|
|
982
1028
|
break;
|
|
@@ -1002,14 +1048,14 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|
|
1002
1048
|
assert(handle->write_queue_size >= req->queued_bytes);
|
|
1003
1049
|
handle->write_queue_size -= req->queued_bytes;
|
|
1004
1050
|
|
|
1051
|
+
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
|
1052
|
+
|
|
1005
1053
|
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
|
|
1006
1054
|
if (req->wait_handle != INVALID_HANDLE_VALUE) {
|
|
1007
1055
|
UnregisterWait(req->wait_handle);
|
|
1008
|
-
req->wait_handle = INVALID_HANDLE_VALUE;
|
|
1009
1056
|
}
|
|
1010
1057
|
if (req->event_handle) {
|
|
1011
1058
|
CloseHandle(req->event_handle);
|
|
1012
|
-
req->event_handle = NULL;
|
|
1013
1059
|
}
|
|
1014
1060
|
}
|
|
1015
1061
|
|
|
@@ -1025,7 +1071,6 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|
|
1025
1071
|
}
|
|
1026
1072
|
|
|
1027
1073
|
DECREASE_PENDING_REQ_COUNT(handle);
|
|
1028
|
-
uv_unref(loop);
|
|
1029
1074
|
}
|
|
1030
1075
|
|
|
1031
1076
|
|
|
@@ -1042,6 +1087,7 @@ void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|
|
1042
1087
|
if (req->accept_socket == INVALID_SOCKET) {
|
|
1043
1088
|
if (handle->flags & UV_HANDLE_LISTENING) {
|
|
1044
1089
|
handle->flags &= ~UV_HANDLE_LISTENING;
|
|
1090
|
+
DECREASE_ACTIVE_COUNT(loop, handle);
|
|
1045
1091
|
if (handle->connection_cb) {
|
|
1046
1092
|
uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req));
|
|
1047
1093
|
handle->connection_cb((uv_stream_t*)handle, -1);
|
|
@@ -1079,28 +1125,27 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
|
|
|
1079
1125
|
uv_connect_t* req) {
|
|
1080
1126
|
assert(handle->type == UV_TCP);
|
|
1081
1127
|
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
uv__set_sys_error(loop, WSAGetLastError());
|
|
1094
|
-
((uv_connect_cb)req->cb)(req, -1);
|
|
1095
|
-
}
|
|
1128
|
+
UNREGISTER_HANDLE_REQ(loop, handle, req);
|
|
1129
|
+
|
|
1130
|
+
if (REQ_SUCCESS(req)) {
|
|
1131
|
+
if (setsockopt(handle->socket,
|
|
1132
|
+
SOL_SOCKET,
|
|
1133
|
+
SO_UPDATE_CONNECT_CONTEXT,
|
|
1134
|
+
NULL,
|
|
1135
|
+
0) == 0) {
|
|
1136
|
+
uv_connection_init((uv_stream_t*)handle);
|
|
1137
|
+
loop->active_tcp_streams++;
|
|
1138
|
+
((uv_connect_cb)req->cb)(req, 0);
|
|
1096
1139
|
} else {
|
|
1097
|
-
uv__set_sys_error(loop,
|
|
1140
|
+
uv__set_sys_error(loop, WSAGetLastError());
|
|
1098
1141
|
((uv_connect_cb)req->cb)(req, -1);
|
|
1099
1142
|
}
|
|
1143
|
+
} else {
|
|
1144
|
+
uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req));
|
|
1145
|
+
((uv_connect_cb)req->cb)(req, -1);
|
|
1100
1146
|
}
|
|
1101
1147
|
|
|
1102
1148
|
DECREASE_PENDING_REQ_COUNT(handle);
|
|
1103
|
-
uv_unref(loop);
|
|
1104
1149
|
}
|
|
1105
1150
|
|
|
1106
1151
|
|
|
@@ -1118,21 +1163,28 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
|
|
|
1118
1163
|
return -1;
|
|
1119
1164
|
}
|
|
1120
1165
|
|
|
1121
|
-
|
|
1122
|
-
|
|
1166
|
+
if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0)) {
|
|
1167
|
+
uv__set_sys_error(tcp->loop, GetLastError());
|
|
1168
|
+
closesocket(socket);
|
|
1169
|
+
return -1;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
if (uv_tcp_set_socket(tcp->loop, tcp, socket, 1) != 0) {
|
|
1173
|
+
closesocket(socket);
|
|
1174
|
+
return -1;
|
|
1175
|
+
}
|
|
1123
1176
|
|
|
1124
1177
|
if (tcp_connection) {
|
|
1125
1178
|
uv_connection_init((uv_stream_t*)tcp);
|
|
1126
1179
|
}
|
|
1127
1180
|
|
|
1181
|
+
tcp->flags |= UV_HANDLE_BOUND;
|
|
1182
|
+
tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET;
|
|
1183
|
+
|
|
1128
1184
|
if (socket_protocol_info->iAddressFamily == AF_INET6) {
|
|
1129
1185
|
tcp->flags |= UV_HANDLE_IPV6;
|
|
1130
1186
|
}
|
|
1131
1187
|
|
|
1132
|
-
if (uv_tcp_set_socket(tcp->loop, tcp, socket, 1) != 0) {
|
|
1133
|
-
return -1;
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
1188
|
tcp->loop->active_tcp_streams++;
|
|
1137
1189
|
return 0;
|
|
1138
1190
|
}
|
|
@@ -1172,11 +1224,10 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
|
|
|
1172
1224
|
}
|
|
1173
1225
|
|
|
1174
1226
|
|
|
1175
|
-
|
|
1176
1227
|
int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
|
|
1177
1228
|
LPWSAPROTOCOL_INFOW protocol_info) {
|
|
1178
1229
|
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
|
|
1179
|
-
/*
|
|
1230
|
+
/*
|
|
1180
1231
|
* We're about to share the socket with another process. Because
|
|
1181
1232
|
* this is a listening socket, we assume that the other process will
|
|
1182
1233
|
* be accepting connections on it. So, before sharing the socket
|
|
@@ -1240,42 +1291,109 @@ int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
|
|
|
1240
1291
|
}
|
|
1241
1292
|
|
|
1242
1293
|
|
|
1243
|
-
|
|
1294
|
+
static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) {
|
|
1295
|
+
SOCKET socket = tcp->socket;
|
|
1244
1296
|
int non_ifs_lsp;
|
|
1297
|
+
|
|
1298
|
+
/* Check if we have any non-IFS LSPs stacked on top of TCP */
|
|
1299
|
+
non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 :
|
|
1300
|
+
uv_tcp_non_ifs_lsp_ipv4;
|
|
1301
|
+
|
|
1302
|
+
/* If there are non-ifs LSPs then try to obtain a base handle for the */
|
|
1303
|
+
/* socket. This will always fail on Windows XP/3k. */
|
|
1304
|
+
if (non_ifs_lsp) {
|
|
1305
|
+
DWORD bytes;
|
|
1306
|
+
if (WSAIoctl(socket,
|
|
1307
|
+
SIO_BASE_HANDLE,
|
|
1308
|
+
NULL,
|
|
1309
|
+
0,
|
|
1310
|
+
&socket,
|
|
1311
|
+
sizeof socket,
|
|
1312
|
+
&bytes,
|
|
1313
|
+
NULL,
|
|
1314
|
+
NULL) != 0) {
|
|
1315
|
+
/* Failed. We can't do CancelIo. */
|
|
1316
|
+
return -1;
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
assert(socket != 0 && socket != INVALID_SOCKET);
|
|
1321
|
+
|
|
1322
|
+
if (!CancelIo((HANDLE) socket)) {
|
|
1323
|
+
return -1;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
/* It worked. */
|
|
1327
|
+
return 0;
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
|
|
1245
1332
|
int close_socket = 1;
|
|
1246
1333
|
|
|
1247
|
-
/*
|
|
1248
|
-
* In order for winsock to do a graceful close there must not be
|
|
1249
|
-
* any pending reads.
|
|
1250
|
-
*/
|
|
1251
1334
|
if (tcp->flags & UV_HANDLE_READ_PENDING) {
|
|
1252
|
-
/*
|
|
1335
|
+
/* In order for winsock to do a graceful close there must not be any */
|
|
1336
|
+
/* any pending reads, or the socket must be shut down for writing */
|
|
1253
1337
|
if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) {
|
|
1338
|
+
/* Just do shutdown on non-shared sockets, which ensures graceful close. */
|
|
1254
1339
|
shutdown(tcp->socket, SD_SEND);
|
|
1255
1340
|
tcp->flags |= UV_HANDLE_SHUT;
|
|
1341
|
+
|
|
1342
|
+
} else if (uv_tcp_try_cancel_io(tcp) == 0) {
|
|
1343
|
+
/* In case of a shared socket, we try to cancel all outstanding I/O, */
|
|
1344
|
+
/* If that works, don't close the socket yet - wait for the read req to */
|
|
1345
|
+
/* return and close the socket in uv_tcp_endgame. */
|
|
1346
|
+
close_socket = 0;
|
|
1347
|
+
|
|
1256
1348
|
} else {
|
|
1257
|
-
/*
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1349
|
+
/* When cancelling isn't possible - which could happen when an LSP is */
|
|
1350
|
+
/* present on an old Windows version, we will have to close the socket */
|
|
1351
|
+
/* with a read pending. That is not nice because trailing sent bytes */
|
|
1352
|
+
/* may not make it to the other side. */
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
} else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
|
|
1356
|
+
tcp->accept_reqs != NULL) {
|
|
1357
|
+
/* Under normal circumstances closesocket() will ensure that all pending */
|
|
1358
|
+
/* accept reqs are canceled. However, when the socket is shared the */
|
|
1359
|
+
/* presence of another reference to the socket in another process will */
|
|
1360
|
+
/* keep the accept reqs going, so we have to ensure that these are */
|
|
1361
|
+
/* canceled. */
|
|
1362
|
+
if (uv_tcp_try_cancel_io(tcp) != 0) {
|
|
1363
|
+
/* When cancellation is not possible, there is another option: we can */
|
|
1364
|
+
/* close the incoming sockets, which will also cancel the accept */
|
|
1365
|
+
/* operations. However this is not cool because we might inadvertedly */
|
|
1366
|
+
/* close a socket that just accepted a new connection, which will */
|
|
1367
|
+
/* cause the connection to be aborted. */
|
|
1368
|
+
unsigned int i;
|
|
1369
|
+
for (i = 0; i < uv_simultaneous_server_accepts; i++) {
|
|
1370
|
+
uv_tcp_accept_t* req = &tcp->accept_reqs[i];
|
|
1371
|
+
if (req->accept_socket != INVALID_SOCKET &&
|
|
1372
|
+
!HasOverlappedIoCompleted(&req->overlapped)) {
|
|
1373
|
+
closesocket(req->accept_socket);
|
|
1374
|
+
req->accept_socket = INVALID_SOCKET;
|
|
1375
|
+
}
|
|
1268
1376
|
}
|
|
1269
1377
|
}
|
|
1270
1378
|
}
|
|
1271
1379
|
|
|
1272
|
-
tcp->flags
|
|
1380
|
+
if (tcp->flags & UV_HANDLE_READING) {
|
|
1381
|
+
tcp->flags &= ~UV_HANDLE_READING;
|
|
1382
|
+
DECREASE_ACTIVE_COUNT(loop, tcp);
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
if (tcp->flags & UV_HANDLE_LISTENING) {
|
|
1386
|
+
tcp->flags &= ~UV_HANDLE_LISTENING;
|
|
1387
|
+
DECREASE_ACTIVE_COUNT(loop, tcp);
|
|
1388
|
+
}
|
|
1273
1389
|
|
|
1274
1390
|
if (close_socket) {
|
|
1275
1391
|
closesocket(tcp->socket);
|
|
1276
1392
|
tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
|
|
1277
1393
|
}
|
|
1278
1394
|
|
|
1395
|
+
uv__handle_start(tcp);
|
|
1396
|
+
|
|
1279
1397
|
if (tcp->reqs_pending == 0) {
|
|
1280
1398
|
uv_want_endgame(tcp->loop, (uv_handle_t*)tcp);
|
|
1281
1399
|
}
|