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
@@ -0,0 +1,20 @@
1
+ #ifndef AE_TCP_H
2
+ #define AE_TCP_H
3
+
4
+
5
+ void init_ae_tcp(void);
6
+
7
+ static VALUE AsyncEngineTcpSocket_new(int argc, VALUE *argv, VALUE self);
8
+ static VALUE AsyncEngineTcpSocket_send_data(int argc, VALUE *argv, VALUE self);
9
+ static VALUE AsyncEngineTcpSocket_local_address(VALUE self);
10
+ static VALUE AsyncEngineTcpSocket_peer_address(VALUE self);
11
+ static VALUE AsyncEngineTcpSocket_set_connect_timeout(VALUE self, VALUE timeout);
12
+ static VALUE AsyncEngineTcpSocket_status(VALUE self);
13
+ static VALUE AsyncEngineTcpSocket_is_connected(VALUE self);
14
+ static VALUE AsyncEngineTcpSocket_is_alive(VALUE self);
15
+ static VALUE AsyncEngineTcpSocket_close(VALUE self);
16
+ static VALUE AsyncEngineTcpSocket_close_gracefully(int argc, VALUE *argv, VALUE self);
17
+ static VALUE AsyncEngineTcpSocket_destroy(VALUE self);
18
+
19
+
20
+ #endif /* AE_TCP_H */
@@ -4,149 +4,423 @@
4
4
 
5
5
 
6
6
  static VALUE cAsyncEngineTimer;
7
+ static VALUE cAsyncEnginePeriodicTimer;
7
8
 
8
9
 
9
10
  typedef struct {
10
11
  uv_timer_t *_uv_handle;
11
12
  int periodic;
12
- VALUE rb_block_id;
13
- int has_rb_instance;
14
- VALUE rb_instance; // Points to the owner AE::Timer (if there is).
15
- } struct_ae_timer_cdata;
13
+ long delay;
14
+ long interval;
15
+ VALUE ae_handle_id;
16
+ VALUE on_fire_proc;
17
+ } struct_cdata;
18
+
19
+ struct timer_callback_data {
20
+ struct_cdata* cdata;
21
+ };
22
+
23
+
24
+ // Used for storing information about the last timer callback.
25
+ static struct timer_callback_data last_timer_callback_data;
26
+
27
+
28
+ /** Predeclaration of static functions. */
29
+
30
+ static VALUE AsyncEngineTimer_alloc(VALUE klass);
31
+ static void AsyncEngineTimer_mark(struct_cdata* cdata);
32
+ static void AsyncEngineTimer_free(struct_cdata* cdata);
33
+ static void init_instance(VALUE self, long delay, long interval, VALUE proc);
34
+ static void _uv_timer_callback(uv_timer_t* handle, int status);
35
+ static VALUE _ae_timer_callback(void);
36
+ static void close_handle(struct_cdata *cdata);
16
37
 
17
38
 
18
39
  void init_ae_timer()
19
40
  {
20
- cAsyncEngineTimer = rb_define_class_under(mAsyncEngine, "Timer", rb_cObject);
21
- rb_define_module_function(mAsyncEngine, "_c_add_timer", AsyncEngine_c_add_timer, 4);
22
- rb_define_method(cAsyncEngineTimer, "cancel", AsyncEngineTimer_cancel, 0);
23
- rb_define_alias(cAsyncEngineTimer, "stop", "cancel");
24
- rb_define_private_method(cAsyncEngineTimer, "_c_set_interval", AsyncEngineTimer_c_set_interval, 1);
41
+ AE_TRACE();
42
+
43
+ cAsyncEngineTimer = rb_define_class_under(mAsyncEngine, "Timer", cAsyncEngineHandle);
44
+ cAsyncEnginePeriodicTimer = rb_define_class_under(mAsyncEngine, "PeriodicTimer", cAsyncEngineTimer);
45
+
46
+ rb_define_alloc_func(cAsyncEngineTimer, AsyncEngineTimer_alloc);
47
+
48
+ rb_define_singleton_method(cAsyncEngineTimer, "new", AsyncEngineTimer_new, -1);
49
+ rb_define_singleton_method(cAsyncEnginePeriodicTimer, "new", AsyncEnginePeriodicTimer_new, -1);
50
+
51
+ rb_define_method(cAsyncEngineTimer, "pause", AsyncEngineTimer_pause, 0);
52
+ rb_define_method(cAsyncEngineTimer, "restart", AsyncEngineTimer_restart, -1);
53
+ rb_define_method(cAsyncEnginePeriodicTimer, "restart", AsyncEnginePeriodicTimer_restart, -1);
54
+ rb_define_method(cAsyncEngineTimer, "alive?", AsyncEngineTimer_is_alive, 0);
55
+ rb_define_method(cAsyncEngineTimer, "delay", AsyncEngineTimer_delay, 0);
56
+ rb_define_method(cAsyncEnginePeriodicTimer, "interval", AsyncEnginePeriodicTimer_interval, 0);
57
+ rb_define_method(cAsyncEngineTimer, "alive?", AsyncEngineTimer_is_alive, 0);
58
+ rb_define_method(cAsyncEngineTimer, "close", AsyncEngineTimer_close, 0);
59
+ rb_define_alias(cAsyncEngineTimer, "stop", "close");
60
+ rb_define_private_method(cAsyncEngineTimer, "destroy", AsyncEngineTimer_destroy, 0);
25
61
  }
26
62
 
27
63
 
64
+ /** Class alloc, mark and free functions. */
65
+
28
66
  static
29
- void deallocate(struct_ae_timer_cdata* cdata)
67
+ VALUE AsyncEngineTimer_alloc(VALUE klass)
68
+ {
69
+ AE_TRACE();
70
+
71
+ struct_cdata* cdata = ALLOC(struct_cdata);
72
+
73
+ /* IMPORTANT: Set the _uv_handle to NULL right now since GC could
74
+ * call our mark() function before cdata->on_fire_proc is set.
75
+ */
76
+ cdata->_uv_handle = NULL;
77
+
78
+ return Data_Wrap_Struct(klass, AsyncEngineTimer_mark, AsyncEngineTimer_free, cdata);
79
+ }
80
+
81
+
82
+ static
83
+ void AsyncEngineTimer_mark(struct_cdata* cdata)
84
+ {
85
+ AE_TRACE();
86
+
87
+ // This tells Ruby not to GC cdata->on_fire_proc if the Timer
88
+ // instance continues alive in Ruby land.
89
+ if (cdata->_uv_handle)
90
+ rb_gc_mark(cdata->on_fire_proc);
91
+ }
92
+
93
+
94
+ static
95
+ void AsyncEngineTimer_free(struct_cdata* cdata)
30
96
  {
31
97
  AE_TRACE();
32
98
 
33
- // Let the GC work.
34
- ae_remove_block(cdata->rb_block_id);
35
- // Close the timer so it's unreferenced by uv.
36
- uv_close((uv_handle_t *)cdata->_uv_handle, ae_handle_close_callback_0);
37
- // Free memory.
38
99
  xfree(cdata);
39
100
  }
40
101
 
41
102
 
103
+ /** Timer.new() method.
104
+ *
105
+ * Arguments:
106
+ * - delay (Float).
107
+ * - proc (Proc) (optional).
108
+ *
109
+ * Block optional.
110
+ */
111
+
42
112
  static
43
- void execute_timer_with_gvl(uv_timer_t* handle)
113
+ VALUE AsyncEngineTimer_new(int argc, VALUE *argv, VALUE self)
44
114
  {
45
115
  AE_TRACE();
116
+ long delay;
117
+ VALUE proc, instance;
46
118
 
47
- struct_ae_timer_cdata* cdata = (struct_ae_timer_cdata*)handle->data;
48
- VALUE block = ae_get_block(cdata->rb_block_id);
49
- int exception_tag;
119
+ AE_CHECK_STATUS();
120
+ AE_RB_CHECK_NUM_ARGS(1,2);
121
+ AE_RB_ENSURE_BLOCK_OR_PROC(2, proc);
50
122
 
51
- exception_tag = ae_protect_block_call_0(block);
123
+ // Parameter 1: delay.
124
+ delay = (long)(NUM2DBL(argv[0]) * 1000);
125
+ if (delay < 1)
126
+ delay = 1;
52
127
 
53
- // Terminate the timer if it is not periodic.
54
- if (cdata->periodic == 0) {
55
- // If the timer has a ruby AE::Timer instance then set its attribute
56
- // @_handle_terminated to true.
57
- if (cdata->has_rb_instance == 1)
58
- rb_ivar_set(cdata->rb_instance, att_handle_terminated, Qtrue);
59
- deallocate(cdata);
60
- }
128
+ // Allocate the Ruby instance.
129
+ instance = rb_obj_alloc(self);
130
+
131
+ // Init the UV stuff within the instance.
132
+ init_instance(instance, delay, 0, proc);
61
133
 
62
- if (exception_tag)
63
- ae_manage_exception(exception_tag);
134
+ return instance;
64
135
  }
65
136
 
66
137
 
138
+ /** PeriodicTimer.new() method.
139
+ *
140
+ * Arguments:
141
+ * - interval (Float).
142
+ * - delay (Float) (optional).
143
+ * - proc (Proc) (optional).
144
+ *
145
+ * Block optional.
146
+ */
147
+
67
148
  static
68
- void timer_callback(uv_timer_t* handle, int status)
149
+ VALUE AsyncEnginePeriodicTimer_new(int argc, VALUE *argv, VALUE self)
69
150
  {
70
151
  AE_TRACE();
71
- rb_thread_call_with_gvl(execute_timer_with_gvl, handle);
152
+ long interval, delay;
153
+ VALUE proc, instance;
154
+
155
+ AE_CHECK_STATUS();
156
+ AE_RB_CHECK_NUM_ARGS(1,3);
157
+ AE_RB_ENSURE_BLOCK_OR_PROC(3, proc);
158
+
159
+ // Parameter 1: interval.
160
+ interval = (long)(NUM2DBL(argv[0]) * 1000);
161
+ if (interval < 1)
162
+ interval = 1;
163
+
164
+ // Parameter 2: delay (optional).
165
+ if (argc >= 2 && ! NIL_P(argv[1])) {
166
+ delay = (long)(NUM2DBL(argv[1]) * 1000);
167
+ if (delay < 1)
168
+ delay = 1;
169
+ }
170
+ else
171
+ delay = interval;
172
+
173
+ // Allocate the Ruby instance.
174
+ instance = rb_obj_alloc(self);
175
+
176
+ // Init the UV stuff within the instance.
177
+ init_instance(instance, delay, interval, proc);
178
+
179
+ return instance;
72
180
  }
73
181
 
74
182
 
75
- VALUE AsyncEngine_c_add_timer(VALUE self, VALUE rb_delay, VALUE rb_interval, VALUE block, VALUE instance)
183
+ static
184
+ void init_instance(VALUE self, long delay, long interval, VALUE proc)
76
185
  {
77
186
  AE_TRACE();
78
- uv_timer_t* _uv_handle = ALLOC(uv_timer_t);
79
- struct_ae_timer_cdata* cdata = ALLOC(struct_ae_timer_cdata);
80
- long delay, interval;
187
+ uv_timer_t *_uv_handle;
188
+ int r;
189
+
190
+ // Create and init the UV handle.
191
+ _uv_handle = ALLOC(uv_timer_t);
192
+ r = uv_timer_init(AE_uv_loop, _uv_handle);
193
+ if (r != 0) {
194
+ xfree(_uv_handle);
195
+ ae_raise_last_uv_error();
196
+ }
81
197
 
198
+ // Fill cdata struct.
199
+ GET_CDATA_FROM_SELF;
82
200
  cdata->_uv_handle = _uv_handle;
83
-
84
- delay = NUM2LONG(rb_delay);
85
- if (NIL_P(rb_interval)) {
86
- interval = 0;
201
+ cdata->delay = delay;
202
+ cdata->interval = interval;
203
+ if (interval)
204
+ cdata->periodic = 1;
205
+ else
87
206
  cdata->periodic = 0;
207
+ cdata->on_fire_proc = proc;
208
+ cdata->ae_handle_id = ae_store_handle(self); // Avoid GC.
209
+
210
+ // Fill data field of the UV handle.
211
+ cdata->_uv_handle->data = (void *)cdata;
212
+
213
+ // Run the timer.
214
+ r = uv_timer_start(_uv_handle, _uv_timer_callback, delay, interval);
215
+ if (r != 0) {
216
+ close_handle(cdata);
217
+ ae_raise_last_uv_error();
88
218
  }
89
- else {
90
- interval = NUM2LONG(rb_interval);
91
- if (interval == 0) interval = 1;
92
- cdata->periodic = 1;
219
+ }
220
+
221
+
222
+ static
223
+ void _uv_timer_callback(uv_timer_t* handle, int status)
224
+ {
225
+ AE_TRACE();
226
+
227
+ last_timer_callback_data.cdata = (struct_cdata*)handle->data;
228
+ ae_take_gvl_and_run_with_error_handler(_ae_timer_callback);
229
+ }
230
+
231
+
232
+ static
233
+ VALUE _ae_timer_callback(void)
234
+ {
235
+ AE_TRACE();
236
+
237
+ struct_cdata* cdata = last_timer_callback_data.cdata;
238
+
239
+ // Terminate the timer if it is not periodic.
240
+ if (cdata->periodic == 0)
241
+ close_handle(cdata);
242
+
243
+ return ae_proc_call_0(cdata->on_fire_proc);
244
+ }
245
+
246
+
247
+ /** Timer#pause() method. */
248
+
249
+ static
250
+ VALUE AsyncEngineTimer_pause(VALUE self)
251
+ {
252
+ AE_TRACE();
253
+ int r;
254
+
255
+ GET_CDATA_FROM_SELF_AND_CHECK_UV_HANDLE_IS_OPEN;
256
+
257
+ r = uv_timer_stop(cdata->_uv_handle);
258
+ if (r != 0)
259
+ ae_raise_last_uv_error();
260
+
261
+ return Qtrue;
262
+ }
263
+
264
+
265
+ /**
266
+ * Timer#restart() method.
267
+ *
268
+ * Arguments:
269
+ * - new delay (Float) (optional). If not set, previous delay is used.
270
+ */
271
+
272
+ static
273
+ VALUE AsyncEngineTimer_restart(int argc, VALUE *argv, VALUE self)
274
+ {
275
+ AE_TRACE();
276
+ long delay;
277
+ int r;
278
+
279
+ GET_CDATA_FROM_SELF_AND_CHECK_UV_HANDLE_IS_OPEN;
280
+ AE_RB_CHECK_NUM_ARGS(0,1);
281
+
282
+ // Parameter 1: delay (optional).
283
+ if (argc == 1 && ! NIL_P(argv[0])) {
284
+ delay = (long)(NUM2DBL(argv[0]) * 1000);
285
+ if (delay < 1)
286
+ delay = 1;
287
+ cdata->delay = delay;
93
288
  }
94
289
 
95
- // Save the block from being GC'd.
96
- cdata->rb_block_id = ae_store_block(block);
290
+ r = uv_timer_stop(cdata->_uv_handle);
291
+ if (r != 0)
292
+ ae_raise_last_uv_error();
97
293
 
98
- if (NIL_P(instance))
99
- cdata->has_rb_instance = 0;
100
- else {
101
- cdata->has_rb_instance = 1;
102
- cdata->rb_instance = instance;
294
+ r = uv_timer_start(cdata->_uv_handle, _uv_timer_callback, cdata->delay, 0);
295
+ if (r != 0)
296
+ ae_raise_last_uv_error();
297
+
298
+ return Qtrue;
299
+ }
300
+
301
+
302
+ /**
303
+ * PeriodicTimer#restart() method.
304
+ *
305
+ * Arguments:
306
+ * - new interval (Float) (optional). If not set, previous interval is used.
307
+ * - new delay (Float) (optional). If not set, new interval value is used,
308
+ * or previous delay value if no new interval is set.
309
+ */
310
+
311
+ static
312
+ VALUE AsyncEnginePeriodicTimer_restart(int argc, VALUE *argv, VALUE self)
313
+ {
314
+ AE_TRACE();
315
+ long interval, delay;
316
+ int r;
317
+
318
+ GET_CDATA_FROM_SELF_AND_CHECK_UV_HANDLE_IS_OPEN;
319
+ AE_RB_CHECK_NUM_ARGS(0,2);
320
+
321
+ // Parameter 1: interval (optional).
322
+ if (argc >= 1 && ! NIL_P(argv[0])) {
323
+ interval = (long)(NUM2DBL(argv[0]) * 1000);
324
+ if (interval < 1)
325
+ interval = 1;
326
+ cdata->interval = interval;
327
+
328
+ // Parameter 2: delay (optional).
329
+ if (argc == 2 && ! NIL_P(argv[1])) {
330
+ delay = (long)(NUM2DBL(argv[1]) * 1000);
331
+ if (delay < 1)
332
+ delay = 1;
333
+ cdata->delay = delay;
334
+ }
335
+ else
336
+ cdata->delay = interval;
103
337
  }
104
338
 
105
- // Initialize.
106
- uv_timer_init(uv_default_loop(), _uv_handle);
107
- _uv_handle->data = cdata;
339
+ r = uv_timer_stop(cdata->_uv_handle);
340
+ if (r != 0)
341
+ ae_raise_last_uv_error();
342
+
343
+ r = uv_timer_start(cdata->_uv_handle, _uv_timer_callback, cdata->delay, cdata->interval);
344
+ if (r != 0)
345
+ ae_raise_last_uv_error();
346
+
347
+ return Qtrue;
348
+ }
349
+
350
+
351
+ /** Timer#delay() method. */
352
+
353
+ static
354
+ VALUE AsyncEngineTimer_delay(VALUE self)
355
+ {
356
+ AE_TRACE();
357
+
358
+ GET_CDATA_FROM_SELF_AND_CHECK_UV_HANDLE_IS_OPEN;
359
+
360
+ return rb_float_new((double)(cdata->delay / 1000.0));
361
+ }
362
+
108
363
 
109
- uv_timer_start(_uv_handle, timer_callback, delay, interval);
364
+ /** PeriodicTimer#interval() method. */
365
+
366
+ static
367
+ VALUE AsyncEnginePeriodicTimer_interval(VALUE self)
368
+ {
369
+ AE_TRACE();
110
370
 
111
- return Data_Wrap_Struct(cAsyncEngineCData, NULL, NULL, cdata);
371
+ GET_CDATA_FROM_SELF_AND_CHECK_UV_HANDLE_IS_OPEN;
372
+
373
+ return rb_float_new((double)(uv_timer_get_repeat(cdata->_uv_handle) / 1000.0));
112
374
  }
113
375
 
114
376
 
115
- VALUE AsyncEngineTimer_cancel(VALUE self)
377
+ /** Timer#alive?() method. */
378
+
379
+ static
380
+ VALUE AsyncEngineTimer_is_alive(VALUE self)
116
381
  {
117
382
  AE_TRACE();
118
- struct_ae_timer_cdata* cdata;
119
383
 
120
- if (! NIL_P(rb_ivar_get(self, att_handle_terminated)))
121
- return Qfalse;
122
- rb_ivar_set(self, att_handle_terminated, Qtrue);
384
+ GET_CDATA_FROM_SELF_AND_CHECK_UV_HANDLE_IS_OPEN;
123
385
 
124
- Data_Get_Struct(rb_ivar_get(self, att_cdata), struct_ae_timer_cdata, cdata);
386
+ return Qtrue;
387
+ }
125
388
 
126
- // Stop timer.
127
- uv_timer_stop(cdata->_uv_handle);
128
389
 
129
- // Terminate the timer.
130
- deallocate(cdata);
390
+ /** Timer#close() method. */
131
391
 
392
+ static
393
+ VALUE AsyncEngineTimer_close(VALUE self)
394
+ {
395
+ AE_TRACE();
396
+
397
+ GET_CDATA_FROM_SELF_AND_CHECK_UV_HANDLE_IS_OPEN;
398
+
399
+ close_handle(cdata);
132
400
  return Qtrue;
133
401
  }
134
402
 
135
403
 
136
- VALUE AsyncEngineTimer_c_set_interval(VALUE self, VALUE rb_interval)
404
+ /** Timer#destroy() private method. */
405
+
406
+ static
407
+ VALUE AsyncEngineTimer_destroy(VALUE self)
137
408
  {
138
409
  AE_TRACE();
139
- struct_ae_timer_cdata* cdata;
140
- long interval;
141
-
142
- if (! NIL_P(rb_ivar_get(self, att_handle_terminated)))
143
- return Qfalse;
144
-
145
- Data_Get_Struct(rb_ivar_get(self, att_cdata), struct_ae_timer_cdata, cdata);
146
-
147
- interval = NUM2LONG(rb_interval);
148
- if (interval == 0) interval = 1;
149
-
150
- uv_timer_set_repeat(cdata->_uv_handle, interval);
151
- return rb_interval;
152
- }
410
+
411
+ GET_CDATA_FROM_SELF_AND_CHECK_UV_HANDLE_IS_OPEN;
412
+
413
+ close_handle(cdata);
414
+ return Qtrue;
415
+ }
416
+
417
+
418
+ static
419
+ void close_handle(struct_cdata *cdata)
420
+ {
421
+ AE_TRACE();
422
+
423
+ AE_CLOSE_UV_HANDLE(cdata->_uv_handle);
424
+ cdata->_uv_handle = NULL;
425
+ ae_remove_handle(cdata->ae_handle_id);
426
+ }