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
@@ -2,9 +2,22 @@
2
2
  #define AE_UDP_H
3
3
 
4
4
 
5
- void init_ae_udp();
5
+ void init_ae_udp(void);
6
6
 
7
- VALUE AsyncEngine_test_ipv4(VALUE self, VALUE rb_ip, VALUE rb_port);
7
+ static VALUE AsyncEngineUdpSocket_new(int argc, VALUE *argv, VALUE self);
8
+ static VALUE AsyncEngineUdpSocket_send_datagram(int argc, VALUE *argv, VALUE self);
9
+ static VALUE AsyncEngineUdpSocket_local_address(VALUE self);
10
+ static VALUE AsyncEngineUdpSocket_ip_type(VALUE self);
11
+ static VALUE AsyncEngineUdpSocket_pause(VALUE self);
12
+ static VALUE AsyncEngineUdpSocket_resume(VALUE self);
13
+ static VALUE AsyncEngineUdpSocket_is_paused(VALUE self);
14
+ static VALUE AsyncEngineUdpSocket_set_encoding_external(VALUE self);
15
+ static VALUE AsyncEngineUdpSocket_set_encoding_utf8(VALUE self);
16
+ static VALUE AsyncEngineUdpSocket_set_encoding_ascii(VALUE self);
17
+ static VALUE AsyncEngineUdpSocket_encoding(VALUE self);
18
+ static VALUE AsyncEngineUdpSocket_is_alive(VALUE self);
19
+ static VALUE AsyncEngineUdpSocket_close(VALUE self);
20
+ static VALUE AsyncEngineUdpSocket_destroy(VALUE self);
8
21
 
9
22
 
10
23
  #endif /* AE_UDP_H */
@@ -0,0 +1,192 @@
1
+ #include "asyncengine_ruby.h"
2
+ #include "ae_ip_utils.h"
3
+ #include "ae_utils.h"
4
+
5
+
6
+ VALUE mAsyncEngineUtils;
7
+ VALUE cAsyncEngineUtilsNetworkInterface;
8
+ VALUE cAsyncEngineUtilsCpuInfo;
9
+
10
+ // Atributes for AE::Utils::NetworkInterface.
11
+ static ID att_name;
12
+ static ID att_is_internal;
13
+ static ID att_ip_type;
14
+ static ID att_ip;
15
+
16
+ // Atributes for AE::Utils::CpuInfo.
17
+ static ID att_model;
18
+ static ID att_speed;
19
+ static ID att_time_sys;
20
+ static ID att_time_user;
21
+ static ID att_time_idle;
22
+ static ID att_time_irq;
23
+ static ID att_time_nice;
24
+
25
+
26
+ void init_ae_utils(void)
27
+ {
28
+ mAsyncEngineUtils = rb_define_module_under(mAsyncEngine, "Utils");
29
+ cAsyncEngineUtilsNetworkInterface = rb_define_class_under(mAsyncEngineUtils, "NetworkInterface", rb_cObject);
30
+ cAsyncEngineUtilsCpuInfo = rb_define_class_under(mAsyncEngineUtils, "CpuInfo", rb_cObject);
31
+
32
+ rb_define_module_function(mAsyncEngineUtils, "get_hrtime", AsyncEngineUtils_get_hrtime, 0);
33
+ rb_define_module_function(mAsyncEngineUtils, "get_total_memory", AsyncEngineUtils_get_total_memory, 0);
34
+ rb_define_module_function(mAsyncEngineUtils, "get_free_memory", AsyncEngineUtils_get_free_memory, 0);
35
+ rb_define_module_function(mAsyncEngineUtils, "get_loadavg", AsyncEngineUtils_get_loadavg, 0);
36
+ rb_define_module_function(mAsyncEngineUtils, "get_uptime", AsyncEngineUtils_get_uptime, 0);
37
+ rb_define_module_function(mAsyncEngineUtils, "get_network_interfaces", AsyncEngineUtils_get_network_interfaces, 0);
38
+ rb_define_module_function(mAsyncEngineUtils, "get_cpu_info", AsyncEngineUtils_get_cpu_info, 0);
39
+
40
+ att_name = rb_intern("@name");
41
+ att_is_internal = rb_intern("@is_internal");
42
+ att_ip_type = rb_intern("@ip_type");
43
+ att_ip = rb_intern("@ip");
44
+ att_model = rb_intern("@model");
45
+ att_speed = rb_intern("@speed");
46
+ att_time_sys = rb_intern("@time_sys");
47
+ att_time_user = rb_intern("@time_user");
48
+ att_time_idle = rb_intern("@time_idle");
49
+ att_time_irq = rb_intern("@time_irq");
50
+ att_time_nice = rb_intern("@time_nice");
51
+ }
52
+
53
+
54
+ /*
55
+ * Returns the current high-resolution real time. This is expressed in
56
+ * nanoseconds. It is relative to an arbitrary time in the past. It is not
57
+ * related to the time of day and therefore not subject to clock drift. The
58
+ * primary use is for measuring performance between intervals.
59
+ */
60
+ VALUE AsyncEngineUtils_get_hrtime(VALUE self)
61
+ {
62
+ AE_TRACE();
63
+
64
+ return LONG2FIX((long)uv_hrtime());
65
+ }
66
+
67
+
68
+ /* Gets total memory in bytes */
69
+ VALUE AsyncEngineUtils_get_total_memory(VALUE self)
70
+ {
71
+ AE_TRACE();
72
+
73
+ return LONG2FIX((long)uv_get_total_memory());
74
+ }
75
+
76
+
77
+ /* Gets free memory in bytes */
78
+ VALUE AsyncEngineUtils_get_free_memory(VALUE self)
79
+ {
80
+ AE_TRACE();
81
+
82
+ return LONG2FIX((long)uv_get_free_memory());
83
+ }
84
+
85
+
86
+ /* Returns an Array with loadavg data (Float values). */
87
+ VALUE AsyncEngineUtils_get_loadavg(VALUE self)
88
+ {
89
+ AE_TRACE();
90
+
91
+ double avg[3];
92
+ uv_loadavg(avg);
93
+
94
+ return rb_ary_new3(3, rb_float_new(avg[0]), rb_float_new(avg[1]), rb_float_new(avg[2]));
95
+ }
96
+
97
+
98
+ /* Returns system uptime value in seconds .*/
99
+ VALUE AsyncEngineUtils_get_uptime(VALUE self)
100
+ {
101
+ AE_TRACE();
102
+
103
+ double uptime;
104
+ uv_err_t error;
105
+
106
+ error = uv_uptime(&uptime);
107
+ if (error.code)
108
+ ae_raise_uv_error(error.code);
109
+
110
+ return rb_float_new(uptime);
111
+ }
112
+
113
+
114
+ VALUE AsyncEngineUtils_get_network_interfaces(VALUE self)
115
+ {
116
+ AE_TRACE();
117
+
118
+ int i, num_interfaces;
119
+ char ip[INET6_ADDRSTRLEN+1];
120
+ uv_interface_address_t* interfaces;
121
+ uv_err_t error;
122
+ VALUE ae_network_interface, result_array;
123
+
124
+ error = uv_interface_addresses(&interfaces, &num_interfaces);
125
+ if (error.code)
126
+ ae_raise_uv_error(error.code);
127
+
128
+ result_array = rb_ary_new2(num_interfaces);
129
+
130
+ for (i = 0; i < num_interfaces; i++) {
131
+ ae_network_interface = rb_obj_alloc(cAsyncEngineUtilsNetworkInterface);
132
+ rb_ivar_set(ae_network_interface, att_name, rb_str_new2(interfaces[i].name));
133
+ rb_ivar_set(ae_network_interface, att_is_internal, (interfaces[i].is_internal ? Qtrue : Qfalse));
134
+
135
+ if (interfaces[i].address.address4.sin_family == AF_INET) {
136
+ rb_ivar_set(ae_network_interface, att_ip_type, symbol_ipv4);
137
+ uv_ip4_name(&interfaces[i].address.address4, ip, INET_ADDRSTRLEN);
138
+ rb_ivar_set(ae_network_interface, att_ip, rb_str_new2(ip));
139
+ }
140
+ else if (interfaces[i].address.address4.sin_family == AF_INET6) {
141
+ rb_ivar_set(ae_network_interface, att_ip_type, symbol_ipv6);
142
+ uv_ip6_name(&interfaces[i].address.address6, ip, INET6_ADDRSTRLEN);
143
+ rb_ivar_set(ae_network_interface, att_ip, rb_str_new2(ip));
144
+ }
145
+
146
+ rb_ary_store(result_array, i, ae_network_interface);
147
+ }
148
+
149
+ uv_free_interface_addresses(interfaces, num_interfaces);
150
+
151
+ return result_array;
152
+ }
153
+
154
+
155
+ VALUE AsyncEngineUtils_get_cpu_info(VALUE self)
156
+ {
157
+ AE_TRACE();
158
+
159
+ int i, num_cpus;
160
+ uv_cpu_info_t* cpus;
161
+ uv_err_t error;
162
+ uint64_t cpu_times_total;
163
+ VALUE ae_cpu_info, result_array;
164
+
165
+ error = uv_cpu_info(&cpus, &num_cpus);
166
+ if (error.code)
167
+ ae_raise_uv_error(error.code);
168
+
169
+ result_array = rb_ary_new2(num_cpus);
170
+
171
+ for (i = 0; i < num_cpus; i++) {
172
+ ae_cpu_info = rb_obj_alloc(cAsyncEngineUtilsCpuInfo);
173
+
174
+ rb_ivar_set(ae_cpu_info, att_model, rb_str_new2(cpus[i].model));
175
+ rb_ivar_set(ae_cpu_info, att_speed, INT2FIX(cpus[i].speed));
176
+
177
+ cpu_times_total = cpus[i].cpu_times.sys + cpus[i].cpu_times.user + cpus[i].cpu_times.idle +
178
+ cpus[i].cpu_times.irq + cpus[i].cpu_times.nice;
179
+
180
+ rb_ivar_set(ae_cpu_info, att_time_sys, rb_float_new((cpus[i].cpu_times.sys * 100.0 / cpu_times_total)));
181
+ rb_ivar_set(ae_cpu_info, att_time_user, rb_float_new((cpus[i].cpu_times.user * 100.0 / cpu_times_total)));
182
+ rb_ivar_set(ae_cpu_info, att_time_idle, rb_float_new((cpus[i].cpu_times.idle * 100.0 / cpu_times_total)));
183
+ rb_ivar_set(ae_cpu_info, att_time_irq, rb_float_new((cpus[i].cpu_times.irq * 100.0 / cpu_times_total)));
184
+ rb_ivar_set(ae_cpu_info, att_time_nice, rb_float_new((cpus[i].cpu_times.nice * 100.0 / cpu_times_total)));
185
+
186
+ rb_ary_push(result_array, ae_cpu_info);
187
+ }
188
+
189
+ uv_free_cpu_info(cpus, num_cpus);
190
+
191
+ return result_array;
192
+ }
@@ -0,0 +1,16 @@
1
+ #ifndef AE_UTILS_H
2
+ #define AE_UTILS_H
3
+
4
+
5
+ void init_ae_utils(void);
6
+
7
+ VALUE AsyncEngineUtils_get_hrtime(VALUE self);
8
+ VALUE AsyncEngineUtils_get_total_memory(VALUE self);
9
+ VALUE AsyncEngineUtils_get_free_memory(VALUE self);
10
+ VALUE AsyncEngineUtils_get_loadavg(VALUE self);
11
+ VALUE AsyncEngineUtils_get_uptime(VALUE self);
12
+ VALUE AsyncEngineUtils_get_network_interfaces(VALUE self);
13
+ VALUE AsyncEngineUtils_get_cpu_info(VALUE self);
14
+
15
+
16
+ #endif /* AE_UTILS_H */
@@ -1,56 +1,452 @@
1
1
  #include "asyncengine_ruby.h"
2
2
  #include "ae_handle_common.h"
3
- #include "ae_timer.h"
3
+ #include "ae_utils.h"
4
+ #include "ae_ip_utils.h"
5
+ #include "ae_call_from_other_thread.h"
4
6
  #include "ae_next_tick.h"
7
+ #include "ae_timer.h"
5
8
  #include "ae_udp.h"
9
+ #include "ae_tcp.h"
10
+ #include "ae_resolver.h"
11
+
12
+
13
+ static VALUE mProcess;
14
+ static VALUE mKernel;
15
+
16
+ static VALUE AE_thread;
17
+ static VALUE AE_pid;
18
+ static VALUE AE_barrier;
19
+
20
+ static ID att_handles;
21
+ static ID att_procs;
22
+ static ID att_next_tick_procs;
23
+ static ID att_call_from_other_thread_procs;
24
+ static ID att_user_error_handler;
25
+ static ID att_exit_error;
26
+ static ID att_on_exit_procs;
27
+
28
+ static ID method_destroy;
29
+ static ID method_clear;
30
+ static ID method_next_tick;
31
+ static ID method_call_from_other_thread;
32
+ static ID method_pid;
33
+ static ID method_raise;
34
+ static ID method_call;
35
+
36
+ static uv_async_t* ae_ubf_uv_async;
37
+
38
+
39
+ /** Pre-declaration of static functions. */
40
+
41
+ static VALUE uv_run_without_gvl(void);
42
+ static void ae_ubf(void);
43
+ static void ae_ubf_uv_async_callback(uv_async_t* handle, int status);
44
+ static void ae_release_loop(void);
45
+ static int destroy_handle(VALUE key, VALUE handle, VALUE in);
46
+ static VALUE destroy_handle_with_rb_protect(VALUE handle);
47
+ static int ae_is_running_thread(void);
48
+ static VALUE ae_handle_error_with_rb_protect(VALUE error);
49
+
6
50
 
51
+ /** TODO: Temporal functions for debugging: libuv active handlers and requests counters. */
7
52
 
8
53
  static
9
- void prepare_callback(uv_prepare_t* handle, int status)
54
+ int ae_uv_num_active_handlers(void)
10
55
  {
11
56
  AE_TRACE();
12
57
 
13
- // Check received interruptions in Ruby land.
14
- rb_thread_call_with_gvl(rb_thread_check_ints, NULL);
58
+ if (AE_status == AE_STOPPED)
59
+ return 0;
15
60
 
16
- // If this uv_prepare is the only existing handle, then terminate the loop.
17
- if (uv_loop_refcount(uv_default_loop()) == 1)
18
- uv_close((uv_handle_t *)handle, ae_handle_close_callback_0);
61
+ return AE_uv_loop->active_handles;
19
62
  }
20
63
 
21
64
 
22
65
  static
23
- VALUE run_uv_without_gvl(void* param)
66
+ VALUE AsyncEngine_num_uv_active_handles(VALUE self)
24
67
  {
25
68
  AE_TRACE();
26
69
 
27
- if (! uv_run(uv_default_loop())) {
70
+ return INT2FIX(ae_uv_num_active_handlers());
71
+ }
72
+
73
+
74
+ static
75
+ int ae_uv_num_active_reqs(void)
76
+ {
77
+ AE_TRACE();
78
+
79
+ if (AE_status == AE_STOPPED)
80
+ return 0;
81
+
82
+ ngx_queue_t *q;
83
+ int count = 0;
84
+ ngx_queue_foreach(q, &AE_uv_loop->active_reqs)
85
+ count++;
86
+ return count;
87
+ }
88
+
89
+
90
+ static
91
+ VALUE AsyncEngine_num_uv_active_reqs(VALUE self)
92
+ {
93
+ AE_TRACE();
94
+
95
+ return INT2FIX(ae_uv_num_active_reqs());
96
+ }
97
+
98
+
99
+ /** AE.run method. */
100
+
101
+ static
102
+ VALUE AsyncEngine_run(int argc, VALUE *argv, VALUE self)
103
+ {
104
+ AE_TRACE();
105
+ VALUE proc, captured_error, on_exit_procs;
106
+ int r, i;
107
+
108
+ AE_RB_CHECK_NUM_ARGS(0,1);
109
+ AE_RB_ENSURE_BLOCK_OR_PROC(1, proc);
110
+
111
+ if (AE_status == AE_RUNNING && (rb_funcall2(mProcess, method_pid, 0, NULL) != AE_pid))
112
+ rb_raise(eAsyncEngineError, "cannot run AsyncEngine from a forked process while already running");
113
+
114
+ // If already running pass the Proc to the reactor and return true.
115
+ if (AE_status == AE_RUNNING) {
116
+ if (ae_is_running_thread())
117
+ rb_funcall2(mAsyncEngine, method_next_tick, 1, &proc);
118
+ else
119
+ rb_funcall2(mAsyncEngine, method_call_from_other_thread, 1, &proc);
28
120
  return Qtrue;
29
121
  }
30
- else
31
- return Qfalse;
122
+
123
+ // Acquire the barrier lock.
124
+ rb_barrier_wait(AE_barrier);
125
+
126
+ /* Set the UV loop. */
127
+ AE_uv_loop = uv_default_loop();
128
+
129
+ // Mark current thread and PID.
130
+ AE_thread = rb_thread_current();
131
+ AE_pid = rb_funcall2(mProcess, method_pid, 0, NULL);
132
+
133
+ // Get the VALUEs for @_handles and @_procs (faster).
134
+ AE_handles = rb_ivar_get(mAsyncEngine, att_handles);
135
+ AE_procs = rb_ivar_get(mAsyncEngine, att_procs);
136
+
137
+ AE_ASSERT(AE_status == AE_STOPPED);
138
+
139
+ /* Load the UV idle (AE.next_tick) and UV async (AE.call_from_other_thread) now. */
140
+ load_ae_next_tick_uv_idle();
141
+ load_ae_call_from_other_thread();
142
+
143
+ /* Load the UV async for the ae_ubf() function. */
144
+ AE_ASSERT(ae_ubf_uv_async == NULL); // TODO: testing.
145
+ ae_ubf_uv_async = ALLOC(uv_async_t);
146
+ r = uv_async_init(AE_uv_loop, ae_ubf_uv_async, ae_ubf_uv_async_callback);
147
+ AE_ASSERT(r == 0);
148
+
149
+ /* Initial status. */
150
+ AE_status = AE_RUNNING;
151
+
152
+ /* Pass the given Proc to the reactor via next_tick. */
153
+ rb_funcall2(mAsyncEngine, method_next_tick, 1, &proc);
154
+
155
+ // TODO: for testing.
156
+ AE_ASSERT(ae_uv_num_active_reqs() == 0);
157
+
158
+ AE_DEBUG("UV loop starts...");
159
+ // uv_run() will block here until ae_release_loop() is called.
160
+ rb_thread_call_without_gvl(uv_run_without_gvl, NULL, ae_ubf, NULL);
161
+ AE_DEBUG("UV loop terminates");
162
+
163
+ // TODO: for testing.
164
+ AE_ASSERT(ae_uv_num_active_handlers() == 0);
165
+ AE_ASSERT(ae_uv_num_active_reqs() == 0);
166
+
167
+ // Unset the AE_uv_loop, AE_thread and AE_pid.
168
+ AE_uv_loop = NULL;
169
+ AE_thread = Qnil;
170
+ AE_pid = Qnil;
171
+
172
+ // Get the captured error in @_exit_error (if any) and clean @_exit_error.
173
+ captured_error = rb_ivar_get(mAsyncEngine, att_exit_error);
174
+ rb_ivar_set(mAsyncEngine, att_exit_error, Qnil);
175
+
176
+ // Now yes, set the status to AE_STOPPED.
177
+ AE_status = AE_STOPPED;
178
+
179
+ // Release the barrier lock.
180
+ rb_barrier_release(AE_barrier);
181
+
182
+ /*
183
+ * Run the procs within @_on_exit_procs in order by passing the captured error
184
+ * (is any) as argument.
185
+ */
186
+ on_exit_procs = rb_ivar_get(mAsyncEngine, att_on_exit_procs);
187
+ rb_ivar_set(mAsyncEngine, att_on_exit_procs, rb_ary_new());
188
+ for(i=0 ; i<RARRAY_LEN(on_exit_procs) ; i++) {
189
+ ae_proc_call_1(rb_ary_entry(on_exit_procs, i), captured_error);
190
+ }
191
+
192
+ /*
193
+ * If an exception/error has been captured by the exception manager, raise it now
194
+ * but just in case it's an Exception object. Thread#kill does not set the error
195
+ * to an Exception so Ruby will do the rest.
196
+ */
197
+ if (! NIL_P(captured_error)) {
198
+ if (rb_obj_is_kind_of(captured_error, rb_eException) == Qtrue) {
199
+ AE_DEBUG2("raising captured error (class: %s)", rb_obj_classname(captured_error));
200
+ rb_funcall2(mKernel, method_raise, 1, &captured_error);
201
+ }
202
+ else
203
+ AE_DEBUG2("AsyncEngine thread killed by Thread#kill");
204
+ }
205
+
206
+ return Qtrue;
207
+ }
208
+
209
+
210
+ static
211
+ VALUE uv_run_without_gvl(void)
212
+ {
213
+ AE_TRACE();
214
+
215
+ uv_run(AE_uv_loop);
216
+ }
217
+
218
+
219
+ static
220
+ void ae_ubf(void)
221
+ {
222
+ AE_TRACE();
223
+ int r;
224
+
225
+ if (AE_status != AE_RUNNING)
226
+ return;
227
+
228
+ /*
229
+ * When a signal is received by a Ruby process running a blocking code (without GVL)
230
+ * Ruby calls the ubf() function. But this ubf() function could be called also from
231
+ * other thread (i.e. ae_tread.kill) so we don't know if the ubf() is being executing
232
+ * in AE thread, nor if it has been called due a received signal or a Thread#kill.
233
+ * Therefore, do nothing but check interrupts in Ruby land via a thread safe uv_async.
234
+ */
235
+
236
+ r = uv_async_send(ae_ubf_uv_async);
237
+ AE_ASSERT(r == 0);
32
238
  }
33
239
 
34
240
 
35
- VALUE AsyncEngine_c_run(VALUE self)
241
+ static
242
+ void ae_ubf_uv_async_callback(uv_async_t* handle, int status)
36
243
  {
37
244
  AE_TRACE();
38
- uv_prepare_t *_uv_prepare = ALLOC(uv_prepare_t);
39
245
 
40
- uv_prepare_init(uv_default_loop(), _uv_prepare);
41
- uv_prepare_start(_uv_prepare, prepare_callback);
246
+ if (AE_status != AE_RUNNING)
247
+ return;
42
248
 
43
- return rb_thread_call_without_gvl(run_uv_without_gvl, NULL, RUBY_UBF_IO, NULL);
249
+ AE_DEBUG("ae_take_gvl_and_run_with_error_handler(rb_thread_check_ints)");
250
+ ae_take_gvl_and_run_with_error_handler(rb_thread_check_ints);
44
251
  }
45
252
 
46
253
 
47
- /*
48
- * Returns the number of handlers in the loop.
49
- * NOTE: The returned number is the real number of handles minus 1 (the prepare handle).
50
- */
51
- VALUE AsyncEngine_num_handles(VALUE self)
254
+ /** AE.release_loop private method. */
255
+
256
+ static
257
+ VALUE AsyncEngine_release_loop(VALUE self)
52
258
  {
53
- return INT2FIX(uv_loop_refcount(uv_default_loop()) - 1);
259
+ AE_TRACE();
260
+
261
+ ae_release_loop();
262
+ return Qnil;
263
+ }
264
+
265
+
266
+ static
267
+ void ae_release_loop(void)
268
+ {
269
+ AE_TRACE();
270
+
271
+ /*
272
+ * Avoid this function to be called twice. When AE.stop is called it calls this method within
273
+ * a next_tick() or call_from_other_thread(), so when arriving here AE could already be
274
+ * releasing (by a previous AE.stop, exception or whatever).
275
+ */
276
+ switch(AE_status) {
277
+ case AE_RUNNING:
278
+ break;
279
+ case AE_STOPPED:
280
+ AE_DEBUG("AE_status == AE_STOPPED, returning");
281
+ return;
282
+ break;
283
+ case AE_RELEASING:
284
+ AE_DEBUG("AE_status == AE_RELEASING, returning");
285
+ return;
286
+ break;
287
+ }
288
+
289
+ // No more handles can be created from now.
290
+ AE_status = AE_RELEASING;
291
+
292
+ // Clear @_next_tick_procs.
293
+ rb_ary_clear(rb_ivar_get(mAsyncEngine, att_next_tick_procs));
294
+
295
+ // Clear @_call_from_other_thread_procs.
296
+ rb_ary_clear(rb_ivar_get(mAsyncEngine, att_call_from_other_thread_procs));
297
+
298
+ /*
299
+ * Run #destroy() for each existing AE handle. Note that #destroy() method
300
+ * is called safely in every AE handle by ignoring any exception/error.
301
+ * */
302
+ rb_hash_foreach(AE_handles, destroy_handle, Qnil);
303
+
304
+ /* Close AE internal handles. If the async handles are not closed uv_run() won't exit. */
305
+ unload_ae_next_tick_uv_idle();
306
+ unload_ae_call_from_other_thread();
307
+ AE_ASSERT(ae_ubf_uv_async != NULL); // TODO: testing.
308
+ AE_CLOSE_UV_HANDLE(ae_ubf_uv_async);
309
+ ae_ubf_uv_async = NULL;
310
+
311
+ // Clear @_procs.
312
+ rb_funcall2(AE_procs, method_clear, 0, NULL);
313
+ }
314
+
315
+
316
+ static
317
+ int destroy_handle(VALUE key, VALUE handle, VALUE in)
318
+ {
319
+ AE_TRACE();
320
+ VALUE error;
321
+ int error_tag;
322
+
323
+ rb_protect(destroy_handle_with_rb_protect, handle, &error_tag);
324
+ if (error_tag) {
325
+ error = rb_errinfo();
326
+ rb_set_errinfo(Qnil);
327
+ AE_DEBUG2("error (class: %s) rescued with rb_protect() while destroying the handle", rb_obj_classname(error)); // TODO: for testing
328
+ }
329
+
330
+ return 0;
331
+ }
332
+
333
+
334
+ static
335
+ VALUE destroy_handle_with_rb_protect(VALUE handle)
336
+ {
337
+ AE_TRACE();
338
+
339
+ return rb_funcall2(handle, method_destroy, 0, NULL);
340
+ }
341
+
342
+
343
+ /** AE.is_running? method. */
344
+
345
+ static
346
+ VALUE AsyncEngine_is_running(VALUE self)
347
+ {
348
+ AE_TRACE();
349
+
350
+ return (AE_status == AE_RUNNING ? Qtrue : Qfalse);
351
+ }
352
+
353
+
354
+ /** ae_is_running_thread() and AE.is_running_thread methods. */
355
+
356
+ static
357
+ int ae_is_running_thread(void)
358
+ {
359
+ AE_TRACE();
360
+
361
+ return (rb_thread_current() == AE_thread ? 1 : 0);
362
+ }
363
+
364
+
365
+ static
366
+ VALUE AsyncEngine_is_running_thread(VALUE self)
367
+ {
368
+ AE_TRACE();
369
+
370
+ return (ae_is_running_thread() ? Qtrue : Qfalse);
371
+ }
372
+
373
+
374
+ /** ae_handle_error function. */
375
+
376
+ void ae_handle_error(VALUE error)
377
+ {
378
+ AE_TRACE();
379
+ VALUE error2;
380
+ int error_tag;
381
+
382
+ if ((! NIL_P(rb_ivar_get(mAsyncEngine, att_user_error_handler))) && rb_obj_is_kind_of(error, rb_eStandardError) == Qtrue) {
383
+ rb_protect(ae_handle_error_with_rb_protect, error, &error_tag);
384
+ if (error_tag) {
385
+ error2 = rb_errinfo();
386
+ rb_set_errinfo(Qnil);
387
+ AE_DEBUG2("error (class: %s) rescued with rb_protect() while running the user error handler", rb_obj_classname(error2)); // TODO: for testing
388
+ rb_ivar_set(mAsyncEngine, att_exit_error, error2);
389
+ ae_release_loop();
390
+ }
391
+ }
392
+ else {
393
+ AE_DEBUG2("error (class: %s) occurred with rb_protect(), releasing...", rb_obj_classname(error));
394
+ /*
395
+ * error could return Fixnum 8 when AE thread is killed with Thread#kill:
396
+ * https://github.com/ibc/AsyncEngine/issues/4
397
+ * In this case convert to Interrupt.
398
+ */
399
+ if (FIXNUM_P(error))
400
+ error = rb_exc_new2(rb_eInterrupt, "Thread killed (AsyncEngine workaround for https://github.com/ibc/AsyncEngine/issues/4)");
401
+
402
+ rb_ivar_set(mAsyncEngine, att_exit_error, error);
403
+ ae_release_loop();
404
+ }
405
+ }
406
+
407
+
408
+ static
409
+ VALUE ae_handle_error_with_rb_protect(VALUE error)
410
+ {
411
+ AE_TRACE();
412
+
413
+ return rb_funcall2(rb_ivar_get(mAsyncEngine, att_user_error_handler), method_call, 1, &error);
414
+ }
415
+
416
+
417
+ /** AE.check_status method. */
418
+
419
+ static
420
+ VALUE AsyncEngine_check_status(VALUE self)
421
+ {
422
+ AE_TRACE();
423
+
424
+ AE_CHECK_STATUS();
425
+ return Qtrue;
426
+ }
427
+
428
+
429
+ /** Function that generates AE::UV_ERRORS hash reading UV error list. */
430
+
431
+ static
432
+ VALUE generate_AE_UV_ERRORS_hash(void)
433
+ {
434
+ AE_TRACE();
435
+ VALUE hash = rb_hash_new();
436
+ VALUE uv_error;
437
+ VALUE args[3];
438
+
439
+ #define _AE_FILL_UV_ERRORS(val, name, s) \
440
+ args[0] = INT2FIX(val); \
441
+ args[1] = ID2SYM(rb_intern(#name)); \
442
+ args[2] = rb_str_new2(s); \
443
+ uv_error = rb_class_new_instance(3, args, eAsyncEngineUvError); \
444
+ rb_hash_aset(hash, INT2FIX(val), uv_error);
445
+
446
+ UV_ERRNO_MAP(_AE_FILL_UV_ERRORS)
447
+ #undef _AE_FILL_UV_ERRORS
448
+
449
+ return hash;
54
450
  }
55
451
 
56
452
 
@@ -60,13 +456,60 @@ void Init_asyncengine_ext()
60
456
  {
61
457
  AE_TRACE();
62
458
 
459
+ mProcess = rb_define_module("Process");
460
+ mKernel = rb_define_module("Kernel");
461
+
63
462
  mAsyncEngine = rb_define_module("AsyncEngine");
463
+ cAsyncEngineHandle = rb_define_class_under(mAsyncEngine, "Handle", rb_cObject);
464
+ eAsyncEngineError = rb_define_class_under(mAsyncEngine, "Error", rb_eStandardError);
465
+ eAsyncEngineUvError = rb_define_class_under(mAsyncEngine, "UvError", eAsyncEngineError);
466
+ eAsyncEngineNotRunningError = rb_define_class_under(mAsyncEngine, "NotRunningError", eAsyncEngineError);
467
+
468
+ rb_define_module_function(mAsyncEngine, "run", AsyncEngine_run, -1);
469
+ rb_define_module_function(mAsyncEngine, "release_loop", AsyncEngine_release_loop, 0);
470
+ rb_define_module_function(mAsyncEngine, "running?", AsyncEngine_is_running, 0);
471
+ rb_define_module_function(mAsyncEngine, "running_thread?", AsyncEngine_is_running_thread, 0);
472
+ rb_define_module_function(mAsyncEngine, "check_status", AsyncEngine_check_status, 0); // TODO: Should be removed since all will be in C.
473
+ // TODO: temporal methods (for debugging).
474
+ rb_define_module_function(mAsyncEngine, "num_uv_active_handles", AsyncEngine_num_uv_active_handles, 0);
475
+ rb_define_module_function(mAsyncEngine, "num_uv_active_reqs", AsyncEngine_num_uv_active_reqs, 0);
64
476
 
65
- rb_define_module_function(mAsyncEngine, "_c_run", AsyncEngine_c_run, 0);
66
- rb_define_module_function(mAsyncEngine, "num_handles", AsyncEngine_num_handles, 0);
477
+ att_handles = rb_intern("@_handles");
478
+ att_procs = rb_intern("@_procs");
479
+ att_next_tick_procs = rb_intern("@_next_tick_procs");
480
+ att_call_from_other_thread_procs = rb_intern("@_call_from_other_thread_procs");
481
+ att_exit_error = rb_intern("@_exit_error");
482
+ att_user_error_handler = rb_intern("@_user_error_handler");
483
+ att_on_exit_procs = rb_intern("@_on_exit_procs");
67
484
 
485
+ method_destroy = rb_intern("destroy");
486
+ method_clear = rb_intern("clear");
487
+ method_next_tick = rb_intern("next_tick");
488
+ method_call_from_other_thread = rb_intern("call_from_other_thread");
489
+ method_pid = rb_intern("pid");
490
+ method_pid = rb_intern("pid");
491
+ method_raise = rb_intern("raise");
492
+ method_call = rb_intern("call");
493
+
494
+ init_rb_utilities();
68
495
  init_ae_handle_common();
69
- init_ae_timer();
496
+ init_ae_utils();
497
+ init_ae_ip_utils();
498
+ init_ae_call_from_other_thread();
70
499
  init_ae_next_tick();
500
+ init_ae_timer();
71
501
  init_ae_udp();
72
- }
502
+ init_ae_tcp();
503
+ init_ae_resolver();
504
+
505
+ ae_ubf_uv_async = NULL;
506
+
507
+ AE_UV_ERRORS = generate_AE_UV_ERRORS_hash();
508
+ rb_const_set(mAsyncEngine, rb_intern("UV_ERRORS"), AE_UV_ERRORS);
509
+
510
+ AE_barrier = rb_barrier_new();
511
+ rb_gc_register_address(&AE_barrier);
512
+
513
+ AE_uv_loop = NULL;
514
+ AE_status = AE_STOPPED;
515
+ }