poll.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include "io_watcher.h"
  2. #ifdef EVENT_POLL
  3. #include "hplatform.h"
  4. #include "hdef.h"
  5. #include "hio.h"
  6. #define INIT_FDS_NUM 64
  7. typedef struct poll_ctx_s {
  8. int capacity;
  9. int nfds;
  10. struct pollfd* fds;
  11. } poll_ctx_t;
  12. static void poll_ctx_resize(poll_ctx_t* poll_ctx, int size) {
  13. int bytes = sizeof(struct pollfd) * size;
  14. poll_ctx->fds = (struct pollfd*)realloc(poll_ctx->fds, bytes);
  15. poll_ctx->capacity = size;
  16. }
  17. int iowatcher_init(hloop_t* loop) {
  18. if (loop->iowatcher) return 0;
  19. poll_ctx_t* poll_ctx = (poll_ctx_t*)malloc(sizeof(poll_ctx_t));
  20. poll_ctx->capacity = INIT_FDS_NUM;
  21. poll_ctx->nfds = 0;
  22. int bytes = sizeof(struct pollfd) * poll_ctx->capacity;
  23. poll_ctx->fds = (struct pollfd*)malloc(bytes);
  24. memset(poll_ctx->fds, 0, bytes);
  25. loop->iowatcher = poll_ctx;
  26. return 0;
  27. }
  28. int iowatcher_cleanup(hloop_t* loop) {
  29. if (loop->iowatcher == NULL) return 0;
  30. poll_ctx_t* poll_ctx = (poll_ctx_t*)loop->iowatcher;
  31. SAFE_FREE(poll_ctx->fds);
  32. SAFE_FREE(loop->iowatcher);
  33. return 0;
  34. }
  35. int iowatcher_add_event(hio_t* io, int events) {
  36. hloop_t* loop = io->loop;
  37. if (loop->iowatcher == NULL) {
  38. hloop_iowatcher_init(loop);
  39. }
  40. poll_ctx_t* poll_ctx = (poll_ctx_t*)loop->iowatcher;
  41. int idx = io->event_index[0];
  42. if (idx < 0) {
  43. io->event_index[0] = idx = poll_ctx->nfds;
  44. poll_ctx->nfds++;
  45. if (idx == poll_ctx->capacity) {
  46. poll_ctx_resize(poll_ctx, poll_ctx->capacity*2);
  47. }
  48. poll_ctx->fds[idx].fd = io->fd;
  49. poll_ctx->fds[idx].events = 0;
  50. poll_ctx->fds[idx].revents = 0;
  51. }
  52. assert(poll_ctx->fds[idx].fd == io->fd);
  53. if (events & READ_EVENT) {
  54. poll_ctx->fds[idx].events |= POLLIN;
  55. }
  56. if (events & WRITE_EVENT) {
  57. poll_ctx->fds[idx].events |= POLLOUT;
  58. }
  59. return 0;
  60. }
  61. int iowatcher_del_event(hio_t* io, int events) {
  62. hloop_t* loop = io->loop;
  63. poll_ctx_t* poll_ctx = (poll_ctx_t*)loop->iowatcher;
  64. if (poll_ctx == NULL) return 0;
  65. int idx = io->event_index[0];
  66. if (idx < 0) return 0;
  67. assert(poll_ctx->fds[idx].fd == io->fd);
  68. if (events & READ_EVENT) {
  69. poll_ctx->fds[idx].events &= ~POLLIN;
  70. }
  71. if (events & WRITE_EVENT) {
  72. poll_ctx->fds[idx].events &= ~POLLOUT;
  73. }
  74. if (poll_ctx->fds[idx].events == 0) {
  75. io->event_index[0] = -1;
  76. poll_ctx->nfds--;
  77. if (idx < poll_ctx->nfds) {
  78. poll_ctx->fds[idx] = poll_ctx->fds[poll_ctx->nfds];
  79. auto iter = loop->ios.find(poll_ctx->fds[idx].fd);
  80. if (iter != loop->ios.end()) {
  81. iter->second->event_index[0] = idx;
  82. }
  83. }
  84. }
  85. return 0;
  86. }
  87. int iowatcher_poll_events(hloop_t* loop, int timeout) {
  88. poll_ctx_t* poll_ctx = (poll_ctx_t*)loop->iowatcher;
  89. if (poll_ctx == NULL) return 0;
  90. if (poll_ctx->nfds == 0) return 0;
  91. int npoll = poll(poll_ctx->fds, poll_ctx->nfds, timeout);
  92. if (npoll < 0) {
  93. perror("poll");
  94. return npoll;
  95. }
  96. if (npoll == 0) return 0;
  97. int nevent = 0;
  98. for (int i = 0; i < poll_ctx->nfds; ++i) {
  99. if (nevent == npoll) break;
  100. int fd = poll_ctx->fds[i].fd;
  101. short revents = poll_ctx->fds[i].revents;
  102. if (revents) {
  103. ++nevent;
  104. hio_t* io = hio_get(loop, fd);
  105. if (io == NULL) continue;
  106. io->revents = revents;
  107. hio_handle_events(io);
  108. }
  109. }
  110. return nevent;
  111. }
  112. #endif