とみたです。

On Fri, 24 Jun 2005 16:45:34 +0900
Tanaka Akira <akr / m17n.org> wrote:

> 普通というのがどの程度かということによりますが、fd_set を動的に確保する方法は
> NetBSD のマニュアルには載っていて、基本的にはそれにそった形です。
> (BUGS section なのがなんですが)

NetBSD ではマニュアルに書いてあるから、その方法でもいいんでしょうけど、
Solaris のマニュアルには

     The poll(2) function is preferred  over  this  function.  It
     must  be  used  when  the number of file descriptors exceeds
     FD_SETSIZE.

と書いてありますし、手元の Linux(Debian)では

       An  fd_set  is  a  fixed size buffer. Executing FD_CLR or FD_SET with a
       value of fd that is negative or is equal to or larger  than  FD_SETSIZE
       will  result in undefined behavior.

となってます。

その他の OS の事情は知りませんが、結局、OS 毎に異なる実装が必要となっ
てしまい、田中さんが書いてるような「環境によって実装を変える」面倒事に
なってしまうんじゃないでしょうか。

> そして、そのやりかたについて考えてみると、fd_set の中身が bitmap であ
> り、カーネルに FD_SETSIZE の制限がないのであれば動くであろうことが期待
> できます。

たしかに、これでいけそうな気もするんですけど、私は「やってみたらたまた
ま上手くいった」感が拭えないんですよね…。

> poll に具体的な利点があれば poll を使ったほうがいいとは思います。しか
> し、カーネルに FD_SETSIZE の制限があるか、fd_set の中身が bitmap でな
> い場合で、現状 poll を使って救える環境が思い当たりません。
> 
> poll の利点が具体的にあれば変えたほうがいいと思います。でも、現時点で
> 見当たらないのであれば、見つかるまで select でいいんじゃないでしょうか。

poll の利点は、「FD_SETSIZE 以上のファイル記述子を扱うことができる正当
な方法である」ということです。

> > ・ poll() がある環境:
> >    select() ではなく poll() を使う。
> >
> > ・ poll() がない環境:
> >    open/socket/pipe 等で FD_SETSIZE 以上のファイル記述子が生成された場
> >    合は、Errno::EMFILE 例外にする。
> >
> > というような感じではどうでしょう?

> 環境によって実装を変えるのは、避けられるのであれば避けたほうがいいと思
> います。開発者の手元で使用されないコードは壊れたときに気がつくのが遅れ
> ますし、問題があったときの再現実験や修正も厄介です。

「環境によって実装を変える」とは言っても、poll() があるかないかの2種
類だけなので、OS/ライブラリ毎に実装を変えるよりはシンプルだと思います。

> そのような面倒事は、本当に必要な状況が確認されるまで導入を遅らせたほう
> がいいんじゃないでしょうか。

1.8.x への大掛かりな変更の導入はちょっと迷うところですけど、1.9 への導
入だったら考えてもいいんじゃないでしょうか。

-- 
とみたまさひろ <tommy / tmtm.org>
3469 42CC 4D32 F53C AD98  65A5 8C37 FF09 69C1 6040