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.
- 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
|
-
}
|