hloop_test.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * @build: make examples
  3. * @usage: bin/hloop_test
  4. * bin/nc 127.0.0.1 10514
  5. * nc 127.0.0.1 10514
  6. *
  7. */
  8. /*
  9. * @介绍:此程序是为了测试事件循环的各种事件,包括空闲事件、IO事件、定时器事件、自定义事件。
  10. *
  11. */
  12. #include "hloop.h"
  13. #include "hbase.h"
  14. #include "hlog.h"
  15. #include "nlog.h"
  16. // 自定义日志处理器
  17. void mylogger(int loglevel, const char* buf, int len) {
  18. // ERROR以上级别日志打印到标准错误
  19. if (loglevel >= LOG_LEVEL_ERROR) {
  20. stderr_logger(loglevel, buf, len);
  21. }
  22. // INFO以上级别日志写入日志文件
  23. if (loglevel >= LOG_LEVEL_INFO) {
  24. file_logger(loglevel, buf, len);
  25. }
  26. // 所有日志都发送到网络日志器
  27. network_logger(loglevel, buf, len);
  28. }
  29. void on_idle(hidle_t* idle) {
  30. printf("on_idle: event_id=%llu\tpriority=%d\tuserdata=%ld\n",
  31. LLU(hevent_id(idle)), hevent_priority(idle), (long)(intptr_t)(hevent_userdata(idle)));
  32. }
  33. void on_timer(htimer_t* timer) {
  34. hloop_t* loop = hevent_loop(timer);
  35. printf("on_timer: event_id=%llu\tpriority=%d\tuserdata=%ld\ttime=%llus\thrtime=%lluus\n",
  36. LLU(hevent_id(timer)), hevent_priority(timer), (long)(intptr_t)(hevent_userdata(timer)),
  37. LLU(hloop_now(loop)), LLU(hloop_now_hrtime(loop)));
  38. }
  39. void cron_hourly(htimer_t* timer) {
  40. time_t tt;
  41. time(&tt);
  42. printf("cron_hourly: %s\n", ctime(&tt));
  43. }
  44. void timer_write_log(htimer_t* timer) {
  45. static int cnt = 0;
  46. hlogd("[%d] Do you recv me?", ++cnt);
  47. hlogi("[%d] Do you recv me?", ++cnt);
  48. hloge("[%d] Do you recv me?", ++cnt);
  49. }
  50. void on_stdin(hio_t* io, void* buf, int readbytes) {
  51. printf("on_stdin fd=%d readbytes=%d\n", hio_fd(io), readbytes);
  52. printf("> %s\n", (char*)buf);
  53. if (strncmp((char*)buf, "quit", 4) == 0) {
  54. hloop_stop(hevent_loop(io));
  55. }
  56. }
  57. void on_custom_events(hevent_t* ev) {
  58. printf("on_custom_events event_type=%d userdata=%ld\n", (int)ev->event_type, (long)ev->userdata);
  59. }
  60. int main() {
  61. // 在程序退出时做内存检查
  62. // memcheck atexit
  63. HV_MEMCHECK;
  64. // 新建事件循环
  65. hloop_t* loop = hloop_new(0);
  66. // 测试空闲事件和事件优先级
  67. // test idle and priority
  68. for (int i = HEVENT_LOWEST_PRIORITY; i <= HEVENT_HIGHEST_PRIORITY; ++i) {
  69. hidle_t* idle = hidle_add(loop, on_idle, 10);
  70. hevent_set_priority(idle, i);
  71. }
  72. // 测试超时定时器
  73. // test timer timeout
  74. for (int i = 1; i <= 10; ++i) {
  75. htimer_t* timer = htimer_add(loop, on_timer, i*1000, 3);
  76. hevent_set_userdata(timer, (void*)(intptr_t)i);
  77. }
  78. // 测试时间定时器,类似cron效果
  79. // 获取下一分钟的分钟数,如30,则每小时的第30分钟会触发回调
  80. // test timer period
  81. int minute = time(NULL)%3600/60;
  82. htimer_add_period(loop, cron_hourly, minute+1, -1, -1, -1, -1, INFINITE);
  83. // 测试网络日志器,类似android logcat效果,可直接使用telent/nc连接端口10514接收日志
  84. // test network_logger
  85. htimer_add(loop, timer_write_log, 1000, INFINITE);
  86. logger_set_handler(hlog, mylogger);
  87. hlog_set_file("loop.log");
  88. #ifndef _MSC_VER
  89. logger_enable_color(hlog, 1);
  90. #endif
  91. nlog_listen(loop, DEFAULT_LOG_PORT);
  92. // 测试非阻塞标准输入
  93. // test nonblock stdin
  94. printf("input 'quit' to quit loop\n");
  95. char buf[64];
  96. hread(loop, 0, buf, sizeof(buf), on_stdin);
  97. // 测试自定义事件
  98. // test custom_events
  99. for (int i = 0; i < 10; ++i) {
  100. hevent_t ev;
  101. memset(&ev, 0, sizeof(ev));
  102. ev.event_type = (hevent_type_e)(HEVENT_TYPE_CUSTOM + i);
  103. ev.cb = on_custom_events;
  104. ev.userdata = (void*)(long)i;
  105. hloop_post_event(loop, &ev);
  106. }
  107. // 运行事件循环
  108. hloop_run(loop);
  109. // 释放事件循环
  110. hloop_free(&loop);
  111. return 0;
  112. }