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.
Files changed (251) hide show
  1. data/README.markdown +3 -0
  2. data/Rakefile +38 -0
  3. data/asyncengine.gemspec +8 -4
  4. data/ext/asyncengine/ae_call_from_other_thread.c +106 -0
  5. data/ext/asyncengine/ae_call_from_other_thread.h +12 -0
  6. data/ext/asyncengine/ae_handle_common.c +193 -48
  7. data/ext/asyncengine/ae_handle_common.h +40 -13
  8. data/ext/asyncengine/ae_ip_utils.c +246 -0
  9. data/ext/asyncengine/ae_ip_utils.h +25 -0
  10. data/ext/asyncengine/ae_next_tick.c +81 -21
  11. data/ext/asyncengine/ae_next_tick.h +4 -2
  12. data/ext/asyncengine/ae_resolver.c +156 -0
  13. data/ext/asyncengine/ae_resolver.h +10 -0
  14. data/ext/asyncengine/ae_tcp.c +908 -0
  15. data/ext/asyncengine/ae_tcp.h +20 -0
  16. data/ext/asyncengine/ae_timer.c +355 -81
  17. data/ext/asyncengine/ae_timer.h +11 -4
  18. data/ext/asyncengine/ae_udp.c +579 -13
  19. data/ext/asyncengine/ae_udp.h +15 -2
  20. data/ext/asyncengine/ae_utils.c +192 -0
  21. data/ext/asyncengine/ae_utils.h +16 -0
  22. data/ext/asyncengine/asyncengine_ruby.c +469 -26
  23. data/ext/asyncengine/asyncengine_ruby.h +49 -11
  24. data/ext/asyncengine/debug.h +68 -0
  25. data/ext/asyncengine/extconf.rb +26 -2
  26. data/ext/asyncengine/ip_parser.c +5954 -0
  27. data/ext/asyncengine/ip_parser.h +16 -0
  28. data/ext/asyncengine/libuv/AUTHORS +16 -0
  29. data/ext/asyncengine/libuv/common.gypi +4 -4
  30. data/ext/asyncengine/libuv/config-mingw.mk +6 -6
  31. data/ext/asyncengine/libuv/config-unix.mk +13 -13
  32. data/ext/asyncengine/libuv/gyp_uv +5 -1
  33. data/ext/asyncengine/libuv/ibc_tests/exec_test.sh +8 -0
  34. data/ext/asyncengine/libuv/ibc_tests/uv_shutdown_write_issue.c +171 -0
  35. data/ext/asyncengine/libuv/ibc_tests/uv_tcp_close_while_connecting.c +102 -0
  36. data/ext/asyncengine/libuv/include/uv-private/ngx-queue.h +3 -1
  37. data/ext/asyncengine/libuv/include/uv-private/uv-unix.h +103 -50
  38. data/ext/asyncengine/libuv/include/uv-private/uv-win.h +76 -24
  39. data/ext/asyncengine/libuv/include/uv.h +353 -88
  40. data/ext/asyncengine/libuv/src/ares/ares__close_sockets.o +0 -0
  41. data/ext/asyncengine/libuv/src/ares/ares__get_hostent.o +0 -0
  42. data/ext/asyncengine/libuv/src/ares/ares__read_line.o +0 -0
  43. data/ext/asyncengine/libuv/src/ares/ares__timeval.o +0 -0
  44. data/ext/asyncengine/libuv/src/ares/ares_cancel.o +0 -0
  45. data/ext/asyncengine/libuv/src/ares/ares_data.o +0 -0
  46. data/ext/asyncengine/libuv/src/ares/ares_destroy.o +0 -0
  47. data/ext/asyncengine/libuv/src/ares/ares_expand_name.o +0 -0
  48. data/ext/asyncengine/libuv/src/ares/ares_expand_string.o +0 -0
  49. data/ext/asyncengine/libuv/src/ares/ares_fds.o +0 -0
  50. data/ext/asyncengine/libuv/src/ares/ares_free_hostent.o +0 -0
  51. data/ext/asyncengine/libuv/src/ares/ares_free_string.o +0 -0
  52. data/ext/asyncengine/libuv/src/ares/ares_gethostbyaddr.o +0 -0
  53. data/ext/asyncengine/libuv/src/ares/ares_gethostbyname.o +0 -0
  54. data/ext/asyncengine/libuv/src/ares/ares_getnameinfo.o +0 -0
  55. data/ext/asyncengine/libuv/src/ares/ares_getopt.o +0 -0
  56. data/ext/asyncengine/libuv/src/ares/ares_getsock.o +0 -0
  57. data/ext/asyncengine/libuv/src/ares/ares_init.o +0 -0
  58. data/ext/asyncengine/libuv/src/ares/ares_library_init.o +0 -0
  59. data/ext/asyncengine/libuv/src/ares/ares_llist.o +0 -0
  60. data/ext/asyncengine/libuv/src/ares/ares_mkquery.o +0 -0
  61. data/ext/asyncengine/libuv/src/ares/ares_nowarn.o +0 -0
  62. data/ext/asyncengine/libuv/src/ares/ares_options.o +0 -0
  63. data/ext/asyncengine/libuv/src/ares/ares_parse_a_reply.o +0 -0
  64. data/ext/asyncengine/libuv/src/ares/ares_parse_aaaa_reply.o +0 -0
  65. data/ext/asyncengine/libuv/src/ares/ares_parse_mx_reply.o +0 -0
  66. data/ext/asyncengine/libuv/src/ares/ares_parse_ns_reply.o +0 -0
  67. data/ext/asyncengine/libuv/src/ares/ares_parse_ptr_reply.o +0 -0
  68. data/ext/asyncengine/libuv/src/ares/ares_parse_srv_reply.o +0 -0
  69. data/ext/asyncengine/libuv/src/ares/ares_parse_txt_reply.o +0 -0
  70. data/ext/asyncengine/libuv/src/ares/ares_process.o +0 -0
  71. data/ext/asyncengine/libuv/src/ares/ares_query.o +0 -0
  72. data/ext/asyncengine/libuv/src/ares/ares_search.o +0 -0
  73. data/ext/asyncengine/libuv/src/ares/ares_send.o +0 -0
  74. data/ext/asyncengine/libuv/src/ares/ares_strcasecmp.o +0 -0
  75. data/ext/asyncengine/libuv/src/ares/ares_strdup.o +0 -0
  76. data/ext/asyncengine/libuv/src/ares/ares_strerror.o +0 -0
  77. data/ext/asyncengine/libuv/src/ares/ares_timeout.o +0 -0
  78. data/ext/asyncengine/libuv/src/ares/ares_version.o +0 -0
  79. data/ext/asyncengine/libuv/src/ares/ares_writev.o +0 -0
  80. data/ext/asyncengine/libuv/src/ares/bitncmp.o +0 -0
  81. data/ext/asyncengine/libuv/src/ares/inet_net_pton.o +0 -0
  82. data/ext/asyncengine/libuv/src/ares/inet_ntop.o +0 -0
  83. data/ext/asyncengine/libuv/src/cares.c +225 -0
  84. data/ext/asyncengine/libuv/src/cares.o +0 -0
  85. data/ext/asyncengine/libuv/src/fs-poll.c +237 -0
  86. data/ext/asyncengine/libuv/src/fs-poll.o +0 -0
  87. data/ext/asyncengine/libuv/src/unix/async.c +78 -17
  88. data/ext/asyncengine/libuv/src/unix/async.o +0 -0
  89. data/ext/asyncengine/libuv/src/unix/core.c +305 -213
  90. data/ext/asyncengine/libuv/src/unix/core.o +0 -0
  91. data/ext/asyncengine/libuv/src/unix/cygwin.c +1 -1
  92. data/ext/asyncengine/libuv/src/unix/darwin.c +2 -1
  93. data/ext/asyncengine/libuv/src/unix/dl.c +36 -44
  94. data/ext/asyncengine/libuv/src/unix/dl.o +0 -0
  95. data/ext/asyncengine/libuv/src/unix/eio/eio.o +0 -0
  96. data/ext/asyncengine/libuv/src/unix/error.c +6 -0
  97. data/ext/asyncengine/libuv/src/unix/error.o +0 -0
  98. data/ext/asyncengine/libuv/src/unix/ev/ev.c +8 -4
  99. data/ext/asyncengine/libuv/src/unix/ev/ev.o +0 -0
  100. data/ext/asyncengine/libuv/src/unix/freebsd.c +1 -1
  101. data/ext/asyncengine/libuv/src/unix/fs.c +25 -33
  102. data/ext/asyncengine/libuv/src/unix/fs.o +0 -0
  103. data/ext/asyncengine/libuv/src/unix/internal.h +50 -31
  104. data/ext/asyncengine/libuv/src/unix/kqueue.c +2 -7
  105. data/ext/asyncengine/libuv/src/unix/linux/core.o +0 -0
  106. data/ext/asyncengine/libuv/src/unix/linux/inotify.c +12 -14
  107. data/ext/asyncengine/libuv/src/unix/linux/inotify.o +0 -0
  108. data/ext/asyncengine/libuv/src/unix/linux/{core.c → linux-core.c} +1 -1
  109. data/ext/asyncengine/libuv/src/unix/linux/linux-core.o +0 -0
  110. data/ext/asyncengine/libuv/src/unix/linux/syscalls.c +147 -1
  111. data/ext/asyncengine/libuv/src/unix/linux/syscalls.h +39 -2
  112. data/ext/asyncengine/libuv/src/unix/linux/syscalls.o +0 -0
  113. data/ext/asyncengine/libuv/src/unix/loop-watcher.c +63 -0
  114. data/ext/asyncengine/libuv/src/unix/loop-watcher.o +0 -0
  115. data/ext/asyncengine/libuv/src/unix/loop.c +29 -6
  116. data/ext/asyncengine/libuv/src/unix/loop.o +0 -0
  117. data/ext/asyncengine/libuv/src/unix/netbsd.c +1 -1
  118. data/ext/asyncengine/libuv/src/unix/openbsd.c +1 -1
  119. data/ext/asyncengine/libuv/src/unix/pipe.c +31 -36
  120. data/ext/asyncengine/libuv/src/unix/pipe.o +0 -0
  121. data/ext/asyncengine/libuv/src/unix/poll.c +116 -0
  122. data/ext/asyncengine/libuv/src/unix/poll.o +0 -0
  123. data/ext/asyncengine/libuv/src/unix/process.c +193 -115
  124. data/ext/asyncengine/libuv/src/unix/process.o +0 -0
  125. data/ext/asyncengine/libuv/src/unix/stream.c +146 -153
  126. data/ext/asyncengine/libuv/src/unix/stream.o +0 -0
  127. data/ext/asyncengine/libuv/src/unix/sunos.c +45 -36
  128. data/ext/asyncengine/libuv/src/unix/tcp.c +6 -5
  129. data/ext/asyncengine/libuv/src/unix/tcp.o +0 -0
  130. data/ext/asyncengine/libuv/src/unix/thread.c +82 -25
  131. data/ext/asyncengine/libuv/src/unix/thread.o +0 -0
  132. data/ext/asyncengine/libuv/src/unix/timer.c +69 -58
  133. data/ext/asyncengine/libuv/src/unix/timer.o +0 -0
  134. data/ext/asyncengine/libuv/src/unix/tty.c +3 -3
  135. data/ext/asyncengine/libuv/src/unix/tty.o +0 -0
  136. data/ext/asyncengine/libuv/src/unix/udp.c +57 -66
  137. data/ext/asyncengine/libuv/src/unix/udp.o +0 -0
  138. data/ext/asyncengine/libuv/src/unix/uv-eio.c +33 -50
  139. data/ext/asyncengine/libuv/src/unix/uv-eio.o +0 -0
  140. data/ext/asyncengine/libuv/src/uv-common.c +68 -38
  141. data/ext/asyncengine/libuv/src/uv-common.h +104 -20
  142. data/ext/asyncengine/libuv/src/uv-common.o +0 -0
  143. data/ext/asyncengine/libuv/src/win/async.c +20 -17
  144. data/ext/asyncengine/libuv/src/win/core.c +44 -31
  145. data/ext/asyncengine/libuv/src/win/dl.c +40 -36
  146. data/ext/asyncengine/libuv/src/win/error.c +21 -1
  147. data/ext/asyncengine/libuv/src/win/fs-event.c +19 -21
  148. data/ext/asyncengine/libuv/src/win/fs.c +541 -189
  149. data/ext/asyncengine/libuv/src/win/getaddrinfo.c +56 -63
  150. data/ext/asyncengine/libuv/src/win/handle-inl.h +145 -0
  151. data/ext/asyncengine/libuv/src/win/handle.c +26 -101
  152. data/ext/asyncengine/libuv/src/win/internal.h +92 -107
  153. data/ext/asyncengine/libuv/src/win/loop-watcher.c +6 -14
  154. data/ext/asyncengine/libuv/src/win/pipe.c +78 -64
  155. data/ext/asyncengine/libuv/src/win/poll.c +618 -0
  156. data/ext/asyncengine/libuv/src/win/process-stdio.c +479 -0
  157. data/ext/asyncengine/libuv/src/win/process.c +147 -274
  158. data/ext/asyncengine/libuv/src/win/req-inl.h +225 -0
  159. data/ext/asyncengine/libuv/src/win/req.c +0 -149
  160. data/ext/asyncengine/libuv/src/{unix/check.c → win/stream-inl.h} +31 -42
  161. data/ext/asyncengine/libuv/src/win/stream.c +9 -43
  162. data/ext/asyncengine/libuv/src/win/tcp.c +200 -82
  163. data/ext/asyncengine/libuv/src/win/thread.c +42 -2
  164. data/ext/asyncengine/libuv/src/win/threadpool.c +3 -2
  165. data/ext/asyncengine/libuv/src/win/timer.c +13 -63
  166. data/ext/asyncengine/libuv/src/win/tty.c +26 -20
  167. data/ext/asyncengine/libuv/src/win/udp.c +26 -17
  168. data/ext/asyncengine/libuv/src/win/util.c +312 -167
  169. data/ext/asyncengine/libuv/src/win/winapi.c +16 -1
  170. data/ext/asyncengine/libuv/src/win/winapi.h +33 -9
  171. data/ext/asyncengine/libuv/src/win/winsock.c +88 -1
  172. data/ext/asyncengine/libuv/src/win/winsock.h +36 -3
  173. data/ext/asyncengine/libuv/test/benchmark-ares.c +16 -17
  174. data/ext/asyncengine/libuv/test/benchmark-fs-stat.c +164 -0
  175. data/ext/asyncengine/libuv/test/benchmark-list.h +9 -0
  176. data/ext/asyncengine/libuv/{src/unix/prepare.c → test/benchmark-loop-count.c} +42 -33
  177. data/ext/asyncengine/libuv/test/benchmark-million-timers.c +65 -0
  178. data/ext/asyncengine/libuv/test/benchmark-pound.c +1 -1
  179. data/ext/asyncengine/libuv/test/benchmark-sizes.c +2 -0
  180. data/ext/asyncengine/libuv/test/benchmark-spawn.c +7 -1
  181. data/ext/asyncengine/libuv/test/benchmark-udp-packet-storm.c +1 -1
  182. data/ext/asyncengine/libuv/test/echo-server.c +8 -0
  183. data/ext/asyncengine/libuv/test/run-tests.c +30 -0
  184. data/ext/asyncengine/libuv/test/runner-unix.c +6 -26
  185. data/ext/asyncengine/libuv/test/runner-win.c +5 -63
  186. data/ext/asyncengine/libuv/test/runner.c +10 -1
  187. data/ext/asyncengine/libuv/test/task.h +0 -8
  188. data/ext/asyncengine/libuv/test/test-async.c +43 -141
  189. data/ext/asyncengine/libuv/test/test-callback-order.c +76 -0
  190. data/ext/asyncengine/libuv/test/test-counters-init.c +2 -3
  191. data/ext/asyncengine/libuv/test/test-dlerror.c +17 -8
  192. data/ext/asyncengine/libuv/test/test-fs-event.c +31 -39
  193. data/ext/asyncengine/libuv/test/test-fs-poll.c +146 -0
  194. data/ext/asyncengine/libuv/test/test-fs.c +114 -2
  195. data/ext/asyncengine/libuv/test/test-gethostbyname.c +8 -8
  196. data/ext/asyncengine/libuv/test/test-hrtime.c +18 -15
  197. data/ext/asyncengine/libuv/test/test-ipc.c +8 -2
  198. data/ext/asyncengine/libuv/test/test-list.h +59 -9
  199. data/ext/asyncengine/libuv/test/test-loop-handles.c +2 -25
  200. data/ext/asyncengine/libuv/{src/unix/idle.c → test/test-poll-close.c} +37 -39
  201. data/ext/asyncengine/libuv/test/test-poll.c +573 -0
  202. data/ext/asyncengine/libuv/test/test-ref.c +79 -63
  203. data/ext/asyncengine/libuv/test/test-run-once.c +15 -11
  204. data/ext/asyncengine/libuv/test/test-semaphore.c +111 -0
  205. data/ext/asyncengine/libuv/test/test-spawn.c +368 -20
  206. data/ext/asyncengine/libuv/test/test-stdio-over-pipes.c +25 -35
  207. data/ext/asyncengine/libuv/test/test-tcp-close-while-connecting.c +80 -0
  208. data/ext/asyncengine/libuv/test/test-tcp-close.c +1 -1
  209. data/ext/asyncengine/libuv/test/test-tcp-connect-error-after-write.c +95 -0
  210. data/ext/asyncengine/libuv/test/test-tcp-connect-timeout.c +85 -0
  211. data/ext/asyncengine/libuv/test/test-tcp-shutdown-after-write.c +131 -0
  212. data/ext/asyncengine/libuv/test/test-tcp-write-error.c +2 -2
  213. data/ext/asyncengine/libuv/test/test-tcp-writealot.c +29 -54
  214. data/ext/asyncengine/libuv/test/test-timer-again.c +1 -1
  215. data/ext/asyncengine/libuv/test/test-timer.c +23 -1
  216. data/ext/asyncengine/libuv/test/test-udp-options.c +1 -1
  217. data/ext/asyncengine/libuv/test/{test-eio-overflow.c → test-walk-handles.c} +31 -44
  218. data/ext/asyncengine/libuv/uv.gyp +26 -9
  219. data/ext/asyncengine/rb_utilities.c +54 -0
  220. data/ext/asyncengine/rb_utilities.h +63 -0
  221. data/lib/asyncengine.rb +45 -38
  222. data/lib/asyncengine/asyncengine_ext.so +0 -0
  223. data/lib/asyncengine/debug.rb +37 -0
  224. data/lib/asyncengine/handle.rb +9 -0
  225. data/lib/asyncengine/tcp.rb +28 -0
  226. data/lib/asyncengine/timer.rb +18 -28
  227. data/lib/asyncengine/udp.rb +29 -0
  228. data/lib/asyncengine/utils.rb +32 -0
  229. data/lib/asyncengine/uv_error.rb +17 -0
  230. data/lib/asyncengine/version.rb +9 -1
  231. data/test/ae_test_helper.rb +62 -0
  232. data/test/test_basic.rb +169 -0
  233. data/test/test_call_from_other_thread.rb +55 -0
  234. data/test/test_error.rb +92 -0
  235. data/test/test_ip_utils.rb +44 -0
  236. data/test/test_next_tick.rb +37 -0
  237. data/test/test_resolver.rb +51 -0
  238. data/test/test_threads.rb +69 -0
  239. data/test/test_timer.rb +95 -0
  240. data/test/test_udp.rb +216 -0
  241. data/test/test_utils.rb +49 -0
  242. metadata +84 -57
  243. data/ext/asyncengine/libuv/mkmf.log +0 -24
  244. data/ext/asyncengine/libuv/src/unix/cares.c +0 -194
  245. data/ext/asyncengine/libuv/src/unix/cares.o +0 -0
  246. data/ext/asyncengine/libuv/src/unix/check.o +0 -0
  247. data/ext/asyncengine/libuv/src/unix/idle.o +0 -0
  248. data/ext/asyncengine/libuv/src/unix/prepare.o +0 -0
  249. data/ext/asyncengine/libuv/src/win/cares.c +0 -290
  250. data/lib/asyncengine/errors.rb +0 -5
  251. data/lib/asyncengine/next_tick.rb +0 -24
@@ -22,17 +22,22 @@
22
22
  #include <assert.h>
23
23
 
24
24
  #include "uv.h"
25
- #include "../uv-common.h"
26
25
  #include "internal.h"
27
26
 
28
27
 
28
+ /* Ntdll function pointers */
29
29
  sRtlNtStatusToDosError pRtlNtStatusToDosError;
30
30
  sNtDeviceIoControlFile pNtDeviceIoControlFile;
31
31
  sNtQueryInformationFile pNtQueryInformationFile;
32
32
  sNtSetInformationFile pNtSetInformationFile;
33
+ sNtQuerySystemInformation pNtQuerySystemInformation;
34
+
35
+
36
+ /* Kernel32 function pointers */
33
37
  sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
34
38
  sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
35
39
  sCreateSymbolicLinkW pCreateSymbolicLinkW;
40
+ sCancelIoEx pCancelIoEx;
36
41
  sInitializeSRWLock pInitializeSRWLock;
37
42
  sAcquireSRWLockShared pAcquireSRWLockShared;
38
43
  sAcquireSRWLockExclusive pAcquireSRWLockExclusive;
@@ -79,6 +84,13 @@ void uv_winapi_init() {
79
84
  uv_fatal_error(GetLastError(), "GetProcAddress");
80
85
  }
81
86
 
87
+ pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress(
88
+ ntdll_module,
89
+ "NtQuerySystemInformation");
90
+ if (pNtQuerySystemInformation == NULL) {
91
+ uv_fatal_error(GetLastError(), "GetProcAddress");
92
+ }
93
+
82
94
  kernel32_module = GetModuleHandleA("kernel32.dll");
83
95
  if (kernel32_module == NULL) {
84
96
  uv_fatal_error(GetLastError(), "GetModuleHandleA");
@@ -94,6 +106,9 @@ void uv_winapi_init() {
94
106
  pCreateSymbolicLinkW = (sCreateSymbolicLinkW)
95
107
  GetProcAddress(kernel32_module, "CreateSymbolicLinkW");
96
108
 
109
+ pCancelIoEx = (sCancelIoEx)
110
+ GetProcAddress(kernel32_module, "CancelIoEx");
111
+
97
112
  pInitializeSRWLock = (sInitializeSRWLock)
98
113
  GetProcAddress(kernel32_module, "InitializeSRWLock");
99
114
 
@@ -28,11 +28,6 @@
28
28
  /*
29
29
  * Ntdll headers
30
30
  */
31
- #ifndef _NTDEF_
32
- typedef LONG NTSTATUS;
33
- typedef NTSTATUS *PNTSTATUS;
34
- #endif
35
-
36
31
  #ifndef STATUS_SEVERITY_SUCCESS
37
32
  # define STATUS_SEVERITY_SUCCESS 0x0
38
33
  #endif
@@ -4079,8 +4074,8 @@
4079
4074
  (FACILITY_NTWIN32 << 16) | ERROR_SEVERITY_WARNING)))
4080
4075
 
4081
4076
  /* from ntifs.h */
4082
- /* MinGW already has it */
4083
- #if defined(_MSC_VER) || defined(__MINGW64__)
4077
+ /* MinGW already has it, mingw-w64 does not. */
4078
+ #if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
4084
4079
  typedef struct _REPARSE_DATA_BUFFER {
4085
4080
  ULONG ReparseTag;
4086
4081
  USHORT ReparseDataLength;
@@ -4141,6 +4136,10 @@ typedef struct _FILE_MODE_INFORMATION {
4141
4136
  ULONG Mode;
4142
4137
  } FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;
4143
4138
 
4139
+ typedef struct _FILE_END_OF_FILE_INFORMATION {
4140
+ LARGE_INTEGER EndOfFile;
4141
+ } FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;
4142
+
4144
4143
  #define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
4145
4144
  #define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
4146
4145
 
@@ -4203,6 +4202,19 @@ typedef enum _FILE_INFORMATION_CLASS {
4203
4202
  FileMaximumInformation
4204
4203
  } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
4205
4204
 
4205
+ typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
4206
+ LARGE_INTEGER IdleTime;
4207
+ LARGE_INTEGER KernelTime;
4208
+ LARGE_INTEGER UserTime;
4209
+ LARGE_INTEGER DpcTime;
4210
+ LARGE_INTEGER InterruptTime;
4211
+ ULONG InterruptCount;
4212
+ } SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
4213
+
4214
+ #ifndef SystemProcessorPerformanceInformation
4215
+ # define SystemProcessorPerformanceInformation 8
4216
+ #endif
4217
+
4206
4218
  #ifndef DEVICE_TYPE
4207
4219
  # define DEVICE_TYPE DWORD
4208
4220
  #endif
@@ -4319,6 +4331,12 @@ typedef NTSTATUS (NTAPI *sNtSetInformationFile)
4319
4331
  ULONG Length,
4320
4332
  FILE_INFORMATION_CLASS FileInformationClass);
4321
4333
 
4334
+ typedef NTSTATUS (NTAPI *sNtQuerySystemInformation)
4335
+ (UINT SystemInformationClass,
4336
+ PVOID SystemInformation,
4337
+ ULONG SystemInformationLength,
4338
+ PULONG ReturnLength);
4339
+
4322
4340
 
4323
4341
  /*
4324
4342
  * Kernel32 headers
@@ -4335,7 +4353,7 @@ typedef NTSTATUS (NTAPI *sNtSetInformationFile)
4335
4353
  # define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
4336
4354
  #endif
4337
4355
 
4338
- #ifdef __MINGW32__
4356
+ #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
4339
4357
  typedef struct _OVERLAPPED_ENTRY {
4340
4358
  ULONG_PTR lpCompletionKey;
4341
4359
  LPOVERLAPPED lpOverlapped;
@@ -4374,6 +4392,10 @@ typedef BOOLEAN (WINAPI* sCreateSymbolicLinkW)
4374
4392
  LPCWSTR lpTargetFileName,
4375
4393
  DWORD dwFlags);
4376
4394
 
4395
+ typedef BOOL (WINAPI* sCancelIoEx)
4396
+ (HANDLE hFile,
4397
+ LPOVERLAPPED lpOverlapped);
4398
+
4377
4399
  typedef VOID (WINAPI* sInitializeSRWLock)
4378
4400
  (PSRWLOCK SRWLock);
4379
4401
 
@@ -4397,17 +4419,19 @@ typedef VOID (WINAPI* sReleaseSRWLockExclusive)
4397
4419
 
4398
4420
 
4399
4421
 
4400
- /* Ntapi function pointers */
4422
+ /* Ntdll function pointers */
4401
4423
  extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
4402
4424
  extern sNtDeviceIoControlFile pNtDeviceIoControlFile;
4403
4425
  extern sNtQueryInformationFile pNtQueryInformationFile;
4404
4426
  extern sNtSetInformationFile pNtSetInformationFile;
4427
+ extern sNtQuerySystemInformation pNtQuerySystemInformation;
4405
4428
 
4406
4429
 
4407
4430
  /* Kernel32 function pointers */
4408
4431
  extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
4409
4432
  extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
4410
4433
  extern sCreateSymbolicLinkW pCreateSymbolicLinkW;
4434
+ extern sCancelIoEx pCancelIoEx;
4411
4435
  extern sInitializeSRWLock pInitializeSRWLock;
4412
4436
  extern sAcquireSRWLockShared pAcquireSRWLockShared;
4413
4437
  extern sAcquireSRWLockExclusive pAcquireSRWLockExclusive;
@@ -22,9 +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
26
 
27
+
28
28
  /* Whether ipv6 is supported */
29
29
  int uv_allow_ipv6;
30
30
 
@@ -468,3 +468,90 @@ int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
468
468
  return SOCKET_ERROR;
469
469
  }
470
470
  }
471
+
472
+
473
+ int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
474
+ OVERLAPPED* overlapped) {
475
+ IO_STATUS_BLOCK iosb;
476
+ IO_STATUS_BLOCK* iosb_ptr;
477
+ HANDLE event = NULL;
478
+ void* apc_context;
479
+ NTSTATUS status;
480
+ DWORD error;
481
+
482
+ if (overlapped != NULL) {
483
+ /* Overlapped operation. */
484
+ iosb_ptr = (IO_STATUS_BLOCK*) &overlapped->Internal;
485
+ event = overlapped->hEvent;
486
+
487
+ /* Do not report iocp completion if hEvent is tagged. */
488
+ if ((uintptr_t) event & 1) {
489
+ event = (HANDLE)((uintptr_t) event & ~(uintptr_t) 1);
490
+ apc_context = NULL;
491
+ } else {
492
+ apc_context = overlapped;
493
+ }
494
+
495
+ } else {
496
+ /* Blocking operation. */
497
+ iosb_ptr = &iosb;
498
+ event = CreateEvent(NULL, FALSE, FALSE, NULL);
499
+ if (event == NULL) {
500
+ return SOCKET_ERROR;
501
+ }
502
+ apc_context = NULL;
503
+ }
504
+
505
+ iosb_ptr->Status = STATUS_PENDING;
506
+ status = pNtDeviceIoControlFile((HANDLE) socket,
507
+ event,
508
+ NULL,
509
+ apc_context,
510
+ iosb_ptr,
511
+ IOCTL_AFD_POLL,
512
+ info,
513
+ sizeof *info,
514
+ info,
515
+ sizeof *info);
516
+
517
+ if (overlapped == NULL) {
518
+ /* If this is a blocking operation, wait for the event to become */
519
+ /* signaled, and then grab the real status from the io status block. */
520
+ if (status == STATUS_PENDING) {
521
+ DWORD r = WaitForSingleObject(event, INFINITE);
522
+
523
+ if (r == WAIT_FAILED) {
524
+ DWORD saved_error = GetLastError();
525
+ CloseHandle(event);
526
+ WSASetLastError(saved_error);
527
+ return SOCKET_ERROR;
528
+ }
529
+
530
+ status = iosb.Status;
531
+ }
532
+
533
+ CloseHandle(event);
534
+ }
535
+
536
+ switch (status) {
537
+ case STATUS_SUCCESS:
538
+ error = ERROR_SUCCESS;
539
+ break;
540
+
541
+ case STATUS_PENDING:
542
+ error = WSA_IO_PENDING;
543
+ break;
544
+
545
+ default:
546
+ error = uv_ntstatus_to_winsock_error(status);
547
+ break;
548
+ }
549
+
550
+ WSASetLastError(error);
551
+
552
+ if (error == ERROR_SUCCESS) {
553
+ return 0;
554
+ } else {
555
+ return SOCKET_ERROR;
556
+ }
557
+ }
@@ -43,11 +43,15 @@
43
43
  #endif
44
44
 
45
45
  #ifndef IPV6_V6ONLY
46
- #define IPV6_V6ONLY 27
46
+ # define IPV6_V6ONLY 27
47
47
  #endif
48
48
 
49
49
  #ifndef IPV6_HOPLIMIT
50
- #define IPV6_HOPLIMIT 21
50
+ # define IPV6_HOPLIMIT 21
51
+ #endif
52
+
53
+ #ifndef SIO_BASE_HANDLE
54
+ # define SIO_BASE_HANDLE 0x48000022
51
55
  #endif
52
56
 
53
57
  /*
@@ -81,6 +85,32 @@
81
85
  #define AFD_OVERLAPPED 0x00000002
82
86
  #define AFD_IMMEDIATE 0x00000004
83
87
 
88
+ #define AFD_POLL_RECEIVE_BIT 0
89
+ #define AFD_POLL_RECEIVE (1 << AFD_POLL_RECEIVE_BIT)
90
+ #define AFD_POLL_RECEIVE_EXPEDITED_BIT 1
91
+ #define AFD_POLL_RECEIVE_EXPEDITED (1 << AFD_POLL_RECEIVE_EXPEDITED_BIT)
92
+ #define AFD_POLL_SEND_BIT 2
93
+ #define AFD_POLL_SEND (1 << AFD_POLL_SEND_BIT)
94
+ #define AFD_POLL_DISCONNECT_BIT 3
95
+ #define AFD_POLL_DISCONNECT (1 << AFD_POLL_DISCONNECT_BIT)
96
+ #define AFD_POLL_ABORT_BIT 4
97
+ #define AFD_POLL_ABORT (1 << AFD_POLL_ABORT_BIT)
98
+ #define AFD_POLL_LOCAL_CLOSE_BIT 5
99
+ #define AFD_POLL_LOCAL_CLOSE (1 << AFD_POLL_LOCAL_CLOSE_BIT)
100
+ #define AFD_POLL_CONNECT_BIT 6
101
+ #define AFD_POLL_CONNECT (1 << AFD_POLL_CONNECT_BIT)
102
+ #define AFD_POLL_ACCEPT_BIT 7
103
+ #define AFD_POLL_ACCEPT (1 << AFD_POLL_ACCEPT_BIT)
104
+ #define AFD_POLL_CONNECT_FAIL_BIT 8
105
+ #define AFD_POLL_CONNECT_FAIL (1 << AFD_POLL_CONNECT_FAIL_BIT)
106
+ #define AFD_POLL_QOS_BIT 9
107
+ #define AFD_POLL_QOS (1 << AFD_POLL_QOS_BIT)
108
+ #define AFD_POLL_GROUP_QOS_BIT 10
109
+ #define AFD_POLL_GROUP_QOS (1 << AFD_POLL_GROUP_QOS_BIT)
110
+
111
+ #define AFD_NUM_POLL_EVENTS 11
112
+ #define AFD_POLL_ALL ((1 << AFD_NUM_POLL_EVENTS) - 1)
113
+
84
114
  typedef struct _AFD_RECV_DATAGRAM_INFO {
85
115
  LPWSABUF BufferArray;
86
116
  ULONG BufferCount;
@@ -105,6 +135,7 @@ typedef struct _AFD_RECV_INFO {
105
135
 
106
136
  #define AFD_RECEIVE 5
107
137
  #define AFD_RECEIVE_DATAGRAM 6
138
+ #define AFD_POLL 9
108
139
 
109
140
  #define IOCTL_AFD_RECEIVE \
110
141
  _AFD_CONTROL_CODE(AFD_RECEIVE, METHOD_NEITHER)
@@ -112,8 +143,10 @@ typedef struct _AFD_RECV_INFO {
112
143
  #define IOCTL_AFD_RECEIVE_DATAGRAM \
113
144
  _AFD_CONTROL_CODE(AFD_RECEIVE_DATAGRAM, METHOD_NEITHER)
114
145
 
115
- #if defined(__MINGW32__) && !defined(__MINGW64__)
146
+ #define IOCTL_AFD_POLL \
147
+ _AFD_CONTROL_CODE(AFD_POLL, METHOD_BUFFERED)
116
148
 
149
+ #if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
117
150
  typedef struct _IP_ADAPTER_UNICAST_ADDRESS_XP {
118
151
  /* FIXME: __C89_NAMELESS was removed */
119
152
  /* __C89_NAMELESS */ union {
@@ -41,16 +41,16 @@ static int argument;
41
41
  static int64_t start_time;
42
42
  static int64_t end_time;
43
43
 
44
- /* callback method. may issue another call */
45
- static void aresbynamecallback( void *arg,
46
- int status,
47
- int timeouts,
48
- struct hostent *hostent) {
49
- ares_callbacks++;
50
- if (status != 0) {
51
- ares_errors++;
52
- }
53
44
 
45
+ /* callback method. */
46
+ static void aresbynamecallback(void *arg,
47
+ int status,
48
+ int timeouts,
49
+ struct hostent *hostent) {
50
+ ares_callbacks++;
51
+ if (status != 0) {
52
+ ares_errors++;
53
+ }
54
54
  }
55
55
 
56
56
 
@@ -89,30 +89,29 @@ BENCHMARK_IMPL(gethostbyname) {
89
89
  ares_callbacks = 0;
90
90
  ares_errors = 0;
91
91
 
92
- uv_update_time(loop);
93
- start_time = uv_now(loop);
92
+ start_time = uv_hrtime();
94
93
 
95
94
  prep_tcploopback();
96
95
 
97
96
  for (ares_start = 0; ares_start < NUM_CALLS_TO_START; ares_start++) {
98
97
  ares_gethostbyname(channel,
99
- "echos.srv",
100
- AF_INET,
101
- &aresbynamecallback,
102
- &argument);
98
+ "echos.srv",
99
+ AF_INET,
100
+ &aresbynamecallback,
101
+ &argument);
103
102
  }
104
103
 
105
104
  uv_run(loop);
106
105
 
107
106
  uv_ares_destroy(loop, channel);
108
107
 
109
- end_time = uv_now(loop);
108
+ end_time = uv_hrtime();
110
109
 
111
110
  if (ares_errors > 0) {
112
111
  printf("There were %d failures\n", ares_errors);
113
112
  }
114
113
  LOGF("ares_gethostbyname: %.0f req/s\n",
115
- 1000.0 * ares_callbacks / (double)(end_time - start_time));
114
+ 1e9 * ares_callbacks / (double)(end_time - start_time));
116
115
 
117
116
  return 0;
118
117
  }
@@ -0,0 +1,164 @@
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 "task.h"
23
+ #include "uv.h"
24
+
25
+ #include <stdio.h>
26
+ #include <stdlib.h>
27
+
28
+ #define NUM_SYNC_REQS (10 * 1e5)
29
+ #define NUM_ASYNC_REQS (1 * 1e5)
30
+ #define MAX_CONCURRENT_REQS 32
31
+
32
+ #define sync_stat(req, path) \
33
+ do { \
34
+ uv_fs_stat(uv_default_loop(), (req), (path), NULL); \
35
+ uv_fs_req_cleanup((req)); \
36
+ } \
37
+ while (0)
38
+
39
+ struct async_req {
40
+ const char* path;
41
+ uv_fs_t fs_req;
42
+ int* count;
43
+ };
44
+
45
+
46
+ static const char* fmt(double d) {
47
+ uint64_t v;
48
+ char* p;
49
+
50
+ p = (char *) calloc(1, 32) + 31; /* leaks memory */
51
+ v = d;
52
+
53
+ #if 0 /* works but we don't care about fractional precision */
54
+ if (d - v >= 0.01) {
55
+ *--p = '0' + (uint64_t) (d * 100) % 10;
56
+ *--p = '0' + (uint64_t) (d * 10) % 10;
57
+ *--p = '.';
58
+ }
59
+ #endif
60
+
61
+ if (v == 0)
62
+ *--p = '0';
63
+
64
+ while (v) {
65
+ if (v) *--p = '0' + (v % 10), v /= 10;
66
+ if (v) *--p = '0' + (v % 10), v /= 10;
67
+ if (v) *--p = '0' + (v % 10), v /= 10;
68
+ if (v) *--p = ',';
69
+ }
70
+
71
+ return p;
72
+ }
73
+
74
+
75
+ static void warmup(const char* path) {
76
+ uv_fs_t reqs[MAX_CONCURRENT_REQS];
77
+ int i;
78
+
79
+ /* warm up the thread pool */
80
+ for (i = 0; i < ARRAY_SIZE(reqs); i++)
81
+ uv_fs_stat(uv_default_loop(), reqs + i, path, uv_fs_req_cleanup);
82
+
83
+ uv_run(uv_default_loop());
84
+
85
+ /* warm up the OS dirent cache */
86
+ for (i = 0; i < 16; i++)
87
+ sync_stat(reqs + 0, path);
88
+ }
89
+
90
+
91
+ static void sync_bench(const char* path) {
92
+ uint64_t before;
93
+ uint64_t after;
94
+ uv_fs_t req;
95
+ int i;
96
+
97
+ /* do the sync benchmark */
98
+ before = uv_hrtime();
99
+
100
+ for (i = 0; i < NUM_SYNC_REQS; i++)
101
+ sync_stat(&req, path);
102
+
103
+ after = uv_hrtime();
104
+
105
+ printf("%s stats (sync): %.2fs (%s/s)\n",
106
+ fmt(1.0 * NUM_SYNC_REQS),
107
+ (after - before) / 1e9,
108
+ fmt((1.0 * NUM_SYNC_REQS) / ((after - before) / 1e9)));
109
+ fflush(stdout);
110
+ }
111
+
112
+
113
+ static void stat_cb(uv_fs_t* fs_req) {
114
+ struct async_req* req = container_of(fs_req, struct async_req, fs_req);
115
+ uv_fs_req_cleanup(&req->fs_req);
116
+ if (*req->count == 0) return;
117
+ uv_fs_stat(uv_default_loop(), &req->fs_req, req->path, stat_cb);
118
+ (*req->count)--;
119
+ }
120
+
121
+
122
+ static void async_bench(const char* path) {
123
+ struct async_req reqs[MAX_CONCURRENT_REQS];
124
+ struct async_req* req;
125
+ uint64_t before;
126
+ uint64_t after;
127
+ int count;
128
+ int i;
129
+
130
+ for (i = 1; i <= MAX_CONCURRENT_REQS; i++) {
131
+ count = NUM_ASYNC_REQS;
132
+
133
+ for (req = reqs; req < reqs + i; req++) {
134
+ req->path = path;
135
+ req->count = &count;
136
+ uv_fs_stat(uv_default_loop(), &req->fs_req, req->path, stat_cb);
137
+ }
138
+
139
+ before = uv_hrtime();
140
+ uv_run(uv_default_loop());
141
+ after = uv_hrtime();
142
+
143
+ printf("%s stats (%d concurrent): %.2fs (%s/s)\n",
144
+ fmt(1.0 * NUM_ASYNC_REQS),
145
+ i,
146
+ (after - before) / 1e9,
147
+ fmt((1.0 * NUM_ASYNC_REQS) / ((after - before) / 1e9)));
148
+ fflush(stdout);
149
+ }
150
+ }
151
+
152
+
153
+ /* This benchmark aims to measure the overhead of doing I/O syscalls from
154
+ * the thread pool. The stat() syscall was chosen because its results are
155
+ * easy for the operating system to cache, taking the actual I/O overhead
156
+ * out of the equation.
157
+ */
158
+ BENCHMARK_IMPL(fs_stat) {
159
+ const char path[] = ".";
160
+ warmup(path);
161
+ sync_bench(path);
162
+ async_bench(path);
163
+ return 0;
164
+ }