Bug #5993
Thread.new{ Fiber.new { Thread.exit }.resume }.join で例外
| Status: | Assigned | Start date: | 02/10/2012 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | % Done: | 0% |
||
| Category: | core | |||
| Target version: | 2.0.0 | |||
| ruby -v: | ruby 2.0.0dev (2012-02-09 trunk 34514) [x86_64-darwin10.8.0] |
Description
以下のように Fiber 内で Thread.exit するとメッセージが空の RuntimeError が発生します。
Thread.new{ Fiber.new { Thread.exit }.resume }.join #=> RuntimeError:
rb_fiber_start() で Thread.exit 時の TAG_FATAL での TAG_JUMP を想定していないためだと思います。とりあえず以下のようにすると例外にならなくなります。
あと th->errinfo は空を Qnil としているのに th->thrown_errinfo は 0 (Qfalse)を空であることを示すのに使っているので、その食い違いで thrown_errinfo に Qnil を入れてしまっていた(rb_vm_make_jump_tag_but_local_jump() の結果が Qnil の時)のが原因のようなので、そちらをなんとかすべきかもしれません。全体的に thrown_errinfo も空を意味するために Qnil を使うようにそろえるとか?
--- a/cont.c
+++ b/cont.c
@@ -1152,6 +1152,9 @@ rb_fiber_start(void)
if (state == TAG_RAISE) {
th->thrown_errinfo = th->errinfo;
}
+ else if (state == TAG_FATAL && th->errinfo == INT2FIX(TAG_FATAL)) {
+ /* terminating */
+ }
else {
th->thrown_errinfo =
rb_vm_make_jump_tag_but_local_jump(state, th->errinfo);
History
Updated by shyouhei (Shyouhei Urabe) 2 months ago
- Status changed from Open to Assigned
Updated by ko1 (Koichi Sasada) 27 days ago
ちょっと思い出せないんですが(多分、その辺整理すると思う)、
近永さんのことだから信じられると思います。
というわけで、テスト付きでコミットいただければ。
Updated by nagachika (Tomoyuki Chikanaga) 26 days ago
長らく放置しててすみません。
先のパッチをテストしていて、これだけでは不十分で確か Fiber 内で fatal() を呼んだりした時の挙動に問題があったためもう少し考えないといけないなぁ、というところで止まってたと思います。
ちょっとどうやら作業していたブランチを消してしまったみたいで、すぐには具体的な内容を思い出せないのですが、少し調べてみてこの修正とは別の問題として切り分けられそうであれば別チケットを作ろうかと思います。