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
@@ -38,6 +38,7 @@
38
38
  static void uv__stream_connect(uv_stream_t*);
39
39
  static void uv__write(uv_stream_t* stream);
40
40
  static void uv__read(uv_stream_t* stream);
41
+ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, int events);
41
42
 
42
43
 
43
44
  static size_t uv__buf_count(uv_buf_t bufs[], int bufcnt) {
@@ -62,23 +63,16 @@ void uv__stream_init(uv_loop_t* loop,
62
63
  stream->close_cb = NULL;
63
64
  stream->connection_cb = NULL;
64
65
  stream->connect_req = NULL;
66
+ stream->shutdown_req = NULL;
65
67
  stream->accepted_fd = -1;
66
68
  stream->fd = -1;
67
69
  stream->delayed_error = 0;
68
- stream->blocking = 0;
69
70
  ngx_queue_init(&stream->write_queue);
70
71
  ngx_queue_init(&stream->write_completed_queue);
71
72
  stream->write_queue_size = 0;
72
73
 
73
- ev_init(&stream->read_watcher, uv__stream_io);
74
- stream->read_watcher.data = stream;
75
-
76
- ev_init(&stream->write_watcher, uv__stream_io);
77
- stream->write_watcher.data = stream;
78
-
79
- assert(ngx_queue_empty(&stream->write_queue));
80
- assert(ngx_queue_empty(&stream->write_completed_queue));
81
- assert(stream->write_queue_size == 0);
74
+ uv__io_init(&stream->read_watcher, uv__stream_io, -1, 0);
75
+ uv__io_init(&stream->write_watcher, uv__stream_io, -1, 0);
82
76
  }
83
77
 
84
78
 
@@ -110,13 +104,9 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
110
104
  }
111
105
  }
112
106
 
113
- /* Associate the fd with each ev_io watcher. */
114
- ev_io_set(&stream->read_watcher, fd, EV_READ);
115
- ev_io_set(&stream->write_watcher, fd, EV_WRITE);
116
-
117
- /* These should have been set up by uv_tcp_init or uv_pipe_init. */
118
- assert(stream->read_watcher.cb == uv__stream_io);
119
- assert(stream->write_watcher.cb == uv__stream_io);
107
+ /* Associate the fd with each watcher. */
108
+ uv__io_set(&stream->read_watcher, uv__stream_io, fd, UV__IO_READ);
109
+ uv__io_set(&stream->write_watcher, uv__stream_io, fd, UV__IO_WRITE);
120
110
 
121
111
  return 0;
122
112
  }
@@ -128,11 +118,20 @@ void uv__stream_destroy(uv_stream_t* stream) {
128
118
 
129
119
  assert(stream->flags & UV_CLOSED);
130
120
 
121
+ if (stream->connect_req) {
122
+ uv__req_unregister(stream->loop, stream->connect_req);
123
+ uv__set_artificial_error(stream->loop, UV_EINTR);
124
+ stream->connect_req->cb(stream->connect_req, -1);
125
+ stream->connect_req = NULL;
126
+ }
127
+
131
128
  while (!ngx_queue_empty(&stream->write_queue)) {
132
129
  q = ngx_queue_head(&stream->write_queue);
133
130
  ngx_queue_remove(q);
134
131
 
135
132
  req = ngx_queue_data(q, uv_write_t, queue);
133
+ uv__req_unregister(stream->loop, req);
134
+
136
135
  if (req->bufs != req->bufsml)
137
136
  free(req->bufs);
138
137
 
@@ -147,35 +146,32 @@ void uv__stream_destroy(uv_stream_t* stream) {
147
146
  ngx_queue_remove(q);
148
147
 
149
148
  req = ngx_queue_data(q, uv_write_t, queue);
149
+ uv__req_unregister(stream->loop, req);
150
+
150
151
  if (req->cb) {
151
152
  uv__set_sys_error(stream->loop, req->error);
152
153
  req->cb(req, req->error ? -1 : 0);
153
154
  }
154
155
  }
155
156
 
156
- if (stream->flags & UV_SHUTTING) {
157
- uv_shutdown_t* req = stream->shutdown_req;
158
- if (req && req->cb) {
159
- uv__set_artificial_error(stream->loop, UV_EINTR);
160
- req->cb(req, -1);
161
- }
157
+ if (stream->shutdown_req) {
158
+ uv__req_unregister(stream->loop, stream->shutdown_req);
159
+ uv__set_artificial_error(stream->loop, UV_EINTR);
160
+ stream->shutdown_req->cb(stream->shutdown_req, -1);
161
+ stream->shutdown_req = NULL;
162
162
  }
163
163
  }
164
164
 
165
165
 
166
- void uv__server_io(EV_P_ ev_io* watcher, int revents) {
166
+ void uv__server_io(uv_loop_t* loop, uv__io_t* w, int events) {
167
167
  int fd;
168
- struct sockaddr_storage addr;
169
- uv_stream_t* stream = watcher->data;
170
-
171
- assert(watcher == &stream->read_watcher ||
172
- watcher == &stream->write_watcher);
173
- assert(revents == EV_READ);
168
+ uv_stream_t* stream = container_of(w, uv_stream_t, read_watcher);
174
169
 
170
+ assert(events == UV__IO_READ);
175
171
  assert(!(stream->flags & UV_CLOSING));
176
172
 
177
173
  if (stream->accepted_fd >= 0) {
178
- ev_io_stop(EV_A, &stream->read_watcher);
174
+ uv__io_stop(loop, &stream->read_watcher);
179
175
  return;
180
176
  }
181
177
 
@@ -184,10 +180,10 @@ void uv__server_io(EV_P_ ev_io* watcher, int revents) {
184
180
  */
185
181
  while (stream->fd != -1) {
186
182
  assert(stream->accepted_fd < 0);
187
- fd = uv__accept(stream->fd, (struct sockaddr*)&addr, sizeof addr);
183
+ fd = uv__accept(stream->fd);
188
184
 
189
185
  if (fd < 0) {
190
- if (errno == EAGAIN) {
186
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
191
187
  /* No problem. */
192
188
  return;
193
189
  } else if (errno == EMFILE) {
@@ -205,7 +201,7 @@ void uv__server_io(EV_P_ ev_io* watcher, int revents) {
205
201
  stream->connection_cb((uv_stream_t*)stream, 0);
206
202
  if (stream->accepted_fd >= 0) {
207
203
  /* The user hasn't yet accepted called uv_accept() */
208
- ev_io_stop(stream->loop->ev, &stream->read_watcher);
204
+ uv__io_stop(stream->loop, &stream->read_watcher);
209
205
  return;
210
206
  }
211
207
  }
@@ -234,14 +230,14 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
234
230
  }
235
231
 
236
232
  if (uv__stream_open(streamClient, streamServer->accepted_fd,
237
- UV_READABLE | UV_WRITABLE)) {
233
+ UV_STREAM_READABLE | UV_STREAM_WRITABLE)) {
238
234
  /* TODO handle error */
239
235
  close(streamServer->accepted_fd);
240
236
  streamServer->accepted_fd = -1;
241
237
  goto out;
242
238
  }
243
239
 
244
- ev_io_start(streamServer->loop->ev, &streamServer->read_watcher);
240
+ uv__io_start(streamServer->loop, &streamServer->read_watcher);
245
241
  streamServer->accepted_fd = -1;
246
242
  status = 0;
247
243
 
@@ -252,15 +248,26 @@ out:
252
248
 
253
249
 
254
250
  int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
251
+ int r;
252
+
255
253
  switch (stream->type) {
256
254
  case UV_TCP:
257
- return uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
255
+ r = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
256
+ break;
257
+
258
258
  case UV_NAMED_PIPE:
259
- return uv_pipe_listen((uv_pipe_t*)stream, backlog, cb);
259
+ r = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb);
260
+ break;
261
+
260
262
  default:
261
263
  assert(0);
262
264
  return -1;
263
265
  }
266
+
267
+ if (r == 0)
268
+ uv__handle_start(stream);
269
+
270
+ return r;
264
271
  }
265
272
 
266
273
 
@@ -290,16 +297,17 @@ static void uv__drain(uv_stream_t* stream) {
290
297
  assert(!uv_write_queue_head(stream));
291
298
  assert(stream->write_queue_size == 0);
292
299
 
293
- ev_io_stop(stream->loop->ev, &stream->write_watcher);
300
+ uv__io_stop(stream->loop, &stream->write_watcher);
294
301
 
295
302
  /* Shutdown? */
296
- if ((stream->flags & UV_SHUTTING) &&
303
+ if ((stream->flags & UV_STREAM_SHUTTING) &&
297
304
  !(stream->flags & UV_CLOSING) &&
298
- !(stream->flags & UV_SHUT)) {
305
+ !(stream->flags & UV_STREAM_SHUT)) {
299
306
  assert(stream->shutdown_req);
300
307
 
301
308
  req = stream->shutdown_req;
302
309
  stream->shutdown_req = NULL;
310
+ uv__req_unregister(stream->loop, req);
303
311
 
304
312
  if (shutdown(stream->fd, SHUT_WR)) {
305
313
  /* Error. Report it. User should call uv_close(). */
@@ -309,7 +317,7 @@ static void uv__drain(uv_stream_t* stream) {
309
317
  }
310
318
  } else {
311
319
  uv__set_sys_error(stream->loop, 0);
312
- ((uv_handle_t*) stream)->flags |= UV_SHUT;
320
+ ((uv_handle_t*) stream)->flags |= UV_STREAM_SHUT;
313
321
  if (req->cb) {
314
322
  req->cb(req, 0);
315
323
  }
@@ -343,7 +351,7 @@ static void uv__write_req_finish(uv_write_t* req) {
343
351
  * callback called in the near future.
344
352
  */
345
353
  ngx_queue_insert_tail(&stream->write_completed_queue, &req->queue);
346
- ev_feed_event(stream->loop->ev, &stream->write_watcher, EV_WRITE);
354
+ uv__io_feed(stream->loop, &stream->write_watcher, UV__IO_WRITE);
347
355
  }
348
356
 
349
357
 
@@ -428,13 +436,13 @@ start:
428
436
  }
429
437
 
430
438
  if (n < 0) {
431
- if (errno != EAGAIN) {
439
+ if (errno != EAGAIN && errno != EWOULDBLOCK) {
432
440
  /* Error */
433
441
  req->error = errno;
434
442
  stream->write_queue_size -= uv__write_req_size(req);
435
443
  uv__write_req_finish(req);
436
444
  return;
437
- } else if (stream->blocking) {
445
+ } else if (stream->flags & UV_STREAM_BLOCKING) {
438
446
  /* If this is a blocking stream, try again. */
439
447
  goto start;
440
448
  }
@@ -455,7 +463,7 @@ start:
455
463
  n = 0;
456
464
 
457
465
  /* There is more to write. */
458
- if (stream->blocking) {
466
+ if (stream->flags & UV_STREAM_BLOCKING) {
459
467
  /*
460
468
  * If we're blocking then we should not be enabling the write
461
469
  * watcher - instead we need to try again.
@@ -491,32 +499,29 @@ start:
491
499
  assert(n == 0 || n == -1);
492
500
 
493
501
  /* Only non-blocking streams should use the write_watcher. */
494
- assert(!stream->blocking);
502
+ assert(!(stream->flags & UV_STREAM_BLOCKING));
495
503
 
496
504
  /* We're not done. */
497
- ev_io_start(stream->loop->ev, &stream->write_watcher);
505
+ uv__io_start(stream->loop, &stream->write_watcher);
498
506
  }
499
507
 
500
508
 
501
509
  static void uv__write_callbacks(uv_stream_t* stream) {
502
- int callbacks_made = 0;
503
- ngx_queue_t* q;
504
510
  uv_write_t* req;
511
+ ngx_queue_t* q;
505
512
 
506
513
  while (!ngx_queue_empty(&stream->write_completed_queue)) {
507
514
  /* Pop a req off write_completed_queue. */
508
515
  q = ngx_queue_head(&stream->write_completed_queue);
509
- assert(q);
510
- req = ngx_queue_data(q, struct uv_write_s, queue);
516
+ req = ngx_queue_data(q, uv_write_t, queue);
511
517
  ngx_queue_remove(q);
518
+ uv__req_unregister(stream->loop, req);
512
519
 
513
520
  /* NOTE: call callback AFTER freeing the request data. */
514
521
  if (req->cb) {
515
522
  uv__set_sys_error(stream->loop, req->error);
516
523
  req->cb(req, req->error ? -1 : 0);
517
524
  }
518
-
519
- callbacks_made++;
520
525
  }
521
526
 
522
527
  assert(ngx_queue_empty(&stream->write_completed_queue));
@@ -556,13 +561,19 @@ static void uv__read(uv_stream_t* stream) {
556
561
  struct msghdr msg;
557
562
  struct cmsghdr* cmsg;
558
563
  char cmsg_space[64];
559
- struct ev_loop* ev = stream->loop->ev;
564
+ int count;
565
+
566
+ /* Prevent loop starvation when the data comes in as fast as (or faster than)
567
+ * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O.
568
+ */
569
+ count = 32;
560
570
 
561
- /* XXX: Maybe instead of having UV_READING we just test if
571
+ /* XXX: Maybe instead of having UV_STREAM_READING we just test if
562
572
  * tcp->read_cb is NULL or not?
563
573
  */
564
- while ((stream->read_cb || stream->read2_cb) &&
565
- stream->flags & UV_READING) {
574
+ while ((stream->read_cb || stream->read2_cb)
575
+ && (stream->flags & UV_STREAM_READING)
576
+ && (count-- > 0)) {
566
577
  assert(stream->alloc_cb);
567
578
  buf = stream->alloc_cb((uv_handle_t*)stream, 64 * 1024);
568
579
 
@@ -596,10 +607,10 @@ static void uv__read(uv_stream_t* stream) {
596
607
 
597
608
  if (nread < 0) {
598
609
  /* Error */
599
- if (errno == EAGAIN) {
610
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
600
611
  /* Wait for the next one. */
601
- if (stream->flags & UV_READING) {
602
- ev_io_start(ev, &stream->read_watcher);
612
+ if (stream->flags & UV_STREAM_READING) {
613
+ uv__io_start(stream->loop, &stream->read_watcher);
603
614
  }
604
615
  uv__set_sys_error(stream->loop, EAGAIN);
605
616
 
@@ -620,14 +631,16 @@ static void uv__read(uv_stream_t* stream) {
620
631
  stream->read2_cb((uv_pipe_t*)stream, -1, buf, UV_UNKNOWN_HANDLE);
621
632
  }
622
633
 
623
- assert(!ev_is_active(&stream->read_watcher));
634
+ assert(!uv__io_active(&stream->read_watcher));
624
635
  return;
625
636
  }
626
637
 
627
638
  } else if (nread == 0) {
628
639
  /* EOF */
629
640
  uv__set_artificial_error(stream->loop, UV_EOF);
630
- ev_io_stop(ev, &stream->read_watcher);
641
+ uv__io_stop(stream->loop, &stream->read_watcher);
642
+ if (!uv__io_active(&stream->write_watcher))
643
+ uv__handle_stop(stream);
631
644
 
632
645
  if (stream->read_cb) {
633
646
  stream->read_cb(stream, -1, buf);
@@ -691,54 +704,53 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
691
704
  "uv_shutdown (unix) only supports uv_handle_t right now");
692
705
  assert(stream->fd >= 0);
693
706
 
694
- if (!(stream->flags & UV_WRITABLE) ||
695
- stream->flags & UV_SHUT ||
707
+ if (!(stream->flags & UV_STREAM_WRITABLE) ||
708
+ stream->flags & UV_STREAM_SHUT ||
696
709
  stream->flags & UV_CLOSED ||
697
710
  stream->flags & UV_CLOSING) {
698
- uv__set_sys_error(stream->loop, EINVAL);
711
+ uv__set_artificial_error(stream->loop, UV_ENOTCONN);
699
712
  return -1;
700
713
  }
701
714
 
702
715
  /* Initialize request */
703
- uv__req_init(stream->loop, (uv_req_t*)req);
716
+ uv__req_init(stream->loop, req, UV_SHUTDOWN);
704
717
  req->handle = stream;
705
718
  req->cb = cb;
706
-
707
719
  stream->shutdown_req = req;
708
- req->type = UV_SHUTDOWN;
709
-
710
- ((uv_handle_t*)stream)->flags |= UV_SHUTTING;
711
-
720
+ stream->flags |= UV_STREAM_SHUTTING;
712
721
 
713
- ev_io_start(stream->loop->ev, &stream->write_watcher);
722
+ uv__io_start(stream->loop, &stream->write_watcher);
714
723
 
715
724
  return 0;
716
725
  }
717
726
 
718
727
 
719
- void uv__stream_io(EV_P_ ev_io* watcher, int revents) {
720
- uv_stream_t* stream = watcher->data;
728
+ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, int events) {
729
+ uv_stream_t* stream;
721
730
 
722
- assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
723
- stream->type == UV_TTY);
724
- assert(watcher == &stream->read_watcher ||
725
- watcher == &stream->write_watcher);
731
+ /* either UV__IO_READ or UV__IO_WRITE but not both */
732
+ assert(!!(events & UV__IO_READ) ^ !!(events & UV__IO_WRITE));
733
+
734
+ if (events & UV__IO_READ)
735
+ stream = container_of(w, uv_stream_t, read_watcher);
736
+ else
737
+ stream = container_of(w, uv_stream_t, write_watcher);
738
+
739
+ assert(stream->type == UV_TCP ||
740
+ stream->type == UV_NAMED_PIPE ||
741
+ stream->type == UV_TTY);
726
742
  assert(!(stream->flags & UV_CLOSING));
727
743
 
728
- if (stream->connect_req) {
744
+ if (stream->connect_req)
729
745
  uv__stream_connect(stream);
730
- } else {
731
- assert(revents & (EV_READ | EV_WRITE));
746
+ else if (events & UV__IO_READ) {
732
747
  assert(stream->fd >= 0);
733
-
734
- if (revents & EV_READ) {
735
- uv__read((uv_stream_t*)stream);
736
- }
737
-
738
- if (revents & EV_WRITE) {
739
- uv__write(stream);
740
- uv__write_callbacks(stream);
741
- }
748
+ uv__read(stream);
749
+ }
750
+ else {
751
+ assert(stream->fd >= 0);
752
+ uv__write(stream);
753
+ uv__write_callbacks(stream);
742
754
  }
743
755
  }
744
756
 
@@ -769,32 +781,24 @@ static void uv__stream_connect(uv_stream_t* stream) {
769
781
  getsockopt(stream->fd, SOL_SOCKET, SO_ERROR, &error, &errorsize);
770
782
  }
771
783
 
772
- if (!error) {
773
- ev_io_start(stream->loop->ev, &stream->read_watcher);
784
+ if (error == EINPROGRESS)
785
+ return;
774
786
 
775
- /* Successful connection */
776
- stream->connect_req = NULL;
777
- if (req->cb) {
778
- req->cb(req, 0);
779
- }
787
+ if (error == 0)
788
+ uv__io_start(stream->loop, &stream->read_watcher);
780
789
 
781
- } else if (error == EINPROGRESS) {
782
- /* Still connecting. */
783
- return;
784
- } else {
785
- /* Error */
786
- uv__set_sys_error(stream->loop, error);
790
+ stream->connect_req = NULL;
791
+ uv__req_unregister(stream->loop, req);
787
792
 
788
- stream->connect_req = NULL;
789
- if (req->cb) {
790
- req->cb(req, -1);
791
- }
793
+ if (req->cb) {
794
+ uv__set_sys_error(stream->loop, error);
795
+ req->cb(req, error ? -1 : 0);
792
796
  }
793
797
  }
794
798
 
795
799
 
796
800
  int uv__connect(uv_connect_t* req, uv_stream_t* stream, struct sockaddr* addr,
797
- socklen_t addrlen, uv_connect_cb cb) {
801
+ socklen_t addrlen, uv_connect_cb cb) {
798
802
  int sockfd;
799
803
  int r;
800
804
 
@@ -804,16 +808,17 @@ int uv__connect(uv_connect_t* req, uv_stream_t* stream, struct sockaddr* addr,
804
808
  return -1;
805
809
  }
806
810
 
807
- if (uv__stream_open(stream, sockfd, UV_READABLE | UV_WRITABLE)) {
811
+ if (uv__stream_open(stream,
812
+ sockfd,
813
+ UV_STREAM_READABLE | UV_STREAM_WRITABLE)) {
808
814
  close(sockfd);
809
815
  return -2;
810
816
  }
811
817
  }
812
818
 
813
- uv__req_init(stream->loop, (uv_req_t*)req);
819
+ uv__req_init(stream->loop, req, UV_CONNECT);
814
820
  req->cb = cb;
815
821
  req->handle = stream;
816
- req->type = UV_CONNECT;
817
822
  ngx_queue_init(&req->queue);
818
823
 
819
824
  if (stream->connect_req) {
@@ -853,12 +858,10 @@ int uv__connect(uv_connect_t* req, uv_stream_t* stream, struct sockaddr* addr,
853
858
  }
854
859
  }
855
860
 
856
- assert(stream->write_watcher.data == stream);
857
- ev_io_start(stream->loop->ev, &stream->write_watcher);
861
+ uv__io_start(stream->loop, &stream->write_watcher);
858
862
 
859
- if (stream->delayed_error) {
860
- ev_feed_event(stream->loop->ev, &stream->write_watcher, EV_WRITE);
861
- }
863
+ if (stream->delayed_error)
864
+ uv__io_feed(stream->loop, &stream->write_watcher, UV__IO_WRITE);
862
865
 
863
866
  return 0;
864
867
  }
@@ -887,54 +890,44 @@ int uv_write2(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
887
890
  empty_queue = (stream->write_queue_size == 0);
888
891
 
889
892
  /* Initialize the req */
890
- uv__req_init(stream->loop, (uv_req_t*)req);
893
+ uv__req_init(stream->loop, req, UV_WRITE);
891
894
  req->cb = cb;
892
895
  req->handle = stream;
893
896
  req->error = 0;
894
897
  req->send_handle = send_handle;
895
- req->type = UV_WRITE;
896
898
  ngx_queue_init(&req->queue);
897
899
 
898
- if (bufcnt <= UV_REQ_BUFSML_SIZE) {
900
+ if (bufcnt <= UV_REQ_BUFSML_SIZE)
899
901
  req->bufs = req->bufsml;
900
- }
901
- else {
902
+ else
902
903
  req->bufs = malloc(sizeof(uv_buf_t) * bufcnt);
903
- }
904
904
 
905
905
  memcpy(req->bufs, bufs, bufcnt * sizeof(uv_buf_t));
906
906
  req->bufcnt = bufcnt;
907
-
908
- /*
909
- * fprintf(stderr, "cnt: %d bufs: %p bufsml: %p\n", bufcnt, req->bufs, req->bufsml);
910
- */
911
-
912
907
  req->write_index = 0;
913
908
  stream->write_queue_size += uv__buf_count(bufs, bufcnt);
914
909
 
915
910
  /* Append the request to write_queue. */
916
911
  ngx_queue_insert_tail(&stream->write_queue, &req->queue);
917
912
 
918
- assert(!ngx_queue_empty(&stream->write_queue));
919
- assert(stream->write_watcher.cb == uv__stream_io);
920
- assert(stream->write_watcher.data == stream);
921
- assert(stream->write_watcher.fd == stream->fd);
922
-
923
913
  /* If the queue was empty when this function began, we should attempt to
924
914
  * do the write immediately. Otherwise start the write_watcher and wait
925
915
  * for the fd to become writable.
926
916
  */
927
- if (empty_queue) {
917
+ if (stream->connect_req) {
918
+ /* Still connecting, do nothing. */
919
+ }
920
+ else if (empty_queue) {
928
921
  uv__write(stream);
929
- } else {
922
+ }
923
+ else {
930
924
  /*
931
925
  * blocking streams should never have anything in the queue.
932
926
  * if this assert fires then somehow the blocking stream isn't being
933
- * sufficently flushed in uv__write.
927
+ * sufficiently flushed in uv__write.
934
928
  */
935
- assert(!stream->blocking);
936
-
937
- ev_io_start(stream->loop->ev, &stream->write_watcher);
929
+ assert(!(stream->flags & UV_STREAM_BLOCKING));
930
+ uv__io_start(stream->loop, &stream->write_watcher);
938
931
  }
939
932
 
940
933
  return 0;
@@ -960,10 +953,10 @@ int uv__read_start_common(uv_stream_t* stream, uv_alloc_cb alloc_cb,
960
953
  return -1;
961
954
  }
962
955
 
963
- /* The UV_READING flag is irrelevant of the state of the tcp - it just
956
+ /* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just
964
957
  * expresses the desired state of the user.
965
958
  */
966
- ((uv_handle_t*)stream)->flags |= UV_READING;
959
+ stream->flags |= UV_STREAM_READING;
967
960
 
968
961
  /* TODO: try to do the read inline? */
969
962
  /* TODO: keep track of tcp state. If we've gotten a EOF then we should
@@ -976,10 +969,9 @@ int uv__read_start_common(uv_stream_t* stream, uv_alloc_cb alloc_cb,
976
969
  stream->read2_cb = read2_cb;
977
970
  stream->alloc_cb = alloc_cb;
978
971
 
979
- /* These should have been set by uv_tcp_init. */
980
- assert(stream->read_watcher.cb == uv__stream_io);
972
+ uv__io_start(stream->loop, &stream->read_watcher);
973
+ uv__handle_start(stream);
981
974
 
982
- ev_io_start(stream->loop->ev, &stream->read_watcher);
983
975
  return 0;
984
976
  }
985
977
 
@@ -997,8 +989,9 @@ int uv_read2_start(uv_stream_t* stream, uv_alloc_cb alloc_cb,
997
989
 
998
990
 
999
991
  int uv_read_stop(uv_stream_t* stream) {
1000
- ev_io_stop(stream->loop->ev, &stream->read_watcher);
1001
- stream->flags &= ~UV_READING;
992
+ uv__io_stop(stream->loop, &stream->read_watcher);
993
+ uv__handle_stop(stream);
994
+ stream->flags &= ~UV_STREAM_READING;
1002
995
  stream->read_cb = NULL;
1003
996
  stream->read2_cb = NULL;
1004
997
  stream->alloc_cb = NULL;
@@ -1006,19 +999,19 @@ int uv_read_stop(uv_stream_t* stream) {
1006
999
  }
1007
1000
 
1008
1001
 
1009
- int uv_is_readable(uv_stream_t* stream) {
1010
- return stream->flags & UV_READABLE;
1002
+ int uv_is_readable(const uv_stream_t* stream) {
1003
+ return stream->flags & UV_STREAM_READABLE;
1011
1004
  }
1012
1005
 
1013
1006
 
1014
- int uv_is_writable(uv_stream_t* stream) {
1015
- return stream->flags & UV_WRITABLE;
1007
+ int uv_is_writable(const uv_stream_t* stream) {
1008
+ return stream->flags & UV_STREAM_WRITABLE;
1016
1009
  }
1017
1010
 
1018
1011
 
1019
1012
  void uv__stream_close(uv_stream_t* handle) {
1020
1013
  uv_read_stop(handle);
1021
- ev_io_stop(handle->loop->ev, &handle->write_watcher);
1014
+ uv__io_stop(handle->loop, &handle->write_watcher);
1022
1015
 
1023
1016
  close(handle->fd);
1024
1017
  handle->fd = -1;
@@ -1028,6 +1021,6 @@ void uv__stream_close(uv_stream_t* handle) {
1028
1021
  handle->accepted_fd = -1;
1029
1022
  }
1030
1023
 
1031
- assert(!ev_is_active(&handle->read_watcher));
1032
- assert(!ev_is_active(&handle->write_watcher));
1024
+ assert(!uv__io_active(&handle->read_watcher));
1025
+ assert(!uv__io_active(&handle->write_watcher));
1033
1026
  }