event 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5039784abaf0f999187afbed8ca930bf99cf66cc089136da3b3e42ea6831b729
4
- data.tar.gz: 712d0693031af7bd93c1da59e5ad716d8be81a895d1d3ea23dca6cf80e42f5d0
3
+ metadata.gz: 287fe2e9885bd34fd2595c49589c2cfe751799e34f738a18e93f9ccdf13f3ffd
4
+ data.tar.gz: 88cec8cd2badba810501a9a3aef7309dcb76d87ef0c6029bca147ba2d3eea09e
5
5
  SHA512:
6
- metadata.gz: 3de44f33a4410d1cf5b52186ac606d1d03f33326f3124e69b50b705ac8840c2f7facc5924378353b2fce55324cbf353fc407bf60f041e6b0b0990d889eaad7dc
7
- data.tar.gz: e34bc430b17351ba2210e89c2d3cec4049eafd3e2e8c3297d777c6dfae6cdc9dc9a823b83bf503c4c1a9e7463f74064d0632f1e641cdac9d5034012f76bf50c9
6
+ metadata.gz: 956801d0c052c06efe6cf126e76472a02f2271d8476a0501f262ab1d71b0e97992fc5bf2ffce33b753f510179ec42f8f5529152d9bd48ed6029b4009ba754d3c
7
+ data.tar.gz: 3f35bf37920170794733e5b3671aa9e0e1a3a64620dde2209310d5c8143866ce92289c5efe6b9f2010f271b2452b3efdb9bbb3d2c3c72d80cefd847154746355
@@ -0,0 +1,206 @@
1
+ // Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ #include "kqueue.h"
22
+
23
+ #include <sys/epoll.h>
24
+ #include <time.h>
25
+ #include <errno.h>
26
+
27
+ static VALUE Event_Backend_EPoll = Qnil;
28
+ static ID id_fileno, id_transfer;
29
+
30
+ static const int READABLE = 1, PRIORITY = 2, WRITABLE = 4;
31
+
32
+ static const unsigned EPOLL_MAX_EVENTS = 1024;
33
+
34
+ struct Event_Backend_EPoll {
35
+ VALUE loop;
36
+ int descriptor;
37
+ };
38
+
39
+ void Event_Backend_EPoll_Type_mark(void *_data)
40
+ {
41
+ struct Event_Backend_EPoll *data = _data;
42
+ rb_gc_mark(data->loop);
43
+ }
44
+
45
+ void Event_Backend_EPoll_Type_free(void *_data)
46
+ {
47
+ struct Event_Backend_EPoll *data = _data;
48
+
49
+ if (data->descriptor >= 0) {
50
+ close(data->descriptor);
51
+ }
52
+
53
+ free(data);
54
+ }
55
+
56
+ size_t Event_Backend_EPoll_Type_size(const void *data)
57
+ {
58
+ return sizeof(struct Event_Backend_EPoll);
59
+ }
60
+
61
+ static const rb_data_type_t Event_Backend_EPoll_Type = {
62
+ .wrap_struct_name = "Event::Backend::EPoll",
63
+ .function = {
64
+ .dmark = Event_Backend_EPoll_Type_mark,
65
+ .dfree = Event_Backend_EPoll_Type_free,
66
+ .dsize = Event_Backend_EPoll_Type_size,
67
+ },
68
+ .data = NULL,
69
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
70
+ };
71
+
72
+ VALUE Event_Backend_EPoll_allocate(VALUE self) {
73
+ struct Event_Backend_EPoll *data = NULL;
74
+ VALUE instance = TypedData_Make_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
75
+
76
+ data->loop = Qnil;
77
+ data->descriptor = -1;
78
+
79
+ return instance;
80
+ }
81
+
82
+ VALUE Event_Backend_EPoll_initialize(VALUE self, VALUE loop) {
83
+ struct Event_Backend_EPoll *data = NULL;
84
+ TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
85
+
86
+ data->loop = loop;
87
+ int result = epoll_create1(EPOLL_CLOEXEC);
88
+
89
+ if (result == -1) {
90
+ rb_sys_fail("epoll_create");
91
+ } else {
92
+ data->descriptor = result;
93
+
94
+ rb_update_max_fd(data->descriptor);
95
+ }
96
+
97
+ return self;
98
+ }
99
+
100
+ VALUE Event_Backend_EPoll_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE events) {
101
+ struct Event_Backend_EPoll *data = NULL;
102
+ TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
103
+
104
+ struct epoll_event event = {0};
105
+
106
+ int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
107
+ int duplicate = -1;
108
+
109
+ int mask = NUM2INT(events);
110
+
111
+ if (mask & READABLE) {
112
+ event.events |= EPOLLIN;
113
+ }
114
+
115
+ if (mask & PRIORITY) {
116
+ event.events |= EPOLLPRI;
117
+ }
118
+
119
+ if (mask & WRITABLE) {
120
+ event.events |= EPOLLOUT;
121
+ }
122
+
123
+ event.events |= EPOLLRDHUP;
124
+ event.events |= EPOLLONESHOT;
125
+
126
+ event.data.ptr = (void*)fiber;
127
+
128
+ // A better approach is to batch all changes:
129
+ int result = epoll_ctl(data->descriptor, EPOLL_CTL_ADD, descriptor, &event);;
130
+
131
+ if (result == -1 && errno == EEXIST) {
132
+ // The file descriptor was already inserted into epoll.
133
+ duplicate = descriptor = dup(descriptor);
134
+
135
+ rb_update_max_fd(duplicate);
136
+
137
+ if (descriptor == -1)
138
+ rb_sys_fail("dup");
139
+
140
+ result = epoll_ctl(data->descriptor, EPOLL_CTL_ADD, descriptor, &event);;
141
+ }
142
+
143
+ if (result == -1) {
144
+ rb_sys_fail("epoll_ctl");
145
+ }
146
+
147
+ rb_funcall(data->loop, id_transfer, 0);
148
+
149
+ if (duplicate >= 0) {
150
+ close(duplicate);
151
+ }
152
+
153
+ return Qnil;
154
+ }
155
+
156
+ static
157
+ int make_timeout(VALUE duration) {
158
+ if (duration == Qnil) {
159
+ return -1;
160
+ }
161
+
162
+ if (FIXNUM_P(duration)) {
163
+ return NUM2LONG(duration) * 1000L;
164
+ }
165
+
166
+ else if (RB_FLOAT_TYPE_P(duration)) {
167
+ double value = RFLOAT_VALUE(duration);
168
+
169
+ return value * 1000;
170
+ }
171
+
172
+ rb_raise(rb_eRuntimeError, "unable to convert timeout");
173
+ }
174
+
175
+ VALUE Event_Backend_EPoll_select(VALUE self, VALUE duration) {
176
+ struct Event_Backend_EPoll *data = NULL;
177
+ TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
178
+
179
+ struct epoll_event events[EPOLL_MAX_EVENTS];
180
+
181
+ int count = epoll_wait(data->descriptor, events, EPOLL_MAX_EVENTS, make_timeout(duration));
182
+
183
+ if (count == -1) {
184
+ rb_sys_fail("epoll_wait");
185
+ }
186
+
187
+ for (int i = 0; i < count; i += 1) {
188
+ VALUE fiber = (VALUE)events[i].data.ptr;
189
+ rb_funcall(fiber, id_transfer, 0);
190
+ }
191
+
192
+ return INT2NUM(count);
193
+ }
194
+
195
+ void Init_Event_Backend_EPoll(VALUE Event_Backend) {
196
+ id_fileno = rb_intern("fileno");
197
+ id_transfer = rb_intern("transfer");
198
+
199
+ Event_Backend_EPoll = rb_define_class_under(Event_Backend, "EPoll", rb_cObject);
200
+
201
+ rb_define_alloc_func(Event_Backend_EPoll, Event_Backend_EPoll_allocate);
202
+ rb_define_method(Event_Backend_EPoll, "initialize", Event_Backend_EPoll_initialize, 1);
203
+
204
+ rb_define_method(Event_Backend_EPoll, "io_wait", Event_Backend_EPoll_io_wait, 3);
205
+ rb_define_method(Event_Backend_EPoll, "select", Event_Backend_EPoll_select, 1);
206
+ }
@@ -0,0 +1,25 @@
1
+ // Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ #pragma once
22
+
23
+ #define EVENT_BACKEND_EPOLL
24
+
25
+ void Init_Event_Backend_EPoll(VALUE Event_Backend);
@@ -0,0 +1,196 @@
1
+ // Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ #include "kqueue.h"
22
+
23
+ #include <sys/event.h>
24
+ #include <sys/ioctl.h>
25
+ #include <time.h>
26
+
27
+ static VALUE Event_Backend_KQueue = Qnil;
28
+ static ID id_fileno, id_transfer;
29
+
30
+ static const int READABLE = 1, PRIORITY = 2, WRITABLE = 4;
31
+
32
+ static const unsigned KQUEUE_MAX_EVENTS = 1024;
33
+
34
+ struct Event_Backend_KQueue {
35
+ VALUE loop;
36
+ int descriptor;
37
+ };
38
+
39
+ void Event_Backend_KQueue_Type_mark(void *_data)
40
+ {
41
+ struct Event_Backend_KQueue *data = _data;
42
+ rb_gc_mark(data->loop);
43
+ }
44
+
45
+ void Event_Backend_KQueue_Type_free(void *_data)
46
+ {
47
+ struct Event_Backend_KQueue *data = _data;
48
+
49
+ if (data->descriptor >= 0) {
50
+ close(data->descriptor);
51
+ }
52
+
53
+ free(data);
54
+ }
55
+
56
+ size_t Event_Backend_KQueue_Type_size(const void *data)
57
+ {
58
+ return sizeof(struct Event_Backend_KQueue);
59
+ }
60
+
61
+ static const rb_data_type_t Event_Backend_KQueue_Type = {
62
+ .wrap_struct_name = "Event::Backend::KQueue",
63
+ .function = {
64
+ .dmark = Event_Backend_KQueue_Type_mark,
65
+ .dfree = Event_Backend_KQueue_Type_free,
66
+ .dsize = Event_Backend_KQueue_Type_size,
67
+ },
68
+ .data = NULL,
69
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
70
+ };
71
+
72
+ VALUE Event_Backend_KQueue_allocate(VALUE self) {
73
+ struct Event_Backend_KQueue *data = NULL;
74
+ VALUE instance = TypedData_Make_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data);
75
+
76
+ data->loop = Qnil;
77
+ data->descriptor = -1;
78
+
79
+ return instance;
80
+ }
81
+
82
+ VALUE Event_Backend_KQueue_initialize(VALUE self, VALUE loop) {
83
+ struct Event_Backend_KQueue *data = NULL;
84
+ TypedData_Get_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data);
85
+
86
+ data->loop = loop;
87
+ int result = kqueue();
88
+
89
+ if (result == -1) {
90
+ rb_sys_fail("kqueue");
91
+ } else {
92
+ ioctl(result, FIOCLEX);
93
+ data->descriptor = result;
94
+
95
+ rb_update_max_fd(data->descriptor);
96
+ }
97
+
98
+ return self;
99
+ }
100
+
101
+ VALUE Event_Backend_KQueue_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE events) {
102
+ struct Event_Backend_KQueue *data = NULL;
103
+ TypedData_Get_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data);
104
+
105
+ struct kevent event;
106
+ u_short flags = 0;
107
+
108
+ int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
109
+
110
+ int mask = NUM2INT(events);
111
+
112
+ if (mask & READABLE) {
113
+ flags |= EVFILT_READ;
114
+ }
115
+
116
+ if (mask & PRIORITY) {
117
+ flags |= EV_OOBAND;
118
+ }
119
+
120
+ if (mask & WRITABLE) {
121
+ flags |= EVFILT_WRITE;
122
+ }
123
+
124
+ EV_SET(&event, descriptor, flags, EV_ADD|EV_ENABLE|EV_ONESHOT, 0, 0, (void*)fiber);
125
+
126
+ // A better approach is to batch all changes:
127
+ int result = kevent(data->descriptor, &event, 1, NULL, 0, NULL);
128
+
129
+ if (result == -1) {
130
+ rb_sys_fail("kevent");
131
+ }
132
+
133
+ rb_funcall(data->loop, id_transfer, 0);
134
+
135
+ return Qnil;
136
+ }
137
+
138
+ static
139
+ struct timespec * make_timeout(VALUE duration, struct timespec * storage) {
140
+ if (duration == Qnil) {
141
+ return NULL;
142
+ }
143
+
144
+ if (FIXNUM_P(duration)) {
145
+ storage->tv_sec = NUM2TIMET(duration);
146
+ storage->tv_nsec = 0;
147
+
148
+ return storage;
149
+ }
150
+
151
+ else if (RB_FLOAT_TYPE_P(duration)) {
152
+ double value = RFLOAT_VALUE(duration);
153
+ time_t seconds = duration;
154
+
155
+ storage->tv_sec = seconds;
156
+ storage->tv_nsec = (value - seconds) * 1000000000L;
157
+
158
+ return storage;
159
+ }
160
+
161
+ rb_raise(rb_eRuntimeError, "unable to convert timeout");
162
+ }
163
+
164
+ VALUE Event_Backend_KQueue_select(VALUE self, VALUE duration) {
165
+ struct Event_Backend_KQueue *data = NULL;
166
+ TypedData_Get_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data);
167
+
168
+ struct kevent events[KQUEUE_MAX_EVENTS];
169
+ struct timespec storage;
170
+
171
+ int count = kevent(data->descriptor, NULL, 0, events, KQUEUE_MAX_EVENTS, make_timeout(duration, &storage));
172
+
173
+ if (count == -1) {
174
+ rb_sys_fail("kevent");
175
+ }
176
+
177
+ for (int i = 0; i < count; i += 1) {
178
+ VALUE fiber = (VALUE)events[i].udata;
179
+ rb_funcall(fiber, id_transfer, 0);
180
+ }
181
+
182
+ return INT2NUM(count);
183
+ }
184
+
185
+ void Init_Event_Backend_KQueue(VALUE Event_Backend) {
186
+ id_fileno = rb_intern("fileno");
187
+ id_transfer = rb_intern("transfer");
188
+
189
+ Event_Backend_KQueue = rb_define_class_under(Event_Backend, "KQueue", rb_cObject);
190
+
191
+ rb_define_alloc_func(Event_Backend_KQueue, Event_Backend_KQueue_allocate);
192
+ rb_define_method(Event_Backend_KQueue, "initialize", Event_Backend_KQueue_initialize, 1);
193
+
194
+ rb_define_method(Event_Backend_KQueue, "io_wait", Event_Backend_KQueue_io_wait, 3);
195
+ rb_define_method(Event_Backend_KQueue, "select", Event_Backend_KQueue_select, 1);
196
+ }
@@ -0,0 +1,27 @@
1
+ // Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ #pragma once
22
+
23
+ #include <ruby.h>
24
+
25
+ #define EVENT_BACKEND_KQUEUE
26
+
27
+ void Init_Event_Backend_KQueue(VALUE Event_Backend);
@@ -0,0 +1,288 @@
1
+ // Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ #include "uring.h"
22
+
23
+ #include <liburing.h>
24
+ #include <time.h>
25
+
26
+ static VALUE Event_Backend_URing = Qnil;
27
+ static ID id_fileno, id_transfer;
28
+
29
+ static const int READABLE = 1, PRIORITY = 2, WRITABLE = 4;
30
+
31
+ static const int URING_ENTRIES = 1024;
32
+ static const int URING_MAX_EVENTS = 1024;
33
+
34
+ struct Event_Backend_URing {
35
+ VALUE loop;
36
+ struct io_uring* ring;
37
+ };
38
+
39
+ void Event_Backend_URing_Type_mark(void *_data)
40
+ {
41
+ struct Event_Backend_URing *data = _data;
42
+ rb_gc_mark(data->loop);
43
+ }
44
+
45
+ void Event_Backend_URing_Type_free(void *_data)
46
+ {
47
+ struct Event_Backend_URing *data = _data;
48
+
49
+ if (data->ring) {
50
+ io_uring_queue_exit(data->ring);
51
+ xfree(data->ring);
52
+ }
53
+
54
+ free(data);
55
+ }
56
+
57
+ size_t Event_Backend_URing_Type_size(const void *data)
58
+ {
59
+ return sizeof(struct Event_Backend_URing);
60
+ }
61
+
62
+ static const rb_data_type_t Event_Backend_URing_Type = {
63
+ .wrap_struct_name = "Event::Backend::URing",
64
+ .function = {
65
+ .dmark = Event_Backend_URing_Type_mark,
66
+ .dfree = Event_Backend_URing_Type_free,
67
+ .dsize = Event_Backend_URing_Type_size,
68
+ },
69
+ .data = NULL,
70
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
71
+ };
72
+
73
+ VALUE Event_Backend_URing_allocate(VALUE self) {
74
+ struct Event_Backend_URing *data = NULL;
75
+ VALUE instance = TypedData_Make_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
76
+
77
+ data->loop = Qnil;
78
+ data->ring = NULL;
79
+
80
+ return instance;
81
+ }
82
+
83
+ VALUE Event_Backend_URing_initialize(VALUE self, VALUE loop) {
84
+ struct Event_Backend_URing *data = NULL;
85
+ TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
86
+
87
+ data->loop = loop;
88
+ data->ring = xmalloc(sizeof(struct io_uring));
89
+
90
+ int result = io_uring_queue_init(URING_ENTRIES, data->ring, 0);
91
+
92
+ if (result == -1) {
93
+ rb_sys_fail("io_uring_queue_init");
94
+ }
95
+
96
+ return self;
97
+ }
98
+
99
+ VALUE Event_Backend_URing_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE events) {
100
+ struct Event_Backend_URing *data = NULL;
101
+ TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
102
+
103
+ int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
104
+ struct io_uring_sqe *sqe = io_uring_get_sqe(data->ring);
105
+
106
+ int mask = NUM2INT(events);
107
+ short flags = 0;
108
+
109
+ if (mask & READABLE) {
110
+ flags |= POLL_IN;
111
+ }
112
+
113
+ if (mask & PRIORITY) {
114
+ flags |= POLL_PRI;
115
+ }
116
+
117
+ if (mask & WRITABLE) {
118
+ flags |= POLL_OUT;
119
+ }
120
+
121
+ // fprintf(stderr, "poll_add(%p, %d, %d)\n", sqe, descriptor, flags);
122
+
123
+ io_uring_prep_poll_add(sqe, descriptor, flags);
124
+ io_uring_sqe_set_data(sqe, (void*)fiber);
125
+ io_uring_submit(data->ring);
126
+
127
+ // fprintf(stderr, "count = %d, errno = %d\n", count, errno);
128
+
129
+ rb_funcall(data->loop, id_transfer, 0);
130
+
131
+ return Qnil;
132
+ }
133
+
134
+ static
135
+ struct __kernel_timespec * make_timeout(VALUE duration, struct __kernel_timespec *storage) {
136
+ if (duration == Qnil) {
137
+ return NULL;
138
+ }
139
+
140
+ if (FIXNUM_P(duration)) {
141
+ storage->tv_sec = NUM2TIMET(duration);
142
+ storage->tv_nsec = 0;
143
+
144
+ return storage;
145
+ }
146
+
147
+ else if (RB_FLOAT_TYPE_P(duration)) {
148
+ double value = RFLOAT_VALUE(duration);
149
+ time_t seconds = duration;
150
+
151
+ storage->tv_sec = seconds;
152
+ storage->tv_nsec = (value - seconds) * 1000000000L;
153
+
154
+ return storage;
155
+ }
156
+
157
+ rb_raise(rb_eRuntimeError, "unable to convert timeout");
158
+ }
159
+
160
+ inline static
161
+ void resize_to_capacity(VALUE string, size_t offset, size_t length) {
162
+ size_t current_length = RSTRING_LEN(string);
163
+ long difference = (long)(offset + length) - (long)current_length;
164
+
165
+ difference += 1;
166
+
167
+ if (difference > 0) {
168
+ rb_str_modify_expand(string, difference);
169
+ } else {
170
+ rb_str_modify(string);
171
+ }
172
+ }
173
+
174
+ inline static
175
+ void resize_to_fit(VALUE string, size_t offset, size_t length) {
176
+ size_t current_length = RSTRING_LEN(string);
177
+
178
+ if (current_length < (offset + length)) {
179
+ rb_str_set_len(string, offset + length);
180
+ }
181
+ }
182
+
183
+ VALUE Event_Backend_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE offset, VALUE length) {
184
+ struct Event_Backend_URing *data = NULL;
185
+ TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
186
+
187
+ resize_to_capacity(buffer, NUM2SIZET(offset), NUM2SIZET(length));
188
+
189
+ int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
190
+ struct io_uring_sqe *sqe = io_uring_get_sqe(data->ring);
191
+
192
+ struct iovec iovecs[1];
193
+ iovecs[0].iov_base = RSTRING_PTR(buffer) + NUM2SIZET(offset);
194
+ iovecs[0].iov_len = NUM2SIZET(length);
195
+
196
+ io_uring_prep_readv(sqe, descriptor, iovecs, 1, 0);
197
+ io_uring_sqe_set_data(sqe, (void*)fiber);
198
+ io_uring_submit(data->ring);
199
+
200
+ int result = NUM2INT(rb_funcall(data->loop, id_transfer, 0));
201
+
202
+ if (result < 0) {
203
+ rb_syserr_fail(-result, strerror(-result));
204
+ }
205
+
206
+ resize_to_fit(buffer, NUM2SIZET(offset), (size_t)result);
207
+
208
+ return INT2NUM(result);
209
+ }
210
+
211
+ VALUE Event_Backend_URing_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE offset, VALUE length) {
212
+ struct Event_Backend_URing *data = NULL;
213
+ TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
214
+
215
+ if ((size_t)RSTRING_LEN(buffer) < NUM2SIZET(offset) + NUM2SIZET(length)) {
216
+ rb_raise(rb_eRuntimeError, "invalid offset/length exceeds bounds of buffer");
217
+ }
218
+
219
+ int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
220
+ struct io_uring_sqe *sqe = io_uring_get_sqe(data->ring);
221
+
222
+ struct iovec iovecs[1];
223
+ iovecs[0].iov_base = RSTRING_PTR(buffer) + NUM2SIZET(offset);
224
+ iovecs[0].iov_len = NUM2SIZET(length);
225
+
226
+ io_uring_prep_writev(sqe, descriptor, iovecs, 1, 0);
227
+ io_uring_sqe_set_data(sqe, (void*)fiber);
228
+ io_uring_submit(data->ring);
229
+
230
+ int result = NUM2INT(rb_funcall(data->loop, id_transfer, 0));
231
+
232
+ if (result < 0) {
233
+ rb_syserr_fail(-result, strerror(-result));
234
+ }
235
+
236
+ return INT2NUM(result);
237
+ }
238
+
239
+ VALUE Event_Backend_URing_select(VALUE self, VALUE duration) {
240
+ struct Event_Backend_URing *data = NULL;
241
+ TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
242
+
243
+ struct io_uring_cqe *cqes[URING_MAX_EVENTS];
244
+ struct __kernel_timespec storage;
245
+
246
+ if (duration != Qnil) {
247
+ int result = io_uring_wait_cqe_timeout(data->ring, cqes, make_timeout(duration, &storage));
248
+
249
+ if (result == -ETIME) {
250
+ // Timeout.
251
+ } else if (result < 0) {
252
+ rb_syserr_fail(-result, strerror(-result));
253
+ }
254
+ }
255
+
256
+ int count = io_uring_peek_batch_cqe(data->ring, cqes, URING_MAX_EVENTS);
257
+
258
+ if (count == -1) {
259
+ rb_sys_fail("io_uring_peek_batch_cqe");
260
+ }
261
+
262
+ for (int i = 0; i < count; i += 1) {
263
+ VALUE fiber = (VALUE)io_uring_cqe_get_data(cqes[i]);
264
+ VALUE result = INT2NUM(cqes[i]->res);
265
+
266
+ io_uring_cqe_seen(data->ring, cqes[i]);
267
+
268
+ rb_funcall(fiber, id_transfer, 1, result);
269
+ }
270
+
271
+ return INT2NUM(count);
272
+ }
273
+
274
+ void Init_Event_Backend_URing(VALUE Event_Backend) {
275
+ id_fileno = rb_intern("fileno");
276
+ id_transfer = rb_intern("transfer");
277
+
278
+ Event_Backend_URing = rb_define_class_under(Event_Backend, "URing", rb_cObject);
279
+
280
+ rb_define_alloc_func(Event_Backend_URing, Event_Backend_URing_allocate);
281
+ rb_define_method(Event_Backend_URing, "initialize", Event_Backend_URing_initialize, 1);
282
+
283
+ rb_define_method(Event_Backend_URing, "io_wait", Event_Backend_URing_io_wait, 3);
284
+ rb_define_method(Event_Backend_URing, "select", Event_Backend_URing_select, 1);
285
+
286
+ rb_define_method(Event_Backend_URing, "io_read", Event_Backend_URing_io_read, 5);
287
+ rb_define_method(Event_Backend_URing, "io_write", Event_Backend_URing_io_write, 5);
288
+ }
@@ -0,0 +1,27 @@
1
+ // Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ #pragma once
22
+
23
+ #include <ruby.h>
24
+
25
+ #define EVENT_BACKEND_URING
26
+
27
+ void Init_Event_Backend_URing(VALUE Event_Backend);
data/ext/event/event.c ADDED
@@ -0,0 +1,46 @@
1
+ // Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ #include "event.h"
22
+
23
+ VALUE Event = Qnil;
24
+ VALUE Event_Backend = Qnil;
25
+
26
+ void Init_event()
27
+ {
28
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
29
+ rb_ext_ractor_safe(true);
30
+ #endif
31
+
32
+ Event = rb_define_module("Event");
33
+ Event_Backend = rb_define_module_under(Event, "Backend");
34
+
35
+ #ifdef EVENT_BACKEND_URING
36
+ Init_Event_Backend_URing(Event_Backend);
37
+ #endif
38
+
39
+ #ifdef EVENT_BACKEND_EPOLL
40
+ Init_Event_Backend_EPoll(Event_Backend);
41
+ #endif
42
+
43
+ #ifdef EVENT_BACKEND_KQUEUE
44
+ Init_Event_Backend_KQueue(Event_Backend);
45
+ #endif
46
+ }
data/ext/event/event.h ADDED
@@ -0,0 +1,39 @@
1
+ // Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ #pragma once
22
+
23
+ #include <ruby.h>
24
+
25
+ #include "extconf.h"
26
+
27
+ void Init_event();
28
+
29
+ #if HAVE_LIBURING_H
30
+ #include "backend/uring.h"
31
+ #endif
32
+
33
+ #if HAVE_SYS_EPOLL_H
34
+ #include "backend/epoll.h"
35
+ #endif
36
+
37
+ #if HAVE_SYS_EVENT_H
38
+ #include "backend/kqueue.h"
39
+ #endif
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require 'mkmf'
24
+
25
+ gem_name = File.basename(__dir__)
26
+ extension_name = 'event'
27
+
28
+ # The destination
29
+ dir_config(extension_name)
30
+
31
+ $srcs = ["event.c"]
32
+ $VPATH << "$(srcdir)/backend"
33
+
34
+ if have_library('uring') and have_header('liburing.h')
35
+ $srcs << "backend/uring.c"
36
+ end
37
+
38
+ if have_header('sys/epoll.h')
39
+ $srcs << "backend/epoll.c"
40
+ end
41
+
42
+ if have_header('sys/event.h')
43
+ $srcs << "backend/kqueue.c"
44
+ end
45
+
46
+ create_header
47
+
48
+ # Generate the makefile to compile the native binary into `lib`:
49
+ create_makefile(File.join(gem_name, extension_name))
data/lib/event.rb CHANGED
@@ -18,4 +18,19 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
- require "event/version"
21
+ require_relative 'event/version'
22
+ require_relative 'event/backend/select'
23
+
24
+ module Event
25
+ # These constants are the same as those defined in IO.
26
+
27
+ READABLE = 1
28
+ PRIORITY = 2
29
+ WRITABLE = 4
30
+ end
31
+
32
+ begin
33
+ require_relative '../ext/event/event'
34
+ rescue LoadError
35
+ # Ignore.
36
+ end
@@ -18,12 +18,10 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  # THE SOFTWARE.
20
20
 
21
- require "event/version"
22
-
23
21
  module Event
24
22
  module Backend
25
23
  class Select
26
- def initialize(loop = Fiber.current)
24
+ def initialize(loop)
27
25
  @loop = loop
28
26
 
29
27
  @readable = {}
@@ -31,11 +29,11 @@ module Event
31
29
  end
32
30
 
33
31
  def io_wait(fiber, io, events)
34
- if (events & IO::READABLE) > 0 or (events & IO::PRIORITY) > 0
32
+ if (events & READABLE) > 0 or (events & PRIORITY) > 0
35
33
  @readable[io] = fiber
36
34
  end
37
35
 
38
- if (events & IO::WRITABLE) > 0
36
+ if (events & WRITABLE) > 0
39
37
  @writable[io] = fiber
40
38
  end
41
39
 
@@ -47,12 +45,12 @@ module Event
47
45
 
48
46
  ready = {}
49
47
 
50
- readable.each do |io|
48
+ readable&.each do |io|
51
49
  fiber = @readable.delete(io)
52
50
  ready[fiber] = true
53
51
  end
54
52
 
55
- writable.each do |io|
53
+ writable&.each do |io|
56
54
  fiber = @writable.delete(io)
57
55
  ready[fiber] = true
58
56
  end
@@ -0,0 +1,99 @@
1
+ # Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require "event/version"
22
+
23
+ module Event
24
+ module Debug
25
+ class Selector
26
+ def initialize(selector)
27
+ @selector = selector
28
+
29
+ @readable = {}
30
+ @writable = {}
31
+ @priority = {}
32
+ end
33
+
34
+ def io_wait(fiber, io, events)
35
+ register_readable(fiber, io, events)
36
+ end
37
+
38
+ def select(duration = nil)
39
+ @selector.select(duration)
40
+ end
41
+
42
+ private
43
+
44
+ def register_readable(fiber, io, events)
45
+ if (events & READABLE) > 0
46
+ if @readable.key?(io)
47
+ raise "Cannot wait for #{io} to become readable from multiple fibers."
48
+ end
49
+
50
+ begin
51
+ @readable[io] = fiber
52
+
53
+ register_writable(fiber, io, events)
54
+ ensure
55
+ @readable.delete(io)
56
+ end
57
+ else
58
+ register_writable(fiber, io, events)
59
+ end
60
+ end
61
+
62
+ def register_writable(fiber, io, events)
63
+ if (events & WRITABLE) > 0
64
+ if @writable.key?(io)
65
+ raise "Cannot wait for #{io} to become writable from multiple fibers."
66
+ end
67
+
68
+ begin
69
+ @writable[io] = fiber
70
+
71
+ register_priority(fiber, io, events)
72
+ ensure
73
+ @writable.delete(io)
74
+ end
75
+ else
76
+ register_priority(fiber, io, events)
77
+ end
78
+ end
79
+
80
+ def register_priority(fiber, io, events)
81
+ if (events & PRIORITY) > 0
82
+ if @priority.key?(io)
83
+ raise "Cannot wait for #{io} to become priority from multiple fibers."
84
+ end
85
+
86
+ begin
87
+ @priority[io] = fiber
88
+
89
+ @selector.io_wait(fiber, io, events)
90
+ ensure
91
+ @priority.delete(io)
92
+ end
93
+ else
94
+ @selector.io_wait(fiber, io, events)
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
data/lib/event/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Event
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: event
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -10,6 +10,20 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2021-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -55,11 +69,22 @@ dependencies:
55
69
  description:
56
70
  email:
57
71
  executables: []
58
- extensions: []
72
+ extensions:
73
+ - ext/event/extconf.rb
59
74
  extra_rdoc_files: []
60
75
  files:
76
+ - ext/event/backend/epoll.c
77
+ - ext/event/backend/epoll.h
78
+ - ext/event/backend/kqueue.c
79
+ - ext/event/backend/kqueue.h
80
+ - ext/event/backend/uring.c
81
+ - ext/event/backend/uring.h
82
+ - ext/event/event.c
83
+ - ext/event/event.h
84
+ - ext/event/extconf.rb
61
85
  - lib/event.rb
62
86
  - lib/event/backend/select.rb
87
+ - lib/event/debug/selector.rb
63
88
  - lib/event/selector.rb
64
89
  - lib/event/version.rb
65
90
  homepage: https://github.com/socketry/event
@@ -81,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
106
  - !ruby/object:Gem::Version
82
107
  version: '0'
83
108
  requirements: []
84
- rubygems_version: 3.2.15
109
+ rubygems_version: 3.1.2
85
110
  signing_key:
86
111
  specification_version: 4
87
112
  summary: An event loop.