In article <200506010140.j511edY4012889 / sharui.nakada.niregi.kanuma.tochigi.jp>, nobu / ruby-lang.org writes: > こんな感じでしょうか。 基本的な方針は「なぜか余計にメモリを確保しておいて動いたらラッキー」な ので、今まで参照していなかった FD_SETSIZE は今さら参照しなくても書ける はずなんじゃないかと思います。 > void > rb_fd_zero(fds) > rb_fdset_t *fds; > { > if (fds->fdset) { > MEMZERO(fds->fdset, fd_mask, howmany(fds->maxfd, NFDBITS)); > if (sizeof(fd_set) * CHAR_BIT != howmany(FD_SETSIZE, NFDBITS) * NFDBITS) > FD_ZERO(fds->fdset); > } > } FD_ZERO による初期状態が 0 の並びでない可能性を考慮するなら、FD_ZERO は常に行うべきでしょう。 if (fds->fdset) { MEMZERO(fds->fdset, fd_mask, howmany(fds->maxfd, NFDBITS)); FD_ZERO(fds->fdset); } > void > rb_fd_set(n, fds) > int n; > rb_fdset_t *fds; > { > int m, o; > > if (n < FD_SETSIZE) > m = sizeof(fd_set); > else > m = howmany(n + 1, NFDBITS) * NFDBITS; > if (fds->maxfd <= FD_SETSIZE) > o = sizeof(fd_set); > else > o = howmany(fds->maxfd, NFDBITS) * NFDBITS; > > if (m > o) { > fds->fdset = realloc(fds->fdset, m); > memset((char *)fds->fdset + o, 0, m - o); > } > if (n >= fds->maxfd) fds->maxfd = n + 1; > FD_SET(n, fds->fdset); > } FD_SETSIZE を避けるならこうかなぁ。 int m, o; m = howmany(n + 1, NFDBITS) * NFDBITS; if (m < sizeof(fd_set)) m = sizeof(fd_set); o = howmany(fds->maxfd, NFDBITS) * NFDBITS; if (o < sizeof(fd_set)) o = sizeof(fd_set); if (m > o) { fds->fdset = realloc(fds->fdset, m); memset((char *)fds->fdset + o, 0, m - o); } if (n >= fds->maxfd) fds->maxfd = n + 1; FD_SET(n, fds->fdset); > void > rb_fd_clr(n, fds) > int n; > rb_fdset_t *fds; > { > if (n > FD_SETSIZE && n >= fds->maxfd) return; > FD_CLR(n, fds->fdset); > } これもこうですかねぇ。 if (n >= fds->maxfd) return; FD_CLR(n, fds->fdset); > int > rb_fd_isset(n, fds) > int n; > const rb_fdset_t *fds; > { > if (n > FD_SETSIZE && n >= fds->maxfd) return 0; > return FD_ISSET(n, fds->fdset); > } これも。 if (n >= fds->maxfd) return 0; return FD_ISSET(n, fds->fdset); > void > rb_fd_copy(dst, src, max) > rb_fdset_t *dst; > const fd_set *src; > int max; > { > int size = sizeof(fd_set); > if ((dst->maxfd = max) > FD_SETSIZE) { > size = howmany(max, NFDBITS) * NFDBITS; > } > dst->fdset = realloc(dst->fdset, size); > memcpy(dst->fdset, src, size); > } これはこうかなぁ。 int size = howmany(max, NFDBITS) * NFDBITS; if (size < sizeof(fd_set)) size = sizeof(fd_set); dst->fdset = realloc(dst->fdset, size); memcpy(dst->fdset, src, size); >> # Windows の fd_set は違うというので探したら、 >> # http://msdn.microsoft.com/library/en-us/winsock/winsock/fd_set_2.asp >> # を見る限りは MEMZERO だけでよさそうですねぇ。 > > そもそもwinsockがFD_SETSIZE以上を見てくれるかどうか、というより > もWaitForMultipleObjects()が見てくれなさげ。 MEMZERO だけでいいというのは、FD_ZERO と同等の効果がありそうだ、という 意味です。 FD_SETSIZE以上のサポートを広げるという意味では、poll にする意味が有る かというのが興味の有るところなのですが、Windows は救えなさそうですね。 (そもそも Windows に poll があるのかどうか知りませんが) poll にすれば救える環境って存在するのかなぁ? -- [田中 哲][たなか あきら][Tanaka Akira]