polyphony 0.39 → 0.40
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/polyphony.svg)](http://rubygems.org/gems/polyphony)
|
4
5
|
[![Modulation Test](https://github.com/digital-fabric/polyphony/workflows/Tests/badge.svg)](https://github.com/digital-fabric/polyphony/actions?query=workflow%3ATests)
|
5
6
|
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](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);
|