From: "nagachika (Tomoyuki Chikanaga)" Date: 2013-11-14T22:42:20+09:00 Subject: [ruby-dev:47807] [ruby-trunk - Bug #9105][Open] callcc による不整合(例:Hash) Issue #9105 has been updated by nagachika (Tomoyuki Chikanaga). Status changed from Closed to Open r43675 はマルチスレッドで同一の Hash を使っている場合に RHASH_ITER_LEV(hash) の値が不正になることがあると思います。 以下のようなスクリプトを実行すると RHASH_ITER_LEV() が 0 に戻らなくなるので要素追加に失敗します。 h = {1=>2} th1 = Thread.start{ h.each{ sleep 1 } } sleep 0.1 th2 = Thread.start{ h.each { sleep 3 } } th1.join th2.join h[5] = 6 # => can't add a new key into hash during iteration (RuntimeError) ---------------------------------------- Bug #9105: callcc による不整合(例:Hash) https://bugs.ruby-lang.org/issues/9105#change-42934 Author: tarui (Masaya Tarui) Status: Open Priority: Normal Assignee: Category: core Target version: current: 2.1.0 ruby -v: ruby 2.1.0dev (2013-11-11 trunk 43647) [x86_64-linux] Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN =begin 以下のコードを実行すると、 equire 'continuation' h = {1=>2,3=>4} c = nil f = false h.each { callcc {|c2| c = c2 } } unless f f = true c.call end h.each {|i| h.delete(1); p i} 以下のような結果になります。 [1, 2] [false, false] test.rb:10:in `each': hash modified during iteration (RuntimeError) from test.rb:10:in `
' [false, false]自体はst_foreach_checkで全く機能していない /* call func with error notice */ retval = (*func)(0, 0, arg, 1); を消せばいいのですが、 RuntimeErrorが発生するのはcallccによりhash_foreach_ensureの実行が2重に行われて、 RHASH_ITER_LEV(hash)の管理が破綻してしまっている為です。 他の所でも容易に起こりうると思うのですが、未調査です。 &そもそもどう対処すべきでしょう? =end -- http://bugs.ruby-lang.org/