event 0.8.2 → 0.9.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: 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.