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.
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
+ }