зеркало из https://github.com/github/ruby.git
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:
Родитель
3fa768c5c3
Коммит
4b14b2902a
|
@ -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
2
vm.c
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче