diff options
author | Jeremy Evans <[email protected]> | 2022-03-22 16:36:16 -0700 |
---|---|---|
committer | Jeremy Evans <[email protected]> | 2022-04-21 20:48:27 -0700 |
commit | 4b14b2902abaa0e8f0d1e8282d2322f47431fa3f (patch) | |
tree | 086716257ae8dc7b4f0e5b928348648be3c9a57e | |
parent | 3fa768c5c308b61677342fe2caa9c54fe3a2c3c9 (diff) |
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]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/5692
-rw-r--r-- | test/ruby/test_thread.rb | 55 | ||||
-rw-r--r-- | vm.c | 2 |
2 files changed, 55 insertions, 2 deletions
diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb index e80ca16022..ddb4516b3c 100644 --- a/test/ruby/test_thread.rb +++ b/test/ruby/test_thread.rb @@ -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} @@ -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); |