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