lighttpd 1.4.x https://www.lighttpd.net/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.1 KiB

  1. #include "first.h"
  2. #include "fdevent_impl.h"
  3. #include "fdevent.h"
  4. #include "buffer.h"
  5. #include <unistd.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #ifdef FDEVENT_USE_LINUX_EPOLL
  9. # include <sys/epoll.h>
  10. __attribute_cold__
  11. static void fdevent_linux_sysepoll_free(fdevents *ev) {
  12. close(ev->epoll_fd);
  13. free(ev->epoll_events);
  14. }
  15. static int fdevent_linux_sysepoll_event_del(fdevents *ev, fdnode *fdn) {
  16. return epoll_ctl(ev->epoll_fd, EPOLL_CTL_DEL, fdn->fd, NULL);
  17. }
  18. static int fdevent_linux_sysepoll_event_set(fdevents *ev, fdnode *fdn, int events) {
  19. int op = (-1 == fdn->fde_ndx) ? EPOLL_CTL_ADD : EPOLL_CTL_MOD;
  20. int fd = fdn->fde_ndx = fdn->fd;
  21. struct epoll_event ep;
  22. #ifndef EPOLLRDHUP
  23. events &= ~FDEVENT_RDHUP;
  24. #endif
  25. ep.events = events | EPOLLERR | EPOLLHUP;
  26. ep.data.ptr = fdn;
  27. return epoll_ctl(ev->epoll_fd, op, fd, &ep);
  28. }
  29. static int fdevent_linux_sysepoll_poll(fdevents * const ev, int timeout_ms) {
  30. int n = epoll_wait(ev->epoll_fd, ev->epoll_events, ev->maxfds, timeout_ms);
  31. for (int i = 0; i < n; ++i) {
  32. fdnode * const fdn = (fdnode *)ev->epoll_events[i].data.ptr;
  33. int revents = ev->epoll_events[i].events;
  34. if ((fdevent_handler)NULL != fdn->handler) {
  35. (*fdn->handler)(fdn->ctx, revents);
  36. }
  37. }
  38. return n;
  39. }
  40. __attribute_cold__
  41. int fdevent_linux_sysepoll_init(fdevents *ev) {
  42. force_assert(EPOLLIN == FDEVENT_IN);
  43. force_assert(EPOLLPRI == FDEVENT_PRI);
  44. force_assert(EPOLLOUT == FDEVENT_OUT);
  45. force_assert(EPOLLERR == FDEVENT_ERR);
  46. force_assert(EPOLLHUP == FDEVENT_HUP);
  47. #ifdef EPOLLRDHUP
  48. force_assert(EPOLLRDHUP == FDEVENT_RDHUP);
  49. #endif
  50. ev->type = FDEVENT_HANDLER_LINUX_SYSEPOLL;
  51. ev->event_set = fdevent_linux_sysepoll_event_set;
  52. ev->event_del = fdevent_linux_sysepoll_event_del;
  53. ev->poll = fdevent_linux_sysepoll_poll;
  54. ev->free = fdevent_linux_sysepoll_free;
  55. if (-1 == (ev->epoll_fd = epoll_create(ev->maxfds))) return -1;
  56. fdevent_setfd_cloexec(ev->epoll_fd);
  57. ev->epoll_events = malloc(ev->maxfds * sizeof(*ev->epoll_events));
  58. force_assert(NULL != ev->epoll_events);
  59. return 0;
  60. }
  61. #endif