event 0.4.4 → 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: 73f2afe0a8b33db63d97b134f1c8c2ae2778d2a1982ee335e1fa17df2c6a1aba
4
- data.tar.gz: 608e5adf0b404609b4ffebdfce321e1a6aa09d4e0067b2157c48562536599006
3
+ metadata.gz: 932f834070b1bb738a09a9cb306599f80386755e4bfa2c78b502715acecf56b7
4
+ data.tar.gz: a04db89605437563a594e9012adb50a60af4a6c6dfacdd048ec0b03048f68010
5
5
  SHA512:
6
- metadata.gz: 1b33aa76aca72169ad6c8f0b054b58f960a8f255bd77d12d44ab85622367474cac9f65edd3db39e8d414d27851963476301757465aa874879d794c11437743d5
7
- data.tar.gz: b30be2add6fe30be434ed728ebd49bec2ded7b3cb290f9512d7856be4508576342d4164ce6d018d345ba0bc4e8397d8dde4836cdb71566dba677036295fc37c5
6
+ metadata.gz: 074e688c34260fe28c3f15857c731052a745605deafd7d75bd07f9e0dc59aeed34d6633a05f5259d03a357c7f5c45762ef7de53a2f5dfc5c32213471f66eb847
7
+ data.tar.gz: 2214b5749ca680a7892e01539ec962b976f4fad480aa4a5d6d0d589981af8944a2ac94b03484e3e7e7936fd4bbf344418b72cb457fa229ffda11ff91bae9e5e8
data/ext/event/Makefile CHANGED
@@ -3,7 +3,6 @@ SHELL = /bin/sh
3
3
 
4
4
  # V=0 quiet, V=1 verbose. other values don't work.
5
5
  V = 0
6
- V0 = $(V:0=)
7
6
  Q1 = $(V:1=)
8
7
  Q = $(Q1:0=@)
9
8
  ECHO1 = $(V:1=@ :)
@@ -13,12 +12,12 @@ NULLCMD = :
13
12
  #### Start of system configuration section. ####
14
13
 
15
14
  srcdir = .
16
- topdir = /home/samuel/.rubies/ruby-head/include/ruby-3.1.0
15
+ topdir = /Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0
17
16
  hdrdir = $(topdir)
18
- arch_hdrdir = /home/samuel/.rubies/ruby-head/include/ruby-3.1.0/x86_64-linux
17
+ arch_hdrdir = /Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-darwin20
19
18
  PATH_SEPARATOR = :
20
19
  VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby:$(srcdir)/backend
21
- prefix = $(DESTDIR)/home/samuel/.rubies/ruby-head
20
+ prefix = $(DESTDIR)/Users/samuel/.rubies/ruby-3.0.1
22
21
  rubysitearchprefix = $(rubylibprefix)/$(sitearch)
23
22
  rubyarchprefix = $(rubylibprefix)/$(arch)
24
23
  rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
@@ -51,7 +50,7 @@ dvidir = $(docdir)
51
50
  htmldir = $(docdir)
52
51
  infodir = $(datarootdir)/info
53
52
  docdir = $(datarootdir)/doc/$(PACKAGE)
54
- oldincludedir = $(DESTDIR)/usr/include
53
+ oldincludedir = $(SDKROOT)/usr/include
55
54
  includedir = $(prefix)/include
56
55
  runstatedir = $(localstatedir)/run
57
56
  localstatedir = $(prefix)/var
@@ -66,12 +65,12 @@ archdir = $(rubyarchdir)
66
65
 
67
66
 
68
67
  CC_WRAPPER =
69
- CC = gcc
70
- CXX = g++
68
+ CC = clang -fdeclspec
69
+ CXX = clang++ -fdeclspec
71
70
  LIBRUBY = $(LIBRUBY_A)
72
71
  LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
73
- LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir)
74
- 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)
75
74
  empty =
76
75
  OUTFLAG = -o $(empty)
77
76
  COUTFLAG = -o $(empty)
@@ -80,43 +79,43 @@ CSRCFLAG = $(empty)
80
79
  RUBY_EXTCONF_H = extconf.h
81
80
  cflags = $(optflags) $(debugflags) $(warnflags)
82
81
  cxxflags =
83
- optflags = -O3 -fno-fast-math
82
+ optflags = -O3
84
83
  debugflags = -ggdb3
85
- 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 -Wundef
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
86
85
  cppflags =
87
- CCDLFLAGS = -fPIC
88
- CFLAGS = $(CCDLFLAGS) $(cflags) -Wall $(ARCH_FLAG)
86
+ CCDLFLAGS = -fno-common
87
+ CFLAGS = $(CCDLFLAGS) $(cflags) -pipe -Wall $(ARCH_FLAG)
89
88
  INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
90
89
  DEFS =
91
- 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)
92
91
  CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG)
93
- ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic
94
- 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
95
94
  ARCH_FLAG =
96
95
  DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
97
- LDSHARED = $(CC) -shared
98
- LDSHAREDXX = $(CXX) -shared
99
- AR = gcc-ar
96
+ LDSHARED = $(CC) -dynamic -bundle
97
+ LDSHAREDXX = $(CXX) -dynamic -bundle
98
+ AR = ar
100
99
  EXEEXT =
101
100
 
102
101
  RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)
103
- RUBY_SO_NAME = ruby
102
+ RUBY_SO_NAME = ruby.3.0
104
103
  RUBYW_INSTALL_NAME =
105
104
  RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
106
105
  RUBYW_BASE_NAME = rubyw
107
106
  RUBY_BASE_NAME = ruby
108
107
 
109
- arch = x86_64-linux
108
+ arch = x86_64-darwin20
110
109
  sitearch = $(arch)
111
- ruby_version = 3.1.0
110
+ ruby_version = 3.0.0
112
111
  ruby = $(bindir)/$(RUBY_BASE_NAME)
113
112
  RUBY = $(ruby)
114
113
  ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h $(RUBY_EXTCONF_H)
115
114
 
116
115
  RM = rm -f
117
116
  RM_RF = $(RUBY) -run -e rm -- -rf
118
- RMDIRS = rmdir --ignore-fail-on-non-empty -p
119
- MAKEDIRS = /usr/bin/mkdir -p
117
+ RMDIRS = rmdir -p
118
+ MAKEDIRS = /opt/local/bin/gmkdir -p
120
119
  INSTALL = /usr/bin/install -c
121
120
  INSTALL_PROG = $(INSTALL) -m 0755
122
121
  INSTALL_DATA = $(INSTALL) -m 644
@@ -126,8 +125,8 @@ TOUCH = exit >
126
125
  #### End of system configuration section. ####
127
126
 
128
127
  preload =
129
- libpath = . $(libdir)
130
- LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir)
128
+ libpath = . $(libdir) /opt/local/lib
129
+ LIBPATH = -L. -L$(libdir) -L/opt/local/lib
131
130
  DEFFILE =
132
131
 
133
132
  CLEANFILES = mkmf.log
@@ -138,16 +137,16 @@ extout =
138
137
  extout_prefix =
139
138
  target_prefix = /event
140
139
  LOCAL_LIBS =
141
- LIBS = -luring -lm -lc
140
+ LIBS =
142
141
  ORIG_SRCS = event.c
143
- SRCS = $(ORIG_SRCS) event.c backend.c uring.c epoll.c
144
- OBJS = event.o backend.o uring.o epoll.o
142
+ SRCS = $(ORIG_SRCS) event.c backend.c kqueue.c
143
+ OBJS = event.o backend.o kqueue.o
145
144
  HDRS = $(srcdir)/event.h $(srcdir)/extconf.h
146
145
  LOCAL_HDRS =
147
146
  TARGET = event
148
147
  TARGET_NAME = event
149
148
  TARGET_ENTRY = Init_$(TARGET_NAME)
150
- DLLIB = $(TARGET).so
149
+ DLLIB = $(TARGET).bundle
151
150
  EXTSTATIC =
152
151
  STATIC_LIB =
153
152
 
@@ -156,8 +155,8 @@ BINDIR = $(bindir)
156
155
  RUBYCOMMONDIR = $(sitedir)$(target_prefix)
157
156
  RUBYLIBDIR = $(sitelibdir)$(target_prefix)
158
157
  RUBYARCHDIR = $(sitearchdir)$(target_prefix)
159
- HDRDIR = $(sitehdrdir)$(target_prefix)
160
- ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix)
158
+ HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
159
+ ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
161
160
  TARGET_SO_DIR =
162
161
  TARGET_SO = $(TARGET_SO_DIR)$(DLLIB)
163
162
  CLEANLIBS = $(TARGET_SO)
@@ -261,6 +260,7 @@ $(TARGET_SO): $(OBJS) Makefile
261
260
  $(ECHO) linking shared-object event/$(DLLIB)
262
261
  -$(Q)$(RM) $(@)
263
262
  $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
263
+ $(Q) $(POSTLINK)
264
264
 
265
265
 
266
266
 
data/ext/event/backend.o CHANGED
Binary file
@@ -20,20 +20,45 @@
20
20
 
21
21
  #include "backend.h"
22
22
 
23
- static ID id_transfer, id_alive_p;
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;
24
31
 
25
32
  void Init_Event_Backend(VALUE Event_Backend) {
26
33
  id_transfer = rb_intern("transfer");
27
- id_alive_p = rb_intern("alive?");
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
28
46
  }
29
47
 
30
48
  VALUE
31
- Event_Backend_resume_safe(VALUE fiber, VALUE result) {
32
- VALUE alive = rb_funcall(fiber, id_alive_p, 0);
49
+ Event_Backend_transfer_result(VALUE fiber, VALUE result) {
50
+ // if (!RTEST(rb_fiber_alive_p(fiber))) {
51
+ // return Qnil;
52
+ // }
33
53
 
34
- if (RTEST(alive)) {
35
- return rb_funcall(fiber, id_transfer, 1, result);
36
- } else {
37
- return Qnil;
38
- }
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));
39
64
  }
@@ -32,5 +32,7 @@ enum Event {
32
32
  void
33
33
  Init_Event_Backend();
34
34
 
35
- VALUE
36
- Event_Backend_resume_safe(VALUE fiber, VALUE argument);
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
  };
@@ -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
- Event_Backend_resume_safe(fiber, 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
  };
@@ -326,7 +407,7 @@ VALUE Event_Backend_KQueue_select(VALUE self, VALUE duration) {
326
407
  VALUE fiber = (VALUE)arguments.events[i].udata;
327
408
  VALUE result = INT2NUM(arguments.events[i].filter);
328
409
 
329
- Event_Backend_resume_safe(fiber, result);
410
+ Event_Backend_transfer_result(fiber, result);
330
411
  }
331
412
 
332
413
  return INT2NUM(arguments.count);
@@ -334,7 +415,6 @@ VALUE Event_Backend_KQueue_select(VALUE self, VALUE duration) {
334
415
 
335
416
  void Init_Event_Backend_KQueue(VALUE Event_Backend) {
336
417
  id_fileno = rb_intern("fileno");
337
- id_transfer = rb_intern("transfer");
338
418
 
339
419
  Event_Backend_KQueue = rb_define_class_under(Event_Backend, "KQueue", rb_cObject);
340
420
 
@@ -344,4 +424,5 @@ void Init_Event_Backend_KQueue(VALUE Event_Backend) {
344
424
 
345
425
  rb_define_method(Event_Backend_KQueue, "io_wait", Event_Backend_KQueue_io_wait, 3);
346
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);
347
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
 
@@ -239,6 +291,7 @@ VALUE Event_Backend_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffe
239
291
 
240
292
  int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
241
293
  struct io_uring_sqe *sqe = io_get_sqe(data);
294
+ assert(sqe);
242
295
 
243
296
  struct iovec iovecs[1];
244
297
  iovecs[0].iov_base = RSTRING_PTR(buffer) + NUM2SIZET(offset);
@@ -250,7 +303,7 @@ VALUE Event_Backend_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffe
250
303
 
251
304
  // fprintf(stderr, "prep_readv(%p, %d, %ld)\n", sqe, descriptor, iovecs[0].iov_len);
252
305
 
253
- int result = NUM2INT(rb_funcall(data->loop, id_transfer, 0));
306
+ int result = NUM2INT(Event_Backend_transfer(data->loop));
254
307
 
255
308
  if (result < 0) {
256
309
  rb_syserr_fail(-result, strerror(-result));
@@ -282,7 +335,7 @@ VALUE Event_Backend_URing_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buff
282
335
 
283
336
  // fprintf(stderr, "prep_writev(%p, %d, %ld)\n", sqe, descriptor, iovecs[0].iov_len);
284
337
 
285
- int result = NUM2INT(rb_funcall(data->loop, id_transfer, 0));
338
+ int result = NUM2INT(Event_Backend_transfer(data->loop));
286
339
 
287
340
  if (result < 0) {
288
341
  rb_syserr_fail(-result, strerror(-result));
@@ -325,8 +378,7 @@ int timeout_nonblocking(struct __kernel_timespec *timespec) {
325
378
  struct select_arguments {
326
379
  struct Event_Backend_URing *data;
327
380
 
328
- int count;
329
- struct io_uring_cqe **cqes;
381
+ int result;
330
382
 
331
383
  struct __kernel_timespec storage;
332
384
  struct __kernel_timespec *timeout;
@@ -338,17 +390,8 @@ void * select_internal(void *_arguments) {
338
390
 
339
391
  io_uring_submit(&arguments->data->ring);
340
392
 
341
- int result = io_uring_wait_cqes(&arguments->data->ring, arguments->cqes, 1, arguments->timeout, NULL);
342
-
343
- if (result == -ETIME) {
344
- // If waiting resulted in a timeout, there are 0 events.
345
- arguments->count = 0;
346
- } else if (result == 0) {
347
- // Otherwise, there was no error, at least 1 event was reported. So we ask for them all.
348
- arguments->count = io_uring_peek_batch_cqe(&arguments->data->ring, arguments->cqes, URING_MAX_EVENTS);
349
- } else {
350
- arguments->count = result;
351
- }
393
+ struct io_uring_cqe *cqe = NULL;
394
+ arguments->result = io_uring_wait_cqe_timeout(&arguments->data->ring, &cqe, arguments->timeout);
352
395
 
353
396
  return NULL;
354
397
  }
@@ -357,21 +400,52 @@ static
357
400
  int select_internal_without_gvl(struct select_arguments *arguments) {
358
401
  rb_thread_call_without_gvl(select_internal, (void *)arguments, RUBY_UBF_IO, 0);
359
402
 
360
- if (arguments->count < 0) {
361
- 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;
362
410
  }
363
411
 
364
- return arguments->count;
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);
439
+ }
440
+
441
+ return completed;
365
442
  }
366
443
 
367
444
  VALUE Event_Backend_URing_select(VALUE self, VALUE duration) {
368
445
  struct Event_Backend_URing *data = NULL;
369
446
  TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
370
447
 
371
- struct io_uring_cqe *cqes[URING_MAX_EVENTS];
372
-
373
- // This is a non-blocking operation:
374
- int result = io_uring_peek_batch_cqe(&data->ring, cqes, URING_MAX_EVENTS);
448
+ int result = select_process_completions(&data->ring);
375
449
 
376
450
  if (result < 0) {
377
451
  rb_syserr_fail(-result, strerror(-result));
@@ -379,7 +453,6 @@ VALUE Event_Backend_URing_select(VALUE self, VALUE duration) {
379
453
  // We might need to wait for events:
380
454
  struct select_arguments arguments = {
381
455
  .data = data,
382
- .cqes = cqes,
383
456
  .timeout = NULL,
384
457
  };
385
458
 
@@ -389,34 +462,16 @@ VALUE Event_Backend_URing_select(VALUE self, VALUE duration) {
389
462
  result = select_internal_without_gvl(&arguments);
390
463
  } else {
391
464
  io_uring_submit(&data->ring);
392
- result = io_uring_peek_batch_cqe(&data->ring, cqes, URING_MAX_EVENTS);
393
465
  }
394
466
  }
395
467
 
396
- // fprintf(stderr, "cqes count=%d\n", result);
397
-
398
- for (int i = 0; i < result; i += 1) {
399
- // If the operation was cancelled, or the operation has no user data (fiber):
400
- if (cqes[i]->res == -ECANCELED || cqes[i]->user_data == 0) {
401
- continue;
402
- }
403
-
404
- VALUE fiber = (VALUE)io_uring_cqe_get_data(cqes[i]);
405
- VALUE result = INT2NUM(cqes[i]->res);
406
-
407
- // fprintf(stderr, "cqes[i] res=%d user_data=%p\n", cqes[i]->res, (void*)cqes[i]->user_data);
408
-
409
- io_uring_cqe_seen(&data->ring, cqes[i]);
410
-
411
- Event_Backend_resume_safe(fiber, result);
412
- }
468
+ result = select_process_completions(&data->ring);
413
469
 
414
470
  return INT2NUM(result);
415
471
  }
416
472
 
417
473
  void Init_Event_Backend_URing(VALUE Event_Backend) {
418
474
  id_fileno = rb_intern("fileno");
419
- id_transfer = rb_intern("transfer");
420
475
 
421
476
  Event_Backend_URing = rb_define_class_under(Event_Backend, "URing", rb_cObject);
422
477
 
@@ -429,4 +484,5 @@ void Init_Event_Backend_URing(VALUE Event_Backend) {
429
484
 
430
485
  rb_define_method(Event_Backend_URing, "io_read", Event_Backend_URing_io_read, 5);
431
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);
432
488
  }
Binary file
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
@@ -33,6 +33,9 @@ $CFLAGS << " -Wall"
33
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-head/include/ruby-3.1.0/x86_64-linux -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0/ruby/backward -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0 -I. -O3 -fno-fast-math -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 -Wundef -Wall conftest.c -L. -L/home/samuel/.rubies/ruby-head/lib -Wl,-rpath,/home/samuel/.rubies/ruby-head/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-rpath,/home/samuel/.rubies/ruby-head/lib -L/home/samuel/.rubies/ruby-head/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-head/include/ruby-3.1.0/x86_64-linux -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0/ruby/backward -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0 -I. -O3 -fno-fast-math -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 -Wundef -Wall conftest.c -L. -L/home/samuel/.rubies/ruby-head/lib -Wl,-rpath,/home/samuel/.rubies/ruby-head/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,-rpath,/home/samuel/.rubies/ruby-head/lib -L/home/samuel/.rubies/ruby-head/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 -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0/x86_64-linux -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0/ruby/backward -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0 -I. -O3 -fno-fast-math -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 -Wundef -Wall -c conftest.c"
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 -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0/x86_64-linux -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0/ruby/backward -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0 -I. -O3 -fno-fast-math -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 -Wundef -Wall -c conftest.c"
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 -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0/x86_64-linux -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0/ruby/backward -I/home/samuel/.rubies/ruby-head/include/ruby-3.1.0 -I. -O3 -fno-fast-math -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 -Wundef -Wall -c conftest.c"
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)
data/lib/event/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Event
2
- VERSION = "0.4.4"
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.4
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-11 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
@@ -81,17 +81,17 @@ files:
81
81
  - ext/event/backend/epoll.h
82
82
  - ext/event/backend/kqueue.c
83
83
  - ext/event/backend/kqueue.h
84
+ - ext/event/backend/pidfd.c
84
85
  - ext/event/backend/uring.c
85
86
  - ext/event/backend/uring.h
86
- - ext/event/epoll.o
87
+ - ext/event/event.bundle
87
88
  - ext/event/event.c
88
89
  - ext/event/event.h
89
90
  - ext/event/event.o
90
- - ext/event/event.so
91
91
  - ext/event/extconf.h
92
92
  - ext/event/extconf.rb
93
+ - ext/event/kqueue.o
93
94
  - ext/event/mkmf.log
94
- - ext/event/uring.o
95
95
  - lib/event.rb
96
96
  - lib/event/backend.rb
97
97
  - lib/event/backend/select.rb
@@ -117,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
117
  - !ruby/object:Gem::Version
118
118
  version: '0'
119
119
  requirements: []
120
- rubygems_version: 3.3.0.dev
120
+ rubygems_version: 3.2.15
121
121
  signing_key:
122
122
  specification_version: 4
123
123
  summary: An event loop.
data/ext/event/epoll.o DELETED
Binary file
data/ext/event/event.so DELETED
Binary file
data/ext/event/uring.o DELETED
Binary file