1
0

epoll.cpp 3.7 KB

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