From: Nobuyoshi Nakada Date: 2007-03-19T15:26:29+09:00 Subject: [ruby-dev:30636] Re: stdout flush in fork なかだです。 At Mon, 19 Mar 2007 13:28:46 +0900, Yukihiro Matsumoto wrote in [ruby-dev:30630]: > とはいえ、flushせねばならないのはforkを行ったスレッドが出力 > したもので、他のスレッドが出力したものについては他のスレッド > からいずれflushされるのは間違いないように思います。 通常の流れではそうですが、fork(2)がEAGAINで失敗したときにはリトライ前に sleepしてますから、そこで他のスレッドからfork前に出力されてしまう可能性 はあるかもしれません。 1.8だとリトライしていたのはsystemだけだったんですが、rubyレベルで毎回そ こまで面倒見ないといけないというのもイヤなのでProcess.forkもあわせてしま いました。見落としてました。 Index: process.c =================================================================== --- process.c (revision 12090) +++ process.c (working copy) @@ -1344,8 +1344,14 @@ rb_fork(int *status, int (*chfunc)(void* #ifndef __VMS - rb_io_flush(rb_stdout); - rb_io_flush(rb_stderr); +#define prefork() ( \ + rb_io_flush(rb_stdout), \ + rb_io_flush(rb_stderr) \ + ) +#else +#define prefork() ((void)0) #endif + prefork(); + #ifdef FD_CLOEXEC if (chfunc) { @@ -1357,5 +1363,5 @@ rb_fork(int *status, int (*chfunc)(void* } #endif - while ((pid = fork()) < 0) { + for (; (pid = fork()) < 0; prefork()) { switch (errno) { case EAGAIN: -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦