poll.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include "iowatcher.h"
  2. #ifdef EVENT_POLL
  3. #include "hplatform.h"
  4. #include "hdef.h"
  5. #include "hevent.h"
  6. #ifdef OS_WIN
  7. #define poll WSAPoll
  8. #endif
  9. #ifdef OS_LINUX
  10. #include <sys/poll.h>
  11. #endif
  12. #include "array.h"
  13. #define FDS_INIT_SIZE 64
  14. ARRAY_DECL(struct pollfd, pollfds);
  15. typedef struct poll_ctx_s {
  16. int capacity;
  17. struct pollfds fds;
  18. } poll_ctx_t;
  19. int iowatcher_init(hloop_t* loop) {
  20. if (loop->iowatcher) return 0;
  21. poll_ctx_t* poll_ctx;
  22. HV_ALLOC_SIZEOF(poll_ctx);
  23. pollfds_init(&poll_ctx->fds, FDS_INIT_SIZE);
  24. loop->iowatcher = poll_ctx;
  25. return 0;
  26. }
  27. int iowatcher_cleanup(hloop_t* loop) {
  28. if (loop->iowatcher == NULL) return 0;
  29. poll_ctx_t* poll_ctx = (poll_ctx_t*)loop->iowatcher;
  30. pollfds_cleanup(&poll_ctx->fds);
  31. HV_FREE(loop->iowatcher);
  32. return 0;
  33. }
  34. int iowatcher_add_event(hloop_t* loop, int fd, int events) {
  35. if (loop->iowatcher == NULL) {
  36. iowatcher_init(loop);
  37. }
  38. poll_ctx_t* poll_ctx = (poll_ctx_t*)loop->iowatcher;
  39. hio_t* io = loop->ios.ptr[fd];
  40. int idx = io->event_index[0];
  41. struct pollfd* pfd = NULL;
  42. if (idx < 0) {
  43. io->event_index[0] = idx = poll_ctx->fds.size;
  44. if (idx == poll_ctx->fds.maxsize) {
  45. pollfds_double_resize(&poll_ctx->fds);
  46. }
  47. poll_ctx->fds.size++;
  48. pfd = poll_ctx->fds.ptr + idx;
  49. pfd->fd = fd;
  50. pfd->events = 0;
  51. pfd->revents = 0;
  52. }
  53. else {
  54. pfd = poll_ctx->fds.ptr + idx;
  55. assert(pfd->fd == fd);
  56. }
  57. if (events & HV_READ) {
  58. pfd->events |= POLLIN;
  59. }
  60. if (events & HV_WRITE) {
  61. pfd->events |= POLLOUT;
  62. }
  63. return 0;
  64. }
  65. int iowatcher_del_event(hloop_t* loop, int fd, int events) {
  66. poll_ctx_t* poll_ctx = (poll_ctx_t*)loop->iowatcher;
  67. if (poll_ctx == NULL) return 0;
  68. hio_t* io = loop->ios.ptr[fd];
  69. int idx = io->event_index[0];
  70. if (idx < 0) return 0;
  71. struct pollfd* pfd = poll_ctx->fds.ptr + idx;
  72. assert(pfd->fd == fd);
  73. if (events & HV_READ) {
  74. pfd->events &= ~POLLIN;
  75. }
  76. if (events & HV_WRITE) {
  77. pfd->events &= ~POLLOUT;
  78. }
  79. if (pfd->events == 0) {
  80. pollfds_del_nomove(&poll_ctx->fds, idx);
  81. // NOTE: correct event_index
  82. if (idx < poll_ctx->fds.size) {
  83. hio_t* last = loop->ios.ptr[poll_ctx->fds.ptr[idx].fd];
  84. last->event_index[0] = idx;
  85. }
  86. io->event_index[0] = -1;
  87. }
  88. return 0;
  89. }
  90. int iowatcher_poll_events(hloop_t* loop, int timeout) {
  91. poll_ctx_t* poll_ctx = (poll_ctx_t*)loop->iowatcher;
  92. if (poll_ctx == NULL) return 0;
  93. if (poll_ctx->fds.size == 0) return 0;
  94. int npoll = poll(poll_ctx->fds.ptr, poll_ctx->fds.size, timeout);
  95. if (npoll < 0) {
  96. if (errno == EINTR) {
  97. return 0;
  98. }
  99. perror("poll");
  100. return npoll;
  101. }
  102. if (npoll == 0) return 0;
  103. int nevents = 0;
  104. for (int i = 0; i < poll_ctx->fds.size; ++i) {
  105. int fd = poll_ctx->fds.ptr[i].fd;
  106. short revents = poll_ctx->fds.ptr[i].revents;
  107. if (revents) {
  108. ++nevents;
  109. hio_t* io = loop->ios.ptr[fd];
  110. if (io) {
  111. if (revents & (POLLIN | POLLHUP | POLLERR)) {
  112. io->revents |= HV_READ;
  113. }
  114. if (revents & (POLLOUT | POLLHUP | POLLERR)) {
  115. io->revents |= HV_WRITE;
  116. }
  117. EVENT_PENDING(io);
  118. }
  119. }
  120. if (nevents == npoll) break;
  121. }
  122. return nevents;
  123. }
  124. #endif