1 | /* |
1 | /* |
2 | * libev epoll fd activity backend |
2 | * libev epoll fd activity backend |
3 | * |
3 | * |
4 | * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de> |
4 | * Copyright (c) 2007,2008,2009,2010,2011,2016,2017,2019 Marc Alexander Lehmann <libev@schmorp.de> |
5 | * All rights reserved. |
5 | * All rights reserved. |
6 | * |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without modifica- |
7 | * Redistribution and use in source and binary forms, with or without modifica- |
8 | * tion, are permitted provided that the following conditions are met: |
8 | * tion, are permitted provided that the following conditions are met: |
9 | * |
9 | * |
… | |
… | |
122 | anfds [fd].emask = EV_EMASK_EPERM; |
122 | anfds [fd].emask = EV_EMASK_EPERM; |
123 | |
123 | |
124 | /* add fd to epoll_eperms, if not already inside */ |
124 | /* add fd to epoll_eperms, if not already inside */ |
125 | if (!(oldmask & EV_EMASK_EPERM)) |
125 | if (!(oldmask & EV_EMASK_EPERM)) |
126 | { |
126 | { |
127 | array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, EMPTY2); |
127 | array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, array_needsize_noinit); |
128 | epoll_eperms [epoll_epermcnt++] = fd; |
128 | epoll_eperms [epoll_epermcnt++] = fd; |
129 | } |
129 | } |
130 | |
130 | |
131 | return; |
131 | return; |
132 | } |
132 | } |
… | |
… | |
177 | * we assume that fd is always in range, as we never shrink the anfds array |
177 | * we assume that fd is always in range, as we never shrink the anfds array |
178 | */ |
178 | */ |
179 | if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32))) |
179 | if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32))) |
180 | { |
180 | { |
181 | /* recreate kernel state */ |
181 | /* recreate kernel state */ |
182 | postfork = 1; |
182 | postfork |= 2; |
183 | continue; |
183 | continue; |
184 | } |
184 | } |
185 | |
185 | |
186 | if (expect_false (got & ~want)) |
186 | if (expect_false (got & ~want)) |
187 | { |
187 | { |
… | |
… | |
201 | |
201 | |
202 | /* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */ |
202 | /* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */ |
203 | /* which is fortunately easy to do for us. */ |
203 | /* which is fortunately easy to do for us. */ |
204 | if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev)) |
204 | if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev)) |
205 | { |
205 | { |
206 | postfork = 1; /* an error occurred, recreate kernel state */ |
206 | postfork |= 2; /* an error occurred, recreate kernel state */ |
207 | continue; |
207 | continue; |
208 | } |
208 | } |
209 | } |
209 | } |
210 | |
210 | |
211 | fd_event (EV_A_ fd, got); |
211 | fd_event (EV_A_ fd, got); |
… | |
… | |
226 | unsigned char events = anfds [fd].events & (EV_READ | EV_WRITE); |
226 | unsigned char events = anfds [fd].events & (EV_READ | EV_WRITE); |
227 | |
227 | |
228 | if (anfds [fd].emask & EV_EMASK_EPERM && events) |
228 | if (anfds [fd].emask & EV_EMASK_EPERM && events) |
229 | fd_event (EV_A_ fd, events); |
229 | fd_event (EV_A_ fd, events); |
230 | else |
230 | else |
|
|
231 | { |
231 | epoll_eperms [i] = epoll_eperms [--epoll_epermcnt]; |
232 | epoll_eperms [i] = epoll_eperms [--epoll_epermcnt]; |
|
|
233 | anfds [fd].emask = 0; |
|
|
234 | } |
232 | } |
235 | } |
233 | } |
236 | } |
234 | |
237 | |
235 | int inline_size |
238 | inline_size |
|
|
239 | int |
236 | epoll_init (EV_P_ int flags) |
240 | epoll_init (EV_P_ int flags) |
237 | { |
241 | { |
238 | #ifdef EPOLL_CLOEXEC |
242 | #if defined EPOLL_CLOEXEC && !defined __ANDROID__ |
239 | backend_fd = epoll_create1 (EPOLL_CLOEXEC); |
243 | backend_fd = epoll_create1 (EPOLL_CLOEXEC); |
240 | |
244 | |
241 | if (backend_fd < 0 && (errno == EINVAL || errno == ENOSYS)) |
245 | if (backend_fd < 0 && (errno == EINVAL || errno == ENOSYS)) |
242 | #endif |
246 | #endif |
243 | backend_fd = epoll_create (256); |
247 | backend_fd = epoll_create (256); |
… | |
… | |
255 | epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax); |
259 | epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax); |
256 | |
260 | |
257 | return EVBACKEND_EPOLL; |
261 | return EVBACKEND_EPOLL; |
258 | } |
262 | } |
259 | |
263 | |
260 | void inline_size |
264 | inline_size |
|
|
265 | void |
261 | epoll_destroy (EV_P) |
266 | epoll_destroy (EV_P) |
262 | { |
267 | { |
263 | ev_free (epoll_events); |
268 | ev_free (epoll_events); |
264 | array_free (epoll_eperm, EMPTY); |
269 | array_free (epoll_eperm, EMPTY); |
265 | } |
270 | } |
266 | |
271 | |
267 | void inline_size |
272 | inline_size |
|
|
273 | void |
268 | epoll_fork (EV_P) |
274 | epoll_fork (EV_P) |
269 | { |
275 | { |
270 | close (backend_fd); |
276 | close (backend_fd); |
271 | |
277 | |
272 | while ((backend_fd = epoll_create (256)) < 0) |
278 | while ((backend_fd = epoll_create (256)) < 0) |