17 fdevents
*fdevent_init(server
*srv
, size_t maxfds
, fdevent_handler_t type
) {
20 ev
= calloc(1, sizeof(*ev
));
21 force_assert(NULL
!= ev
);
23 ev
->fdarray
= calloc(maxfds
, sizeof(*ev
->fdarray
));
24 force_assert(NULL
!= ev
->fdarray
);
28 case FDEVENT_HANDLER_POLL
:
29 if (0 != fdevent_poll_init(ev
)) {
30 log_error_write(srv
, __FILE__
, __LINE__
, "S",
31 "event-handler poll failed");
35 case FDEVENT_HANDLER_SELECT
:
36 if (0 != fdevent_select_init(ev
)) {
37 log_error_write(srv
, __FILE__
, __LINE__
, "S",
38 "event-handler select failed");
42 case FDEVENT_HANDLER_LINUX_SYSEPOLL
:
43 if (0 != fdevent_linux_sysepoll_init(ev
)) {
44 log_error_write(srv
, __FILE__
, __LINE__
, "S",
45 "event-handler linux-sysepoll failed, try to set server.event-handler = \"poll\" or \"select\"");
49 case FDEVENT_HANDLER_SOLARIS_DEVPOLL
:
50 if (0 != fdevent_solaris_devpoll_init(ev
)) {
51 log_error_write(srv
, __FILE__
, __LINE__
, "S",
52 "event-handler solaris-devpoll failed, try to set server.event-handler = \"poll\" or \"select\"");
56 case FDEVENT_HANDLER_SOLARIS_PORT
:
57 if (0 != fdevent_solaris_port_init(ev
)) {
58 log_error_write(srv
, __FILE__
, __LINE__
, "S",
59 "event-handler solaris-eventports failed, try to set server.event-handler = \"poll\" or \"select\"");
63 case FDEVENT_HANDLER_FREEBSD_KQUEUE
:
64 if (0 != fdevent_freebsd_kqueue_init(ev
)) {
65 log_error_write(srv
, __FILE__
, __LINE__
, "S",
66 "event-handler freebsd-kqueue failed, try to set server.event-handler = \"poll\" or \"select\"");
70 case FDEVENT_HANDLER_LIBEV
:
71 if (0 != fdevent_libev_init(ev
)) {
72 log_error_write(srv
, __FILE__
, __LINE__
, "S",
73 "event-handler libev failed, try to set server.event-handler = \"poll\" or \"select\"");
77 case FDEVENT_HANDLER_UNSET
:
85 log_error_write(srv
, __FILE__
, __LINE__
, "S",
86 "event-handler is unknown, try to set server.event-handler = \"poll\" or \"select\"");
90 void fdevent_free(fdevents
*ev
) {
94 if (ev
->free
) ev
->free(ev
);
96 for (i
= 0; i
< ev
->maxfds
; i
++) {
97 if (ev
->fdarray
[i
]) free(ev
->fdarray
[i
]);
104 int fdevent_reset(fdevents
*ev
) {
105 if (ev
->reset
) return ev
->reset(ev
);
110 static fdnode
*fdnode_init(void) {
113 fdn
= calloc(1, sizeof(*fdn
));
114 force_assert(NULL
!= fdn
);
119 static void fdnode_free(fdnode
*fdn
) {
123 int fdevent_register(fdevents
*ev
, int fd
, fdevent_handler handler
, void *ctx
) {
127 fdn
->handler
= handler
;
130 fdn
->handler_ctx
= NULL
;
133 ev
->fdarray
[fd
] = fdn
;
138 int fdevent_unregister(fdevents
*ev
, int fd
) {
142 fdn
= ev
->fdarray
[fd
];
144 force_assert(fdn
->events
== 0);
148 ev
->fdarray
[fd
] = NULL
;
153 void fdevent_event_del(fdevents
*ev
, int *fde_ndx
, int fd
) {
154 if (-1 == fd
) return;
155 if (NULL
== ev
->fdarray
[fd
]) return;
157 if (ev
->event_del
) *fde_ndx
= ev
->event_del(ev
, *fde_ndx
, fd
);
158 ev
->fdarray
[fd
]->events
= 0;
161 void fdevent_event_set(fdevents
*ev
, int *fde_ndx
, int fd
, int events
) {
162 if (-1 == fd
) return;
164 /*(Note: skips registering with kernel if initial events is 0,
165 * so caller should pass non-zero events for initial registration.
166 * If never registered due to never being called with non-zero events,
167 * then FDEVENT_HUP or FDEVENT_ERR will never be returned.) */
168 if (ev
->fdarray
[fd
]->events
== events
) return;/*(no change; nothing to do)*/
170 if (ev
->event_set
) *fde_ndx
= ev
->event_set(ev
, *fde_ndx
, fd
, events
);
171 ev
->fdarray
[fd
]->events
= events
;
174 int fdevent_poll(fdevents
*ev
, int timeout_ms
) {
175 if (ev
->poll
== NULL
) SEGFAULT();
176 return ev
->poll(ev
, timeout_ms
);
179 int fdevent_event_get_revent(fdevents
*ev
, size_t ndx
) {
180 if (ev
->event_get_revent
== NULL
) SEGFAULT();
182 return ev
->event_get_revent(ev
, ndx
);
185 int fdevent_event_get_fd(fdevents
*ev
, size_t ndx
) {
186 if (ev
->event_get_fd
== NULL
) SEGFAULT();
188 return ev
->event_get_fd(ev
, ndx
);
191 fdevent_handler
fdevent_get_handler(fdevents
*ev
, int fd
) {
192 if (ev
->fdarray
[fd
] == NULL
) SEGFAULT();
193 if (ev
->fdarray
[fd
]->fd
!= fd
) SEGFAULT();
195 return ev
->fdarray
[fd
]->handler
;
198 void * fdevent_get_context(fdevents
*ev
, int fd
) {
199 if (ev
->fdarray
[fd
] == NULL
) SEGFAULT();
200 if (ev
->fdarray
[fd
]->fd
!= fd
) SEGFAULT();
202 return ev
->fdarray
[fd
]->ctx
;
205 void fd_close_on_exec(int fd
) {
208 force_assert(-1 != fcntl(fd
, F_SETFD
, FD_CLOEXEC
));
214 int fdevent_fcntl_set(fdevents
*ev
, int fd
) {
215 fd_close_on_exec(fd
);
216 if ((ev
) && (ev
->fcntl_set
)) return ev
->fcntl_set(ev
, fd
);
218 return fcntl(fd
, F_SETFL
, O_NONBLOCK
| O_RDWR
);
225 int fdevent_event_next_fdndx(fdevents
*ev
, int ndx
) {
226 if (ev
->event_next_fdndx
) return ev
->event_next_fdndx(ev
, ndx
);