浏览 4016 次
锁定老帖子 主题:简单封装一下epoll
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-05-06
event.h头文件 #include <sys/epoll.h> #define BV(x) (1 << x) #define FDEVENT_IN BV(0) #define FDEVENT_PRI BV(1) #define FDEVENT_OUT BV(2) #define FDEVENT_ERR BV(3) #define FDEVENT_HUP BV(4) #define FDEVENT_NVAL BV(5) typedef void (*fdevent_handler)(int fd,void *ctx, int revents); typedef struct _fdnode{ fdevent_handler handler; int fd; void *ctx; int status; }fdnode; typedef struct fdevents{ fdnode **fdarray; size_t maxfds; int epoll_fd; struct epoll_event *epoll_events; }fdevents; fdevents *fdevent_init(size_t maxfds); void fdevent_free(fdevents *ev); int fdevent_register(fdevents *ev,int fd,fdevent_handler handler,void *ctx); int fdevent_unregister(fdevents *ev,int fd); int fdevent_event_add(fdevents *ev,int fd,int events); int fdevent_event_del(fdevents *ev,int fd); int fdevent_poll(fdevents *ev, int timeout_ms); event.c实现 #include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<stdlib.h> #include<sys/socket.h> #include<errno.h> #include<fcntl.h> #include<netinet/in.h> #include<sys/resource.h> #include "event.h" //foward declaration static fdnode *fdnode_init(); static void fdnode_free(fdnode *fdn); fdevents *fdevent_init(size_t maxfds){ fdevents *ev; ev = calloc(1,sizeof(*ev)); ev->fdarray = calloc(maxfds , sizeof(*ev->fdarray)); ev->maxfds = maxfds; ev->epoll_fd=epoll_create(maxfds); if(-1==ev->epoll_fd){ fprintf(stderr,"epoll create failed,%s\n",strerror(errno)); return NULL; } ev->epoll_events=malloc(maxfds * sizeof(*ev->epoll_events)); return ev; } void fdevent_free(fdevents *ev){ size_t i; if(!ev) return ; close(ev->epoll_fd); free(ev->epoll_events); for(i=0;i<ev->maxfds;i++){ if(ev->fdarray[i]) free(ev->fdarray[i]); } free(ev->fdarray); free(ev); } int fdevent_register(fdevents *ev,int fd,fdevent_handler handler,void *ctx){ fdnode *fdn; fdn=fdnode_init(); fdn->handler=handler; fdn->fd=fd; fdn->ctx=ctx; ev->fdarray[fd]=fdn; return 0; } int fdevent_unregister(fdevents *ev,int fd){ if(!ev) return 0; fdnode *fdn=ev->fdarray[fd]; fdnode_free(fdn); ev->fdarray[fd]=NULL; return 0; } int fdevent_event_add(fdevents *ev,int fd,int events){ struct epoll_event ep; int add=0; fdnode *fdn=ev->fdarray[fd]; add = (fdn->status == -1 ? 1 : 0); memset(&ep,0,sizeof(ep)); ep.events = 0; if(events & FDEVENT_IN) ep.events |=EPOLLIN; if(events & FDEVENT_OUT) ep.events |=EPOLLOUT; ep.data.ptr=NULL; ep.data.fd=fd; if(0 != epoll_ctl(ev->epoll_fd,add ? EPOLL_CTL_ADD : EPOLL_CTL_MOD,fd,&ep)){ fprintf(stderr,"epoll_ctl failed %s\n",strerror(errno)); return -1; } if(add){ fdn->status=1; } return 0; } int fdevent_event_del(fdevents *ev,int fd){ struct epoll_event ep; fdnode *fdn=ev->fdarray[fd]; if(-1==fdn->status){ return 0; } memset(&ep,0,sizeof(ep)); ep.data.ptr=NULL; ep.data.fd=fd; if(0 != epoll_ctl(ev->epoll_fd,EPOLL_CTL_DEL,fd,&ep)){ fprintf(stderr,"epoll del failed %s\n",strerror(errno)); return -1; } fdn->status=-1; return 0; } int fdevent_poll(fdevents *ev, int timeout_ms){ int n,i; for(;;){ n=0; if((n=epoll_wait(ev->epoll_fd,ev->epoll_events,ev->maxfds,timeout_ms))>0){ for(i=0;i<n;i++){ fdevent_handler handler; void *context; int events = 0, e,fd; fdnode *fdn; e=ev->epoll_events[i].events; if (e & EPOLLIN) events |= FDEVENT_IN; if (e & EPOLLOUT) events |= FDEVENT_OUT; fd=ev->epoll_events[i].data.fd; fdn = ev->fdarray[fd]; context = fdn->ctx; fdn->handler(fd,context,events); } } } } static fdnode *fdnode_init(){ fdnode *fdn; fdn=calloc(1,sizeof(*fdn)); fdn->fd=-1; fdn->status=-1; return fdn; } static void fdnode_free(fdnode *fdn){ free(fdn); } 简单调用流程就是下面这几个接口 fdevents *fdevent_init(size_t maxfds); int fdevent_register(fdevents *ev,int fd,fdevent_handler handler,void *ctx); int fdevent_event_add(fdevents *ev,int fd,int events); int fdevent_poll(fdevents *ev, int timeout_ms); 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |