A clone of btpd with my configuration changes.
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

epoll.c 2.8 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <sys/epoll.h>
  2. #include <errno.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include "evloop.h"
  6. static int m_epfd;
  7. static struct epoll_event m_evs[100];
  8. static uint8_t m_valid[100];
  9. int
  10. evloop_init(void)
  11. {
  12. if (timeheap_init() != 0)
  13. return -1;
  14. m_epfd = epoll_create(getdtablesize());
  15. return m_epfd >= 0 ? 0 : -1;
  16. }
  17. int
  18. fdev_new(struct fdev *ev, int fd, uint16_t flags, evloop_cb_t cb, void *arg)
  19. {
  20. ev->fd = fd;
  21. ev->cb = cb;
  22. ev->arg = arg;
  23. ev->flags = 0;
  24. ev->index = -1;
  25. return fdev_enable(ev, flags);
  26. }
  27. int
  28. fdev_enable(struct fdev *ev, uint16_t flags)
  29. {
  30. struct epoll_event epev;
  31. int err = 0;
  32. uint16_t sf = ev->flags;
  33. ev->flags |= flags;
  34. if (sf != ev->flags) {
  35. epev.data.ptr = ev;
  36. epev.events =
  37. ((ev->flags & EV_READ) ? EPOLLIN : 0) |
  38. ((ev->flags & EV_WRITE) ? EPOLLOUT : 0);
  39. if (sf == 0)
  40. err = epoll_ctl(m_epfd, EPOLL_CTL_ADD, ev->fd, &epev);
  41. else
  42. err = epoll_ctl(m_epfd, EPOLL_CTL_MOD, ev->fd, &epev);
  43. }
  44. return err;
  45. }
  46. int
  47. fdev_disable(struct fdev *ev, uint16_t flags)
  48. {
  49. struct epoll_event epev;
  50. int err = 0;
  51. uint16_t sf = ev->flags;
  52. ev->flags &= ~flags;
  53. if (sf != ev->flags) {
  54. epev.data.ptr = ev;
  55. epev.events =
  56. ((ev->flags & EV_READ) ? EPOLLIN : 0) |
  57. ((ev->flags & EV_WRITE) ? EPOLLOUT : 0);
  58. if (ev->flags == 0)
  59. err = epoll_ctl(m_epfd, EPOLL_CTL_DEL, ev->fd, &epev);
  60. else
  61. err = epoll_ctl(m_epfd, EPOLL_CTL_MOD, ev->fd, &epev);
  62. }
  63. return err;
  64. }
  65. int
  66. fdev_del(struct fdev *ev)
  67. {
  68. if (ev->index >= 0)
  69. m_valid[ev->index] = 0;
  70. return fdev_disable(ev, EV_READ|EV_WRITE);
  71. }
  72. int
  73. evloop(void)
  74. {
  75. int nev, i, millisecs;
  76. struct timespec delay;
  77. while (1) {
  78. evtimers_run();
  79. delay = evtimer_delay();
  80. if (delay.tv_sec >= 0)
  81. millisecs = delay.tv_sec * 1000 + delay.tv_nsec / 1000000;
  82. else
  83. millisecs = -1;
  84. if ((nev = epoll_wait(m_epfd, m_evs, 100, millisecs)) < 0) {
  85. if (errno == EINTR)
  86. continue;
  87. else
  88. return -1;
  89. }
  90. memset(m_valid, 1, nev);
  91. for (i = 0; i < nev; i++) {
  92. struct fdev *ev = m_evs[i].data.ptr;
  93. ev->index = i;
  94. }
  95. for (i = 0; i < nev; i++) {
  96. struct fdev *ev = m_evs[i].data.ptr;
  97. if ((m_valid[i] &&
  98. ev->flags & EV_READ &&
  99. m_evs[i].events & (EPOLLIN|EPOLLERR|EPOLLHUP)))
  100. ev->cb(ev->fd, EV_READ, ev->arg);
  101. if ((m_valid[i] && ev->flags & EV_WRITE &&
  102. m_evs[i].events & (EPOLLOUT|EPOLLERR|EPOLLHUP)))
  103. ev->cb(ev->fd, EV_WRITE, ev->arg);
  104. if (m_valid[i])
  105. ev->index = -1;
  106. }
  107. }
  108. }