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.

141 lines
3.4 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->rdidx = -1;
  27. ev->wridx = -1;
  28. return fdev_enable(ev, flags);
  29. }
  30. int
  31. fdev_enable(struct fdev *ev, uint16_t flags)
  32. {
  33. struct kevent kev[2], *kp = NULL;
  34. int count = 0;
  35. uint16_t sf = ev->flags;
  36. ev->flags |= flags;
  37. if ((sf & EV_READ) == 0 && (flags & EV_READ) != 0) {
  38. EV_SET(&kev[0], ev->fd, EVFILT_READ, EV_ADD, 0, 0, ev);
  39. kp = kev;
  40. count = 1;
  41. }
  42. if ((sf & EV_WRITE) == 0 && (flags & EV_WRITE) != 0) {
  43. EV_SET(&kev[1], ev->fd, EVFILT_WRITE, EV_ADD, 0, 0, ev);
  44. if (count == 0)
  45. kp = &kev[1];
  46. count++;
  47. }
  48. return count > 0 ? kevent(m_kq, kp, count, NULL, 0, NULL) : 0;
  49. }
  50. int
  51. fdev_disable(struct fdev *ev, uint16_t flags)
  52. {
  53. struct kevent kev[2], *kp = NULL;
  54. int count = 0;
  55. uint16_t sf = ev->flags;
  56. ev->flags &= ~flags;
  57. if ((sf & EV_READ) != 0 && (flags & EV_READ) != 0) {
  58. EV_SET(&kev[0], ev->fd, EVFILT_READ, EV_DELETE, 0, 0, ev);
  59. kp = kev;
  60. count = 1;
  61. }
  62. if ((sf & EV_WRITE) != 0 && (flags & EV_WRITE) != 0) {
  63. EV_SET(&kev[1], ev->fd, EVFILT_WRITE, EV_DELETE, 0, 0, ev);
  64. if (count == 0)
  65. kp = &kev[1];
  66. count++;
  67. }
  68. return count > 0 ? kevent(m_kq, kp, count, NULL, 0, NULL) : 0;
  69. }
  70. int
  71. fdev_del(struct fdev *ev)
  72. {
  73. if (ev->rdidx >= 0)
  74. m_valid[ev->rdidx] = 0;
  75. if (ev->wridx >= 0)
  76. m_valid[ev->wridx] = 0;
  77. return fdev_disable(ev, EV_READ|EV_WRITE);
  78. }
  79. int
  80. evloop(void)
  81. {
  82. int nev, i;
  83. struct timespec delay;
  84. while (1) {
  85. evtimers_run();
  86. delay = evtimer_delay();
  87. if ((nev = kevent(m_kq, NULL, 0, m_evs, 100, &delay)) < 0) {
  88. if (errno == EINTR)
  89. continue;
  90. else
  91. return -1;
  92. }
  93. memset(m_valid, 1, nev);
  94. for (i = 0; i < nev; i++) {
  95. if (m_evs[i].flags & EV_ERROR) {
  96. errno = m_evs[i].data;
  97. return -1;
  98. }
  99. struct fdev *ev = (struct fdev *)m_evs[i].udata;
  100. switch (m_evs[i].filter) {
  101. case EVFILT_READ:
  102. ev->rdidx = i;
  103. break;
  104. case EVFILT_WRITE:
  105. ev->wridx = i;
  106. break;
  107. }
  108. }
  109. for (i = 0; i < nev; i++) {
  110. if (!m_valid[i])
  111. continue;
  112. struct fdev *ev = (struct fdev *)m_evs[i].udata;
  113. switch (m_evs[i].filter) {
  114. case EVFILT_READ:
  115. if (ev->flags & EV_READ)
  116. ev->cb(ev->fd, EV_READ, ev->arg);
  117. if (m_valid[i])
  118. ev->rdidx = -1;
  119. break;
  120. case EVFILT_WRITE:
  121. if (ev->flags & EV_WRITE)
  122. ev->cb(ev->fd, EV_WRITE, ev->arg);
  123. if (m_valid[i])
  124. ev->wridx = -1;
  125. break;
  126. }
  127. }
  128. }
  129. }