1
0

hloop.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #ifndef HW_LOOP_H_
  2. #define HW_LOOP_H_
  3. #include "hdef.h"
  4. BEGIN_EXTERN_C
  5. #include "htime.h"
  6. #include "array.h"
  7. #include "list.h"
  8. #include "heap.h"
  9. #include "queue.h"
  10. #include "hbuf.h"
  11. typedef struct hloop_s hloop_t;
  12. typedef struct hevent_s hevent_t;
  13. typedef struct hidle_s hidle_t;
  14. typedef struct htimer_s htimer_t;
  15. typedef struct htimeout_s htimeout_t;
  16. typedef struct hperiod_s hperiod_t;
  17. typedef struct hio_s hio_t;
  18. typedef void (*hevent_cb) (hevent_t* ev);
  19. typedef void (*hidle_cb) (hidle_t* idle);
  20. typedef void (*htimer_cb) (htimer_t* timer);
  21. typedef void (*hio_cb) (hio_t* io);
  22. typedef void (*haccept_cb) (hio_t* io);
  23. typedef void (*hconnect_cb) (hio_t* io);
  24. typedef void (*hread_cb) (hio_t* io, void* buf, int readbytes);
  25. typedef void (*hwrite_cb) (hio_t* io, const void* buf, int writebytes);
  26. typedef void (*hclose_cb) (hio_t* io);
  27. typedef enum {
  28. HEVENT_TYPE_NONE = 0,
  29. HEVENT_TYPE_IDLE = 0x00000010,
  30. HEVENT_TYPE_TIMEOUT = 0x00000100,
  31. HEVENT_TYPE_PERIOD = 0x00000200,
  32. HEVENT_TYPE_TIMER = HEVENT_TYPE_TIMEOUT|HEVENT_TYPE_PERIOD,
  33. HEVENT_TYPE_IO = 0x00001000,
  34. } hevent_type_e;
  35. #define HEVENT_LOWEST_PRIORITY (-5)
  36. #define HEVENT_LOW_PRIORITY (-3)
  37. #define HEVENT_NORMAL_PRIORITY 0
  38. #define HEVENT_HIGH_PRIORITY 3
  39. #define HEVENT_HIGHEST_PRIORITY 5
  40. #define HEVENT_PRIORITY_SIZE (HEVENT_HIGHEST_PRIORITY-HEVENT_LOWEST_PRIORITY+1)
  41. #define HEVENT_PRIORITY_INDEX(priority) (priority-HEVENT_LOWEST_PRIORITY)
  42. #define HEVENT_FLAGS \
  43. unsigned destroy :1; \
  44. unsigned active :1; \
  45. unsigned pending :1;
  46. #define HEVENT_FIELDS \
  47. hloop_t* loop; \
  48. hevent_type_e event_type; \
  49. uint64_t event_id; \
  50. hevent_cb cb; \
  51. void* userdata; \
  52. int priority; \
  53. struct hevent_s* pending_next; \
  54. HEVENT_FLAGS
  55. struct hevent_s {
  56. HEVENT_FIELDS
  57. };
  58. struct hidle_s {
  59. HEVENT_FIELDS
  60. uint32_t repeat;
  61. //private:
  62. struct list_node node;
  63. };
  64. #define HTIMER_FIELDS \
  65. HEVENT_FIELDS \
  66. uint32_t repeat; \
  67. uint64_t next_timeout; \
  68. struct heap_node node;
  69. struct htimer_s {
  70. HTIMER_FIELDS
  71. };
  72. struct htimeout_s {
  73. HTIMER_FIELDS
  74. uint32_t timeout; \
  75. };
  76. struct hperiod_s {
  77. HTIMER_FIELDS
  78. int8_t minute;
  79. int8_t hour;
  80. int8_t day;
  81. int8_t week;
  82. int8_t month;
  83. };
  84. QUEUE_DECL(offset_buf_t, write_queue);
  85. typedef enum {
  86. HIO_TYPE_UNKNOWN = 0,
  87. HIO_TYPE_STDIN = 0x00000001,
  88. HIO_TYPE_STDOUT = 0x00000002,
  89. HIO_TYPE_STDERR = 0x00000004,
  90. HIO_TYPE_STDIO = 0x0000000F,
  91. HIO_TYPE_FILE = 0x00000010,
  92. HIO_TYPE_IP = 0x00000100,
  93. HIO_TYPE_UDP = 0x00001000,
  94. HIO_TYPE_TCP = 0x00010000,
  95. HIO_TYPE_SSL = 0x00020000,
  96. HIO_TYPE_SOCKET = 0x00FFFF00,
  97. } hio_type_e;
  98. struct hio_s {
  99. HEVENT_FIELDS
  100. unsigned ready :1;
  101. unsigned closed :1;
  102. unsigned accept :1;
  103. unsigned connect :1;
  104. unsigned connectex :1; // for ConnectEx/DisconnectEx
  105. unsigned recv :1;
  106. unsigned send :1;
  107. unsigned recvfrom :1;
  108. unsigned sendto :1;
  109. int fd;
  110. hio_type_e io_type;
  111. int error;
  112. int events;
  113. int revents;
  114. struct sockaddr* localaddr;
  115. struct sockaddr* peeraddr;
  116. hbuf_t readbuf; // for hread
  117. struct write_queue write_queue; // for hwrite
  118. // callbacks
  119. hread_cb read_cb;
  120. hwrite_cb write_cb;
  121. hclose_cb close_cb;
  122. haccept_cb accept_cb;
  123. hconnect_cb connect_cb;
  124. //private:
  125. int event_index[2]; // for poll,kqueue
  126. void* hovlp; // for iocp/overlapio
  127. void* ssl; // for SSL
  128. };
  129. typedef enum {
  130. HLOOP_STATUS_STOP,
  131. HLOOP_STATUS_RUNNING,
  132. HLOOP_STATUS_PAUSE
  133. } hloop_status_e;
  134. ARRAY_DECL(hio_t*, io_array);
  135. struct hloop_s {
  136. hloop_status_e status;
  137. time_t start_time;
  138. // hrtime: us
  139. uint64_t start_hrtime;
  140. uint64_t end_hrtime;
  141. uint64_t cur_hrtime;
  142. uint64_t loop_cnt;
  143. void* userdata;
  144. //private:
  145. // events
  146. uint64_t event_counter;
  147. uint32_t nactives;
  148. uint32_t npendings;
  149. // pendings: with priority as array.index
  150. hevent_t* pendings[HEVENT_PRIORITY_SIZE];
  151. // idles
  152. struct list_head idles;
  153. uint32_t nidles;
  154. // timers
  155. struct heap timers;
  156. uint32_t ntimers;
  157. // ios: with fd as array.index
  158. struct io_array ios;
  159. uint32_t nios;
  160. void* iowatcher;
  161. };
  162. // loop
  163. int hloop_init(hloop_t* loop);
  164. //void hloop_cleanup(hloop_t* loop);
  165. int hloop_run(hloop_t* loop);
  166. int hloop_stop(hloop_t* loop);
  167. int hloop_pause(hloop_t* loop);
  168. int hloop_resume(hloop_t* loop);
  169. static inline void hloop_update_time(hloop_t* loop) {
  170. loop->cur_hrtime = gethrtime();
  171. }
  172. static inline time_t hloop_now(hloop_t* loop) {
  173. return loop->start_time + (loop->cur_hrtime - loop->start_hrtime) / 1000000;
  174. }
  175. static inline uint64_t hloop_now_hrtime(hloop_t* loop) {
  176. return loop->start_time*1e6 + (loop->cur_hrtime - loop->start_hrtime);
  177. }
  178. // idle
  179. hidle_t* hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat DEFAULT(INFINITE));
  180. void hidle_del(hidle_t* idle);
  181. // timer
  182. // @param timeout: unit(ms)
  183. htimer_t* htimer_add(hloop_t* loop, htimer_cb cb, uint64_t timeout, uint32_t repeat DEFAULT(INFINITE));
  184. /*
  185. * minute hour day week month cb
  186. * 0~59 0~23 1~31 0~6 1~12
  187. * 30 -1 -1 -1 -1 cron.hourly
  188. * 30 1 -1 -1 -1 cron.daily
  189. * 30 1 15 -1 -1 cron.monthly
  190. * 30 1 -1 7 -1 cron.weekly
  191. * 30 1 1 -1 10 cron.yearly
  192. */
  193. htimer_t* htimer_add_period(hloop_t* loop, htimer_cb cb,
  194. int8_t minute DEFAULT(0), int8_t hour DEFAULT(-1), int8_t day DEFAULT(-1),
  195. int8_t week DEFAULT(-1), int8_t month DEFAULT(-1), uint32_t repeat DEFAULT(INFINITE));
  196. void htimer_del(htimer_t* timer);
  197. void htimer_reset(htimer_t* timer);
  198. // io
  199. // low-level api
  200. #define READ_EVENT 0x0001
  201. #define WRITE_EVENT 0x0004
  202. #define ALL_EVENTS READ_EVENT|WRITE_EVENT
  203. hio_t* hio_get(hloop_t* loop, int fd);
  204. int hio_add(hio_t* io, hio_cb cb, int events DEFAULT(READ_EVENT));
  205. int hio_del(hio_t* io, int events DEFAULT(ALL_EVENTS));
  206. void hio_setlocaladdr(hio_t* io, struct sockaddr* addr, int addrlen);
  207. void hio_setpeeraddr (hio_t* io, struct sockaddr* addr, int addrlen);
  208. // high-level api
  209. hio_t* hread (hloop_t* loop, int fd, void* buf, size_t len, hread_cb read_cb);
  210. hio_t* hwrite (hloop_t* loop, int fd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
  211. void hclose (hio_t* io);
  212. // tcp
  213. hio_t* haccept (hloop_t* loop, int listenfd, haccept_cb accept_cb);
  214. hio_t* hconnect (hloop_t* loop, int connfd, hconnect_cb connect_cb);
  215. hio_t* hrecv (hloop_t* loop, int connfd, void* buf, size_t len, hread_cb read_cb);
  216. hio_t* hsend (hloop_t* loop, int connfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
  217. // @tcp_server: socket -> bind -> listen -> haccept
  218. hio_t* create_tcp_server (hloop_t* loop, int port, haccept_cb accept_cb);
  219. // @tcp_client: resolver -> socket -> hio_get -> hio_setpeeraddr -> hconnect
  220. hio_t* create_tcp_client (hloop_t* loop, const char* host, int port, hconnect_cb connect_cb);
  221. // udp/ip
  222. // NOTE: recvfrom/sendto struct sockaddr* addr save in io->peeraddr
  223. hio_t* hrecvfrom (hloop_t* loop, int sockfd, void* buf, size_t len, hread_cb read_cb);
  224. hio_t* hsendto (hloop_t* loop, int sockfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
  225. // @udp_server: socket -> bind -> hio_get
  226. hio_t* create_udp_server(hloop_t* loop, int port);
  227. // @udp_client: resolver -> socket -> hio_get -> hio_setpeeraddr
  228. hio_t* create_udp_client(hloop_t* loop, const char* host, int port);
  229. // ssl
  230. int hio_enable_ssl(hio_t* io);
  231. END_EXTERN_C
  232. #endif // HW_LOOP_H_