A clone of btpd with my configuration changes.
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.

poll.c 3.1 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include <assert.h>
  2. #include <errno.h>
  3. #include <poll.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "evloop.h"
  7. #define POLL_INIT_SIZE 64
  8. struct poll_ev {
  9. struct fdev *ev;
  10. evloop_cb_t cb;
  11. void *arg;
  12. };
  13. static struct pollfd *m_pfds;
  14. static struct poll_ev *m_pevs;
  15. static int m_cap, m_size;
  16. static int m_cur = -1, m_curdel;
  17. static int
  18. poll_grow(void)
  19. {
  20. int ncap = m_cap * 2;
  21. struct pollfd *nm_pfds = realloc(m_pfds, ncap * sizeof(*m_pfds));
  22. struct poll_ev *nm_pevs = realloc(m_pevs, ncap * sizeof(*m_pevs));
  23. if (nm_pfds != NULL)
  24. m_pfds = nm_pfds;
  25. if (nm_pevs != NULL)
  26. m_pevs = nm_pevs;
  27. if (nm_pfds == NULL || nm_pevs == NULL)
  28. return errno;
  29. m_cap = ncap;
  30. return 0;
  31. }
  32. int
  33. evloop_init(void)
  34. {
  35. if (timeheap_init() != 0)
  36. return -1;
  37. m_cap = POLL_INIT_SIZE;
  38. m_size = 0;
  39. if ((m_pfds = calloc(m_cap, sizeof(*m_pfds))) == NULL)
  40. return -1;
  41. if ((m_pevs = calloc(m_cap, sizeof(*m_pevs))) == NULL) {
  42. free(m_pfds);
  43. return -1;
  44. }
  45. return 0;
  46. }
  47. int
  48. fdev_new(struct fdev *ev, int fd, uint16_t flags, evloop_cb_t cb, void *arg)
  49. {
  50. if (m_size == m_cap && poll_grow() != 0)
  51. return errno;
  52. ev->i = m_size;
  53. m_size++;
  54. m_pfds[ev->i].fd = fd;
  55. m_pfds[ev->i].events =
  56. ((flags & EV_READ) ? POLLIN : 0) |
  57. ((flags & EV_WRITE) ? POLLOUT : 0);
  58. m_pevs[ev->i].ev = ev;
  59. m_pevs[ev->i].cb = cb;
  60. m_pevs[ev->i].arg = arg;
  61. return 0;
  62. }
  63. int
  64. fdev_enable(struct fdev *ev, uint16_t flags)
  65. {
  66. m_pfds[ev->i].events |=
  67. ((flags & EV_READ) ? POLLIN : 0) |
  68. ((flags & EV_WRITE) ? POLLOUT : 0);
  69. return 0;
  70. }
  71. int
  72. fdev_disable(struct fdev *ev, uint16_t flags)
  73. {
  74. short pflags =
  75. ((flags & EV_READ) ? POLLIN : 0) |
  76. ((flags & EV_WRITE) ? POLLOUT : 0);
  77. m_pfds[ev->i].events &= ~pflags;
  78. return 0;
  79. }
  80. int
  81. fdev_del(struct fdev *ev)
  82. {
  83. assert(ev->i < m_size);
  84. m_size--;
  85. m_pfds[ev->i] = m_pfds[m_size];
  86. m_pevs[ev->i] = m_pevs[m_size];
  87. m_pevs[ev->i].ev->i = ev->i;
  88. if (ev->i == m_cur)
  89. m_curdel = 1;
  90. return 0;
  91. }
  92. int
  93. evloop(void)
  94. {
  95. int millisecs;
  96. struct timespec delay;
  97. while (1) {
  98. evtimers_run();
  99. delay = evtimer_delay();
  100. if (delay.tv_sec >= 0)
  101. millisecs = delay.tv_sec * 1000 + delay.tv_nsec / 1000000;
  102. else
  103. millisecs = -1;
  104. if (poll(m_pfds, m_size, millisecs) < 0) {
  105. if (errno == EINTR)
  106. continue;
  107. else
  108. return -1;
  109. }
  110. m_cur = 0;
  111. while (m_cur < m_size) {
  112. struct pollfd *pfd = &m_pfds[m_cur];
  113. struct poll_ev *pev = &m_pevs[m_cur];
  114. if ((pfd->events & POLLIN &&
  115. pfd->revents & (POLLIN|POLLERR|POLLHUP)))
  116. pev->cb(pfd->fd, EV_READ, pev->arg);
  117. if ((!m_curdel && pfd->events & POLLOUT &&
  118. pfd->revents & (POLLOUT|POLLERR|POLLHUP)))
  119. pev->cb(pfd->fd, EV_WRITE, pev->arg);
  120. if (!m_curdel)
  121. m_cur++;
  122. else
  123. m_curdel = 0;
  124. }
  125. m_cur = -1;
  126. }
  127. }