KQUEUE(2) FreeBSD システムコールマニュアル KQUEUE(2)
名称
kqueue, kevent − カーネルイベント通知メカニズム |
ライブラリ
標準 C ライブラリ (libc, −lc) |
書式
#include <sys/types.h> int |
kqueue(void); int |
kevent(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents, const struct timespec *timeout); |
EV_SET(&kev, ident, filter, flags, fflags, data, udata); |
解説 |
kqueue() システムコールは、フィルタと呼ばれる小さなカーネルコードの実行結 果に基づき、イベントの発生やある状態の成立をユーザに通知する一般的な方法 を提供します。 kevent は (ident, filter) のペアによって識別されます。ここ で、ident は識別子、filter はフィルタを表します。 1 つの kqueue には、同 じ kevent が複数存在することはできません。 フィルタは、kevent の初期登録時に以前から存在した状態を検出するために実行 されます。また、あるイベントが評価のためにフィルタに渡されるたびに実行さ れます。状態を報告すべきとフィルタが決定した場合には、その kevent はユー ザが回収できるように kqueue に置かれます。 ユーザが kqueue から kevent を回収しようとしたときにも、フィルタが実行さ れます。フィルタの実行により、そのイベントをトリガした状態が成立していな いことが示された場合には、その kevent は kqueue から削除され、ユーザに渡 されません。 フィルタをトリガするイベントが複数ある場合でも、 kqueue の中に kevent が 複数置かれるわけではありません。代わりに、フィルタは複数のイベントを単一 の kevent 構造体へ集めます。ファイル記述子に対する close() の呼び出しは、 その記述子を参照しているあらゆる kevent を削除します。 kqueue() システムコールは新規のカーネルイベントキューを生成して記述子を返 します。キューは fork(2) で生成された子プロセスには継承されません。しかし ながら、 RFFDG フラグなしで rfork(2) が呼び出された場合には、記述子テーブ ルが共有され、2 つのプロセス間で kqueue の共有が可能になります。 kevent() システムコールは、キューにイベントを登録し、保留中のあらゆるイベ ントをユーザに返すために使用されます。 changelist 引数は kevent 構造体の 配列へのポインタです。この構造体は <sys/event.h> で定義されています。保留 中のイベントをキューから読み取る前に、 changelist に含まれている全ての変 更を適用します。 nchanges 引数は changelist の大きさを与えます。 eventlist 引数は kevent 構造体の配列へのポインタです。 nevents 引数は eventlist の大きさを決定します。 nevents が 0 の時には、 select(2) とは 違って、たとえ timeout がある場合でも kevent() はすぐに戻ります。 timeout が NULL でないポインタの場合には、timespec 構造体であると解釈されて、イベ ントを待つ最大待ち時間を指定します。 timeout が NULL ポインタの場合には、 kevent() は無期限に待ちます。ポーリングの効果を得るためには、 timeout 引 数に、0 を示す timespec 構造体を指す非 NULL のポインタを与えるべきです。 changelist と eventlist 用に同じ配列を使うことができます。 EV_SET() マクロは kevent 構造体の初期化を簡単にするために用意されていま す。 kevent 構造体は次のように定義されています: struct kevent { |
uintptr_t ident; |
/* このイベントの識別子 */ |
||||
short |
filter; |
/* イベントのフィルタ */ |
|||
u_short |
flags; |
/* kqueue のアクションフラグ */ |
|||
u_int |
fflags; |
/* フィルタフラグ値 */ |
|||
intptr_t data; |
/* フィルタデータ値 */ |
||||
void |
*udata; |
/* 不透明なユーザデータ識別子 */ |
}; struct kevent のフィールドは以下のとおりです: |
ident
このイベントを識別するために使用される値です。厳密な解釈は結び 付けられたフィルタにより決定されますが、普通はファイル記述子と して解釈されます。 filter flags fflags data udata flags フィールドは以下の値を含むことができます: EV_ADD EV_ENABLE EV_DISABLE EV_DELETE EV_ONESHOT EV_CLEAR EV_EOF EV_ERROR あらかじめ定義されたシステムフィルタを次に示します。引数は kevent 構造体 の fflags および data フィールドを経由してやりとりすることができます。 EVFILT_READ ソケット その他のソケット記述子の場合、ソケットバッファの SO_RCVLOWAT の値を基準にして、読み取るデータがあるとき に戻ります。フィルタを追加するときに、 fflags に NOTE_LOWAT を設定し data に新しい最低基準値を指定する ことにより、この値を、フィルタごとの最低基準値で上書き することが可能です。戻るときには、 data には読取り可能 なプロトコルデータのバイト数が入っています。 ソケットの読取り側が切断された場合には、フィルタは flags に EV_EOF も設定します。ここでエラーが起きた場合 には、 fflags にソケットエラーを返します。ソケットバッ ファの中に保留中のデータが残っていても、 (接続が切れた ことを示す) EOF が返されることがあります。 vnode FIFO とパイプ 最後の書込み側が切断したときに、フィルタは flags に EV_EOF をセットします。 EV_CLEAR を渡すことで、このフ ラグをクリアすることができ、フィルタはデータが読み取る ようになるのを戻らずに再び待ちます。 BPF デバイス EVFILT_WRITE ソケットの場合、最低基準値およびソケットエラーの取り扱いは EVFULT_READ の場合と同じです。 EVFILT_AIO 別の方法として、 ident に kqueue 記述子を入れて kevent 構 造体を初期化し、そのアドレスを非同期要求の aio_lio_opcode フィールドに置くことも可能です。しかしながら、このアプロー チは 64 ビットポインタのアーキテクチャでは動作しないでしょ うし、あてにするべきではありません。 EVFILT_VNODE NOTE_DELETE NOTE_WRITE NOTE_EXTEND NOTE_ATTRIB NOTE_LINK NOTE_RENAME NOTE_REVOKE 戻るときに、 fflags にフィルタをトリガしたイベントが入って います。 EVFILT_PROC NOTE_EXIT NOTE_FORK NOTE_EXEC NOTE_TRACK NOTE_TRACKERR 戻るときに、 fflags はフィルタをトリガしたイベントが入って います。 EVFILT_SIGNAL EVFILT_TIMER EVFILT_NETDEV NOTE_LINKUP NOTE_LINKDOWN NOTE_LINKINV 戻るとき、フィルタをトリガしたイベントが fflags に格納され ます。 戻り値 |
kqueue() システムコールは新規のカーネルイベントキューを生成し、ファイル記 述子を返します。カーネルイベントキューの生成時にエラーがあった場合には、 値 -1 が返されて errno がセットされます。 kevent() システムコールは eventlist に配列されているイベントの数を返しま す。この数は、最大 nevents で与えられた値までです。 changelist の要素の処 理中にエラーが発生し、かつ eventlist に十分な余地がある場合には、 flags に EV_ERROR がセットされ、 data にシステムエラーがセットされたイベント が、 eventlist に置かれます。さもなければ、 -1 が返され、 errno がエラー 状態を示すためにセットされます。時間切れの場合には、 kevent() は 0 を返し ます。 |
エラー
kqueue() システムコールは以下の場合に失敗します: |
[ENOMEM]
カーネルがカーネルキューのための十分なメモリの割り当て に失敗しました。 [EMFILE] [ENFILE] kevent() 関数は以下の場合に失敗します: [EACCES] [EFAULT] [EBADF] [EINTR] [EINVAL] [ENOENT] [ENOMEM] [ESRCH] 関連項目 |
aio_error(2), aio_read(2), aio_return(2), poll(2), read(2), select(2), sigaction(2), write(2), signal(3) |
歴史
kqueue() および kevent() システムコールは FreeBSD 4.1 ではじめて登場しま した。 |
作者
kqueue() システムと、このマニュアルページは Jonathan Lemon 〈jlemon@FreeBSD.org〉 が書きました。 |
バグ
現在は、UFS ファイルシステムに属さない vnode(9) を監視することができませ ん。 EVFILT_NETDEV フィルタが現在実装されているのは、LINKUP と LINKDOWN の操作 に miibus(4) ドライバを使用しているデバイスに対してのみです。そのため、非 イーサネットデバイスに対しては動作しません。 timeout の値は 24 時間に制限されています。より長いタイムアウトは暗黙のう ちに 24 時間として再解釈されます。 FreeBSD 10.0 April 14, 2000 FreeBSD 10.0 |