プロトコルハンドラをイベントドリブンに書く場合に O_NONBLOCK をセットするかしないか。または、それらを多重化する場合の方針について

 まず、イベントドリブンなプロトコルハンドラを実装する側の事情を説明すると、O_NONBLOCK をセットすると、複雑なプロトコルの実装 (あちこちで write(2) を呼んでるとか) にあたって、いちいち select(2)->poll(2) のステップをふまなくても、返り値が EWOULDBLOCK (EAGAIN) だったら戻るようにすればいいので楽。
 逆に、プロトコルハンドラの呼び出しは、必ず、ソケットが(読み|書き)できるという事前条件が満たされる場合に限るべし、という方針のもとに、O_NONBLOCK をセットしない派の人たちもいる。

 一方、既存の(他人が書いた)プロトコルハンドラを多重化して (select(2) や poll(2) を呼んだり、子ルーチンを使ったりして) 書く場合、両方のモデルに対応する必要がある。よって、

  • プロトコルハンドラを呼び出す際には、読み(書き)可能であるという事前条件を確実に満たすようにする
  • O_NONBLOCK フラグを勝手に書き換えない

ことが重要になる。さもないと通信エラー、ビジーループ、予期せぬブロック処理、といったものが発生する可能性がある。