A clone of btpd with my configuration changes.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

143 lignes
3.1 KiB

  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. }