io-wait 0.2.3 → 0.3.1
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/Gemfile +1 -0
- data/ext/io/wait/extconf.rb +1 -0
- data/ext/io/wait/wait.c +107 -71
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ab2e90fe2ac7d5df2d629e3ccd501b8c01570fadd3eeee5d42709e55deb26ec6
|
|
4
|
+
data.tar.gz: 12663accc0c74fb25368e47a87fbc7a5b4f06ccd7435ee1ab4528e51b4dca843
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1bc887d4119a7c39978294b99d6bc2affbc0124236ec4062fe439ffbfa64db295ec4de180a1db16ad2c481927a72f046def66e34dae9cca49157ccd25a8b82e4
|
|
7
|
+
data.tar.gz: 1b237ca1a3f74ff1208059f49061df665ff4a78f8da89d9b7ffbb9a57cd9205ffbb848fb583704fafad66954df7f2481d9a145e1d68591c31d11ab8fff1b2dbe
|
data/Gemfile
CHANGED
data/ext/io/wait/extconf.rb
CHANGED
|
@@ -6,6 +6,7 @@ if RUBY_VERSION < "2.6"
|
|
|
6
6
|
else
|
|
7
7
|
target = "io/wait"
|
|
8
8
|
have_func("rb_io_wait")
|
|
9
|
+
have_func("rb_io_descriptor")
|
|
9
10
|
unless macro_defined?("DOSISH", "#include <ruby.h>")
|
|
10
11
|
have_header(ioctl_h = "sys/ioctl.h") or ioctl_h = nil
|
|
11
12
|
fionread = %w[sys/ioctl.h sys/filio.h sys/socket.h].find do |h|
|
data/ext/io/wait/wait.c
CHANGED
|
@@ -41,22 +41,17 @@
|
|
|
41
41
|
#endif
|
|
42
42
|
|
|
43
43
|
#ifndef HAVE_RB_IO_WAIT
|
|
44
|
-
static VALUE io_ready_p _((VALUE io));
|
|
45
|
-
static VALUE io_wait_readable _((int argc, VALUE *argv, VALUE io));
|
|
46
|
-
static VALUE io_wait_writable _((int argc, VALUE *argv, VALUE io));
|
|
47
|
-
void Init_wait _((void));
|
|
48
|
-
|
|
49
44
|
static struct timeval *
|
|
50
45
|
get_timeout(int argc, VALUE *argv, struct timeval *timerec)
|
|
51
46
|
{
|
|
52
47
|
VALUE timeout = Qnil;
|
|
53
48
|
rb_check_arity(argc, 0, 1);
|
|
54
49
|
if (!argc || NIL_P(timeout = argv[0])) {
|
|
55
|
-
|
|
50
|
+
return NULL;
|
|
56
51
|
}
|
|
57
52
|
else {
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
*timerec = rb_time_interval(timeout);
|
|
54
|
+
return timerec;
|
|
60
55
|
}
|
|
61
56
|
}
|
|
62
57
|
|
|
@@ -65,7 +60,7 @@ wait_for_single_fd(rb_io_t *fptr, int events, struct timeval *tv)
|
|
|
65
60
|
{
|
|
66
61
|
int i = rb_wait_for_single_fd(fptr->fd, events, tv);
|
|
67
62
|
if (i < 0)
|
|
68
|
-
|
|
63
|
+
rb_sys_fail(0);
|
|
69
64
|
rb_io_check_closed(fptr);
|
|
70
65
|
return (i & events);
|
|
71
66
|
}
|
|
@@ -92,29 +87,39 @@ io_nread(VALUE io)
|
|
|
92
87
|
rb_io_check_readable(fptr);
|
|
93
88
|
len = rb_io_read_pending(fptr);
|
|
94
89
|
if (len > 0) return INT2FIX(len);
|
|
95
|
-
|
|
96
|
-
|
|
90
|
+
|
|
91
|
+
#ifdef HAVE_RB_IO_DESCRIPTOR
|
|
92
|
+
int fd = rb_io_descriptor(io);
|
|
93
|
+
#else
|
|
94
|
+
int fd = fptr->fd;
|
|
95
|
+
#endif
|
|
96
|
+
|
|
97
|
+
if (!FIONREAD_POSSIBLE_P(fd)) return INT2FIX(0);
|
|
98
|
+
if (ioctl(fd, FIONREAD, &n)) return INT2FIX(0);
|
|
97
99
|
if (n > 0) return ioctl_arg2num(n);
|
|
98
100
|
return INT2FIX(0);
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
#ifdef HAVE_RB_IO_WAIT
|
|
102
104
|
static VALUE
|
|
103
|
-
io_wait_event(VALUE io, int event, VALUE timeout)
|
|
105
|
+
io_wait_event(VALUE io, int event, VALUE timeout, int return_io)
|
|
104
106
|
{
|
|
105
107
|
VALUE result = rb_io_wait(io, RB_INT2NUM(event), timeout);
|
|
106
108
|
|
|
107
109
|
if (!RB_TEST(result)) {
|
|
108
|
-
|
|
110
|
+
return Qnil;
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
int mask = RB_NUM2INT(result);
|
|
112
114
|
|
|
113
115
|
if (mask & event) {
|
|
114
|
-
|
|
116
|
+
if (return_io)
|
|
117
|
+
return io;
|
|
118
|
+
else
|
|
119
|
+
return result;
|
|
115
120
|
}
|
|
116
121
|
else {
|
|
117
|
-
|
|
122
|
+
return Qfalse;
|
|
118
123
|
}
|
|
119
124
|
}
|
|
120
125
|
#endif
|
|
@@ -142,15 +147,15 @@ io_ready_p(VALUE io)
|
|
|
142
147
|
if (rb_io_read_pending(fptr)) return Qtrue;
|
|
143
148
|
|
|
144
149
|
#ifndef HAVE_RB_IO_WAIT
|
|
145
|
-
|
|
146
|
-
return Qtrue;
|
|
150
|
+
return wait_for_single_fd(fptr, RB_WAITFD_IN, &tv) ? Qtrue : Qfalse;
|
|
147
151
|
#else
|
|
148
|
-
|
|
149
|
-
return Qtrue;
|
|
152
|
+
return io_wait_event(io, RUBY_IO_READABLE, RB_INT2NUM(0), 1);
|
|
150
153
|
#endif
|
|
151
|
-
return Qfalse;
|
|
152
154
|
}
|
|
153
155
|
|
|
156
|
+
/* Ruby 3.2+ can define these methods. This macro indicates that case. */
|
|
157
|
+
#ifndef RUBY_IO_WAIT_METHODS
|
|
158
|
+
|
|
154
159
|
/*
|
|
155
160
|
* call-seq:
|
|
156
161
|
* io.wait_readable -> truthy or falsy
|
|
@@ -182,14 +187,14 @@ io_wait_readable(int argc, VALUE *argv, VALUE io)
|
|
|
182
187
|
|
|
183
188
|
#ifndef HAVE_RB_IO_WAIT
|
|
184
189
|
if (wait_for_single_fd(fptr, RB_WAITFD_IN, tv)) {
|
|
185
|
-
|
|
190
|
+
return io;
|
|
186
191
|
}
|
|
187
192
|
return Qnil;
|
|
188
193
|
#else
|
|
189
194
|
rb_check_arity(argc, 0, 1);
|
|
190
195
|
VALUE timeout = (argc == 1 ? argv[0] : Qnil);
|
|
191
196
|
|
|
192
|
-
return io_wait_event(io, RUBY_IO_READABLE, timeout);
|
|
197
|
+
return io_wait_event(io, RUBY_IO_READABLE, timeout, 1);
|
|
193
198
|
#endif
|
|
194
199
|
}
|
|
195
200
|
|
|
@@ -218,14 +223,14 @@ io_wait_writable(int argc, VALUE *argv, VALUE io)
|
|
|
218
223
|
#ifndef HAVE_RB_IO_WAIT
|
|
219
224
|
tv = get_timeout(argc, argv, &timerec);
|
|
220
225
|
if (wait_for_single_fd(fptr, RB_WAITFD_OUT, tv)) {
|
|
221
|
-
|
|
226
|
+
return io;
|
|
222
227
|
}
|
|
223
228
|
return Qnil;
|
|
224
229
|
#else
|
|
225
230
|
rb_check_arity(argc, 0, 1);
|
|
226
231
|
VALUE timeout = (argc == 1 ? argv[0] : Qnil);
|
|
227
232
|
|
|
228
|
-
return io_wait_event(io, RUBY_IO_WRITABLE, timeout);
|
|
233
|
+
return io_wait_event(io, RUBY_IO_WRITABLE, timeout, 1);
|
|
229
234
|
#endif
|
|
230
235
|
}
|
|
231
236
|
|
|
@@ -236,7 +241,8 @@ io_wait_writable(int argc, VALUE *argv, VALUE io)
|
|
|
236
241
|
* io.wait_priority(timeout) -> truthy or falsy
|
|
237
242
|
*
|
|
238
243
|
* Waits until IO is priority and returns a truthy value or a falsy
|
|
239
|
-
* value when times out.
|
|
244
|
+
* value when times out. Priority data is sent and received using
|
|
245
|
+
* the Socket::MSG_OOB flag and is typically limited to streams.
|
|
240
246
|
*
|
|
241
247
|
* You must require 'io/wait' to use this method.
|
|
242
248
|
*/
|
|
@@ -253,7 +259,7 @@ io_wait_priority(int argc, VALUE *argv, VALUE io)
|
|
|
253
259
|
rb_check_arity(argc, 0, 1);
|
|
254
260
|
VALUE timeout = argc == 1 ? argv[0] : Qnil;
|
|
255
261
|
|
|
256
|
-
return io_wait_event(io, RUBY_IO_PRIORITY, timeout);
|
|
262
|
+
return io_wait_event(io, RUBY_IO_PRIORITY, timeout, 1);
|
|
257
263
|
}
|
|
258
264
|
#endif
|
|
259
265
|
|
|
@@ -261,40 +267,52 @@ static int
|
|
|
261
267
|
wait_mode_sym(VALUE mode)
|
|
262
268
|
{
|
|
263
269
|
if (mode == ID2SYM(rb_intern("r"))) {
|
|
264
|
-
|
|
270
|
+
return RB_WAITFD_IN;
|
|
265
271
|
}
|
|
266
272
|
if (mode == ID2SYM(rb_intern("read"))) {
|
|
267
|
-
|
|
273
|
+
return RB_WAITFD_IN;
|
|
268
274
|
}
|
|
269
275
|
if (mode == ID2SYM(rb_intern("readable"))) {
|
|
270
|
-
|
|
276
|
+
return RB_WAITFD_IN;
|
|
271
277
|
}
|
|
272
278
|
if (mode == ID2SYM(rb_intern("w"))) {
|
|
273
|
-
|
|
279
|
+
return RB_WAITFD_OUT;
|
|
274
280
|
}
|
|
275
281
|
if (mode == ID2SYM(rb_intern("write"))) {
|
|
276
|
-
|
|
282
|
+
return RB_WAITFD_OUT;
|
|
277
283
|
}
|
|
278
284
|
if (mode == ID2SYM(rb_intern("writable"))) {
|
|
279
|
-
|
|
285
|
+
return RB_WAITFD_OUT;
|
|
280
286
|
}
|
|
281
287
|
if (mode == ID2SYM(rb_intern("rw"))) {
|
|
282
|
-
|
|
288
|
+
return RB_WAITFD_IN|RB_WAITFD_OUT;
|
|
283
289
|
}
|
|
284
290
|
if (mode == ID2SYM(rb_intern("read_write"))) {
|
|
285
|
-
|
|
291
|
+
return RB_WAITFD_IN|RB_WAITFD_OUT;
|
|
286
292
|
}
|
|
287
293
|
if (mode == ID2SYM(rb_intern("readable_writable"))) {
|
|
288
|
-
|
|
294
|
+
return RB_WAITFD_IN|RB_WAITFD_OUT;
|
|
289
295
|
}
|
|
290
296
|
rb_raise(rb_eArgError, "unsupported mode: %"PRIsVALUE, mode);
|
|
291
297
|
return 0;
|
|
292
298
|
}
|
|
293
299
|
|
|
300
|
+
#ifdef HAVE_RB_IO_WAIT
|
|
301
|
+
static inline rb_io_event_t
|
|
302
|
+
io_event_from_value(VALUE value)
|
|
303
|
+
{
|
|
304
|
+
int events = RB_NUM2INT(value);
|
|
305
|
+
|
|
306
|
+
if (events <= 0) rb_raise(rb_eArgError, "Events must be positive integer!");
|
|
307
|
+
|
|
308
|
+
return events;
|
|
309
|
+
}
|
|
310
|
+
#endif
|
|
311
|
+
|
|
294
312
|
/*
|
|
295
313
|
* call-seq:
|
|
296
|
-
* io.wait(events, timeout) ->
|
|
297
|
-
* io.wait(timeout = nil, mode = :read) ->
|
|
314
|
+
* io.wait(events, timeout) -> event mask, false or nil
|
|
315
|
+
* io.wait(timeout = nil, mode = :read) -> self, true, or false
|
|
298
316
|
*
|
|
299
317
|
* Waits until the IO becomes ready for the specified events and returns the
|
|
300
318
|
* subset of events that become ready, or a falsy value when times out.
|
|
@@ -322,61 +340,77 @@ io_wait(int argc, VALUE *argv, VALUE io)
|
|
|
322
340
|
|
|
323
341
|
GetOpenFile(io, fptr);
|
|
324
342
|
for (i = 0; i < argc; ++i) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
343
|
+
if (SYMBOL_P(argv[i])) {
|
|
344
|
+
event |= wait_mode_sym(argv[i]);
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
*(tv = &timerec) = rb_time_interval(argv[i]);
|
|
348
|
+
}
|
|
331
349
|
}
|
|
332
350
|
/* rb_time_interval() and might_mode() might convert the argument */
|
|
333
351
|
rb_io_check_closed(fptr);
|
|
334
352
|
if (!event) event = RB_WAITFD_IN;
|
|
335
353
|
if ((event & RB_WAITFD_IN) && rb_io_read_pending(fptr))
|
|
336
|
-
|
|
354
|
+
return Qtrue;
|
|
337
355
|
if (wait_for_single_fd(fptr, event, tv))
|
|
338
|
-
|
|
356
|
+
return io;
|
|
339
357
|
return Qnil;
|
|
340
358
|
#else
|
|
341
359
|
VALUE timeout = Qundef;
|
|
342
360
|
rb_io_event_t events = 0;
|
|
361
|
+
int i, return_io = 0;
|
|
343
362
|
|
|
363
|
+
/* The documented signature for this method is actually incorrect.
|
|
364
|
+
* A single timeout is allowed in any position, and multiple symbols can be given.
|
|
365
|
+
* Whether this is intentional or not, I don't know, and as such I consider this to
|
|
366
|
+
* be a legacy/slow path. */
|
|
344
367
|
if (argc != 2 || (RB_SYMBOL_P(argv[0]) || RB_SYMBOL_P(argv[1]))) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
368
|
+
/* We'd prefer to return the actual mask, but this form would return the io itself: */
|
|
369
|
+
return_io = 1;
|
|
370
|
+
|
|
371
|
+
/* Slow/messy path: */
|
|
372
|
+
for (i = 0; i < argc; i += 1) {
|
|
373
|
+
if (RB_SYMBOL_P(argv[i])) {
|
|
374
|
+
events |= wait_mode_sym(argv[i]);
|
|
375
|
+
}
|
|
376
|
+
else if (timeout == Qundef) {
|
|
377
|
+
rb_time_interval(timeout = argv[i]);
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
rb_raise(rb_eArgError, "timeout given more than once");
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (timeout == Qundef) timeout = Qnil;
|
|
385
|
+
|
|
386
|
+
if (events == 0) {
|
|
387
|
+
events = RUBY_IO_READABLE;
|
|
388
|
+
}
|
|
357
389
|
}
|
|
358
|
-
else /* argc == 2 */ {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
if (events == 0) {
|
|
364
|
-
events = RUBY_IO_READABLE;
|
|
390
|
+
else /* argc == 2 and neither are symbols */ {
|
|
391
|
+
/* This is the fast path: */
|
|
392
|
+
events = io_event_from_value(argv[0]);
|
|
393
|
+
timeout = argv[1];
|
|
365
394
|
}
|
|
366
395
|
|
|
367
396
|
if (events & RUBY_IO_READABLE) {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
397
|
+
rb_io_t *fptr = NULL;
|
|
398
|
+
RB_IO_POINTER(io, fptr);
|
|
399
|
+
|
|
400
|
+
if (rb_io_read_pending(fptr)) {
|
|
401
|
+
/* This was the original behaviour: */
|
|
402
|
+
if (return_io) return Qtrue;
|
|
403
|
+
/* New behaviour always returns an event mask: */
|
|
404
|
+
else return RB_INT2NUM(RUBY_IO_READABLE);
|
|
405
|
+
}
|
|
374
406
|
}
|
|
375
407
|
|
|
376
|
-
return io_wait_event(io, events, timeout);
|
|
408
|
+
return io_wait_event(io, events, timeout, return_io);
|
|
377
409
|
#endif
|
|
378
410
|
}
|
|
379
411
|
|
|
412
|
+
#endif /* RUBY_IO_WAIT_METHODS */
|
|
413
|
+
|
|
380
414
|
/*
|
|
381
415
|
* IO wait methods
|
|
382
416
|
*/
|
|
@@ -391,6 +425,7 @@ Init_wait(void)
|
|
|
391
425
|
rb_define_method(rb_cIO, "nread", io_nread, 0);
|
|
392
426
|
rb_define_method(rb_cIO, "ready?", io_ready_p, 0);
|
|
393
427
|
|
|
428
|
+
#ifndef RUBY_IO_WAIT_METHODS
|
|
394
429
|
rb_define_method(rb_cIO, "wait", io_wait, -1);
|
|
395
430
|
|
|
396
431
|
rb_define_method(rb_cIO, "wait_readable", io_wait_readable, -1);
|
|
@@ -398,4 +433,5 @@ Init_wait(void)
|
|
|
398
433
|
#ifdef HAVE_RB_IO_WAIT
|
|
399
434
|
rb_define_method(rb_cIO, "wait_priority", io_wait_priority, -1);
|
|
400
435
|
#endif
|
|
436
|
+
#endif
|
|
401
437
|
}
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: io-wait
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nobu Nakada
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: exe
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2023-12-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies: []
|
|
14
14
|
description: Waits until IO is readable or writable without blocking.
|
|
15
15
|
email:
|
|
@@ -48,7 +48,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
48
48
|
- !ruby/object:Gem::Version
|
|
49
49
|
version: '0'
|
|
50
50
|
requirements: []
|
|
51
|
-
rubygems_version: 3.
|
|
51
|
+
rubygems_version: 3.5.0.dev
|
|
52
52
|
signing_key:
|
|
53
53
|
specification_version: 4
|
|
54
54
|
summary: Waits until IO is readable or writable without blocking.
|