rbuv 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (233) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +0 -1
  6. data/README.md +6 -1
  7. data/Rakefile +42 -0
  8. data/deps/libuv/.gitignore +34 -0
  9. data/deps/libuv/.mailmap +16 -0
  10. data/deps/libuv/AUTHORS +81 -0
  11. data/deps/libuv/ChangeLog +45 -0
  12. data/deps/libuv/LICENSE +41 -0
  13. data/deps/libuv/Makefile +53 -0
  14. data/deps/libuv/README.md +118 -0
  15. data/deps/libuv/build.mk +164 -0
  16. data/deps/libuv/checksparse.sh +230 -0
  17. data/deps/libuv/common.gypi +197 -0
  18. data/deps/libuv/config-mingw.mk +48 -0
  19. data/deps/libuv/config-unix.mk +167 -0
  20. data/deps/libuv/gyp_uv +98 -0
  21. data/deps/libuv/include/uv-private/ngx-queue.h +129 -0
  22. data/deps/libuv/include/uv-private/stdint-msvc2008.h +247 -0
  23. data/deps/libuv/include/uv-private/tree.h +768 -0
  24. data/deps/libuv/include/uv-private/uv-bsd.h +34 -0
  25. data/deps/libuv/include/uv-private/uv-darwin.h +61 -0
  26. data/deps/libuv/include/uv-private/uv-linux.h +34 -0
  27. data/deps/libuv/include/uv-private/uv-sunos.h +44 -0
  28. data/deps/libuv/include/uv-private/uv-unix.h +332 -0
  29. data/deps/libuv/include/uv-private/uv-win.h +585 -0
  30. data/deps/libuv/include/uv.h +1987 -0
  31. data/deps/libuv/src/fs-poll.c +248 -0
  32. data/deps/libuv/src/inet.c +298 -0
  33. data/deps/libuv/src/unix/aix.c +393 -0
  34. data/deps/libuv/src/unix/async.c +281 -0
  35. data/deps/libuv/src/unix/core.c +714 -0
  36. data/deps/libuv/src/unix/cygwin.c +93 -0
  37. data/deps/libuv/src/unix/darwin-proctitle.m +78 -0
  38. data/deps/libuv/src/unix/darwin.c +431 -0
  39. data/deps/libuv/src/unix/dl.c +83 -0
  40. data/deps/libuv/src/unix/error.c +109 -0
  41. data/deps/libuv/src/unix/freebsd.c +343 -0
  42. data/deps/libuv/src/unix/fs.c +869 -0
  43. data/deps/libuv/src/unix/fsevents.c +299 -0
  44. data/deps/libuv/src/unix/getaddrinfo.c +159 -0
  45. data/deps/libuv/src/unix/internal.h +259 -0
  46. data/deps/libuv/src/unix/kqueue.c +347 -0
  47. data/deps/libuv/src/unix/linux-core.c +724 -0
  48. data/deps/libuv/src/unix/linux-inotify.c +236 -0
  49. data/deps/libuv/src/unix/linux-syscalls.c +388 -0
  50. data/deps/libuv/src/unix/linux-syscalls.h +150 -0
  51. data/deps/libuv/src/unix/loop-watcher.c +64 -0
  52. data/deps/libuv/src/unix/loop.c +114 -0
  53. data/deps/libuv/src/unix/netbsd.c +353 -0
  54. data/deps/libuv/src/unix/openbsd.c +304 -0
  55. data/deps/libuv/src/unix/pipe.c +261 -0
  56. data/deps/libuv/src/unix/poll.c +108 -0
  57. data/deps/libuv/src/unix/process.c +501 -0
  58. data/deps/libuv/src/unix/proctitle.c +103 -0
  59. data/deps/libuv/src/unix/signal.c +455 -0
  60. data/deps/libuv/src/unix/stream.c +1380 -0
  61. data/deps/libuv/src/unix/sunos.c +647 -0
  62. data/deps/libuv/src/unix/tcp.c +357 -0
  63. data/deps/libuv/src/unix/thread.c +431 -0
  64. data/deps/libuv/src/unix/threadpool.c +286 -0
  65. data/deps/libuv/src/unix/timer.c +153 -0
  66. data/deps/libuv/src/unix/tty.c +179 -0
  67. data/deps/libuv/src/unix/udp.c +715 -0
  68. data/deps/libuv/src/uv-common.c +431 -0
  69. data/deps/libuv/src/uv-common.h +204 -0
  70. data/deps/libuv/src/version.c +60 -0
  71. data/deps/libuv/src/win/async.c +99 -0
  72. data/deps/libuv/src/win/atomicops-inl.h +56 -0
  73. data/deps/libuv/src/win/core.c +310 -0
  74. data/deps/libuv/src/win/dl.c +86 -0
  75. data/deps/libuv/src/win/error.c +164 -0
  76. data/deps/libuv/src/win/fs-event.c +506 -0
  77. data/deps/libuv/src/win/fs.c +1951 -0
  78. data/deps/libuv/src/win/getaddrinfo.c +365 -0
  79. data/deps/libuv/src/win/handle-inl.h +164 -0
  80. data/deps/libuv/src/win/handle.c +153 -0
  81. data/deps/libuv/src/win/internal.h +346 -0
  82. data/deps/libuv/src/win/loop-watcher.c +124 -0
  83. data/deps/libuv/src/win/pipe.c +1656 -0
  84. data/deps/libuv/src/win/poll.c +615 -0
  85. data/deps/libuv/src/win/process-stdio.c +503 -0
  86. data/deps/libuv/src/win/process.c +1048 -0
  87. data/deps/libuv/src/win/req-inl.h +224 -0
  88. data/deps/libuv/src/win/req.c +25 -0
  89. data/deps/libuv/src/win/signal.c +354 -0
  90. data/deps/libuv/src/win/stream-inl.h +67 -0
  91. data/deps/libuv/src/win/stream.c +198 -0
  92. data/deps/libuv/src/win/tcp.c +1422 -0
  93. data/deps/libuv/src/win/thread.c +666 -0
  94. data/deps/libuv/src/win/threadpool.c +82 -0
  95. data/deps/libuv/src/win/timer.c +230 -0
  96. data/deps/libuv/src/win/tty.c +1857 -0
  97. data/deps/libuv/src/win/udp.c +744 -0
  98. data/deps/libuv/src/win/util.c +946 -0
  99. data/deps/libuv/src/win/winapi.c +152 -0
  100. data/deps/libuv/src/win/winapi.h +4476 -0
  101. data/deps/libuv/src/win/winsock.c +560 -0
  102. data/deps/libuv/src/win/winsock.h +171 -0
  103. data/deps/libuv/test/benchmark-async-pummel.c +119 -0
  104. data/deps/libuv/test/benchmark-async.c +139 -0
  105. data/deps/libuv/test/benchmark-fs-stat.c +136 -0
  106. data/deps/libuv/test/benchmark-getaddrinfo.c +91 -0
  107. data/deps/libuv/test/benchmark-list.h +163 -0
  108. data/deps/libuv/test/benchmark-loop-count.c +90 -0
  109. data/deps/libuv/test/benchmark-million-async.c +112 -0
  110. data/deps/libuv/test/benchmark-million-timers.c +77 -0
  111. data/deps/libuv/test/benchmark-multi-accept.c +432 -0
  112. data/deps/libuv/test/benchmark-ping-pongs.c +212 -0
  113. data/deps/libuv/test/benchmark-pound.c +325 -0
  114. data/deps/libuv/test/benchmark-pump.c +459 -0
  115. data/deps/libuv/test/benchmark-sizes.c +45 -0
  116. data/deps/libuv/test/benchmark-spawn.c +163 -0
  117. data/deps/libuv/test/benchmark-tcp-write-batch.c +141 -0
  118. data/deps/libuv/test/benchmark-thread.c +64 -0
  119. data/deps/libuv/test/benchmark-udp-pummel.c +238 -0
  120. data/deps/libuv/test/blackhole-server.c +118 -0
  121. data/deps/libuv/test/dns-server.c +329 -0
  122. data/deps/libuv/test/echo-server.c +384 -0
  123. data/deps/libuv/test/fixtures/empty_file +0 -0
  124. data/deps/libuv/test/fixtures/load_error.node +1 -0
  125. data/deps/libuv/test/run-benchmarks.c +64 -0
  126. data/deps/libuv/test/run-tests.c +159 -0
  127. data/deps/libuv/test/runner-unix.c +328 -0
  128. data/deps/libuv/test/runner-unix.h +36 -0
  129. data/deps/libuv/test/runner-win.c +318 -0
  130. data/deps/libuv/test/runner-win.h +43 -0
  131. data/deps/libuv/test/runner.c +394 -0
  132. data/deps/libuv/test/runner.h +165 -0
  133. data/deps/libuv/test/task.h +122 -0
  134. data/deps/libuv/test/test-active.c +83 -0
  135. data/deps/libuv/test/test-async.c +136 -0
  136. data/deps/libuv/test/test-barrier.c +98 -0
  137. data/deps/libuv/test/test-callback-order.c +77 -0
  138. data/deps/libuv/test/test-callback-stack.c +204 -0
  139. data/deps/libuv/test/test-condvar.c +173 -0
  140. data/deps/libuv/test/test-connection-fail.c +150 -0
  141. data/deps/libuv/test/test-cwd-and-chdir.c +64 -0
  142. data/deps/libuv/test/test-delayed-accept.c +189 -0
  143. data/deps/libuv/test/test-dlerror.c +58 -0
  144. data/deps/libuv/test/test-embed.c +136 -0
  145. data/deps/libuv/test/test-error.c +59 -0
  146. data/deps/libuv/test/test-fail-always.c +29 -0
  147. data/deps/libuv/test/test-fs-event.c +504 -0
  148. data/deps/libuv/test/test-fs-poll.c +148 -0
  149. data/deps/libuv/test/test-fs.c +1899 -0
  150. data/deps/libuv/test/test-get-currentexe.c +63 -0
  151. data/deps/libuv/test/test-get-loadavg.c +36 -0
  152. data/deps/libuv/test/test-get-memory.c +38 -0
  153. data/deps/libuv/test/test-getaddrinfo.c +120 -0
  154. data/deps/libuv/test/test-getsockname.c +344 -0
  155. data/deps/libuv/test/test-hrtime.c +54 -0
  156. data/deps/libuv/test/test-idle.c +82 -0
  157. data/deps/libuv/test/test-ipc-send-recv.c +218 -0
  158. data/deps/libuv/test/test-ipc.c +625 -0
  159. data/deps/libuv/test/test-list.h +492 -0
  160. data/deps/libuv/test/test-loop-handles.c +337 -0
  161. data/deps/libuv/test/test-loop-stop.c +73 -0
  162. data/deps/libuv/test/test-multiple-listen.c +103 -0
  163. data/deps/libuv/test/test-mutexes.c +63 -0
  164. data/deps/libuv/test/test-pass-always.c +28 -0
  165. data/deps/libuv/test/test-ping-pong.c +250 -0
  166. data/deps/libuv/test/test-pipe-bind-error.c +144 -0
  167. data/deps/libuv/test/test-pipe-connect-error.c +98 -0
  168. data/deps/libuv/test/test-platform-output.c +87 -0
  169. data/deps/libuv/test/test-poll-close.c +73 -0
  170. data/deps/libuv/test/test-poll.c +575 -0
  171. data/deps/libuv/test/test-process-title.c +49 -0
  172. data/deps/libuv/test/test-ref.c +415 -0
  173. data/deps/libuv/test/test-run-nowait.c +46 -0
  174. data/deps/libuv/test/test-run-once.c +49 -0
  175. data/deps/libuv/test/test-semaphore.c +111 -0
  176. data/deps/libuv/test/test-shutdown-close.c +105 -0
  177. data/deps/libuv/test/test-shutdown-eof.c +184 -0
  178. data/deps/libuv/test/test-signal-multiple-loops.c +270 -0
  179. data/deps/libuv/test/test-signal.c +152 -0
  180. data/deps/libuv/test/test-spawn.c +938 -0
  181. data/deps/libuv/test/test-stdio-over-pipes.c +250 -0
  182. data/deps/libuv/test/test-tcp-bind-error.c +198 -0
  183. data/deps/libuv/test/test-tcp-bind6-error.c +159 -0
  184. data/deps/libuv/test/test-tcp-close-while-connecting.c +81 -0
  185. data/deps/libuv/test/test-tcp-close.c +130 -0
  186. data/deps/libuv/test/test-tcp-connect-error-after-write.c +96 -0
  187. data/deps/libuv/test/test-tcp-connect-error.c +71 -0
  188. data/deps/libuv/test/test-tcp-connect-timeout.c +86 -0
  189. data/deps/libuv/test/test-tcp-connect6-error.c +69 -0
  190. data/deps/libuv/test/test-tcp-flags.c +52 -0
  191. data/deps/libuv/test/test-tcp-open.c +175 -0
  192. data/deps/libuv/test/test-tcp-read-stop.c +73 -0
  193. data/deps/libuv/test/test-tcp-shutdown-after-write.c +132 -0
  194. data/deps/libuv/test/test-tcp-unexpected-read.c +114 -0
  195. data/deps/libuv/test/test-tcp-write-to-half-open-connection.c +136 -0
  196. data/deps/libuv/test/test-tcp-writealot.c +171 -0
  197. data/deps/libuv/test/test-thread.c +183 -0
  198. data/deps/libuv/test/test-threadpool-cancel.c +311 -0
  199. data/deps/libuv/test/test-threadpool.c +77 -0
  200. data/deps/libuv/test/test-timer-again.c +142 -0
  201. data/deps/libuv/test/test-timer.c +266 -0
  202. data/deps/libuv/test/test-tty.c +111 -0
  203. data/deps/libuv/test/test-udp-dgram-too-big.c +87 -0
  204. data/deps/libuv/test/test-udp-ipv6.c +158 -0
  205. data/deps/libuv/test/test-udp-multicast-join.c +140 -0
  206. data/deps/libuv/test/test-udp-multicast-ttl.c +87 -0
  207. data/deps/libuv/test/test-udp-open.c +154 -0
  208. data/deps/libuv/test/test-udp-options.c +87 -0
  209. data/deps/libuv/test/test-udp-send-and-recv.c +210 -0
  210. data/deps/libuv/test/test-util.c +97 -0
  211. data/deps/libuv/test/test-walk-handles.c +78 -0
  212. data/deps/libuv/uv.gyp +431 -0
  213. data/deps/libuv/vcbuild.bat +128 -0
  214. data/ext/rbuv/debug.h +27 -0
  215. data/ext/rbuv/error.c +7 -0
  216. data/ext/rbuv/error.h +10 -0
  217. data/ext/rbuv/extconf.rb +35 -0
  218. data/ext/rbuv/handle.c +40 -0
  219. data/ext/rbuv/handle.h +14 -0
  220. data/ext/rbuv/libuv.mk +12 -0
  221. data/ext/rbuv/loop.c +50 -0
  222. data/ext/rbuv/loop.h +13 -0
  223. data/ext/rbuv/rbuv.c +15 -0
  224. data/ext/rbuv/rbuv.h +27 -0
  225. data/ext/rbuv/timer.c +133 -0
  226. data/ext/rbuv/timer.h +13 -0
  227. data/lib/rbuv/timer.rb +7 -0
  228. data/lib/rbuv/version.rb +1 -1
  229. data/lib/rbuv.rb +24 -2
  230. data/rbuv.gemspec +5 -1
  231. data/spec/spec_helper.rb +22 -0
  232. data/spec/timer_spec.rb +144 -0
  233. metadata +278 -9
@@ -0,0 +1,560 @@
1
+ /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to
5
+ * deal in the Software without restriction, including without limitation the
6
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ * sell copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in
11
+ * all copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19
+ * IN THE SOFTWARE.
20
+ */
21
+
22
+ #include <assert.h>
23
+
24
+ #include "uv.h"
25
+ #include "internal.h"
26
+
27
+
28
+ /* Whether there are any non-IFS LSPs stacked on TCP */
29
+ int uv_tcp_non_ifs_lsp_ipv4;
30
+ int uv_tcp_non_ifs_lsp_ipv6;
31
+
32
+ /* Ip address used to bind to any port at any interface */
33
+ struct sockaddr_in uv_addr_ip4_any_;
34
+ struct sockaddr_in6 uv_addr_ip6_any_;
35
+
36
+
37
+ /*
38
+ * Retrieves the pointer to a winsock extension function.
39
+ */
40
+ static BOOL uv_get_extension_function(SOCKET socket, GUID guid,
41
+ void **target) {
42
+ DWORD result, bytes;
43
+
44
+ result = WSAIoctl(socket,
45
+ SIO_GET_EXTENSION_FUNCTION_POINTER,
46
+ &guid,
47
+ sizeof(guid),
48
+ (void*)target,
49
+ sizeof(*target),
50
+ &bytes,
51
+ NULL,
52
+ NULL);
53
+
54
+ if (result == SOCKET_ERROR) {
55
+ *target = NULL;
56
+ return FALSE;
57
+ } else {
58
+ return TRUE;
59
+ }
60
+ }
61
+
62
+
63
+ BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target) {
64
+ const GUID wsaid_acceptex = WSAID_ACCEPTEX;
65
+ return uv_get_extension_function(socket, wsaid_acceptex, (void**)target);
66
+ }
67
+
68
+
69
+ BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target) {
70
+ const GUID wsaid_connectex = WSAID_CONNECTEX;
71
+ return uv_get_extension_function(socket, wsaid_connectex, (void**)target);
72
+ }
73
+
74
+
75
+ static int error_means_no_support(DWORD error) {
76
+ return error == WSAEPROTONOSUPPORT || error == WSAESOCKTNOSUPPORT ||
77
+ error == WSAEPFNOSUPPORT || error == WSAEAFNOSUPPORT;
78
+ }
79
+
80
+
81
+ void uv_winsock_init() {
82
+ const GUID wsaid_connectex = WSAID_CONNECTEX;
83
+ const GUID wsaid_acceptex = WSAID_ACCEPTEX;
84
+ const GUID wsaid_getacceptexsockaddrs = WSAID_GETACCEPTEXSOCKADDRS;
85
+ const GUID wsaid_disconnectex = WSAID_DISCONNECTEX;
86
+ const GUID wsaid_transmitfile = WSAID_TRANSMITFILE;
87
+
88
+ WSADATA wsa_data;
89
+ int errorno;
90
+ SOCKET dummy;
91
+ WSAPROTOCOL_INFOW protocol_info;
92
+ int opt_len;
93
+
94
+ /* Initialize winsock */
95
+ errorno = WSAStartup(MAKEWORD(2, 2), &wsa_data);
96
+ if (errorno != 0) {
97
+ uv_fatal_error(errorno, "WSAStartup");
98
+ }
99
+
100
+ /* Set implicit binding address used by connectEx */
101
+ uv_addr_ip4_any_ = uv_ip4_addr("0.0.0.0", 0);
102
+ uv_addr_ip6_any_ = uv_ip6_addr("::", 0);
103
+
104
+ /* Detect non-IFS LSPs */
105
+ dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
106
+
107
+ if (dummy != INVALID_SOCKET) {
108
+ opt_len = (int) sizeof protocol_info;
109
+ if (!getsockopt(dummy,
110
+ SOL_SOCKET,
111
+ SO_PROTOCOL_INFOW,
112
+ (char*) &protocol_info,
113
+ &opt_len) == SOCKET_ERROR)
114
+ uv_fatal_error(WSAGetLastError(), "getsockopt");
115
+
116
+ if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
117
+ uv_tcp_non_ifs_lsp_ipv4 = 1;
118
+
119
+ if (closesocket(dummy) == SOCKET_ERROR)
120
+ uv_fatal_error(WSAGetLastError(), "closesocket");
121
+
122
+ } else if (!error_means_no_support(WSAGetLastError())) {
123
+ /* Any error other than "socket type not supported" is fatal. */
124
+ uv_fatal_error(WSAGetLastError(), "socket");
125
+ }
126
+
127
+ /* Detect IPV6 support and non-IFS LSPs */
128
+ dummy = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP);
129
+
130
+ if (dummy != INVALID_SOCKET) {
131
+ opt_len = (int) sizeof protocol_info;
132
+ if (!getsockopt(dummy,
133
+ SOL_SOCKET,
134
+ SO_PROTOCOL_INFOW,
135
+ (char*) &protocol_info,
136
+ &opt_len) == SOCKET_ERROR)
137
+ uv_fatal_error(WSAGetLastError(), "getsockopt");
138
+
139
+ if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
140
+ uv_tcp_non_ifs_lsp_ipv6 = 1;
141
+
142
+ if (closesocket(dummy) == SOCKET_ERROR)
143
+ uv_fatal_error(WSAGetLastError(), "closesocket");
144
+
145
+ } else if (!error_means_no_support(WSAGetLastError())) {
146
+ /* Any error other than "socket type not supported" is fatal. */
147
+ uv_fatal_error(WSAGetLastError(), "socket");
148
+ }
149
+ }
150
+
151
+
152
+ int uv_ntstatus_to_winsock_error(NTSTATUS status) {
153
+ switch (status) {
154
+ case STATUS_SUCCESS:
155
+ return ERROR_SUCCESS;
156
+
157
+ case STATUS_PENDING:
158
+ return ERROR_IO_PENDING;
159
+
160
+ case STATUS_INVALID_HANDLE:
161
+ case STATUS_OBJECT_TYPE_MISMATCH:
162
+ return WSAENOTSOCK;
163
+
164
+ case STATUS_INSUFFICIENT_RESOURCES:
165
+ case STATUS_PAGEFILE_QUOTA:
166
+ case STATUS_COMMITMENT_LIMIT:
167
+ case STATUS_WORKING_SET_QUOTA:
168
+ case STATUS_NO_MEMORY:
169
+ case STATUS_CONFLICTING_ADDRESSES:
170
+ case STATUS_QUOTA_EXCEEDED:
171
+ case STATUS_TOO_MANY_PAGING_FILES:
172
+ case STATUS_REMOTE_RESOURCES:
173
+ case STATUS_TOO_MANY_ADDRESSES:
174
+ return WSAENOBUFS;
175
+
176
+ case STATUS_SHARING_VIOLATION:
177
+ case STATUS_ADDRESS_ALREADY_EXISTS:
178
+ return WSAEADDRINUSE;
179
+
180
+ case STATUS_LINK_TIMEOUT:
181
+ case STATUS_IO_TIMEOUT:
182
+ case STATUS_TIMEOUT:
183
+ return WSAETIMEDOUT;
184
+
185
+ case STATUS_GRACEFUL_DISCONNECT:
186
+ return WSAEDISCON;
187
+
188
+ case STATUS_REMOTE_DISCONNECT:
189
+ case STATUS_CONNECTION_RESET:
190
+ case STATUS_LINK_FAILED:
191
+ case STATUS_CONNECTION_DISCONNECTED:
192
+ case STATUS_PORT_UNREACHABLE:
193
+ case STATUS_HOPLIMIT_EXCEEDED:
194
+ return WSAECONNRESET;
195
+
196
+ case STATUS_LOCAL_DISCONNECT:
197
+ case STATUS_TRANSACTION_ABORTED:
198
+ case STATUS_CONNECTION_ABORTED:
199
+ return WSAECONNABORTED;
200
+
201
+ case STATUS_BAD_NETWORK_PATH:
202
+ case STATUS_NETWORK_UNREACHABLE:
203
+ case STATUS_PROTOCOL_UNREACHABLE:
204
+ return WSAENETUNREACH;
205
+
206
+ case STATUS_HOST_UNREACHABLE:
207
+ return WSAEHOSTUNREACH;
208
+
209
+ case STATUS_CANCELLED:
210
+ case STATUS_REQUEST_ABORTED:
211
+ return WSAEINTR;
212
+
213
+ case STATUS_BUFFER_OVERFLOW:
214
+ case STATUS_INVALID_BUFFER_SIZE:
215
+ return WSAEMSGSIZE;
216
+
217
+ case STATUS_BUFFER_TOO_SMALL:
218
+ case STATUS_ACCESS_VIOLATION:
219
+ return WSAEFAULT;
220
+
221
+ case STATUS_DEVICE_NOT_READY:
222
+ case STATUS_REQUEST_NOT_ACCEPTED:
223
+ return WSAEWOULDBLOCK;
224
+
225
+ case STATUS_INVALID_NETWORK_RESPONSE:
226
+ case STATUS_NETWORK_BUSY:
227
+ case STATUS_NO_SUCH_DEVICE:
228
+ case STATUS_NO_SUCH_FILE:
229
+ case STATUS_OBJECT_PATH_NOT_FOUND:
230
+ case STATUS_OBJECT_NAME_NOT_FOUND:
231
+ case STATUS_UNEXPECTED_NETWORK_ERROR:
232
+ return WSAENETDOWN;
233
+
234
+ case STATUS_INVALID_CONNECTION:
235
+ return WSAENOTCONN;
236
+
237
+ case STATUS_REMOTE_NOT_LISTENING:
238
+ case STATUS_CONNECTION_REFUSED:
239
+ return WSAECONNREFUSED;
240
+
241
+ case STATUS_PIPE_DISCONNECTED:
242
+ return WSAESHUTDOWN;
243
+
244
+ case STATUS_INVALID_ADDRESS:
245
+ case STATUS_INVALID_ADDRESS_COMPONENT:
246
+ return WSAEADDRNOTAVAIL;
247
+
248
+ case STATUS_NOT_SUPPORTED:
249
+ case STATUS_NOT_IMPLEMENTED:
250
+ return WSAEOPNOTSUPP;
251
+
252
+ case STATUS_ACCESS_DENIED:
253
+ return WSAEACCES;
254
+
255
+ default:
256
+ if ((status & (FACILITY_NTWIN32 << 16)) == (FACILITY_NTWIN32 << 16) &&
257
+ (status & (ERROR_SEVERITY_ERROR | ERROR_SEVERITY_WARNING))) {
258
+ /* It's a windows error that has been previously mapped to an */
259
+ /* ntstatus code. */
260
+ return (DWORD) (status & 0xffff);
261
+ } else {
262
+ /* The default fallback for unmappable ntstatus codes. */
263
+ return WSAEINVAL;
264
+ }
265
+ }
266
+ }
267
+
268
+
269
+ /*
270
+ * This function provides a workaround for a bug in the winsock implementation
271
+ * of WSARecv. The problem is that when SetFileCompletionNotificationModes is
272
+ * used to avoid IOCP notifications of completed reads, WSARecv does not
273
+ * reliably indicate whether we can expect a completion package to be posted
274
+ * when the receive buffer is smaller than the received datagram.
275
+ *
276
+ * However it is desirable to use SetFileCompletionNotificationModes because
277
+ * it yields a massive performance increase.
278
+ *
279
+ * This function provides a workaround for that bug, but it only works for the
280
+ * specific case that we need it for. E.g. it assumes that the "avoid iocp"
281
+ * bit has been set, and supports only overlapped operation. It also requires
282
+ * the user to use the default msafd driver, doesn't work when other LSPs are
283
+ * stacked on top of it.
284
+ */
285
+ int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers,
286
+ DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped,
287
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) {
288
+ NTSTATUS status;
289
+ void* apc_context;
290
+ IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal;
291
+ AFD_RECV_INFO info;
292
+ DWORD error;
293
+
294
+ if (overlapped == NULL || completion_routine != NULL) {
295
+ WSASetLastError(WSAEINVAL);
296
+ return SOCKET_ERROR;
297
+ }
298
+
299
+ info.BufferArray = buffers;
300
+ info.BufferCount = buffer_count;
301
+ info.AfdFlags = AFD_OVERLAPPED;
302
+ info.TdiFlags = TDI_RECEIVE_NORMAL;
303
+
304
+ if (*flags & MSG_PEEK) {
305
+ info.TdiFlags |= TDI_RECEIVE_PEEK;
306
+ }
307
+
308
+ if (*flags & MSG_PARTIAL) {
309
+ info.TdiFlags |= TDI_RECEIVE_PARTIAL;
310
+ }
311
+
312
+ if (!((intptr_t) overlapped->hEvent & 1)) {
313
+ apc_context = (void*) overlapped;
314
+ } else {
315
+ apc_context = NULL;
316
+ }
317
+
318
+ iosb->Status = STATUS_PENDING;
319
+ iosb->Pointer = 0;
320
+
321
+ status = pNtDeviceIoControlFile((HANDLE) socket,
322
+ overlapped->hEvent,
323
+ NULL,
324
+ apc_context,
325
+ iosb,
326
+ IOCTL_AFD_RECEIVE,
327
+ &info,
328
+ sizeof(info),
329
+ NULL,
330
+ 0);
331
+
332
+ *flags = 0;
333
+ *bytes = (DWORD) iosb->Information;
334
+
335
+ switch (status) {
336
+ case STATUS_SUCCESS:
337
+ error = ERROR_SUCCESS;
338
+ break;
339
+
340
+ case STATUS_PENDING:
341
+ error = WSA_IO_PENDING;
342
+ break;
343
+
344
+ case STATUS_BUFFER_OVERFLOW:
345
+ error = WSAEMSGSIZE;
346
+ break;
347
+
348
+ case STATUS_RECEIVE_EXPEDITED:
349
+ error = ERROR_SUCCESS;
350
+ *flags = MSG_OOB;
351
+ break;
352
+
353
+ case STATUS_RECEIVE_PARTIAL_EXPEDITED:
354
+ error = ERROR_SUCCESS;
355
+ *flags = MSG_PARTIAL | MSG_OOB;
356
+ break;
357
+
358
+ case STATUS_RECEIVE_PARTIAL:
359
+ error = ERROR_SUCCESS;
360
+ *flags = MSG_PARTIAL;
361
+ break;
362
+
363
+ default:
364
+ error = uv_ntstatus_to_winsock_error(status);
365
+ break;
366
+ }
367
+
368
+ WSASetLastError(error);
369
+
370
+ if (error == ERROR_SUCCESS) {
371
+ return 0;
372
+ } else {
373
+ return SOCKET_ERROR;
374
+ }
375
+ }
376
+
377
+
378
+ /* See description of uv_wsarecv_workaround. */
379
+ int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
380
+ DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr,
381
+ int* addr_len, WSAOVERLAPPED *overlapped,
382
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) {
383
+ NTSTATUS status;
384
+ void* apc_context;
385
+ IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal;
386
+ AFD_RECV_DATAGRAM_INFO info;
387
+ DWORD error;
388
+
389
+ if (overlapped == NULL || addr == NULL || addr_len == NULL ||
390
+ completion_routine != NULL) {
391
+ WSASetLastError(WSAEINVAL);
392
+ return SOCKET_ERROR;
393
+ }
394
+
395
+ info.BufferArray = buffers;
396
+ info.BufferCount = buffer_count;
397
+ info.AfdFlags = AFD_OVERLAPPED;
398
+ info.TdiFlags = TDI_RECEIVE_NORMAL;
399
+ info.Address = addr;
400
+ info.AddressLength = addr_len;
401
+
402
+ if (*flags & MSG_PEEK) {
403
+ info.TdiFlags |= TDI_RECEIVE_PEEK;
404
+ }
405
+
406
+ if (*flags & MSG_PARTIAL) {
407
+ info.TdiFlags |= TDI_RECEIVE_PARTIAL;
408
+ }
409
+
410
+ if (!((intptr_t) overlapped->hEvent & 1)) {
411
+ apc_context = (void*) overlapped;
412
+ } else {
413
+ apc_context = NULL;
414
+ }
415
+
416
+ iosb->Status = STATUS_PENDING;
417
+ iosb->Pointer = 0;
418
+
419
+ status = pNtDeviceIoControlFile((HANDLE) socket,
420
+ overlapped->hEvent,
421
+ NULL,
422
+ apc_context,
423
+ iosb,
424
+ IOCTL_AFD_RECEIVE_DATAGRAM,
425
+ &info,
426
+ sizeof(info),
427
+ NULL,
428
+ 0);
429
+
430
+ *flags = 0;
431
+ *bytes = (DWORD) iosb->Information;
432
+
433
+ switch (status) {
434
+ case STATUS_SUCCESS:
435
+ error = ERROR_SUCCESS;
436
+ break;
437
+
438
+ case STATUS_PENDING:
439
+ error = WSA_IO_PENDING;
440
+ break;
441
+
442
+ case STATUS_BUFFER_OVERFLOW:
443
+ error = WSAEMSGSIZE;
444
+ break;
445
+
446
+ case STATUS_RECEIVE_EXPEDITED:
447
+ error = ERROR_SUCCESS;
448
+ *flags = MSG_OOB;
449
+ break;
450
+
451
+ case STATUS_RECEIVE_PARTIAL_EXPEDITED:
452
+ error = ERROR_SUCCESS;
453
+ *flags = MSG_PARTIAL | MSG_OOB;
454
+ break;
455
+
456
+ case STATUS_RECEIVE_PARTIAL:
457
+ error = ERROR_SUCCESS;
458
+ *flags = MSG_PARTIAL;
459
+ break;
460
+
461
+ default:
462
+ error = uv_ntstatus_to_winsock_error(status);
463
+ break;
464
+ }
465
+
466
+ WSASetLastError(error);
467
+
468
+ if (error == ERROR_SUCCESS) {
469
+ return 0;
470
+ } else {
471
+ return SOCKET_ERROR;
472
+ }
473
+ }
474
+
475
+
476
+ int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
477
+ OVERLAPPED* overlapped) {
478
+ IO_STATUS_BLOCK iosb;
479
+ IO_STATUS_BLOCK* iosb_ptr;
480
+ HANDLE event = NULL;
481
+ void* apc_context;
482
+ NTSTATUS status;
483
+ DWORD error;
484
+
485
+ if (overlapped != NULL) {
486
+ /* Overlapped operation. */
487
+ iosb_ptr = (IO_STATUS_BLOCK*) &overlapped->Internal;
488
+ event = overlapped->hEvent;
489
+
490
+ /* Do not report iocp completion if hEvent is tagged. */
491
+ if ((uintptr_t) event & 1) {
492
+ event = (HANDLE)((uintptr_t) event & ~(uintptr_t) 1);
493
+ apc_context = NULL;
494
+ } else {
495
+ apc_context = overlapped;
496
+ }
497
+
498
+ } else {
499
+ /* Blocking operation. */
500
+ iosb_ptr = &iosb;
501
+ event = CreateEvent(NULL, FALSE, FALSE, NULL);
502
+ if (event == NULL) {
503
+ return SOCKET_ERROR;
504
+ }
505
+ apc_context = NULL;
506
+ }
507
+
508
+ iosb_ptr->Status = STATUS_PENDING;
509
+ status = pNtDeviceIoControlFile((HANDLE) socket,
510
+ event,
511
+ NULL,
512
+ apc_context,
513
+ iosb_ptr,
514
+ IOCTL_AFD_POLL,
515
+ info,
516
+ sizeof *info,
517
+ info,
518
+ sizeof *info);
519
+
520
+ if (overlapped == NULL) {
521
+ /* If this is a blocking operation, wait for the event to become */
522
+ /* signaled, and then grab the real status from the io status block. */
523
+ if (status == STATUS_PENDING) {
524
+ DWORD r = WaitForSingleObject(event, INFINITE);
525
+
526
+ if (r == WAIT_FAILED) {
527
+ DWORD saved_error = GetLastError();
528
+ CloseHandle(event);
529
+ WSASetLastError(saved_error);
530
+ return SOCKET_ERROR;
531
+ }
532
+
533
+ status = iosb.Status;
534
+ }
535
+
536
+ CloseHandle(event);
537
+ }
538
+
539
+ switch (status) {
540
+ case STATUS_SUCCESS:
541
+ error = ERROR_SUCCESS;
542
+ break;
543
+
544
+ case STATUS_PENDING:
545
+ error = WSA_IO_PENDING;
546
+ break;
547
+
548
+ default:
549
+ error = uv_ntstatus_to_winsock_error(status);
550
+ break;
551
+ }
552
+
553
+ WSASetLastError(error);
554
+
555
+ if (error == ERROR_SUCCESS) {
556
+ return 0;
557
+ } else {
558
+ return SOCKET_ERROR;
559
+ }
560
+ }