diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4 index 89c53a0c4d28..d21d1e6370cb 100644 --- a/sapi/fpm/config.m4 +++ b/sapi/fpm/config.m4 @@ -464,11 +464,6 @@ if test "$PHP_FPM" != "no"; then fpm/fpm_unix.c \ fpm/fpm_worker_pool.c \ fpm/zlog.c \ - fpm/events/select.c \ - fpm/events/poll.c \ - fpm/events/epoll.c \ - fpm/events/kqueue.c \ - fpm/events/port.c \ " PHP_SELECT_SAPI([fpm], diff --git a/sapi/fpm/fpm/events/epoll.c b/sapi/fpm/fpm/events/epoll.c deleted file mode 100644 index 2de3b463ae59..000000000000 --- a/sapi/fpm/fpm/events/epoll.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright © The PHP Group and Contributors. | - +----------------------------------------------------------------------+ - | This source file is subject to the Modified BSD License that is | - | bundled with this package in the file LICENSE, and is available | - | through the World Wide Web at . | - | | - | SPDX-License-Identifier: BSD-3-Clause | - +----------------------------------------------------------------------+ - | Authors: Jerome Loyet | - +----------------------------------------------------------------------+ -*/ - -#include "../fpm_config.h" -#include "../fpm_events.h" -#include "../fpm.h" -#include "../zlog.h" - -#ifdef HAVE_EPOLL - -#include -#include - -static int fpm_event_epoll_init(int max); -static int fpm_event_epoll_clean(void); -static int fpm_event_epoll_wait(struct fpm_event_queue_s *queue, unsigned long int timeout); -static int fpm_event_epoll_add(struct fpm_event_s *ev); -static int fpm_event_epoll_remove(struct fpm_event_s *ev); - -static struct fpm_event_module_s epoll_module = { - .name = "epoll", - .support_edge_trigger = 1, - .init = fpm_event_epoll_init, - .clean = fpm_event_epoll_clean, - .wait = fpm_event_epoll_wait, - .add = fpm_event_epoll_add, - .remove = fpm_event_epoll_remove, -}; - -static struct epoll_event *epollfds = NULL; -static int nepollfds = 0; -static int epollfd = -1; - -#endif /* HAVE_EPOLL */ - -struct fpm_event_module_s *fpm_event_epoll_module(void) -{ -#ifdef HAVE_EPOLL - return &epoll_module; -#else - return NULL; -#endif /* HAVE_EPOLL */ -} - -#ifdef HAVE_EPOLL - -/* - * Init the module - */ -static int fpm_event_epoll_init(int max) /* {{{ */ -{ - if (max < 1) { - return 0; - } - - /* init epoll */ - epollfd = epoll_create(max + 1); - if (epollfd < 0) { - zlog(ZLOG_ERROR, "epoll: unable to initialize"); - return -1; - } - - /* allocate fds */ - epollfds = malloc(sizeof(struct epoll_event) * max); - if (!epollfds) { - zlog(ZLOG_ERROR, "epoll: unable to allocate %d events", max); - return -1; - } - memset(epollfds, 0, sizeof(struct epoll_event) * max); - - /* save max */ - nepollfds = max; - - return 0; -} -/* }}} */ - -/* - * Clean the module - */ -static int fpm_event_epoll_clean(void) -{ - /* free epollfds */ - if (epollfds) { - free(epollfds); - epollfds = NULL; - } - if (epollfd != -1) { - close(epollfd); - epollfd = -1; - } - - nepollfds = 0; - - return 0; -} - -/* - * wait for events or timeout - */ -static int fpm_event_epoll_wait(struct fpm_event_queue_s *queue, unsigned long int timeout) /* {{{ */ -{ - int ret, i; - - /* ensure we have a clean epoolfds before calling epoll_wait() */ - memset(epollfds, 0, sizeof(struct epoll_event) * nepollfds); - - /* wait for incoming event or timeout */ - ret = epoll_wait(epollfd, epollfds, nepollfds, timeout); - if (ret == -1) { - - /* trigger error unless signal interrupt */ - if (errno != EINTR) { - zlog(ZLOG_WARNING, "epoll_wait() returns %d", errno); - return -1; - } - } - - /* events have been triggered, let's fire them */ - for (i = 0; i < ret; i++) { - - /* do we have a valid ev ptr ? */ - if (!epollfds[i].data.ptr) { - continue; - } - - /* fire the event */ - fpm_event_fire((struct fpm_event_s *)epollfds[i].data.ptr); - - /* sanity check */ - if (fpm_globals.parent_pid != getpid()) { - return -2; - } - } - - return ret; -} -/* }}} */ - -/* - * Add a FD to the fd set - */ -static int fpm_event_epoll_add(struct fpm_event_s *ev) /* {{{ */ -{ - struct epoll_event e; - - /* fill epoll struct */ -#if SIZEOF_SIZE_T == 4 - /* Completely initialize event data to prevent valgrind reports */ - e.data.u64 = 0; -#endif - e.events = EPOLLIN; - e.data.fd = ev->fd; - e.data.ptr = (void *)ev; - - if (ev->flags & FPM_EV_EDGE) { - e.events = e.events | EPOLLET; - } - - /* add the event to epoll internal queue */ - if (epoll_ctl(epollfd, EPOLL_CTL_ADD, ev->fd, &e) == -1) { - zlog(ZLOG_ERROR, "epoll: unable to add fd %d", ev->fd); - return -1; - } - - /* mark the event as registered */ - ev->index = ev->fd; - return 0; -} -/* }}} */ - -/* - * Remove a FD from the fd set - */ -static int fpm_event_epoll_remove(struct fpm_event_s *ev) /* {{{ */ -{ - struct epoll_event e; - - /* fill epoll struct the same way we did in fpm_event_epoll_add() */ - e.events = EPOLLIN; - e.data.fd = ev->fd; - e.data.ptr = (void *)ev; - - if (ev->flags & FPM_EV_EDGE) { - e.events = e.events | EPOLLET; - } - - /* remove the event from epoll internal queue */ - if (epoll_ctl(epollfd, EPOLL_CTL_DEL, ev->fd, &e) == -1) { - zlog(ZLOG_ERROR, "epoll: unable to remove fd %d", ev->fd); - return -1; - } - - /* mark the event as not registered */ - ev->index = -1; - return 0; -} -/* }}} */ - -#endif /* HAVE_EPOLL */ diff --git a/sapi/fpm/fpm/events/epoll.h b/sapi/fpm/fpm/events/epoll.h deleted file mode 100644 index 8b3d1867c0b1..000000000000 --- a/sapi/fpm/fpm/events/epoll.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright © The PHP Group and Contributors. | - +----------------------------------------------------------------------+ - | This source file is subject to the Modified BSD License that is | - | bundled with this package in the file LICENSE, and is available | - | through the World Wide Web at . | - | | - | SPDX-License-Identifier: BSD-3-Clause | - +----------------------------------------------------------------------+ - | Authors: Jerome Loyet | - +----------------------------------------------------------------------+ -*/ - -#ifndef FPM_EVENTS_EPOLL_H -#define FPM_EVENTS_EPOLL_H - -#include "../fpm_config.h" -#include "../fpm_events.h" - -struct fpm_event_module_s *fpm_event_epoll_module(void); - -#endif /* FPM_EVENTS_EPOLL_H */ diff --git a/sapi/fpm/fpm/events/kqueue.c b/sapi/fpm/fpm/events/kqueue.c deleted file mode 100644 index 22b9d1a8d3ab..000000000000 --- a/sapi/fpm/fpm/events/kqueue.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright © The PHP Group and Contributors. | - +----------------------------------------------------------------------+ - | This source file is subject to the Modified BSD License that is | - | bundled with this package in the file LICENSE, and is available | - | through the World Wide Web at . | - | | - | SPDX-License-Identifier: BSD-3-Clause | - +----------------------------------------------------------------------+ - | Authors: Jerome Loyet | - +----------------------------------------------------------------------+ -*/ - -#include "../fpm_config.h" -#include "../fpm_events.h" -#include "../fpm.h" -#include "../zlog.h" - -#ifdef HAVE_KQUEUE - -#include -#include -#include - -#include - -static int fpm_event_kqueue_init(int max); -static int fpm_event_kqueue_clean(void); -static int fpm_event_kqueue_wait(struct fpm_event_queue_s *queue, unsigned long int timeout); -static int fpm_event_kqueue_add(struct fpm_event_s *ev); -static int fpm_event_kqueue_remove(struct fpm_event_s *ev); - -static struct fpm_event_module_s kqueue_module = { - .name = "kqueue", - .support_edge_trigger = 1, - .init = fpm_event_kqueue_init, - .clean = fpm_event_kqueue_clean, - .wait = fpm_event_kqueue_wait, - .add = fpm_event_kqueue_add, - .remove = fpm_event_kqueue_remove, -}; - -static struct kevent *kevents = NULL; -static int nkevents = 0; -static int kfd = 0; - -#endif /* HAVE_KQUEUE */ - -/* - * Return the module configuration - */ -struct fpm_event_module_s *fpm_event_kqueue_module(void) /* {{{ */ -{ -#ifdef HAVE_KQUEUE - return &kqueue_module; -#else - return NULL; -#endif /* HAVE_KQUEUE */ -} -/* }}} */ - -#ifdef HAVE_KQUEUE - -/* - * init kqueue and stuff - */ -static int fpm_event_kqueue_init(int max) /* {{{ */ -{ - if (max < 1) { - return 0; - } - - kfd = kqueue(); - if (kfd < 0) { - zlog(ZLOG_ERROR, "kqueue: unable to initialize"); - return -1; - } - - kevents = calloc(max, sizeof(struct kevent)); - if (!kevents) { - zlog(ZLOG_ERROR, "kevent: unable to allocate %d events", max); - return -1; - } - - nkevents = max; - - return 0; -} -/* }}} */ - -/* - * release kqueue stuff - */ -static int fpm_event_kqueue_clean(void) /* {{{ */ -{ - if (kevents) { - free(kevents); - kevents = NULL; - } - - nkevents = 0; - - return 0; -} -/* }}} */ - -/* - * wait for events or timeout - */ -static int fpm_event_kqueue_wait(struct fpm_event_queue_s *queue, unsigned long int timeout) /* {{{ */ -{ - struct timespec t; - int ret, i; - - /* ensure we have a clean kevents before calling kevent() */ - memset(kevents, 0, sizeof(struct kevent) * nkevents); - - /* convert ms to timespec struct */ - t.tv_sec = timeout / 1000; - t.tv_nsec = (timeout % 1000) * 1000 * 1000; - - /* wait for incoming event or timeout */ - ret = kevent(kfd, NULL, 0, kevents, nkevents, &t); - if (ret == -1) { - - /* trigger error unless signal interrupt */ - if (errno != EINTR) { - zlog(ZLOG_WARNING, "kevent() returns %d", errno); - return -1; - } - } - - /* fire triggered events */ - for (i = 0; i < ret; i++) { - if (kevents[i].udata) { - struct fpm_event_s *ev = (struct fpm_event_s *)kevents[i].udata; - fpm_event_fire(ev); - /* sanity check */ - if (fpm_globals.parent_pid != getpid()) { - return -2; - } - } - } - - return ret; -} -/* }}} */ - -/* - * Add a FD to kevent queue - */ -static int fpm_event_kqueue_add(struct fpm_event_s *ev) /* {{{ */ -{ - struct kevent k; - int flags = EV_ADD; - - if (ev->flags & FPM_EV_EDGE) { - flags = flags | EV_CLEAR; - } - - EV_SET(&k, ev->fd, EVFILT_READ, flags, 0, 0, (void *)ev); - - if (kevent(kfd, &k, 1, NULL, 0, NULL) < 0) { - zlog(ZLOG_ERROR, "kevent: unable to add event"); - return -1; - } - - /* mark the event as registered */ - ev->index = ev->fd; - return 0; -} -/* }}} */ - -/* - * Remove a FD from the kevent queue - */ -static int fpm_event_kqueue_remove(struct fpm_event_s *ev) /* {{{ */ -{ - struct kevent k; - int flags = EV_DELETE; - - if (ev->flags & FPM_EV_EDGE) { - flags = flags | EV_CLEAR; - } - - EV_SET(&k, ev->fd, EVFILT_READ, flags, 0, 0, (void *)ev); - - if (kevent(kfd, &k, 1, NULL, 0, NULL) < 0) { - zlog(ZLOG_ERROR, "kevent: unable to delete event"); - return -1; - } - - /* mark the event as not registered */ - ev->index = -1; - return 0; -} -/* }}} */ - -#endif /* HAVE_KQUEUE */ diff --git a/sapi/fpm/fpm/events/kqueue.h b/sapi/fpm/fpm/events/kqueue.h deleted file mode 100644 index 4690b065dfce..000000000000 --- a/sapi/fpm/fpm/events/kqueue.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright © The PHP Group and Contributors. | - +----------------------------------------------------------------------+ - | This source file is subject to the Modified BSD License that is | - | bundled with this package in the file LICENSE, and is available | - | through the World Wide Web at . | - | | - | SPDX-License-Identifier: BSD-3-Clause | - +----------------------------------------------------------------------+ - | Authors: Jerome Loyet | - +----------------------------------------------------------------------+ -*/ - -#ifndef FPM_EVENTS_KQUEUE_H -#define FPM_EVENTS_KQUEUE_H - -#include "../fpm_config.h" -#include "../fpm_events.h" - -struct fpm_event_module_s *fpm_event_kqueue_module(void); - -#endif /* FPM_EVENTS_KQUEUE_H */ diff --git a/sapi/fpm/fpm/events/poll.c b/sapi/fpm/fpm/events/poll.c deleted file mode 100644 index 10085e83faa8..000000000000 --- a/sapi/fpm/fpm/events/poll.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright © The PHP Group and Contributors. | - +----------------------------------------------------------------------+ - | This source file is subject to the Modified BSD License that is | - | bundled with this package in the file LICENSE, and is available | - | through the World Wide Web at . | - | | - | SPDX-License-Identifier: BSD-3-Clause | - +----------------------------------------------------------------------+ - | Authors: Jerome Loyet | - +----------------------------------------------------------------------+ -*/ - -#include "../fpm_config.h" -#include "../fpm_events.h" -#include "../fpm.h" -#include "../zlog.h" - -#ifdef HAVE_POLL - -#include -#include -#include - -static int fpm_event_poll_init(int max); -static int fpm_event_poll_clean(void); -static int fpm_event_poll_wait(struct fpm_event_queue_s *queue, unsigned long int timeout); -static int fpm_event_poll_add(struct fpm_event_s *ev); -static int fpm_event_poll_remove(struct fpm_event_s *ev); - -static struct fpm_event_module_s poll_module = { - .name = "poll", - .support_edge_trigger = 0, - .init = fpm_event_poll_init, - .clean = fpm_event_poll_clean, - .wait = fpm_event_poll_wait, - .add = fpm_event_poll_add, - .remove = fpm_event_poll_remove, -}; - -static struct pollfd *pollfds = NULL; -static struct pollfd *active_pollfds = NULL; -static int npollfds = 0; -static int next_free_slot = 0; -#endif /* HAVE_POLL */ - -/* - * return the module configuration - */ -struct fpm_event_module_s *fpm_event_poll_module(void) -{ -#ifdef HAVE_POLL - return &poll_module; -#else - return NULL; -#endif /* HAVE_POLL */ -} - -#ifdef HAVE_POLL - -/* - * Init the module - */ -static int fpm_event_poll_init(int max) -{ - int i; - - if (max < 1) { - return 0; - } - - /* alloc and clear pollfds */ - pollfds = malloc(sizeof(struct pollfd) * max); - if (!pollfds) { - zlog(ZLOG_ERROR, "poll: unable to allocate %d events", max); - return -1; - } - memset(pollfds, 0, sizeof(struct pollfd) * max); - - /* set all fd to -1 in order to ensure it's not set */ - for (i = 0; i < max; i++) { - pollfds[i].fd = -1; - } - - /* alloc and clear active_pollfds */ - active_pollfds = malloc(sizeof(struct pollfd) * max); - if (!active_pollfds) { - free(pollfds); - zlog(ZLOG_ERROR, "poll: unable to allocate %d events", max); - return -1; - } - memset(active_pollfds, 0, sizeof(struct pollfd) * max); - - /* save max */ - npollfds = max; - return 0; -} - -/* - * Clean the module - */ -static int fpm_event_poll_clean(void) -{ - /* free pollfds */ - if (pollfds) { - free(pollfds); - pollfds = NULL; - } - - /* free active_pollfds */ - if (active_pollfds) { - free(active_pollfds); - active_pollfds = NULL; - } - - npollfds = 0; - return 0; -} - -/* - * wait for events or timeout - */ -static int fpm_event_poll_wait(struct fpm_event_queue_s *queue, unsigned long int timeout) /* {{{ */ -{ - int ret; - struct fpm_event_queue_s *q; - - if (npollfds > 0) { - /* copy pollfds because poll() alters it */ - memcpy(active_pollfds, pollfds, sizeof(struct pollfd) * npollfds); - } - - /* wait for incoming event or timeout */ - ret = poll(active_pollfds, npollfds, timeout); - if (ret == -1) { - - /* trigger error unless signal interrupt */ - if (errno != EINTR) { - zlog(ZLOG_WARNING, "poll() returns %d", errno); - return -1; - } - } - - /* events have been triggered */ - if (ret > 0) { - - /* trigger POLLIN events */ - q = queue; - while (q) { - /* ensure ev->index is valid */ - if (q->ev && q->ev->index >= 0 && q->ev->index < npollfds && q->ev->fd == active_pollfds[q->ev->index].fd) { - - /* has the event has been triggered ? */ - if (active_pollfds[q->ev->index].revents & POLLIN) { - - /* fire the event */ - fpm_event_fire(q->ev); - - /* sanity check */ - if (fpm_globals.parent_pid != getpid()) { - return -2; - } - } - } - q = q->next; /* iterate */ - } - } - - return ret; -} -/* }}} */ - -/* - * Add a FD to the fd set - */ -static int fpm_event_poll_add(struct fpm_event_s *ev) /* {{{ */ -{ - int i; - - /* do we have a direct free slot */ - if (pollfds[next_free_slot].fd == -1) { - /* register the event */ - pollfds[next_free_slot].fd = ev->fd; - pollfds[next_free_slot].events = POLLIN; - - /* remember the event place in the fd list and suppose next slot is free */ - ev->index = next_free_slot++; - if (next_free_slot >= npollfds) { - next_free_slot = 0; - } - return 0; - } - - /* let's search */ - for (i = 0; i < npollfds; i++) { - if (pollfds[i].fd != -1) { - /* not free */ - continue; - } - - /* register the event */ - pollfds[i].fd = ev->fd; - pollfds[i].events = POLLIN; - - /* remember the event place in the fd list and suppose next slot is free */ - ev->index = next_free_slot++; - if (next_free_slot >= npollfds) { - next_free_slot = 0; - } - return 0; - } - - zlog(ZLOG_ERROR, "poll: not enough space to add event (fd=%d)", ev->fd); - return -1; -} -/* }}} */ - -/* - * Remove a FD from the fd set - */ -static int fpm_event_poll_remove(struct fpm_event_s *ev) /* {{{ */ -{ - int i; - - /* do we have a direct access */ - if (ev->index >= 0 && ev->index < npollfds && pollfds[ev->index].fd == ev->fd) { - /* remember this slot as free */ - next_free_slot = ev->index; - - /* clear event in pollfds */ - pollfds[ev->index].fd = -1; - pollfds[ev->index].events = 0; - - /* mark the event as not registered */ - ev->index = -1; - - return 0; - } - - /* let's search */ - for (i = 0; i < npollfds; i++) { - - if (pollfds[i].fd != ev->fd) { - /* not found */ - continue; - } - - /* remember this slot as free */ - next_free_slot = i; - - /* clear event in pollfds */ - pollfds[i].fd = -1; - pollfds[i].events = 0; - - /* mark the event as not registered */ - ev->index = -1; - - return 0; - } - - zlog(ZLOG_ERROR, "poll: unable to remove event: not found (fd=%d, index=%d)", ev->fd, ev->index); - return -1; -} -/* }}} */ - -#endif /* HAVE_POLL */ diff --git a/sapi/fpm/fpm/events/poll.h b/sapi/fpm/fpm/events/poll.h deleted file mode 100644 index 24fa512eda9e..000000000000 --- a/sapi/fpm/fpm/events/poll.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright © The PHP Group and Contributors. | - +----------------------------------------------------------------------+ - | This source file is subject to the Modified BSD License that is | - | bundled with this package in the file LICENSE, and is available | - | through the World Wide Web at . | - | | - | SPDX-License-Identifier: BSD-3-Clause | - +----------------------------------------------------------------------+ - | Authors: Jerome Loyet | - +----------------------------------------------------------------------+ -*/ - -#ifndef FPM_EVENTS_POLL_H -#define FPM_EVENTS_POLL_H - -#include "../fpm_config.h" -#include "../fpm_events.h" - -struct fpm_event_module_s *fpm_event_poll_module(void); - -#endif /* FPM_EVENTS_POLL_H */ diff --git a/sapi/fpm/fpm/events/port.c b/sapi/fpm/fpm/events/port.c deleted file mode 100644 index b7f5715abad4..000000000000 --- a/sapi/fpm/fpm/events/port.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright © The PHP Group and Contributors. | - +----------------------------------------------------------------------+ - | This source file is subject to the Modified BSD License that is | - | bundled with this package in the file LICENSE, and is available | - | through the World Wide Web at . | - | | - | SPDX-License-Identifier: BSD-3-Clause | - +----------------------------------------------------------------------+ - | Authors: Jerome Loyet | - +----------------------------------------------------------------------+ -*/ - -#include "../fpm_config.h" -#include "../fpm_events.h" -#include "../fpm.h" -#include "../zlog.h" - -#ifdef HAVE_EVENT_PORTS - -#include -#include -#include - -static int fpm_event_port_init(int max); -static int fpm_event_port_clean(void); -static int fpm_event_port_wait(struct fpm_event_queue_s *queue, unsigned long int timeout); -static int fpm_event_port_add(struct fpm_event_s *ev); -static int fpm_event_port_remove(struct fpm_event_s *ev); - -static struct fpm_event_module_s port_module = { - .name = "port", - .support_edge_trigger = 0, - .init = fpm_event_port_init, - .clean = fpm_event_port_clean, - .wait = fpm_event_port_wait, - .add = fpm_event_port_add, - .remove = fpm_event_port_remove, -}; - -port_event_t *events = NULL; -int nevents = 0; -static int pfd = -1; - -#endif /* HAVE_EVENT_PORTS */ - -struct fpm_event_module_s *fpm_event_port_module(void) /* {{{ */ -{ -#ifdef HAVE_EVENT_PORTS - return &port_module; -#else - return NULL; -#endif /* HAVE_EVENT_PORTS */ -} -/* }}} */ - -#ifdef HAVE_EVENT_PORTS - -/* - * Init the module - */ -static int fpm_event_port_init(int max) /* {{{ */ -{ - /* open port */ - pfd = port_create(); - if (pfd < 0) { - zlog(ZLOG_ERROR, "port: unable to initialize port_create()"); - return -1; - } - - if (max < 1) { - return 0; - } - - /* alloc and clear active_pollfds */ - events = malloc(sizeof(port_event_t) * max); - if (!events) { - zlog(ZLOG_ERROR, "port: Unable to allocate %d events", max); - return -1; - } - - nevents = max; - return 0; -} -/* }}} */ - -/* - * Clean the module - */ -static int fpm_event_port_clean(void) -{ - if (pfd > -1) { - close(pfd); - pfd = -1; - } - - if (events) { - free(events); - events = NULL; - } - - nevents = 0; - return 0; -} - -/* - * wait for events or timeout - */ -static int fpm_event_port_wait(struct fpm_event_queue_s *queue, unsigned long int timeout) /* {{{ */ -{ - int ret; - unsigned int i, nget; - timespec_t t; - - /* convert timeout into timespec_t */ - t.tv_sec = (int)(timeout / 1000); - t.tv_nsec = (timeout % 1000) * 1000 * 1000; - - /* wait for incoming event or timeout. We want at least one event or timeout */ - nget = 1; - events[0].portev_user = (void *)-1; /* so we can double check that an event was returned */ - - ret = port_getn(pfd, events, nevents, &nget, &t); - if (ret < 0) { - - /* trigger error unless signal interrupt or timeout */ - if (errno != EINTR && errno != ETIME) { - zlog(ZLOG_WARNING, "poll() returns %d", errno); - return -1; - } else if (nget > 0 && events[0].portev_user == (void *)-1) { - /* This confusing API can return an event at the same time - * that it reports EINTR or ETIME. If that occurs, just - * report the event. With EINTR, nget can be > 0 without - * any event, so check that portev_user was filled in. - * - * See discussion thread - * http://marc.info/?l=opensolaris-networking-discuss&m=125071205204540 - */ - nget = 0; - } - } - - for (i = 0; i < nget; i++) { - struct fpm_event_s *ev; - - /* do we have a ptr to the event ? */ - if (!events[i].portev_user) { - continue; - } - - ev = (struct fpm_event_s *)events[i].portev_user; - - /* re-associate for next event */ - fpm_event_port_add(ev); - - /* fire the event */ - fpm_event_fire(ev); - - /* sanity check */ - if (fpm_globals.parent_pid != getpid()) { - return -2; - } - } - return nget; -} -/* }}} */ - -/* - * Add a FD to the fd set - */ -static int fpm_event_port_add(struct fpm_event_s *ev) /* {{{ */ -{ - /* add the event to port */ - if (port_associate(pfd, PORT_SOURCE_FD, ev->fd, POLLIN, (void *)ev) < 0) { - zlog(ZLOG_ERROR, "port: unable to add the event"); - return -1; - } - return 0; -} -/* }}} */ - -/* - * Remove a FD from the fd set - */ -static int fpm_event_port_remove(struct fpm_event_s *ev) /* {{{ */ -{ - /* remove the event from port */ - if (port_dissociate(pfd, PORT_SOURCE_FD, ev->fd) < 0) { - zlog(ZLOG_ERROR, "port: unable to add the event"); - return -1; - } - return 0; -} -/* }}} */ - -#endif /* HAVE_EVENT_PORTS */ diff --git a/sapi/fpm/fpm/events/port.h b/sapi/fpm/fpm/events/port.h deleted file mode 100644 index 5768c891bdac..000000000000 --- a/sapi/fpm/fpm/events/port.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright © The PHP Group and Contributors. | - +----------------------------------------------------------------------+ - | This source file is subject to the Modified BSD License that is | - | bundled with this package in the file LICENSE, and is available | - | through the World Wide Web at . | - | | - | SPDX-License-Identifier: BSD-3-Clause | - +----------------------------------------------------------------------+ - | Authors: Jerome Loyet | - +----------------------------------------------------------------------+ -*/ - -#ifndef FPM_EVENTS_PORT_H -#define FPM_EVENTS_PORT_H - -#include "../fpm_config.h" -#include "../fpm_events.h" - -struct fpm_event_module_s *fpm_event_port_module(void); - -#endif /* FPM_EVENTS_PORT_H */ diff --git a/sapi/fpm/fpm/events/select.c b/sapi/fpm/fpm/events/select.c deleted file mode 100644 index f6132b025747..000000000000 --- a/sapi/fpm/fpm/events/select.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright © The PHP Group and Contributors. | - +----------------------------------------------------------------------+ - | This source file is subject to the Modified BSD License that is | - | bundled with this package in the file LICENSE, and is available | - | through the World Wide Web at . | - | | - | SPDX-License-Identifier: BSD-3-Clause | - +----------------------------------------------------------------------+ - | Authors: Jerome Loyet | - +----------------------------------------------------------------------+ -*/ - -#include "../fpm_config.h" -#include "../fpm_events.h" -#include "../fpm.h" -#include "../zlog.h" - -#ifdef HAVE_SELECT - -/* According to POSIX.1-2001 */ -#include - -/* According to earlier standards */ -#include -#include -#include - -#include - -static int fpm_event_select_init(int max); -static int fpm_event_select_wait(struct fpm_event_queue_s *queue, unsigned long int timeout); -static int fpm_event_select_add(struct fpm_event_s *ev); -static int fpm_event_select_remove(struct fpm_event_s *ev); - -static struct fpm_event_module_s select_module = { - .name = "select", - .support_edge_trigger = 0, - .init = fpm_event_select_init, - .clean = NULL, - .wait = fpm_event_select_wait, - .add = fpm_event_select_add, - .remove = fpm_event_select_remove, -}; - -static fd_set fds; - -#endif /* HAVE_SELECT */ - -/* - * return the module configuration - */ -struct fpm_event_module_s *fpm_event_select_module(void) -{ -#ifdef HAVE_SELECT - return &select_module; -#else - return NULL; -#endif /* HAVE_SELECT */ -} - -#ifdef HAVE_SELECT - -/* - * Init the module - */ -static int fpm_event_select_init(int max) /* {{{ */ -{ - FD_ZERO(&fds); - return 0; -} -/* }}} */ - - -/* - * wait for events or timeout - */ -static int fpm_event_select_wait(struct fpm_event_queue_s *queue, unsigned long int timeout) /* {{{ */ -{ - int ret; - struct fpm_event_queue_s *q; - fd_set current_fds; - struct timeval t; - - /* copy fds because select() alters it */ - current_fds = fds; - - /* fill struct timeval with timeout */ - t.tv_sec = timeout / 1000; - t.tv_usec = (timeout % 1000) * 1000; - - /* wait for incoming event or timeout */ - ret = select(FD_SETSIZE, ¤t_fds, NULL, NULL, &t); - if (ret == -1) { - - /* trigger error unless signal interrupt */ - if (errno != EINTR) { - zlog(ZLOG_WARNING, "poll() returns %d", errno); - return -1; - } - } - - /* events have been triggered */ - if (ret > 0) { - - /* trigger POLLIN events */ - q = queue; - while (q) { - if (q->ev) { /* sanity check */ - - /* check if the event has been triggered */ - if (FD_ISSET(q->ev->fd, ¤t_fds)) { - - /* fire the event */ - fpm_event_fire(q->ev); - - /* sanity check */ - if (fpm_globals.parent_pid != getpid()) { - return -2; - } - } - } - q = q->next; /* iterate */ - } - } - return ret; - -} -/* }}} */ - -/* - * Add a FD to the fd set - */ -static int fpm_event_select_add(struct fpm_event_s *ev) /* {{{ */ -{ - /* check size limitation */ - if (ev->fd >= FD_SETSIZE) { - zlog(ZLOG_ERROR, "select: not enough space in the select fd list (max = %d). Please consider using another event mechanism.", FD_SETSIZE); - return -1; - } - - /* add the FD if not already in */ - if (!FD_ISSET(ev->fd, &fds)) { - FD_SET(ev->fd, &fds); - ev->index = ev->fd; - } - - return 0; -} -/* }}} */ - -/* - * Remove a FD from the fd set - */ -static int fpm_event_select_remove(struct fpm_event_s *ev) /* {{{ */ -{ - /* remove the fd if it's in */ - if (FD_ISSET(ev->fd, &fds)) { - FD_CLR(ev->fd, &fds); - ev->index = -1; - } - - return 0; -} -/* }}} */ - -#endif /* HAVE_SELECT */ diff --git a/sapi/fpm/fpm/events/select.h b/sapi/fpm/fpm/events/select.h deleted file mode 100644 index e4cafde1ed9b..000000000000 --- a/sapi/fpm/fpm/events/select.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright © The PHP Group and Contributors. | - +----------------------------------------------------------------------+ - | This source file is subject to the Modified BSD License that is | - | bundled with this package in the file LICENSE, and is available | - | through the World Wide Web at . | - | | - | SPDX-License-Identifier: BSD-3-Clause | - +----------------------------------------------------------------------+ - | Authors: Jerome Loyet | - +----------------------------------------------------------------------+ -*/ - -#ifndef FPM_EVENTS_SELECT_H -#define FPM_EVENTS_SELECT_H - -#include "../fpm_config.h" -#include "../fpm_events.h" - -struct fpm_event_module_s *fpm_event_select_module(void); - -#endif /* FPM_EVENTS_SELECT_H */ diff --git a/sapi/fpm/fpm/fpm_events.c b/sapi/fpm/fpm/fpm_events.c index 1ccf2c9c5490..624651486534 100644 --- a/sapi/fpm/fpm/fpm_events.c +++ b/sapi/fpm/fpm/fpm_events.c @@ -8,6 +8,7 @@ #include #include +#include #include "fpm.h" #include "fpm_process_ctl.h" @@ -20,12 +21,6 @@ #include "fpm_clock.h" #include "fpm_log.h" -#include "events/select.h" -#include "events/poll.h" -#include "events/epoll.h" -#include "events/port.h" -#include "events/kqueue.h" - #ifdef HAVE_SYSTEMD #include "fpm_systemd.h" #endif @@ -40,15 +35,19 @@ static int fpm_event_queue_add(struct fpm_event_queue_s **queue, struct fpm_even static int fpm_event_queue_del(struct fpm_event_queue_s **queue, struct fpm_event_s *ev); static void fpm_event_queue_destroy(struct fpm_event_queue_s **queue); -static struct fpm_event_module_s *module; +static struct php_poll_ctx *poll_ctx = NULL; static struct fpm_event_queue_s *fpm_event_queue_timer = NULL; static struct fpm_event_queue_s *fpm_event_queue_fd = NULL; static struct fpm_event_s children_bury_timer; +static php_poll_event *events = NULL; +static int max_events; static void fpm_event_cleanup(int which, void *arg) /* {{{ */ { fpm_event_queue_destroy(&fpm_event_queue_timer); fpm_event_queue_destroy(&fpm_event_queue_fd); + // XXX: Freeing the poll context causes more problems than not. + free(events); } /* }}} */ @@ -185,8 +184,15 @@ static int fpm_event_queue_add(struct fpm_event_queue_s **queue, struct fpm_even *queue = elt; /* ask the event module to add the fd from its own queue */ - if (*queue == fpm_event_queue_fd && module->add) { - module->add(ev); + if (*queue == fpm_event_queue_fd) { + uint32_t events = 0; + if (ev->flags & FPM_EV_EDGE) { + events |= PHP_POLL_ET; + } + if (ev->flags & FPM_EV_READ) { + events |= PHP_POLL_READ; + } + ev->index = php_poll_add(poll_ctx, ev->fd, events, ev) == SUCCESS ? ev->fd : -1; } return 0; @@ -216,8 +222,9 @@ static int fpm_event_queue_del(struct fpm_event_queue_s **queue, struct fpm_even } /* ask the event module to remove the fd from its own queue */ - if (*queue == fpm_event_queue_fd && module->remove) { - module->remove(ev); + if (*queue == fpm_event_queue_fd) { + php_poll_remove(poll_ctx, ev->fd); + ev->index = ev->fd; } free(q); @@ -237,10 +244,6 @@ static void fpm_event_queue_destroy(struct fpm_event_queue_s **queue) /* {{{ */ return; } - if (*queue == fpm_event_queue_fd && module->clean) { - module->clean(); - } - q = *queue; while (q) { tmp = q; @@ -254,44 +257,16 @@ static void fpm_event_queue_destroy(struct fpm_event_queue_s **queue) /* {{{ */ int fpm_event_pre_init(char *mechanism) /* {{{ */ { - /* kqueue */ - module = fpm_event_kqueue_module(); - if (module) { - if (!mechanism || strcasecmp(module->name, mechanism) == 0) { - return 0; - } - } + php_poll_register_backends(); - /* port */ - module = fpm_event_port_module(); - if (module) { - if (!mechanism || strcasecmp(module->name, mechanism) == 0) { - return 0; - } - } - - /* epoll */ - module = fpm_event_epoll_module(); - if (module) { - if (!mechanism || strcasecmp(module->name, mechanism) == 0) { - return 0; - } - } - - /* poll */ - module = fpm_event_poll_module(); - if (module) { - if (!mechanism || strcasecmp(module->name, mechanism) == 0) { - return 0; - } + uint32_t flags = PHP_POLL_FLAG_PERSISTENT; + if (mechanism) { + poll_ctx = php_poll_create_by_name(mechanism, flags); + } else { + poll_ctx = php_poll_create(PHP_POLL_BACKEND_AUTO, flags); } - - /* select */ - module = fpm_event_select_module(); - if (module) { - if (!mechanism || strcasecmp(module->name, mechanism) == 0) { - return 0; - } + if (poll_ctx) { + return 0; } if (mechanism) { @@ -305,44 +280,45 @@ int fpm_event_pre_init(char *mechanism) /* {{{ */ const char *fpm_event_mechanism_name(void) { - return module ? module->name : NULL; + return poll_ctx ? php_poll_backend_name(poll_ctx) : NULL; } int fpm_event_support_edge_trigger(void) { - return module ? module->support_edge_trigger : 0; + return poll_ctx ? php_poll_backend_supports_edge_triggering(php_poll_get_backend_type(poll_ctx)) : 0; } int fpm_event_init_main(void) { struct fpm_worker_pool_s *wp; - int max; - if (!module) { - zlog(ZLOG_ERROR, "no event module found"); + if (!poll_ctx) { + zlog(ZLOG_ERROR, "no event poll_ctx found"); return -1; } - if (!module->wait) { - zlog(ZLOG_ERROR, "Incomplete event implementation. Please open a bug report on https://github.com/php/php-src/issues."); - return -1; - } + const char *poll_ctx_name = fpm_event_mechanism_name(); /* count the max number of necessary fds for polling */ - max = 1; /* only one FD is necessary at startup for the master process signal pipe */ + max_events = 1; /* only one FD is necessary at startup for the master process signal pipe */ for (wp = fpm_worker_all_pools; wp; wp = wp->next) { if (!wp->config) continue; if (wp->config->catch_workers_output && wp->config->pm_max_children > 0) { - max += (wp->config->pm_max_children * 2); + max_events += (wp->config->pm_max_children * 2); } } - if (module->init(max) < 0) { - zlog(ZLOG_ERROR, "Unable to initialize the event module %s", module->name); + if (php_poll_init(poll_ctx) != SUCCESS) { + php_poll_error poll_error = php_poll_get_error(poll_ctx); + zlog(ZLOG_ERROR, "Unable to initialize the event poll_ctx %s: %s", + poll_ctx_name, + php_poll_error_string(poll_error)); return -1; } + php_poll_set_max_events_hint(poll_ctx, max_events); + events = calloc(max_events, sizeof(*events)); - zlog(ZLOG_DEBUG, "event module is %s and %d fds have been reserved", module->name, max); + zlog(ZLOG_DEBUG, "event poll_ctx is %s and %d fds have been reserved", poll_ctx_name, max_events); if (0 > fpm_cleanup_add(FPM_CLEANUP_ALL, fpm_event_cleanup, NULL)) { return -1; @@ -383,10 +359,11 @@ void fpm_event_loop(int err) /* {{{ */ struct timeval ms; struct timeval tmp; struct timeval now; - unsigned long int timeout; + struct timespec timeout; int ret; /* sanity check */ + /* is a child, nothing to do here */ if (fpm_globals.parent_pid != getpid()) { return; } @@ -409,21 +386,33 @@ void fpm_event_loop(int err) /* {{{ */ /* 1s timeout if none has been set */ if (!timerisset(&ms) || timercmp(&ms, &now, <) || timercmp(&ms, &now, ==)) { - timeout = 1000; + timeout.tv_sec = 0; + timeout.tv_nsec = 1000; } else { timersub(&ms, &now, &tmp); - timeout = (tmp.tv_sec * 1000) + (tmp.tv_usec / 1000) + 1; + TIMEVAL_TO_TIMESPEC(&tmp, &timeout); + // timeout.tv_nsec += 1000; + // timeout = (tmp.tv_sec * 1000) + (tmp.tv_usec / 1000) + 1; } - ret = module->wait(fpm_event_queue_fd, timeout); - - /* is a child, nothing to do here */ - if (ret == -2) { - return; - } + /* translate from our linked list to its array */ + ret = php_poll_wait(poll_ctx, events, max_events, &timeout); if (ret > 0) { - zlog(ZLOG_DEBUG, "event module triggered %d events", ret); + zlog(ZLOG_DEBUG, "event poll_ctx triggered %d events", ret); + } else if (ret < 0) { + php_poll_error poll_error = php_poll_get_error(poll_ctx); + /* we don't care about signal interrupts */ + if (poll_error != PHP_POLL_ERROR_CODE_INTERRUPTED) { + zlog(ZLOG_ERROR, "poll error: %s", php_poll_error_string(poll_error)); + } + } + /* do the logic the event module used to */ + for (int i = 0; i < ret; i++) { + struct fpm_event_s *ev = (struct fpm_event_s *)events[i].data; + if (events[i].data) { + fpm_event_fire(ev); + } } /* trigger timers */