]>
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
);
56 deregisterhook(HOOK_CORE_STATSREQUEST
, &eventstats
);
62 * Given the number of a new file descriptor, makes sure that the array
63 * will be big enough to deal with it.
66 void checkindex(unsigned index
) {
73 while (maxfds
<=index
) {
77 eventhandlers
=(reghandler
*)realloc((void *)eventhandlers
,maxfds
*sizeof(reghandler
));
78 memset(&eventhandlers
[oldmax
],0,(maxfds
-oldmax
)*sizeof(reghandler
));
83 * Converts a poll-style event variable to an epoll one.
85 unsigned int polltoepoll(short events
) {
86 unsigned int epe
=EPOLLERR
|EPOLLHUP
; /* Default event mask */
88 if (events
& POLLIN
) epe
|= EPOLLIN
;
89 if (events
& POLLOUT
) epe
|= EPOLLOUT
;
90 if (events
& POLLPRI
) epe
|= EPOLLPRI
;
95 short epolltopoll(unsigned int events
) {
98 if (events
& EPOLLIN
) e
|= POLLIN
;
99 if (events
& EPOLLOUT
) e
|= POLLOUT
;
100 if (events
& EPOLLERR
) e
|= POLLERR
;
101 if (events
& EPOLLPRI
) e
|= POLLPRI
;
102 if (events
& EPOLLHUP
) e
|= POLLHUP
;
109 * Add an fd to the epoll array.
112 int registerhandler(int fd
, short events
, FDHandler handler
) {
113 struct epoll_event epe
;
117 /* Check that it's not already registered */
118 if (eventhandlers
[fd
].handler
!=NULL
) {
119 Error("events",ERR_WARNING
,"Attempting to register already-registered fd %d.",fd
);
123 eventhandlers
[fd
].handler
=handler
;
125 memset(&epe
, 0, sizeof(epe
));
127 epe
.events
=polltoepoll(events
);
129 if (epoll_ctl(epollfd
, EPOLL_CTL_ADD
, fd
, &epe
)) {
130 Error("events",ERR_WARNING
,"Error %d adding fd %d to epoll (events=%d)",errno
,fd
,epe
.events
);
140 * deregisterhandler():
141 * Remove an fd from the poll() array.
143 * The poll() version can't save any time if doclose is set, so
144 * we just do the same work and then close the socket if it's set.
150 int deregisterhandler(int fd
, int doclose
) {
151 struct epoll_event epe
;
155 /* Check that the handler exists */
156 if (eventhandlers
[fd
].handler
==NULL
) {
157 Error("events",ERR_WARNING
,"Attempt to deregister unregistered fd: %d",fd
);
161 eventhandlers
[fd
].handler
=NULL
;
163 if (epoll_ctl(epollfd
, EPOLL_CTL_DEL
, fd
, &epe
)) {
164 Error("events",ERR_WARNING
,"Error deleting FD %d from epoll: %d",fd
,errno
);
179 * Call epoll_wait() and handle and call appropiate handlers
180 * for any sockets that come up.
183 int handleevents(int timeout
) {
185 struct epoll_event epes
[100];
187 res
=epoll_wait(epollfd
, epes
, 100, timeout
);
190 if (errno
== EINTR
) {
194 Error("events",ERR_WARNING
,"Error in epoll_wait(): %d",errno
);
198 for (i
=0;i
<res
;i
++) {
199 (eventhandlers
[epes
[i
].data
.fd
].handler
)(epes
[i
].data
.fd
, epolltopoll(epes
[i
].events
));
206 void eventstats(int hooknum
, void *arg
) {
208 long level
=(long) arg
;
211 sprintf(buf
,"Events :%7d fds registered, %7d fds deregistered",eventadds
,eventdels
);
212 triggerhook(HOOK_CORE_STATSREPLY
,(void *)buf
);
213 sprintf(buf
,"Events :%7d events triggered, %6d fds active",eventexes
,regfds
);
214 triggerhook(HOOK_CORE_STATSREPLY
,(void *)buf
);