Skip to content

Commit

Permalink
Uncomment code to raise LocalJumpError for yield across thread throug…
Browse files Browse the repository at this point in the history
…h 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]
  • Loading branch information
jeremyevans committed Apr 22, 2022
1 parent 3fa768c commit 4b14b29
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
55 changes: 55 additions & 0 deletions test/ruby/test_thread.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1338,6 +1338,61 @@ def test_thread_invalid_object
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}
Expand Down
2 changes: 0 additions & 2 deletions vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 4b14b29

Please sign in to comment.