From: "nobu (Nobuyoshi Nakada)" Date: 2022-04-19T09:46:11+00:00 Subject: [ruby-core:108292] [Ruby master Bug#18649] Enumerable#first breaks out of the incorect block when across threads Issue #18649 has been updated by nobu (Nobuyoshi Nakada). jeremyevans0 (Jeremy Evans) wrote in #note-2: > With the block uncommented, the yielding thread raises LocalJumpError, but the calling thread gets the yielded value without an exception. Isn't it natural because the test code rescues but doesn't re-raise? ---------------------------------------- Bug #18649: Enumerable#first breaks out of the incorect block when across threads https://bugs.ruby-lang.org/issues/18649#change-97313 * Author: Eregon (Benoit Daloze) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [x86_64-linux] * Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- ```ruby def synchronize yield end def 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 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 foo Thread.new do result = execute(-> { yield 42 }) p [:result, result] end.join end p [:first, to_enum(:foo).first] ``` This code should raise LocalJumpError (and that should get `rescue`'d) because Enumerable#first can't break/return across threads. But instead, it seems to break out of the block given to `synchronize`, which is clearly wrong. That case is shown as `:should_not_reach_here!`. Results: ``` ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [x86_64-linux] :before :should_not_reach_here! [:result, [true, nil, nil]] [:first, 42] ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [x86_64-linux] :before :should_not_reach_here! [:result, [true, nil, nil]] [:first, 42] ``` CRuby (3.0 and 3.1) print `:should_not_reach_here!`, which is a semantic bug, if we get to the end of `execute` we should have gotten to the end of the block given to synchronize. This is related to #18474 and https://github.com/ruby-concurrency/concurrent-ruby/issues/931. -- https://bugs.ruby-lang.org/ Unsubscribe: