Open Source Web Development Tutorials - Dev Shed
Linuxファイルとイベントポーリングインターフェース
(2009/03/10公開)
Epollの管理
epoll_ctl()システムコールを利用して、特定のepollコンテクストに対してファイル記述子の追加/削除を行うことができます。以下のとおりです。
#include <sys/epoll.h>
int epoll_ctl (int epfd,
int op,
int fd,
struct epoll_event *event);
struct epoll_event {
__u32 events; /* events */
union {
void *ptr;
int fd;
__u32 u32;
__u64 u64;
} data;
};
epoll_ctl()のコールが成功すると、ファイル記述子epfdと関連付いたepollインスタンスが制御されます。opパラメータはfdと関連付いたファイルに対する操作を特定し、eventパラメータは操作による動作をさらに記述します。
以下がopパラメータの有効値です。
EPOLL_CTL_ADD
eventに定義されているイベントごとに、ファイル記述子fdに関連付いているファイルのモニターを、epfdに関連付いているepollインスタンスに追加します。
EPOLL_CTL_DEL
ファイル記述子fdに関連付いているファイルのモニターを、epfdに関連付いているepollインスタンスから削除します。
EPOLL_CTL_MOD
Eventが指定する更新イベントで、fdの既存モニターを修正します。
epoll_event構造にあるeventsフィールドは、特定のファイル記述子上でモニターの対象とするイベントをリストアップします。複数のイベントをビット単位の論理和にできます。以下が有効値です。
EPOLLERR
ファイルにエラー状態が発生しました。このイベントは、たとえ特定されていない場合にも、常にモニターされます。
EPOLLET
ファイルのモニターに対するエッジトリガ方式動作を有効にします(後記の「エッジトリガイベント VS レベルトリガ・イベント」を参照してください)。デフォルト動作はレベルトリガです。
EPOLLHUP
ファイルでハングアップが発生しました。このイベントは、たとえ特定されていない場合にも、常にモニターされます。
EPOLLIN
ファイルはブロックされておらず、読み出しが可能です。
EPOLLONESHOT
イベントの生成および読み出し後、ファイルのモニターは自動的に停止します。監視を再度有効にするには、EPOLL_CTL_MODによって、新規のイベントマスクを指定する必要があります。
EPOLLOUT
ファイルはブロックされておらず、書き込みが可能です。
EPOLLPRI
読み出し可能な緊急の帯域外データが存在します。
event_poll構造内のdataフィールドは、ユーザーが私的に使用します。コンテンツは、要求イベントの受取時、ユーザーに戻されます。イベントを引き起こしたファイル記述子を簡単に調べられるように、通常は、event.data.fdをfdに設定します。
成功すると、epoll_ctl()はゼロを戻します。失敗すると-1が戻り、errnoが以下のいずれかの値を示します。
EBADF
Epfdが有効なepollインスタンスではありません、あるいは、fdが有効なファイル記述子ではありません。
EEXIST
OpがEPOLL_CTL_ADDでしたが、fdはすでにepfdに関連付いています。
EINVAL
Epfdがepollインスタンスではありません。あるいは、Epfdがfdと同じです。あるいは、opが無効です。
ENOENT
OpがEPOLL_CTL_MODまたはEPOLL_CTL_DELでしたが、fdはepfdと関連付いていません。
ENOMEM
メモリー不足のため、要求を処理できませんでした。
EPERM
Fdがepollをサポートしていません。
一例として、epollインスタンスepfdにfdと関連付いたファイルの新規の監視を追加する場合、コードは以下のようになります。
struct epoll_event event;
int ret;
event.data.fd = fd; /* return the fd to us later */
event.events = EPOLLIN | EPOLLOUT;
ret = epoll_ctl (epfd, EPOLL_CTL_ADD, fd, &event);
if (ret)
perror ("epoll_ctl");
epoll インスタンスepfdにあるfdと関連付いたファイルの既存イベントを修正する場合、コードは以下のようになります。
struct epoll_event event;
int ret;
event.data.fd = fd; /* return the fd to us later */
event.events = EPOLLIN;
ret = epoll_ctl (epfd, EPOLL_CTL_MOD, fd, &event);
if (ret)
perror ("epoll_ctl");
反対に、epoll インスタンスepfdからfdと関連付いたファイルの既存イベントを削除する場合、コードは以下のようになります。
struct epoll_event event;
int ret;
ret = epoll_ctl (epfd, EPOLL_CTL_DEL, fd, &event);
if (ret)
perror ("epoll_ctl");
OpがEPOLL_CTL_DELのときは、提供するイベントマスクがないため、eventパラメータがNULLとなる可能性がある点に留意してください。しかし、2.6.9より前のバージョンのカーネルは、誤って非NULLのeventパラメータを求めます。これら旧バージョンのカーネルに対しては、移植性のために、有効な非NULLポインタを渡しましょう。非NULLポインタはそのままの状態で残ります。カーネル2.6.9は、この問題を解消しています。
Copyright © 2008 Ziff Davis Enterprise, Inc.
Originally appearing in the U.S. Edition of Dev Shed. All Rights Reserved.








