зеркало из https://github.com/github/ruby.git
Do not check pending interrupts when running finalizers
This fixes cases where exceptions raised using Thread#raise are swallowed by finalizers and not delivered to the running thread. This could cause issues with finalizers that rely on pending interrupts, but that case is expected to be rarer. Fixes [Bug #13876] Fixes [Bug #15507] Co-authored-by: Koichi Sasada <ko1@atdot.net>
This commit is contained in:
Родитель
cbecf9c7ba
Коммит
87b327efe6
4
gc.c
4
gc.c
|
@ -4088,10 +4088,14 @@ static void
|
||||||
finalize_deferred(rb_objspace_t *objspace)
|
finalize_deferred(rb_objspace_t *objspace)
|
||||||
{
|
{
|
||||||
VALUE zombie;
|
VALUE zombie;
|
||||||
|
rb_execution_context_t *ec = GET_EC();
|
||||||
|
ec->interrupt_mask |= PENDING_INTERRUPT_MASK;
|
||||||
|
|
||||||
while ((zombie = ATOMIC_VALUE_EXCHANGE(heap_pages_deferred_final, 0)) != 0) {
|
while ((zombie = ATOMIC_VALUE_EXCHANGE(heap_pages_deferred_final, 0)) != 0) {
|
||||||
finalize_list(objspace, zombie);
|
finalize_list(objspace, zombie);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ec->interrupt_mask &= ~PENDING_INTERRUPT_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -168,6 +168,31 @@ End
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_finalizer_thread_raise
|
||||||
|
GC.disable
|
||||||
|
fzer = proc do |id|
|
||||||
|
sleep 0.2
|
||||||
|
end
|
||||||
|
2.times do
|
||||||
|
o = Object.new
|
||||||
|
ObjectSpace.define_finalizer(o, fzer)
|
||||||
|
end
|
||||||
|
|
||||||
|
my_error = Class.new(RuntimeError)
|
||||||
|
begin
|
||||||
|
main_th = Thread.current
|
||||||
|
Thread.new do
|
||||||
|
sleep 0.1
|
||||||
|
main_th.raise(my_error)
|
||||||
|
end
|
||||||
|
GC.start
|
||||||
|
puts "After GC"
|
||||||
|
sleep(10)
|
||||||
|
assert(false)
|
||||||
|
rescue my_error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_each_object
|
def test_each_object
|
||||||
klass = Class.new
|
klass = Class.new
|
||||||
new_obj = klass.new
|
new_obj = klass.new
|
||||||
|
|
Загрузка…
Ссылка в новой задаче