ori-rb 0.4.4 → 0.4.5
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 +4 -4
- data/lib/ori/scope.rb +58 -11
- data/lib/ori/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 982c11168837e41b1cb170b200732867a648c00546ef530b5f390da2436f4c63
|
|
4
|
+
data.tar.gz: 42a74eeba76762d3ec9ed5f3dd5e379be15d941a7a04a4ee7431da732e03b3bf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 200f9cb47a64c132688613fffb42b5a642c288f47004821e60ee451758c4fb241e9a2136e26ac23053db33e474bb9aad082949d03f7e04f1197fdc2fe09ead11
|
|
7
|
+
data.tar.gz: 38817593a3040a762ad3fff44e18352dfa7c0367e47a3e8aa7434222ce059cedc58c113b249df39a0f93cecf4fe87189dccd25820a5d2a870b6448cebf791e17
|
data/lib/ori/scope.rb
CHANGED
|
@@ -54,9 +54,10 @@ module Ori
|
|
|
54
54
|
@cancelled = false
|
|
55
55
|
@closed = false
|
|
56
56
|
|
|
57
|
-
# Cross-thread wakeup mechanism for unblock
|
|
57
|
+
# Cross-thread wakeup mechanism for unblock and fiber_interrupt
|
|
58
58
|
@wakeup_mutex = ::Mutex.new
|
|
59
59
|
@wakeup_queue = [] #: Array[Fiber]
|
|
60
|
+
@pending_interrupts = {} #: Hash[Fiber, Exception]
|
|
60
61
|
@wakeup_reader, @wakeup_writer = IO.pipe
|
|
61
62
|
|
|
62
63
|
# Instead, use thread-local storage
|
|
@@ -79,6 +80,9 @@ module Ori
|
|
|
79
80
|
process_available_work
|
|
80
81
|
Fiber.yield if parent_scope && pending_work?
|
|
81
82
|
end
|
|
83
|
+
rescue Interrupt => error
|
|
84
|
+
puts "Scope interrupted! Shutting down..."
|
|
85
|
+
shutdown!(error)
|
|
82
86
|
ensure
|
|
83
87
|
close_scope
|
|
84
88
|
@parent_scope&.deregister_child_scope(self)
|
|
@@ -174,8 +178,8 @@ module Ori
|
|
|
174
178
|
0
|
|
175
179
|
end
|
|
176
180
|
ensure
|
|
177
|
-
cleanup_io_wait(fiber, io, added)
|
|
178
|
-
cleanup_timeout(fiber) if timeout
|
|
181
|
+
cleanup_io_wait(fiber, io, added) if added
|
|
182
|
+
cleanup_timeout(fiber) if timeout && fiber
|
|
179
183
|
end
|
|
180
184
|
|
|
181
185
|
def io_select(readables, writables, exceptables, timeout)
|
|
@@ -224,7 +228,7 @@ module Ori
|
|
|
224
228
|
Fiber.yield
|
|
225
229
|
end
|
|
226
230
|
ensure
|
|
227
|
-
cleanup_timeout(fiber)
|
|
231
|
+
cleanup_timeout(fiber) if fiber
|
|
228
232
|
end
|
|
229
233
|
|
|
230
234
|
def block(...)
|
|
@@ -246,6 +250,14 @@ module Ori
|
|
|
246
250
|
@wakeup_writer.write_nonblock(".") rescue nil # rubocop:disable Style/RescueModifier
|
|
247
251
|
end
|
|
248
252
|
|
|
253
|
+
def fiber_interrupt(fiber, exception)
|
|
254
|
+
@wakeup_mutex.synchronize do
|
|
255
|
+
@pending_interrupts[fiber] = exception
|
|
256
|
+
@wakeup_queue << fiber
|
|
257
|
+
end
|
|
258
|
+
@wakeup_writer.write_nonblock(".") rescue nil # rubocop:disable Style/RescueModifier
|
|
259
|
+
end
|
|
260
|
+
|
|
249
261
|
def io_read(io, buffer, length, offset)
|
|
250
262
|
return @parent_scope.io_read(io, buffer, length, offset) unless fiber_ids.key?(Fiber.current)
|
|
251
263
|
|
|
@@ -486,8 +498,39 @@ module Ori
|
|
|
486
498
|
end
|
|
487
499
|
|
|
488
500
|
def drain_wakeup_queue
|
|
489
|
-
|
|
490
|
-
fibers
|
|
501
|
+
interrupts = nil
|
|
502
|
+
fibers = @wakeup_mutex.synchronize do
|
|
503
|
+
unless @pending_interrupts.empty?
|
|
504
|
+
interrupts = @pending_interrupts.dup
|
|
505
|
+
@pending_interrupts.clear
|
|
506
|
+
end
|
|
507
|
+
@wakeup_queue.shift(@wakeup_queue.size)
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
fibers.each do |fiber|
|
|
511
|
+
next unless fiber.alive?
|
|
512
|
+
|
|
513
|
+
if (exception = interrupts&.delete(fiber))
|
|
514
|
+
interrupt_fiber(fiber, exception)
|
|
515
|
+
else
|
|
516
|
+
resume_fiber(fiber)
|
|
517
|
+
end
|
|
518
|
+
end
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
def interrupt_fiber(fiber, exception)
|
|
522
|
+
id = fiber_ids[fiber]
|
|
523
|
+
@tracer&.record(id, :interrupted, exception.message)
|
|
524
|
+
|
|
525
|
+
# Remove from wait states before cancelling
|
|
526
|
+
waiting.delete(fiber)
|
|
527
|
+
blocked.delete(fiber)
|
|
528
|
+
|
|
529
|
+
if (task = task_queue[fiber])
|
|
530
|
+
task.cancel(exception)
|
|
531
|
+
else
|
|
532
|
+
fiber.kill
|
|
533
|
+
end
|
|
491
534
|
end
|
|
492
535
|
|
|
493
536
|
def close_scope
|
|
@@ -691,15 +734,19 @@ module Ori
|
|
|
691
734
|
end
|
|
692
735
|
|
|
693
736
|
def cleanup_io_wait(fiber, io, added)
|
|
694
|
-
|
|
695
|
-
|
|
737
|
+
state = thread_local_state&.[](object_id)
|
|
738
|
+
return unless state
|
|
696
739
|
|
|
697
|
-
readable
|
|
698
|
-
writable
|
|
740
|
+
state.readable[io]&.delete(fiber) if added[:readable]
|
|
741
|
+
state.writable[io]&.delete(fiber) if added[:writable]
|
|
742
|
+
|
|
743
|
+
state.readable.delete(io) if state.readable[io]&.empty?
|
|
744
|
+
state.writable.delete(io) if state.writable[io]&.empty?
|
|
699
745
|
end
|
|
700
746
|
|
|
701
747
|
def cleanup_timeout(fiber)
|
|
702
|
-
|
|
748
|
+
state = thread_local_state&.[](object_id)
|
|
749
|
+
state&.waiting&.delete(fiber)
|
|
703
750
|
end
|
|
704
751
|
|
|
705
752
|
# Add helper method to access thread-local state
|
data/lib/ori/version.rb
CHANGED