polyphony 0.39 → 0.40
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/CHANGELOG.md +2 -2
- data/Gemfile.lock +3 -3
- data/README.md +2 -1
- data/examples/io/tunnel.rb +48 -0
- data/ext/gyro/async.c +15 -45
- data/ext/gyro/child.c +8 -41
- data/ext/gyro/fiber.c +4 -3
- data/ext/gyro/gyro.c +12 -17
- data/ext/gyro/gyro.h +48 -0
- data/ext/gyro/io.c +13 -45
- data/ext/gyro/queue.c +31 -27
- data/ext/gyro/selector.c +0 -23
- data/ext/gyro/signal.c +8 -42
- data/ext/gyro/socket.c +7 -4
- data/ext/gyro/thread.c +27 -18
- data/ext/gyro/timer.c +18 -54
- data/lib/polyphony/version.rb +1 -1
- data/lib/polyphony.rb +1 -3
- data/polyphony.gemspec +1 -1
- data/test/helper.rb +3 -10
- data/test/test_async.rb +2 -0
- data/test/test_global_api.rb +9 -9
- data/test/test_io.rb +0 -7
- data/test/test_thread.rb +1 -1
- data/test/test_thread_pool.rb +2 -2
- data/test/test_throttler.rb +5 -3
- data/test/test_timer.rb +24 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fac2ba159f62bc767c1c022a9ac84e0d682e9dc1cbb10f53e92ba53da376745
|
4
|
+
data.tar.gz: 8d43be97359735d5b7ac6b9867716c06c420385bb41f14916edd0a2d2bbca454
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0350c4dbee7ad72ba68dfff4fc431870481f43a763d9e265e05ade0ce9545456adef2a79c5efd98ce7fc28b2314ab5558a9e69f9e9ef92759e5ae320c78435be
|
7
|
+
data.tar.gz: 7c7774de233962a1b06bac02623a6127f9b716e36852bc6e5849227db80fc0e910549756c83441f6d40dd75a22c26253fcfeef7e50d62482c1cc7603f6c4b2f3
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
polyphony (0.
|
4
|
+
polyphony (0.40)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -78,7 +78,7 @@ GEM
|
|
78
78
|
ast (~> 2.4.0)
|
79
79
|
pathutil (0.16.2)
|
80
80
|
forwardable-extended (~> 2.6)
|
81
|
-
pg (1.1.
|
81
|
+
pg (1.1.4)
|
82
82
|
public_suffix (4.0.3)
|
83
83
|
rainbow (3.0.0)
|
84
84
|
rake (12.3.3)
|
@@ -127,7 +127,7 @@ DEPENDENCIES
|
|
127
127
|
localhost (= 1.1.4)
|
128
128
|
minitest (= 5.13.0)
|
129
129
|
minitest-reporters (= 1.4.2)
|
130
|
-
pg (= 1.1.
|
130
|
+
pg (= 1.1.4)
|
131
131
|
polyphony!
|
132
132
|
rake-compiler (= 1.0.5)
|
133
133
|
redis (= 4.1.0)
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Polyphony - Fine-Grained Concurrency for Ruby
|
2
2
|
|
3
|
+
|
3
4
|
[](http://rubygems.org/gems/polyphony)
|
4
5
|
[](https://github.com/digital-fabric/polyphony/actions?query=workflow%3ATests)
|
5
6
|
[](https://github.com/digital-fabric/polyphony/blob/master/LICENSE)
|
@@ -46,4 +47,4 @@ The complete documentation for Polyphony could be found on the
|
|
46
47
|
|
47
48
|
Issues and pull requests will be gladly accepted. Please use the [Polyphony git
|
48
49
|
repository](https://github.com/digital-fabric/polyphony) as your primary point
|
49
|
-
of departure for contributing.
|
50
|
+
of departure for contributing.
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'polyphony'
|
5
|
+
|
6
|
+
Ports = ARGV[0..1]
|
7
|
+
EndPoints = []
|
8
|
+
|
9
|
+
def log(msg)
|
10
|
+
puts "#{Time.now.strftime('%Y-%m-%d %H:%M:%S.%3N')} #{msg}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def endpoint_loop(idx, peer_idx)
|
14
|
+
port = Ports[idx]
|
15
|
+
server = Polyphony::Net.tcp_listen(
|
16
|
+
'0.0.0.0',
|
17
|
+
port,
|
18
|
+
reuse_addr: true
|
19
|
+
)
|
20
|
+
# server = TCPServer.open('0.0.0.0', port)
|
21
|
+
log "Listening on port #{port}"
|
22
|
+
loop do
|
23
|
+
conn = server.accept
|
24
|
+
conn.binmode
|
25
|
+
EndPoints[idx] = conn
|
26
|
+
log "Client connected on port #{port} (#{conn.remote_address.inspect})"
|
27
|
+
while data = conn.readpartial(8192)
|
28
|
+
peer = EndPoints[peer_idx]
|
29
|
+
if peer
|
30
|
+
peer << data
|
31
|
+
log "#{idx} => #{peer_idx} #{data.inspect}"
|
32
|
+
else
|
33
|
+
log "#{idx}: #{data.inspect}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
EndPoints[idx] = nil
|
37
|
+
log "Connection closed on port #{port}"
|
38
|
+
rescue => e
|
39
|
+
log "Error on port #{port}: #{e.inspect}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
spin { endpoint_loop(0, 1) }
|
44
|
+
spin { endpoint_loop(1, 0) }
|
45
|
+
|
46
|
+
log "Tunneling port #{Ports[0]} to port #{Ports[1]}..."
|
47
|
+
sleep
|
48
|
+
|
data/ext/gyro/async.c
CHANGED
@@ -1,41 +1,23 @@
|
|
1
1
|
#include "gyro.h"
|
2
2
|
|
3
3
|
struct Gyro_Async {
|
4
|
-
|
5
|
-
|
6
|
-
int active;
|
7
|
-
VALUE self;
|
8
|
-
VALUE fiber;
|
9
|
-
VALUE value;
|
10
|
-
VALUE selector;
|
4
|
+
GYRO_WATCHER_DECL(ev_async);
|
5
|
+
VALUE value;
|
11
6
|
};
|
12
7
|
|
13
8
|
VALUE cGyro_Async = Qnil;
|
14
9
|
|
15
10
|
static void Gyro_Async_mark(void *ptr) {
|
16
11
|
struct Gyro_Async *async = ptr;
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
if (async->value != Qnil) {
|
21
|
-
rb_gc_mark(async->value);
|
22
|
-
}
|
23
|
-
if (async->selector != Qnil) {
|
24
|
-
rb_gc_mark(async->selector);
|
25
|
-
}
|
12
|
+
|
13
|
+
GYRO_WATCHER_MARK(async);
|
14
|
+
if (async->value != Qnil) rb_gc_mark(async->value);
|
26
15
|
}
|
27
16
|
|
28
17
|
static void Gyro_Async_free(void *ptr) {
|
29
18
|
struct Gyro_Async *async = ptr;
|
30
|
-
|
31
|
-
|
32
|
-
return;
|
33
|
-
case 1:
|
34
|
-
ev_clear_pending(async->ev_loop, &async->ev_async);
|
35
|
-
ev_async_stop(async->ev_loop, &async->ev_async);
|
36
|
-
default:
|
37
|
-
xfree(async);
|
38
|
-
}
|
19
|
+
|
20
|
+
GYRO_WATCHER_FREE(async);
|
39
21
|
}
|
40
22
|
|
41
23
|
static size_t Gyro_Async_size(const void *ptr) {
|
@@ -50,6 +32,7 @@ static const rb_data_type_t Gyro_Async_type = {
|
|
50
32
|
|
51
33
|
static VALUE Gyro_Async_allocate(VALUE klass) {
|
52
34
|
struct Gyro_Async *async = ALLOC(struct Gyro_Async);
|
35
|
+
|
53
36
|
return TypedData_Wrap_Struct(klass, &Gyro_Async_type, async);
|
54
37
|
}
|
55
38
|
|
@@ -90,13 +73,8 @@ static VALUE Gyro_Async_initialize(VALUE self) {
|
|
90
73
|
struct Gyro_Async *async;
|
91
74
|
GetGyro_Async(self, async);
|
92
75
|
|
93
|
-
async
|
94
|
-
async->fiber = Qnil;
|
76
|
+
GYRO_WATCHER_INITIALIZE(async, self);
|
95
77
|
async->value = Qnil;
|
96
|
-
async->selector = Qnil;
|
97
|
-
async->active = 0;
|
98
|
-
async->ev_loop = 0;
|
99
|
-
|
100
78
|
ev_async_init(&async->ev_async, Gyro_Async_callback);
|
101
79
|
|
102
80
|
return Qnil;
|
@@ -119,10 +97,11 @@ static VALUE Gyro_Async_signal(int argc, VALUE *argv, VALUE self) {
|
|
119
97
|
|
120
98
|
VALUE Gyro_Async_await(VALUE self) {
|
121
99
|
struct Gyro_Async *async;
|
100
|
+
VALUE ret;
|
122
101
|
GetGyro_Async(self, async);
|
123
102
|
|
124
103
|
async_activate(async);
|
125
|
-
|
104
|
+
ret = Gyro_switchpoint();
|
126
105
|
async_deactivate(async);
|
127
106
|
|
128
107
|
TEST_RESUME_EXCEPTION(ret);
|
@@ -130,23 +109,15 @@ VALUE Gyro_Async_await(VALUE self) {
|
|
130
109
|
return ret;
|
131
110
|
}
|
132
111
|
|
133
|
-
VALUE Gyro_Async_deactivate_post_fork(VALUE self) {
|
134
|
-
struct Gyro_Async *async;
|
135
|
-
GetGyro_Async(self, async);
|
136
|
-
|
137
|
-
if (async->active)
|
138
|
-
async->active = GYRO_WATCHER_POST_FORK;
|
139
|
-
return self;
|
140
|
-
}
|
141
|
-
|
142
112
|
VALUE Gyro_Async_await_no_raise(VALUE self) {
|
143
113
|
struct Gyro_Async *async;
|
114
|
+
VALUE ret;
|
144
115
|
GetGyro_Async(self, async);
|
145
116
|
|
146
117
|
async_activate(async);
|
147
|
-
|
118
|
+
ret = Gyro_switchpoint();
|
148
119
|
async_deactivate(async);
|
149
|
-
|
120
|
+
|
150
121
|
RB_GC_GUARD(ret);
|
151
122
|
return ret;
|
152
123
|
}
|
@@ -157,6 +128,5 @@ void Init_Gyro_Async() {
|
|
157
128
|
|
158
129
|
rb_define_method(cGyro_Async, "initialize", Gyro_Async_initialize, 0);
|
159
130
|
rb_define_method(cGyro_Async, "await", Gyro_Async_await, 0);
|
160
|
-
rb_define_method(cGyro_Async, "deactivate_post_fork", Gyro_Async_deactivate_post_fork, 0);
|
161
131
|
rb_define_method(cGyro_Async, "signal", Gyro_Async_signal, -1);
|
162
|
-
}
|
132
|
+
}
|
data/ext/gyro/child.c
CHANGED
@@ -1,38 +1,20 @@
|
|
1
1
|
#include "gyro.h"
|
2
2
|
|
3
3
|
struct Gyro_Child {
|
4
|
-
|
5
|
-
|
6
|
-
int active;
|
7
|
-
int pid;
|
8
|
-
VALUE self;
|
9
|
-
VALUE fiber;
|
10
|
-
VALUE selector;
|
4
|
+
GYRO_WATCHER_DECL(ev_child);
|
5
|
+
int pid;
|
11
6
|
};
|
12
7
|
|
13
8
|
static VALUE cGyro_Child = Qnil;
|
14
9
|
|
15
10
|
static void Gyro_Child_mark(void *ptr) {
|
16
11
|
struct Gyro_Child *child = ptr;
|
17
|
-
|
18
|
-
rb_gc_mark(child->fiber);
|
19
|
-
}
|
20
|
-
if (child->selector != Qnil) {
|
21
|
-
rb_gc_mark(child->selector);
|
22
|
-
}
|
12
|
+
GYRO_WATCHER_MARK(child);
|
23
13
|
}
|
24
14
|
|
25
15
|
static void Gyro_Child_free(void *ptr) {
|
26
16
|
struct Gyro_Child *child = ptr;
|
27
|
-
|
28
|
-
case GYRO_WATCHER_POST_FORK:
|
29
|
-
return;
|
30
|
-
case 1:
|
31
|
-
ev_clear_pending(child->ev_loop, &child->ev_child);
|
32
|
-
ev_child_stop(child->ev_loop, &child->ev_child);
|
33
|
-
default:
|
34
|
-
xfree(child);
|
35
|
-
}
|
17
|
+
GYRO_WATCHER_FREE(child);
|
36
18
|
}
|
37
19
|
|
38
20
|
static size_t Gyro_Child_size(const void *ptr) {
|
@@ -96,14 +78,8 @@ static VALUE Gyro_Child_initialize(VALUE self, VALUE pid) {
|
|
96
78
|
struct Gyro_Child *child;
|
97
79
|
|
98
80
|
GetGyro_Child(self, child);
|
99
|
-
|
100
|
-
child->
|
101
|
-
child->fiber = Qnil;
|
102
|
-
child->selector = Qnil;
|
103
|
-
child->pid = NUM2INT(pid);
|
104
|
-
child->active = 0;
|
105
|
-
child->ev_loop = 0;
|
106
|
-
|
81
|
+
GYRO_WATCHER_INITIALIZE(child, self);
|
82
|
+
child->pid = NUM2INT(pid);
|
107
83
|
ev_child_init(&child->ev_child, Gyro_Child_callback, child->pid, 0);
|
108
84
|
|
109
85
|
return Qnil;
|
@@ -111,10 +87,11 @@ static VALUE Gyro_Child_initialize(VALUE self, VALUE pid) {
|
|
111
87
|
|
112
88
|
static VALUE Gyro_Child_await(VALUE self) {
|
113
89
|
struct Gyro_Child *child;
|
90
|
+
VALUE ret;
|
114
91
|
GetGyro_Child(self, child);
|
115
92
|
|
116
93
|
child_activate(child);
|
117
|
-
|
94
|
+
ret = Gyro_switchpoint();
|
118
95
|
child_deactivate(child);
|
119
96
|
|
120
97
|
TEST_RESUME_EXCEPTION(ret);
|
@@ -122,20 +99,10 @@ static VALUE Gyro_Child_await(VALUE self) {
|
|
122
99
|
return ret;
|
123
100
|
}
|
124
101
|
|
125
|
-
VALUE Gyro_Child_deactivate_post_fork(VALUE self) {
|
126
|
-
struct Gyro_Child *child;
|
127
|
-
GetGyro_Child(self, child);
|
128
|
-
|
129
|
-
if (child->active)
|
130
|
-
child->active = GYRO_WATCHER_POST_FORK;
|
131
|
-
return self;
|
132
|
-
}
|
133
|
-
|
134
102
|
void Init_Gyro_Child() {
|
135
103
|
cGyro_Child = rb_define_class_under(mGyro, "Child", rb_cData);
|
136
104
|
rb_define_alloc_func(cGyro_Child, Gyro_Child_allocate);
|
137
105
|
|
138
106
|
rb_define_method(cGyro_Child, "initialize", Gyro_Child_initialize, 1);
|
139
107
|
rb_define_method(cGyro_Child, "await", Gyro_Child_await, 0);
|
140
|
-
rb_define_method(cGyro_Child, "deactivate_post_fork", Gyro_Child_deactivate_post_fork, 0);
|
141
108
|
}
|
data/ext/gyro/fiber.c
CHANGED
@@ -26,7 +26,7 @@ VALUE SYM_fiber_terminate;
|
|
26
26
|
static VALUE Fiber_safe_transfer(int argc, VALUE *argv, VALUE self) {
|
27
27
|
VALUE arg = (argc == 0) ? Qnil : argv[0];
|
28
28
|
VALUE ret = rb_funcall(self, ID_transfer, 1, arg);
|
29
|
-
|
29
|
+
|
30
30
|
TEST_RESUME_EXCEPTION(ret);
|
31
31
|
RB_GC_GUARD(ret);
|
32
32
|
return ret;
|
@@ -61,7 +61,7 @@ static VALUE Fiber_state(VALUE self) {
|
|
61
61
|
return SYM_dead;
|
62
62
|
if (rb_fiber_current() == self) return SYM_running;
|
63
63
|
if (rb_ivar_get(self, ID_runnable) != Qnil) return SYM_runnable;
|
64
|
-
|
64
|
+
|
65
65
|
return SYM_waiting;
|
66
66
|
}
|
67
67
|
|
@@ -71,8 +71,9 @@ void Fiber_make_runnable(VALUE fiber, VALUE value) {
|
|
71
71
|
Thread_schedule_fiber(thread, fiber, value);
|
72
72
|
}
|
73
73
|
else {
|
74
|
+
VALUE caller;
|
74
75
|
rb_warn("No thread set for fiber (fiber, value, caller):");
|
75
|
-
|
76
|
+
caller = rb_funcall(rb_cObject, rb_intern("caller"), 0);
|
76
77
|
INSPECT(3, fiber, value, caller);
|
77
78
|
}
|
78
79
|
}
|
data/ext/gyro/gyro.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#include "gyro.h"
|
2
2
|
|
3
3
|
VALUE mGyro;
|
4
|
+
int __gyro_current_generation__ = 0;
|
4
5
|
|
5
6
|
ID ID_call;
|
6
7
|
ID ID_caller;
|
@@ -24,21 +25,12 @@ ID ID_R;
|
|
24
25
|
ID ID_W;
|
25
26
|
ID ID_RW;
|
26
27
|
|
27
|
-
static VALUE Gyro_break_set(VALUE self) {
|
28
|
-
// break_flag = 1;
|
29
|
-
ev_break(Gyro_Selector_current_thread_ev_loop(), EVBREAK_ALL);
|
30
|
-
return Qnil;
|
31
|
-
}
|
32
|
-
|
33
|
-
// static VALUE Gyro_break_get(VALUE self) {
|
34
|
-
// return (break_flag == 0) ? Qfalse : Qtrue;
|
35
|
-
// }
|
36
|
-
|
37
28
|
VALUE Gyro_snooze(VALUE self) {
|
29
|
+
VALUE ret;
|
38
30
|
VALUE fiber = rb_fiber_current();
|
39
|
-
Fiber_make_runnable(fiber, Qnil);
|
40
31
|
|
41
|
-
|
32
|
+
Fiber_make_runnable(fiber, Qnil);
|
33
|
+
ret = Thread_switch_fiber(rb_thread_current());
|
42
34
|
TEST_RESUME_EXCEPTION(ret);
|
43
35
|
RB_GC_GUARD(ret);
|
44
36
|
return ret;
|
@@ -54,7 +46,7 @@ static VALUE Gyro_unref(VALUE self) {
|
|
54
46
|
|
55
47
|
static VALUE Gyro_suspend(VALUE self) {
|
56
48
|
VALUE ret = Thread_switch_fiber(rb_thread_current());
|
57
|
-
|
49
|
+
|
58
50
|
TEST_RESUME_EXCEPTION(ret);
|
59
51
|
RB_GC_GUARD(ret);
|
60
52
|
return ret;
|
@@ -65,15 +57,18 @@ VALUE Gyro_trace(VALUE self, VALUE enabled) {
|
|
65
57
|
return Qnil;
|
66
58
|
}
|
67
59
|
|
60
|
+
VALUE Gyro_incr_generation(VALUE self) {
|
61
|
+
__gyro_current_generation__++;
|
62
|
+
return Qnil;
|
63
|
+
}
|
64
|
+
|
68
65
|
void Init_Gyro() {
|
69
66
|
mGyro = rb_define_module("Gyro");
|
70
67
|
|
68
|
+
rb_define_singleton_method(mGyro, "incr_generation", Gyro_incr_generation, 0);
|
71
69
|
rb_define_singleton_method(mGyro, "ref", Gyro_ref, 0);
|
72
|
-
rb_define_singleton_method(mGyro, "unref", Gyro_unref, 0);
|
73
70
|
rb_define_singleton_method(mGyro, "trace", Gyro_trace, 1);
|
74
|
-
|
75
|
-
rb_define_singleton_method(mGyro, "break!", Gyro_break_set, 0);
|
76
|
-
// rb_define_singleton_method(mGyro, "break?", Gyro_break_get, 0);
|
71
|
+
rb_define_singleton_method(mGyro, "unref", Gyro_unref, 0);
|
77
72
|
|
78
73
|
rb_define_global_function("snooze", Gyro_snooze, 0);
|
79
74
|
rb_define_global_function("suspend", Gyro_suspend, 0);
|
data/ext/gyro/gyro.h
CHANGED
@@ -16,6 +16,53 @@
|
|
16
16
|
return rb_funcall(rb_mKernel, ID_raise, 1, ret); \
|
17
17
|
}
|
18
18
|
|
19
|
+
typedef struct Gyro_watcher {
|
20
|
+
int active;
|
21
|
+
int generation;
|
22
|
+
|
23
|
+
struct ev_loop *ev_loop;
|
24
|
+
|
25
|
+
VALUE self;
|
26
|
+
VALUE fiber;
|
27
|
+
VALUE selector;
|
28
|
+
} Gyro_watcher_t;
|
29
|
+
|
30
|
+
|
31
|
+
#define GYRO_WATCHER_DECL(type) \
|
32
|
+
struct type type; \
|
33
|
+
int active; \
|
34
|
+
int generation; \
|
35
|
+
struct ev_loop *ev_loop; \
|
36
|
+
VALUE self; \
|
37
|
+
VALUE fiber; \
|
38
|
+
VALUE selector;
|
39
|
+
|
40
|
+
#define GYRO_WATCHER_INITIALIZE(o, self) \
|
41
|
+
o->active = 0; \
|
42
|
+
o->generation = __gyro_current_generation__; \
|
43
|
+
o->ev_loop = 0; \
|
44
|
+
o->self = self; \
|
45
|
+
o->fiber = Qnil; \
|
46
|
+
o->selector = Qnil;
|
47
|
+
|
48
|
+
#define GYRO_WATCHER_MARK(o) \
|
49
|
+
if (o->fiber != Qnil) rb_gc_mark(o->fiber); \
|
50
|
+
if (o->selector != Qnil) rb_gc_mark(o->selector);
|
51
|
+
|
52
|
+
#define GYRO_WATCHER_STOP_EXPAND(o) ev_ ## o ## _stop
|
53
|
+
#define GYRO_WATCHER_STOP(o) GYRO_WATCHER_STOP_EXPAND(o)
|
54
|
+
|
55
|
+
#define GYRO_WATCHER_FIELD_EXPAND(o) ev_ ## o
|
56
|
+
#define GYRO_WATCHER_FIELD(o) GYRO_WATCHER_FIELD_EXPAND(o)
|
57
|
+
|
58
|
+
#define GYRO_WATCHER_FREE(o) \
|
59
|
+
if (o->generation < __gyro_current_generation__) return; \
|
60
|
+
if (o->active) { \
|
61
|
+
ev_clear_pending(o->ev_loop, &o->GYRO_WATCHER_FIELD(o)); \
|
62
|
+
GYRO_WATCHER_STOP(o)(o->ev_loop, &o->GYRO_WATCHER_FIELD(o)); \
|
63
|
+
} \
|
64
|
+
xfree(o);
|
65
|
+
|
19
66
|
extern VALUE mGyro;
|
20
67
|
extern VALUE cGyro_Async;
|
21
68
|
extern VALUE cGyro_IO;
|
@@ -52,6 +99,7 @@ extern VALUE SYM_fiber_switchpoint;
|
|
52
99
|
extern VALUE SYM_fiber_terminate;
|
53
100
|
|
54
101
|
extern int __tracing_enabled__;
|
102
|
+
extern int __gyro_current_generation__;
|
55
103
|
|
56
104
|
enum {
|
57
105
|
FIBER_STATE_NOT_SCHEDULED = 0,
|
data/ext/gyro/io.c
CHANGED
@@ -7,12 +7,7 @@
|
|
7
7
|
#endif /* GetReadFile */
|
8
8
|
|
9
9
|
struct Gyro_IO {
|
10
|
-
|
11
|
-
struct ev_loop *ev_loop;
|
12
|
-
int active;
|
13
|
-
VALUE self;
|
14
|
-
VALUE fiber;
|
15
|
-
VALUE selector;
|
10
|
+
GYRO_WATCHER_DECL(ev_io);
|
16
11
|
};
|
17
12
|
|
18
13
|
VALUE cGyro_IO = Qnil;
|
@@ -24,25 +19,12 @@ VALUE SYM_w;
|
|
24
19
|
|
25
20
|
static void Gyro_IO_mark(void *ptr) {
|
26
21
|
struct Gyro_IO *io = ptr;
|
27
|
-
|
28
|
-
rb_gc_mark(io->fiber);
|
29
|
-
}
|
30
|
-
if (io->selector != Qnil) {
|
31
|
-
rb_gc_mark(io->selector);
|
32
|
-
}
|
22
|
+
GYRO_WATCHER_MARK(io);
|
33
23
|
}
|
34
24
|
|
35
25
|
static void Gyro_IO_free(void *ptr) {
|
36
26
|
struct Gyro_IO *io = ptr;
|
37
|
-
|
38
|
-
case GYRO_WATCHER_POST_FORK:
|
39
|
-
return;
|
40
|
-
case 1:
|
41
|
-
ev_clear_pending(io->ev_loop, &io->ev_io);
|
42
|
-
ev_io_stop(io->ev_loop, &io->ev_io);
|
43
|
-
default:
|
44
|
-
xfree(io);
|
45
|
-
}
|
27
|
+
GYRO_WATCHER_FREE(io);
|
46
28
|
}
|
47
29
|
|
48
30
|
static size_t Gyro_IO_size(const void *ptr) {
|
@@ -119,16 +101,11 @@ static const char * S_to_io = "to_io";
|
|
119
101
|
static VALUE Gyro_IO_initialize(VALUE self, VALUE io_obj, VALUE event_mask) {
|
120
102
|
struct Gyro_IO *io;
|
121
103
|
rb_io_t *fptr;
|
104
|
+
int fd;
|
105
|
+
int events;
|
122
106
|
|
123
107
|
GetGyro_IO(self, io);
|
124
|
-
|
125
|
-
io->self = self;
|
126
|
-
io->fiber = Qnil;
|
127
|
-
io->selector = Qnil;
|
128
|
-
io->active = 0;
|
129
|
-
io->ev_loop = 0;
|
130
|
-
|
131
|
-
int fd;
|
108
|
+
GYRO_WATCHER_INITIALIZE(io, self);
|
132
109
|
if (NIL_P(io_obj)) {
|
133
110
|
fd = 0;
|
134
111
|
}
|
@@ -136,8 +113,7 @@ static VALUE Gyro_IO_initialize(VALUE self, VALUE io_obj, VALUE event_mask) {
|
|
136
113
|
GetOpenFile(rb_convert_type(io_obj, T_FILE, S_IO, S_to_io), fptr);
|
137
114
|
fd = FPTR_TO_FD(fptr);
|
138
115
|
}
|
139
|
-
|
140
|
-
|
116
|
+
events = Gyro_IO_symbol2event_mask(event_mask);
|
141
117
|
ev_io_init(&io->ev_io, Gyro_IO_callback, fd, events);
|
142
118
|
|
143
119
|
return Qnil;
|
@@ -145,10 +121,11 @@ static VALUE Gyro_IO_initialize(VALUE self, VALUE io_obj, VALUE event_mask) {
|
|
145
121
|
|
146
122
|
VALUE Gyro_IO_await(VALUE self) {
|
147
123
|
struct Gyro_IO *io;
|
124
|
+
VALUE ret;
|
148
125
|
GetGyro_IO(self, io);
|
149
126
|
|
150
127
|
io_activate(io);
|
151
|
-
|
128
|
+
ret = Gyro_switchpoint();
|
152
129
|
io_deactivate(io);
|
153
130
|
|
154
131
|
TEST_RESUME_EXCEPTION(ret);
|
@@ -156,16 +133,6 @@ VALUE Gyro_IO_await(VALUE self) {
|
|
156
133
|
return ret;
|
157
134
|
}
|
158
135
|
|
159
|
-
VALUE Gyro_IO_deactivate_post_fork(VALUE self) {
|
160
|
-
struct Gyro_IO *io;
|
161
|
-
GetGyro_IO(self, io);
|
162
|
-
|
163
|
-
if (io->active)
|
164
|
-
io->active = GYRO_WATCHER_POST_FORK;
|
165
|
-
|
166
|
-
return self;
|
167
|
-
}
|
168
|
-
|
169
136
|
VALUE Gyro_IO_auto_io(int fd, int events) {
|
170
137
|
VALUE watcher = Fiber_auto_io(rb_fiber_current());
|
171
138
|
struct Gyro_IO *io;
|
@@ -265,7 +232,7 @@ static VALUE IO_read(int argc, VALUE *argv, VALUE io) {
|
|
265
232
|
|
266
233
|
if (len == 0)
|
267
234
|
return str;
|
268
|
-
|
235
|
+
|
269
236
|
char *buf = RSTRING_PTR(str);
|
270
237
|
long total = 0;
|
271
238
|
|
@@ -462,14 +429,15 @@ VALUE IO_write_watcher(VALUE self) {
|
|
462
429
|
}
|
463
430
|
|
464
431
|
void Init_Gyro_IO() {
|
432
|
+
VALUE cIO;
|
433
|
+
|
465
434
|
cGyro_IO = rb_define_class_under(mGyro, "IO", rb_cData);
|
466
435
|
rb_define_alloc_func(cGyro_IO, Gyro_IO_allocate);
|
467
436
|
|
468
437
|
rb_define_method(cGyro_IO, "initialize", Gyro_IO_initialize, 2);
|
469
438
|
rb_define_method(cGyro_IO, "await", Gyro_IO_await, 0);
|
470
|
-
rb_define_method(cGyro_IO, "deactivate_post_fork", Gyro_IO_deactivate_post_fork, 0);
|
471
439
|
|
472
|
-
|
440
|
+
cIO = rb_const_get(rb_cObject, rb_intern("IO"));
|
473
441
|
// rb_define_method(cIO, "gets", IO_gets, -1);
|
474
442
|
rb_define_method(cIO, "read", IO_read, -1);
|
475
443
|
rb_define_method(cIO, "readpartial", IO_readpartial, -1);
|