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.

123 lines
2.9 KiB

  1. #include <sys/types.h>
  2. #include <sys/event.h>
  3. #include <sys/time.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <unistd.h>
  7. #include "evloop.h"
  8. static int m_kq;
  9. static struct kevent m_evs[100];
  10. static uint8_t m_valid[100];
  11. int
  12. evloop_init(void)
  13. {
  14. if (timeheap_init() != 0)
  15. return -1;
  16. m_kq = kqueue();
  17. return m_kq >= 0 ? 0 : -1;
  18. }
  19. int
  20. fdev_new(struct fdev *ev, int fd, uint16_t flags, evloop_cb_t cb, void *arg)
  21. {
  22. ev->fd = fd;
  23. ev->cb = cb;
  24. ev->arg = arg;
  25. ev->flags = 0;
  26. ev->index = -1;
  27. return fdev_enable(ev, flags);
  28. }
  29. int
  30. fdev_enable(struct fdev *ev, uint16_t flags)
  31. {
  32. struct kevent kev[2], *kp = NULL;
  33. int count = 0;
  34. uint16_t sf = ev->flags;
  35. ev->flags |= flags;
  36. if ((sf & EV_READ) == 0 && (flags & EV_READ) != 0) {
  37. EV_SET(&kev[0], ev->fd, EVFILT_READ, EV_ADD, 0, 0, ev);
  38. kp = kev;
  39. count = 1;
  40. }
  41. if ((sf & EV_WRITE) == 0 && (flags & EV_WRITE) != 0) {
  42. EV_SET(&kev[1], ev->fd, EVFILT_WRITE, EV_ADD, 0, 0, ev);
  43. if (count == 0)
  44. kp = &kev[1];
  45. count++;
  46. }
  47. return count > 0 ? kevent(m_kq, kp, count, NULL, 0, NULL) : 0;
  48. }
  49. int
  50. fdev_disable(struct fdev *ev, uint16_t flags)
  51. {
  52. struct kevent kev[2], *kp = NULL;
  53. int count = 0;
  54. uint16_t sf = ev->flags;
  55. ev->flags &= ~flags;
  56. if ((sf & EV_READ) != 0 && (flags & EV_READ) != 0) {
  57. EV_SET(&kev[0], ev->fd, EVFILT_READ, EV_DELETE, 0, 0, ev);
  58. kp = kev;
  59. count = 1;
  60. }
  61. if ((sf & EV_WRITE) != 0 && (flags & EV_WRITE) != 0) {
  62. EV_SET(&kev[1], ev->fd, EVFILT_WRITE, EV_DELETE, 0, 0, ev);
  63. if (count == 0)
  64. kp = &kev[1];
  65. count++;
  66. }
  67. return count > 0 ? kevent(m_kq, kp, count, NULL, 0, NULL) : 0;
  68. }
  69. int
  70. fdev_del(struct fdev *ev)
  71. {
  72. if (ev->index >= 0)
  73. m_valid[ev->index] = 0;
  74. return fdev_disable(ev, EV_READ|EV_WRITE);
  75. }
  76. int
  77. evloop(void)
  78. {
  79. int nev, i;
  80. struct timespec delay;
  81. while (1) {
  82. evtimers_run();
  83. delay = evtimer_delay();
  84. if ((nev = kevent(m_kq, NULL, 0, m_evs, 100, &delay)) < 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 = (struct fdev *)m_evs[i].udata;
  93. ev->index = i;
  94. }
  95. for (i = 0; i < nev; i++) {
  96. if (m_evs[i].flags & EV_ERROR) {
  97. errno = m_evs[i].data;
  98. return -1;
  99. }
  100. struct fdev *ev = (struct fdev *)m_evs[i].udata;
  101. if (m_valid[i] && ev->flags & EV_READ &&
  102. m_evs[i].filter == EVFILT_READ)
  103. ev->cb(ev->fd, EV_READ, ev->arg);
  104. if (m_valid[i] && ev->flags & EV_WRITE &&
  105. m_evs[i].filter == EVFILT_WRITE)
  106. ev->cb(ev->fd, EV_WRITE, ev->arg);
  107. if (m_valid[i])
  108. ev->index = -1;
  109. }
  110. }
  111. }