hloop.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. #include "hloop.h"
  2. #include "hdef.h"
  3. #include "htime.h"
  4. #include "hevent.h"
  5. static void hloop_update_time(hloop_t* loop) {
  6. loop->cur_time = gethrtime();
  7. }
  8. int hloop_init(hloop_t* loop) {
  9. loop->status = HLOOP_STATUS_STOP;
  10. loop->timer_counter = 0;
  11. loop->idle_counter = 0;
  12. loop->min_timer_timeout = INFINITE;
  13. loop->event_ctx = NULL;
  14. // hloop_event_init when add_event first
  15. // hloop_event_init(loop);
  16. return 0;
  17. }
  18. void hloop_cleanup(hloop_t* loop) {
  19. for (auto& pair : loop->timers) {
  20. SAFE_FREE(pair.second);
  21. }
  22. loop->timers.clear();
  23. for (auto& pair : loop->idles) {
  24. SAFE_FREE(pair.second);
  25. }
  26. loop->idles.clear();
  27. for (auto& pair : loop->events) {
  28. hevent_t* event = pair.second;
  29. hloop_del_event(event);
  30. SAFE_FREE(event);
  31. }
  32. loop->events.clear();
  33. hloop_event_cleanup(loop);
  34. }
  35. int hloop_handle_timers(hloop_t* loop) {
  36. int ntimer = 0;
  37. auto iter = loop->timers.begin();
  38. while (iter != loop->timers.end()) {
  39. htimer_t* timer = iter->second;
  40. if (timer->destroy) goto destroy;
  41. if (timer->disable) goto next;
  42. if (timer->repeat == 0) goto destroy;
  43. if (timer->next_timeout < loop->cur_time) {
  44. ++ntimer;
  45. if (timer->cb) {
  46. timer->cb(timer, timer->userdata);
  47. }
  48. timer->next_timeout += timer->timeout*1000;
  49. if (timer->repeat != INFINITE) {
  50. --timer->repeat;
  51. }
  52. }
  53. next:
  54. ++iter;
  55. continue;
  56. destroy:
  57. free(timer);
  58. iter = loop->timers.erase(iter);
  59. }
  60. return ntimer;
  61. }
  62. int hloop_handle_idles(hloop_t* loop) {
  63. int nidle = 0;
  64. auto iter = loop->idles.begin();
  65. while (iter != loop->idles.end()) {
  66. hidle_t* idle = iter->second;
  67. if (idle->destroy) goto destroy;
  68. if (idle->disable) goto next;
  69. if (idle->repeat == 0) goto destroy;
  70. ++nidle;
  71. if (idle->cb) {
  72. idle->cb(idle, idle->userdata);
  73. }
  74. if (idle->repeat != INFINITE) {
  75. --idle->repeat;
  76. }
  77. next:
  78. ++iter;
  79. continue;
  80. destroy:
  81. free(idle);
  82. iter = loop->idles.erase(iter);
  83. }
  84. return nidle;
  85. }
  86. #define PAUSE_SLEEP_TIME 10 // ms
  87. #define MIN_EVENT_TIMEOUT 1 // ms
  88. #define MAX_EVENT_TIMEOUT 1000 // ms
  89. int hloop_run(hloop_t* loop) {
  90. int ntimer, nevent, nidle;
  91. int event_timeout;
  92. loop->start_time = gethrtime();
  93. loop->status = HLOOP_STATUS_RUNNING;
  94. loop->loop_cnt = 0;
  95. while (loop->status != HLOOP_STATUS_STOP) {
  96. hloop_update_time(loop);
  97. if (loop->status == HLOOP_STATUS_PAUSE) {
  98. msleep(PAUSE_SLEEP_TIME);
  99. continue;
  100. }
  101. ++loop->loop_cnt;
  102. // timers -> events -> idles
  103. ntimer = nevent = nidle = 0;
  104. event_timeout = INFINITE;
  105. if (loop->timers.size() != 0) {
  106. ntimer = hloop_handle_timers(loop);
  107. event_timeout = MAX(MIN_EVENT_TIMEOUT, loop->min_timer_timeout/10);
  108. }
  109. if (loop->events.size() == 0 || loop->idles.size() != 0) {
  110. event_timeout = MIN(event_timeout, MAX_EVENT_TIMEOUT);
  111. }
  112. if (loop->events.size() != 0) {
  113. nevent = hloop_handle_events(loop, event_timeout);
  114. }
  115. else {
  116. msleep(event_timeout);
  117. }
  118. if (ntimer == 0 && nevent == 0 && loop->idles.size() != 0) {
  119. nidle = hloop_handle_idles(loop);
  120. }
  121. //printf("loop_cnt=%lu ntimer=%d nevent=%d nidle=%d\n", loop->loop_cnt, ntimer, nevent, nidle);
  122. }
  123. loop->status = HLOOP_STATUS_STOP;
  124. loop->end_time = gethrtime();
  125. hloop_cleanup(loop);
  126. return 0;
  127. }
  128. int hloop_stop(hloop_t* loop) {
  129. loop->status = HLOOP_STATUS_STOP;
  130. return 0;
  131. }
  132. int hloop_pause(hloop_t* loop) {
  133. if (loop->status == HLOOP_STATUS_RUNNING) {
  134. loop->status = HLOOP_STATUS_PAUSE;
  135. }
  136. return 0;
  137. }
  138. int hloop_resume(hloop_t* loop) {
  139. if (loop->status == HLOOP_STATUS_PAUSE) {
  140. loop->status = HLOOP_STATUS_RUNNING;
  141. }
  142. return 0;
  143. }
  144. htimer_t* htimer_add(hloop_t* loop, htimer_cb cb, void* userdata, uint64_t timeout, uint32_t repeat) {
  145. htimer_t* timer = (htimer_t*)malloc(sizeof(htimer_t));
  146. memset(timer, 0, sizeof(htimer_t));
  147. timer->loop = loop;
  148. timer->timer_id = ++loop->timer_counter;
  149. timer->cb = cb;
  150. timer->userdata = userdata;
  151. timer->timeout = timeout;
  152. timer->repeat = repeat;
  153. timer->next_timeout = gethrtime() + timeout*1000;
  154. loop->timers[timer->timer_id] = timer;
  155. loop->min_timer_timeout = MIN(timeout, loop->min_timer_timeout);
  156. return timer;
  157. }
  158. void htimer_del(htimer_t* timer) {
  159. timer->destroy = 1;
  160. }
  161. void htimer_del(hloop_t* loop, uint32_t timer_id) {
  162. auto iter = loop->timers.find(timer_id);
  163. if (iter != loop->timers.end()) {
  164. htimer_t* timer = iter->second;
  165. htimer_del(timer);
  166. }
  167. }
  168. hidle_t* hidle_add(hloop_t* loop, hidle_cb cb, void* userdata, uint32_t repeat) {
  169. hidle_t* idle = (hidle_t*)malloc(sizeof(hidle_t));
  170. memset(idle, 0, sizeof(hidle_t));
  171. idle->loop = loop;
  172. idle->idle_id = ++loop->idle_counter;
  173. idle->cb = cb;
  174. idle->userdata = userdata;
  175. idle->repeat = repeat;
  176. loop->idles[idle->idle_id] = idle;
  177. return idle;
  178. }
  179. void hidle_del(hidle_t* idle) {
  180. idle->destroy = 1;
  181. }
  182. void hidle_del(hloop_t* loop, uint32_t idle_id) {
  183. auto iter = loop->idles.find(idle_id);
  184. if (iter != loop->idles.end()) {
  185. hidle_t* idle = iter->second;
  186. hidle_del(idle);
  187. }
  188. }
  189. hevent_t* hevent_add(hloop_t* loop, int fd) {
  190. #ifdef EVENT_SELECT
  191. if (loop->events.size() >= FD_SETSIZE) return NULL;
  192. #endif
  193. hevent_t* event = (hevent_t*)malloc(sizeof(hevent_t));
  194. memset(event, 0, sizeof(hevent_t));
  195. event->loop = loop;
  196. event->fd = fd;
  197. event->event_index[0] = -1;
  198. event->event_index[1] = -1;
  199. event->events = 0;
  200. loop->events[fd] = event;
  201. return event;
  202. }
  203. hevent_t* hevent_get(hloop_t* loop, int fd) {
  204. auto iter = loop->events.find(fd);
  205. if (iter != loop->events.end()) {
  206. return iter->second;
  207. }
  208. return NULL;
  209. }
  210. hevent_t* hevent_get_or_add(hloop_t* loop, int fd) {
  211. hevent_t* event = hevent_get(loop, fd);
  212. if (event) {
  213. event->destroy = 0;
  214. event->disable = 0;
  215. return event;
  216. }
  217. return hevent_add(loop, fd);
  218. }
  219. void hevent_del(hevent_t* event) {
  220. event->destroy = 1;
  221. hloop_del_event(event, READ_EVENT|WRITE_EVENT);
  222. }
  223. void hevent_del(hloop_t* loop, int fd) {
  224. auto iter = loop->events.find(fd);
  225. if (iter != loop->events.end()) {
  226. hevent_del(iter->second);
  227. }
  228. }
  229. hevent_t* hevent_read(hloop_t* loop, int fd, hevent_cb cb, void* userdata) {
  230. hevent_t* event = hevent_get_or_add(loop, fd);
  231. if (event == NULL) return NULL;
  232. event->read_cb = cb;
  233. event->read_userdata = userdata;
  234. hloop_add_event(event, READ_EVENT);
  235. return event;
  236. }
  237. hevent_t* hevent_write(hloop_t* loop, int fd, hevent_cb cb, void* userdata) {
  238. hevent_t* event = hevent_get_or_add(loop, fd);
  239. if (event == NULL) return NULL;
  240. event->write_cb = cb;
  241. event->write_userdata = userdata;
  242. hloop_add_event(event, WRITE_EVENT);
  243. return event;
  244. }
  245. #include "hsocket.h"
  246. hevent_t* hevent_accept(hloop_t* loop, int listenfd, hevent_cb cb, void* userdata) {
  247. hevent_t* event = hevent_read(loop, listenfd, cb, userdata);
  248. if (event) {
  249. nonblocking(listenfd);
  250. event->accept = 1;
  251. }
  252. return event;
  253. }
  254. hevent_t* hevent_connect(hloop_t* loop, int connfd, hevent_cb cb, void* userdata) {
  255. hevent_t* event = hevent_write(loop, connfd, cb, userdata);
  256. if (event) {
  257. nonblocking(connfd);
  258. event->connect = 1;
  259. }
  260. return event;
  261. }