event 0.8.1 → 0.9.2

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: 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