epoll_ctl - epoll
ディスクリプターのインターフェースを操作する
#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int
fd, struct epoll_event *event);
このシステムコールは、ファイルディスクリプター
epfd が参照する
epoll(7)
インスタンスに対する操作を行う。
対象のファイルディスクリプター
fd に対して、 操作
op
の実行が要求される。
op
引き数に指定できる有効な値は以下の通りである。
- EPOLL_CTL_ADD
- 対象のファイルディスクリプター
fd
をファイルディスクリプター
epfd が参照する epoll
インスタンスに登録し、イベント
event を fd
に結び付けられた内部ファイルに関連付ける。
- EPOLL_CTL_MOD
- イベント event
を対象のファイルディスクリプター
fd
に関連付けるように変更する。
- EPOLL_CTL_DEL
- 対象のファイルディスクリプター
fd を epfd が参照する
epoll
インスタンスから削除する。
event
引き数は無視されるので、NULL
にすることもできる
(但し、下記の「バグ」を参照)。
event
引き数は、ファイルディスクリプター
fd
にリンクされたオブジェクトを表す。
struct epoll_event
は以下のように定義される。
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event {
uint32_t events; /* epoll イベント */
epoll_data_t data; /* ユーザーデータ変数 */
};
events
メンバは、以下のような使用可能なイベントタイプを使って構成された
ビットセットである。
- EPOLLIN
- 関連付けられたファイルに対して、
read(2)
操作が可能である。
- EPOLLOUT
- 関連付けられたファイルに対して、
write(2)
操作が可能である。
-
EPOLLRDHUP"(Linux2.6.17以降)"
- ストリームソケットの他端が、コネクションの
close 、
またはコネクションの書き込み側の
shutdown を行った。
(このフラグを使うと、エッジトリガーの監視を行う場合に、
通信のもう一端が閉じられたことを検知するコードを
非常に簡潔に書くことができる。)
- EPOLLPRI
-
read(2)
操作が可能な緊急 (urgent)
データがある。
- EPOLLERR
- 関連付けられたファイルディスクリプターにエラー条件が起こった。
epoll_wait(2)
は常にこのイベントを待つので、
events
に設定する必要はない。
- EPOLLHUP
- 関連付けられたファイルディスクリプターにハングアップが起こった。
epoll_wait(2)
は常にこのイベントを待つので、
events
に設定する必要はない。
- EPOLLET
- 関連付けられたファイルディスクリプターに
エッジトリガー動作
(Edge Triggered behavior) を設定する。
epoll
のデフォルトの動作は、レベルトリガー
(Level Triggered) である。
エッジトリガーとレベルトリガーによるイベント分配機構
(event distribution architectures)
についての詳細な情報は、
epoll(7)
を参照すること。
-
EPOLLONESHOT (Linux 2.6.2 以降)
- 関連付けられたファイルディスクリプターに
一撃動作 (One-Shot behavior)
を設定する。
これはイベントが
epoll_wait(2)
によって引き出された後、
関連付けられたファイルディスクリプターが内部的に破棄され、
epoll
インターフェースによってイベントが報告されなくなることを意味する。
新しいイベントマスクでファイルディスクリプターを再度有効にするためには、
epoll_ctl() に EPOLL_CTL_MOD
を指定して呼び出さなければならない。
op
引き数に指定できる有効な値は、以下の通り:
-
EPOLLWAKEUP (Linux 3.5 以降)
-
EPOLLONESHOT と EPOLLET
がクリアされており、
プロセスが CAP_BLOCK_SUSPEND
ケーパビリティを持っている場合、
イベントが処理待ちか処理中かにかかわらず、必ずシステムが
"suspend" や "hibernate"
に入らないようにすること。
epoll_wait(2)
の呼び出しが返った時点から、
同じ epoll(7)
ファイルディスクリプターに対して
epoll_wait(2)
が次に呼び出されるか、
そのファイルディスクリプターが閉じられるか、
イベントファイルディスクリプターが
EPOLL_CTL_DEL
で削除されるか、
EPOLL_CTL_MOD
でイベントファイルディスクリプターの
EPOLLWAKEUP
がクリアされるか、
のいずれかになるまで、イベントは「処理中」であるとみなされる。
「バグ」の節も参照のこと。
成功した場合、
epoll_ctl()
は 0 を返す。
エラーが起こった場合、
epoll_ctl() は -1 を返し、
errno
を適切に設定する。
- EBADF
-
epfd か fd
が有効なファイルディスクリプターでない。
- EEXIST
-
op が EPOLL_CTL_ADD
であり、かつ与えられたファイルディスクリプター
fd がこの epoll
インスタンスに既に登録されている。
- EINVAL
-
epfd が epoll
ファイルディスクリプターでない。
または fd が epfd
と同一である。
または要求された操作
op
がこのインターフェースでサポートされていない。
- ENOENT
-
op が EPOLL_CTL_MOD
または EPOLL_CTL_DEL
で、かつ fd がこの epoll
インスタンスに登録されていない。
- ENOMEM
- 要求された op
制御操作を扱うのに十分なメモリーがない。
- ENOSPC
- epoll
インスタンスに新しいファイルディスクリプターを登録
( EPOLL_CTL_ADD)
しようとした際に、
/proc/sys/fs/epoll/max_user_watches
で決まる上限に達した。
詳細は epoll(7)
を参照。
- EPERM
- 対象ファイル fd
が epoll
に対応していない。
このエラーは fd
が例えば通常ファイルやディレクトリを参照している場合にも起こり得る。
epoll_ctl() はカーネル 2.6
で追加された。
epoll_ctl() は Linux
独自である。
ライブラリによるサポートは
glibc バージョン 2.3.2
以降で提供されている。
epoll
インターフェースは、
poll(2)
に対応している全てのファイルディスクリプターに対応している。
Linux 2.6.9 より前では、
EPOLL_CTL_DEL
操作の際、引き数
event
に
(たとえ無視される場合であっても)
NULL
でないポインターを渡す必要があった。
カーネル 2.6.9
以降では、
EPOLL_CTL_DEL
を使う際に
event に NULL
を指定できるようになっている。
2.6.9
より前のカーネルへの移植性が必要なアプリケーションでは、
event に NULL
でないポインターを指定すべきである。
flags に
EPOLLWAKEUP
が指定されたが、呼び出し元が
CAP_BLOCK_SUSPEND
ケーパビリティを持っていない場合、
EPOLLWAKEUP フラグは
黙って無視される。
元の実装では
flags
引き数に対する正当性チェックが実行されていないため、
この残念な動作は必要である。
また、 呼び出し元が
CAP_BLOCK_SUSPEND
ケーパビリティを持っていなかった場合に呼び出しを失敗させるようにチェックを
EPOLLWAKEUP に追加すると、
少なくともひとつは動かなくなる既存のユーザー空間アプリケーションがあった。
そのアプリケーションはたまたま
(しかも意味もなく)
このビットを指定していた。
したがって、信頼性が求められるアプリケーションでは、
EPOLLWAKEUP
フラグを使おうする場合には
CAP_BLOCK_SUSPEND
ケーパビリティを持っているかも確認するようにすべきである。
epoll_create(2),
epoll_wait(2),
poll(2),
epoll(7)
この man ページは Linux
man-pages
プロジェクトのリリース
3.79 の一部
である。プロジェクトの説明とバグ報告に関する情報は
http://www.kernel.org/doc/man-pages/
に書かれている。