From: "Eregon (Benoit Daloze)" Date: 2022-03-18T16:20:56+00:00 Subject: [ruby-core:107980] [Ruby master Bug#18649] Enumerable#first breaks out of the incorect block when across threads Issue #18649 has been reported by Eregon (Benoit Daloze). ---------------------------------------- Bug #18649: Enumerable#first breaks out of the incorect block when across threads https://bugs.ruby-lang.org/issues/18649 * 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: