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
@@ -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
  }