山本です。 自分のパッチを整理してみました。コミットできるものがありますか? できれば 1.8.2 の前にコミットしておきたいです。 //---------------------------------------------------------------- // Thread: [ruby-dev:23717] // Subject: test/drb の途中で EINVAL が出る問題 (bcc32) // Reason: bcc32 ではオープンできるファイル数が 50 に設定されており、 // この上限に達してしまっている。ENFILE ではなく EINVAL なのは、 // bcc32 で errno が設定されないため。(io.c(2418)) //---------------------------------------------------------------- * プールサイズを1つ減らす Index: drb.rb =================================================================== RCS file: /var/cvs/src/ruby/lib/drb/drb.rb,v retrieving revision 1.19 diff -u -w -b -p -r1.19 drb.rb --- drb.rb 16 May 2004 15:09:52 -0000 1.19 +++ drb.rb 4 Jul 2004 00:59:50 -0000 @@ -1054,7 +1054,7 @@ module DRb # This class is used internally by DRbObject. The user does # not normally need to deal with it directly. class DRbConn - POOL_SIZE = 16 # :nodoc: + POOL_SIZE = 15 # :nodoc: @mutex = Mutex.new @pool = [] もしくは、 * プールの古いソケットと入れ替える Index: drb.rb =================================================================== RCS file: /var/cvs/src/ruby/lib/drb/drb.rb,v retrieving revision 1.19 diff -u -w -b -p -r1.19 drb.rb --- drb.rb 16 May 2004 15:09:52 -0000 1.19 +++ drb.rb 4 Jul 2004 00:13:48 -0000 @@ -1080,11 +1080,14 @@ module DRb return succ, result ensure + if conn + if succ @mutex.synchronize do - if @pool.size > POOL_SIZE or ! succ - conn.close if conn - else @pool.unshift(conn) + @pool.pop.close while @pool.size > POOL_SIZE + end + else + conn.close end end end どちらでもテストが通るようになります。根本的な解決ではありませんが、 プールの古いソケットと入れ替えるのは、それほど悪い処置ではないと思います。 [ruby-dev:23743] の ENFILE, EMFILE のときプールを空ける処理は、 あまり自信がないので削りました。 また、win32/win32.c の fopen などで errno を設定するパッチも、 内部実装に依存する点が気になるので見送りました。 //---------------------------------------------------------------- // Thread: [ruby-dev:23730] // Subject: test/ruby/test_pipe.rb で EOF のテストに失敗する問題 (bcc32) // Reason: Win32APIのReadFile は、書き込み端が閉じている名前なしパイプに // 対してデータ以上読もうとすると、GetLastError に ERROR_BROKEN_PIPE // を設定して失敗する。bcc32のfreadはこれに対処していないため、 // EOFフラグが立たずEPIPE例外になる。 //---------------------------------------------------------------- //---------------------------------------------------------------- // Thread: なし // Subject: miniruby -ve "r, w = IO.pipe; p r.stat.ftype; r.close; w.close" // で "blockSpecial" と表示される問題 (bcc32) // Reason: bcc32 の stdio.h で、なぜか S_IFBLK が S_IFIFO と S_IFCHR の和 // になっているため。仕様? //---------------------------------------------------------------- * win32/win32.c(rb_w32_fread): EPIPE のときは、エラーをクリアして、EOFフラグを 立てる。 * S_ISBLK(パイプハンドル) が false になるよう、定義を復活 * プロトタイプの宣言されていない rb_w32_??? があったので追加 read(n) と EOF の問題について、過去ログを読んで考えたんですが、 これといった結論がでませんでした。ただ、fread の前に clearerr すれば、増えつづけるファイルを読みつづけられと思うのですが、どうでしょうか。 Index: win32.c =================================================================== RCS file: /var/cvs/src/ruby/win32/win32.c,v retrieving revision 1.117 diff -u -w -b -p -r1.117 win32.c --- win32.c 21 Jun 2004 00:27:39 -0000 1.117 +++ win32.c 4 Jul 2004 03:28:28 -0000 @@ -3034,11 +3034,15 @@ rb_w32_getc(FILE* stream) else #endif { - c = _filbuf(stream); #if defined __BORLANDC__ || defined _WIN32_WCE - if ((c == EOF) && (errno == EPIPE)) { + errno = 0; + c = _filbuf(stream); + if (c == EOF && errno == EPIPE) { clearerr(stream); + stream->flags |= _F_EOF; } +#else + c = _filbuf(stream); #endif rb_trap_immediate = trap_immediate; catch_interrupt(); @@ -3065,6 +3069,22 @@ rb_w32_putc(int c, FILE* stream) } return c; } + +#if defined __BORLANDC__ || defined _WIN32_WCE +#undef fread +size_t rb_w32_fread(void *ptr, size_t size, size_t n, FILE *stream) +{ + size_t ret; + + errno = 0; + ret = fread(ptr, size, n, stream); + if (ret < n && errno == EPIPE) { + clearerr(stream); + stream->flags |= _F_EOF; + } + return ret; +} +#endif struct asynchronous_arg_t { /* output field */ Index: win32.h =================================================================== RCS file: /var/cvs/src/ruby/win32/win32.h,v retrieving revision 1.51 diff -u -w -b -p -r1.51 win32.h --- win32.h 19 Feb 2004 09:08:23 -0000 1.51 +++ win32.h 4 Jul 2004 03:23:50 -0000 @@ -121,6 +121,10 @@ extern "C++" { #define stat(path,st) rb_w32_stat(path,st) #undef execv #define execv(path,argv) rb_w32_aspawn(P_OVERLAY,path,argv) +#if defined __BORLANDC__ || defined _WIN32_WCE +#undef fread +#define fread(p, m, n, stream) rb_w32_fread(p, m, n, stream) +#endif #ifdef __MINGW32__ struct timezone { @@ -179,6 +183,14 @@ extern int rb_w32_aspawn(int, const char extern int kill(int, int); extern pid_t rb_w32_getpid(void); +extern int rb_w32_stat(const char *, struct stat *); +#if defined __BORLANDC__ +extern int rb_w32_fstat(int, struct stat *); +#endif +#if defined __BORLANDC__ || defined _WIN32_WCE +extern size_t rb_w32_fread(void *, size_t, size_t, FILE *); +#endif + #include <float.h> #if !defined __MINGW32__ || defined __NO_ISOCEXT #ifndef isnan @@ -189,7 +201,7 @@ extern pid_t rb_w32_getpid(void); #endif #endif -#if 0 && defined __BORLANDC__ +#if defined __BORLANDC__ #undef S_ISDIR #undef S_ISFIFO #undef S_ISBLK //---------------------------------------------------------------- // Thread: [ruby-talk:105100] // Subject: "Inf".to_f が 0.0 になる // Reason: ruby_strtod が "NaN" と "Inf" を扱っていなかった //---------------------------------------------------------------- * numeric.c(flo_to_s): 無限大の表記を Inf にあわせた * util.c(ruby_strtod): "NaN" と "Inf" の処理を追加した(case insensitive) * util.h: atof も ruby_strtod を使うようにした。(使っているソースはありませんが、念のため) Index: numeric.c =================================================================== RCS file: /var/cvs/src/ruby/numeric.c,v retrieving revision 1.112 diff -u -w -b -p -r1.112 numeric.c --- numeric.c 16 Jun 2004 14:21:33 -0000 1.112 +++ numeric.c 3 Jul 2004 02:07:37 -0000 @@ -495,7 +495,7 @@ flo_to_s(flt) char *p, *e; if (isinf(value)) - return rb_str_new2(value < 0 ? "-Infinity" : "Infinity"); + return rb_str_new2(value < 0 ? "-Inf" : "Inf"); else if(isnan(value)) return rb_str_new2("NaN"); Index: util.c =================================================================== RCS file: /var/cvs/src/ruby/util.c,v retrieving revision 1.43 diff -u -w -b -p -r1.43 util.c --- util.c 14 May 2004 03:17:29 -0000 1.43 +++ util.c 3 Jul 2004 02:11:15 -0000 @@ -750,6 +750,7 @@ ruby_strtod(string, endPtr) * in string. */ const char *pExp; /* Temporarily holds location of exponent * in string. */ + int frac1, frac2; /* * Strip off leading blanks and check for a sign. @@ -772,6 +773,22 @@ ruby_strtod(string, endPtr) } /* + * Check for NaN and Inf. + */ + + if (strncmpi(p, "NaN", 3) == 0) { + p += 3; + fraction = 0.0 / 0; + goto exit; + } + + if (strncmpi(p, "Inf", 3) == 0) { + p += 3; + fraction = 1.0 / 0; + goto exit; + } + + /* * Count the number of digits in the mantissa * and also locate the decimal point. */ @@ -812,8 +829,7 @@ ruby_strtod(string, endPtr) fracExp += (mantSize - 18); mantSize = 18; } - { - int frac1, frac2; + frac1 = 0; for ( ; mantSize > 9; mantSize -= 1) { c = *p; @@ -920,12 +936,11 @@ ruby_strtod(string, endPtr) else { fraction += frac2 * dblExp; } - } + exit: if (endPtr != NULL) { *endPtr = (char *) p; } - if (sign) { return -fraction; } Index: util.h =================================================================== RCS file: /var/cvs/src/ruby/util.h,v retrieving revision 1.14 diff -u -w -b -p -r1.14 util.h --- util.h 4 Aug 2003 01:27:25 -0000 1.14 +++ util.h 3 Jul 2004 02:11:20 -0000 @@ -62,5 +62,6 @@ char *ruby_getcwd _((void)); double ruby_strtod _((const char*, char **)); #define strtod(s,e) ruby_strtod(s,e) +#define atof(s) ruby_strtod(s,0) #endif /* UTIL_H */