io-wait 0.2.3 → 0.3.0
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/ext/io/wait/wait.c +98 -69
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 630936f8af6e2cf9265ebff0794cab1daf10048933460b71306486aecb92a85a
|
4
|
+
data.tar.gz: 153bc0301fdb8fce6f4983d45879364509bb6534a81775d98e5f61b5ffe1923e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07e0a9997d9e8dd84368feb0fdcd681282d7c583aea8d03d90abf031d6474224aa7a6f61050de11a03750cc0e20ba5759ac4eca28aae07891a778ef82cef24c6
|
7
|
+
data.tar.gz: 7294e823b4536cded39faead19916b437e4a8a4d398e35917c81e84d4618d5f99bd414aa9f6989cfad4bfb8bf0721fb7934b083a72576a7e95a60d7fcf35e853
|
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
|
}
|
@@ -100,21 +95,24 @@ io_nread(VALUE io)
|
|
100
95
|
|
101
96
|
#ifdef HAVE_RB_IO_WAIT
|
102
97
|
static VALUE
|
103
|
-
io_wait_event(VALUE io, int event, VALUE timeout)
|
98
|
+
io_wait_event(VALUE io, int event, VALUE timeout, int return_io)
|
104
99
|
{
|
105
100
|
VALUE result = rb_io_wait(io, RB_INT2NUM(event), timeout);
|
106
101
|
|
107
102
|
if (!RB_TEST(result)) {
|
108
|
-
|
103
|
+
return Qnil;
|
109
104
|
}
|
110
105
|
|
111
106
|
int mask = RB_NUM2INT(result);
|
112
107
|
|
113
108
|
if (mask & event) {
|
114
|
-
|
109
|
+
if (return_io)
|
110
|
+
return io;
|
111
|
+
else
|
112
|
+
return result;
|
115
113
|
}
|
116
114
|
else {
|
117
|
-
|
115
|
+
return Qfalse;
|
118
116
|
}
|
119
117
|
}
|
120
118
|
#endif
|
@@ -142,15 +140,15 @@ io_ready_p(VALUE io)
|
|
142
140
|
if (rb_io_read_pending(fptr)) return Qtrue;
|
143
141
|
|
144
142
|
#ifndef HAVE_RB_IO_WAIT
|
145
|
-
|
146
|
-
return Qtrue;
|
143
|
+
return wait_for_single_fd(fptr, RB_WAITFD_IN, &tv) ? Qtrue : Qfalse;
|
147
144
|
#else
|
148
|
-
|
149
|
-
return Qtrue;
|
145
|
+
return io_wait_event(io, RUBY_IO_READABLE, RB_INT2NUM(0), 1);
|
150
146
|
#endif
|
151
|
-
return Qfalse;
|
152
147
|
}
|
153
148
|
|
149
|
+
/* Ruby 3.2+ can define these methods. This macro indicates that case. */
|
150
|
+
#ifndef RUBY_IO_WAIT_METHODS
|
151
|
+
|
154
152
|
/*
|
155
153
|
* call-seq:
|
156
154
|
* io.wait_readable -> truthy or falsy
|
@@ -182,14 +180,14 @@ io_wait_readable(int argc, VALUE *argv, VALUE io)
|
|
182
180
|
|
183
181
|
#ifndef HAVE_RB_IO_WAIT
|
184
182
|
if (wait_for_single_fd(fptr, RB_WAITFD_IN, tv)) {
|
185
|
-
|
183
|
+
return io;
|
186
184
|
}
|
187
185
|
return Qnil;
|
188
186
|
#else
|
189
187
|
rb_check_arity(argc, 0, 1);
|
190
188
|
VALUE timeout = (argc == 1 ? argv[0] : Qnil);
|
191
189
|
|
192
|
-
return io_wait_event(io, RUBY_IO_READABLE, timeout);
|
190
|
+
return io_wait_event(io, RUBY_IO_READABLE, timeout, 1);
|
193
191
|
#endif
|
194
192
|
}
|
195
193
|
|
@@ -218,14 +216,14 @@ io_wait_writable(int argc, VALUE *argv, VALUE io)
|
|
218
216
|
#ifndef HAVE_RB_IO_WAIT
|
219
217
|
tv = get_timeout(argc, argv, &timerec);
|
220
218
|
if (wait_for_single_fd(fptr, RB_WAITFD_OUT, tv)) {
|
221
|
-
|
219
|
+
return io;
|
222
220
|
}
|
223
221
|
return Qnil;
|
224
222
|
#else
|
225
223
|
rb_check_arity(argc, 0, 1);
|
226
224
|
VALUE timeout = (argc == 1 ? argv[0] : Qnil);
|
227
225
|
|
228
|
-
return io_wait_event(io, RUBY_IO_WRITABLE, timeout);
|
226
|
+
return io_wait_event(io, RUBY_IO_WRITABLE, timeout, 1);
|
229
227
|
#endif
|
230
228
|
}
|
231
229
|
|
@@ -236,7 +234,8 @@ io_wait_writable(int argc, VALUE *argv, VALUE io)
|
|
236
234
|
* io.wait_priority(timeout) -> truthy or falsy
|
237
235
|
*
|
238
236
|
* Waits until IO is priority and returns a truthy value or a falsy
|
239
|
-
* value when times out.
|
237
|
+
* value when times out. Priority data is sent and received using
|
238
|
+
* the Socket::MSG_OOB flag and is typically limited to streams.
|
240
239
|
*
|
241
240
|
* You must require 'io/wait' to use this method.
|
242
241
|
*/
|
@@ -253,7 +252,7 @@ io_wait_priority(int argc, VALUE *argv, VALUE io)
|
|
253
252
|
rb_check_arity(argc, 0, 1);
|
254
253
|
VALUE timeout = argc == 1 ? argv[0] : Qnil;
|
255
254
|
|
256
|
-
return io_wait_event(io, RUBY_IO_PRIORITY, timeout);
|
255
|
+
return io_wait_event(io, RUBY_IO_PRIORITY, timeout, 1);
|
257
256
|
}
|
258
257
|
#endif
|
259
258
|
|
@@ -261,40 +260,52 @@ static int
|
|
261
260
|
wait_mode_sym(VALUE mode)
|
262
261
|
{
|
263
262
|
if (mode == ID2SYM(rb_intern("r"))) {
|
264
|
-
|
263
|
+
return RB_WAITFD_IN;
|
265
264
|
}
|
266
265
|
if (mode == ID2SYM(rb_intern("read"))) {
|
267
|
-
|
266
|
+
return RB_WAITFD_IN;
|
268
267
|
}
|
269
268
|
if (mode == ID2SYM(rb_intern("readable"))) {
|
270
|
-
|
269
|
+
return RB_WAITFD_IN;
|
271
270
|
}
|
272
271
|
if (mode == ID2SYM(rb_intern("w"))) {
|
273
|
-
|
272
|
+
return RB_WAITFD_OUT;
|
274
273
|
}
|
275
274
|
if (mode == ID2SYM(rb_intern("write"))) {
|
276
|
-
|
275
|
+
return RB_WAITFD_OUT;
|
277
276
|
}
|
278
277
|
if (mode == ID2SYM(rb_intern("writable"))) {
|
279
|
-
|
278
|
+
return RB_WAITFD_OUT;
|
280
279
|
}
|
281
280
|
if (mode == ID2SYM(rb_intern("rw"))) {
|
282
|
-
|
281
|
+
return RB_WAITFD_IN|RB_WAITFD_OUT;
|
283
282
|
}
|
284
283
|
if (mode == ID2SYM(rb_intern("read_write"))) {
|
285
|
-
|
284
|
+
return RB_WAITFD_IN|RB_WAITFD_OUT;
|
286
285
|
}
|
287
286
|
if (mode == ID2SYM(rb_intern("readable_writable"))) {
|
288
|
-
|
287
|
+
return RB_WAITFD_IN|RB_WAITFD_OUT;
|
289
288
|
}
|
290
289
|
rb_raise(rb_eArgError, "unsupported mode: %"PRIsVALUE, mode);
|
291
290
|
return 0;
|
292
291
|
}
|
293
292
|
|
293
|
+
#ifdef HAVE_RB_IO_WAIT
|
294
|
+
static inline rb_io_event_t
|
295
|
+
io_event_from_value(VALUE value)
|
296
|
+
{
|
297
|
+
int events = RB_NUM2INT(value);
|
298
|
+
|
299
|
+
if (events <= 0) rb_raise(rb_eArgError, "Events must be positive integer!");
|
300
|
+
|
301
|
+
return events;
|
302
|
+
}
|
303
|
+
#endif
|
304
|
+
|
294
305
|
/*
|
295
306
|
* call-seq:
|
296
|
-
* io.wait(events, timeout) ->
|
297
|
-
* io.wait(timeout = nil, mode = :read) ->
|
307
|
+
* io.wait(events, timeout) -> event mask, false or nil
|
308
|
+
* io.wait(timeout = nil, mode = :read) -> self, true, or false
|
298
309
|
*
|
299
310
|
* Waits until the IO becomes ready for the specified events and returns the
|
300
311
|
* subset of events that become ready, or a falsy value when times out.
|
@@ -322,61 +333,77 @@ io_wait(int argc, VALUE *argv, VALUE io)
|
|
322
333
|
|
323
334
|
GetOpenFile(io, fptr);
|
324
335
|
for (i = 0; i < argc; ++i) {
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
336
|
+
if (SYMBOL_P(argv[i])) {
|
337
|
+
event |= wait_mode_sym(argv[i]);
|
338
|
+
}
|
339
|
+
else {
|
340
|
+
*(tv = &timerec) = rb_time_interval(argv[i]);
|
341
|
+
}
|
331
342
|
}
|
332
343
|
/* rb_time_interval() and might_mode() might convert the argument */
|
333
344
|
rb_io_check_closed(fptr);
|
334
345
|
if (!event) event = RB_WAITFD_IN;
|
335
346
|
if ((event & RB_WAITFD_IN) && rb_io_read_pending(fptr))
|
336
|
-
|
347
|
+
return Qtrue;
|
337
348
|
if (wait_for_single_fd(fptr, event, tv))
|
338
|
-
|
349
|
+
return io;
|
339
350
|
return Qnil;
|
340
351
|
#else
|
341
352
|
VALUE timeout = Qundef;
|
342
353
|
rb_io_event_t events = 0;
|
354
|
+
int i, return_io = 0;
|
343
355
|
|
356
|
+
/* The documented signature for this method is actually incorrect.
|
357
|
+
* A single timeout is allowed in any position, and multiple symbols can be given.
|
358
|
+
* Whether this is intentional or not, I don't know, and as such I consider this to
|
359
|
+
* be a legacy/slow path. */
|
344
360
|
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
|
-
|
361
|
+
/* We'd prefer to return the actual mask, but this form would return the io itself: */
|
362
|
+
return_io = 1;
|
363
|
+
|
364
|
+
/* Slow/messy path: */
|
365
|
+
for (i = 0; i < argc; i += 1) {
|
366
|
+
if (RB_SYMBOL_P(argv[i])) {
|
367
|
+
events |= wait_mode_sym(argv[i]);
|
368
|
+
}
|
369
|
+
else if (timeout == Qundef) {
|
370
|
+
rb_time_interval(timeout = argv[i]);
|
371
|
+
}
|
372
|
+
else {
|
373
|
+
rb_raise(rb_eArgError, "timeout given more than once");
|
374
|
+
}
|
375
|
+
}
|
376
|
+
|
377
|
+
if (timeout == Qundef) timeout = Qnil;
|
378
|
+
|
379
|
+
if (events == 0) {
|
380
|
+
events = RUBY_IO_READABLE;
|
381
|
+
}
|
357
382
|
}
|
358
|
-
else /* argc == 2 */ {
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
if (events == 0) {
|
364
|
-
events = RUBY_IO_READABLE;
|
383
|
+
else /* argc == 2 and neither are symbols */ {
|
384
|
+
/* This is the fast path: */
|
385
|
+
events = io_event_from_value(argv[0]);
|
386
|
+
timeout = argv[1];
|
365
387
|
}
|
366
388
|
|
367
389
|
if (events & RUBY_IO_READABLE) {
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
390
|
+
rb_io_t *fptr = NULL;
|
391
|
+
RB_IO_POINTER(io, fptr);
|
392
|
+
|
393
|
+
if (rb_io_read_pending(fptr)) {
|
394
|
+
/* This was the original behaviour: */
|
395
|
+
if (return_io) return Qtrue;
|
396
|
+
/* New behaviour always returns an event mask: */
|
397
|
+
else return RB_INT2NUM(RUBY_IO_READABLE);
|
398
|
+
}
|
374
399
|
}
|
375
400
|
|
376
|
-
return io_wait_event(io, events, timeout);
|
401
|
+
return io_wait_event(io, events, timeout, return_io);
|
377
402
|
#endif
|
378
403
|
}
|
379
404
|
|
405
|
+
#endif /* RUBY_IO_WAIT_METHODS */
|
406
|
+
|
380
407
|
/*
|
381
408
|
* IO wait methods
|
382
409
|
*/
|
@@ -391,6 +418,7 @@ Init_wait(void)
|
|
391
418
|
rb_define_method(rb_cIO, "nread", io_nread, 0);
|
392
419
|
rb_define_method(rb_cIO, "ready?", io_ready_p, 0);
|
393
420
|
|
421
|
+
#ifndef RUBY_IO_WAIT_METHODS
|
394
422
|
rb_define_method(rb_cIO, "wait", io_wait, -1);
|
395
423
|
|
396
424
|
rb_define_method(rb_cIO, "wait_readable", io_wait_readable, -1);
|
@@ -398,4 +426,5 @@ Init_wait(void)
|
|
398
426
|
#ifdef HAVE_RB_IO_WAIT
|
399
427
|
rb_define_method(rb_cIO, "wait_priority", io_wait_priority, -1);
|
400
428
|
#endif
|
429
|
+
#endif
|
401
430
|
}
|
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.0
|
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: 2022-
|
12
|
+
date: 2022-12-16 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Waits until IO is readable or writable without blocking.
|
15
15
|
email:
|