1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Uncomment code to raise LocalJumpError for yield across thread through enum

Not sure if this is the correct fix.  It does raise LocalJumpError in
the yielding thread as you would expect, but the value yielded to the calling
thread is still yielded without an exception.

Fixes [Bug #18649]
This commit is contained in:
Jeremy Evans 2022-03-22 16:36:16 -07:00
parent 3fa768c5c3
commit 4b14b2902a
Notes: git 2022-04-22 12:48:46 +09:00
2 changed files with 55 additions and 2 deletions

View file

@ -1338,6 +1338,61 @@ q.pop
t.join
end
def test_yield_across_thread_through_enum
bug18649 = '[ruby-core:107980] [Bug #18649]'
@log = []
def self.p(arg)
@log << arg
end
def self.synchronize
yield
end
def self.execute(task)
success = true
value = reason = nil
end_sync = false
synchronize do
begin
p :before
value = task.call
p :never_reached
success = true
rescue StandardError => ex
ex = ex.class
p [:rescue, ex]
reason = ex
success = false
end
end_sync = true
p :end_sync
end
p :should_not_reach_here! unless end_sync
[success, value, reason]
end
def self.foo
Thread.new do
result = execute(-> { yield 42 })
p [:result, result]
end.join
end
value = to_enum(:foo).first
expected = [:before,
[:rescue, LocalJumpError],
:end_sync,
[:result, [false, nil, LocalJumpError]]]
assert_equal(expected, @log, bug18649)
assert_equal(42, value, bug18649)
end
def test_thread_setname_in_initialize
bug12290 = '[ruby-core:74963] [Bug #12290]'
c = Class.new(Thread) {def initialize() self.name = "foo"; super; end}

2
vm.c
View file

@ -1806,11 +1806,9 @@ vm_iter_break(rb_execution_context_t *ec, VALUE val)
const VALUE *ep = VM_CF_PREV_EP(cfp);
const rb_control_frame_t *target_cfp = rb_vm_search_cf_from_ep(ec, cfp, ep);
#if 0 /* raise LocalJumpError */
if (!target_cfp) {
rb_vm_localjump_error("unexpected break", val, TAG_BREAK);
}
#endif
ec->errinfo = (VALUE)THROW_DATA_NEW(val, target_cfp, TAG_BREAK);
EC_JUMP_TAG(ec, TAG_BREAK);