17 #ifdef USE_LINUX_EPOLL
19 # include <sys/epoll.h>
21 static void fdevent_linux_sysepoll_free(fdevents
*ev
) {
23 free(ev
->epoll_events
);
26 static int fdevent_linux_sysepoll_event_del(fdevents
*ev
, int fde_ndx
, int fd
) {
27 struct epoll_event ep
;
29 if (fde_ndx
< 0) return -1;
31 memset(&ep
, 0, sizeof(ep
));
36 if (0 != epoll_ctl(ev
->epoll_fd
, EPOLL_CTL_DEL
, fd
, &ep
)) {
37 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SSS",
38 "epoll_ctl failed: ", strerror(errno
), ", dying");
49 static int fdevent_linux_sysepoll_event_set(fdevents
*ev
, int fde_ndx
, int fd
, int events
) {
50 struct epoll_event ep
;
53 if (fde_ndx
== -1) add
= 1;
55 memset(&ep
, 0, sizeof(ep
));
59 if (events
& FDEVENT_IN
) ep
.events
|= EPOLLIN
;
60 if (events
& FDEVENT_OUT
) ep
.events
|= EPOLLOUT
;
64 * with EPOLLET we don't get a FDEVENT_HUP
65 * if the close is delay after everything has
70 ep
.events
|= EPOLLERR
| EPOLLHUP
/* | EPOLLET */;
75 if (0 != epoll_ctl(ev
->epoll_fd
, add
? EPOLL_CTL_ADD
: EPOLL_CTL_MOD
, fd
, &ep
)) {
76 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SSS",
77 "epoll_ctl failed: ", strerror(errno
), ", dying");
87 static int fdevent_linux_sysepoll_poll(fdevents
*ev
, int timeout_ms
) {
88 return epoll_wait(ev
->epoll_fd
, ev
->epoll_events
, ev
->maxfds
, timeout_ms
);
91 static int fdevent_linux_sysepoll_event_get_revent(fdevents
*ev
, size_t ndx
) {
94 e
= ev
->epoll_events
[ndx
].events
;
95 if (e
& EPOLLIN
) events
|= FDEVENT_IN
;
96 if (e
& EPOLLOUT
) events
|= FDEVENT_OUT
;
97 if (e
& EPOLLERR
) events
|= FDEVENT_ERR
;
98 if (e
& EPOLLHUP
) events
|= FDEVENT_HUP
;
99 if (e
& EPOLLPRI
) events
|= FDEVENT_PRI
;
104 static int fdevent_linux_sysepoll_event_get_fd(fdevents
*ev
, size_t ndx
) {
106 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SD, D",
107 "fdevent_linux_sysepoll_event_get_fd: ", (int) ndx
, ev
->epoll_events
[ndx
].data
.fd
);
110 return ev
->epoll_events
[ndx
].data
.fd
;
113 static int fdevent_linux_sysepoll_event_next_fdndx(fdevents
*ev
, int ndx
) {
118 i
= (ndx
< 0) ? 0 : ndx
+ 1;
123 int fdevent_linux_sysepoll_init(fdevents
*ev
) {
124 ev
->type
= FDEVENT_HANDLER_LINUX_SYSEPOLL
;
126 ev->x = fdevent_linux_sysepoll_##x;
134 SET(event_next_fdndx
);
136 SET(event_get_revent
);
138 if (-1 == (ev
->epoll_fd
= epoll_create(ev
->maxfds
))) {
139 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SSS",
140 "epoll_create failed (", strerror(errno
), "), try to set server.event-handler = \"poll\" or \"select\"");
145 fd_close_on_exec(ev
->epoll_fd
);
147 ev
->epoll_events
= malloc(ev
->maxfds
* sizeof(*ev
->epoll_events
));
148 force_assert(NULL
!= ev
->epoll_events
);
154 int fdevent_linux_sysepoll_init(fdevents
*ev
) {
157 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "S",
158 "linux-sysepoll not supported, try to set server.event-handler = \"poll\" or \"select\"");