gauche.selector
- 簡単なディスパッチャ ¶このモジュールは、sys-select
(I/Oの多重化参照)に基づき、
登録されたハンドラにI/Oイベントをディスパッチするためのシンプルな
インタフェースを提供します。
{gauche.selector
}
ディスパッチャのインスタンスで、ハンドラを携えてI/Oポートを監視します。
make
メソッドで新しいインスタンスを作れます。
{gauche.selector
}
セレクタにハンドラprocを追加します。procは、port-or-fd
(ポートオブジェクトかシステムのファイルディスクリプタを表す整数)が
flagsで指定された条件に合致した場合に呼ばれます。
flagsは、以下のシンボルの1つ以上のリストでなければなりません。
r
port-or-fdが読み取り可能になった時点でprocが呼ばれます。
w
port-or-fdが書き込み可能になった時点でprocが呼ばれます。
x
port-or-fdで例外的な状況が発生した場合にprocが呼ばれます。
procは、2引数で呼ばれます。1つ目はport-or-fdそのもので、
2つ目は条件を表すシンボル、r
、w
あるいはx
です。
同じ条件の下ですでにport-or-fdにハンドラが関連付けられていた場合は、 以前のハンドラがprocで置き換えられます。
{gauche.selector
}
port-or-fd、proc、flagsにマッチするハンドラエントリを
削除します。引数のいずれかが#f
である場合は、それが何でも良いことを
意味します。例えば、
(selector-delete! selector the-port #f #f)
the-portに関連付けられた全てのハンドラを削除します。
(selector-delete! selector #f #f '(w))
書き込み可能になるのを待っている全てのハンドラを削除します。
{gauche.selector
}
ディスパッチャのボディです。selfに登録された条件を待ち、条件が合致すると
それに関連付けられたハンドラを呼びます。
timeout引数が省略されるか偽の場合、このメソッドは永久に待ちます。
タイムアウトの値を与える場合は、マイクロ秒を表す実数か、秒とマイクロ秒を
表す2つの整数のリストを与えます。
戻り値は、ハンドラが呼ばれた回数です。0(ゼロ)は、セレクタがタイムアウト したことを意味します。
ハンドラの中でselfを変更することは安全です。その変更は、次回の
selector-select
の呼び出し以降に反映されます。
echoサーバのシンプルな例を示します。
(use gauche.net) (use gauche.selector) (use gauche.uvector) (define (echo-server port) (let ((selector (make <selector>)) (server (make-server-socket 'inet port :reuse-addr? #t))) (define (accept-handler sock flag) (let* ((client (socket-accept server)) (output (socket-output-port client))) (selector-add! selector (socket-input-port client :buffering #f) (lambda (input flag) (echo client input output)) '(r)))) (define (echo client input output) (let ((str (read-uvector <u8vector> 4096 input))) (if (eof-object? str) (begin (selector-delete! selector input #f #f) (socket-close client)) (begin (write-uvector str output) (flush output))))) (selector-add! selector (socket-fd server) accept-handler '(r)) (do () (#f) (selector-select selector))))