From: Tanaka Akira Date: 2012-06-20T07:50:25+09:00 Subject: [ruby-dev:45783] Re: [ruby-changes:24083] nobu:r36134 (trunk): process.c: no method calls in async-signal-safe 2012/6/19 Tanaka Akira : > > どういう状況でこの NUM2MODET からメソッド呼び出しが起こるのか > 理解できなかったんですが、どういう話なんでしょう? さらに調べたところ、 rb_num2uint の check_uint(num, rb_funcall(val, '<', 1, INT2FIX(0))) というところで、 メソッド呼び出しが起こることを理解しました。 うぅむ。これは rb_num2uint を変えた方がまだマシなような。 (根本的には親プロセスで mode_t な値に変換するのが適切でしょうが) なお、記録として調べた方法を書いておきますが、 中田さんの変更を入れる直前の r36133 に 以下のパッチの numeric.c の部分を除いて適用すると、make check や ./ruby -e 'system("echo a", :umask => 0)' において、 fork した (async-signal-safe を意図した) 子プロセスで rb_call0 が 呼ばれることを確認できます。 また、numeric.c の部分も適用すれば、rb_call0 が呼ばれなくなることを 確認できます。 % svn diff --diff-cmd diff -x '-u -p' Index: vm_eval.c =================================================================== --- vm_eval.c (revision 36133) +++ vm_eval.c (working copy) @@ -219,6 +219,7 @@ static inline VALUE rb_call0(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope, VALUE self) { + assert(!forked_child); rb_method_entry_t *me = rb_search_method_entry(recv, mid); rb_thread_t *th = GET_THREAD(); int call_status = rb_method_call_status(th, me, scope, self); Index: process.c =================================================================== --- process.c (revision 36133) +++ process.c (working copy) @@ -984,7 +984,7 @@ proc_detach(VALUE obj, VALUE pid) return rb_detach_process(NUM2PIDT(pid)); } -static int forked_child = 0; +int forked_child = 0; #ifdef SIGPIPE static RETSIGTYPE (*saved_sigpipe_handler)(int) = 0; Index: internal.h =================================================================== --- internal.h (revision 36133) +++ internal.h (working copy) @@ -12,6 +12,8 @@ #ifndef RUBY_INTERNAL_H #define RUBY_INTERNAL_H 1 +#include + #if defined(__cplusplus) extern "C" { #if 0 @@ -158,6 +160,7 @@ VALUE rb_proc_location(VALUE self); st_index_t rb_hash_proc(st_index_t hash, VALUE proc); /* process.c */ +extern int forked_child; /* argv_str contains extra two elements. * The beginning one is for /bin/sh used by exec_with_sh. Index: numeric.c =================================================================== --- numeric.c (revision 36133) +++ numeric.c (working copy) @@ -1945,7 +1945,8 @@ rb_num2uint(VALUE val) { VALUE num = rb_num2ulong(val); - check_uint(num, rb_funcall(val, '<', 1, INT2FIX(0))); + check_uint(num, FIXNUM_P(val) ? FIX2LONG(val) < 0 : + rb_funcall(val, '<', 1, INT2FIX(0))); return (unsigned long)num; } -- [田中 哲][たなか あきら][Tanaka Akira]