polyphony 0.19 → 0.20
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.rubocop.yml +87 -1
- data/CHANGELOG.md +35 -0
- data/Gemfile.lock +17 -6
- data/README.md +200 -139
- data/Rakefile +4 -4
- data/TODO.md +35 -7
- data/bin/poly +11 -0
- data/docs/getting-started/getting-started.md +1 -1
- data/docs/summary.md +3 -0
- data/docs/technical-overview/exception-handling.md +94 -0
- data/docs/technical-overview/fiber-scheduling.md +99 -0
- data/examples/core/cancel.rb +8 -4
- data/examples/core/channel_echo.rb +18 -17
- data/examples/core/defer.rb +12 -0
- data/examples/core/enumerator.rb +4 -4
- data/examples/core/fiber_error.rb +9 -0
- data/examples/core/fiber_error_with_backtrace.rb +73 -0
- data/examples/core/fork.rb +6 -6
- data/examples/core/genserver.rb +16 -8
- data/examples/core/lock.rb +3 -3
- data/examples/core/move_on.rb +4 -3
- data/examples/core/move_on_twice.rb +5 -5
- data/examples/core/move_on_with_ensure.rb +8 -11
- data/examples/core/move_on_with_value.rb +14 -0
- data/examples/core/{multiple_spawn.rb → multiple_spin.rb} +5 -5
- data/examples/core/nested_cancel.rb +5 -5
- data/examples/core/{nested_multiple_spawn.rb → nested_multiple_spin.rb} +6 -6
- data/examples/core/nested_spin.rb +17 -0
- data/examples/core/pingpong.rb +21 -0
- data/examples/core/pulse.rb +4 -5
- data/examples/core/resource.rb +6 -4
- data/examples/core/resource_cancel.rb +6 -9
- data/examples/core/resource_delegate.rb +3 -3
- data/examples/core/sleep.rb +3 -3
- data/examples/core/sleep_spin.rb +19 -0
- data/examples/core/snooze.rb +32 -0
- data/examples/core/spin.rb +14 -0
- data/examples/core/{spawn_cancel.rb → spin_cancel.rb} +6 -7
- data/examples/core/spin_error.rb +17 -0
- data/examples/core/spin_error_backtrace.rb +30 -0
- data/examples/core/spin_uncaught_error.rb +15 -0
- data/examples/core/supervisor.rb +8 -8
- data/examples/core/supervisor_with_cancel_scope.rb +7 -7
- data/examples/core/supervisor_with_error.rb +8 -8
- data/examples/core/supervisor_with_manual_move_on.rb +6 -7
- data/examples/core/suspend.rb +13 -0
- data/examples/core/thread.rb +1 -1
- data/examples/core/thread_cancel.rb +9 -11
- data/examples/core/thread_pool.rb +18 -14
- data/examples/core/throttle.rb +7 -7
- data/examples/core/timeout.rb +3 -3
- data/examples/fs/read.rb +7 -9
- data/examples/http/config.ru +7 -3
- data/examples/http/cuba.ru +22 -0
- data/examples/http/happy_eyeballs.rb +6 -4
- data/examples/http/http_client.rb +1 -1
- data/examples/http/http_get.rb +1 -1
- data/examples/http/http_parse_experiment.rb +21 -16
- data/examples/http/http_proxy.rb +28 -26
- data/examples/http/http_server.rb +10 -10
- data/examples/http/http_server_forked.rb +6 -5
- data/examples/http/http_server_throttled.rb +3 -3
- data/examples/http/http_ws_server.rb +11 -11
- data/examples/http/https_raw_client.rb +1 -1
- data/examples/http/https_server.rb +8 -8
- data/examples/http/https_wss_server.rb +13 -11
- data/examples/http/rack_server.rb +2 -2
- data/examples/http/rack_server_https.rb +4 -4
- data/examples/http/rack_server_https_forked.rb +5 -5
- data/examples/http/websocket_secure_server.rb +6 -6
- data/examples/http/websocket_server.rb +5 -5
- data/examples/interfaces/pg_client.rb +4 -4
- data/examples/interfaces/pg_pool.rb +13 -6
- data/examples/interfaces/pg_transaction.rb +5 -4
- data/examples/interfaces/redis_channels.rb +15 -11
- data/examples/interfaces/redis_client.rb +2 -2
- data/examples/interfaces/redis_pubsub.rb +2 -1
- data/examples/interfaces/redis_pubsub_perf.rb +13 -9
- data/examples/io/backticks.rb +11 -0
- data/examples/io/cat.rb +4 -5
- data/examples/io/echo_client.rb +9 -4
- data/examples/io/echo_client_from_stdin.rb +20 -0
- data/examples/io/echo_pipe.rb +7 -8
- data/examples/io/echo_server.rb +8 -6
- data/examples/io/echo_server_with_timeout.rb +13 -10
- data/examples/io/echo_stdin.rb +3 -3
- data/examples/io/httparty.rb +2 -2
- data/examples/io/httparty_multi.rb +8 -4
- data/examples/io/httparty_threaded.rb +6 -2
- data/examples/io/io_read.rb +2 -2
- data/examples/io/irb.rb +16 -4
- data/examples/io/net-http.rb +3 -3
- data/examples/io/open.rb +17 -0
- data/examples/io/system.rb +3 -3
- data/examples/io/tcpserver.rb +15 -0
- data/examples/io/tcpsocket.rb +6 -5
- data/examples/performance/multi_snooze.rb +29 -0
- data/examples/performance/{perf_snooze.rb → snooze.rb} +7 -5
- data/examples/performance/snooze_raw.rb +39 -0
- data/ext/gyro/async.c +165 -0
- data/ext/gyro/child.c +167 -0
- data/ext/{ev → gyro}/extconf.rb +4 -3
- data/ext/gyro/gyro.c +316 -0
- data/ext/{ev/ev.h → gyro/gyro.h} +12 -7
- data/ext/gyro/gyro_ext.c +23 -0
- data/ext/{ev → gyro}/io.c +65 -57
- data/ext/{ev → gyro}/libev.h +0 -0
- data/ext/gyro/signal.c +117 -0
- data/ext/{ev → gyro}/socket.c +61 -6
- data/ext/gyro/timer.c +199 -0
- data/ext/libev/Changes +35 -0
- data/ext/libev/README +2 -1
- data/ext/libev/ev.c +213 -151
- data/ext/libev/ev.h +95 -88
- data/ext/libev/ev_epoll.c +26 -15
- data/ext/libev/ev_kqueue.c +11 -5
- data/ext/libev/ev_linuxaio.c +642 -0
- data/ext/libev/ev_poll.c +13 -8
- data/ext/libev/ev_port.c +5 -2
- data/ext/libev/ev_vars.h +14 -3
- data/ext/libev/ev_wrap.h +16 -0
- data/lib/ev_ext.bundle +0 -0
- data/lib/polyphony.rb +46 -50
- data/lib/polyphony/auto_run.rb +12 -0
- data/lib/polyphony/core/cancel_scope.rb +11 -7
- data/lib/polyphony/core/channel.rb +16 -9
- data/lib/polyphony/core/coprocess.rb +101 -51
- data/lib/polyphony/core/exceptions.rb +14 -12
- data/lib/polyphony/core/resource_pool.rb +21 -8
- data/lib/polyphony/core/supervisor.rb +10 -5
- data/lib/polyphony/core/sync.rb +7 -6
- data/lib/polyphony/core/thread.rb +4 -4
- data/lib/polyphony/core/thread_pool.rb +4 -4
- data/lib/polyphony/core/throttler.rb +6 -4
- data/lib/polyphony/extensions/core.rb +253 -0
- data/lib/polyphony/extensions/io.rb +28 -16
- data/lib/polyphony/extensions/openssl.rb +2 -1
- data/lib/polyphony/extensions/socket.rb +47 -52
- data/lib/polyphony/http.rb +4 -3
- data/lib/polyphony/http/agent.rb +68 -57
- data/lib/polyphony/http/server.rb +5 -5
- data/lib/polyphony/http/server/http1.rb +268 -0
- data/lib/polyphony/http/server/http2.rb +62 -0
- data/lib/polyphony/http/server/http2_stream.rb +104 -0
- data/lib/polyphony/http/server/rack.rb +64 -0
- data/lib/polyphony/http/server/request.rb +119 -0
- data/lib/polyphony/net.rb +26 -15
- data/lib/polyphony/postgres.rb +17 -13
- data/lib/polyphony/redis.rb +16 -15
- data/lib/polyphony/version.rb +1 -1
- data/lib/polyphony/websocket.rb +11 -4
- data/polyphony.gemspec +13 -9
- data/test/eg.rb +27 -0
- data/test/helper.rb +25 -0
- data/test/run.rb +5 -0
- data/test/test_async.rb +33 -0
- data/test/test_coprocess.rb +239 -77
- data/test/test_core.rb +95 -61
- data/test/test_gyro.rb +148 -0
- data/test/test_http_server.rb +313 -0
- data/test/test_io.rb +79 -27
- data/test/test_kernel.rb +22 -12
- data/test/test_signal.rb +36 -0
- data/test/test_timer.rb +24 -0
- metadata +89 -33
- data/examples/core/nested_async.rb +0 -17
- data/examples/core/next_tick.rb +0 -12
- data/examples/core/sleep_spawn.rb +0 -19
- data/examples/core/spawn.rb +0 -14
- data/examples/core/spawn_error.rb +0 -28
- data/examples/performance/perf_multi_snooze.rb +0 -21
- data/ext/ev/async.c +0 -168
- data/ext/ev/child.c +0 -169
- data/ext/ev/ev_ext.c +0 -23
- data/ext/ev/ev_module.c +0 -242
- data/ext/ev/signal.c +0 -119
- data/ext/ev/timer.c +0 -197
- data/lib/polyphony/core/fiber_pool.rb +0 -98
- data/lib/polyphony/extensions/kernel.rb +0 -169
- data/lib/polyphony/http/http1_adapter.rb +0 -254
- data/lib/polyphony/http/http2_adapter.rb +0 -157
- data/lib/polyphony/http/rack.rb +0 -25
- data/lib/polyphony/http/request.rb +0 -66
- data/test/test_ev.rb +0 -110
data/ext/ev/ev_ext.c
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
#include "ev.h"
|
2
|
-
#include "../libev/ev.c"
|
3
|
-
|
4
|
-
void Init_EV();
|
5
|
-
void Init_EV_Async();
|
6
|
-
void Init_EV_Child();
|
7
|
-
void Init_EV_IO();
|
8
|
-
void Init_EV_Signal();
|
9
|
-
void Init_EV_Timer();
|
10
|
-
void Init_Socket();
|
11
|
-
|
12
|
-
void Init_ev_ext() {
|
13
|
-
ev_set_allocator(xrealloc);
|
14
|
-
|
15
|
-
Init_EV();
|
16
|
-
Init_EV_Async();
|
17
|
-
Init_EV_Child();
|
18
|
-
Init_EV_IO();
|
19
|
-
Init_EV_Signal();
|
20
|
-
Init_EV_Timer();
|
21
|
-
|
22
|
-
Init_Socket();
|
23
|
-
}
|
data/ext/ev/ev_module.c
DELETED
@@ -1,242 +0,0 @@
|
|
1
|
-
#include "ev.h"
|
2
|
-
|
3
|
-
static VALUE mEV = Qnil;
|
4
|
-
|
5
|
-
static VALUE EV_run(VALUE self);
|
6
|
-
static VALUE EV_break(VALUE self);
|
7
|
-
static VALUE EV_restart(VALUE self);
|
8
|
-
static VALUE EV_rerun(VALUE self);
|
9
|
-
|
10
|
-
static VALUE EV_ref(VALUE self);
|
11
|
-
static VALUE EV_unref(VALUE self);
|
12
|
-
|
13
|
-
static VALUE EV_next_tick(VALUE self);
|
14
|
-
static VALUE EV_snooze(VALUE self);
|
15
|
-
static VALUE EV_post_fork(VALUE self);
|
16
|
-
|
17
|
-
static VALUE EV_suspend(VALUE self);
|
18
|
-
static VALUE EV_schedule_fiber(VALUE self, VALUE fiber, VALUE value);
|
19
|
-
|
20
|
-
static VALUE Fiber_safe_transfer(int argc, VALUE *argv, VALUE self);
|
21
|
-
|
22
|
-
static VALUE watcher_refs;
|
23
|
-
static VALUE next_tick_items;
|
24
|
-
|
25
|
-
static struct ev_idle next_tick_watcher;
|
26
|
-
static int next_tick_active;
|
27
|
-
void EV_next_tick_callback(ev_loop *ev_loop, struct ev_idle *watcher, int revents);
|
28
|
-
|
29
|
-
VALUE EV_reactor_fiber;
|
30
|
-
VALUE EV_root_fiber;
|
31
|
-
|
32
|
-
ID ID_call;
|
33
|
-
ID ID_caller;
|
34
|
-
ID ID_clear;
|
35
|
-
ID ID_each;
|
36
|
-
ID ID_inspect;
|
37
|
-
ID ID_raise;
|
38
|
-
ID ID_read_watcher;
|
39
|
-
ID ID_scheduled_value;
|
40
|
-
ID ID_transfer;
|
41
|
-
ID ID_write_watcher;
|
42
|
-
ID ID_R;
|
43
|
-
ID ID_W;
|
44
|
-
ID ID_RW;
|
45
|
-
|
46
|
-
void Init_EV() {
|
47
|
-
mEV = rb_define_module("EV");
|
48
|
-
|
49
|
-
rb_define_singleton_method(mEV, "break", EV_break, 0);
|
50
|
-
rb_define_singleton_method(mEV, "restart", EV_restart, 0);
|
51
|
-
rb_define_singleton_method(mEV, "rerun", EV_rerun, 0);
|
52
|
-
rb_define_singleton_method(mEV, "ref", EV_ref, 0);
|
53
|
-
rb_define_singleton_method(mEV, "unref", EV_unref, 0);
|
54
|
-
rb_define_singleton_method(mEV, "next_tick", EV_next_tick, 0);
|
55
|
-
rb_define_singleton_method(mEV, "snooze", EV_snooze, 0);
|
56
|
-
rb_define_singleton_method(mEV, "post_fork", EV_post_fork, 0);
|
57
|
-
rb_define_singleton_method(mEV, "schedule_fiber", EV_schedule_fiber, 2);
|
58
|
-
|
59
|
-
rb_define_global_function("suspend", EV_suspend, 0);
|
60
|
-
rb_define_global_function("snooze", EV_snooze, 0);
|
61
|
-
rb_define_global_function("next_tick", EV_next_tick, 0);
|
62
|
-
|
63
|
-
VALUE cFiber = rb_const_get(rb_cObject, rb_intern("Fiber"));
|
64
|
-
rb_define_method(cFiber, "safe_transfer", Fiber_safe_transfer, -1);
|
65
|
-
|
66
|
-
ID_call = rb_intern("call");
|
67
|
-
ID_caller = rb_intern("caller");
|
68
|
-
ID_clear = rb_intern("clear");
|
69
|
-
ID_each = rb_intern("each");
|
70
|
-
ID_inspect = rb_intern("inspect");
|
71
|
-
ID_raise = rb_intern("raise");
|
72
|
-
ID_read_watcher = rb_intern("read_watcher");
|
73
|
-
ID_scheduled_value = rb_intern("@scheduled_value");
|
74
|
-
ID_transfer = rb_intern("transfer");
|
75
|
-
ID_write_watcher = rb_intern("write_watcher");
|
76
|
-
ID_R = rb_intern("r");
|
77
|
-
ID_W = rb_intern("w");
|
78
|
-
ID_RW = rb_intern("rw");
|
79
|
-
|
80
|
-
EV_root_fiber = rb_fiber_current();
|
81
|
-
EV_reactor_fiber = rb_fiber_new(EV_run, Qnil);
|
82
|
-
rb_gv_set("__reactor_fiber__", EV_reactor_fiber);
|
83
|
-
|
84
|
-
|
85
|
-
watcher_refs = rb_hash_new();
|
86
|
-
rb_global_variable(&watcher_refs);
|
87
|
-
|
88
|
-
next_tick_items = rb_ary_new();
|
89
|
-
rb_global_variable(&next_tick_items);
|
90
|
-
|
91
|
-
ev_idle_init(&next_tick_watcher, EV_next_tick_callback);
|
92
|
-
next_tick_active = 0;
|
93
|
-
}
|
94
|
-
|
95
|
-
static VALUE EV_run(VALUE self) {
|
96
|
-
ev_run(EV_DEFAULT, 0);
|
97
|
-
rb_gv_set("__reactor_fiber__", Qnil);
|
98
|
-
return Qnil;
|
99
|
-
}
|
100
|
-
|
101
|
-
static VALUE EV_break(VALUE self) {
|
102
|
-
// make sure reactor fiber is alive
|
103
|
-
if (!RTEST(rb_fiber_alive_p(EV_reactor_fiber))) {
|
104
|
-
return Qnil;
|
105
|
-
}
|
106
|
-
|
107
|
-
ev_break(EV_DEFAULT, EVBREAK_ALL);
|
108
|
-
return YIELD_TO_REACTOR();
|
109
|
-
}
|
110
|
-
|
111
|
-
static VALUE EV_restart(VALUE self) {
|
112
|
-
EV_reactor_fiber = rb_fiber_new(EV_run, Qnil);
|
113
|
-
rb_gv_set("__reactor_fiber__", EV_reactor_fiber);
|
114
|
-
return Qnil;
|
115
|
-
}
|
116
|
-
|
117
|
-
static VALUE EV_rerun(VALUE self) {
|
118
|
-
EV_break(self);
|
119
|
-
EV_restart(self);
|
120
|
-
return Qnil;
|
121
|
-
}
|
122
|
-
|
123
|
-
static VALUE EV_ref(VALUE self) {
|
124
|
-
ev_ref(EV_DEFAULT);
|
125
|
-
return Qnil;
|
126
|
-
}
|
127
|
-
|
128
|
-
static VALUE EV_unref(VALUE self) {
|
129
|
-
ev_unref(EV_DEFAULT);
|
130
|
-
return Qnil;
|
131
|
-
}
|
132
|
-
|
133
|
-
void EV_add_watcher_ref(VALUE obj) {
|
134
|
-
rb_hash_aset(watcher_refs, rb_obj_id(obj), obj);
|
135
|
-
}
|
136
|
-
|
137
|
-
void EV_del_watcher_ref(VALUE obj) {
|
138
|
-
rb_hash_delete(watcher_refs, rb_obj_id(obj));
|
139
|
-
}
|
140
|
-
|
141
|
-
static VALUE EV_next_tick(VALUE self) {
|
142
|
-
VALUE proc = rb_block_proc();
|
143
|
-
if (RTEST(proc)) {
|
144
|
-
rb_ary_push(next_tick_items, proc);
|
145
|
-
if (!next_tick_active) {
|
146
|
-
next_tick_active = 1;
|
147
|
-
ev_idle_start(EV_DEFAULT, &next_tick_watcher);
|
148
|
-
}
|
149
|
-
}
|
150
|
-
return Qnil;
|
151
|
-
}
|
152
|
-
|
153
|
-
static VALUE EV_snooze(VALUE self) {
|
154
|
-
VALUE ret;
|
155
|
-
VALUE fiber = rb_fiber_current();
|
156
|
-
|
157
|
-
rb_ary_push(next_tick_items, fiber);
|
158
|
-
if (!next_tick_active) {
|
159
|
-
next_tick_active = 1;
|
160
|
-
ev_idle_start(EV_DEFAULT, &next_tick_watcher);
|
161
|
-
}
|
162
|
-
|
163
|
-
ret = YIELD_TO_REACTOR();
|
164
|
-
|
165
|
-
// fiber is resumed, check if resumed value is an exception
|
166
|
-
if (RTEST(rb_obj_is_kind_of(ret, rb_eException))) {
|
167
|
-
rb_ary_delete(next_tick_items, fiber);
|
168
|
-
return rb_funcall(ret, ID_raise, 1, ret);
|
169
|
-
}
|
170
|
-
else {
|
171
|
-
return ret;
|
172
|
-
}
|
173
|
-
}
|
174
|
-
|
175
|
-
static VALUE EV_post_fork(VALUE self) {
|
176
|
-
ev_loop_fork(EV_DEFAULT);
|
177
|
-
|
178
|
-
EV_reactor_fiber = rb_fiber_new(EV_run, Qnil);
|
179
|
-
rb_gv_set("__reactor_fiber__", EV_reactor_fiber);
|
180
|
-
EV_root_fiber = rb_fiber_current();
|
181
|
-
|
182
|
-
return Qnil;
|
183
|
-
}
|
184
|
-
|
185
|
-
VALUE EV_next_tick_runner(VALUE proc) {
|
186
|
-
if (rb_obj_is_proc(proc)) {
|
187
|
-
rb_funcall(proc, ID_call, 1, Qtrue);
|
188
|
-
}
|
189
|
-
else {
|
190
|
-
SCHEDULE_FIBER(proc, 1, rb_ivar_get(proc, ID_scheduled_value));
|
191
|
-
}
|
192
|
-
return Qnil;
|
193
|
-
}
|
194
|
-
|
195
|
-
void EV_next_tick_callback(ev_loop *ev_loop, struct ev_idle *watcher, int revents) {
|
196
|
-
VALUE scheduled_items = next_tick_items;
|
197
|
-
next_tick_items = rb_ary_new();
|
198
|
-
|
199
|
-
long len = RARRAY_LEN(scheduled_items);
|
200
|
-
for (long i = 0; i < len; i++) {
|
201
|
-
EV_next_tick_runner(RARRAY_AREF(scheduled_items, i));
|
202
|
-
}
|
203
|
-
|
204
|
-
// if no next tick items were added during callback, stop the idle watcher
|
205
|
-
if (rb_array_len(next_tick_items) == 0) {
|
206
|
-
next_tick_active = 0;
|
207
|
-
ev_idle_stop(EV_DEFAULT, &next_tick_watcher);
|
208
|
-
}
|
209
|
-
}
|
210
|
-
|
211
|
-
static VALUE EV_suspend(VALUE self) {
|
212
|
-
if (!RTEST(rb_fiber_alive_p(EV_reactor_fiber))) {
|
213
|
-
return Qnil;
|
214
|
-
}
|
215
|
-
|
216
|
-
VALUE ret = YIELD_TO_REACTOR();
|
217
|
-
|
218
|
-
// fiber is resumed, check if resumed value is an exception
|
219
|
-
return RTEST(rb_obj_is_kind_of(ret, rb_eException)) ?
|
220
|
-
rb_funcall(ret, ID_raise, 1, ret) : ret;
|
221
|
-
}
|
222
|
-
|
223
|
-
static VALUE EV_schedule_fiber(VALUE self, VALUE fiber, VALUE value) {
|
224
|
-
rb_ivar_set(fiber, ID_scheduled_value, value);
|
225
|
-
|
226
|
-
rb_ary_push(next_tick_items, fiber);
|
227
|
-
if (!next_tick_active) {
|
228
|
-
next_tick_active = 1;
|
229
|
-
ev_idle_start(EV_DEFAULT, &next_tick_watcher);
|
230
|
-
}
|
231
|
-
|
232
|
-
return Qnil;
|
233
|
-
}
|
234
|
-
|
235
|
-
static VALUE Fiber_safe_transfer(int argc, VALUE *argv, VALUE self) {
|
236
|
-
VALUE arg = (argc == 0) ? Qnil : argv[0];
|
237
|
-
VALUE ret = rb_funcall(self, ID_transfer, 1, arg);
|
238
|
-
|
239
|
-
// fiber is resumed, check if resumed value is an exception
|
240
|
-
return RTEST(rb_obj_is_kind_of(ret, rb_eException)) ?
|
241
|
-
rb_funcall(ret, ID_raise, 1, ret) : ret;
|
242
|
-
}
|
data/ext/ev/signal.c
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
#include "ev.h"
|
2
|
-
|
3
|
-
struct EV_Signal {
|
4
|
-
struct ev_signal ev_signal;
|
5
|
-
int active;
|
6
|
-
int signum;
|
7
|
-
VALUE callback;
|
8
|
-
};
|
9
|
-
|
10
|
-
static VALUE mEV = Qnil;
|
11
|
-
static VALUE cEV_Signal = Qnil;
|
12
|
-
|
13
|
-
/* Allocator/deallocator */
|
14
|
-
static VALUE EV_Signal_allocate(VALUE klass);
|
15
|
-
static void EV_Signal_mark(void *ptr);
|
16
|
-
static void EV_Signal_free(void *ptr);
|
17
|
-
static size_t EV_Signal_size(const void *ptr);
|
18
|
-
|
19
|
-
/* Methods */
|
20
|
-
static VALUE EV_Signal_initialize(VALUE self, VALUE sig);
|
21
|
-
|
22
|
-
static VALUE EV_Signal_start(VALUE self);
|
23
|
-
static VALUE EV_Signal_stop(VALUE self);
|
24
|
-
|
25
|
-
void EV_Signal_callback(ev_loop *ev_loop, struct ev_signal *signal, int revents);
|
26
|
-
|
27
|
-
/* Signal encapsulates a signal watcher */
|
28
|
-
void Init_EV_Signal() {
|
29
|
-
mEV = rb_define_module("EV");
|
30
|
-
cEV_Signal = rb_define_class_under(mEV, "Signal", rb_cData);
|
31
|
-
rb_define_alloc_func(cEV_Signal, EV_Signal_allocate);
|
32
|
-
|
33
|
-
rb_define_method(cEV_Signal, "initialize", EV_Signal_initialize, 1);
|
34
|
-
rb_define_method(cEV_Signal, "start", EV_Signal_start, 0);
|
35
|
-
rb_define_method(cEV_Signal, "stop", EV_Signal_stop, 0);
|
36
|
-
}
|
37
|
-
|
38
|
-
static const rb_data_type_t EV_Signal_type = {
|
39
|
-
"EV_Signal",
|
40
|
-
{EV_Signal_mark, EV_Signal_free, EV_Signal_size,},
|
41
|
-
0, 0,
|
42
|
-
RUBY_TYPED_FREE_IMMEDIATELY,
|
43
|
-
};
|
44
|
-
|
45
|
-
static VALUE EV_Signal_allocate(VALUE klass) {
|
46
|
-
struct EV_Signal *signal = (struct EV_Signal *)xmalloc(sizeof(struct EV_Signal));
|
47
|
-
return TypedData_Wrap_Struct(klass, &EV_Signal_type, signal);
|
48
|
-
}
|
49
|
-
|
50
|
-
static void EV_Signal_mark(void *ptr) {
|
51
|
-
struct EV_Signal *signal = ptr;
|
52
|
-
if (signal->callback != Qnil) {
|
53
|
-
rb_gc_mark(signal->callback);
|
54
|
-
}
|
55
|
-
}
|
56
|
-
|
57
|
-
static void EV_Signal_free(void *ptr) {
|
58
|
-
struct EV_Signal *signal = ptr;
|
59
|
-
ev_signal_stop(EV_DEFAULT, &signal->ev_signal);
|
60
|
-
xfree(signal);
|
61
|
-
}
|
62
|
-
|
63
|
-
static size_t EV_Signal_size(const void *ptr) {
|
64
|
-
return sizeof(struct EV_Signal);
|
65
|
-
}
|
66
|
-
|
67
|
-
#define GetEV_Signal(obj, signal) \
|
68
|
-
TypedData_Get_Struct((obj), struct EV_Signal, &EV_Signal_type, (signal))
|
69
|
-
|
70
|
-
static VALUE EV_Signal_initialize(VALUE self, VALUE sig) {
|
71
|
-
struct EV_Signal *signal;
|
72
|
-
VALUE signum = sig;
|
73
|
-
|
74
|
-
GetEV_Signal(self, signal);
|
75
|
-
signal->signum = NUM2INT(signum);
|
76
|
-
|
77
|
-
if (rb_block_given_p()) {
|
78
|
-
signal->callback = rb_block_proc();
|
79
|
-
}
|
80
|
-
|
81
|
-
ev_signal_init(&signal->ev_signal, EV_Signal_callback, signal->signum);
|
82
|
-
|
83
|
-
signal->active = 1;
|
84
|
-
ev_signal_start(EV_DEFAULT, &signal->ev_signal);
|
85
|
-
|
86
|
-
return Qnil;
|
87
|
-
}
|
88
|
-
|
89
|
-
void EV_Signal_callback(ev_loop *ev_loop, struct ev_signal *ev_signal, int revents) {
|
90
|
-
struct EV_Signal *signal = (struct EV_Signal*)ev_signal;
|
91
|
-
|
92
|
-
if (signal->callback != Qnil) {
|
93
|
-
rb_funcall(signal->callback, ID_call, 1, INT2NUM(signal->signum));
|
94
|
-
}
|
95
|
-
}
|
96
|
-
|
97
|
-
static VALUE EV_Signal_start(VALUE self) {
|
98
|
-
struct EV_Signal *signal;
|
99
|
-
GetEV_Signal(self, signal);
|
100
|
-
|
101
|
-
if (!signal->active) {
|
102
|
-
ev_signal_start(EV_DEFAULT, &signal->ev_signal);
|
103
|
-
signal->active = 1;
|
104
|
-
}
|
105
|
-
|
106
|
-
return self;
|
107
|
-
}
|
108
|
-
|
109
|
-
static VALUE EV_Signal_stop(VALUE self) {
|
110
|
-
struct EV_Signal *signal;
|
111
|
-
GetEV_Signal(self, signal);
|
112
|
-
|
113
|
-
if (signal->active) {
|
114
|
-
ev_signal_stop(EV_DEFAULT, &signal->ev_signal);
|
115
|
-
signal->active = 0;
|
116
|
-
}
|
117
|
-
|
118
|
-
return self;
|
119
|
-
}
|
data/ext/ev/timer.c
DELETED
@@ -1,197 +0,0 @@
|
|
1
|
-
#include "ev.h"
|
2
|
-
|
3
|
-
struct EV_Timer {
|
4
|
-
struct ev_timer ev_timer;
|
5
|
-
int active;
|
6
|
-
double after;
|
7
|
-
double repeat;
|
8
|
-
VALUE self;
|
9
|
-
VALUE callback;
|
10
|
-
VALUE fiber;
|
11
|
-
};
|
12
|
-
|
13
|
-
static VALUE mEV = Qnil;
|
14
|
-
static VALUE cEV_Timer = Qnil;
|
15
|
-
|
16
|
-
/* Allocator/deallocator */
|
17
|
-
static VALUE EV_Timer_allocate(VALUE klass);
|
18
|
-
static void EV_Timer_mark(void *ptr);
|
19
|
-
static void EV_Timer_free(void *ptr);
|
20
|
-
static size_t EV_Timer_size(const void *ptr);
|
21
|
-
|
22
|
-
/* Methods */
|
23
|
-
static VALUE EV_Timer_initialize(VALUE self, VALUE after, VALUE repeat);
|
24
|
-
|
25
|
-
static VALUE EV_Timer_start(VALUE self);
|
26
|
-
static VALUE EV_Timer_stop(VALUE self);
|
27
|
-
static VALUE EV_Timer_reset(VALUE self);
|
28
|
-
static VALUE EV_Timer_await(VALUE self);
|
29
|
-
|
30
|
-
void EV_Timer_callback(ev_loop *ev_loop, struct ev_timer *timer, int revents);
|
31
|
-
|
32
|
-
/* Timer encapsulates an timer watcher */
|
33
|
-
void Init_EV_Timer() {
|
34
|
-
mEV = rb_define_module("EV");
|
35
|
-
cEV_Timer = rb_define_class_under(mEV, "Timer", rb_cData);
|
36
|
-
rb_define_alloc_func(cEV_Timer, EV_Timer_allocate);
|
37
|
-
|
38
|
-
rb_define_method(cEV_Timer, "initialize", EV_Timer_initialize, 2);
|
39
|
-
rb_define_method(cEV_Timer, "start", EV_Timer_start, 0);
|
40
|
-
rb_define_method(cEV_Timer, "stop", EV_Timer_stop, 0);
|
41
|
-
rb_define_method(cEV_Timer, "reset", EV_Timer_reset, 0);
|
42
|
-
rb_define_method(cEV_Timer, "await", EV_Timer_await, 0);
|
43
|
-
}
|
44
|
-
|
45
|
-
static const rb_data_type_t EV_Timer_type = {
|
46
|
-
"EV_Timer",
|
47
|
-
{EV_Timer_mark, EV_Timer_free, EV_Timer_size,},
|
48
|
-
0, 0,
|
49
|
-
RUBY_TYPED_FREE_IMMEDIATELY,
|
50
|
-
};
|
51
|
-
|
52
|
-
static VALUE EV_Timer_allocate(VALUE klass) {
|
53
|
-
struct EV_Timer *timer = (struct EV_Timer *)xmalloc(sizeof(struct EV_Timer));
|
54
|
-
return TypedData_Wrap_Struct(klass, &EV_Timer_type, timer);
|
55
|
-
}
|
56
|
-
|
57
|
-
static void EV_Timer_mark(void *ptr) {
|
58
|
-
struct EV_Timer *timer = ptr;
|
59
|
-
if (timer->callback != Qnil) {
|
60
|
-
rb_gc_mark(timer->callback);
|
61
|
-
}
|
62
|
-
if (timer->fiber != Qnil) {
|
63
|
-
rb_gc_mark(timer->fiber);
|
64
|
-
}
|
65
|
-
}
|
66
|
-
|
67
|
-
static void EV_Timer_free(void *ptr) {
|
68
|
-
struct EV_Timer *timer = ptr;
|
69
|
-
if (timer->active) {
|
70
|
-
ev_timer_stop(EV_DEFAULT, &timer->ev_timer);
|
71
|
-
}
|
72
|
-
xfree(timer);
|
73
|
-
}
|
74
|
-
|
75
|
-
static size_t EV_Timer_size(const void *ptr) {
|
76
|
-
return sizeof(struct EV_Timer);
|
77
|
-
}
|
78
|
-
|
79
|
-
#define GetEV_Timer(obj, timer) \
|
80
|
-
TypedData_Get_Struct((obj), struct EV_Timer, &EV_Timer_type, (timer))
|
81
|
-
|
82
|
-
static VALUE EV_Timer_initialize(VALUE self, VALUE after, VALUE repeat) {
|
83
|
-
struct EV_Timer *timer;
|
84
|
-
|
85
|
-
GetEV_Timer(self, timer);
|
86
|
-
|
87
|
-
timer->self = self;
|
88
|
-
timer->callback = Qnil;
|
89
|
-
timer->fiber = Qnil;
|
90
|
-
timer->after = NUM2DBL(after);
|
91
|
-
timer->repeat = NUM2DBL(repeat);
|
92
|
-
timer->active = 0;
|
93
|
-
|
94
|
-
ev_timer_init(&timer->ev_timer, EV_Timer_callback, timer->after, timer->repeat);
|
95
|
-
|
96
|
-
return Qnil;
|
97
|
-
}
|
98
|
-
|
99
|
-
void EV_Timer_callback(ev_loop *ev_loop, struct ev_timer *ev_timer, int revents) {
|
100
|
-
VALUE fiber;
|
101
|
-
VALUE resume_value;
|
102
|
-
struct EV_Timer *timer = (struct EV_Timer*)ev_timer;
|
103
|
-
|
104
|
-
if (!timer->repeat) {
|
105
|
-
timer->active = 0;
|
106
|
-
EV_del_watcher_ref(timer->self);
|
107
|
-
}
|
108
|
-
|
109
|
-
if (timer->fiber != Qnil) {
|
110
|
-
ev_timer_stop(EV_DEFAULT, ev_timer);
|
111
|
-
EV_del_watcher_ref(timer->self);
|
112
|
-
timer->active = 0;
|
113
|
-
fiber = timer->fiber;
|
114
|
-
timer->fiber = Qnil;
|
115
|
-
resume_value = DBL2NUM(timer->after);
|
116
|
-
SCHEDULE_FIBER(fiber, 1, resume_value);
|
117
|
-
}
|
118
|
-
else if (timer->callback != Qnil) {
|
119
|
-
rb_funcall(timer->callback, ID_call, 1, Qtrue);
|
120
|
-
}
|
121
|
-
}
|
122
|
-
|
123
|
-
static VALUE EV_Timer_start(VALUE self) {
|
124
|
-
struct EV_Timer *timer;
|
125
|
-
GetEV_Timer(self, timer);
|
126
|
-
|
127
|
-
if (rb_block_given_p()) {
|
128
|
-
timer->callback = rb_block_proc();
|
129
|
-
}
|
130
|
-
|
131
|
-
if (!timer->active) {
|
132
|
-
ev_timer_start(EV_DEFAULT, &timer->ev_timer);
|
133
|
-
timer->active = 1;
|
134
|
-
EV_add_watcher_ref(self);
|
135
|
-
}
|
136
|
-
|
137
|
-
return self;
|
138
|
-
}
|
139
|
-
|
140
|
-
static VALUE EV_Timer_stop(VALUE self) {
|
141
|
-
struct EV_Timer *timer;
|
142
|
-
GetEV_Timer(self, timer);
|
143
|
-
|
144
|
-
if (timer->active) {
|
145
|
-
ev_timer_stop(EV_DEFAULT, &timer->ev_timer);
|
146
|
-
timer->active = 0;
|
147
|
-
EV_del_watcher_ref(self);
|
148
|
-
}
|
149
|
-
|
150
|
-
return self;
|
151
|
-
}
|
152
|
-
|
153
|
-
static VALUE EV_Timer_reset(VALUE self) {
|
154
|
-
struct EV_Timer *timer;
|
155
|
-
int prev_active;
|
156
|
-
GetEV_Timer(self, timer);
|
157
|
-
|
158
|
-
prev_active = timer->active;
|
159
|
-
|
160
|
-
if (prev_active) {
|
161
|
-
ev_timer_stop(EV_DEFAULT, &timer->ev_timer);
|
162
|
-
}
|
163
|
-
ev_timer_set(&timer->ev_timer, timer->after, timer->repeat);
|
164
|
-
ev_timer_start(EV_DEFAULT, &timer->ev_timer);
|
165
|
-
if (!prev_active) {
|
166
|
-
timer->active = 1;
|
167
|
-
EV_add_watcher_ref(self);
|
168
|
-
}
|
169
|
-
|
170
|
-
return self;
|
171
|
-
}
|
172
|
-
|
173
|
-
static VALUE EV_Timer_await(VALUE self) {
|
174
|
-
struct EV_Timer *timer;
|
175
|
-
VALUE ret;
|
176
|
-
|
177
|
-
GetEV_Timer(self, timer);
|
178
|
-
|
179
|
-
timer->fiber = rb_fiber_current();
|
180
|
-
timer->active = 1;
|
181
|
-
ev_timer_start(EV_DEFAULT, &timer->ev_timer);
|
182
|
-
EV_add_watcher_ref(self);
|
183
|
-
|
184
|
-
ret = YIELD_TO_REACTOR();
|
185
|
-
|
186
|
-
// fiber is resumed, check if resumed value is an exception
|
187
|
-
if (RTEST(rb_obj_is_kind_of(ret, rb_eException))) {
|
188
|
-
if (timer->active) {
|
189
|
-
timer->active = 0;
|
190
|
-
ev_timer_stop(EV_DEFAULT, &timer->ev_timer);
|
191
|
-
}
|
192
|
-
return rb_funcall(ret, ID_raise, 1, ret);
|
193
|
-
}
|
194
|
-
else {
|
195
|
-
return ret;
|
196
|
-
}
|
197
|
-
}
|