polyphony 0.26 → 0.27
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -3
- data/CHANGELOG.md +8 -0
- data/Gemfile.lock +1 -1
- data/TODO.md +34 -14
- data/examples/core/xx-mt-scheduler.rb +349 -0
- data/examples/core/xx-queue-async.rb +120 -0
- data/examples/core/xx-readpartial.rb +18 -0
- data/examples/core/xx-thread-selector-sleep.rb +51 -0
- data/examples/core/xx-thread-selector-snooze.rb +46 -0
- data/examples/core/xx-thread-sleep.rb +17 -0
- data/examples/core/xx-thread-snooze.rb +34 -0
- data/examples/performance/snooze.rb +5 -5
- data/examples/performance/thread-vs-fiber/polyphony_mt_server.rb +73 -0
- data/examples/performance/thread-vs-fiber/polyphony_server.rb +12 -4
- data/ext/gyro/async.c +58 -61
- data/ext/gyro/child.c +50 -59
- data/ext/gyro/gyro.c +84 -192
- data/ext/gyro/gyro.h +29 -2
- data/ext/gyro/gyro_ext.c +6 -0
- data/ext/gyro/io.c +87 -96
- data/ext/gyro/queue.c +109 -0
- data/ext/gyro/selector.c +117 -0
- data/ext/gyro/signal.c +44 -54
- data/ext/gyro/socket.c +15 -20
- data/ext/gyro/thread.c +203 -0
- data/ext/gyro/timer.c +79 -50
- data/ext/libev/ev.c +3 -0
- data/lib/polyphony.rb +7 -12
- data/lib/polyphony/core/global_api.rb +5 -1
- data/lib/polyphony/core/throttler.rb +6 -11
- data/lib/polyphony/extensions/core.rb +2 -0
- data/lib/polyphony/extensions/fiber.rb +11 -13
- data/lib/polyphony/extensions/thread.rb +52 -0
- data/lib/polyphony/version.rb +1 -1
- data/test/helper.rb +8 -3
- data/test/test_fiber.rb +2 -2
- data/test/test_global_api.rb +4 -5
- data/test/test_gyro.rb +3 -2
- data/test/test_io.rb +1 -0
- data/test/test_supervisor.rb +3 -3
- data/test/test_thread.rb +44 -0
- data/test/test_throttler.rb +41 -0
- data/test/test_timer.rb +13 -7
- metadata +17 -6
- data/examples/core/xx-thread_cancel.rb +0 -28
- data/examples/performance/thread.rb +0 -27
- data/lib/polyphony/core/thread.rb +0 -23
data/ext/gyro/gyro.h
CHANGED
@@ -15,25 +15,48 @@ enum {
|
|
15
15
|
// void Gyro_del_watcher_ref(VALUE obj);
|
16
16
|
VALUE Gyro_snooze(VALUE self);
|
17
17
|
|
18
|
-
VALUE Gyro_run_next_fiber();
|
19
|
-
VALUE Gyro_await();
|
20
18
|
void Gyro_schedule_fiber(VALUE fiber, VALUE value);
|
21
19
|
|
22
20
|
int Gyro_ref_count();
|
23
21
|
void Gyro_ref_count_incr();
|
24
22
|
void Gyro_ref_count_decr();
|
25
23
|
|
24
|
+
VALUE Gyro_Async_await(VALUE async);
|
25
|
+
|
26
26
|
VALUE IO_read_watcher(VALUE io);
|
27
27
|
VALUE IO_write_watcher(VALUE io);
|
28
28
|
VALUE Gyro_IO_await(VALUE self);
|
29
29
|
|
30
|
+
VALUE Gyro_Selector_run(VALUE self);
|
31
|
+
|
32
|
+
VALUE Gyro_Timer_await(VALUE self);
|
33
|
+
|
30
34
|
int io_setstrbuf(VALUE *str, long len);
|
31
35
|
void io_set_read_length(VALUE str, long n, int shrinkable);
|
32
36
|
VALUE io_enc_str(VALUE str, rb_io_t *fptr);
|
33
37
|
|
38
|
+
struct ev_loop *Gyro_Selector_ev_loop(VALUE selector);
|
39
|
+
struct ev_loop *Gyro_Selector_current_thread_ev_loop();
|
40
|
+
long Gyro_Selector_pending_count(VALUE self);
|
41
|
+
|
42
|
+
VALUE Thread_current_event_selector();
|
43
|
+
VALUE Thread_ref(VALUE thread);
|
44
|
+
VALUE Thread_unref(VALUE thread);
|
45
|
+
VALUE Thread_switch_fiber(VALUE thread);
|
46
|
+
VALUE Fiber_await();
|
47
|
+
VALUE Thread_schedule_fiber(VALUE thread, VALUE fiber);
|
48
|
+
VALUE Thread_post_fork(VALUE thread);
|
49
|
+
|
50
|
+
|
34
51
|
#define OBJ_ID(obj) (NUM2LONG(rb_funcall(obj, rb_intern("object_id"), 0)))
|
52
|
+
#define INSPECT(...) (rb_funcall(rb_cObject, rb_intern("p"), __VA_ARGS__))
|
35
53
|
|
36
54
|
extern VALUE mGyro;
|
55
|
+
extern VALUE cGyro_Async;
|
56
|
+
extern VALUE cGyro_IO;
|
57
|
+
extern VALUE cGyro_Queue;
|
58
|
+
extern VALUE cGyro_Selector;
|
59
|
+
extern VALUE cGyro_Timer;
|
37
60
|
|
38
61
|
extern VALUE Gyro_reactor_fiber;
|
39
62
|
extern VALUE Gyro_root_fiber;
|
@@ -43,8 +66,12 @@ extern ID ID_caller;
|
|
43
66
|
extern ID ID_clear;
|
44
67
|
extern ID ID_each;
|
45
68
|
extern ID ID_inspect;
|
69
|
+
extern ID ID_new;
|
46
70
|
extern ID ID_raise;
|
47
71
|
extern ID ID_scheduled_value;
|
72
|
+
extern ID ID_signal_bang;
|
73
|
+
extern ID ID_size;
|
74
|
+
extern ID ID_switch_fiber;
|
48
75
|
extern ID ID_transfer;
|
49
76
|
extern ID ID_R;
|
50
77
|
extern ID ID_W;
|
data/ext/gyro/gyro_ext.c
CHANGED
@@ -4,9 +4,12 @@ void Init_Gyro();
|
|
4
4
|
void Init_Gyro_Async();
|
5
5
|
void Init_Gyro_Child();
|
6
6
|
void Init_Gyro_IO();
|
7
|
+
void Init_Gyro_Queue();
|
8
|
+
void Init_Gyro_Selector();
|
7
9
|
void Init_Gyro_Signal();
|
8
10
|
void Init_Gyro_Timer();
|
9
11
|
void Init_Socket();
|
12
|
+
void Init_Thread();
|
10
13
|
|
11
14
|
void Init_gyro_ext() {
|
12
15
|
ev_set_allocator(xrealloc);
|
@@ -15,8 +18,11 @@ void Init_gyro_ext() {
|
|
15
18
|
Init_Gyro_Async();
|
16
19
|
Init_Gyro_Child();
|
17
20
|
Init_Gyro_IO();
|
21
|
+
Init_Gyro_Queue();
|
22
|
+
Init_Gyro_Selector();
|
18
23
|
Init_Gyro_Signal();
|
19
24
|
Init_Gyro_Timer();
|
20
25
|
|
21
26
|
Init_Socket();
|
27
|
+
Init_Thread();
|
22
28
|
}
|
data/ext/gyro/io.c
CHANGED
@@ -8,56 +8,36 @@
|
|
8
8
|
|
9
9
|
struct Gyro_IO {
|
10
10
|
struct ev_io ev_io;
|
11
|
+
struct ev_loop *ev_loop;
|
11
12
|
int active;
|
12
13
|
int event_mask;
|
13
14
|
VALUE fiber;
|
14
15
|
};
|
15
16
|
|
16
|
-
|
17
|
+
VALUE cGyro_IO = Qnil;
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
static void Gyro_IO_free(void *ptr);
|
21
|
-
static size_t Gyro_IO_size(const void *ptr);
|
22
|
-
|
23
|
-
static VALUE Gyro_IO_initialize(VALUE self, VALUE io, VALUE event_mask);
|
24
|
-
|
25
|
-
void Gyro_IO_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
|
26
|
-
|
27
|
-
static int Gyro_IO_symbol2event_mask(VALUE sym);
|
28
|
-
|
29
|
-
// static VALUE IO_gets(int argc, VALUE *argv, VALUE io);
|
30
|
-
static VALUE IO_read(int argc, VALUE *argv, VALUE io);
|
31
|
-
static VALUE IO_readpartial(int argc, VALUE *argv, VALUE io);
|
32
|
-
static VALUE IO_write(int argc, VALUE *argv, VALUE io);
|
33
|
-
static VALUE IO_write_chevron(VALUE io, VALUE str);
|
34
|
-
|
35
|
-
ID ID_read_watcher;
|
36
|
-
ID ID_write_watcher;
|
19
|
+
ID ID_ivar_read_watcher;
|
20
|
+
ID ID_ivar_write_watcher;
|
37
21
|
VALUE SYM_r;
|
38
22
|
VALUE SYM_w;
|
39
23
|
|
40
|
-
void
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
24
|
+
static void Gyro_IO_mark(void *ptr) {
|
25
|
+
struct Gyro_IO *io = ptr;
|
26
|
+
if (io->fiber != Qnil) {
|
27
|
+
rb_gc_mark(io->fiber);
|
28
|
+
}
|
29
|
+
}
|
46
30
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
rb_define_method(cIO, "read_watcher", IO_read_watcher, 0);
|
55
|
-
rb_define_method(cIO, "write_watcher", IO_write_watcher, 0);
|
31
|
+
static void Gyro_IO_free(void *ptr) {
|
32
|
+
struct Gyro_IO *io = ptr;
|
33
|
+
if (io->active) {
|
34
|
+
printf("IO watcher garbage collected while still active!\n");
|
35
|
+
}
|
36
|
+
xfree(io);
|
37
|
+
}
|
56
38
|
|
57
|
-
|
58
|
-
|
59
|
-
SYM_r = ID2SYM(rb_intern("r"));
|
60
|
-
SYM_w = ID2SYM(rb_intern("w"));
|
39
|
+
static size_t Gyro_IO_size(const void *ptr) {
|
40
|
+
return sizeof(struct Gyro_IO);
|
61
41
|
}
|
62
42
|
|
63
43
|
static const rb_data_type_t Gyro_IO_type = {
|
@@ -73,25 +53,42 @@ static VALUE Gyro_IO_allocate(VALUE klass) {
|
|
73
53
|
return TypedData_Wrap_Struct(klass, &Gyro_IO_type, io);
|
74
54
|
}
|
75
55
|
|
76
|
-
static
|
77
|
-
|
56
|
+
static const char * S_IO = "IO";
|
57
|
+
static const char * S_to_io = "to_io";
|
58
|
+
|
59
|
+
void Gyro_IO_callback(struct ev_loop *ev_loop, struct ev_io *ev_io, int revents) {
|
60
|
+
struct Gyro_IO *io = (struct Gyro_IO*)ev_io;
|
61
|
+
|
62
|
+
ev_io_stop(io->ev_loop, ev_io);
|
63
|
+
io->active = 0;
|
64
|
+
|
78
65
|
if (io->fiber != Qnil) {
|
79
|
-
|
66
|
+
VALUE fiber = io->fiber;
|
67
|
+
io->fiber = Qnil;
|
68
|
+
Gyro_schedule_fiber(fiber, Qnil);
|
80
69
|
}
|
81
70
|
}
|
82
71
|
|
83
|
-
static
|
84
|
-
|
85
|
-
ev_io_stop(EV_DEFAULT, &io->ev_io);
|
86
|
-
xfree(io);
|
87
|
-
}
|
72
|
+
static int Gyro_IO_symbol2event_mask(VALUE sym) {
|
73
|
+
ID sym_id;
|
88
74
|
|
89
|
-
|
90
|
-
|
91
|
-
}
|
75
|
+
if (NIL_P(sym)) {
|
76
|
+
return 0;
|
77
|
+
}
|
92
78
|
|
93
|
-
|
94
|
-
|
79
|
+
sym_id = SYM2ID(sym);
|
80
|
+
|
81
|
+
if(sym_id == ID_R) {
|
82
|
+
return EV_READ;
|
83
|
+
} else if(sym_id == ID_W) {
|
84
|
+
return EV_WRITE;
|
85
|
+
} else if(sym_id == ID_RW) {
|
86
|
+
return EV_READ | EV_WRITE;
|
87
|
+
} else {
|
88
|
+
rb_raise(rb_eArgError, "invalid interest type %s (must be :r, :w, or :rw)",
|
89
|
+
RSTRING_PTR(rb_funcall(sym, ID_inspect, 0)));
|
90
|
+
}
|
91
|
+
}
|
95
92
|
|
96
93
|
#define GetGyro_IO(obj, io) TypedData_Get_Struct((obj), struct Gyro_IO, &Gyro_IO_type, (io))
|
97
94
|
|
@@ -111,19 +108,6 @@ static VALUE Gyro_IO_initialize(VALUE self, VALUE io_obj, VALUE event_mask) {
|
|
111
108
|
return Qnil;
|
112
109
|
}
|
113
110
|
|
114
|
-
void Gyro_IO_callback(struct ev_loop *ev_loop, struct ev_io *ev_io, int revents) {
|
115
|
-
struct Gyro_IO *io = (struct Gyro_IO*)ev_io;
|
116
|
-
|
117
|
-
ev_io_stop(EV_DEFAULT, ev_io);
|
118
|
-
io->active = 0;
|
119
|
-
|
120
|
-
if (io->fiber != Qnil) {
|
121
|
-
VALUE fiber = io->fiber;
|
122
|
-
io->fiber = Qnil;
|
123
|
-
Gyro_schedule_fiber(fiber, Qnil);
|
124
|
-
}
|
125
|
-
}
|
126
|
-
|
127
111
|
VALUE Gyro_IO_await(VALUE self) {
|
128
112
|
struct Gyro_IO *io;
|
129
113
|
VALUE ret;
|
@@ -132,14 +116,16 @@ VALUE Gyro_IO_await(VALUE self) {
|
|
132
116
|
|
133
117
|
io->fiber = rb_fiber_current();
|
134
118
|
io->active = 1;
|
135
|
-
|
136
|
-
|
119
|
+
io->ev_loop = Gyro_Selector_current_thread_ev_loop();
|
120
|
+
ev_io_start(io->ev_loop, &io->ev_io);
|
121
|
+
|
122
|
+
ret = Fiber_await();
|
123
|
+
RB_GC_GUARD(ret);
|
137
124
|
|
138
|
-
// make sure io watcher is stopped
|
139
|
-
io->fiber = Qnil;
|
140
125
|
if (io->active) {
|
141
126
|
io->active = 0;
|
142
|
-
|
127
|
+
io->fiber = Qnil;
|
128
|
+
ev_io_stop(io->ev_loop, &io->ev_io);
|
143
129
|
}
|
144
130
|
|
145
131
|
// fiber is resumed, check if resumed value is an exception
|
@@ -151,27 +137,6 @@ VALUE Gyro_IO_await(VALUE self) {
|
|
151
137
|
}
|
152
138
|
}
|
153
139
|
|
154
|
-
static int Gyro_IO_symbol2event_mask(VALUE sym) {
|
155
|
-
ID sym_id;
|
156
|
-
|
157
|
-
if (NIL_P(sym)) {
|
158
|
-
return 0;
|
159
|
-
}
|
160
|
-
|
161
|
-
sym_id = SYM2ID(sym);
|
162
|
-
|
163
|
-
if(sym_id == ID_R) {
|
164
|
-
return EV_READ;
|
165
|
-
} else if(sym_id == ID_W) {
|
166
|
-
return EV_WRITE;
|
167
|
-
} else if(sym_id == ID_RW) {
|
168
|
-
return EV_READ | EV_WRITE;
|
169
|
-
} else {
|
170
|
-
rb_raise(rb_eArgError, "invalid interest type %s (must be :r, :w, or :rw)",
|
171
|
-
RSTRING_PTR(rb_funcall(sym, ID_inspect, 0)));
|
172
|
-
}
|
173
|
-
}
|
174
|
-
|
175
140
|
//////////////////////////////////////////////////////////////////////
|
176
141
|
//////////////////////////////////////////////////////////////////////
|
177
142
|
// the following is copied verbatim from the Ruby source code (io.c)
|
@@ -436,21 +401,47 @@ static VALUE IO_write_chevron(VALUE io, VALUE str) {
|
|
436
401
|
}
|
437
402
|
|
438
403
|
VALUE IO_read_watcher(VALUE self) {
|
439
|
-
VALUE watcher = rb_ivar_get(self,
|
404
|
+
VALUE watcher = rb_ivar_get(self, ID_ivar_read_watcher);
|
440
405
|
if (watcher == Qnil) {
|
441
406
|
VALUE args[] = {self, SYM_r};
|
442
407
|
watcher = rb_class_new_instance(2, args, cGyro_IO);
|
443
|
-
rb_ivar_set(self,
|
408
|
+
rb_ivar_set(self, ID_ivar_read_watcher, watcher);
|
444
409
|
}
|
445
410
|
return watcher;
|
446
411
|
}
|
447
412
|
|
448
413
|
VALUE IO_write_watcher(VALUE self) {
|
449
|
-
VALUE watcher = rb_ivar_get(self,
|
414
|
+
VALUE watcher = rb_ivar_get(self, ID_ivar_write_watcher);
|
450
415
|
if (watcher == Qnil) {
|
451
416
|
VALUE args[] = {self, SYM_w};
|
452
417
|
watcher = rb_class_new_instance(2, args, cGyro_IO);
|
453
|
-
rb_ivar_set(self,
|
418
|
+
rb_ivar_set(self, ID_ivar_write_watcher, watcher);
|
454
419
|
}
|
455
420
|
return watcher;
|
456
|
-
}
|
421
|
+
}
|
422
|
+
|
423
|
+
void Init_Gyro_IO() {
|
424
|
+
cGyro_IO = rb_define_class_under(mGyro, "IO", rb_cData);
|
425
|
+
rb_define_alloc_func(cGyro_IO, Gyro_IO_allocate);
|
426
|
+
|
427
|
+
rb_define_method(cGyro_IO, "initialize", Gyro_IO_initialize, 2);
|
428
|
+
rb_define_method(cGyro_IO, "await", Gyro_IO_await, 0);
|
429
|
+
|
430
|
+
VALUE cIO = rb_const_get(rb_cObject, rb_intern("IO"));
|
431
|
+
// rb_define_method(cIO, "gets", IO_gets, -1);
|
432
|
+
rb_define_method(cIO, "read", IO_read, -1);
|
433
|
+
rb_define_method(cIO, "readpartial", IO_readpartial, -1);
|
434
|
+
rb_define_method(cIO, "write", IO_write, -1);
|
435
|
+
rb_define_method(cIO, "write_nonblock", IO_write, -1);
|
436
|
+
rb_define_method(cIO, "<<", IO_write_chevron, 1);
|
437
|
+
rb_define_method(cIO, "read_watcher", IO_read_watcher, 0);
|
438
|
+
rb_define_method(cIO, "write_watcher", IO_write_watcher, 0);
|
439
|
+
|
440
|
+
ID_ivar_read_watcher = rb_intern("@read_watcher");
|
441
|
+
ID_ivar_write_watcher = rb_intern("@write_watcher");
|
442
|
+
SYM_r = ID2SYM(rb_intern("r"));
|
443
|
+
SYM_w = ID2SYM(rb_intern("w"));
|
444
|
+
|
445
|
+
rb_global_variable(&SYM_r);
|
446
|
+
rb_global_variable(&SYM_w);
|
447
|
+
}
|
data/ext/gyro/queue.c
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
#include "gyro.h"
|
2
|
+
|
3
|
+
struct Gyro_Queue {
|
4
|
+
VALUE self;
|
5
|
+
VALUE queue;
|
6
|
+
VALUE wait_queue;
|
7
|
+
};
|
8
|
+
|
9
|
+
VALUE cGyro_Queue = Qnil;
|
10
|
+
|
11
|
+
static void Gyro_Queue_mark(void *ptr) {
|
12
|
+
struct Gyro_Queue *queue = ptr;
|
13
|
+
if (queue->queue != Qnil) {
|
14
|
+
rb_gc_mark(queue->queue);
|
15
|
+
}
|
16
|
+
if (queue->wait_queue != Qnil) {
|
17
|
+
rb_gc_mark(queue->wait_queue);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
static void Gyro_Queue_free(void *ptr) {
|
22
|
+
struct Gyro_Queue *queue = ptr;
|
23
|
+
xfree(queue);
|
24
|
+
}
|
25
|
+
|
26
|
+
static size_t Gyro_Queue_size(const void *ptr) {
|
27
|
+
return sizeof(struct Gyro_Queue);
|
28
|
+
}
|
29
|
+
|
30
|
+
static const rb_data_type_t Gyro_Queue_type = {
|
31
|
+
"Gyro_Queue",
|
32
|
+
{Gyro_Queue_mark, Gyro_Queue_free, Gyro_Queue_size,},
|
33
|
+
0, 0,
|
34
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
35
|
+
};
|
36
|
+
|
37
|
+
static VALUE Gyro_Queue_allocate(VALUE klass) {
|
38
|
+
struct Gyro_Queue *queue = (struct Gyro_Queue *)xmalloc(sizeof(struct Gyro_Queue));
|
39
|
+
return TypedData_Wrap_Struct(klass, &Gyro_Queue_type, queue);
|
40
|
+
}
|
41
|
+
#define GetGyro_Queue(obj, queue) \
|
42
|
+
TypedData_Get_Struct((obj), struct Gyro_Queue, &Gyro_Queue_type, (queue))
|
43
|
+
|
44
|
+
static VALUE Gyro_Queue_initialize(VALUE self) {
|
45
|
+
struct Gyro_Queue *queue;
|
46
|
+
GetGyro_Queue(self, queue);
|
47
|
+
|
48
|
+
queue->self = self;
|
49
|
+
queue->queue = rb_ary_new();
|
50
|
+
queue->wait_queue = rb_ary_new();
|
51
|
+
|
52
|
+
return Qnil;
|
53
|
+
}
|
54
|
+
|
55
|
+
VALUE Gyro_Queue_push(VALUE self, VALUE value) {
|
56
|
+
struct Gyro_Queue *queue;
|
57
|
+
GetGyro_Queue(self, queue);
|
58
|
+
|
59
|
+
if (RARRAY_LEN(queue->wait_queue) > 0) {
|
60
|
+
VALUE async = rb_ary_shift(queue->wait_queue);
|
61
|
+
return rb_funcall(async, ID_signal_bang, 1, value);
|
62
|
+
}
|
63
|
+
|
64
|
+
rb_ary_push(queue->queue, value);
|
65
|
+
return self;
|
66
|
+
}
|
67
|
+
|
68
|
+
VALUE Gyro_Queue_shift(VALUE self) {
|
69
|
+
struct Gyro_Queue *queue;
|
70
|
+
GetGyro_Queue(self, queue);
|
71
|
+
|
72
|
+
if (RARRAY_LEN(queue->queue) > 0) {
|
73
|
+
return rb_ary_shift(queue->queue);
|
74
|
+
}
|
75
|
+
|
76
|
+
VALUE async = rb_funcall(cGyro_Async, ID_new, 0);
|
77
|
+
rb_ary_push(queue->wait_queue, async);
|
78
|
+
return Gyro_Async_await(async);
|
79
|
+
}
|
80
|
+
|
81
|
+
VALUE Gyro_Queue_shift_all(VALUE self) {
|
82
|
+
struct Gyro_Queue *queue;
|
83
|
+
GetGyro_Queue(self, queue);
|
84
|
+
|
85
|
+
if (rb_block_given_p()) {
|
86
|
+
while (RARRAY_LEN(queue->queue) > 0) {
|
87
|
+
rb_yield(rb_ary_shift(queue->queue));
|
88
|
+
}
|
89
|
+
}
|
90
|
+
else {
|
91
|
+
rb_ary_clear(queue->queue);
|
92
|
+
}
|
93
|
+
|
94
|
+
return self;
|
95
|
+
}
|
96
|
+
|
97
|
+
void Init_Gyro_Queue() {
|
98
|
+
cGyro_Queue = rb_define_class_under(mGyro, "Queue", rb_cData);
|
99
|
+
rb_define_alloc_func(cGyro_Queue, Gyro_Queue_allocate);
|
100
|
+
|
101
|
+
rb_define_method(cGyro_Queue, "initialize", Gyro_Queue_initialize, 0);
|
102
|
+
rb_define_method(cGyro_Queue, "push", Gyro_Queue_push, 1);
|
103
|
+
rb_define_method(cGyro_Queue, "<<", Gyro_Queue_push, 1);
|
104
|
+
|
105
|
+
rb_define_method(cGyro_Queue, "pop", Gyro_Queue_shift, 0);
|
106
|
+
rb_define_method(cGyro_Queue, "shift", Gyro_Queue_shift, 0);
|
107
|
+
|
108
|
+
rb_define_method(cGyro_Queue, "shift_each", Gyro_Queue_shift_all, 0);
|
109
|
+
}
|