polyphony 0.34 → 0.41
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +11 -2
- data/.gitignore +2 -2
- data/.rubocop.yml +30 -0
- data/CHANGELOG.md +34 -0
- data/Gemfile +0 -11
- data/Gemfile.lock +11 -10
- data/README.md +2 -1
- data/Rakefile +6 -2
- data/TODO.md +18 -95
- data/docs/_includes/head.html +40 -0
- data/docs/_includes/nav.html +5 -5
- data/docs/api-reference.md +1 -1
- data/docs/api-reference/fiber.md +18 -0
- data/docs/api-reference/gyro-async.md +57 -0
- data/docs/api-reference/gyro-child.md +29 -0
- data/docs/api-reference/gyro-queue.md +44 -0
- data/docs/api-reference/gyro-timer.md +51 -0
- data/docs/api-reference/gyro.md +25 -0
- data/docs/index.md +10 -7
- data/docs/main-concepts/design-principles.md +67 -9
- data/docs/main-concepts/extending.md +1 -1
- data/docs/main-concepts/fiber-scheduling.md +55 -72
- data/examples/core/xx-agent.rb +102 -0
- data/examples/core/xx-fork-cleanup.rb +22 -0
- data/examples/core/xx-sleeping.rb +14 -6
- data/examples/core/xx-timer-gc.rb +17 -0
- data/examples/io/tunnel.rb +48 -0
- data/examples/io/xx-irb.rb +1 -1
- data/examples/performance/thread-vs-fiber/polyphony_mt_server.rb +7 -6
- data/examples/performance/thread-vs-fiber/polyphony_server.rb +14 -25
- data/ext/{gyro → polyphony}/extconf.rb +2 -2
- data/ext/polyphony/fiber.c +112 -0
- data/ext/{gyro → polyphony}/libev.c +0 -0
- data/ext/{gyro → polyphony}/libev.h +0 -0
- data/ext/polyphony/libev_agent.c +503 -0
- data/ext/polyphony/libev_queue.c +214 -0
- data/ext/polyphony/polyphony.c +89 -0
- data/ext/{gyro/gyro.h → polyphony/polyphony.h} +49 -59
- data/ext/polyphony/polyphony_ext.c +23 -0
- data/ext/{gyro → polyphony}/socket.c +21 -19
- data/ext/{gyro → polyphony}/thread.c +55 -119
- data/ext/{gyro → polyphony}/tracing.c +1 -1
- data/lib/polyphony.rb +37 -44
- data/lib/polyphony/adapters/fs.rb +1 -4
- data/lib/polyphony/adapters/irb.rb +2 -2
- data/lib/polyphony/adapters/postgres.rb +6 -5
- data/lib/polyphony/adapters/process.rb +27 -23
- data/lib/polyphony/adapters/trace.rb +110 -105
- data/lib/polyphony/core/channel.rb +35 -35
- data/lib/polyphony/core/exceptions.rb +29 -29
- data/lib/polyphony/core/global_api.rb +94 -91
- data/lib/polyphony/core/resource_pool.rb +83 -83
- data/lib/polyphony/core/sync.rb +16 -16
- data/lib/polyphony/core/thread_pool.rb +49 -37
- data/lib/polyphony/core/throttler.rb +30 -23
- data/lib/polyphony/event.rb +27 -0
- data/lib/polyphony/extensions/core.rb +23 -14
- data/lib/polyphony/extensions/fiber.rb +269 -267
- data/lib/polyphony/extensions/io.rb +56 -26
- data/lib/polyphony/extensions/openssl.rb +5 -9
- data/lib/polyphony/extensions/socket.rb +29 -10
- data/lib/polyphony/extensions/thread.rb +19 -12
- data/lib/polyphony/net.rb +64 -60
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +3 -6
- data/test/helper.rb +14 -1
- data/test/stress.rb +17 -12
- data/test/test_agent.rb +77 -0
- data/test/{test_async.rb → test_event.rb} +17 -9
- data/test/test_ext.rb +25 -4
- data/test/test_fiber.rb +23 -14
- data/test/test_global_api.rb +5 -5
- data/test/test_io.rb +46 -24
- data/test/test_queue.rb +74 -0
- data/test/test_signal.rb +3 -40
- data/test/test_socket.rb +33 -0
- data/test/test_thread.rb +38 -16
- data/test/test_thread_pool.rb +3 -3
- data/test/test_throttler.rb +0 -1
- data/test/test_trace.rb +6 -5
- metadata +34 -39
- data/ext/gyro/async.c +0 -158
- data/ext/gyro/child.c +0 -117
- data/ext/gyro/gyro.c +0 -203
- data/ext/gyro/gyro_ext.c +0 -31
- data/ext/gyro/io.c +0 -447
- data/ext/gyro/queue.c +0 -142
- data/ext/gyro/selector.c +0 -183
- data/ext/gyro/signal.c +0 -108
- data/ext/gyro/timer.c +0 -154
- data/test/test_timer.rb +0 -56
@@ -0,0 +1,214 @@
|
|
1
|
+
#include "polyphony.h"
|
2
|
+
|
3
|
+
struct async_watcher {
|
4
|
+
ev_async async;
|
5
|
+
struct ev_loop *ev_loop;
|
6
|
+
VALUE fiber;
|
7
|
+
};
|
8
|
+
|
9
|
+
struct async_queue {
|
10
|
+
struct async_watcher **queue;
|
11
|
+
unsigned int len;
|
12
|
+
unsigned int count;
|
13
|
+
unsigned int push_idx;
|
14
|
+
unsigned int pop_idx;
|
15
|
+
};
|
16
|
+
|
17
|
+
void async_queue_init(struct async_queue *queue) {
|
18
|
+
queue->len = 4;
|
19
|
+
queue->count = 0;
|
20
|
+
queue->queue = malloc(sizeof(struct async_watcher *) * queue->len);
|
21
|
+
queue->push_idx = 0;
|
22
|
+
queue->pop_idx = 0;
|
23
|
+
}
|
24
|
+
|
25
|
+
void async_queue_free(struct async_queue *queue) {
|
26
|
+
free(queue->queue);
|
27
|
+
}
|
28
|
+
|
29
|
+
void async_queue_push(struct async_queue *queue, struct async_watcher *watcher) {
|
30
|
+
if (queue->push_idx == queue->len) {
|
31
|
+
queue->len = queue->len * 2;
|
32
|
+
queue->queue = realloc(queue->queue, sizeof(struct async_watcher *) * queue->len);
|
33
|
+
}
|
34
|
+
if (queue->count == 0) {
|
35
|
+
queue->push_idx = 0;
|
36
|
+
queue->pop_idx = 0;
|
37
|
+
}
|
38
|
+
queue->count++;
|
39
|
+
queue->queue[queue->push_idx++] = watcher;
|
40
|
+
}
|
41
|
+
|
42
|
+
struct async_watcher *async_queue_pop(struct async_queue *queue) {
|
43
|
+
if (queue->count == 0) return 0;
|
44
|
+
|
45
|
+
queue->count--;
|
46
|
+
|
47
|
+
return queue->queue[queue->pop_idx++];
|
48
|
+
}
|
49
|
+
|
50
|
+
void async_queue_remove_at_idx(struct async_queue *queue, unsigned int remove_idx) {
|
51
|
+
queue->count--;
|
52
|
+
queue->push_idx--;
|
53
|
+
if (remove_idx < queue->push_idx)
|
54
|
+
memmove(
|
55
|
+
queue->queue + remove_idx,
|
56
|
+
queue->queue + remove_idx + 1,
|
57
|
+
(queue->push_idx - remove_idx) * sizeof(struct async_watcher *)
|
58
|
+
);
|
59
|
+
}
|
60
|
+
|
61
|
+
void async_queue_remove_by_fiber(struct async_queue *queue, VALUE fiber) {
|
62
|
+
if (queue->count == 0) return;
|
63
|
+
|
64
|
+
for (unsigned idx = queue->pop_idx; idx < queue->push_idx; idx++) {
|
65
|
+
if (queue->queue[idx]->fiber == fiber) {
|
66
|
+
async_queue_remove_at_idx(queue, idx);
|
67
|
+
return;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
typedef struct queue {
|
73
|
+
VALUE items;
|
74
|
+
struct async_queue shift_queue;
|
75
|
+
} LibevQueue_t;
|
76
|
+
|
77
|
+
|
78
|
+
VALUE cLibevQueue = Qnil;
|
79
|
+
|
80
|
+
static void LibevQueue_mark(void *ptr) {
|
81
|
+
LibevQueue_t *queue = ptr;
|
82
|
+
rb_gc_mark(queue->items);
|
83
|
+
}
|
84
|
+
|
85
|
+
static void LibevQueue_free(void *ptr) {
|
86
|
+
LibevQueue_t *queue = ptr;
|
87
|
+
async_queue_free(&queue->shift_queue);
|
88
|
+
xfree(ptr);
|
89
|
+
}
|
90
|
+
|
91
|
+
static size_t LibevQueue_size(const void *ptr) {
|
92
|
+
return sizeof(LibevQueue_t);
|
93
|
+
}
|
94
|
+
|
95
|
+
static const rb_data_type_t LibevQueue_type = {
|
96
|
+
"Queue",
|
97
|
+
{LibevQueue_mark, LibevQueue_free, LibevQueue_size,},
|
98
|
+
0, 0, 0
|
99
|
+
};
|
100
|
+
|
101
|
+
static VALUE LibevQueue_allocate(VALUE klass) {
|
102
|
+
LibevQueue_t *queue;
|
103
|
+
|
104
|
+
queue = ALLOC(LibevQueue_t);
|
105
|
+
return TypedData_Wrap_Struct(klass, &LibevQueue_type, queue);
|
106
|
+
}
|
107
|
+
|
108
|
+
#define GetQueue(obj, queue) \
|
109
|
+
TypedData_Get_Struct((obj), LibevQueue_t, &LibevQueue_type, (queue))
|
110
|
+
|
111
|
+
static VALUE LibevQueue_initialize(VALUE self) {
|
112
|
+
LibevQueue_t *queue;
|
113
|
+
GetQueue(self, queue);
|
114
|
+
|
115
|
+
queue->items = rb_ary_new();
|
116
|
+
async_queue_init(&queue->shift_queue);
|
117
|
+
|
118
|
+
return self;
|
119
|
+
}
|
120
|
+
|
121
|
+
VALUE LibevQueue_push(VALUE self, VALUE value) {
|
122
|
+
LibevQueue_t *queue;
|
123
|
+
struct async_watcher *watcher;
|
124
|
+
GetQueue(self, queue);
|
125
|
+
watcher = async_queue_pop(&queue->shift_queue);
|
126
|
+
if (watcher) {
|
127
|
+
ev_async_send(watcher->ev_loop, &watcher->async);
|
128
|
+
}
|
129
|
+
rb_ary_push(queue->items, value);
|
130
|
+
return self;
|
131
|
+
}
|
132
|
+
|
133
|
+
struct ev_loop *LibevAgent_ev_loop(VALUE self);
|
134
|
+
|
135
|
+
void async_queue_callback(struct ev_loop *ev_loop, struct ev_async *ev_async, int revents) {
|
136
|
+
struct async_watcher *watcher = (struct async_watcher *)ev_async;
|
137
|
+
Fiber_make_runnable(watcher->fiber, Qnil);
|
138
|
+
}
|
139
|
+
|
140
|
+
VALUE LibevQueue_shift(VALUE self) {
|
141
|
+
LibevQueue_t *queue;
|
142
|
+
GetQueue(self, queue);
|
143
|
+
|
144
|
+
if (RARRAY_LEN(queue->items) == 0) {
|
145
|
+
struct async_watcher watcher;
|
146
|
+
VALUE agent = rb_ivar_get(rb_thread_current(), ID_ivar_agent);
|
147
|
+
VALUE switchpoint_result = Qnil;
|
148
|
+
|
149
|
+
watcher.ev_loop = LibevAgent_ev_loop(agent);
|
150
|
+
watcher.fiber = rb_fiber_current();
|
151
|
+
async_queue_push(&queue->shift_queue, &watcher);
|
152
|
+
ev_async_init(&watcher.async, async_queue_callback);
|
153
|
+
ev_async_start(watcher.ev_loop, &watcher.async);
|
154
|
+
|
155
|
+
switchpoint_result = Polyphony_switchpoint();
|
156
|
+
ev_async_stop(watcher.ev_loop, &watcher.async);
|
157
|
+
|
158
|
+
if (RTEST(rb_obj_is_kind_of(switchpoint_result, rb_eException))) {
|
159
|
+
async_queue_remove_by_fiber(&queue->shift_queue, watcher.fiber);
|
160
|
+
return rb_funcall(rb_mKernel, ID_raise, 1, switchpoint_result);
|
161
|
+
}
|
162
|
+
RB_GC_GUARD(watcher.fiber);
|
163
|
+
RB_GC_GUARD(agent);
|
164
|
+
RB_GC_GUARD(switchpoint_result);
|
165
|
+
}
|
166
|
+
|
167
|
+
return rb_ary_shift(queue->items);
|
168
|
+
}
|
169
|
+
|
170
|
+
VALUE LibevQueue_shift_each(VALUE self) {
|
171
|
+
LibevQueue_t *queue;
|
172
|
+
VALUE old_queue;
|
173
|
+
GetQueue(self, queue);
|
174
|
+
old_queue = queue->items;
|
175
|
+
queue->items = rb_ary_new();
|
176
|
+
|
177
|
+
if (rb_block_given_p()) {
|
178
|
+
long len = RARRAY_LEN(old_queue);
|
179
|
+
long i;
|
180
|
+
for (i = 0; i < len; i++) {
|
181
|
+
rb_yield(RARRAY_AREF(old_queue, i));
|
182
|
+
}
|
183
|
+
RB_GC_GUARD(old_queue);
|
184
|
+
return self;
|
185
|
+
}
|
186
|
+
else {
|
187
|
+
RB_GC_GUARD(old_queue);
|
188
|
+
return old_queue;
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
VALUE LibevQueue_empty_p(VALUE self) {
|
193
|
+
LibevQueue_t *queue;
|
194
|
+
GetQueue(self, queue);
|
195
|
+
|
196
|
+
return (RARRAY_LEN(queue->items) == 0) ? Qtrue : Qfalse;
|
197
|
+
}
|
198
|
+
|
199
|
+
void Init_LibevQueue() {
|
200
|
+
cLibevQueue = rb_define_class_under(mPolyphony, "LibevQueue", rb_cData);
|
201
|
+
rb_define_alloc_func(cLibevQueue, LibevQueue_allocate);
|
202
|
+
|
203
|
+
rb_define_method(cLibevQueue, "initialize", LibevQueue_initialize, 0);
|
204
|
+
rb_define_method(cLibevQueue, "push", LibevQueue_push, 1);
|
205
|
+
rb_define_method(cLibevQueue, "<<", LibevQueue_push, 1);
|
206
|
+
|
207
|
+
rb_define_method(cLibevQueue, "pop", LibevQueue_shift, 0);
|
208
|
+
rb_define_method(cLibevQueue, "shift", LibevQueue_shift, 0);
|
209
|
+
|
210
|
+
rb_define_method(cLibevQueue, "shift_each", LibevQueue_shift_each, 0);
|
211
|
+
rb_define_method(cLibevQueue, "empty?", LibevQueue_empty_p, 0);
|
212
|
+
}
|
213
|
+
|
214
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
#include "polyphony.h"
|
2
|
+
|
3
|
+
VALUE mPolyphony;
|
4
|
+
|
5
|
+
ID ID_await_no_raise;
|
6
|
+
ID ID_call;
|
7
|
+
ID ID_caller;
|
8
|
+
ID ID_clear;
|
9
|
+
ID ID_each;
|
10
|
+
ID ID_empty;
|
11
|
+
ID ID_inspect;
|
12
|
+
ID ID_new;
|
13
|
+
ID ID_pop;
|
14
|
+
ID ID_push;
|
15
|
+
ID ID_raise;
|
16
|
+
ID ID_ivar_running;
|
17
|
+
ID ID_ivar_thread;
|
18
|
+
ID ID_runnable;
|
19
|
+
ID ID_runnable_value;
|
20
|
+
ID ID_size;
|
21
|
+
ID ID_signal;
|
22
|
+
ID ID_switch_fiber;
|
23
|
+
ID ID_transfer;
|
24
|
+
ID ID_R;
|
25
|
+
ID ID_W;
|
26
|
+
ID ID_RW;
|
27
|
+
|
28
|
+
VALUE Polyphony_snooze(VALUE self) {
|
29
|
+
VALUE ret;
|
30
|
+
VALUE fiber = rb_fiber_current();
|
31
|
+
|
32
|
+
Fiber_make_runnable(fiber, Qnil);
|
33
|
+
ret = Thread_switch_fiber(rb_thread_current());
|
34
|
+
TEST_RESUME_EXCEPTION(ret);
|
35
|
+
RB_GC_GUARD(ret);
|
36
|
+
return ret;
|
37
|
+
}
|
38
|
+
|
39
|
+
static VALUE Polyphony_ref(VALUE self) {
|
40
|
+
return Thread_ref(rb_thread_current());
|
41
|
+
}
|
42
|
+
|
43
|
+
static VALUE Polyphony_unref(VALUE self) {
|
44
|
+
return Thread_unref(rb_thread_current());
|
45
|
+
}
|
46
|
+
|
47
|
+
static VALUE Polyphony_suspend(VALUE self) {
|
48
|
+
VALUE ret = Thread_switch_fiber(rb_thread_current());
|
49
|
+
|
50
|
+
TEST_RESUME_EXCEPTION(ret);
|
51
|
+
RB_GC_GUARD(ret);
|
52
|
+
return ret;
|
53
|
+
}
|
54
|
+
|
55
|
+
VALUE Polyphony_trace(VALUE self, VALUE enabled) {
|
56
|
+
__tracing_enabled__ = RTEST(enabled) ? 1 : 0;
|
57
|
+
return Qnil;
|
58
|
+
}
|
59
|
+
|
60
|
+
void Init_Polyphony() {
|
61
|
+
mPolyphony = rb_define_module("Polyphony");
|
62
|
+
|
63
|
+
rb_define_singleton_method(mPolyphony, "ref", Polyphony_ref, 0);
|
64
|
+
rb_define_singleton_method(mPolyphony, "trace", Polyphony_trace, 1);
|
65
|
+
rb_define_singleton_method(mPolyphony, "unref", Polyphony_unref, 0);
|
66
|
+
|
67
|
+
rb_define_global_function("snooze", Polyphony_snooze, 0);
|
68
|
+
rb_define_global_function("suspend", Polyphony_suspend, 0);
|
69
|
+
|
70
|
+
ID_await_no_raise = rb_intern("await_no_raise");
|
71
|
+
ID_call = rb_intern("call");
|
72
|
+
ID_caller = rb_intern("caller");
|
73
|
+
ID_clear = rb_intern("clear");
|
74
|
+
ID_each = rb_intern("each");
|
75
|
+
ID_empty = rb_intern("empty?");
|
76
|
+
ID_inspect = rb_intern("inspect");
|
77
|
+
ID_ivar_running = rb_intern("@running");
|
78
|
+
ID_ivar_thread = rb_intern("@thread");
|
79
|
+
ID_new = rb_intern("new");
|
80
|
+
ID_pop = rb_intern("pop");
|
81
|
+
ID_push = rb_intern("push");
|
82
|
+
ID_raise = rb_intern("raise");
|
83
|
+
ID_runnable = rb_intern("runnable");
|
84
|
+
ID_runnable_value = rb_intern("runnable_value");
|
85
|
+
ID_signal = rb_intern("signal");
|
86
|
+
ID_size = rb_intern("size");
|
87
|
+
ID_switch_fiber = rb_intern("switch_fiber");
|
88
|
+
ID_transfer = rb_intern("transfer");
|
89
|
+
}
|
@@ -5,87 +5,41 @@
|
|
5
5
|
#include "ruby/io.h"
|
6
6
|
#include "libev.h"
|
7
7
|
|
8
|
-
|
9
|
-
FIBER_STATE_NOT_SCHEDULED = 0,
|
10
|
-
FIBER_STATE_WAITING = 1,
|
11
|
-
FIBER_STATE_SCHEDULED = 2
|
12
|
-
};
|
13
|
-
|
14
|
-
// void Gyro_add_watcher_ref(VALUE obj);
|
15
|
-
// void Gyro_del_watcher_ref(VALUE obj);
|
16
|
-
VALUE Gyro_snooze(VALUE self);
|
17
|
-
|
18
|
-
void Gyro_schedule_fiber(VALUE fiber, VALUE value);
|
19
|
-
|
20
|
-
int Gyro_ref_count();
|
21
|
-
void Gyro_ref_count_incr();
|
22
|
-
void Gyro_ref_count_decr();
|
23
|
-
|
24
|
-
VALUE Gyro_Async_await(VALUE async);
|
25
|
-
VALUE Gyro_Async_await_no_raise(VALUE async);
|
26
|
-
|
27
|
-
VALUE IO_read_watcher(VALUE io);
|
28
|
-
VALUE IO_write_watcher(VALUE io);
|
29
|
-
VALUE Gyro_IO_await(VALUE self);
|
30
|
-
|
31
|
-
VALUE Gyro_Selector_run(VALUE self, VALUE current_fiber);
|
32
|
-
void Gyro_Selector_run_no_wait(VALUE self, VALUE current_fiber, long runnable_count);
|
33
|
-
|
34
|
-
VALUE Gyro_Timer_await(VALUE self);
|
35
|
-
|
36
|
-
int io_setstrbuf(VALUE *str, long len);
|
37
|
-
void io_set_read_length(VALUE str, long n, int shrinkable);
|
38
|
-
VALUE io_enc_str(VALUE str, rb_io_t *fptr);
|
39
|
-
|
40
|
-
struct ev_loop *Gyro_Selector_ev_loop(VALUE selector);
|
41
|
-
ev_tstamp Gyro_Selector_now(VALUE selector);
|
42
|
-
struct ev_loop *Gyro_Selector_current_thread_ev_loop();
|
43
|
-
long Gyro_Selector_pending_count(VALUE self);
|
44
|
-
VALUE Gyro_Selector_post_fork(VALUE self);
|
45
|
-
|
46
|
-
VALUE Thread_current_event_selector();
|
47
|
-
VALUE Thread_ref(VALUE thread);
|
48
|
-
VALUE Thread_unref(VALUE thread);
|
49
|
-
VALUE Thread_switch_fiber(VALUE thread);
|
50
|
-
VALUE Fiber_await();
|
51
|
-
VALUE Thread_schedule_fiber(VALUE thread, VALUE fiber, VALUE value);
|
52
|
-
VALUE Thread_post_fork(VALUE thread);
|
53
|
-
VALUE Gyro_Selector_break_out_of_ev_loop(VALUE self);
|
54
|
-
|
55
|
-
VALUE Gyro_Queue_push(VALUE self, VALUE value);
|
56
|
-
|
8
|
+
// debugging
|
57
9
|
#define OBJ_ID(obj) (NUM2LONG(rb_funcall(obj, rb_intern("object_id"), 0)))
|
58
10
|
#define INSPECT(...) (rb_funcall(rb_cObject, rb_intern("p"), __VA_ARGS__))
|
59
11
|
#define FIBER_TRACE(...) if (__tracing_enabled__) { \
|
60
12
|
rb_funcall(rb_cObject, ID_fiber_trace, __VA_ARGS__); \
|
61
13
|
}
|
62
14
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
15
|
+
#define TEST_EXCEPTION(ret) (RTEST(rb_obj_is_kind_of(ret, rb_eException)))
|
16
|
+
|
17
|
+
#define TEST_RESUME_EXCEPTION(ret) if (RTEST(rb_obj_is_kind_of(ret, rb_eException))) { \
|
18
|
+
return rb_funcall(rb_mKernel, ID_raise, 1, ret); \
|
19
|
+
}
|
20
|
+
|
21
|
+
extern VALUE mPolyphony;
|
22
|
+
extern VALUE cLibevQueue;
|
23
|
+
extern VALUE cEvent;
|
69
24
|
|
25
|
+
extern ID ID_await_no_raise;
|
70
26
|
extern ID ID_call;
|
71
27
|
extern ID ID_caller;
|
72
28
|
extern ID ID_clear;
|
73
29
|
extern ID ID_each;
|
74
30
|
extern ID ID_fiber_trace;
|
75
31
|
extern ID ID_inspect;
|
32
|
+
extern ID ID_ivar_agent;
|
76
33
|
extern ID ID_ivar_running;
|
77
34
|
extern ID ID_ivar_thread;
|
78
35
|
extern ID ID_new;
|
79
36
|
extern ID ID_raise;
|
80
37
|
extern ID ID_runnable;
|
81
38
|
extern ID ID_runnable_value;
|
82
|
-
extern ID
|
39
|
+
extern ID ID_signal;
|
83
40
|
extern ID ID_size;
|
84
41
|
extern ID ID_switch_fiber;
|
85
42
|
extern ID ID_transfer;
|
86
|
-
extern ID ID_R;
|
87
|
-
extern ID ID_W;
|
88
|
-
extern ID ID_RW;
|
89
43
|
|
90
44
|
extern VALUE SYM_fiber_create;
|
91
45
|
extern VALUE SYM_fiber_ev_loop_enter;
|
@@ -97,4 +51,40 @@ extern VALUE SYM_fiber_terminate;
|
|
97
51
|
|
98
52
|
extern int __tracing_enabled__;
|
99
53
|
|
54
|
+
enum {
|
55
|
+
FIBER_STATE_NOT_SCHEDULED = 0,
|
56
|
+
FIBER_STATE_WAITING = 1,
|
57
|
+
FIBER_STATE_SCHEDULED = 2
|
58
|
+
};
|
59
|
+
|
60
|
+
// watcher flags
|
61
|
+
enum {
|
62
|
+
// a watcher's active field will be set to this after fork
|
63
|
+
GYRO_WATCHER_POST_FORK = 0xFF
|
64
|
+
};
|
65
|
+
|
66
|
+
VALUE Fiber_auto_watcher(VALUE self);
|
67
|
+
void Fiber_make_runnable(VALUE fiber, VALUE value);
|
68
|
+
|
69
|
+
VALUE Polyphony_switchpoint();
|
70
|
+
|
71
|
+
VALUE LibevAgent_poll(VALUE self, VALUE nowait, VALUE current_fiber, VALUE queue);
|
72
|
+
VALUE LibevAgent_break(VALUE self);
|
73
|
+
VALUE LibevAgent_pending_count(VALUE self);
|
74
|
+
VALUE LibevAgent_wait_io(VALUE self, VALUE io, VALUE write);
|
75
|
+
|
76
|
+
VALUE Polyphony_snooze(VALUE self);
|
77
|
+
|
78
|
+
VALUE Polyphony_Queue_push(VALUE self, VALUE value);
|
79
|
+
|
80
|
+
VALUE Thread_post_fork(VALUE thread);
|
81
|
+
VALUE Thread_ref(VALUE thread);
|
82
|
+
VALUE Thread_schedule_fiber(VALUE thread, VALUE fiber, VALUE value);
|
83
|
+
VALUE Thread_switch_fiber(VALUE thread);
|
84
|
+
VALUE Thread_unref(VALUE thread);
|
85
|
+
|
86
|
+
int io_setstrbuf(VALUE *str, long len);
|
87
|
+
void io_set_read_length(VALUE str, long n, int shrinkable);
|
88
|
+
VALUE io_enc_str(VALUE str, rb_io_t *fptr);
|
89
|
+
|
100
90
|
#endif /* RUBY_EV_H */
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#include "polyphony.h"
|
2
|
+
|
3
|
+
void Init_Fiber();
|
4
|
+
void Init_Polyphony();
|
5
|
+
void Init_LibevAgent();
|
6
|
+
void Init_LibevQueue();
|
7
|
+
void Init_Socket();
|
8
|
+
void Init_Thread();
|
9
|
+
void Init_Tracing();
|
10
|
+
|
11
|
+
void Init_polyphony_ext() {
|
12
|
+
ev_set_allocator(xrealloc);
|
13
|
+
|
14
|
+
Init_Polyphony();
|
15
|
+
Init_LibevAgent();
|
16
|
+
Init_LibevQueue();
|
17
|
+
|
18
|
+
Init_Fiber();
|
19
|
+
Init_Socket();
|
20
|
+
Init_Thread();
|
21
|
+
|
22
|
+
Init_Tracing();
|
23
|
+
}
|