--- libev/ev_epoll.c 2011/06/27 21:51:52 1.64 +++ libev/ev_epoll.c 2019/06/26 00:01:46 1.76 @@ -1,7 +1,7 @@ /* * libev epoll fd activity backend * - * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann + * Copyright (c) 2007,2008,2009,2010,2011,2016,2017,2019 Marc Alexander Lehmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- @@ -124,12 +124,14 @@ /* add fd to epoll_eperms, if not already inside */ if (!(oldmask & EV_EMASK_EPERM)) { - array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, EMPTY2); + array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, array_needsize_noinit); epoll_eperms [epoll_epermcnt++] = fd; } return; } + else + assert (("libev: I/O watcher with invalid fd found in epoll_ctl", errno != EBADF && errno != ELOOP && errno != EINVAL)); fd_kill (EV_A_ fd); @@ -179,7 +181,7 @@ if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32))) { /* recreate kernel state */ - postfork = 1; + postfork |= 2; continue; } @@ -203,7 +205,7 @@ /* which is fortunately easy to do for us. */ if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev)) { - postfork = 1; /* an error occurred, recreate kernel state */ + postfork |= 2; /* an error occurred, recreate kernel state */ continue; } } @@ -228,26 +230,41 @@ if (anfds [fd].emask & EV_EMASK_EPERM && events) fd_event (EV_A_ fd, events); else - epoll_eperms [i] = epoll_eperms [--epoll_epermcnt]; + { + epoll_eperms [i] = epoll_eperms [--epoll_epermcnt]; + anfds [fd].emask = 0; + } } } -int inline_size -epoll_init (EV_P_ int flags) +static int +epoll_epoll_create (void) { -#ifdef EPOLL_CLOEXEC - backend_fd = epoll_create1 (EPOLL_CLOEXEC); + int fd; + +#if defined EPOLL_CLOEXEC && !defined __ANDROID__ + fd = epoll_create1 (EPOLL_CLOEXEC); - if (backend_fd <= 0) + if (fd < 0 && (errno == EINVAL || errno == ENOSYS)) #endif - backend_fd = epoll_create (256); + { + fd = epoll_create (256); - if (backend_fd < 0) - return 0; + if (fd >= 0) + fcntl (fd, F_SETFD, FD_CLOEXEC); + } - fcntl (backend_fd, F_SETFD, FD_CLOEXEC); + return fd; +} + +inline_size +int +epoll_init (EV_P_ int flags) +{ + if ((backend_fd = epoll_epoll_create ()) < 0) + return 0; - backend_mintime = 1./1024.; /* epoll does sometimes return early, this is just to avoid the worst */ + backend_mintime = 1e-3; /* epoll does sometimes return early, this is just to avoid the worst */ backend_modify = epoll_modify; backend_poll = epoll_poll; @@ -257,23 +274,23 @@ return EVBACKEND_EPOLL; } -void inline_size +inline_size +void epoll_destroy (EV_P) { ev_free (epoll_events); array_free (epoll_eperm, EMPTY); } -void inline_size +inline_size +void epoll_fork (EV_P) { close (backend_fd); - while ((backend_fd = epoll_create (256)) < 0) + while ((backend_fd = epoll_epoll_create ()) < 0) ev_syserr ("(libev) epoll_create"); - fcntl (backend_fd, F_SETFD, FD_CLOEXEC); - fd_rearm_all (EV_A); }