]>
jfr.im git - irc/quakenet/newserv.git/blob - core/events-epoll.c
2 * events.c: the event handling core, epoll() version
13 #include "../lib/array.h"
18 /* We need to track the handler for each fd - epoll() can
19 * return an fd or a pointer but not both :(. We'll keep the
20 * fd in the epoll_data structure for simplicity. */
26 reghandler
*eventhandlers
;
34 /* How many fds are currently registered */
38 void eventstats(int hooknum
, void *arg
);
42 eventadds
=eventdels
=eventexes
=0;
44 eventhandlers
=(reghandler
*)malloc(maxfds
*sizeof(reghandler
));
45 memset(eventhandlers
,0,maxfds
*sizeof(reghandler
));
48 if ((epollfd
=epoll_create(STARTFDS
))<0) {
49 Error("events",ERR_STOP
,"Unable to initialise epoll.");
52 registerhook(HOOK_CORE_STATSREQUEST
, &eventstats
);
57 * Given the number of a new file descriptor, makes sure that the array
58 * will be big enough to deal with it.
61 void checkindex(unsigned index
) {
68 while (maxfds
<=index
) {
72 eventhandlers
=(reghandler
*)realloc((void *)eventhandlers
,maxfds
*sizeof(reghandler
));
73 memset(&eventhandlers
[oldmax
],0,(maxfds
-oldmax
)*sizeof(reghandler
));
78 * Converts a poll-style event variable to an epoll one.
80 unsigned int polltoepoll(short events
) {
81 unsigned int epe
=EPOLLERR
|EPOLLHUP
; /* Default event mask */
83 if (events
& POLLIN
) epe
|= EPOLLIN
;
84 if (events
& POLLOUT
) epe
|= EPOLLOUT
;
85 if (events
& POLLPRI
) epe
|= EPOLLPRI
;
90 short epolltopoll(unsigned int events
) {
93 if (events
& EPOLLIN
) e
|= POLLIN
;
94 if (events
& EPOLLOUT
) e
|= POLLOUT
;
95 if (events
& EPOLLERR
) e
|= POLLERR
;
96 if (events
& EPOLLPRI
) e
|= POLLPRI
;
97 if (events
& EPOLLHUP
) e
|= POLLHUP
;
104 * Add an fd to the epoll array.
107 int registerhandler(int fd
, short events
, FDHandler handler
) {
108 struct epoll_event epe
;
112 /* Check that it's not already registered */
113 if (eventhandlers
[fd
].handler
!=NULL
) {
114 Error("events",ERR_WARNING
,"Attempting to register already-registered fd %d.",fd
);
118 eventhandlers
[fd
].handler
=handler
;
121 epe
.events
=polltoepoll(events
);
123 if (epoll_ctl(epollfd
, EPOLL_CTL_ADD
, fd
, &epe
)) {
124 Error("events",ERR_WARNING
,"Error %d adding fd %d to epoll (events=%d)",errno
,fd
,epe
.events
);
134 * deregisterhandler():
135 * Remove an fd from the poll() array.
137 * The poll() version can't save any time if doclose is set, so
138 * we just do the same work and then close the socket if it's set.
144 int deregisterhandler(int fd
, int doclose
) {
145 struct epoll_event epe
;
149 /* Check that the handler exists */
150 if (eventhandlers
[fd
].handler
==NULL
) {
151 Error("events",ERR_WARNING
,"Attempt to deregister unregistered fd: %d",fd
);
155 eventhandlers
[fd
].handler
=NULL
;
157 if (epoll_ctl(epollfd
, EPOLL_CTL_DEL
, fd
, &epe
)) {
158 Error("events",ERR_WARNING
,"Error deleting FD %d from epoll: %d",fd
,errno
);
173 * Call epoll_wait() and handle and call appropiate handlers
174 * for any sockets that come up.
177 int handleevents(int timeout
) {
179 struct epoll_event epes
[100];
181 res
=epoll_wait(epollfd
, epes
, 100, timeout
);
184 Error("events",ERR_WARNING
,"Error in epoll_wait(): %d",errno
);
188 for (i
=0;i
<res
;i
++) {
189 (eventhandlers
[epes
[i
].data
.fd
].handler
)(epes
[i
].data
.fd
, epolltopoll(epes
[i
].events
));
196 void eventstats(int hooknum
, void *arg
) {
198 long level
=(long) arg
;
201 sprintf(buf
,"Events :%7d fds registered, %7d fds deregistered",eventadds
,eventdels
);
202 triggerhook(HOOK_CORE_STATSREPLY
,(void *)buf
);
203 sprintf(buf
,"Events :%7d events triggered, %6d fds active",eventexes
,regfds
);
204 triggerhook(HOOK_CORE_STATSREPLY
,(void *)buf
);