1
0

poll.cpp 3.7 KB

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