polyphony 0.26 → 0.27
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/.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
|
+
}
|