event 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29775c0ba7779c7773bf794270f5259429ee7e6d6611e6dcd3b4007a59dabc55
4
- data.tar.gz: 4df129eb3e0c99ad4d23131df66a794c0756a8a34032ef4864a492579faf61d3
3
+ metadata.gz: 932f834070b1bb738a09a9cb306599f80386755e4bfa2c78b502715acecf56b7
4
+ data.tar.gz: a04db89605437563a594e9012adb50a60af4a6c6dfacdd048ec0b03048f68010
5
5
  SHA512:
6
- metadata.gz: 6540f3372b5cded8e108c4dd314efb95f0e5fc6b794be77e84819e054c13a63c479d985ce35f6e5fbff35e1196b4f5606f7a4e46c93d856c91c32b5e5e7dbac2
7
- data.tar.gz: 687b15f76c4715b3f34b7467732887d75a3a15b3bfa7b29cdc9cd1385600e9fb4c797ca0ad6b3f8c1d5401e7bc87d1850a861e8e3cb9a333021d96fe4a348f18
6
+ metadata.gz: 074e688c34260fe28c3f15857c731052a745605deafd7d75bd07f9e0dc59aeed34d6633a05f5259d03a357c7f5c45762ef7de53a2f5dfc5c32213471f66eb847
7
+ data.tar.gz: 2214b5749ca680a7892e01539ec962b976f4fad480aa4a5d6d0d589981af8944a2ac94b03484e3e7e7936fd4bbf344418b72cb457fa229ffda11ff91bae9e5e8
data/ext/event/Makefile CHANGED
@@ -12,12 +12,12 @@ NULLCMD = :
12
12
  #### Start of system configuration section. ####
13
13
 
14
14
  srcdir = .
15
- topdir = /home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0
15
+ topdir = /Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0
16
16
  hdrdir = $(topdir)
17
- arch_hdrdir = /home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-linux
17
+ arch_hdrdir = /Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-darwin20
18
18
  PATH_SEPARATOR = :
19
19
  VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby:$(srcdir)/backend
20
- prefix = $(DESTDIR)/home/samuel/.rubies/ruby-3.0.1
20
+ prefix = $(DESTDIR)/Users/samuel/.rubies/ruby-3.0.1
21
21
  rubysitearchprefix = $(rubylibprefix)/$(sitearch)
22
22
  rubyarchprefix = $(rubylibprefix)/$(arch)
23
23
  rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
@@ -50,7 +50,7 @@ dvidir = $(docdir)
50
50
  htmldir = $(docdir)
51
51
  infodir = $(datarootdir)/info
52
52
  docdir = $(datarootdir)/doc/$(PACKAGE)
53
- oldincludedir = $(DESTDIR)/usr/include
53
+ oldincludedir = $(SDKROOT)/usr/include
54
54
  includedir = $(prefix)/include
55
55
  runstatedir = $(localstatedir)/run
56
56
  localstatedir = $(prefix)/var
@@ -65,12 +65,12 @@ archdir = $(rubyarchdir)
65
65
 
66
66
 
67
67
  CC_WRAPPER =
68
- CC = gcc
69
- CXX = g++
68
+ CC = clang -fdeclspec
69
+ CXX = clang++ -fdeclspec
70
70
  LIBRUBY = $(LIBRUBY_A)
71
71
  LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
72
- LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir)
73
- LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS)
72
+ LIBRUBYARG_SHARED =
73
+ LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static -framework Security -framework Foundation $(MAINLIBS)
74
74
  empty =
75
75
  OUTFLAG = -o $(empty)
76
76
  COUTFLAG = -o $(empty)
@@ -81,31 +81,31 @@ cflags = $(optflags) $(debugflags) $(warnflags)
81
81
  cxxflags =
82
82
  optflags = -O3
83
83
  debugflags = -ggdb3
84
- warnflags = -Wall -Wextra -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable
84
+ warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens
85
85
  cppflags =
86
- CCDLFLAGS = -fPIC
87
- CFLAGS = $(CCDLFLAGS) $(cflags) -Wall $(ARCH_FLAG)
86
+ CCDLFLAGS = -fno-common
87
+ CFLAGS = $(CCDLFLAGS) $(cflags) -pipe -Wall $(ARCH_FLAG)
88
88
  INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
89
89
  DEFS =
90
- CPPFLAGS = -DRUBY_EXTCONF_H=\"$(RUBY_EXTCONF_H)\" $(DEFS) $(cppflags)
90
+ CPPFLAGS = -DRUBY_EXTCONF_H=\"$(RUBY_EXTCONF_H)\" -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT $(DEFS) $(cppflags)
91
91
  CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG)
92
- ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic
93
- dldflags = -Wl,--compress-debug-sections=zlib
92
+ ldflags = -L. -fstack-protector-strong -L/opt/local/lib
93
+ dldflags = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -L/opt/local/lib
94
94
  ARCH_FLAG =
95
95
  DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
96
- LDSHARED = $(CC) -shared
97
- LDSHAREDXX = $(CXX) -shared
98
- AR = gcc-ar
96
+ LDSHARED = $(CC) -dynamic -bundle
97
+ LDSHAREDXX = $(CXX) -dynamic -bundle
98
+ AR = ar
99
99
  EXEEXT =
100
100
 
101
101
  RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)
102
- RUBY_SO_NAME = ruby
102
+ RUBY_SO_NAME = ruby.3.0
103
103
  RUBYW_INSTALL_NAME =
104
104
  RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
105
105
  RUBYW_BASE_NAME = rubyw
106
106
  RUBY_BASE_NAME = ruby
107
107
 
108
- arch = x86_64-linux
108
+ arch = x86_64-darwin20
109
109
  sitearch = $(arch)
110
110
  ruby_version = 3.0.0
111
111
  ruby = $(bindir)/$(RUBY_BASE_NAME)
@@ -114,8 +114,8 @@ ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h
114
114
 
115
115
  RM = rm -f
116
116
  RM_RF = $(RUBY) -run -e rm -- -rf
117
- RMDIRS = rmdir --ignore-fail-on-non-empty -p
118
- MAKEDIRS = /usr/bin/mkdir -p
117
+ RMDIRS = rmdir -p
118
+ MAKEDIRS = /opt/local/bin/gmkdir -p
119
119
  INSTALL = /usr/bin/install -c
120
120
  INSTALL_PROG = $(INSTALL) -m 0755
121
121
  INSTALL_DATA = $(INSTALL) -m 644
@@ -125,8 +125,8 @@ TOUCH = exit >
125
125
  #### End of system configuration section. ####
126
126
 
127
127
  preload =
128
- libpath = . $(libdir)
129
- LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir)
128
+ libpath = . $(libdir) /opt/local/lib
129
+ LIBPATH = -L. -L$(libdir) -L/opt/local/lib
130
130
  DEFFILE =
131
131
 
132
132
  CLEANFILES = mkmf.log
@@ -137,16 +137,16 @@ extout =
137
137
  extout_prefix =
138
138
  target_prefix = /event
139
139
  LOCAL_LIBS =
140
- LIBS = -luring -lm -lc
140
+ LIBS =
141
141
  ORIG_SRCS = event.c
142
- SRCS = $(ORIG_SRCS) event.c uring.c epoll.c
143
- OBJS = event.o uring.o epoll.o
142
+ SRCS = $(ORIG_SRCS) event.c backend.c kqueue.c
143
+ OBJS = event.o backend.o kqueue.o
144
144
  HDRS = $(srcdir)/event.h $(srcdir)/extconf.h
145
145
  LOCAL_HDRS =
146
146
  TARGET = event
147
147
  TARGET_NAME = event
148
148
  TARGET_ENTRY = Init_$(TARGET_NAME)
149
- DLLIB = $(TARGET).so
149
+ DLLIB = $(TARGET).bundle
150
150
  EXTSTATIC =
151
151
  STATIC_LIB =
152
152
 
@@ -260,6 +260,7 @@ $(TARGET_SO): $(OBJS) Makefile
260
260
  $(ECHO) linking shared-object event/$(DLLIB)
261
261
  -$(Q)$(RM) $(@)
262
262
  $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
263
+ $(Q) $(POSTLINK)
263
264
 
264
265
 
265
266
 
Binary file
@@ -0,0 +1,64 @@
1
+ // Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ #include "backend.h"
22
+
23
+ #if HAVE_RB_FIBER_TRANSFER_KW
24
+ #define HAVE_RB_FIBER_TRANSFER 1
25
+ #else
26
+ #define HAVE_RB_FIBER_TRANSFER 0
27
+ #endif
28
+
29
+ static ID id_transfer, id_wait;
30
+ static VALUE rb_Process_Status = Qnil;
31
+
32
+ void Init_Event_Backend(VALUE Event_Backend) {
33
+ id_transfer = rb_intern("transfer");
34
+ id_wait = rb_intern("wait");
35
+ // id_alive_p = rb_intern("alive?");
36
+ rb_Process_Status = rb_const_get_at(rb_mProcess, rb_intern("Status"));
37
+ }
38
+
39
+ VALUE
40
+ Event_Backend_transfer(VALUE fiber) {
41
+ #if HAVE_RB_FIBER_TRANSFER
42
+ return rb_fiber_transfer(fiber, 0, NULL);
43
+ #else
44
+ return rb_funcall(fiber, id_transfer, 0);
45
+ #endif
46
+ }
47
+
48
+ VALUE
49
+ Event_Backend_transfer_result(VALUE fiber, VALUE result) {
50
+ // if (!RTEST(rb_fiber_alive_p(fiber))) {
51
+ // return Qnil;
52
+ // }
53
+
54
+ #if HAVE_RB_FIBER_TRANSFER
55
+ return rb_fiber_transfer(fiber, 1, &result);
56
+ #else
57
+ return rb_funcall(fiber, id_transfer, 1, result);
58
+ #endif
59
+ }
60
+
61
+ VALUE Event_Backend_process_status_wait(rb_pid_t pid)
62
+ {
63
+ return rb_funcall(rb_Process_Status, id_wait, 2, PIDT2NUM(pid), INT2NUM(WNOHANG));
64
+ }
@@ -18,6 +18,9 @@
18
18
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  // THE SOFTWARE.
20
20
 
21
+ #include <ruby.h>
22
+ #include <ruby/thread.h>
23
+
21
24
  enum Event {
22
25
  READABLE = 1,
23
26
  PRIORITY = 2,
@@ -26,4 +29,10 @@ enum Event {
26
29
  HANGUP = 16
27
30
  };
28
31
 
29
- #include <ruby/thread.h>
32
+ void
33
+ Init_Event_Backend();
34
+
35
+ VALUE Event_Backend_transfer(VALUE fiber);
36
+ VALUE Event_Backend_transfer_result(VALUE fiber, VALUE argument);
37
+
38
+ VALUE Event_Backend_process_status_wait(rb_pid_t pid);
@@ -25,8 +25,10 @@
25
25
  #include <time.h>
26
26
  #include <errno.h>
27
27
 
28
+ #include "pidfd.c"
29
+
28
30
  static VALUE Event_Backend_EPoll = Qnil;
29
- static ID id_fileno, id_transfer;
31
+ static ID id_fileno;
30
32
 
31
33
  enum {EPOLL_MAX_EVENTS = 64};
32
34
 
@@ -111,6 +113,60 @@ VALUE Event_Backend_EPoll_close(VALUE self) {
111
113
  return Qnil;
112
114
  }
113
115
 
116
+ struct process_wait_arguments {
117
+ struct Event_Backend_EPoll *data;
118
+ pid_t pid;
119
+ int flags;
120
+ int descriptor;
121
+ };
122
+
123
+ static
124
+ VALUE process_wait_transfer(VALUE _arguments) {
125
+ struct process_wait_arguments *arguments = (struct process_wait_arguments *)_arguments;
126
+
127
+ Event_Backend_transfer(arguments->data->loop);
128
+
129
+ return Event_Backend_process_status_wait(arguments->pid);
130
+ }
131
+
132
+ static
133
+ VALUE process_wait_ensure(VALUE _arguments) {
134
+ struct process_wait_arguments *arguments = (struct process_wait_arguments *)_arguments;
135
+
136
+ // epoll_ctl(arguments->data->descriptor, EPOLL_CTL_DEL, arguments->descriptor, NULL);
137
+
138
+ close(arguments->descriptor);
139
+
140
+ return Qnil;
141
+ }
142
+
143
+ VALUE Event_Backend_EPoll_process_wait(VALUE self, VALUE fiber, VALUE pid, VALUE flags) {
144
+ struct Event_Backend_EPoll *data = NULL;
145
+ TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
146
+
147
+ struct process_wait_arguments process_wait_arguments = {
148
+ .data = data,
149
+ .pid = NUM2PIDT(pid),
150
+ .flags = NUM2INT(flags),
151
+ };
152
+
153
+ process_wait_arguments.descriptor = pidfd_open(process_wait_arguments.pid, 0);
154
+ rb_update_max_fd(process_wait_arguments.descriptor);
155
+
156
+ struct epoll_event event = {
157
+ .events = EPOLLIN|EPOLLRDHUP|EPOLLONESHOT,
158
+ .data = {.ptr = (void*)fiber},
159
+ };
160
+
161
+ int result = epoll_ctl(data->descriptor, EPOLL_CTL_ADD, process_wait_arguments.descriptor, &event);
162
+
163
+ if (result == -1) {
164
+ rb_sys_fail("epoll_ctl(process_wait)");
165
+ }
166
+
167
+ return rb_ensure(process_wait_transfer, (VALUE)&process_wait_arguments, process_wait_ensure, (VALUE)&process_wait_arguments);
168
+ }
169
+
114
170
  static inline
115
171
  uint32_t epoll_flags_from_events(int events) {
116
172
  uint32_t flags = 0;
@@ -161,7 +217,7 @@ static
161
217
  VALUE io_wait_transfer(VALUE _arguments) {
162
218
  struct io_wait_arguments *arguments = (struct io_wait_arguments *)_arguments;
163
219
 
164
- VALUE result = rb_funcall(arguments->data->loop, id_transfer, 0);
220
+ VALUE result = Event_Backend_transfer(arguments->data->loop);
165
221
 
166
222
  return INT2NUM(events_from_epoll_flags(NUM2INT(result)));
167
223
  };
@@ -272,13 +328,13 @@ VALUE Event_Backend_EPoll_select(VALUE self, VALUE duration) {
272
328
  .timeout = 0
273
329
  };
274
330
 
275
- select_internal_without_gvl(&arguments);
331
+ select_internal_with_gvl(&arguments);
276
332
 
277
333
  if (arguments.count == 0) {
278
334
  arguments.timeout = make_timeout(duration);
279
335
 
280
336
  if (arguments.timeout != 0) {
281
- select_internal_with_gvl(&arguments);
337
+ select_internal_without_gvl(&arguments);
282
338
  }
283
339
  }
284
340
 
@@ -288,7 +344,7 @@ VALUE Event_Backend_EPoll_select(VALUE self, VALUE duration) {
288
344
 
289
345
  // fprintf(stderr, "-> fiber=%p descriptor=%d\n", (void*)fiber, events[i].data.fd);
290
346
 
291
- rb_funcall(fiber, id_transfer, 1, result);
347
+ Event_Backend_transfer_result(fiber, result);
292
348
  }
293
349
 
294
350
  return INT2NUM(arguments.count);
@@ -296,7 +352,6 @@ VALUE Event_Backend_EPoll_select(VALUE self, VALUE duration) {
296
352
 
297
353
  void Init_Event_Backend_EPoll(VALUE Event_Backend) {
298
354
  id_fileno = rb_intern("fileno");
299
- id_transfer = rb_intern("transfer");
300
355
 
301
356
  Event_Backend_EPoll = rb_define_class_under(Event_Backend, "EPoll", rb_cObject);
302
357
 
@@ -306,4 +361,5 @@ void Init_Event_Backend_EPoll(VALUE Event_Backend) {
306
361
 
307
362
  rb_define_method(Event_Backend_EPoll, "io_wait", Event_Backend_EPoll_io_wait, 3);
308
363
  rb_define_method(Event_Backend_EPoll, "select", Event_Backend_EPoll_select, 1);
364
+ rb_define_method(Event_Backend_EPoll, "process_wait", Event_Backend_EPoll_process_wait, 3);
309
365
  }
@@ -24,9 +24,10 @@
24
24
  #include <sys/event.h>
25
25
  #include <sys/ioctl.h>
26
26
  #include <time.h>
27
+ #include <errno.h>
27
28
 
28
29
  static VALUE Event_Backend_KQueue = Qnil;
29
- static ID id_fileno, id_transfer;
30
+ static ID id_fileno;
30
31
 
31
32
  enum {KQUEUE_MAX_EVENTS = 64};
32
33
 
@@ -112,6 +113,86 @@ VALUE Event_Backend_KQueue_close(VALUE self) {
112
113
  return Qnil;
113
114
  }
114
115
 
116
+ struct process_wait_arguments {
117
+ struct Event_Backend_KQueue *data;
118
+ pid_t pid;
119
+ int flags;
120
+ };
121
+
122
+ static
123
+ int process_add_filters(int descriptor, int ident, VALUE fiber) {
124
+ struct kevent event = {0};
125
+
126
+ event.ident = ident;
127
+ event.filter = EVFILT_PROC;
128
+ event.flags = EV_ADD | EV_ENABLE | EV_ONESHOT;
129
+ event.fflags = NOTE_EXIT;
130
+ event.udata = (void*)fiber;
131
+
132
+ int result = kevent(descriptor, &event, 1, NULL, 0, NULL);
133
+
134
+ if (result == -1) {
135
+ // No such process - the process has probably already terminated:
136
+ if (errno == ESRCH) {
137
+ return 0;
138
+ }
139
+
140
+ rb_sys_fail("kevent(process_add_filters)");
141
+ }
142
+
143
+ return 1;
144
+ }
145
+
146
+ static
147
+ void process_remove_filters(int descriptor, int ident) {
148
+ struct kevent event = {0};
149
+
150
+ event.ident = ident;
151
+ event.filter = EVFILT_PROC;
152
+ event.flags = EV_DELETE;
153
+ event.fflags = NOTE_EXIT;
154
+
155
+ // Ignore the result.
156
+ kevent(descriptor, &event, 1, NULL, 0, NULL);
157
+ }
158
+
159
+ static
160
+ VALUE process_wait_transfer(VALUE _arguments) {
161
+ struct process_wait_arguments *arguments = (struct process_wait_arguments *)_arguments;
162
+
163
+ Event_Backend_transfer(arguments->data->loop);
164
+
165
+ return Event_Backend_process_status_wait(arguments->pid);
166
+ }
167
+
168
+ static
169
+ VALUE process_wait_rescue(VALUE _arguments, VALUE exception) {
170
+ struct process_wait_arguments *arguments = (struct process_wait_arguments *)_arguments;
171
+
172
+ process_remove_filters(arguments->data->descriptor, arguments->pid);
173
+
174
+ rb_exc_raise(exception);
175
+ }
176
+
177
+ VALUE Event_Backend_KQueue_process_wait(VALUE self, VALUE fiber, VALUE pid, VALUE flags) {
178
+ struct Event_Backend_KQueue *data = NULL;
179
+ TypedData_Get_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data);
180
+
181
+ struct process_wait_arguments process_wait_arguments = {
182
+ .data = data,
183
+ .pid = NUM2PIDT(pid),
184
+ .flags = NUM2INT(flags),
185
+ };
186
+
187
+ int waiting = process_add_filters(data->descriptor, process_wait_arguments.pid, fiber);
188
+
189
+ if (waiting) {
190
+ return rb_rescue(process_wait_transfer, (VALUE)&process_wait_arguments, process_wait_rescue, (VALUE)&process_wait_arguments);
191
+ } else {
192
+ return Event_Backend_process_status_wait(process_wait_arguments.pid);
193
+ }
194
+ }
195
+
115
196
  static
116
197
  int io_add_filters(int descriptor, int ident, int events, VALUE fiber) {
117
198
  int count = 0;
@@ -143,7 +224,7 @@ int io_add_filters(int descriptor, int ident, int events, VALUE fiber) {
143
224
  int result = kevent(descriptor, kevents, count, NULL, 0, NULL);
144
225
 
145
226
  if (result == -1) {
146
- rb_sys_fail("kevent(register)");
227
+ rb_sys_fail("kevent(io_add_filters)");
147
228
  }
148
229
 
149
230
  return events;
@@ -200,7 +281,7 @@ static
200
281
  VALUE io_wait_transfer(VALUE _arguments) {
201
282
  struct io_wait_arguments *arguments = (struct io_wait_arguments *)_arguments;
202
283
 
203
- VALUE result = rb_funcall(arguments->data->loop, id_transfer, 0);
284
+ VALUE result = Event_Backend_transfer(arguments->data->loop);
204
285
 
205
286
  return INT2NUM(events_from_kqueue_filter(NUM2INT(result)));
206
287
  };
@@ -325,7 +406,8 @@ VALUE Event_Backend_KQueue_select(VALUE self, VALUE duration) {
325
406
  for (int i = 0; i < arguments.count; i += 1) {
326
407
  VALUE fiber = (VALUE)arguments.events[i].udata;
327
408
  VALUE result = INT2NUM(arguments.events[i].filter);
328
- rb_funcall(fiber, id_transfer, 1, result);
409
+
410
+ Event_Backend_transfer_result(fiber, result);
329
411
  }
330
412
 
331
413
  return INT2NUM(arguments.count);
@@ -333,14 +415,14 @@ VALUE Event_Backend_KQueue_select(VALUE self, VALUE duration) {
333
415
 
334
416
  void Init_Event_Backend_KQueue(VALUE Event_Backend) {
335
417
  id_fileno = rb_intern("fileno");
336
- id_transfer = rb_intern("transfer");
337
418
 
338
419
  Event_Backend_KQueue = rb_define_class_under(Event_Backend, "KQueue", rb_cObject);
339
420
 
340
421
  rb_define_alloc_func(Event_Backend_KQueue, Event_Backend_KQueue_allocate);
341
422
  rb_define_method(Event_Backend_KQueue, "initialize", Event_Backend_KQueue_initialize, 1);
342
- rb_define_method(Event_Backend_KQueue, "initialize", Event_Backend_KQueue_close, 0);
423
+ rb_define_method(Event_Backend_KQueue, "close", Event_Backend_KQueue_close, 0);
343
424
 
344
425
  rb_define_method(Event_Backend_KQueue, "io_wait", Event_Backend_KQueue_io_wait, 3);
345
426
  rb_define_method(Event_Backend_KQueue, "select", Event_Backend_KQueue_select, 1);
427
+ rb_define_method(Event_Backend_KQueue, "process_wait", Event_Backend_KQueue_process_wait, 3);
346
428
  }
@@ -0,0 +1,36 @@
1
+ // Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ #include <sys/types.h>
22
+ #include <sys/syscall.h>
23
+ #include <unistd.h>
24
+ #include <poll.h>
25
+ #include <stdlib.h>
26
+ #include <stdio.h>
27
+
28
+ #ifndef __NR_pidfd_open
29
+ #define __NR_pidfd_open 434 /* System call # on most architectures */
30
+ #endif
31
+
32
+ static int
33
+ pidfd_open(pid_t pid, unsigned int flags)
34
+ {
35
+ return syscall(__NR_pidfd_open, pid, flags);
36
+ }
@@ -25,8 +25,10 @@
25
25
  #include <poll.h>
26
26
  #include <time.h>
27
27
 
28
+ #include "pidfd.c"
29
+
28
30
  static VALUE Event_Backend_URing = Qnil;
29
- static ID id_fileno, id_transfer;
31
+ static ID id_fileno;
30
32
 
31
33
  enum {URING_ENTRIES = 128};
32
34
  enum {URING_MAX_EVENTS = 128};
@@ -111,6 +113,66 @@ VALUE Event_Backend_URing_close(VALUE self) {
111
113
  return Qnil;
112
114
  }
113
115
 
116
+ struct io_uring_sqe * io_get_sqe(struct Event_Backend_URing *data) {
117
+ struct io_uring_sqe *sqe = io_uring_get_sqe(&data->ring);
118
+
119
+ while (sqe == NULL) {
120
+ io_uring_submit(&data->ring);
121
+ sqe = io_uring_get_sqe(&data->ring);
122
+ }
123
+
124
+ // fprintf(stderr, "io_get_sqe -> %p\n", sqe);
125
+
126
+ return sqe;
127
+ }
128
+
129
+ struct process_wait_arguments {
130
+ struct Event_Backend_URing *data;
131
+ pid_t pid;
132
+ int flags;
133
+ int descriptor;
134
+ };
135
+
136
+ static
137
+ VALUE process_wait_transfer(VALUE _arguments) {
138
+ struct process_wait_arguments *arguments = (struct process_wait_arguments *)_arguments;
139
+
140
+ Event_Backend_transfer(arguments->data->loop);
141
+
142
+ return Event_Backend_process_status_wait(arguments->pid);
143
+ }
144
+
145
+ static
146
+ VALUE process_wait_ensure(VALUE _arguments) {
147
+ struct process_wait_arguments *arguments = (struct process_wait_arguments *)_arguments;
148
+
149
+ close(arguments->descriptor);
150
+
151
+ return Qnil;
152
+ }
153
+
154
+ VALUE Event_Backend_URing_process_wait(VALUE self, VALUE fiber, VALUE pid, VALUE flags) {
155
+ struct Event_Backend_URing *data = NULL;
156
+ TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
157
+
158
+ struct process_wait_arguments process_wait_arguments = {
159
+ .data = data,
160
+ .pid = NUM2PIDT(pid),
161
+ .flags = NUM2INT(flags),
162
+ };
163
+
164
+ process_wait_arguments.descriptor = pidfd_open(process_wait_arguments.pid, 0);
165
+ rb_update_max_fd(process_wait_arguments.descriptor);
166
+
167
+ struct io_uring_sqe *sqe = io_get_sqe(data);
168
+ assert(sqe);
169
+
170
+ io_uring_prep_poll_add(sqe, process_wait_arguments.descriptor, POLLIN|POLLHUP|POLLERR);
171
+ io_uring_sqe_set_data(sqe, (void*)fiber);
172
+
173
+ return rb_ensure(process_wait_transfer, (VALUE)&process_wait_arguments, process_wait_ensure, (VALUE)&process_wait_arguments);
174
+ }
175
+
114
176
  static inline
115
177
  short poll_flags_from_events(int events) {
116
178
  short flags = 0;
@@ -142,22 +204,13 @@ struct io_wait_arguments {
142
204
  short flags;
143
205
  };
144
206
 
145
- struct io_uring_sqe * io_get_sqe(struct Event_Backend_URing *data) {
146
- struct io_uring_sqe *sqe = io_uring_get_sqe(&data->ring);
147
-
148
- while (sqe == NULL) {
149
- sqe = io_uring_get_sqe(&data->ring);
150
- }
151
-
152
- return sqe;
153
- }
154
-
155
207
  static
156
208
  VALUE io_wait_rescue(VALUE _arguments, VALUE exception) {
157
209
  struct io_wait_arguments *arguments = (struct io_wait_arguments *)_arguments;
158
210
  struct Event_Backend_URing *data = arguments->data;
159
211
 
160
212
  struct io_uring_sqe *sqe = io_get_sqe(data);
213
+ assert(sqe);
161
214
 
162
215
  // fprintf(stderr, "poll_remove(%p, %p)\n", sqe, (void*)arguments->fiber);
163
216
 
@@ -171,8 +224,8 @@ static
171
224
  VALUE io_wait_transfer(VALUE _arguments) {
172
225
  struct io_wait_arguments *arguments = (struct io_wait_arguments *)_arguments;
173
226
  struct Event_Backend_URing *data = arguments->data;
174
-
175
- VALUE result = rb_funcall(data->loop, id_transfer, 0);
227
+
228
+ VALUE result = Event_Backend_transfer(data->loop);
176
229
 
177
230
  // We explicitly filter the resulting events based on the requested events.
178
231
  // In some cases, poll will report events we didn't ask for.
@@ -187,8 +240,7 @@ VALUE Event_Backend_URing_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE event
187
240
 
188
241
  int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
189
242
  struct io_uring_sqe *sqe = io_get_sqe(data);
190
-
191
- if (!sqe) return INT2NUM(0);
243
+ assert(sqe);
192
244
 
193
245
  short flags = poll_flags_from_events(NUM2INT(events));
194
246
 
@@ -196,7 +248,8 @@ VALUE Event_Backend_URing_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE event
196
248
 
197
249
  io_uring_prep_poll_add(sqe, descriptor, flags);
198
250
  io_uring_sqe_set_data(sqe, (void*)fiber);
199
- io_uring_submit(&data->ring);
251
+ // fprintf(stderr, "io_uring_submit\n");
252
+ // io_uring_submit(&data->ring);
200
253
 
201
254
  struct io_wait_arguments io_wait_arguments = {
202
255
  .data = data,
@@ -238,6 +291,7 @@ VALUE Event_Backend_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffe
238
291
 
239
292
  int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
240
293
  struct io_uring_sqe *sqe = io_get_sqe(data);
294
+ assert(sqe);
241
295
 
242
296
  struct iovec iovecs[1];
243
297
  iovecs[0].iov_base = RSTRING_PTR(buffer) + NUM2SIZET(offset);
@@ -249,7 +303,7 @@ VALUE Event_Backend_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffe
249
303
 
250
304
  // fprintf(stderr, "prep_readv(%p, %d, %ld)\n", sqe, descriptor, iovecs[0].iov_len);
251
305
 
252
- int result = NUM2INT(rb_funcall(data->loop, id_transfer, 0));
306
+ int result = NUM2INT(Event_Backend_transfer(data->loop));
253
307
 
254
308
  if (result < 0) {
255
309
  rb_syserr_fail(-result, strerror(-result));
@@ -281,7 +335,7 @@ VALUE Event_Backend_URing_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buff
281
335
 
282
336
  // fprintf(stderr, "prep_writev(%p, %d, %ld)\n", sqe, descriptor, iovecs[0].iov_len);
283
337
 
284
- int result = NUM2INT(rb_funcall(data->loop, id_transfer, 0));
338
+ int result = NUM2INT(Event_Backend_transfer(data->loop));
285
339
 
286
340
  if (result < 0) {
287
341
  rb_syserr_fail(-result, strerror(-result));
@@ -324,8 +378,7 @@ int timeout_nonblocking(struct __kernel_timespec *timespec) {
324
378
  struct select_arguments {
325
379
  struct Event_Backend_URing *data;
326
380
 
327
- int count;
328
- struct io_uring_cqe **cqes;
381
+ int result;
329
382
 
330
383
  struct __kernel_timespec storage;
331
384
  struct __kernel_timespec *timeout;
@@ -335,12 +388,10 @@ static
335
388
  void * select_internal(void *_arguments) {
336
389
  struct select_arguments * arguments = (struct select_arguments *)_arguments;
337
390
 
338
- arguments->count = io_uring_wait_cqes(&arguments->data->ring, arguments->cqes, 1, arguments->timeout, NULL);
391
+ io_uring_submit(&arguments->data->ring);
339
392
 
340
- // If waiting resulted in a timeout, there are 0 events.
341
- if (arguments->count == -ETIME) {
342
- arguments->count = 0;
343
- }
393
+ struct io_uring_cqe *cqe = NULL;
394
+ arguments->result = io_uring_wait_cqe_timeout(&arguments->data->ring, &cqe, arguments->timeout);
344
395
 
345
396
  return NULL;
346
397
  }
@@ -349,21 +400,52 @@ static
349
400
  int select_internal_without_gvl(struct select_arguments *arguments) {
350
401
  rb_thread_call_without_gvl(select_internal, (void *)arguments, RUBY_UBF_IO, 0);
351
402
 
352
- if (arguments->count < 0) {
353
- rb_syserr_fail(-arguments->count, "select_internal_without_gvl:io_uring_wait_cqes");
403
+ if (arguments->result == -ETIME) {
404
+ arguments->result = 0;
405
+ } else if (arguments->result < 0) {
406
+ rb_syserr_fail(-arguments->result, "select_internal_without_gvl:io_uring_wait_cqes");
407
+ } else {
408
+ // At least 1 event is waiting:
409
+ arguments->result = 1;
410
+ }
411
+
412
+ return arguments->result;
413
+ }
414
+
415
+ static inline
416
+ unsigned select_process_completions(struct io_uring *ring) {
417
+ unsigned completed = 0;
418
+ unsigned head;
419
+ struct io_uring_cqe *cqe;
420
+
421
+ io_uring_for_each_cqe(ring, head, cqe) {
422
+ ++completed;
423
+
424
+ // If the operation was cancelled, or the operation has no user data (fiber):
425
+ if (cqe->res == -ECANCELED || cqe->user_data == 0 || cqe->user_data == LIBURING_UDATA_TIMEOUT) {
426
+ continue;
427
+ }
428
+
429
+ VALUE fiber = (VALUE)cqe->user_data;
430
+ VALUE result = INT2NUM(cqe->res);
431
+
432
+ // fprintf(stderr, "cqe res=%d user_data=%p\n", cqe->res, (void*)cqe->user_data);
433
+
434
+ Event_Backend_transfer_result(fiber, result);
435
+ }
436
+
437
+ if (completed) {
438
+ io_uring_cq_advance(ring, completed);
354
439
  }
355
440
 
356
- return arguments->count;
441
+ return completed;
357
442
  }
358
443
 
359
444
  VALUE Event_Backend_URing_select(VALUE self, VALUE duration) {
360
445
  struct Event_Backend_URing *data = NULL;
361
446
  TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
362
447
 
363
- struct io_uring_cqe *cqes[URING_MAX_EVENTS];
364
-
365
- // This is a non-blocking operation:
366
- int result = io_uring_peek_batch_cqe(&data->ring, cqes, URING_MAX_EVENTS);
448
+ int result = select_process_completions(&data->ring);
367
449
 
368
450
  if (result < 0) {
369
451
  rb_syserr_fail(-result, strerror(-result));
@@ -371,7 +453,6 @@ VALUE Event_Backend_URing_select(VALUE self, VALUE duration) {
371
453
  // We might need to wait for events:
372
454
  struct select_arguments arguments = {
373
455
  .data = data,
374
- .cqes = cqes,
375
456
  .timeout = NULL,
376
457
  };
377
458
 
@@ -379,33 +460,18 @@ VALUE Event_Backend_URing_select(VALUE self, VALUE duration) {
379
460
 
380
461
  if (!timeout_nonblocking(arguments.timeout)) {
381
462
  result = select_internal_without_gvl(&arguments);
463
+ } else {
464
+ io_uring_submit(&data->ring);
382
465
  }
383
466
  }
384
467
 
385
- // fprintf(stderr, "cqes count=%d\n", result);
386
-
387
- for (int i = 0; i < result; i += 1) {
388
- // If the operation was cancelled, or the operation has no user data (fiber):
389
- if (cqes[i]->res == -ECANCELED || cqes[i]->user_data == 0) {
390
- continue;
391
- }
392
-
393
- VALUE fiber = (VALUE)io_uring_cqe_get_data(cqes[i]);
394
- VALUE result = INT2NUM(cqes[i]->res);
395
-
396
- // fprintf(stderr, "cqes[i] res=%d user_data=%p\n", cqes[i]->res, (void*)cqes[i]->user_data);
397
-
398
- io_uring_cqe_seen(&data->ring, cqes[i]);
399
-
400
- rb_funcall(fiber, id_transfer, 1, result);
401
- }
468
+ result = select_process_completions(&data->ring);
402
469
 
403
470
  return INT2NUM(result);
404
471
  }
405
472
 
406
473
  void Init_Event_Backend_URing(VALUE Event_Backend) {
407
474
  id_fileno = rb_intern("fileno");
408
- id_transfer = rb_intern("transfer");
409
475
 
410
476
  Event_Backend_URing = rb_define_class_under(Event_Backend, "URing", rb_cObject);
411
477
 
@@ -418,4 +484,5 @@ void Init_Event_Backend_URing(VALUE Event_Backend) {
418
484
 
419
485
  rb_define_method(Event_Backend_URing, "io_read", Event_Backend_URing_io_read, 5);
420
486
  rb_define_method(Event_Backend_URing, "io_write", Event_Backend_URing_io_write, 5);
487
+ rb_define_method(Event_Backend_URing, "process_wait", Event_Backend_URing_process_wait, 3);
421
488
  }
Binary file
data/ext/event/event.c CHANGED
@@ -19,6 +19,7 @@
19
19
  // THE SOFTWARE.
20
20
 
21
21
  #include "event.h"
22
+ #include "backend/backend.h"
22
23
 
23
24
  VALUE Event = Qnil;
24
25
  VALUE Event_Backend = Qnil;
@@ -32,6 +33,8 @@ void Init_event()
32
33
  Event = rb_define_module("Event");
33
34
  Event_Backend = rb_define_module_under(Event, "Backend");
34
35
 
36
+ Init_Event_Backend(Event_Backend);
37
+
35
38
  #ifdef EVENT_BACKEND_URING
36
39
  Init_Event_Backend_URing(Event_Backend);
37
40
  #endif
data/ext/event/event.h CHANGED
@@ -26,14 +26,14 @@
26
26
 
27
27
  void Init_event();
28
28
 
29
- #if HAVE_LIBURING_H
29
+ #ifdef HAVE_LIBURING_H
30
30
  #include "backend/uring.h"
31
31
  #endif
32
32
 
33
- #if HAVE_SYS_EPOLL_H
33
+ #ifdef HAVE_SYS_EPOLL_H
34
34
  #include "backend/epoll.h"
35
35
  #endif
36
36
 
37
- #if HAVE_SYS_EVENT_H
37
+ #ifdef HAVE_SYS_EVENT_H
38
38
  #include "backend/kqueue.h"
39
39
  #endif
data/ext/event/event.o CHANGED
Binary file
data/ext/event/extconf.h CHANGED
@@ -1,5 +1,4 @@
1
1
  #ifndef EXTCONF_H
2
2
  #define EXTCONF_H
3
- #define HAVE_LIBURING_H 1
4
- #define HAVE_SYS_EPOLL_H 1
3
+ #define HAVE_SYS_EVENT_H 1
5
4
  #endif
data/ext/event/extconf.rb CHANGED
@@ -30,9 +30,12 @@ dir_config(extension_name)
30
30
 
31
31
  $CFLAGS << " -Wall"
32
32
 
33
- $srcs = ["event.c"]
33
+ $srcs = ["event.c", "backend/backend.c"]
34
34
  $VPATH << "$(srcdir)/backend"
35
35
 
36
+ # have_func('rb_fiber_transfer')
37
+ have_func('rb_fiber_transfer_kw')
38
+
36
39
  if have_library('uring') and have_header('liburing.h')
37
40
  $srcs << "backend/uring.c"
38
41
  end
Binary file
data/ext/event/mkmf.log CHANGED
@@ -1,6 +1,6 @@
1
- have_library: checking for -luring... -------------------- yes
1
+ have_func: checking for rb_fiber_transfer_kw()... -------------------- no
2
2
 
3
- "gcc -o conftest -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-linux -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wall conftest.c -L. -L/home/samuel/.rubies/ruby-3.0.1/lib -Wl,-rpath,/home/samuel/.rubies/ruby-3.0.1/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-rpath,/home/samuel/.rubies/ruby-3.0.1/lib -L/home/samuel/.rubies/ruby-3.0.1/lib -lruby-static -lz -lpthread -lrt -lrt -lgmp -ldl -lcrypt -lm -lm -lc"
3
+ "clang -fdeclspec -o conftest -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-darwin20 -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -pipe -Wall conftest.c -L. -L/Users/samuel/.rubies/ruby-3.0.1/lib -L/opt/local/lib -L. -fstack-protector-strong -L/opt/local/lib -lruby.3.0-static -framework Security -framework Foundation -lpthread -lgmp -ldl -lobjc "
4
4
  checked program was:
5
5
  /* begin */
6
6
  1: #include "ruby.h"
@@ -11,7 +11,11 @@ checked program was:
11
11
  6: }
12
12
  /* end */
13
13
 
14
- "gcc -o conftest -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-linux -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wall conftest.c -L. -L/home/samuel/.rubies/ruby-3.0.1/lib -Wl,-rpath,/home/samuel/.rubies/ruby-3.0.1/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-rpath,/home/samuel/.rubies/ruby-3.0.1/lib -L/home/samuel/.rubies/ruby-3.0.1/lib -lruby-static -lz -lpthread -lrt -lrt -lgmp -ldl -lcrypt -lm -luring -lm -lc"
14
+ "clang -fdeclspec -o conftest -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-darwin20 -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -pipe -Wall conftest.c -L. -L/Users/samuel/.rubies/ruby-3.0.1/lib -L/opt/local/lib -L. -fstack-protector-strong -L/opt/local/lib -lruby.3.0-static -framework Security -framework Foundation -lpthread -lgmp -ldl -lobjc "
15
+ conftest.c:14:57: error: use of undeclared identifier 'rb_fiber_transfer_kw'
16
+ int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_fiber_transfer_kw; return !p; }
17
+ ^
18
+ 1 error generated.
15
19
  checked program was:
16
20
  /* begin */
17
21
  1: #include "ruby.h"
@@ -27,27 +31,69 @@ checked program was:
27
31
  11:
28
32
  12: return !!argv[argc];
29
33
  13: }
30
- 14:
31
- 15: int t(void) { ; return 0; }
34
+ 14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_fiber_transfer_kw; return !p; }
35
+ /* end */
36
+
37
+ "clang -fdeclspec -o conftest -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-darwin20 -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -pipe -Wall conftest.c -L. -L/Users/samuel/.rubies/ruby-3.0.1/lib -L/opt/local/lib -L. -fstack-protector-strong -L/opt/local/lib -lruby.3.0-static -framework Security -framework Foundation -lpthread -lgmp -ldl -lobjc "
38
+ Undefined symbols for architecture x86_64:
39
+ "_rb_fiber_transfer_kw", referenced from:
40
+ _t in conftest-3b7f21.o
41
+ ld: symbol(s) not found for architecture x86_64
42
+ clang: error: linker command failed with exit code 1 (use -v to see invocation)
43
+ checked program was:
44
+ /* begin */
45
+ 1: #include "ruby.h"
46
+ 2:
47
+ 3: /*top*/
48
+ 4: extern int t(void);
49
+ 5: int main(int argc, char **argv)
50
+ 6: {
51
+ 7: if (argc > 1000000) {
52
+ 8: int (* volatile tp)(void)=(int (*)(void))&t;
53
+ 9: printf("%d", (*tp)());
54
+ 10: }
55
+ 11:
56
+ 12: return !!argv[argc];
57
+ 13: }
58
+ 14: extern void rb_fiber_transfer_kw();
59
+ 15: int t(void) { rb_fiber_transfer_kw(); return 0; }
32
60
  /* end */
33
61
 
34
62
  --------------------
35
63
 
36
- have_header: checking for liburing.h... -------------------- yes
64
+ have_library: checking for -luring... -------------------- no
37
65
 
38
- "gcc -E -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-linux -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wall conftest.c -o conftest.i"
66
+ "clang -fdeclspec -o conftest -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-darwin20 -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -pipe -Wall conftest.c -L. -L/Users/samuel/.rubies/ruby-3.0.1/lib -L/opt/local/lib -L. -fstack-protector-strong -L/opt/local/lib -lruby.3.0-static -framework Security -framework Foundation -lpthread -lgmp -ldl -lobjc -luring "
67
+ ld: library not found for -luring
68
+ clang: error: linker command failed with exit code 1 (use -v to see invocation)
39
69
  checked program was:
40
70
  /* begin */
41
- 1: #include "ruby.h"
42
- 2:
43
- 3: #include <liburing.h>
71
+ 1: #include "ruby.h"
72
+ 2:
73
+ 3: /*top*/
74
+ 4: extern int t(void);
75
+ 5: int main(int argc, char **argv)
76
+ 6: {
77
+ 7: if (argc > 1000000) {
78
+ 8: int (* volatile tp)(void)=(int (*)(void))&t;
79
+ 9: printf("%d", (*tp)());
80
+ 10: }
81
+ 11:
82
+ 12: return !!argv[argc];
83
+ 13: }
84
+ 14:
85
+ 15: int t(void) { ; return 0; }
44
86
  /* end */
45
87
 
46
88
  --------------------
47
89
 
48
- have_header: checking for sys/epoll.h... -------------------- yes
90
+ have_header: checking for sys/epoll.h... -------------------- no
49
91
 
50
- "gcc -E -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-linux -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wall conftest.c -o conftest.i"
92
+ "clang -E -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-darwin20 -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -pipe -Wall conftest.c -o conftest.i"
93
+ conftest.c:3:10: fatal error: 'sys/epoll.h' file not found
94
+ #include <sys/epoll.h>
95
+ ^~~~~~~~~~~~~
96
+ 1 error generated.
51
97
  checked program was:
52
98
  /* begin */
53
99
  1: #include "ruby.h"
@@ -57,13 +103,9 @@ checked program was:
57
103
 
58
104
  --------------------
59
105
 
60
- have_header: checking for sys/event.h... -------------------- no
106
+ have_header: checking for sys/event.h... -------------------- yes
61
107
 
62
- "gcc -E -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-linux -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/home/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wall conftest.c -o conftest.i"
63
- conftest.c:3:10: fatal error: sys/event.h: No such file or directory
64
- 3 | #include <sys/event.h>
65
- | ^~~~~~~~~~~~~
66
- compilation terminated.
108
+ "clang -E -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-darwin20 -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -pipe -Wall conftest.c -o conftest.i"
67
109
  checked program was:
68
110
  /* begin */
69
111
  1: #include "ruby.h"
@@ -77,8 +119,7 @@ extconf.h is:
77
119
  /* begin */
78
120
  1: #ifndef EXTCONF_H
79
121
  2: #define EXTCONF_H
80
- 3: #define HAVE_LIBURING_H 1
81
- 4: #define HAVE_SYS_EPOLL_H 1
82
- 5: #endif
122
+ 3: #define HAVE_SYS_EVENT_H 1
123
+ 4: #endif
83
124
  /* end */
84
125
 
@@ -52,6 +52,24 @@ module Event
52
52
  @readable.delete(io) if remove_readable
53
53
  @writable.delete(io) if remove_writable
54
54
  end
55
+
56
+ def process_wait(fiber, pid, flags)
57
+ r, w = IO.pipe
58
+
59
+ thread = Thread.new do
60
+ Process::Status.wait(pid, flags)
61
+ ensure
62
+ w.close
63
+ end
64
+
65
+ self.io_wait(fiber, r, READABLE)
66
+
67
+ return thread.value
68
+ ensure
69
+ r.close
70
+ w.close
71
+ thread&.kill
72
+ end
55
73
 
56
74
  def select(duration = nil)
57
75
  readable, writable, _ = ::IO.select(@readable.keys, @writable.keys, nil, duration)
@@ -69,7 +87,7 @@ module Event
69
87
  end
70
88
 
71
89
  ready.each do |fiber, events|
72
- fiber.transfer(events)
90
+ fiber.transfer(events) if fiber.alive?
73
91
  end
74
92
  end
75
93
  end
data/lib/event/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Event
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: event
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-06 00:00:00.000000000 Z
11
+ date: 2021-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bake
@@ -74,22 +74,24 @@ extensions:
74
74
  extra_rdoc_files: []
75
75
  files:
76
76
  - ext/event/Makefile
77
+ - ext/event/backend.o
78
+ - ext/event/backend/backend.c
77
79
  - ext/event/backend/backend.h
78
80
  - ext/event/backend/epoll.c
79
81
  - ext/event/backend/epoll.h
80
82
  - ext/event/backend/kqueue.c
81
83
  - ext/event/backend/kqueue.h
84
+ - ext/event/backend/pidfd.c
82
85
  - ext/event/backend/uring.c
83
86
  - ext/event/backend/uring.h
84
- - ext/event/epoll.o
87
+ - ext/event/event.bundle
85
88
  - ext/event/event.c
86
89
  - ext/event/event.h
87
90
  - ext/event/event.o
88
- - ext/event/event.so
89
91
  - ext/event/extconf.h
90
92
  - ext/event/extconf.rb
93
+ - ext/event/kqueue.o
91
94
  - ext/event/mkmf.log
92
- - ext/event/uring.o
93
95
  - lib/event.rb
94
96
  - lib/event/backend.rb
95
97
  - lib/event/backend/select.rb
data/ext/event/epoll.o DELETED
Binary file
data/ext/event/event.so DELETED
Binary file
data/ext/event/uring.o DELETED
Binary file