polyphony 0.19 → 0.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.rubocop.yml +87 -1
  4. data/CHANGELOG.md +35 -0
  5. data/Gemfile.lock +17 -6
  6. data/README.md +200 -139
  7. data/Rakefile +4 -4
  8. data/TODO.md +35 -7
  9. data/bin/poly +11 -0
  10. data/docs/getting-started/getting-started.md +1 -1
  11. data/docs/summary.md +3 -0
  12. data/docs/technical-overview/exception-handling.md +94 -0
  13. data/docs/technical-overview/fiber-scheduling.md +99 -0
  14. data/examples/core/cancel.rb +8 -4
  15. data/examples/core/channel_echo.rb +18 -17
  16. data/examples/core/defer.rb +12 -0
  17. data/examples/core/enumerator.rb +4 -4
  18. data/examples/core/fiber_error.rb +9 -0
  19. data/examples/core/fiber_error_with_backtrace.rb +73 -0
  20. data/examples/core/fork.rb +6 -6
  21. data/examples/core/genserver.rb +16 -8
  22. data/examples/core/lock.rb +3 -3
  23. data/examples/core/move_on.rb +4 -3
  24. data/examples/core/move_on_twice.rb +5 -5
  25. data/examples/core/move_on_with_ensure.rb +8 -11
  26. data/examples/core/move_on_with_value.rb +14 -0
  27. data/examples/core/{multiple_spawn.rb → multiple_spin.rb} +5 -5
  28. data/examples/core/nested_cancel.rb +5 -5
  29. data/examples/core/{nested_multiple_spawn.rb → nested_multiple_spin.rb} +6 -6
  30. data/examples/core/nested_spin.rb +17 -0
  31. data/examples/core/pingpong.rb +21 -0
  32. data/examples/core/pulse.rb +4 -5
  33. data/examples/core/resource.rb +6 -4
  34. data/examples/core/resource_cancel.rb +6 -9
  35. data/examples/core/resource_delegate.rb +3 -3
  36. data/examples/core/sleep.rb +3 -3
  37. data/examples/core/sleep_spin.rb +19 -0
  38. data/examples/core/snooze.rb +32 -0
  39. data/examples/core/spin.rb +14 -0
  40. data/examples/core/{spawn_cancel.rb → spin_cancel.rb} +6 -7
  41. data/examples/core/spin_error.rb +17 -0
  42. data/examples/core/spin_error_backtrace.rb +30 -0
  43. data/examples/core/spin_uncaught_error.rb +15 -0
  44. data/examples/core/supervisor.rb +8 -8
  45. data/examples/core/supervisor_with_cancel_scope.rb +7 -7
  46. data/examples/core/supervisor_with_error.rb +8 -8
  47. data/examples/core/supervisor_with_manual_move_on.rb +6 -7
  48. data/examples/core/suspend.rb +13 -0
  49. data/examples/core/thread.rb +1 -1
  50. data/examples/core/thread_cancel.rb +9 -11
  51. data/examples/core/thread_pool.rb +18 -14
  52. data/examples/core/throttle.rb +7 -7
  53. data/examples/core/timeout.rb +3 -3
  54. data/examples/fs/read.rb +7 -9
  55. data/examples/http/config.ru +7 -3
  56. data/examples/http/cuba.ru +22 -0
  57. data/examples/http/happy_eyeballs.rb +6 -4
  58. data/examples/http/http_client.rb +1 -1
  59. data/examples/http/http_get.rb +1 -1
  60. data/examples/http/http_parse_experiment.rb +21 -16
  61. data/examples/http/http_proxy.rb +28 -26
  62. data/examples/http/http_server.rb +10 -10
  63. data/examples/http/http_server_forked.rb +6 -5
  64. data/examples/http/http_server_throttled.rb +3 -3
  65. data/examples/http/http_ws_server.rb +11 -11
  66. data/examples/http/https_raw_client.rb +1 -1
  67. data/examples/http/https_server.rb +8 -8
  68. data/examples/http/https_wss_server.rb +13 -11
  69. data/examples/http/rack_server.rb +2 -2
  70. data/examples/http/rack_server_https.rb +4 -4
  71. data/examples/http/rack_server_https_forked.rb +5 -5
  72. data/examples/http/websocket_secure_server.rb +6 -6
  73. data/examples/http/websocket_server.rb +5 -5
  74. data/examples/interfaces/pg_client.rb +4 -4
  75. data/examples/interfaces/pg_pool.rb +13 -6
  76. data/examples/interfaces/pg_transaction.rb +5 -4
  77. data/examples/interfaces/redis_channels.rb +15 -11
  78. data/examples/interfaces/redis_client.rb +2 -2
  79. data/examples/interfaces/redis_pubsub.rb +2 -1
  80. data/examples/interfaces/redis_pubsub_perf.rb +13 -9
  81. data/examples/io/backticks.rb +11 -0
  82. data/examples/io/cat.rb +4 -5
  83. data/examples/io/echo_client.rb +9 -4
  84. data/examples/io/echo_client_from_stdin.rb +20 -0
  85. data/examples/io/echo_pipe.rb +7 -8
  86. data/examples/io/echo_server.rb +8 -6
  87. data/examples/io/echo_server_with_timeout.rb +13 -10
  88. data/examples/io/echo_stdin.rb +3 -3
  89. data/examples/io/httparty.rb +2 -2
  90. data/examples/io/httparty_multi.rb +8 -4
  91. data/examples/io/httparty_threaded.rb +6 -2
  92. data/examples/io/io_read.rb +2 -2
  93. data/examples/io/irb.rb +16 -4
  94. data/examples/io/net-http.rb +3 -3
  95. data/examples/io/open.rb +17 -0
  96. data/examples/io/system.rb +3 -3
  97. data/examples/io/tcpserver.rb +15 -0
  98. data/examples/io/tcpsocket.rb +6 -5
  99. data/examples/performance/multi_snooze.rb +29 -0
  100. data/examples/performance/{perf_snooze.rb → snooze.rb} +7 -5
  101. data/examples/performance/snooze_raw.rb +39 -0
  102. data/ext/gyro/async.c +165 -0
  103. data/ext/gyro/child.c +167 -0
  104. data/ext/{ev → gyro}/extconf.rb +4 -3
  105. data/ext/gyro/gyro.c +316 -0
  106. data/ext/{ev/ev.h → gyro/gyro.h} +12 -7
  107. data/ext/gyro/gyro_ext.c +23 -0
  108. data/ext/{ev → gyro}/io.c +65 -57
  109. data/ext/{ev → gyro}/libev.h +0 -0
  110. data/ext/gyro/signal.c +117 -0
  111. data/ext/{ev → gyro}/socket.c +61 -6
  112. data/ext/gyro/timer.c +199 -0
  113. data/ext/libev/Changes +35 -0
  114. data/ext/libev/README +2 -1
  115. data/ext/libev/ev.c +213 -151
  116. data/ext/libev/ev.h +95 -88
  117. data/ext/libev/ev_epoll.c +26 -15
  118. data/ext/libev/ev_kqueue.c +11 -5
  119. data/ext/libev/ev_linuxaio.c +642 -0
  120. data/ext/libev/ev_poll.c +13 -8
  121. data/ext/libev/ev_port.c +5 -2
  122. data/ext/libev/ev_vars.h +14 -3
  123. data/ext/libev/ev_wrap.h +16 -0
  124. data/lib/ev_ext.bundle +0 -0
  125. data/lib/polyphony.rb +46 -50
  126. data/lib/polyphony/auto_run.rb +12 -0
  127. data/lib/polyphony/core/cancel_scope.rb +11 -7
  128. data/lib/polyphony/core/channel.rb +16 -9
  129. data/lib/polyphony/core/coprocess.rb +101 -51
  130. data/lib/polyphony/core/exceptions.rb +14 -12
  131. data/lib/polyphony/core/resource_pool.rb +21 -8
  132. data/lib/polyphony/core/supervisor.rb +10 -5
  133. data/lib/polyphony/core/sync.rb +7 -6
  134. data/lib/polyphony/core/thread.rb +4 -4
  135. data/lib/polyphony/core/thread_pool.rb +4 -4
  136. data/lib/polyphony/core/throttler.rb +6 -4
  137. data/lib/polyphony/extensions/core.rb +253 -0
  138. data/lib/polyphony/extensions/io.rb +28 -16
  139. data/lib/polyphony/extensions/openssl.rb +2 -1
  140. data/lib/polyphony/extensions/socket.rb +47 -52
  141. data/lib/polyphony/http.rb +4 -3
  142. data/lib/polyphony/http/agent.rb +68 -57
  143. data/lib/polyphony/http/server.rb +5 -5
  144. data/lib/polyphony/http/server/http1.rb +268 -0
  145. data/lib/polyphony/http/server/http2.rb +62 -0
  146. data/lib/polyphony/http/server/http2_stream.rb +104 -0
  147. data/lib/polyphony/http/server/rack.rb +64 -0
  148. data/lib/polyphony/http/server/request.rb +119 -0
  149. data/lib/polyphony/net.rb +26 -15
  150. data/lib/polyphony/postgres.rb +17 -13
  151. data/lib/polyphony/redis.rb +16 -15
  152. data/lib/polyphony/version.rb +1 -1
  153. data/lib/polyphony/websocket.rb +11 -4
  154. data/polyphony.gemspec +13 -9
  155. data/test/eg.rb +27 -0
  156. data/test/helper.rb +25 -0
  157. data/test/run.rb +5 -0
  158. data/test/test_async.rb +33 -0
  159. data/test/test_coprocess.rb +239 -77
  160. data/test/test_core.rb +95 -61
  161. data/test/test_gyro.rb +148 -0
  162. data/test/test_http_server.rb +313 -0
  163. data/test/test_io.rb +79 -27
  164. data/test/test_kernel.rb +22 -12
  165. data/test/test_signal.rb +36 -0
  166. data/test/test_timer.rb +24 -0
  167. metadata +89 -33
  168. data/examples/core/nested_async.rb +0 -17
  169. data/examples/core/next_tick.rb +0 -12
  170. data/examples/core/sleep_spawn.rb +0 -19
  171. data/examples/core/spawn.rb +0 -14
  172. data/examples/core/spawn_error.rb +0 -28
  173. data/examples/performance/perf_multi_snooze.rb +0 -21
  174. data/ext/ev/async.c +0 -168
  175. data/ext/ev/child.c +0 -169
  176. data/ext/ev/ev_ext.c +0 -23
  177. data/ext/ev/ev_module.c +0 -242
  178. data/ext/ev/signal.c +0 -119
  179. data/ext/ev/timer.c +0 -197
  180. data/lib/polyphony/core/fiber_pool.rb +0 -98
  181. data/lib/polyphony/extensions/kernel.rb +0 -169
  182. data/lib/polyphony/http/http1_adapter.rb +0 -254
  183. data/lib/polyphony/http/http2_adapter.rb +0 -157
  184. data/lib/polyphony/http/rack.rb +0 -25
  185. data/lib/polyphony/http/request.rb +0 -66
  186. data/test/test_ev.rb +0 -110
@@ -5,29 +5,34 @@
5
5
  #include "ruby/io.h"
6
6
  #include "libev.h"
7
7
 
8
- void EV_add_watcher_ref(VALUE obj);
9
- void EV_del_watcher_ref(VALUE obj);
10
- void EV_async_free(void *p);
8
+ void Gyro_add_watcher_ref(VALUE obj);
9
+ void Gyro_del_watcher_ref(VALUE obj);
10
+ VALUE Gyro_snooze(VALUE self);
11
11
 
12
12
  VALUE IO_read_watcher(VALUE io);
13
13
  VALUE IO_write_watcher(VALUE io);
14
- VALUE EV_IO_await(VALUE self);
14
+ VALUE Gyro_IO_await(VALUE self);
15
15
 
16
16
  int io_setstrbuf(VALUE *str, long len);
17
17
  void io_set_read_length(VALUE str, long n, int shrinkable);
18
18
  VALUE io_enc_str(VALUE str, rb_io_t *fptr);
19
19
 
20
20
  #define SCHEDULE_FIBER(obj, args...) rb_funcall(obj, ID_transfer, args)
21
- #define YIELD_TO_REACTOR() rb_funcall(EV_reactor_fiber, ID_transfer, 0)
21
+ #define YIELD_TO_REACTOR() rb_funcall(Gyro_reactor_fiber, ID_transfer, 0)
22
22
 
23
- extern VALUE EV_reactor_fiber;
24
- extern VALUE EV_root_fiber;
23
+ #define OBJ_ID(obj) (NUM2LONG(rb_funcall(obj, rb_intern("object_id"), 0)))
24
+
25
+ extern VALUE mGyro;
26
+
27
+ extern VALUE Gyro_reactor_fiber;
28
+ extern VALUE Gyro_root_fiber;
25
29
 
26
30
  extern ID ID_call;
27
31
  extern ID ID_caller;
28
32
  extern ID ID_clear;
29
33
  extern ID ID_each;
30
34
  extern ID ID_inspect;
35
+ extern ID ID_next_deferred;
31
36
  extern ID ID_raise;
32
37
  extern ID ID_read_watcher;
33
38
  extern ID ID_scheduled_value;
@@ -0,0 +1,23 @@
1
+ #include "gyro.h"
2
+ #include "../libev/ev.c"
3
+
4
+ void Init_Gyro();
5
+ void Init_Gyro_Async();
6
+ void Init_Gyro_Child();
7
+ void Init_Gyro_IO();
8
+ void Init_Gyro_Signal();
9
+ void Init_Gyro_Timer();
10
+ void Init_Socket();
11
+
12
+ void Init_gyro_ext() {
13
+ ev_set_allocator(xrealloc);
14
+
15
+ Init_Gyro();
16
+ Init_Gyro_Async();
17
+ Init_Gyro_Child();
18
+ Init_Gyro_IO();
19
+ Init_Gyro_Signal();
20
+ Init_Gyro_Timer();
21
+
22
+ Init_Socket();
23
+ }
@@ -1,4 +1,4 @@
1
- #include "ev.h"
1
+ #include "gyro.h"
2
2
 
3
3
  #ifdef GetReadFile
4
4
  # define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))
@@ -6,7 +6,7 @@
6
6
  # define FPTR_TO_FD(fptr) fptr->fd
7
7
  #endif /* GetReadFile */
8
8
 
9
- struct EV_IO {
9
+ struct Gyro_IO {
10
10
  struct ev_io ev_io;
11
11
  int active;
12
12
  int event_mask;
@@ -14,22 +14,21 @@ struct EV_IO {
14
14
  VALUE fiber;
15
15
  };
16
16
 
17
- static VALUE mEV = Qnil;
18
- static VALUE cEV_IO = Qnil;
17
+ static VALUE cGyro_IO = Qnil;
19
18
 
20
- static VALUE EV_IO_allocate(VALUE klass);
21
- static void EV_IO_mark(void *ptr);
22
- static void EV_IO_free(void *ptr);
23
- static size_t EV_IO_size(const void *ptr);
19
+ static VALUE Gyro_IO_allocate(VALUE klass);
20
+ static void Gyro_IO_mark(void *ptr);
21
+ static void Gyro_IO_free(void *ptr);
22
+ static size_t Gyro_IO_size(const void *ptr);
24
23
 
25
- static VALUE EV_IO_initialize(VALUE self, VALUE io, VALUE event_mask);
24
+ static VALUE Gyro_IO_initialize(VALUE self, VALUE io, VALUE event_mask);
26
25
 
27
- static VALUE EV_IO_start(VALUE self);
28
- static VALUE EV_IO_stop(VALUE self);
26
+ static VALUE Gyro_IO_start(VALUE self);
27
+ static VALUE Gyro_IO_stop(VALUE self);
29
28
 
30
- void EV_IO_callback(ev_loop *ev_loop, struct ev_io *io, int revents);
29
+ void Gyro_IO_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
31
30
 
32
- static int EV_IO_symbol2event_mask(VALUE sym);
31
+ static int Gyro_IO_symbol2event_mask(VALUE sym);
33
32
 
34
33
  // static VALUE IO_gets(int argc, VALUE *argv, VALUE io);
35
34
  static VALUE IO_read(int argc, VALUE *argv, VALUE io);
@@ -37,15 +36,14 @@ static VALUE IO_readpartial(int argc, VALUE *argv, VALUE io);
37
36
  static VALUE IO_write(int argc, VALUE *argv, VALUE io);
38
37
  static VALUE IO_write_chevron(VALUE io, VALUE str);
39
38
 
40
- void Init_EV_IO() {
41
- mEV = rb_define_module("EV");
42
- cEV_IO = rb_define_class_under(mEV, "IO", rb_cData);
43
- rb_define_alloc_func(cEV_IO, EV_IO_allocate);
39
+ void Init_Gyro_IO() {
40
+ cGyro_IO = rb_define_class_under(mGyro, "IO", rb_cData);
41
+ rb_define_alloc_func(cGyro_IO, Gyro_IO_allocate);
44
42
 
45
- rb_define_method(cEV_IO, "initialize", EV_IO_initialize, 2);
46
- rb_define_method(cEV_IO, "start", EV_IO_start, 0);
47
- rb_define_method(cEV_IO, "stop", EV_IO_stop, 0);
48
- rb_define_method(cEV_IO, "await", EV_IO_await, 0);
43
+ rb_define_method(cGyro_IO, "initialize", Gyro_IO_initialize, 2);
44
+ rb_define_method(cGyro_IO, "start", Gyro_IO_start, 0);
45
+ rb_define_method(cGyro_IO, "stop", Gyro_IO_stop, 0);
46
+ rb_define_method(cGyro_IO, "await", Gyro_IO_await, 0);
49
47
 
50
48
  VALUE cIO = rb_const_get(rb_cObject, rb_intern("IO"));
51
49
  // rb_define_method(cIO, "gets", IO_gets, -1);
@@ -58,21 +56,21 @@ void Init_EV_IO() {
58
56
  rb_define_method(cIO, "write_watcher", IO_write_watcher, 0);
59
57
  }
60
58
 
61
- static const rb_data_type_t EV_IO_type = {
62
- "EV_IO",
63
- {EV_IO_mark, EV_IO_free, EV_IO_size,},
59
+ static const rb_data_type_t Gyro_IO_type = {
60
+ "Gyro_IO",
61
+ {Gyro_IO_mark, Gyro_IO_free, Gyro_IO_size,},
64
62
  0, 0,
65
63
  RUBY_TYPED_FREE_IMMEDIATELY,
66
64
  };
67
65
 
68
- static VALUE EV_IO_allocate(VALUE klass) {
69
- struct EV_IO *io = (struct EV_IO *)xmalloc(sizeof(struct EV_IO));
66
+ static VALUE Gyro_IO_allocate(VALUE klass) {
67
+ struct Gyro_IO *io = (struct Gyro_IO *)xmalloc(sizeof(struct Gyro_IO));
70
68
 
71
- return TypedData_Wrap_Struct(klass, &EV_IO_type, io);
69
+ return TypedData_Wrap_Struct(klass, &Gyro_IO_type, io);
72
70
  }
73
71
 
74
- static void EV_IO_mark(void *ptr) {
75
- struct EV_IO *io = ptr;
72
+ static void Gyro_IO_mark(void *ptr) {
73
+ struct Gyro_IO *io = ptr;
76
74
  if (io->callback != Qnil) {
77
75
  rb_gc_mark(io->callback);
78
76
  }
@@ -81,41 +79,41 @@ static void EV_IO_mark(void *ptr) {
81
79
  }
82
80
  }
83
81
 
84
- static void EV_IO_free(void *ptr) {
85
- struct EV_IO *io = ptr;
82
+ static void Gyro_IO_free(void *ptr) {
83
+ struct Gyro_IO *io = ptr;
86
84
  ev_io_stop(EV_DEFAULT, &io->ev_io);
87
85
  xfree(io);
88
86
  }
89
87
 
90
- static size_t EV_IO_size(const void *ptr) {
91
- return sizeof(struct EV_IO);
88
+ static size_t Gyro_IO_size(const void *ptr) {
89
+ return sizeof(struct Gyro_IO);
92
90
  }
93
91
 
94
92
  static const char * S_IO = "IO";
95
93
  static const char * S_to_io = "to_io";
96
94
 
97
- #define GetEV_IO(obj, io) TypedData_Get_Struct((obj), struct EV_IO, &EV_IO_type, (io))
95
+ #define GetGyro_IO(obj, io) TypedData_Get_Struct((obj), struct Gyro_IO, &Gyro_IO_type, (io))
98
96
 
99
- static VALUE EV_IO_initialize(VALUE self, VALUE io_obj, VALUE event_mask) {
100
- struct EV_IO *io;
97
+ static VALUE Gyro_IO_initialize(VALUE self, VALUE io_obj, VALUE event_mask) {
98
+ struct Gyro_IO *io;
101
99
  rb_io_t *fptr;
102
100
 
103
- GetEV_IO(self, io);
101
+ GetGyro_IO(self, io);
104
102
 
105
- io->event_mask = EV_IO_symbol2event_mask(event_mask);
103
+ io->event_mask = Gyro_IO_symbol2event_mask(event_mask);
106
104
  io->callback = Qnil;
107
105
  io->fiber = Qnil;
108
106
  io->active = 0;
109
107
 
110
108
  GetOpenFile(rb_convert_type(io_obj, T_FILE, S_IO, S_to_io), fptr);
111
- ev_io_init(&io->ev_io, EV_IO_callback, FPTR_TO_FD(fptr), io->event_mask);
109
+ ev_io_init(&io->ev_io, Gyro_IO_callback, FPTR_TO_FD(fptr), io->event_mask);
112
110
 
113
111
  return Qnil;
114
112
  }
115
113
 
116
- void EV_IO_callback(ev_loop *ev_loop, struct ev_io *ev_io, int revents) {
114
+ void Gyro_IO_callback(struct ev_loop *ev_loop, struct ev_io *ev_io, int revents) {
117
115
  VALUE fiber;
118
- struct EV_IO *io = (struct EV_IO*)ev_io;
116
+ struct Gyro_IO *io = (struct Gyro_IO*)ev_io;
119
117
 
120
118
  if (io->fiber != Qnil) {
121
119
  ev_io_stop(EV_DEFAULT, ev_io);
@@ -132,9 +130,9 @@ void EV_IO_callback(ev_loop *ev_loop, struct ev_io *ev_io, int revents) {
132
130
  }
133
131
  }
134
132
 
135
- static VALUE EV_IO_start(VALUE self) {
136
- struct EV_IO *io;
137
- GetEV_IO(self, io);
133
+ static VALUE Gyro_IO_start(VALUE self) {
134
+ struct Gyro_IO *io;
135
+ GetGyro_IO(self, io);
138
136
 
139
137
  if (rb_block_given_p()) {
140
138
  io->callback = rb_block_proc();
@@ -148,9 +146,9 @@ static VALUE EV_IO_start(VALUE self) {
148
146
  return self;
149
147
  }
150
148
 
151
- static VALUE EV_IO_stop(VALUE self) {
152
- struct EV_IO *io;
153
- GetEV_IO(self, io);
149
+ static VALUE Gyro_IO_stop(VALUE self) {
150
+ struct Gyro_IO *io;
151
+ GetGyro_IO(self, io);
154
152
 
155
153
  if (io->active) {
156
154
  ev_io_stop(EV_DEFAULT, &io->ev_io);
@@ -160,11 +158,11 @@ static VALUE EV_IO_stop(VALUE self) {
160
158
  return self;
161
159
  }
162
160
 
163
- VALUE EV_IO_await(VALUE self) {
164
- struct EV_IO *io;
161
+ VALUE Gyro_IO_await(VALUE self) {
162
+ struct Gyro_IO *io;
165
163
  VALUE ret;
166
164
 
167
- GetEV_IO(self, io);
165
+ GetGyro_IO(self, io);
168
166
 
169
167
  io->fiber = rb_fiber_current();
170
168
  io->active = 1;
@@ -186,7 +184,7 @@ VALUE EV_IO_await(VALUE self) {
186
184
  }
187
185
  }
188
186
 
189
- static int EV_IO_symbol2event_mask(VALUE sym) {
187
+ static int Gyro_IO_symbol2event_mask(VALUE sym) {
190
188
  ID sym_id;
191
189
 
192
190
  if (NIL_P(sym)) {
@@ -273,7 +271,7 @@ static VALUE IO_read(int argc, VALUE *argv, VALUE io) {
273
271
  VALUE underlying_io = rb_iv_get(io, "@io");
274
272
  if (!NIL_P(underlying_io)) io = underlying_io;
275
273
 
276
- long len = argc == 1 ? NUM2LONG(argv[0]) : 8192;
274
+ long len = argc == 1 ? NUM2LONG(argv[0]) : (1 << 30);
277
275
 
278
276
  rb_io_t *fptr;
279
277
  long n;
@@ -305,7 +303,7 @@ static VALUE IO_read(int argc, VALUE *argv, VALUE io) {
305
303
  if ((e == EWOULDBLOCK || e == EAGAIN)) {
306
304
  if (read_watcher == Qnil)
307
305
  read_watcher = IO_read_watcher(io);
308
- EV_IO_await(read_watcher);
306
+ Gyro_IO_await(read_watcher);
309
307
  }
310
308
  else
311
309
  rb_syserr_fail(e, strerror(e));
@@ -364,7 +362,7 @@ static VALUE IO_readpartial(int argc, VALUE *argv, VALUE io) {
364
362
  if (e == EWOULDBLOCK || e == EAGAIN) {
365
363
  if (read_watcher == Qnil)
366
364
  read_watcher = IO_read_watcher(io);
367
- EV_IO_await(read_watcher);
365
+ Gyro_IO_await(read_watcher);
368
366
  }
369
367
  else
370
368
  rb_syserr_fail(e, strerror(e));
@@ -377,6 +375,11 @@ static VALUE IO_readpartial(int argc, VALUE *argv, VALUE io) {
377
375
  io_set_read_length(str, n, shrinkable);
378
376
  io_enc_str(str, fptr);
379
377
 
378
+ // ensure yielding to reactor if haven't yielded while reading
379
+ // if (read_watcher == Qnil) {
380
+ // Gyro_snooze(Qnil);
381
+ // }
382
+
380
383
  if (n == 0)
381
384
  return Qnil;
382
385
 
@@ -415,7 +418,7 @@ static VALUE IO_write(int argc, VALUE *argv, VALUE io) {
415
418
  if (write_watcher == Qnil)
416
419
  write_watcher = IO_write_watcher(io);
417
420
  // write_watcher = rb_funcall(io, ID_write_watcher, 0);
418
- EV_IO_await(write_watcher);
421
+ Gyro_IO_await(write_watcher);
419
422
  }
420
423
  else {
421
424
  rb_syserr_fail(e, strerror(e));
@@ -433,6 +436,11 @@ static VALUE IO_write(int argc, VALUE *argv, VALUE io) {
433
436
  }
434
437
  }
435
438
 
439
+ // ensure yielding to reactor if haven't yielded while writing
440
+ // if (write_watcher == Qnil) {
441
+ // Gyro_snooze(Qnil);
442
+ // }
443
+
436
444
  return LONG2FIX(total);
437
445
  }
438
446
 
@@ -444,7 +452,7 @@ static VALUE IO_write_chevron(VALUE io, VALUE str) {
444
452
  VALUE IO_read_watcher(VALUE self) {
445
453
  VALUE watcher = rb_iv_get(self, "@read_watcher");
446
454
  if (watcher == Qnil) {
447
- watcher = rb_funcall(cEV_IO, rb_intern("new"), 2, self, ID2SYM(rb_intern("r")));
455
+ watcher = rb_funcall(cGyro_IO, rb_intern("new"), 2, self, ID2SYM(rb_intern("r")));
448
456
  rb_iv_set(self, "@read_watcher", watcher);
449
457
  }
450
458
  return watcher;
@@ -453,7 +461,7 @@ VALUE IO_read_watcher(VALUE self) {
453
461
  VALUE IO_write_watcher(VALUE self) {
454
462
  VALUE watcher = rb_iv_get(self, "@write_watcher");
455
463
  if (watcher == Qnil) {
456
- watcher = rb_funcall(cEV_IO, rb_intern("new"), 2, self, ID2SYM(rb_intern("w")));
464
+ watcher = rb_funcall(cGyro_IO, rb_intern("new"), 2, self, ID2SYM(rb_intern("w")));
457
465
  rb_iv_set(self, "@write_watcher", watcher);
458
466
  }
459
467
  return watcher;
File without changes
data/ext/gyro/signal.c ADDED
@@ -0,0 +1,117 @@
1
+ #include "gyro.h"
2
+
3
+ struct Gyro_Signal {
4
+ struct ev_signal ev_signal;
5
+ int active;
6
+ int signum;
7
+ VALUE callback;
8
+ };
9
+
10
+ static VALUE cGyro_Signal = Qnil;
11
+
12
+ /* Allocator/deallocator */
13
+ static VALUE Gyro_Signal_allocate(VALUE klass);
14
+ static void Gyro_Signal_mark(void *ptr);
15
+ static void Gyro_Signal_free(void *ptr);
16
+ static size_t Gyro_Signal_size(const void *ptr);
17
+
18
+ /* Methods */
19
+ static VALUE Gyro_Signal_initialize(VALUE self, VALUE sig);
20
+
21
+ static VALUE Gyro_Signal_start(VALUE self);
22
+ static VALUE Gyro_Signal_stop(VALUE self);
23
+
24
+ void Gyro_Signal_callback(struct ev_loop *ev_loop, struct ev_signal *signal, int revents);
25
+
26
+ /* Signal encapsulates a signal watcher */
27
+ void Init_Gyro_Signal() {
28
+ cGyro_Signal = rb_define_class_under(mGyro, "Signal", rb_cData);
29
+ rb_define_alloc_func(cGyro_Signal, Gyro_Signal_allocate);
30
+
31
+ rb_define_method(cGyro_Signal, "initialize", Gyro_Signal_initialize, 1);
32
+ rb_define_method(cGyro_Signal, "start", Gyro_Signal_start, 0);
33
+ rb_define_method(cGyro_Signal, "stop", Gyro_Signal_stop, 0);
34
+ }
35
+
36
+ static const rb_data_type_t Gyro_Signal_type = {
37
+ "Gyro_Signal",
38
+ {Gyro_Signal_mark, Gyro_Signal_free, Gyro_Signal_size,},
39
+ 0, 0,
40
+ RUBY_TYPED_FREE_IMMEDIATELY,
41
+ };
42
+
43
+ static VALUE Gyro_Signal_allocate(VALUE klass) {
44
+ struct Gyro_Signal *signal = (struct Gyro_Signal *)xmalloc(sizeof(struct Gyro_Signal));
45
+ return TypedData_Wrap_Struct(klass, &Gyro_Signal_type, signal);
46
+ }
47
+
48
+ static void Gyro_Signal_mark(void *ptr) {
49
+ struct Gyro_Signal *signal = ptr;
50
+ if (signal->callback != Qnil) {
51
+ rb_gc_mark(signal->callback);
52
+ }
53
+ }
54
+
55
+ static void Gyro_Signal_free(void *ptr) {
56
+ struct Gyro_Signal *signal = ptr;
57
+ ev_signal_stop(EV_DEFAULT, &signal->ev_signal);
58
+ xfree(signal);
59
+ }
60
+
61
+ static size_t Gyro_Signal_size(const void *ptr) {
62
+ return sizeof(struct Gyro_Signal);
63
+ }
64
+
65
+ #define GetGyro_Signal(obj, signal) \
66
+ TypedData_Get_Struct((obj), struct Gyro_Signal, &Gyro_Signal_type, (signal))
67
+
68
+ static VALUE Gyro_Signal_initialize(VALUE self, VALUE sig) {
69
+ struct Gyro_Signal *signal;
70
+ VALUE signum = sig;
71
+
72
+ GetGyro_Signal(self, signal);
73
+ signal->signum = NUM2INT(signum);
74
+
75
+ if (rb_block_given_p()) {
76
+ signal->callback = rb_block_proc();
77
+ }
78
+
79
+ ev_signal_init(&signal->ev_signal, Gyro_Signal_callback, signal->signum);
80
+
81
+ signal->active = 1;
82
+ ev_signal_start(EV_DEFAULT, &signal->ev_signal);
83
+
84
+ return Qnil;
85
+ }
86
+
87
+ void Gyro_Signal_callback(struct ev_loop *ev_loop, struct ev_signal *ev_signal, int revents) {
88
+ struct Gyro_Signal *signal = (struct Gyro_Signal*)ev_signal;
89
+
90
+ if (signal->callback != Qnil) {
91
+ rb_funcall(signal->callback, ID_call, 1, INT2NUM(signal->signum));
92
+ }
93
+ }
94
+
95
+ static VALUE Gyro_Signal_start(VALUE self) {
96
+ struct Gyro_Signal *signal;
97
+ GetGyro_Signal(self, signal);
98
+
99
+ if (!signal->active) {
100
+ ev_signal_start(EV_DEFAULT, &signal->ev_signal);
101
+ signal->active = 1;
102
+ }
103
+
104
+ return self;
105
+ }
106
+
107
+ static VALUE Gyro_Signal_stop(VALUE self) {
108
+ struct Gyro_Signal *signal;
109
+ GetGyro_Signal(self, signal);
110
+
111
+ if (signal->active) {
112
+ ev_signal_stop(EV_DEFAULT, &signal->ev_signal);
113
+ signal->active = 0;
114
+ }
115
+
116
+ return self;
117
+ }