event 0.8.1 → 0.9.2

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: 6d2702a6092a7c9a3bbdce138f68335548a7cd6a84087ea4244d59ab40854a79
4
- data.tar.gz: 46d3de2b0d5e18c61ebb6b64de6001385e85228663e4b81ab7130e227f526980
3
+ metadata.gz: 9fab46d1f87926ce1c2c93877e6ca031b5946477479f3801b19fa099267f09ca
4
+ data.tar.gz: 7b04c272e7032227ddee671d1b4341674bd19fd8d3ee4fa87808d331973c4b71
5
5
  SHA512:
6
- metadata.gz: 06ce15bc3d291bc7703978f178b2505b18fb8bb4f0e69ca49a44d0461d20beca89b60356cfe2bfeca54042ce862bc0667c320239f7e64f14eeeb1b1f4188e293
7
- data.tar.gz: 4acaed11e8f3eba30e91002511ad73787a269e4958360c2022b4cc9e8f5f232582e919c5555a180d61ef1af2e075c858a85c55643464d622e21e4bf15c9de323
6
+ metadata.gz: 5b5f1c414836b039caad30b772523aedd8d8cd975d482e0ccddddea12b6c0cb931c91955ff2ca60b90cf3346cfc392db0c41df923f1f8404866d6b8c7270d43a
7
+ data.tar.gz: c0352b81e5fdfed6c90c2cbb82b4ecc9ba2395dce98e604777be512b68938a67855644f73c0ef6956a02b8533af744d642bc99cf1785d698af0b4692bcd60511
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,22 @@ 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_transfer(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_fiber_transfer(data->backend.loop, 0, NULL);
121
+
122
+ return Qnil;
123
+ }
124
+
125
+ VALUE Event_Selector_EPoll_resume(int argc, VALUE *argv, VALUE self)
126
+ {
127
+ struct Event_Selector_EPoll *data = NULL;
128
+ TypedData_Get_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
129
+
130
+ Event_Selector_resume(&data->backend, argc, argv);
121
131
 
122
132
  return Qnil;
123
133
  }
@@ -550,7 +560,8 @@ void Init_Event_Selector_EPoll(VALUE Event_Selector) {
550
560
  rb_define_alloc_func(Event_Selector_EPoll, Event_Selector_EPoll_allocate);
551
561
  rb_define_method(Event_Selector_EPoll, "initialize", Event_Selector_EPoll_initialize, 1);
552
562
 
553
- rb_define_method(Event_Selector_EPoll, "transfer", Event_Selector_EPoll_transfer, -1);
563
+ rb_define_method(Event_Selector_EPoll, "transfer", Event_Selector_EPoll_transfer, 0);
564
+ rb_define_method(Event_Selector_EPoll, "resume", Event_Selector_EPoll_resume, -1);
554
565
  rb_define_method(Event_Selector_EPoll, "yield", Event_Selector_EPoll_yield, 0);
555
566
  rb_define_method(Event_Selector_EPoll, "push", Event_Selector_EPoll_push, 1);
556
567
  rb_define_method(Event_Selector_EPoll, "raise", Event_Selector_EPoll_raise, -1);
@@ -112,12 +112,22 @@ 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_transfer(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
+ Event_Selector_fiber_transfer(data->backend.loop, 0, NULL);
121
+
122
+ return Qnil;
123
+ }
124
+
125
+ VALUE Event_Selector_KQueue_resume(int argc, VALUE *argv, VALUE self)
126
+ {
127
+ struct Event_Selector_KQueue *data = NULL;
128
+ TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
129
+
130
+ return Event_Selector_resume(&data->backend, argc, argv);
121
131
  }
122
132
 
123
133
  VALUE Event_Selector_KQueue_yield(VALUE self)
@@ -379,7 +389,7 @@ VALUE io_read_loop(VALUE _arguments) {
379
389
  offset += result;
380
390
  length -= result;
381
391
  } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
382
- Event_Selector_KQueue_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(READABLE));
392
+ Event_Selector_KQueue_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(EVENT_READABLE));
383
393
  } else {
384
394
  rb_sys_fail("Event_Selector_KQueue_io_read");
385
395
  }
@@ -454,7 +464,7 @@ VALUE io_write_loop(VALUE _arguments) {
454
464
  offset += result;
455
465
  length -= result;
456
466
  } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
457
- Event_Selector_KQueue_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(WRITABLE));
467
+ Event_Selector_KQueue_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(EVENT_WRITABLE));
458
468
  } else {
459
469
  rb_sys_fail("Event_Selector_KQueue_io_write");
460
470
  }
@@ -616,7 +626,8 @@ void Init_Event_Selector_KQueue(VALUE Event_Selector) {
616
626
  rb_define_alloc_func(Event_Selector_KQueue, Event_Selector_KQueue_allocate);
617
627
  rb_define_method(Event_Selector_KQueue, "initialize", Event_Selector_KQueue_initialize, 1);
618
628
 
619
- rb_define_method(Event_Selector_KQueue, "transfer", Event_Selector_KQueue_transfer, -1);
629
+ rb_define_method(Event_Selector_KQueue, "transfer", Event_Selector_KQueue_transfer, 0);
630
+ rb_define_method(Event_Selector_KQueue, "resume", Event_Selector_KQueue_resume, -1);
620
631
  rb_define_method(Event_Selector_KQueue, "yield", Event_Selector_KQueue_yield, 0);
621
632
  rb_define_method(Event_Selector_KQueue, "push", Event_Selector_KQueue_push, 1);
622
633
  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,22 @@ 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_transfer(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_fiber_transfer(data->backend.loop, 0, NULL);
124
+
125
+ return Qnil;
126
+ }
127
+
128
+ VALUE Event_Selector_URing_resume(int argc, VALUE *argv, VALUE self)
129
+ {
130
+ struct Event_Selector_URing *data = NULL;
131
+ TypedData_Get_Struct(self, struct Event_Selector_URing, &Event_Selector_URing_Type, data);
132
+
133
+ Event_Selector_resume(&data->backend, argc, argv);
124
134
 
125
135
  return Qnil;
126
136
  }
@@ -615,7 +625,8 @@ void Init_Event_Selector_URing(VALUE Event_Selector) {
615
625
  rb_define_alloc_func(Event_Selector_URing, Event_Selector_URing_allocate);
616
626
  rb_define_method(Event_Selector_URing, "initialize", Event_Selector_URing_initialize, 1);
617
627
 
618
- rb_define_method(Event_Selector_URing, "transfer", Event_Selector_URing_transfer, -1);
628
+ rb_define_method(Event_Selector_URing, "transfer", Event_Selector_URing_transfer, 0);
629
+ rb_define_method(Event_Selector_URing, "resume", Event_Selector_URing_resume, -1);
619
630
  rb_define_method(Event_Selector_URing, "yield", Event_Selector_URing_yield, 0);
620
631
  rb_define_method(Event_Selector_URing, "push", Event_Selector_URing_push, 1);
621
632
  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.
@@ -0,0 +1,140 @@
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
+ require "event/version"
22
+
23
+ module Event
24
+ module Debug
25
+ class Selector
26
+ def initialize(selector)
27
+ @selector = selector
28
+
29
+ @readable = {}
30
+ @writable = {}
31
+ @priority = {}
32
+ end
33
+
34
+ def close
35
+ if @selector.nil?
36
+ raise "Selector already closed!"
37
+ end
38
+
39
+ @selector.close
40
+ @selector = nil
41
+ end
42
+
43
+ def transfer(fiber, *arguments)
44
+ @selector.transfer(fiber, *arguments)
45
+ end
46
+
47
+ def transfer(*arguments)
48
+ @selector.transfer(*arguments)
49
+ end
50
+
51
+ def resume(*arguments)
52
+ @selector.resume(*arguments)
53
+ end
54
+
55
+ def yield
56
+ @selector.yield
57
+ end
58
+
59
+ def push(fiber)
60
+ @selector.push(fiber)
61
+ end
62
+
63
+ def raise(fiber, *arguments)
64
+ @selector.raise(fiber, *arguments)
65
+ end
66
+
67
+ def ready?
68
+ @selector.ready?
69
+ end
70
+
71
+ def process_wait(*arguments)
72
+ @selector.process_wait(*arguments)
73
+ end
74
+
75
+ def io_wait(fiber, io, events)
76
+ register_readable(fiber, io, events)
77
+ end
78
+
79
+ def select(duration = nil)
80
+ @selector.select(duration)
81
+ end
82
+
83
+ private
84
+
85
+ def register_readable(fiber, io, events)
86
+ if (events & READABLE) > 0
87
+ if @readable.key?(io)
88
+ raise "Cannot wait for #{io} to become readable from multiple fibers."
89
+ end
90
+
91
+ begin
92
+ @readable[io] = fiber
93
+
94
+ register_writable(fiber, io, events)
95
+ ensure
96
+ @readable.delete(io)
97
+ end
98
+ else
99
+ register_writable(fiber, io, events)
100
+ end
101
+ end
102
+
103
+ def register_writable(fiber, io, events)
104
+ if (events & WRITABLE) > 0
105
+ if @writable.key?(io)
106
+ raise "Cannot wait for #{io} to become writable from multiple fibers."
107
+ end
108
+
109
+ begin
110
+ @writable[io] = fiber
111
+
112
+ register_priority(fiber, io, events)
113
+ ensure
114
+ @writable.delete(io)
115
+ end
116
+ else
117
+ register_priority(fiber, io, events)
118
+ end
119
+ end
120
+
121
+ def register_priority(fiber, io, events)
122
+ if (events & PRIORITY) > 0
123
+ if @priority.key?(io)
124
+ raise "Cannot wait for #{io} to become priority from multiple fibers."
125
+ end
126
+
127
+ begin
128
+ @priority[io] = fiber
129
+
130
+ @selector.io_wait(fiber, io, events)
131
+ ensure
132
+ @priority.delete(io)
133
+ end
134
+ else
135
+ @selector.io_wait(fiber, io, events)
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -36,30 +36,58 @@ 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 event loop.
54
+ def transfer
55
+ @loop.transfer
56
+ end
57
+
58
+ # Transfer from the current fiber to the specified fiber. Put the current fiber into the ready list.
59
+ def resume(fiber, *arguments)
60
+ queue = Queue.new(Fiber.current)
61
+ @ready.push(queue)
62
+
41
63
  fiber.transfer(*arguments)
42
64
  ensure
43
- @ready.delete(fiber)
65
+ queue.nullify
44
66
  end
45
67
 
68
+ # Yield from the current fiber back to the event loop. Put the current fiber into the ready list.
46
69
  def yield
47
- fiber = Fiber.current
48
- @ready.push(fiber)
70
+ queue = Queue.new(Fiber.current)
71
+ @ready.push(queue)
72
+
49
73
  @loop.transfer
50
74
  ensure
51
- @ready.delete(fiber)
75
+ queue.nullify
52
76
  end
53
77
 
78
+ # Append the given fiber into the ready list.
54
79
  def push(fiber)
55
80
  @ready.push(fiber)
56
81
  end
57
82
 
83
+ # Transfer to the given fiber and raise an exception. Put the current fiber into the ready list.
58
84
  def raise(fiber, *arguments)
59
- @ready.push(Fiber.current)
60
- @fiber.raise(*arguments)
85
+ queue = Queue.new(Fiber.current)
86
+ @ready.push(queue)
87
+
88
+ fiber.raise(*arguments)
61
89
  ensure
62
- @ready.delete(fiber)
90
+ queue.nullify
63
91
  end
64
92
 
65
93
  def ready?
@@ -150,7 +178,7 @@ module Event
150
178
  thread&.kill
151
179
  end
152
180
 
153
- def select(duration = nil)
181
+ private def pop_ready
154
182
  if @ready.any?
155
183
  ready = @ready
156
184
  @ready = Array.new
@@ -158,6 +186,14 @@ module Event
158
186
  ready.each do |fiber|
159
187
  fiber.transfer if fiber.alive?
160
188
  end
189
+
190
+ return true
191
+ end
192
+ end
193
+
194
+ def select(duration = nil)
195
+ if pop_ready
196
+ duration = 0
161
197
  end
162
198
 
163
199
  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.1"
2
+ VERSION = "0.9.2"
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.1
4
+ version: 0.9.2
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
@@ -86,7 +86,7 @@ files:
86
86
  - ext/event/selector/uring.c
87
87
  - ext/event/selector/uring.h
88
88
  - lib/event.rb
89
- - lib/event/debug.rb
89
+ - lib/event/debug/selector.rb
90
90
  - lib/event/selector.rb
91
91
  - lib/event/selector/select.rb
92
92
  - lib/event/version.rb
@@ -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.
data/lib/event/debug.rb DELETED
@@ -1,126 +0,0 @@
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
- require "event/version"
22
-
23
- module Event
24
- class Debug
25
- def initialize(selector)
26
- @selector = selector
27
-
28
- @readable = {}
29
- @writable = {}
30
- @priority = {}
31
- end
32
-
33
- def close
34
- if @selector.nil?
35
- raise "Selector already closed!"
36
- end
37
-
38
- @selector.close
39
- @selector = nil
40
- end
41
-
42
- def transfer(fiber, *arguments)
43
- @selector.transfer(fiber, *arguments)
44
- end
45
-
46
- def yield
47
- @selector.yield
48
- end
49
-
50
- def push(fiber)
51
- @selector.push(fiber)
52
- end
53
-
54
- def raise(fiber, *arguments)
55
- @selector.raise(fiber, *arguments)
56
- end
57
-
58
- def ready?
59
- @selector.ready?
60
- end
61
-
62
- def io_wait(fiber, io, events)
63
- register_readable(fiber, io, events)
64
- end
65
-
66
- def select(duration = nil)
67
- @selector.select(duration)
68
- end
69
-
70
- private
71
-
72
- def register_readable(fiber, io, events)
73
- if (events & READABLE) > 0
74
- if @readable.key?(io)
75
- raise "Cannot wait for #{io} to become readable from multiple fibers."
76
- end
77
-
78
- begin
79
- @readable[io] = fiber
80
-
81
- register_writable(fiber, io, events)
82
- ensure
83
- @readable.delete(io)
84
- end
85
- else
86
- register_writable(fiber, io, events)
87
- end
88
- end
89
-
90
- def register_writable(fiber, io, events)
91
- if (events & WRITABLE) > 0
92
- if @writable.key?(io)
93
- raise "Cannot wait for #{io} to become writable from multiple fibers."
94
- end
95
-
96
- begin
97
- @writable[io] = fiber
98
-
99
- register_priority(fiber, io, events)
100
- ensure
101
- @writable.delete(io)
102
- end
103
- else
104
- register_priority(fiber, io, events)
105
- end
106
- end
107
-
108
- def register_priority(fiber, io, events)
109
- if (events & PRIORITY) > 0
110
- if @priority.key?(io)
111
- raise "Cannot wait for #{io} to become priority from multiple fibers."
112
- end
113
-
114
- begin
115
- @priority[io] = fiber
116
-
117
- @selector.io_wait(fiber, io, events)
118
- ensure
119
- @priority.delete(io)
120
- end
121
- else
122
- @selector.io_wait(fiber, io, events)
123
- end
124
- end
125
- end
126
- end