io-wait 0.2.3 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|