3 #include "fdevent_impl.h"
15 #ifdef FDEVENT_USE_LINUX_EPOLL
17 # include <sys/epoll.h>
19 static void fdevent_linux_sysepoll_free(fdevents
*ev
) {
21 free(ev
->epoll_events
);
24 static int fdevent_linux_sysepoll_event_del(fdevents
*ev
, int fde_ndx
, int fd
) {
25 struct epoll_event ep
;
27 if (fde_ndx
< 0) return -1;
29 memset(&ep
, 0, sizeof(ep
));
34 if (0 != epoll_ctl(ev
->epoll_fd
, EPOLL_CTL_DEL
, fd
, &ep
)) {
35 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SSS",
36 "epoll_ctl failed: ", strerror(errno
), ", dying");
47 static int fdevent_linux_sysepoll_event_set(fdevents
*ev
, int fde_ndx
, int fd
, int events
) {
48 struct epoll_event ep
;
51 if (fde_ndx
== -1) add
= 1;
53 memset(&ep
, 0, sizeof(ep
));
57 if (events
& FDEVENT_IN
) ep
.events
|= EPOLLIN
;
58 if (events
& FDEVENT_OUT
) ep
.events
|= EPOLLOUT
;
62 * with EPOLLET we don't get a FDEVENT_HUP
63 * if the close is delay after everything has
68 ep
.events
|= EPOLLERR
| EPOLLHUP
/* | EPOLLET */;
73 if (0 != epoll_ctl(ev
->epoll_fd
, add
? EPOLL_CTL_ADD
: EPOLL_CTL_MOD
, fd
, &ep
)) {
74 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SSS",
75 "epoll_ctl failed: ", strerror(errno
), ", dying");
85 static int fdevent_linux_sysepoll_poll(fdevents
*ev
, int timeout_ms
) {
86 return epoll_wait(ev
->epoll_fd
, ev
->epoll_events
, ev
->maxfds
, timeout_ms
);
89 static int fdevent_linux_sysepoll_event_get_revent(fdevents
*ev
, size_t ndx
) {
92 e
= ev
->epoll_events
[ndx
].events
;
93 if (e
& EPOLLIN
) events
|= FDEVENT_IN
;
94 if (e
& EPOLLOUT
) events
|= FDEVENT_OUT
;
95 if (e
& EPOLLERR
) events
|= FDEVENT_ERR
;
96 if (e
& EPOLLHUP
) events
|= FDEVENT_HUP
;
97 if (e
& EPOLLPRI
) events
|= FDEVENT_PRI
;
102 static int fdevent_linux_sysepoll_event_get_fd(fdevents
*ev
, size_t ndx
) {
104 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SD, D",
105 "fdevent_linux_sysepoll_event_get_fd: ", (int) ndx
, ev
->epoll_events
[ndx
].data
.fd
);
108 return ev
->epoll_events
[ndx
].data
.fd
;
111 static int fdevent_linux_sysepoll_event_next_fdndx(fdevents
*ev
, int ndx
) {
116 i
= (ndx
< 0) ? 0 : ndx
+ 1;
121 int fdevent_linux_sysepoll_init(fdevents
*ev
) {
122 ev
->type
= FDEVENT_HANDLER_LINUX_SYSEPOLL
;
124 ev->x = fdevent_linux_sysepoll_##x;
132 SET(event_next_fdndx
);
134 SET(event_get_revent
);
136 if (-1 == (ev
->epoll_fd
= epoll_create(ev
->maxfds
))) {
137 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "SSS",
138 "epoll_create failed (", strerror(errno
), "), try to set server.event-handler = \"poll\" or \"select\"");
143 fdevent_setfd_cloexec(ev
->epoll_fd
);
145 ev
->epoll_events
= malloc(ev
->maxfds
* sizeof(*ev
->epoll_events
));
146 force_assert(NULL
!= ev
->epoll_events
);
152 int fdevent_linux_sysepoll_init(fdevents
*ev
) {
155 log_error_write(ev
->srv
, __FILE__
, __LINE__
, "S",
156 "linux-sysepoll not supported, try to set server.event-handler = \"poll\" or \"select\"");