polyphony 0.19 → 0.20

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