From: nobu.nakada@... Date: 2003-08-30T17:37:25+09:00 Subject: [ruby-dev:21291] Re: スレッド内の例外でRuby停止 なかだです。 At Fri, 29 Aug 2003 19:29:49 +0900, yamamoto madoka wrote: > 大変申し訳ありません、 > このPatchを当てると別のコードで同症状が出るようになってしまいました。 [ruby-dev:21280]の原因は、$stderr.writeが終了したスレッドで実行 されてしまうことです。そしてflushでIO待ちになるときに死んだはず のスレッドが生き返ってしまっています。 ということで、メインスレッドに切り替わってから出力するようにす れば、解決するんではないでしょうか。 Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.525 diff -u -2 -p -r1.525 eval.c --- eval.c 30 Aug 2003 05:26:47 -0000 1.525 +++ eval.c 30 Aug 2003 08:30:44 -0000 @@ -3762,8 +3762,7 @@ rb_mod_protected_method_defined(mod, mid } -#define terminate_process(status, mesg, mlen) rb_exc_raise(system_exit(status, mesg, mlen)) - +NORETURN(static VALUE terminate_process _((int, const char *, long))); static VALUE -system_exit(status, mesg, mlen) +terminate_process(status, mesg, mlen) int status; const char *mesg; @@ -3774,5 +3773,5 @@ system_exit(status, mesg, mlen) args[1] = rb_str_new(mesg, mlen); - return rb_class_new_instance(2, args, rb_eSystemExit); + rb_exc_raise(rb_class_new_instance(2, args, rb_eSystemExit)); } @@ -8160,4 +8159,5 @@ static char *th_signm; #define RESTORE_RAISE 5 #define RESTORE_SIGNAL 6 +#define RESTORE_EXIT 7 extern VALUE *rb_gc_stack_start; @@ -8252,4 +8252,10 @@ rb_thread_switch(n) rb_raise(rb_eSignal, "SIG%s", th_signm); break; + case RESTORE_EXIT: + ruby_errinfo = th_raise_argv[0]; + ruby_current_node = th_raise_node; + error_print(); + terminate_process(1, 0, 0); + break; case RESTORE_NORMAL: default: @@ -8270,5 +8276,5 @@ rb_thread_switch(n) #endif -static void rb_thread_restore_context _((rb_thread_t,int)); +NORETURN(static void rb_thread_restore_context _((rb_thread_t,int))); static void @@ -8412,4 +8418,18 @@ rb_thread_fd_close(fd) } +NORETURN(static void rb_thread_main_jump _((VALUE, int))); +static void +rb_thread_main_jump(err, tag) + VALUE err; + int tag; +{ + curr_thread = main_thread; + th_raise_argc = 1; + th_raise_argv[0] = err; + th_raise_node = ruby_current_node; + rb_thread_restore_context(main_thread, tag); +} + +NORETURN(static void rb_thread_deadlock _((void))); static void rb_thread_deadlock() @@ -8423,9 +8443,5 @@ rb_thread_deadlock() rb_exc_raise(e); } - curr_thread = main_thread; - th_raise_argc = 1; - th_raise_argv[0] = e; - th_raise_node = ruby_current_node; - rb_thread_restore_context(main_thread, RESTORE_RAISE); + rb_thread_main_jump(e, RESTORE_RAISE); } @@ -9420,12 +9436,10 @@ rb_thread_start_0(fn, arg, th_arg) else { /* delegate exception to main_thread */ - rb_thread_raise(1, &ruby_errinfo, main_thread); + rb_thread_main_jump(ruby_errinfo, RESTORE_RAISE); } } else if (th->safe < 4 && (ruby_thread_abort || th->abort || RTEST(ruby_debug))) { - VALUE err = system_exit(1, 0, 0); - error_print(); /* exit on main_thread */ - rb_thread_raise(1, &err, main_thread); + rb_thread_main_jump(ruby_errinfo, RESTORE_EXIT); } else { -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦