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.h → gyro/gyro.h}
RENAMED
@@ -5,29 +5,34 @@
|
|
5
5
|
#include "ruby/io.h"
|
6
6
|
#include "libev.h"
|
7
7
|
|
8
|
-
void
|
9
|
-
void
|
10
|
-
|
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
|
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(
|
21
|
+
#define YIELD_TO_REACTOR() rb_funcall(Gyro_reactor_fiber, ID_transfer, 0)
|
22
22
|
|
23
|
-
|
24
|
-
|
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;
|
data/ext/gyro/gyro_ext.c
ADDED
@@ -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
|
+
}
|
data/ext/{ev → gyro}/io.c
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
#include "
|
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
|
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
|
18
|
-
static VALUE cEV_IO = Qnil;
|
17
|
+
static VALUE cGyro_IO = Qnil;
|
19
18
|
|
20
|
-
static VALUE
|
21
|
-
static void
|
22
|
-
static void
|
23
|
-
static size_t
|
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
|
24
|
+
static VALUE Gyro_IO_initialize(VALUE self, VALUE io, VALUE event_mask);
|
26
25
|
|
27
|
-
static VALUE
|
28
|
-
static VALUE
|
26
|
+
static VALUE Gyro_IO_start(VALUE self);
|
27
|
+
static VALUE Gyro_IO_stop(VALUE self);
|
29
28
|
|
30
|
-
void
|
29
|
+
void Gyro_IO_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
|
31
30
|
|
32
|
-
static int
|
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
|
41
|
-
|
42
|
-
|
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(
|
46
|
-
rb_define_method(
|
47
|
-
rb_define_method(
|
48
|
-
rb_define_method(
|
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
|
62
|
-
"
|
63
|
-
{
|
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
|
69
|
-
struct
|
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, &
|
69
|
+
return TypedData_Wrap_Struct(klass, &Gyro_IO_type, io);
|
72
70
|
}
|
73
71
|
|
74
|
-
static void
|
75
|
-
struct
|
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
|
85
|
-
struct
|
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
|
91
|
-
return sizeof(struct
|
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
|
95
|
+
#define GetGyro_IO(obj, io) TypedData_Get_Struct((obj), struct Gyro_IO, &Gyro_IO_type, (io))
|
98
96
|
|
99
|
-
static VALUE
|
100
|
-
struct
|
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
|
-
|
101
|
+
GetGyro_IO(self, io);
|
104
102
|
|
105
|
-
io->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,
|
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
|
114
|
+
void Gyro_IO_callback(struct ev_loop *ev_loop, struct ev_io *ev_io, int revents) {
|
117
115
|
VALUE fiber;
|
118
|
-
struct
|
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
|
136
|
-
struct
|
137
|
-
|
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
|
152
|
-
struct
|
153
|
-
|
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
|
164
|
-
struct
|
161
|
+
VALUE Gyro_IO_await(VALUE self) {
|
162
|
+
struct Gyro_IO *io;
|
165
163
|
VALUE ret;
|
166
164
|
|
167
|
-
|
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
|
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]) :
|
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
|
-
|
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
|
-
|
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
|
-
|
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(
|
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(
|
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;
|
data/ext/{ev → gyro}/libev.h
RENAMED
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
|
+
}
|