Issue #5993 has been reported by Tomoyuki Chikanaga.
----------------------------------------
Bug #5993: Thread.new{ Fiber.new { Thread.exit }.resume }.join で例外
https://bugs.ruby-lang.org/issues/5993
Author: Tomoyuki Chikanaga
Status: Open
Priority: Normal
Assignee: Tomoyuki Chikanaga
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2012-02-09 trunk 34514) [x86_64-darwin10.8.0]
以下のように 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);
on 2012-02-09 17:59
on 2012-04-27 16:41
Issue #5993 has been updated by ko1 (Koichi Sasada).
ちょっと思い出せないんですが(多分、その辺整理すると思う)、
近永さんのことだから信じられると思います。
というわけで、テスト付きでコミットいただければ。
----------------------------------------
Bug #5993: Thread.new{ Fiber.new { Thread.exit }.resume }.join で例外
https://bugs.ruby-lang.org/issues/5993#change-26253
Author: nagachika (Tomoyuki Chikanaga)
Status: Assigned
Priority: Normal
Assignee: nagachika (Tomoyuki Chikanaga)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2012-02-09 trunk 34514) [x86_64-darwin10.8.0]
以下のように 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);
on 2012-04-28 18:03
Issue #5993 has been updated by nagachika (Tomoyuki Chikanaga).
長らく放置しててすみません。
先のパッチをテストしていて、これだけでは不十分で確か Fiber 内で fatal()
を呼んだりした時の挙動に問題があったためもう少し考えないといけないなぁ、というところで止まってたと思います。
ちょっとどうやら作業していたブランチを消してしまったみたいで、すぐには具体的な内容を思い出せないのですが、少し調べてみてこの修正とは別の問題として切り分けられそうであれば別チケットを作ろうかと思います。
----------------------------------------
Bug #5993: Thread.new{ Fiber.new { Thread.exit }.resume }.join で例外
https://bugs.ruby-lang.org/issues/5993#change-26301
Author: nagachika (Tomoyuki Chikanaga)
Status: Assigned
Priority: Normal
Assignee: nagachika (Tomoyuki Chikanaga)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2012-02-09 trunk 34514) [x86_64-darwin10.8.0]
以下のように 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);
on 2012-12-15 18:03
Issue #5993 has been updated by nagachika (Tomoyuki Chikanaga). Fiber内で rb_fatal() を呼んだ時の問題は http://bugs.ruby-lang.org/issues/7570 として新しくチケットを作成しました。 ---------------------------------------- Bug #5993: Thread.new{ Fiber.new { Thread.exit }.resume }.join で例外 https://bugs.ruby-lang.org/issues/5993#change-34770 Author: nagachika (Tomoyuki Chikanaga) Status: Closed Priority: Normal Assignee: nagachika (Tomoyuki Chikanaga) Category: core Target version: 2.0.0 ruby -v: ruby 2.0.0dev (2012-02-09 trunk 34514) [x86_64-darwin10.8.0] 以下のように 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);
on 2012-12-18 15:20
Issue #5993 has been updated by nagachika (Tomoyuki Chikanaga).
Status changed from Closed to Open
すみません、やっぱり r38414 ではちゃんと修正できていませんでした。
例外は発生しなくなりましたが、Thread.exit が Fiber を終了したところで無視されて Thread は動き続けてしまっていました。
Thread.start{
Fiber.new{ Thread.exit }.resume
p :unreachable # <- 実行されてしまう
}.join
async_errinfo_queue に INT2FIX(TAG_FATAL) を入れて伝播させないといけないですかね。
----------------------------------------
Bug #5993: Thread.new{ Fiber.new { Thread.exit }.resume }.join で例外
https://bugs.ruby-lang.org/issues/5993#change-34829
Author: nagachika (Tomoyuki Chikanaga)
Status: Open
Priority: Normal
Assignee: nagachika (Tomoyuki Chikanaga)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2012-02-09 trunk 34514) [x86_64-darwin10.8.0]
以下のように 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);
on 2012-12-18 18:31
Issue #5993 has been updated by nagachika (Tomoyuki Chikanaga).
File thread_exit_in_fiber.patch added
Status changed from Open to Assigned
パッチを作り直しました。
rb_threadptr_execute_interrupts() で async_errinfo_queue から
INT2FIX(TAG_FATAL) が取れる可能性を考慮するようにしました。通常は INT2FIX(TAG_FATAL) は
rb_threadptr_to_kill() で発生させて同期的例外のように処理するので async_errinfo_queue
に入ることはないはずですが、Fiberの終了時は fiber_terminate()して Fiber を切り替えるまで遅延させるために例外的に
async_errinfo_queue に入ることがあります。というか入れるようにしました。
そのかわり r38441 で rb_vm_make_jump_tag_but_local_jump() で TAG_FATAL
を考慮するようにした変更は revert しています。
手元では make check は通りました。よさそうだったらコミットします。
----------------------------------------
Bug #5993: Thread.new{ Fiber.new { Thread.exit }.resume }.join で例外
https://bugs.ruby-lang.org/issues/5993#change-34833
Author: nagachika (Tomoyuki Chikanaga)
Status: Assigned
Priority: Normal
Assignee: nagachika (Tomoyuki Chikanaga)
Category: core
Target version: 2.0.0
ruby -v: ruby 2.0.0dev (2012-02-09 trunk 34514) [x86_64-darwin10.8.0]
以下のように 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);
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.