mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Make Hash#each family usable in Ractor
We don't need to increment/decrement iteration level for frozen Hash because frozen Hash can't be modified. We can assume that nobody changes the target Hash while calling #each family. How to reproduce: a = {} 100.times do |i| a[i] = true end Ractor.make_shareable(a) 4.times.collect do Ractor.new(a) do |b| 100.times do b.each_value do end end end end.each(&:take) Example output: internal:ractor>:267: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues. #<Thread:0x00007fcfb087bb30 run> terminated with exception (report_on_exception is true): #<Thread:0x00007fcfb087b8d8 run> terminated with exception (report_on_exception is true): #<Thread:0x00007fcfb088d678 run> terminated with exception (report_on_exception is true): #<Thread:0x00007fcfb087bd88 run> terminated with exception (report_on_exception is true): /tmp/h.rb:10:in `each_value'/tmp/h.rb:10:in `each_value': : /tmp/h.rb:10:in `each_value'no implicit conversion from nil to integer/tmp/h.rb:10:in `each_value'no implicit conversion from nil to integer (: : (TypeErrorTypeError)no implicit conversion from nil to integer)no implicit conversion from nil to integer ( (TypeErrorTypeError from /tmp/h.rb:10:in `block (3 levels) in <main>' from /tmp/h.rb:10:in `block (3 levels) in <main>' )) from /tmp/h.rb:9:in `times' from /tmp/h.rb:9:in `times' from /tmp/h.rb:9:in `block (2 levels) in <main>' from /tmp/h.rb:10:in `block (3 levels) in <main>' from /tmp/h.rb:10:in `block (3 levels) in <main>' from /tmp/h.rb:9:in `block (2 levels) in <main>' from /tmp/h.rb:9:in `times' from /tmp/h.rb:9:in `times' from /tmp/h.rb:9:in `block (2 levels) in <main>' from /tmp/h.rb:9:in `block (2 levels) in <main>' <internal:ractor>:694:in `take': thrown by remote Ractor. (Ractor::RemoteError) from /tmp/h.rb:14:in `each' from /tmp/h.rb:14:in `<main>' /tmp/h.rb:10:in `each_value': no implicit conversion from nil to integer (TypeError) from /tmp/h.rb:10:in `block (3 levels) in <main>' from /tmp/h.rb:9:in `times' from /tmp/h.rb:9:in `block (2 levels) in <main>'
This commit is contained in:
parent
27410eaeb2
commit
a2ad0cb7b4
Notes:
git
2021-08-26 13:30:20 +09:00
1 changed files with 7 additions and 2 deletions
9
hash.c
9
hash.c
|
@ -1503,11 +1503,16 @@ rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
|
|||
|
||||
if (RHASH_TABLE_EMPTY_P(hash))
|
||||
return;
|
||||
hash_iter_lev_inc(hash);
|
||||
arg.hash = hash;
|
||||
arg.func = (rb_foreach_func *)func;
|
||||
arg.arg = farg;
|
||||
rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
|
||||
if (RB_OBJ_FROZEN(hash)) {
|
||||
hash_foreach_call((VALUE)&arg);
|
||||
}
|
||||
else {
|
||||
hash_iter_lev_inc(hash);
|
||||
rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
|
||||
}
|
||||
hash_verify(hash);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue