#include <sys/epoll.h>
/*
epoll 很像poll,用于监视多个文件描述符。
epoll既可以是边沿触发,也可以是水位线触发
在epoll实例上注册的文件描述符有时称作epoll集
边沿触发方式时,epoll_wait仍有可能在描述符中有数据可读时挂起,此时,对段可能期待一个回个发送数据的回应。边沿触发只在描述符发生改变时传送信号。所以边沿触发的描述符必须设置为非阻塞的。“with nonblocking file descriptions; and by waiting for an event only after read or write return EAGAIN”
在边沿触发中,信心块的接收产生了各种事件,通过设置EPOLLONESHOT标志来在接收到事件后禁止联合的描述符。指定了EPOLLONESHOT后,调用者必须使用epoll_ctl来重整描述符。
似乎翻译很不到位,原文如下:
Since even with edge-triggered epoll, multiple events can be generateed upon receipt of multiple chunks of data, the caller has the opton to specofy the EPOLLONESHOT flag,
to tell epoll to disable the associate file descriptor after the receipt of an event with epoll_wait. when the EPOLLONESHOT flag is specified, it is the caller;s responsibility to rearm the file descriptor using epoll_ctl with EPOLL_CTL_MOD
水位线触发方式就是一个更加快速的poll, 完全可以替代poll
*/
/*defined events */
enum EPOLL_EVENTS {
EPOLLIN = 0x001,
#define EPOLLIN EPOLLIN
EPOLLPRI = 0x002,
#define EPOLLPRI EPOLLPRI
EPOLLOUT = 0x004,
#define EPOLLOUT EPOLLOUT
EPOLLRDNORM = 0x040,
#define EPOLLRDNORM EPOLLRDBAND
EPOLLRDBAND = 0x08,
#define EPOLLRDBAND EPOLLRDBAND
EPOLLWRNORM = 0x100,
#define EPOLLWRNORM EPOLLWRNORM
EPOLLWRBAND = 0x200,
#define EPOLLWRBAND EPOLLWRBAND
EPOLLMSG = 0x400,
#define EPOLLMSG EPOLLMSG
EPOLLERR = 0x008,
#define EPOLLERR EPOLLERR
EPOLLHUP = 0x010,
#define EPOLLHUP EPOLLHUP
EPOLLRDHUP = 0x2000,
#define EPOLLRDHUP EPOLLRDHUP
EPOLLONESHOT = 1u << 30,
#define EPOLLONESHOT EPLLONESHOT
EPOLLET = 1u << 31
#define EPOLLET EPOLLET
};
/* valid opcodes ("op" parameter) to issue to epoll_ctl() */
#define EPOLL_CTL_ADD 1 /* add a file description to the interfcae */
#define EPOLL_CTL_DEL 2 /* remove a file description from the interface */
#define EPOLL_CTL_MOD 3 /* change file description epoll_event structure */
typedef union epoll_data {
void *ptr;
int fd;
uint32t u32;
uint64_t u64;
}epoll_data_t;
struct epoll_event {
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
}__EPOLL_PACKED;
functions
/**
* creates an epoll instance, return an fd for the new instance.
* the size param is a hint specifying the number of file
* descriptors to be associated with the new instance.
* the fd returned by epoll_create() shoule be closed with
* close()
*/
int epoll_create(int __size) __THROW;
/**
* same as epoll_create but with an flags parameter. the
* unused size parameter has been dropped
*/
int epoll_create1(int __flags) __THROW;
/**
* manipulate an epoll instance "epfd"
* the op parameter is one of the EPOLL_CTL_* constances
* defined above. the fd paramter is the target of the
* operation . the event parameter describes which events the
* caller is interersted in and any associated user data.
* return 0 in case of success, -1 in case of error
*/
int epoll_ctl(int __epfd, int __op, int __fd, struct epoll_event *__event) __THROW;
/**
* wait for events on an epoll instance epfd.
* the events param is a buffer that will contain triggered
* events. the maxevents is the maximum number of events to
* be returned (usually size of events). the timeout
* parameter specofies the maximum wait time in milliseconds
* ( -1 == infinite)
* return the number of triggered events returned in events
* buffer or -1 in case of error with the errno variable set
* to the specific error code
*
* this function is a cancellation point and therefore not
* marked with __THROW.
*
*
* the data of each rturned structure will contain the same
* data the user set with an epoll_ctl(EPOLL_CTL_ADD,
* EPOLL_CTL_MOD) while the events member will contain the
* returned event bit field.
*/
int epoll_wait(int __epfd, struct epoll_event *__events, int __maxevents, int __timeout);
/**
* same as epoll_wait, but the thread's signal mask is
* temporarily and atomically replaced with the one privided
* as prarmeter.
*
* this function is a cancellation point and therefore no tmarked with __THROW.
*
* epoll_pwait to epoll_wait just like select to pselect.
* epoll_pwait allows an application to safely wait until
* either a file descriptor becomes ready or until a
* signal is caught.
* just as below
* ready = epoll_wait(epfd, &events, maxevents, timeout, &sigmask);
* equivalent to atomical executing as following
* sigset_t origmask;
* sigprocmask(SIG_SETMASK, &sigmask, &origmask);
* ready = epoll_wait(epfd, &events, maxevents, timeout);
* sigprocmask(SIG_SETMASK, &origmask, NULL);
*/
int epoll_pwait(int __epfd, struct epoll_event *__events, int _maxevents, int __timeout, const __sigset_t *__ss);
/**
* Questions
* what's cancellation point ?
*/
/***** Examples *****/
#define MAX_EVENTS 10
struct epoll_event ev, events[MAX_EVENTS];
int listen_sock, conn_sock, nfds, epollfd;
/* ...... */
epollfd = epoll_create(10);
if (epollfd == -1 ){
perror("epoll_create");
exit(EXIT_FAILURE);
}
ev.event = EPOLLIN;
ev.data.fd = listen_sock;
if(epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev)) {
perror("epoll_ctl: listen_sock");
exit(EXIT_FAILURE);
}
for(;;) {
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
if(nfds == -1) {
perror("epoll_wait");
exit(EXIT_FAILURE);
}
for(n = 0; n < nfds; n ++) {
if (events[n].data.fd == listen_sock) {
conn_sock = accpet(listen_sock, (struct sockaddr *) &local, &addrlen);
if(conn_sock == -1 ) {
perror("accept");
exit(EXIT_FAILURE);
}
setnonblocking(conn_sock);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = conn_sock;
if(epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &ev) == -1) {
perror("epoll_ctl: conn_sock");
exit(EXIT_FAILURE);
}
}
else {
do_use_fd(events[n].data.fd);
}
}
}epoll笔记
最新推荐文章于 2025-10-14 10:01:47 发布

1183

被折叠的 条评论
为什么被折叠?



