@@ -11,6 +11,7 @@ def initialize
1111 @dns_cache = { }
1212
1313 @alive_fibers = Hash . new { |h , k | h [ k ] = { } }
14+ @fibers_mutex = Mutex . new
1415
1516 start_timeout_worker
1617 end
@@ -75,17 +76,21 @@ def timeout_after(duration, exception_class = Timeout::Error, *exception_argumen
7576 fiber = Fiber . current
7677 timeout_deadline = Process . clock_gettime ( Process ::CLOCK_MONOTONIC ) + duration
7778
78- @alive_fibers [ fiber . __get_id ] [ timeout_deadline ] = {
79- fiber : fiber ,
80- timeout_deadline : timeout_deadline ,
81- exception_class : exception_class ,
82- exception_arguments : exception_arguments
83- }
79+ @fibers_mutex . synchronize do
80+ @alive_fibers [ fiber . __get_id ] [ timeout_deadline ] = {
81+ fiber : fiber ,
82+ timeout_deadline : timeout_deadline ,
83+ exception_class : exception_class ,
84+ exception_arguments : exception_arguments
85+ }
86+ end
8487
8588 begin
8689 block . call
8790 ensure
88- @alive_fibers [ fiber . __get_id ] . delete ( timeout_deadline )
91+ @fibers_mutex . synchronize do
92+ @alive_fibers [ fiber . __get_id ] . delete ( timeout_deadline )
93+ end
8994 end
9095 end
9196
@@ -166,25 +171,31 @@ def start_timeout_worker
166171 end
167172
168173 def check_timeouts
169- @alive_fibers . delete_if do |fiber_id , timeouts |
170- timeouts . delete_if do |timeout_key , fiber_hash |
171- current_time = Process . clock_gettime ( Process ::CLOCK_MONOTONIC )
174+ @fibers_mutex . synchronize do
175+ @alive_fibers . delete_if do |fiber_id , timeouts |
176+ timeouts . delete_if do |timeout_key , fiber_hash |
177+ current_time = Process . clock_gettime ( Process ::CLOCK_MONOTONIC )
178+
179+ next false if current_time < fiber_hash [ :timeout_deadline ]
172180
173- return false if current_time < fiber_hash [ :timeout_deadline ]
181+ fiber = fiber_hash [ :fiber ]
182+ unblock ( nil , fiber )
174183
175- fiber = fiber_hash [ : fiber]
176- unblock ( nil , fiber )
184+ if fiber . alive?
185+ fiber . raise ( RageTimeout )
177186
178- if fiber . alive?
179- fiber . raise ( RageTimeout )
180- else
181- timeouts . delete ( timeout_key )
187+ ::Iodine . run_after ( 1000 ) do
188+ fiber . kill if fiber . alive?
189+ end
190+ else
191+ timeouts . delete ( timeout_key )
192+ end
193+
194+ true
182195 end
183196
184- true
197+ timeouts . length == 0
185198 end
186-
187- timeouts . length == 0
188199 end
189200 end
190201end
0 commit comments