nio4r 2.5.8 → 2.7.4
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
- checksums.yaml.gz.sig +0 -0
- data/{CHANGES.md → changes.md} +48 -0
- data/ext/nio4r/bytebuffer.c +75 -38
- data/ext/nio4r/extconf.rb +19 -1
- data/ext/nio4r/monitor.c +47 -22
- data/ext/nio4r/nio4r.h +1 -5
- data/ext/nio4r/nio4r_ext.c +4 -0
- data/ext/nio4r/org/nio4r/ByteBuffer.java +1 -1
- data/ext/nio4r/org/nio4r/Monitor.java +2 -2
- data/ext/nio4r/org/nio4r/Selector.java +2 -2
- data/ext/nio4r/selector.c +72 -48
- data/lib/nio/bytebuffer.rb +6 -0
- data/lib/nio/monitor.rb +7 -0
- data/lib/nio/selector.rb +15 -0
- data/lib/nio/version.rb +6 -1
- data/lib/nio.rb +9 -0
- data/lib/nio4r.rb +7 -0
- data/license.md +80 -0
- data/readme.md +91 -0
- data.tar.gz.sig +3 -0
- metadata +96 -75
- metadata.gz.sig +0 -0
- data/.github/workflows/workflow.yml +0 -47
- data/.gitignore +0 -21
- data/.rspec +0 -4
- data/.rubocop.yml +0 -100
- data/Gemfile +0 -18
- data/README.md +0 -133
- data/Rakefile +0 -8
- data/examples/echo_server.rb +0 -47
- data/logo.png +0 -0
- data/nio4r.gemspec +0 -42
- data/rakelib/extension.rake +0 -15
- data/rakelib/rspec.rake +0 -9
- data/rakelib/rubocop.rake +0 -5
- data/spec/nio/acceptables_spec.rb +0 -32
- data/spec/nio/bytebuffer_spec.rb +0 -354
- data/spec/nio/monitor_spec.rb +0 -162
- data/spec/nio/selectables/pipe_spec.rb +0 -47
- data/spec/nio/selectables/ssl_socket_spec.rb +0 -194
- data/spec/nio/selectables/tcp_socket_spec.rb +0 -101
- data/spec/nio/selectables/udp_socket_spec.rb +0 -48
- data/spec/nio/selector_spec.rb +0 -240
- data/spec/spec_helper.rb +0 -20
- data/spec/support/selectable_examples.rb +0 -85
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8314c9539cda7366afdf81069ac061dc9ee56985a777b17af13e9d35b613d998
|
4
|
+
data.tar.gz: a8616d47698bd714649278ad575a4038fafcab6a4165978278683214ea0d3898
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ed28a8e9921b297f33c4247440c647a02bccd5ee7325ded2a712dfb4aeb9df34d61e9ebe8e0bc69b413dff78d313d309318291deade808a4b80e02400d5980d
|
7
|
+
data.tar.gz: f0d693629b56cdc3c85adf2200bb982b42df41eb7ce9aea9fc2ad4896afc9713db96c55950440118f242fbd82af0089da6ca8531e6ef6ea6b7b16c130101a631
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data/{CHANGES.md → changes.md}
RENAMED
@@ -1,3 +1,51 @@
|
|
1
|
+
## 2.7.2
|
2
|
+
|
3
|
+
* Modernize gem (list all authors, etc).
|
4
|
+
* Drop official support for Ruby 2.4.
|
5
|
+
* Fix JRuby release version.
|
6
|
+
|
7
|
+
## 2.7.1
|
8
|
+
|
9
|
+
* Fix license specification.
|
10
|
+
* Fix JRuby build warnings.
|
11
|
+
|
12
|
+
## 2.7.0
|
13
|
+
|
14
|
+
* Convert NIO objects to TypedData API.
|
15
|
+
|
16
|
+
## 2.6.1
|
17
|
+
|
18
|
+
* Don't update `io` which is subsequently stored. Retain the original.
|
19
|
+
|
20
|
+
## 2.6.0
|
21
|
+
|
22
|
+
* Fix conversion loses int precision.
|
23
|
+
* Avoid direct access to IO internals.
|
24
|
+
* Resolve issue loading both nio and nio4r gems.
|
25
|
+
|
26
|
+
## 2.5.9 (2023-04-02)
|
27
|
+
|
28
|
+
https://github.com/socketry/nio4r/compare/v2.5.8..v2.5.9
|
29
|
+
|
30
|
+
## 2.5.8 (2021-08-03)
|
31
|
+
|
32
|
+
* [#276](https://github.com/socketry/nio4r/pull/276)
|
33
|
+
Fix missing return statement in function returning non-void (issue [#275](https://github.com/socketry/nio4r/pull/275))
|
34
|
+
([@ioquatix])
|
35
|
+
* Remove `guard-rspec` from development dependencies ([@ioquatix])
|
36
|
+
|
37
|
+
## 2.5.7 (2021-03-04)
|
38
|
+
|
39
|
+
* [#267](https://github.com/socketry/nio4r/pull/267)
|
40
|
+
Don't try to link universal extension
|
41
|
+
([@ioquatix])
|
42
|
+
|
43
|
+
## 2.5.6 (2021-03-04)
|
44
|
+
|
45
|
+
* [#268](https://github.com/socketry/nio4r/pull/268)
|
46
|
+
Prefer kqueue when on OSX >= v10.12.2
|
47
|
+
([@jcmfernandes])
|
48
|
+
|
1
49
|
## 2.5.5 (2021-02-05)
|
2
50
|
|
3
51
|
* [#256](https://github.com/socketry/nio4r/pull/256)
|
data/ext/nio4r/bytebuffer.c
CHANGED
@@ -8,8 +8,8 @@ static VALUE cNIO_ByteBuffer_MarkUnsetError = Qnil;
|
|
8
8
|
|
9
9
|
/* Allocator/deallocator */
|
10
10
|
static VALUE NIO_ByteBuffer_allocate(VALUE klass);
|
11
|
-
static void
|
12
|
-
static
|
11
|
+
static void NIO_ByteBuffer_free(void *data);
|
12
|
+
static size_t NIO_ByteBuffer_memsize(const void *data);
|
13
13
|
|
14
14
|
/* Methods */
|
15
15
|
static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE capacity);
|
@@ -36,6 +36,26 @@ static VALUE NIO_ByteBuffer_inspect(VALUE self);
|
|
36
36
|
|
37
37
|
#define MARK_UNSET -1
|
38
38
|
|
39
|
+
/* Compatibility for Ruby <= 3.1 */
|
40
|
+
#ifndef HAVE_RB_IO_DESCRIPTOR
|
41
|
+
static int
|
42
|
+
io_descriptor_fallback(VALUE io)
|
43
|
+
{
|
44
|
+
rb_io_t *fptr;
|
45
|
+
GetOpenFile(io, fptr);
|
46
|
+
return fptr->fd;
|
47
|
+
}
|
48
|
+
#define rb_io_descriptor io_descriptor_fallback
|
49
|
+
#endif
|
50
|
+
|
51
|
+
static void
|
52
|
+
io_set_nonblock(VALUE io)
|
53
|
+
{
|
54
|
+
rb_io_t *fptr;
|
55
|
+
GetOpenFile(io, fptr);
|
56
|
+
rb_io_set_nonblock(fptr);
|
57
|
+
}
|
58
|
+
|
39
59
|
void Init_NIO_ByteBuffer()
|
40
60
|
{
|
41
61
|
mNIO = rb_define_module("NIO");
|
@@ -72,28 +92,46 @@ void Init_NIO_ByteBuffer()
|
|
72
92
|
rb_define_method(cNIO_ByteBuffer, "inspect", NIO_ByteBuffer_inspect, 0);
|
73
93
|
}
|
74
94
|
|
95
|
+
static const rb_data_type_t NIO_ByteBuffer_type = {
|
96
|
+
"NIO::ByteBuffer",
|
97
|
+
{
|
98
|
+
NULL, // Nothing to mark
|
99
|
+
NIO_ByteBuffer_free,
|
100
|
+
NIO_ByteBuffer_memsize,
|
101
|
+
},
|
102
|
+
0,
|
103
|
+
0,
|
104
|
+
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
105
|
+
};
|
106
|
+
|
75
107
|
static VALUE NIO_ByteBuffer_allocate(VALUE klass)
|
76
108
|
{
|
77
109
|
struct NIO_ByteBuffer *bytebuffer = (struct NIO_ByteBuffer *)xmalloc(sizeof(struct NIO_ByteBuffer));
|
78
110
|
bytebuffer->buffer = NULL;
|
79
|
-
return
|
111
|
+
return TypedData_Wrap_Struct(klass, &NIO_ByteBuffer_type, bytebuffer);
|
80
112
|
}
|
81
113
|
|
82
|
-
static void
|
114
|
+
static void NIO_ByteBuffer_free(void *data)
|
83
115
|
{
|
116
|
+
struct NIO_ByteBuffer *buffer = (struct NIO_ByteBuffer *)data;
|
117
|
+
if (buffer->buffer)
|
118
|
+
xfree(buffer->buffer);
|
119
|
+
xfree(buffer);
|
84
120
|
}
|
85
121
|
|
86
|
-
static
|
122
|
+
static size_t NIO_ByteBuffer_memsize(const void *data)
|
87
123
|
{
|
124
|
+
const struct NIO_ByteBuffer *buffer = (const struct NIO_ByteBuffer *)data;
|
125
|
+
size_t memsize = sizeof(struct NIO_ByteBuffer);
|
88
126
|
if (buffer->buffer)
|
89
|
-
|
90
|
-
|
127
|
+
memsize += buffer->capacity;
|
128
|
+
return memsize;
|
91
129
|
}
|
92
130
|
|
93
131
|
static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE capacity)
|
94
132
|
{
|
95
133
|
struct NIO_ByteBuffer *buffer;
|
96
|
-
|
134
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
97
135
|
|
98
136
|
buffer->capacity = NUM2INT(capacity);
|
99
137
|
buffer->buffer = xmalloc(buffer->capacity);
|
@@ -106,7 +144,7 @@ static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE capacity)
|
|
106
144
|
static VALUE NIO_ByteBuffer_clear(VALUE self)
|
107
145
|
{
|
108
146
|
struct NIO_ByteBuffer *buffer;
|
109
|
-
|
147
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
110
148
|
|
111
149
|
memset(buffer->buffer, 0, buffer->capacity);
|
112
150
|
|
@@ -120,7 +158,7 @@ static VALUE NIO_ByteBuffer_clear(VALUE self)
|
|
120
158
|
static VALUE NIO_ByteBuffer_get_position(VALUE self)
|
121
159
|
{
|
122
160
|
struct NIO_ByteBuffer *buffer;
|
123
|
-
|
161
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
124
162
|
|
125
163
|
return INT2NUM(buffer->position);
|
126
164
|
}
|
@@ -129,7 +167,7 @@ static VALUE NIO_ByteBuffer_set_position(VALUE self, VALUE new_position)
|
|
129
167
|
{
|
130
168
|
int pos;
|
131
169
|
struct NIO_ByteBuffer *buffer;
|
132
|
-
|
170
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
133
171
|
|
134
172
|
pos = NUM2INT(new_position);
|
135
173
|
|
@@ -153,7 +191,7 @@ static VALUE NIO_ByteBuffer_set_position(VALUE self, VALUE new_position)
|
|
153
191
|
static VALUE NIO_ByteBuffer_get_limit(VALUE self)
|
154
192
|
{
|
155
193
|
struct NIO_ByteBuffer *buffer;
|
156
|
-
|
194
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
157
195
|
|
158
196
|
return INT2NUM(buffer->limit);
|
159
197
|
}
|
@@ -162,7 +200,7 @@ static VALUE NIO_ByteBuffer_set_limit(VALUE self, VALUE new_limit)
|
|
162
200
|
{
|
163
201
|
int lim;
|
164
202
|
struct NIO_ByteBuffer *buffer;
|
165
|
-
|
203
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
166
204
|
|
167
205
|
lim = NUM2INT(new_limit);
|
168
206
|
|
@@ -190,7 +228,7 @@ static VALUE NIO_ByteBuffer_set_limit(VALUE self, VALUE new_limit)
|
|
190
228
|
static VALUE NIO_ByteBuffer_capacity(VALUE self)
|
191
229
|
{
|
192
230
|
struct NIO_ByteBuffer *buffer;
|
193
|
-
|
231
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
194
232
|
|
195
233
|
return INT2NUM(buffer->capacity);
|
196
234
|
}
|
@@ -198,7 +236,7 @@ static VALUE NIO_ByteBuffer_capacity(VALUE self)
|
|
198
236
|
static VALUE NIO_ByteBuffer_remaining(VALUE self)
|
199
237
|
{
|
200
238
|
struct NIO_ByteBuffer *buffer;
|
201
|
-
|
239
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
202
240
|
|
203
241
|
return INT2NUM(buffer->limit - buffer->position);
|
204
242
|
}
|
@@ -206,7 +244,7 @@ static VALUE NIO_ByteBuffer_remaining(VALUE self)
|
|
206
244
|
static VALUE NIO_ByteBuffer_full(VALUE self)
|
207
245
|
{
|
208
246
|
struct NIO_ByteBuffer *buffer;
|
209
|
-
|
247
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
210
248
|
|
211
249
|
return buffer->position == buffer->limit ? Qtrue : Qfalse;
|
212
250
|
}
|
@@ -216,7 +254,7 @@ static VALUE NIO_ByteBuffer_get(int argc, VALUE *argv, VALUE self)
|
|
216
254
|
int len;
|
217
255
|
VALUE length, result;
|
218
256
|
struct NIO_ByteBuffer *buffer;
|
219
|
-
|
257
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
220
258
|
|
221
259
|
rb_scan_args(argc, argv, "01", &length);
|
222
260
|
|
@@ -244,7 +282,7 @@ static VALUE NIO_ByteBuffer_fetch(VALUE self, VALUE index)
|
|
244
282
|
{
|
245
283
|
int i;
|
246
284
|
struct NIO_ByteBuffer *buffer;
|
247
|
-
|
285
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
248
286
|
|
249
287
|
i = NUM2INT(index);
|
250
288
|
|
@@ -263,7 +301,7 @@ static VALUE NIO_ByteBuffer_put(VALUE self, VALUE string)
|
|
263
301
|
{
|
264
302
|
long length;
|
265
303
|
struct NIO_ByteBuffer *buffer;
|
266
|
-
|
304
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
267
305
|
|
268
306
|
StringValue(string);
|
269
307
|
length = RSTRING_LEN(string);
|
@@ -281,19 +319,19 @@ static VALUE NIO_ByteBuffer_put(VALUE self, VALUE string)
|
|
281
319
|
static VALUE NIO_ByteBuffer_read_from(VALUE self, VALUE io)
|
282
320
|
{
|
283
321
|
struct NIO_ByteBuffer *buffer;
|
284
|
-
rb_io_t *fptr;
|
285
322
|
ssize_t nbytes, bytes_read;
|
286
323
|
|
287
|
-
|
288
|
-
|
289
|
-
|
324
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
325
|
+
|
326
|
+
io = rb_convert_type(io, T_FILE, "IO", "to_io");
|
327
|
+
io_set_nonblock(io);
|
290
328
|
|
291
329
|
nbytes = buffer->limit - buffer->position;
|
292
330
|
if (nbytes == 0) {
|
293
331
|
rb_raise(cNIO_ByteBuffer_OverflowError, "buffer is full");
|
294
332
|
}
|
295
333
|
|
296
|
-
bytes_read = read(
|
334
|
+
bytes_read = read(rb_io_descriptor(io), buffer->buffer + buffer->position, nbytes);
|
297
335
|
|
298
336
|
if (bytes_read < 0) {
|
299
337
|
if (errno == EAGAIN) {
|
@@ -305,25 +343,24 @@ static VALUE NIO_ByteBuffer_read_from(VALUE self, VALUE io)
|
|
305
343
|
|
306
344
|
buffer->position += bytes_read;
|
307
345
|
|
308
|
-
return
|
346
|
+
return SIZET2NUM(bytes_read);
|
309
347
|
}
|
310
348
|
|
311
349
|
static VALUE NIO_ByteBuffer_write_to(VALUE self, VALUE io)
|
312
350
|
{
|
313
351
|
struct NIO_ByteBuffer *buffer;
|
314
|
-
rb_io_t *fptr;
|
315
352
|
ssize_t nbytes, bytes_written;
|
316
353
|
|
317
|
-
|
318
|
-
|
319
|
-
|
354
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
355
|
+
io = rb_convert_type(io, T_FILE, "IO", "to_io");
|
356
|
+
io_set_nonblock(io);
|
320
357
|
|
321
358
|
nbytes = buffer->limit - buffer->position;
|
322
359
|
if (nbytes == 0) {
|
323
360
|
rb_raise(cNIO_ByteBuffer_UnderflowError, "no data remaining in buffer");
|
324
361
|
}
|
325
362
|
|
326
|
-
bytes_written = write(
|
363
|
+
bytes_written = write(rb_io_descriptor(io), buffer->buffer + buffer->position, nbytes);
|
327
364
|
|
328
365
|
if (bytes_written < 0) {
|
329
366
|
if (errno == EAGAIN) {
|
@@ -335,13 +372,13 @@ static VALUE NIO_ByteBuffer_write_to(VALUE self, VALUE io)
|
|
335
372
|
|
336
373
|
buffer->position += bytes_written;
|
337
374
|
|
338
|
-
return
|
375
|
+
return SIZET2NUM(bytes_written);
|
339
376
|
}
|
340
377
|
|
341
378
|
static VALUE NIO_ByteBuffer_flip(VALUE self)
|
342
379
|
{
|
343
380
|
struct NIO_ByteBuffer *buffer;
|
344
|
-
|
381
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
345
382
|
|
346
383
|
buffer->limit = buffer->position;
|
347
384
|
buffer->position = 0;
|
@@ -353,7 +390,7 @@ static VALUE NIO_ByteBuffer_flip(VALUE self)
|
|
353
390
|
static VALUE NIO_ByteBuffer_rewind(VALUE self)
|
354
391
|
{
|
355
392
|
struct NIO_ByteBuffer *buffer;
|
356
|
-
|
393
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
357
394
|
|
358
395
|
buffer->position = 0;
|
359
396
|
buffer->mark = MARK_UNSET;
|
@@ -364,7 +401,7 @@ static VALUE NIO_ByteBuffer_rewind(VALUE self)
|
|
364
401
|
static VALUE NIO_ByteBuffer_mark(VALUE self)
|
365
402
|
{
|
366
403
|
struct NIO_ByteBuffer *buffer;
|
367
|
-
|
404
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
368
405
|
|
369
406
|
buffer->mark = buffer->position;
|
370
407
|
return self;
|
@@ -373,7 +410,7 @@ static VALUE NIO_ByteBuffer_mark(VALUE self)
|
|
373
410
|
static VALUE NIO_ByteBuffer_reset(VALUE self)
|
374
411
|
{
|
375
412
|
struct NIO_ByteBuffer *buffer;
|
376
|
-
|
413
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
377
414
|
|
378
415
|
if (buffer->mark < 0) {
|
379
416
|
rb_raise(cNIO_ByteBuffer_MarkUnsetError, "mark has not been set");
|
@@ -387,7 +424,7 @@ static VALUE NIO_ByteBuffer_reset(VALUE self)
|
|
387
424
|
static VALUE NIO_ByteBuffer_compact(VALUE self)
|
388
425
|
{
|
389
426
|
struct NIO_ByteBuffer *buffer;
|
390
|
-
|
427
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
391
428
|
|
392
429
|
memmove(buffer->buffer, buffer->buffer + buffer->position, buffer->limit - buffer->position);
|
393
430
|
buffer->position = buffer->limit - buffer->position;
|
@@ -400,7 +437,7 @@ static VALUE NIO_ByteBuffer_each(VALUE self)
|
|
400
437
|
{
|
401
438
|
int i;
|
402
439
|
struct NIO_ByteBuffer *buffer;
|
403
|
-
|
440
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
404
441
|
|
405
442
|
if (rb_block_given_p()) {
|
406
443
|
for (i = 0; i < buffer->limit; i++) {
|
@@ -416,7 +453,7 @@ static VALUE NIO_ByteBuffer_each(VALUE self)
|
|
416
453
|
static VALUE NIO_ByteBuffer_inspect(VALUE self)
|
417
454
|
{
|
418
455
|
struct NIO_ByteBuffer *buffer;
|
419
|
-
|
456
|
+
TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer);
|
420
457
|
|
421
458
|
return rb_sprintf(
|
422
459
|
"#<%s:%p @position=%d @limit=%d @capacity=%d>",
|
data/ext/nio4r/extconf.rb
CHANGED
@@ -1,10 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2011-2020, by Tony Arcieri.
|
5
|
+
# Copyright, 2014, by Hiroshi Shibata.
|
6
|
+
# Copyright, 2014, by Sergey Avseyev.
|
7
|
+
# Copyright, 2015, by Daniel Berger.
|
8
|
+
# Copyright, 2017, by Jun Aruga.
|
9
|
+
# Copyright, 2017, by Usaku Nakamura.
|
10
|
+
# Copyright, 2017, by Lars Kanis.
|
11
|
+
# Copyright, 2019-2023, by Samuel Williams.
|
12
|
+
# Copyright, 2020, by Gregory Longtin.
|
13
|
+
# Copyright, 2020, by Boaz Segev.
|
14
|
+
# Copyright, 2020, by Joao Fernandes.
|
15
|
+
# Copyright, 2021, by Jeffrey Martin.
|
16
|
+
|
3
17
|
require "rubygems"
|
4
18
|
|
5
19
|
# Write a dummy Makefile on Windows because we use the pure Ruby implementation there
|
6
20
|
if Gem.win_platform?
|
7
|
-
|
21
|
+
begin
|
22
|
+
require "devkit" if RUBY_PLATFORM.include?("mingw")
|
23
|
+
rescue LoadError => e
|
24
|
+
end
|
8
25
|
File.write("Makefile", "all install::\n")
|
9
26
|
File.write("nio4r_ext.so", "")
|
10
27
|
exit
|
@@ -13,6 +30,7 @@ end
|
|
13
30
|
require "mkmf"
|
14
31
|
|
15
32
|
have_header("unistd.h")
|
33
|
+
have_func("rb_io_descriptor")
|
16
34
|
|
17
35
|
$defs << "-DEV_USE_LINUXAIO" if have_header("linux/aio_abi.h")
|
18
36
|
$defs << "-DEV_USE_IOURING" if have_header("linux/io_uring.h")
|
data/ext/nio4r/monitor.c
CHANGED
@@ -11,8 +11,8 @@ static VALUE cNIO_Monitor = Qnil;
|
|
11
11
|
|
12
12
|
/* Allocator/deallocator */
|
13
13
|
static VALUE NIO_Monitor_allocate(VALUE klass);
|
14
|
-
static void NIO_Monitor_mark(
|
15
|
-
static
|
14
|
+
static void NIO_Monitor_mark(void *data);
|
15
|
+
static size_t NIO_Monitor_memsize(const void *data);
|
16
16
|
|
17
17
|
/* Methods */
|
18
18
|
static VALUE NIO_Monitor_initialize(VALUE self, VALUE selector, VALUE io, VALUE interests);
|
@@ -34,6 +34,18 @@ static VALUE NIO_Monitor_readiness(VALUE self);
|
|
34
34
|
static int NIO_Monitor_symbol2interest(VALUE interests);
|
35
35
|
static void NIO_Monitor_update_interests(VALUE self, int interests);
|
36
36
|
|
37
|
+
/* Compatibility for Ruby <= 3.1 */
|
38
|
+
#ifndef HAVE_RB_IO_DESCRIPTOR
|
39
|
+
static int
|
40
|
+
io_descriptor_fallback(VALUE io)
|
41
|
+
{
|
42
|
+
rb_io_t *fptr;
|
43
|
+
GetOpenFile(io, fptr);
|
44
|
+
return fptr->fd;
|
45
|
+
}
|
46
|
+
#define rb_io_descriptor io_descriptor_fallback
|
47
|
+
#endif
|
48
|
+
|
37
49
|
/* Monitor control how a channel is being waited for by a monitor */
|
38
50
|
void Init_NIO_Monitor()
|
39
51
|
{
|
@@ -58,22 +70,36 @@ void Init_NIO_Monitor()
|
|
58
70
|
rb_define_method(cNIO_Monitor, "writeable?", NIO_Monitor_is_writable, 0);
|
59
71
|
}
|
60
72
|
|
73
|
+
static const rb_data_type_t NIO_Monitor_type = {
|
74
|
+
"NIO::Monitor",
|
75
|
+
{
|
76
|
+
NIO_Monitor_mark,
|
77
|
+
RUBY_TYPED_DEFAULT_FREE,
|
78
|
+
NIO_Monitor_memsize,
|
79
|
+
},
|
80
|
+
0,
|
81
|
+
0,
|
82
|
+
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
83
|
+
};
|
84
|
+
|
61
85
|
static VALUE NIO_Monitor_allocate(VALUE klass)
|
62
86
|
{
|
63
87
|
struct NIO_Monitor *monitor = (struct NIO_Monitor *)xmalloc(sizeof(struct NIO_Monitor));
|
64
88
|
assert(monitor);
|
65
89
|
*monitor = (struct NIO_Monitor){.self = Qnil};
|
66
|
-
return
|
90
|
+
return TypedData_Wrap_Struct(klass, &NIO_Monitor_type, monitor);
|
67
91
|
}
|
68
92
|
|
69
|
-
static void NIO_Monitor_mark(
|
93
|
+
static void NIO_Monitor_mark(void *data)
|
70
94
|
{
|
95
|
+
struct NIO_Monitor *monitor = (struct NIO_Monitor *)data;
|
71
96
|
rb_gc_mark(monitor->self);
|
72
97
|
}
|
73
98
|
|
74
|
-
static
|
99
|
+
static size_t NIO_Monitor_memsize(const void *data)
|
75
100
|
{
|
76
|
-
|
101
|
+
const struct NIO_Monitor *monitor = (const struct NIO_Monitor *)data;
|
102
|
+
return sizeof(*monitor);
|
77
103
|
}
|
78
104
|
|
79
105
|
static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE selector_obj)
|
@@ -81,11 +107,10 @@ static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE
|
|
81
107
|
struct NIO_Monitor *monitor;
|
82
108
|
struct NIO_Selector *selector;
|
83
109
|
ID interests_id;
|
84
|
-
rb_io_t *fptr;
|
85
110
|
|
86
111
|
interests_id = SYM2ID(interests);
|
87
112
|
|
88
|
-
|
113
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
89
114
|
|
90
115
|
if (interests_id == rb_intern("r")) {
|
91
116
|
monitor->interests = EV_READ;
|
@@ -97,16 +122,16 @@ static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE
|
|
97
122
|
rb_raise(rb_eArgError, "invalid event type %s (must be :r, :w, or :rw)", RSTRING_PTR(rb_funcall(interests, rb_intern("inspect"), 0)));
|
98
123
|
}
|
99
124
|
|
100
|
-
|
101
|
-
ev_io_init(&monitor->ev_io, NIO_Selector_monitor_callback,
|
125
|
+
int descriptor = rb_io_descriptor(rb_convert_type(io, T_FILE, "IO", "to_io"));
|
126
|
+
ev_io_init(&monitor->ev_io, NIO_Selector_monitor_callback, descriptor, monitor->interests);
|
102
127
|
|
103
128
|
rb_ivar_set(self, rb_intern("io"), io);
|
104
129
|
rb_ivar_set(self, rb_intern("interests"), interests);
|
105
130
|
rb_ivar_set(self, rb_intern("selector"), selector_obj);
|
106
131
|
|
107
|
-
|
132
|
+
selector = NIO_Selector_unwrap(selector_obj);
|
108
133
|
|
109
|
-
monitor->self
|
134
|
+
RB_OBJ_WRITE(self, &monitor->self, self);
|
110
135
|
monitor->ev_io.data = (void *)monitor;
|
111
136
|
|
112
137
|
/* We can safely hang onto this as we also hang onto a reference to the
|
@@ -124,7 +149,7 @@ static VALUE NIO_Monitor_close(int argc, VALUE *argv, VALUE self)
|
|
124
149
|
{
|
125
150
|
VALUE deregister, selector;
|
126
151
|
struct NIO_Monitor *monitor;
|
127
|
-
|
152
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
128
153
|
|
129
154
|
rb_scan_args(argc, argv, "01", &deregister);
|
130
155
|
selector = rb_ivar_get(self, rb_intern("selector"));
|
@@ -150,7 +175,7 @@ static VALUE NIO_Monitor_close(int argc, VALUE *argv, VALUE self)
|
|
150
175
|
static VALUE NIO_Monitor_is_closed(VALUE self)
|
151
176
|
{
|
152
177
|
struct NIO_Monitor *monitor;
|
153
|
-
|
178
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
154
179
|
|
155
180
|
return monitor->selector == 0 ? Qtrue : Qfalse;
|
156
181
|
}
|
@@ -179,10 +204,10 @@ static VALUE NIO_Monitor_set_interests(VALUE self, VALUE interests)
|
|
179
204
|
static VALUE NIO_Monitor_add_interest(VALUE self, VALUE interest)
|
180
205
|
{
|
181
206
|
struct NIO_Monitor *monitor;
|
182
|
-
|
207
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
183
208
|
|
184
209
|
interest = monitor->interests | NIO_Monitor_symbol2interest(interest);
|
185
|
-
NIO_Monitor_update_interests(self, interest);
|
210
|
+
NIO_Monitor_update_interests(self, (int)interest);
|
186
211
|
|
187
212
|
return rb_ivar_get(self, rb_intern("interests"));
|
188
213
|
}
|
@@ -190,10 +215,10 @@ static VALUE NIO_Monitor_add_interest(VALUE self, VALUE interest)
|
|
190
215
|
static VALUE NIO_Monitor_remove_interest(VALUE self, VALUE interest)
|
191
216
|
{
|
192
217
|
struct NIO_Monitor *monitor;
|
193
|
-
|
218
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
194
219
|
|
195
220
|
interest = monitor->interests & ~NIO_Monitor_symbol2interest(interest);
|
196
|
-
NIO_Monitor_update_interests(self, interest);
|
221
|
+
NIO_Monitor_update_interests(self, (int)interest);
|
197
222
|
|
198
223
|
return rb_ivar_get(self, rb_intern("interests"));
|
199
224
|
}
|
@@ -216,7 +241,7 @@ static VALUE NIO_Monitor_set_value(VALUE self, VALUE obj)
|
|
216
241
|
static VALUE NIO_Monitor_readiness(VALUE self)
|
217
242
|
{
|
218
243
|
struct NIO_Monitor *monitor;
|
219
|
-
|
244
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
220
245
|
|
221
246
|
if ((monitor->revents & (EV_READ | EV_WRITE)) == (EV_READ | EV_WRITE)) {
|
222
247
|
return ID2SYM(rb_intern("rw"));
|
@@ -232,7 +257,7 @@ static VALUE NIO_Monitor_readiness(VALUE self)
|
|
232
257
|
static VALUE NIO_Monitor_is_readable(VALUE self)
|
233
258
|
{
|
234
259
|
struct NIO_Monitor *monitor;
|
235
|
-
|
260
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
236
261
|
|
237
262
|
if (monitor->revents & EV_READ) {
|
238
263
|
return Qtrue;
|
@@ -244,7 +269,7 @@ static VALUE NIO_Monitor_is_readable(VALUE self)
|
|
244
269
|
static VALUE NIO_Monitor_is_writable(VALUE self)
|
245
270
|
{
|
246
271
|
struct NIO_Monitor *monitor;
|
247
|
-
|
272
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
248
273
|
|
249
274
|
if (monitor->revents & EV_WRITE) {
|
250
275
|
return Qtrue;
|
@@ -275,7 +300,7 @@ static void NIO_Monitor_update_interests(VALUE self, int interests)
|
|
275
300
|
{
|
276
301
|
ID interests_id;
|
277
302
|
struct NIO_Monitor *monitor;
|
278
|
-
|
303
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
279
304
|
|
280
305
|
if (NIO_Monitor_is_closed(self) == Qtrue) {
|
281
306
|
rb_raise(rb_eEOFError, "monitor is closed");
|
data/ext/nio4r/nio4r.h
CHANGED
@@ -40,11 +40,7 @@ struct NIO_ByteBuffer {
|
|
40
40
|
int position, limit, capacity, mark;
|
41
41
|
};
|
42
42
|
|
43
|
-
|
44
|
-
#define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))
|
45
|
-
#else
|
46
|
-
#define FPTR_TO_FD(fptr) fptr->fd
|
47
|
-
#endif /* GetReadFile */
|
43
|
+
struct NIO_Selector *NIO_Selector_unwrap(VALUE selector);
|
48
44
|
|
49
45
|
/* Thunk between libev callbacks in NIO::Monitors and NIO::Selectors */
|
50
46
|
void NIO_Selector_monitor_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
|
data/ext/nio4r/nio4r_ext.c
CHANGED
@@ -27,7 +27,7 @@ created by Upekshej
|
|
27
27
|
*/
|
28
28
|
public class ByteBuffer extends RubyObject {
|
29
29
|
private static final long serialVersionUID = -6903439483039149324L;
|
30
|
-
private java.nio.ByteBuffer byteBuffer;
|
30
|
+
private transient java.nio.ByteBuffer byteBuffer;
|
31
31
|
|
32
32
|
public static RaiseException newOverflowError(ThreadContext context, String message) {
|
33
33
|
RubyClass klass = context.runtime.getModule("NIO").getClass("ByteBuffer").getClass("OverflowError");
|
@@ -14,9 +14,9 @@ import org.jruby.runtime.builtin.IRubyObject;
|
|
14
14
|
|
15
15
|
public class Monitor extends RubyObject {
|
16
16
|
private static final long serialVersionUID = -3733782997115074794L;
|
17
|
-
private SelectionKey key;
|
17
|
+
private transient SelectionKey key;
|
18
18
|
private RubyIO io;
|
19
|
-
private IRubyObject interests, selector, value, closed;
|
19
|
+
private transient IRubyObject interests, selector, value, closed;
|
20
20
|
|
21
21
|
public Monitor(final Ruby ruby, RubyClass rubyClass) {
|
22
22
|
super(ruby, rubyClass);
|
@@ -22,7 +22,7 @@ import org.jruby.util.io.OpenFile;
|
|
22
22
|
|
23
23
|
public class Selector extends RubyObject {
|
24
24
|
private static final long serialVersionUID = -14562818539414873L;
|
25
|
-
private java.nio.channels.Selector selector;
|
25
|
+
private transient java.nio.channels.Selector selector;
|
26
26
|
private HashMap<SelectableChannel,SelectionKey> cancelledKeys;
|
27
27
|
private volatile boolean wakeupFired;
|
28
28
|
|
@@ -234,7 +234,7 @@ public class Selector extends RubyObject {
|
|
234
234
|
|
235
235
|
cancelKeys();
|
236
236
|
try {
|
237
|
-
context.getThread().beforeBlockingCall();
|
237
|
+
context.getThread().beforeBlockingCall(context);
|
238
238
|
if(timeout.isNil()) {
|
239
239
|
result = this.selector.select();
|
240
240
|
} else {
|