sleepy_penguin 1.4.0 → 2.0.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.
- data/.document +3 -0
- data/.manifest +8 -2
- data/ChangeLog +295 -0
- data/GIT-VERSION-FILE +1 -1
- data/GIT-VERSION-GEN +1 -1
- data/LATEST +19 -5
- data/LICENSE +2 -2
- data/NEWS +22 -0
- data/README +4 -4
- data/TODO +0 -2
- data/ext/sleepy_penguin/epoll.c +165 -88
- data/ext/sleepy_penguin/eventfd.c +89 -91
- data/ext/sleepy_penguin/extconf.rb +1 -0
- data/ext/sleepy_penguin/init.c +7 -0
- data/ext/sleepy_penguin/inotify.c +229 -91
- data/ext/sleepy_penguin/missing_epoll.h +30 -0
- data/ext/sleepy_penguin/missing_inotify.h +57 -0
- data/ext/sleepy_penguin/signalfd.c +335 -0
- data/ext/sleepy_penguin/sleepy_penguin.h +15 -55
- data/ext/sleepy_penguin/timerfd.c +78 -36
- data/ext/sleepy_penguin/util.c +149 -0
- data/lib/sleepy_penguin.rb +0 -6
- data/lib/sleepy_penguin/signalfd/sig_info.rb +20 -0
- data/lib/sleepy_penguin/sp.rb +4 -0
- data/pkg.mk +5 -4
- data/test/test_epoll.rb +29 -0
- data/test/test_epoll_gc.rb +1 -1
- data/test/test_epoll_optimizations.rb +5 -2
- data/test/test_eventfd.rb +24 -6
- data/test/test_inotify.rb +80 -1
- data/test/test_signalfd.rb +94 -0
- data/test/test_signalfd_siginfo.rb +32 -0
- data/test/test_timerfd.rb +34 -4
- metadata +22 -10
- data/ext/sleepy_penguin/nonblock.h +0 -19
- data/script/isolate_for_tests +0 -30
data/ext/sleepy_penguin/epoll.c
CHANGED
@@ -1,16 +1,13 @@
|
|
1
1
|
#include "sleepy_penguin.h"
|
2
2
|
#include <sys/epoll.h>
|
3
3
|
#include <pthread.h>
|
4
|
+
#include "missing_epoll.h"
|
4
5
|
#ifdef HAVE_RUBY_ST_H
|
5
6
|
# include <ruby/st.h>
|
6
7
|
#else
|
7
8
|
# include <st.h>
|
8
9
|
#endif
|
9
10
|
|
10
|
-
#ifndef EPOLL_CLOEXEC
|
11
|
-
# define EPOLL_CLOEXEC (int)(02000000)
|
12
|
-
#endif
|
13
|
-
|
14
11
|
#define EP_RECREATE (-2)
|
15
12
|
|
16
13
|
static st_table *active;
|
@@ -49,33 +46,6 @@ static struct rb_epoll *ep_get(VALUE self)
|
|
49
46
|
return ep;
|
50
47
|
}
|
51
48
|
|
52
|
-
#ifndef HAVE_EPOLL_CREATE1
|
53
|
-
/*
|
54
|
-
* fake epoll_create1() since some systems don't have it.
|
55
|
-
* Don't worry about thread-safety since current Ruby 1.9 won't
|
56
|
-
* call this without GVL.
|
57
|
-
*/
|
58
|
-
static int my_epoll_create1(int flags)
|
59
|
-
{
|
60
|
-
int fd = epoll_create(1024); /* size ignored since 2.6.8 */
|
61
|
-
|
62
|
-
if (fd < 0 || flags == 0)
|
63
|
-
return fd;
|
64
|
-
|
65
|
-
if ((flags & EPOLL_CLOEXEC) && (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1))
|
66
|
-
goto err;
|
67
|
-
return fd;
|
68
|
-
err:
|
69
|
-
{
|
70
|
-
int saved_errno = errno;
|
71
|
-
close(fd);
|
72
|
-
errno = saved_errno;
|
73
|
-
return -1;
|
74
|
-
}
|
75
|
-
}
|
76
|
-
#define epoll_create1 my_epoll_create1
|
77
|
-
#endif
|
78
|
-
|
79
49
|
static void gcmark(void *ptr)
|
80
50
|
{
|
81
51
|
struct rb_epoll *ep = ptr;
|
@@ -149,31 +119,19 @@ static void ep_check(struct rb_epoll *ep)
|
|
149
119
|
}
|
150
120
|
|
151
121
|
/*
|
152
|
-
*
|
153
|
-
*
|
154
|
-
*
|
155
|
-
*
|
122
|
+
* call-seq:
|
123
|
+
* SleepyPenguin::Epoll.new([flags]) -> Epoll object
|
124
|
+
*
|
125
|
+
* Creates a new Epoll object with an optional +flags+ argument.
|
126
|
+
* +flags+ may currently be +:CLOEXEC+ or +0+ (or +nil+).
|
156
127
|
*/
|
157
128
|
static VALUE init(int argc, VALUE *argv, VALUE self)
|
158
129
|
{
|
159
|
-
int flags;
|
160
130
|
struct rb_epoll *ep = ep_get(self);
|
161
131
|
VALUE fl;
|
162
132
|
|
163
133
|
rb_scan_args(argc, argv, "01", &fl);
|
164
|
-
|
165
|
-
flags = 0;
|
166
|
-
} else {
|
167
|
-
switch (TYPE(fl)) {
|
168
|
-
case T_FIXNUM:
|
169
|
-
case T_BIGNUM:
|
170
|
-
flags = NUM2INT(fl);
|
171
|
-
break;
|
172
|
-
default:
|
173
|
-
rb_raise(rb_eArgError, "flags must be an integer");
|
174
|
-
}
|
175
|
-
}
|
176
|
-
ep->flags = flags;
|
134
|
+
ep->flags = rb_sp_get_flags(self, fl);
|
177
135
|
my_epoll_create(ep);
|
178
136
|
|
179
137
|
return self;
|
@@ -183,11 +141,11 @@ static VALUE ctl(VALUE self, VALUE io, VALUE flags, int op)
|
|
183
141
|
{
|
184
142
|
struct epoll_event event;
|
185
143
|
struct rb_epoll *ep = ep_get(self);
|
186
|
-
int fd =
|
144
|
+
int fd = rb_sp_fileno(io);
|
187
145
|
int rv;
|
188
146
|
|
189
147
|
ep_check(ep);
|
190
|
-
event.events =
|
148
|
+
event.events = rb_sp_get_uflags(self, flags);
|
191
149
|
pack_event_data(&event, io);
|
192
150
|
|
193
151
|
rv = epoll_ctl(ep->fd, op, fd, &event);
|
@@ -204,6 +162,7 @@ static VALUE ctl(VALUE self, VALUE io, VALUE flags, int op)
|
|
204
162
|
rb_ary_store(ep->marks, fd, io);
|
205
163
|
/* fall-through */
|
206
164
|
case EPOLL_CTL_MOD:
|
165
|
+
flags = UINT2NUM(event.events);
|
207
166
|
rb_ary_store(ep->flag_cache, fd, flags);
|
208
167
|
break;
|
209
168
|
case EPOLL_CTL_DEL:
|
@@ -215,19 +174,30 @@ static VALUE ctl(VALUE self, VALUE io, VALUE flags, int op)
|
|
215
174
|
}
|
216
175
|
|
217
176
|
/*
|
218
|
-
*
|
219
|
-
*
|
177
|
+
* call-seq:
|
178
|
+
* ep.set(io, flags) -> 0
|
179
|
+
*
|
180
|
+
* Used to avoid exceptions when your app is too lazy to check
|
181
|
+
* what state a descriptor is in, this sets the epoll descriptor
|
182
|
+
* to watch an +io+ with the given +flags+
|
183
|
+
*
|
184
|
+
* +flags+ may be an array of symbols or an unsigned Integer bit mask:
|
185
|
+
*
|
186
|
+
* - flags = [ :IN, :ET ]
|
187
|
+
* - flags = SleepyPenguin::Epoll::IN | SleepyPenguin::Epoll::ET
|
188
|
+
*
|
189
|
+
* See constants in Epoll for more information.
|
220
190
|
*/
|
221
191
|
static VALUE set(VALUE self, VALUE io, VALUE flags)
|
222
192
|
{
|
223
193
|
struct epoll_event event;
|
224
194
|
struct rb_epoll *ep = ep_get(self);
|
225
|
-
int fd =
|
195
|
+
int fd = rb_sp_fileno(io);
|
226
196
|
int rv;
|
227
197
|
VALUE cur_io = rb_ary_entry(ep->marks, fd);
|
228
198
|
|
229
199
|
ep_check(ep);
|
230
|
-
event.events =
|
200
|
+
event.events = rb_sp_get_uflags(self, flags);
|
231
201
|
pack_event_data(&event, io);
|
232
202
|
|
233
203
|
if (cur_io == io) {
|
@@ -261,30 +231,34 @@ fallback_add:
|
|
261
231
|
}
|
262
232
|
rb_ary_store(ep->marks, fd, io);
|
263
233
|
}
|
234
|
+
flags = UINT2NUM(event.events);
|
264
235
|
rb_ary_store(ep->flag_cache, fd, flags);
|
265
236
|
|
266
237
|
return INT2NUM(rv);
|
267
238
|
}
|
268
239
|
|
269
240
|
/*
|
270
|
-
*
|
271
|
-
*
|
272
|
-
*
|
241
|
+
* call-seq:
|
242
|
+
* epoll.delete(io) -> io or nil
|
243
|
+
*
|
244
|
+
* Stops an +io+ object from being monitored. This is like Epoll#del
|
245
|
+
* but returns +nil+ on ENOENT instead of raising an error. This is
|
246
|
+
* useful for apps that do not care to track the status of an
|
273
247
|
* epoll object itself.
|
274
248
|
*/
|
275
249
|
static VALUE delete(VALUE self, VALUE io)
|
276
250
|
{
|
277
251
|
struct rb_epoll *ep = ep_get(self);
|
278
|
-
int fd =
|
252
|
+
int fd = rb_sp_fileno(io);
|
279
253
|
int rv;
|
280
254
|
VALUE cur_io;
|
281
255
|
|
282
256
|
ep_check(ep);
|
283
|
-
if (
|
257
|
+
if (rb_sp_io_closed(io))
|
284
258
|
goto out;
|
285
259
|
|
286
260
|
cur_io = rb_ary_entry(ep->marks, fd);
|
287
|
-
if (NIL_P(cur_io) ||
|
261
|
+
if (NIL_P(cur_io) || rb_sp_io_closed(cur_io))
|
288
262
|
return Qnil;
|
289
263
|
|
290
264
|
rv = epoll_ctl(ep->fd, EPOLL_CTL_DEL, fd, NULL);
|
@@ -340,7 +314,7 @@ static VALUE nogvl_wait(void *args)
|
|
340
314
|
|
341
315
|
static VALUE real_epwait(struct rb_epoll *ep)
|
342
316
|
{
|
343
|
-
int n = (int)
|
317
|
+
int n = (int)rb_sp_io_region(nogvl_wait, ep);
|
344
318
|
|
345
319
|
return epwait_result(ep, n);
|
346
320
|
}
|
@@ -438,11 +412,14 @@ static VALUE real_epwait(struct rb_epoll *ep)
|
|
438
412
|
#endif /* 1.8 Green thread compatibility code */
|
439
413
|
|
440
414
|
/*
|
441
|
-
*
|
415
|
+
* call-seq:
|
416
|
+
* epoll.wait([maxevents[, timeout]]) { |flags, io| ... }
|
442
417
|
*
|
443
|
-
*
|
444
|
-
*
|
445
|
-
*
|
418
|
+
* Calls epoll_wait(2) and yields Integer +flags+ and IO objects watched
|
419
|
+
* for. +maxevents+ is the maximum number of events to process at once,
|
420
|
+
* lower numbers may prevent starvation when used by dup-ed Epoll objects
|
421
|
+
* in multiple threads. +timeout+ is specified in milliseconds, +nil+
|
422
|
+
* (the default) meaning it will block and wait indefinitely.
|
446
423
|
*/
|
447
424
|
static VALUE epwait(int argc, VALUE *argv, VALUE self)
|
448
425
|
{
|
@@ -464,23 +441,51 @@ static VALUE epwait(int argc, VALUE *argv, VALUE self)
|
|
464
441
|
return real_epwait(ep);
|
465
442
|
}
|
466
443
|
|
467
|
-
/*
|
444
|
+
/*
|
445
|
+
* call-seq:
|
446
|
+
* epoll.add(io, flags) -> 0
|
447
|
+
*
|
448
|
+
* Starts watching a given +io+ object with +flags+ which may be an Integer
|
449
|
+
* bitmask or Array representing arrays to watch for. Consider Epoll#set
|
450
|
+
* instead as it is easier to use.
|
451
|
+
*/
|
468
452
|
static VALUE add(VALUE self, VALUE io, VALUE flags)
|
469
453
|
{
|
470
454
|
return ctl(self, io, flags, EPOLL_CTL_ADD);
|
471
455
|
}
|
472
456
|
|
473
|
-
/*
|
457
|
+
/*
|
458
|
+
* call-seq:
|
459
|
+
* epoll.del(io) -> 0
|
460
|
+
*
|
461
|
+
* Disables an IO object from being watched. Consider Epoll#delete as
|
462
|
+
* it is easier to use.
|
463
|
+
*/
|
474
464
|
static VALUE del(VALUE self, VALUE io)
|
475
465
|
{
|
476
|
-
return ctl(self, io,
|
466
|
+
return ctl(self, io, INT2FIX(0), EPOLL_CTL_DEL);
|
477
467
|
}
|
478
468
|
|
469
|
+
/*
|
470
|
+
* call-seq:
|
471
|
+
* epoll.mod(io, flags) -> 0
|
472
|
+
*
|
473
|
+
* Changes the watch for an existing IO object based on +flags+.
|
474
|
+
* Consider Epoll#set instead as it is easier to use.
|
475
|
+
*/
|
479
476
|
static VALUE mod(VALUE self, VALUE io, VALUE flags)
|
480
477
|
{
|
481
478
|
return ctl(self, io, flags, EPOLL_CTL_MOD);
|
482
479
|
}
|
483
480
|
|
481
|
+
/*
|
482
|
+
* call-seq:
|
483
|
+
* epoll.to_io -> Epoll::IO object
|
484
|
+
*
|
485
|
+
* Used to expose the given Epoll object as an Epoll::IO object for IO.select
|
486
|
+
* or IO#stat. This is unlikely to be useful directly, but is used internally
|
487
|
+
* by IO.select.
|
488
|
+
*/
|
484
489
|
static VALUE to_io(VALUE self)
|
485
490
|
{
|
486
491
|
struct rb_epoll *ep = ep_get(self);
|
@@ -493,6 +498,13 @@ static VALUE to_io(VALUE self)
|
|
493
498
|
return ep->io;
|
494
499
|
}
|
495
500
|
|
501
|
+
/*
|
502
|
+
* call-seq:
|
503
|
+
* epoll.close -> nil
|
504
|
+
*
|
505
|
+
* Closes an existing Epoll object and returns memory back to the kernel.
|
506
|
+
* Raises IOError if object is already closed.
|
507
|
+
*/
|
496
508
|
static VALUE epclose(VALUE self)
|
497
509
|
{
|
498
510
|
struct rb_epoll *ep = ep_get(self);
|
@@ -522,6 +534,12 @@ static VALUE epclose(VALUE self)
|
|
522
534
|
return Qnil;
|
523
535
|
}
|
524
536
|
|
537
|
+
/*
|
538
|
+
* call-seq:
|
539
|
+
* epoll.closed? -> true or false
|
540
|
+
*
|
541
|
+
* Returns whether or not an Epoll object is closed.
|
542
|
+
*/
|
525
543
|
static VALUE epclosed(VALUE self)
|
526
544
|
{
|
527
545
|
struct rb_epoll *ep = ep_get(self);
|
@@ -534,7 +552,7 @@ static int cloexec_dup(struct rb_epoll *ep)
|
|
534
552
|
#ifdef F_DUPFD_CLOEXEC
|
535
553
|
int flags = ep->flags & EPOLL_CLOEXEC ? F_DUPFD_CLOEXEC : F_DUPFD;
|
536
554
|
int fd = fcntl(ep->fd, flags, 0);
|
537
|
-
#else
|
555
|
+
#else /* potentially racy on GVL-free systems: */
|
538
556
|
int fd = dup(ep->fd);
|
539
557
|
if (fd >= 0)
|
540
558
|
(void)fcntl(fd, F_SETFD, FD_CLOEXEC);
|
@@ -542,6 +560,15 @@ static int cloexec_dup(struct rb_epoll *ep)
|
|
542
560
|
return fd;
|
543
561
|
}
|
544
562
|
|
563
|
+
/*
|
564
|
+
* call-seq:
|
565
|
+
* epoll.dup -> another Epoll object
|
566
|
+
*
|
567
|
+
* Duplicates an Epoll object and userspace buffers related to this library.
|
568
|
+
* This allows the same epoll object in the Linux kernel to be safely used
|
569
|
+
* across multiple native threads as long as there is one SleepyPenguin::Epoll
|
570
|
+
* object per-thread.
|
571
|
+
*/
|
545
572
|
static VALUE init_copy(VALUE copy, VALUE orig)
|
546
573
|
{
|
547
574
|
struct rb_epoll *a = ep_get(orig);
|
@@ -572,30 +599,37 @@ static VALUE init_copy(VALUE copy, VALUE orig)
|
|
572
599
|
return copy;
|
573
600
|
}
|
574
601
|
|
602
|
+
/*
|
603
|
+
* call-seq:
|
604
|
+
* epoll.io_for(io) -> object
|
605
|
+
*
|
606
|
+
* Returns the given IO object currently being watched for. Different
|
607
|
+
* IO objects may internally refer to the same process file descriptor.
|
608
|
+
* Mostly used for debugging.
|
609
|
+
*/
|
575
610
|
static VALUE io_for(VALUE self, VALUE obj)
|
576
611
|
{
|
577
612
|
struct rb_epoll *ep = ep_get(self);
|
578
613
|
|
579
|
-
return rb_ary_entry(ep->marks,
|
614
|
+
return rb_ary_entry(ep->marks, rb_sp_fileno(obj));
|
580
615
|
}
|
581
616
|
|
582
617
|
/*
|
583
|
-
*
|
584
|
-
*
|
585
|
-
* epoll.flags_for(io) => Integer
|
618
|
+
* call-seq:
|
619
|
+
* epoll.flags_for(io) -> Integer
|
586
620
|
*
|
587
621
|
* Returns the flags currently watched for in current Epoll object.
|
622
|
+
* Mostly used for debugging.
|
588
623
|
*/
|
589
624
|
static VALUE flags_for(VALUE self, VALUE obj)
|
590
625
|
{
|
591
626
|
struct rb_epoll *ep = ep_get(self);
|
592
627
|
|
593
|
-
return rb_ary_entry(ep->flag_cache,
|
628
|
+
return rb_ary_entry(ep->flag_cache, rb_sp_fileno(obj));
|
594
629
|
}
|
595
630
|
|
596
631
|
/*
|
597
|
-
*
|
598
|
-
*
|
632
|
+
* call-seq:
|
599
633
|
* epoll.include?(io) => true or false
|
600
634
|
*
|
601
635
|
* Returns whether or not a given IO is watched and prevented from being
|
@@ -606,7 +640,7 @@ static VALUE include_p(VALUE self, VALUE obj)
|
|
606
640
|
{
|
607
641
|
struct rb_epoll *ep = ep_get(self);
|
608
642
|
|
609
|
-
return NIL_P(rb_ary_entry(ep->marks,
|
643
|
+
return NIL_P(rb_ary_entry(ep->marks, rb_sp_fileno(obj))) ? Qfalse : Qtrue;
|
610
644
|
}
|
611
645
|
|
612
646
|
/*
|
@@ -641,8 +675,47 @@ void sleepy_penguin_init_epoll(void)
|
|
641
675
|
{
|
642
676
|
VALUE mSleepyPenguin, cEpoll;
|
643
677
|
|
678
|
+
/*
|
679
|
+
* Document-module: SleepyPenguin
|
680
|
+
*
|
681
|
+
* require "sleepy_penguin"
|
682
|
+
* include SleepyPenguin
|
683
|
+
*
|
684
|
+
* The SleepyPenguin namespace includes the Epoll, Inotify, SignalFD,
|
685
|
+
* TimerFD, EventFD classes in its top level and no other constants.
|
686
|
+
*
|
687
|
+
* If you are uncomfortable including SleepyPenguin, you may also
|
688
|
+
* use the "SP" alias if it doesn't conflict with existing code:
|
689
|
+
*
|
690
|
+
* require "sleepy_penguin/sp"
|
691
|
+
*
|
692
|
+
* And then access classes via:
|
693
|
+
*
|
694
|
+
* - SP::Epoll
|
695
|
+
* - SP::EventFD
|
696
|
+
* - SP::Inotify
|
697
|
+
* - SP::SignalFD
|
698
|
+
* - SP::TimerFD
|
699
|
+
*/
|
644
700
|
mSleepyPenguin = rb_define_module("SleepyPenguin");
|
701
|
+
|
702
|
+
/*
|
703
|
+
* Document-class: SleepyPenguin::Epoll
|
704
|
+
*
|
705
|
+
* The Epoll class provides access to epoll(7) functionality in the
|
706
|
+
* Linux 2.6 kernel. It provides fork and GC-safety for Ruby
|
707
|
+
* objects stored within the IO object and may be passed as an
|
708
|
+
* argument to IO.select.
|
709
|
+
*/
|
645
710
|
cEpoll = rb_define_class_under(mSleepyPenguin, "Epoll", rb_cObject);
|
711
|
+
|
712
|
+
/*
|
713
|
+
* Document-class: SleepyPenguin::Epoll::IO
|
714
|
+
*
|
715
|
+
* Epoll::IO is an internal class. Its only purpose is to be
|
716
|
+
* compatible with IO.select and related methods and should not
|
717
|
+
* be used directly, use Epoll instead.
|
718
|
+
*/
|
646
719
|
cEpoll_IO = rb_define_class_under(cEpoll, "IO", rb_cIO);
|
647
720
|
rb_define_method(cEpoll, "initialize", init, -1);
|
648
721
|
rb_define_method(cEpoll, "initialize_copy", init_copy, 1);
|
@@ -660,39 +733,43 @@ void sleepy_penguin_init_epoll(void)
|
|
660
733
|
rb_define_method(cEpoll, "set", set, 2);
|
661
734
|
rb_define_method(cEpoll, "wait", epwait, -1);
|
662
735
|
|
663
|
-
/* specifies
|
736
|
+
/* specifies whether close-on-exec flag is set for Epoll.new */
|
664
737
|
rb_define_const(cEpoll, "CLOEXEC", INT2NUM(EPOLL_CLOEXEC));
|
665
738
|
|
666
739
|
/* watch for read/recv operations */
|
667
|
-
rb_define_const(cEpoll, "IN",
|
740
|
+
rb_define_const(cEpoll, "IN", UINT2NUM(EPOLLIN));
|
668
741
|
|
669
742
|
/* watch for write/send operations */
|
670
|
-
rb_define_const(cEpoll, "OUT",
|
743
|
+
rb_define_const(cEpoll, "OUT", UINT2NUM(EPOLLOUT));
|
671
744
|
|
672
745
|
#ifdef EPOLLRDHUP
|
673
|
-
/*
|
674
|
-
|
746
|
+
/*
|
747
|
+
* Watch a specified io for shutdown(SHUT_WR) on the remote-end.
|
748
|
+
* Available since Linux 2.6.17.
|
749
|
+
*/
|
750
|
+
rb_define_const(cEpoll, "RDHUP", UINT2NUM(EPOLLRDHUP));
|
675
751
|
#endif
|
752
|
+
|
676
753
|
/* watch for urgent read(2) data */
|
677
|
-
rb_define_const(cEpoll, "PRI",
|
754
|
+
rb_define_const(cEpoll, "PRI", UINT2NUM(EPOLLPRI));
|
678
755
|
|
679
756
|
/*
|
680
757
|
* watch for errors, there is no need to specify this,
|
681
758
|
* it is always monitored when an IO is watched
|
682
759
|
*/
|
683
|
-
rb_define_const(cEpoll, "ERR",
|
760
|
+
rb_define_const(cEpoll, "ERR", UINT2NUM(EPOLLERR));
|
684
761
|
|
685
762
|
/*
|
686
763
|
* watch for hangups, there is no need to specify this,
|
687
764
|
* it is always monitored when an IO is watched
|
688
765
|
*/
|
689
|
-
rb_define_const(cEpoll, "HUP",
|
766
|
+
rb_define_const(cEpoll, "HUP", UINT2NUM(EPOLLHUP));
|
690
767
|
|
691
768
|
/* notifications are only Edge Triggered, see epoll(7) */
|
692
|
-
rb_define_const(cEpoll, "ET",
|
769
|
+
rb_define_const(cEpoll, "ET", UINT2NUM((uint32_t)EPOLLET));
|
693
770
|
|
694
771
|
/* unwatch the descriptor once any event has fired */
|
695
|
-
rb_define_const(cEpoll, "ONESHOT",
|
772
|
+
rb_define_const(cEpoll, "ONESHOT", UINT2NUM(EPOLLONESHOT));
|
696
773
|
|
697
774
|
id_for_fd = rb_intern("for_fd");
|
698
775
|
active = st_init_numtable();
|