event 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 62bded3e0e8e8929ef5f76b427a975f1444c215d3566423e17b6aecdcbbb1f0b
4
- data.tar.gz: 6c241f562c00af271443406efa52c935f84fb6b30023b4c7086a8c4ee5b7b965
3
+ metadata.gz: 3d1a02b3163aca45dcdb7ac4f3589e18894c3e753262d7934ea0f473c88e2a38
4
+ data.tar.gz: fac7fd3d48e616e1c03ca9cb6af19b8457c4dadb452261bb1f4b628d70297bcb
5
5
  SHA512:
6
- metadata.gz: 75b5af033d60eb53df18b9b6fe9805827ccd4bfef0f4e26943428ddb4aee43006ce4eb12897102d33d50b31834c7bbd0be70821f2bcd6fe30cab5a657839321a
7
- data.tar.gz: 57d719b1318c0740c58df4476ffb44719c8ded66d78889eeb60e15aead7d86e9778ad464a460dda4a2318f3435450e43778873aac8ea7a9c0150c37f828b4646
6
+ metadata.gz: 54c8d94a288dc450decd427c2bd7af850b635133b90ca25ee15f4f934c3e9b78cd8465402d1fabb9c4bae8ae3b7fef8c1849567e23303601a2bca4dfefc9acf3
7
+ data.tar.gz: 757e2b00714ace1767d732ab37c93372bd44d14da4911f46190b8ba0efcb1ba249743509fc3c68e957c4b24804ddd35a844257b81e279de0f3fd487d1058015e
data/ext/event/event.c CHANGED
@@ -26,9 +26,9 @@ VALUE Event_Selector = Qnil;
26
26
 
27
27
  void Init_event()
28
28
  {
29
- #ifdef HAVE_RB_EXT_RACTOR_SAFE
29
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
30
30
  rb_ext_ractor_safe(true);
31
- #endif
31
+ #endif
32
32
 
33
33
  Event = rb_define_module("Event");
34
34
  Event_Selector = rb_define_module_under(Event, "Selector");
data/ext/event/extconf.rb CHANGED
@@ -33,6 +33,7 @@ $CFLAGS << " -Wall"
33
33
  $srcs = ["event.c", "selector/selector.c"]
34
34
  $VPATH << "$(srcdir)/selector"
35
35
 
36
+ have_func('rb_ext_ractor_safe')
36
37
  have_func('&rb_fiber_transfer')
37
38
 
38
39
  if have_library('uring') and have_header('liburing.h')
@@ -49,6 +50,7 @@ end
49
50
 
50
51
  have_func("rb_io_descriptor")
51
52
  have_func("&rb_process_status_wait")
53
+ have_func('rb_fiber_current')
52
54
  have_func("&rb_fiber_raise")
53
55
 
54
56
  have_header('ruby/io/buffer.h')
@@ -112,12 +112,12 @@ VALUE Event_Selector_EPoll_close(VALUE self) {
112
112
  return Qnil;
113
113
  }
114
114
 
115
- VALUE Event_Selector_EPoll_transfer(int argc, VALUE *argv, VALUE self)
115
+ VALUE Event_Selector_EPoll_resume(int argc, VALUE *argv, VALUE self)
116
116
  {
117
117
  struct Event_Selector_EPoll *data = NULL;
118
118
  TypedData_Get_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
119
119
 
120
- Event_Selector_wait_and_transfer(&data->backend, argc, argv);
120
+ Event_Selector_resume(&data->backend, argc, argv);
121
121
 
122
122
  return Qnil;
123
123
  }
@@ -550,7 +550,7 @@ void Init_Event_Selector_EPoll(VALUE Event_Selector) {
550
550
  rb_define_alloc_func(Event_Selector_EPoll, Event_Selector_EPoll_allocate);
551
551
  rb_define_method(Event_Selector_EPoll, "initialize", Event_Selector_EPoll_initialize, 1);
552
552
 
553
- rb_define_method(Event_Selector_EPoll, "transfer", Event_Selector_EPoll_transfer, -1);
553
+ rb_define_method(Event_Selector_EPoll, "resume", Event_Selector_EPoll_resume, -1);
554
554
  rb_define_method(Event_Selector_EPoll, "yield", Event_Selector_EPoll_yield, 0);
555
555
  rb_define_method(Event_Selector_EPoll, "push", Event_Selector_EPoll_push, 1);
556
556
  rb_define_method(Event_Selector_EPoll, "raise", Event_Selector_EPoll_raise, -1);
@@ -112,12 +112,12 @@ VALUE Event_Selector_KQueue_close(VALUE self) {
112
112
  return Qnil;
113
113
  }
114
114
 
115
- VALUE Event_Selector_KQueue_transfer(int argc, VALUE *argv, VALUE self)
115
+ VALUE Event_Selector_KQueue_resume(int argc, VALUE *argv, VALUE self)
116
116
  {
117
117
  struct Event_Selector_KQueue *data = NULL;
118
118
  TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
119
119
 
120
- return Event_Selector_wait_and_transfer(&data->backend, argc, argv);
120
+ return Event_Selector_resume(&data->backend, argc, argv);
121
121
  }
122
122
 
123
123
  VALUE Event_Selector_KQueue_yield(VALUE self)
@@ -379,7 +379,7 @@ VALUE io_read_loop(VALUE _arguments) {
379
379
  offset += result;
380
380
  length -= result;
381
381
  } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
382
- Event_Selector_KQueue_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(READABLE));
382
+ Event_Selector_KQueue_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(EVENT_READABLE));
383
383
  } else {
384
384
  rb_sys_fail("Event_Selector_KQueue_io_read");
385
385
  }
@@ -454,7 +454,7 @@ VALUE io_write_loop(VALUE _arguments) {
454
454
  offset += result;
455
455
  length -= result;
456
456
  } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
457
- Event_Selector_KQueue_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(WRITABLE));
457
+ Event_Selector_KQueue_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(EVENT_WRITABLE));
458
458
  } else {
459
459
  rb_sys_fail("Event_Selector_KQueue_io_write");
460
460
  }
@@ -616,7 +616,7 @@ void Init_Event_Selector_KQueue(VALUE Event_Selector) {
616
616
  rb_define_alloc_func(Event_Selector_KQueue, Event_Selector_KQueue_allocate);
617
617
  rb_define_method(Event_Selector_KQueue, "initialize", Event_Selector_KQueue_initialize, 1);
618
618
 
619
- rb_define_method(Event_Selector_KQueue, "transfer", Event_Selector_KQueue_transfer, -1);
619
+ rb_define_method(Event_Selector_KQueue, "resume", Event_Selector_KQueue_resume, -1);
620
620
  rb_define_method(Event_Selector_KQueue, "yield", Event_Selector_KQueue_yield, 0);
621
621
  rb_define_method(Event_Selector_KQueue, "push", Event_Selector_KQueue_push, 1);
622
622
  rb_define_method(Event_Selector_KQueue, "raise", Event_Selector_KQueue_raise, -1);
@@ -23,11 +23,20 @@
23
23
 
24
24
  static ID id_transfer, id_alive_p;
25
25
 
26
- #ifndef HAVE__RB_FIBER_TRANSFER
27
26
  VALUE Event_Selector_fiber_transfer(VALUE fiber, int argc, VALUE *argv) {
28
- return rb_funcallv(fiber, id_transfer, argc, argv);
29
- }
27
+ // TODO Consider introducing something like `rb_fiber_scheduler_transfer(...)`.
28
+ #ifdef HAVE__RB_FIBER_TRANSFER
29
+ if (RTEST(rb_fiber_alive_p(fiber))) {
30
+ return rb_fiber_transfer(fiber, argc, argv);
31
+ }
32
+ #else
33
+ if (RTEST(rb_funcall(fiber, id_alive_p, 0))) {
34
+ return rb_funcallv(fiber, id_transfer, argc, argv);
35
+ }
30
36
  #endif
37
+
38
+ return Qnil;
39
+ }
31
40
 
32
41
  #ifndef HAVE__RB_FIBER_RAISE
33
42
  static ID id_raise;
@@ -37,6 +46,15 @@ VALUE Event_Selector_fiber_raise(VALUE fiber, int argc, VALUE *argv) {
37
46
  }
38
47
  #endif
39
48
 
49
+ #ifndef HAVE_RB_FIBER_CURRENT
50
+ static ID id_current;
51
+
52
+ static VALUE rb_fiber_current() {
53
+ return rb_funcall(rb_cFiber, id_current, 0);
54
+ }
55
+ #endif
56
+
57
+
40
58
  #ifndef HAVE_RB_IO_DESCRIPTOR
41
59
  static ID id_fileno;
42
60
 
@@ -81,6 +99,10 @@ void Init_Event_Selector(VALUE Event_Selector) {
81
99
  id_raise = rb_intern("raise");
82
100
  #endif
83
101
 
102
+ #ifndef HAVE_RB_FIBER_CURRENT
103
+ id_current = rb_intern("current");
104
+ #endif
105
+
84
106
  #ifndef HAVE_RB_IO_DESCRIPTOR
85
107
  id_fileno = rb_intern("fileno");
86
108
  #endif
@@ -142,7 +164,7 @@ static VALUE wait_and_transfer_ensure(VALUE _arguments) {
142
164
  return Qnil;
143
165
  }
144
166
 
145
- VALUE Event_Selector_wait_and_transfer(struct Event_Selector *backend, int argc, VALUE *argv)
167
+ VALUE Event_Selector_resume(struct Event_Selector *backend, int argc, VALUE *argv)
146
168
  {
147
169
  rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
148
170
 
@@ -38,11 +38,7 @@ enum Event {
38
38
 
39
39
  void Init_Event_Selector();
40
40
 
41
- #ifdef HAVE__RB_FIBER_TRANSFER
42
- #define Event_Selector_fiber_transfer(fiber, argc, argv) rb_fiber_transfer(fiber, argc, argv)
43
- #else
44
41
  VALUE Event_Selector_fiber_transfer(VALUE fiber, int argc, VALUE *argv);
45
- #endif
46
42
 
47
43
  #ifdef HAVE__RB_FIBER_RAISE
48
44
  #define Event_Selector_fiber_raise(fiber, argc, argv) rb_fiber_raise(fiber, argc, argv)
@@ -108,13 +104,13 @@ void Event_Selector_mark(struct Event_Selector *backend) {
108
104
  }
109
105
  }
110
106
 
111
- VALUE Event_Selector_wait_and_transfer(struct Event_Selector *backend, int argc, VALUE *argv);
107
+ VALUE Event_Selector_resume(struct Event_Selector *backend, int argc, VALUE *argv);
112
108
  VALUE Event_Selector_wait_and_raise(struct Event_Selector *backend, int argc, VALUE *argv);
113
109
 
114
110
  static inline
115
111
  VALUE Event_Selector_yield(struct Event_Selector *backend)
116
112
  {
117
- return Event_Selector_wait_and_transfer(backend, 1, &backend->loop);
113
+ return Event_Selector_resume(backend, 1, &backend->loop);
118
114
  }
119
115
 
120
116
  void Event_Selector_queue_push(struct Event_Selector *backend, VALUE fiber);
@@ -115,12 +115,12 @@ VALUE Event_Selector_URing_close(VALUE self) {
115
115
  return Qnil;
116
116
  }
117
117
 
118
- VALUE Event_Selector_URing_transfer(int argc, VALUE *argv, VALUE self)
118
+ VALUE Event_Selector_URing_resume(int argc, VALUE *argv, VALUE self)
119
119
  {
120
120
  struct Event_Selector_URing *data = NULL;
121
121
  TypedData_Get_Struct(self, struct Event_Selector_URing, &Event_Selector_URing_Type, data);
122
122
 
123
- Event_Selector_wait_and_transfer(&data->backend, argc, argv);
123
+ Event_Selector_resume(&data->backend, argc, argv);
124
124
 
125
125
  return Qnil;
126
126
  }
@@ -615,7 +615,7 @@ void Init_Event_Selector_URing(VALUE Event_Selector) {
615
615
  rb_define_alloc_func(Event_Selector_URing, Event_Selector_URing_allocate);
616
616
  rb_define_method(Event_Selector_URing, "initialize", Event_Selector_URing_initialize, 1);
617
617
 
618
- rb_define_method(Event_Selector_URing, "transfer", Event_Selector_URing_transfer, -1);
618
+ rb_define_method(Event_Selector_URing, "resume", Event_Selector_URing_resume, -1);
619
619
  rb_define_method(Event_Selector_URing, "yield", Event_Selector_URing_yield, 0);
620
620
  rb_define_method(Event_Selector_URing, "push", Event_Selector_URing_push, 1);
621
621
  rb_define_method(Event_Selector_URing, "raise", Event_Selector_URing_raise, -1);
data/lib/event.rb CHANGED
@@ -20,7 +20,6 @@
20
20
 
21
21
  require_relative 'event/version'
22
22
  require_relative 'event/selector'
23
- require_relative 'event/selector'
24
23
 
25
24
  module Event
26
25
  # These constants are the same as those defined in IO.
@@ -36,30 +36,53 @@ module Event
36
36
  @writable = nil
37
37
  end
38
38
 
39
- def transfer(fiber, *arguments)
40
- @ready.push(Fiber.current)
39
+ Queue = Struct.new(:fiber) do
40
+ def transfer(*arguments)
41
+ fiber&.transfer(*arguments)
42
+ end
43
+
44
+ def alive?
45
+ fiber&.alive?
46
+ end
47
+
48
+ def nullify
49
+ self.fiber = nil
50
+ end
51
+ end
52
+
53
+ # Transfer from the current fiber to the specified fiber. Put the current fiber into the ready list.
54
+ def resume(fiber, *arguments)
55
+ queue = Queue.new(Fiber.current)
56
+ @ready.push(queue)
57
+
41
58
  fiber.transfer(*arguments)
42
59
  ensure
43
- @ready.delete(fiber)
60
+ queue.nullify
44
61
  end
45
62
 
63
+ # Yield from the current fiber back to the event loop. Put the current fiber into the ready list.
46
64
  def yield
47
- fiber = Fiber.current
48
- @ready.push(fiber)
65
+ queue = Queue.new(Fiber.current)
66
+ @ready.push(queue)
67
+
49
68
  @loop.transfer
50
69
  ensure
51
- @ready.delete(fiber)
70
+ queue.nullify
52
71
  end
53
72
 
73
+ # Append the given fiber into the ready list.
54
74
  def push(fiber)
55
75
  @ready.push(fiber)
56
76
  end
57
77
 
78
+ # Transfer to the given fiber and raise an exception. Put the current fiber into the ready list.
58
79
  def raise(fiber, *arguments)
59
- @ready.push(Fiber.current)
80
+ queue = Queue.new(Fiber.current)
81
+ @ready.push(queue)
82
+
60
83
  fiber.raise(*arguments)
61
84
  ensure
62
- @ready.delete(fiber)
85
+ queue.nullify
63
86
  end
64
87
 
65
88
  def ready?
@@ -150,7 +173,7 @@ module Event
150
173
  thread&.kill
151
174
  end
152
175
 
153
- def select(duration = nil)
176
+ private def pop_ready
154
177
  if @ready.any?
155
178
  ready = @ready
156
179
  @ready = Array.new
@@ -158,6 +181,14 @@ module Event
158
181
  ready.each do |fiber|
159
182
  fiber.transfer if fiber.alive?
160
183
  end
184
+
185
+ return true
186
+ end
187
+ end
188
+
189
+ def select(duration = nil)
190
+ if pop_ready
191
+ duration = 0
161
192
  end
162
193
 
163
194
  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.8.2"
2
+ VERSION = "0.9.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.8.2
4
+ version: 0.9.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-07-14 00:00:00.000000000 Z
11
+ date: 2021-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bake
@@ -109,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  requirements: []
112
- rubygems_version: 3.2.15
112
+ rubygems_version: 3.2.22
113
113
  signing_key:
114
114
  specification_version: 4
115
115
  summary: An event loop.