asyncengine 0.0.1.testing1 → 0.0.2.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|