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