poll.c 3.4 KB

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