hloop.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. #ifndef HV_LOOP_H_
  2. #define HV_LOOP_H_
  3. #include "hexport.h"
  4. #include "hplatform.h"
  5. #include "hdef.h"
  6. typedef struct hloop_s hloop_t;
  7. typedef struct hevent_s hevent_t;
  8. // NOTE: The following structures are subclasses of hevent_t,
  9. // inheriting hevent_t data members and function members.
  10. typedef struct hidle_s hidle_t;
  11. typedef struct htimer_s htimer_t;
  12. typedef struct htimeout_s htimeout_t;
  13. typedef struct hperiod_s hperiod_t;
  14. typedef struct hio_s hio_t;
  15. typedef void (*hevent_cb) (hevent_t* ev);
  16. typedef void (*hidle_cb) (hidle_t* idle);
  17. typedef void (*htimer_cb) (htimer_t* timer);
  18. typedef void (*hio_cb) (hio_t* io);
  19. typedef void (*haccept_cb) (hio_t* io);
  20. typedef void (*hconnect_cb) (hio_t* io);
  21. typedef void (*hread_cb) (hio_t* io, void* buf, int readbytes);
  22. typedef void (*hwrite_cb) (hio_t* io, const void* buf, int writebytes);
  23. typedef void (*hclose_cb) (hio_t* io);
  24. typedef enum {
  25. HLOOP_STATUS_STOP,
  26. HLOOP_STATUS_RUNNING,
  27. HLOOP_STATUS_PAUSE
  28. } hloop_status_e;
  29. typedef enum {
  30. HEVENT_TYPE_NONE = 0,
  31. HEVENT_TYPE_IO = 0x00000001,
  32. HEVENT_TYPE_TIMEOUT = 0x00000010,
  33. HEVENT_TYPE_PERIOD = 0x00000020,
  34. HEVENT_TYPE_TIMER = HEVENT_TYPE_TIMEOUT|HEVENT_TYPE_PERIOD,
  35. HEVENT_TYPE_IDLE = 0x00000100,
  36. HEVENT_TYPE_CUSTOM = 0x00000400, // 1024
  37. } hevent_type_e;
  38. #define HEVENT_LOWEST_PRIORITY (-5)
  39. #define HEVENT_LOW_PRIORITY (-3)
  40. #define HEVENT_NORMAL_PRIORITY 0
  41. #define HEVENT_HIGH_PRIORITY 3
  42. #define HEVENT_HIGHEST_PRIORITY 5
  43. #define HEVENT_PRIORITY_SIZE (HEVENT_HIGHEST_PRIORITY-HEVENT_LOWEST_PRIORITY+1)
  44. #define HEVENT_PRIORITY_INDEX(priority) (priority-HEVENT_LOWEST_PRIORITY)
  45. #define HEVENT_FLAGS \
  46. unsigned destroy :1; \
  47. unsigned active :1; \
  48. unsigned pending :1;
  49. #define HEVENT_FIELDS \
  50. hloop_t* loop; \
  51. hevent_type_e event_type; \
  52. uint64_t event_id; \
  53. hevent_cb cb; \
  54. void* userdata; \
  55. void* privdata; \
  56. int priority; \
  57. struct hevent_s* pending_next; \
  58. HEVENT_FLAGS
  59. struct hevent_s {
  60. HEVENT_FIELDS
  61. };
  62. #define hevent_set_priority(ev, prio) ((hevent_t*)(ev))->priority = prio
  63. #define hevent_set_userdata(ev, udata) ((hevent_t*)(ev))->userdata = (void*)udata
  64. #define hevent_loop(ev) (((hevent_t*)(ev))->loop)
  65. #define hevent_type(ev) (((hevent_t*)(ev))->event_type)
  66. #define hevent_id(ev) (((hevent_t*)(ev))->event_id)
  67. #define hevent_priority(ev) (((hevent_t*)(ev))->priority)
  68. #define hevent_userdata(ev) (((hevent_t*)(ev))->userdata)
  69. typedef enum {
  70. HIO_TYPE_UNKNOWN = 0,
  71. HIO_TYPE_STDIN = 0x00000001,
  72. HIO_TYPE_STDOUT = 0x00000002,
  73. HIO_TYPE_STDERR = 0x00000004,
  74. HIO_TYPE_STDIO = 0x0000000F,
  75. HIO_TYPE_FILE = 0x00000010,
  76. HIO_TYPE_IP = 0x00000100,
  77. HIO_TYPE_UDP = 0x00001000,
  78. HIO_TYPE_TCP = 0x00010000,
  79. HIO_TYPE_SSL = 0x00020000,
  80. HIO_TYPE_SOCKET = 0x00FFFF00,
  81. } hio_type_e;
  82. #define HIO_DEFAULT_CONNECT_TIMEOUT 5000 // ms
  83. #define HIO_DEFAULT_CLOSE_TIMEOUT 60000 // ms
  84. #define HIO_DEFAULT_KEEPALIVE_TIMEOUT 75000 // ms
  85. #define HIO_DEFAULT_HEARTBEAT_INTERVAL 30000 // ms
  86. BEGIN_EXTERN_C
  87. // loop
  88. #define HLOOP_FLAG_RUN_ONCE 0x00000001
  89. #define HLOOP_FLAG_AUTO_FREE 0x00000002
  90. #define HLOOP_FLAG_QUIT_WHEN_NO_ACTIVE_EVENTS 0x00000004
  91. HV_EXPORT hloop_t* hloop_new(int flags DEFAULT(HLOOP_FLAG_AUTO_FREE));
  92. // WARN: Forbid to call hloop_free if HLOOP_FLAG_AUTO_FREE set.
  93. HV_EXPORT void hloop_free(hloop_t** pp);
  94. // NOTE: when no active events, loop will quit if HLOOP_FLAG_QUIT_WHEN_NO_ACTIVE_EVENTS set.
  95. HV_EXPORT int hloop_run(hloop_t* loop);
  96. // NOTE: hloop_stop called in loop-thread just set flag to quit in next loop,
  97. // if called in other thread, it will wakeup loop-thread from blocking poll system call,
  98. // then you should join loop thread to safely exit loop thread.
  99. HV_EXPORT int hloop_stop(hloop_t* loop);
  100. HV_EXPORT int hloop_pause(hloop_t* loop);
  101. HV_EXPORT int hloop_resume(hloop_t* loop);
  102. HV_EXPORT int hloop_wakeup(hloop_t* loop);
  103. HV_EXPORT hloop_status_e hloop_status(hloop_t* loop);
  104. HV_EXPORT void hloop_update_time(hloop_t* loop);
  105. HV_EXPORT uint64_t hloop_now(hloop_t* loop); // s
  106. HV_EXPORT uint64_t hloop_now_ms(hloop_t* loop); // ms
  107. HV_EXPORT uint64_t hloop_now_hrtime(hloop_t* loop); // us
  108. #define hloop_now_us hloop_now_hrtime
  109. // @return pid of hloop_run
  110. HV_EXPORT long hloop_pid(hloop_t* loop);
  111. // @return tid of hloop_run
  112. HV_EXPORT long hloop_tid(hloop_t* loop);
  113. // userdata
  114. HV_EXPORT void hloop_set_userdata(hloop_t* loop, void* userdata);
  115. HV_EXPORT void* hloop_userdata(hloop_t* loop);
  116. // custom_event
  117. /*
  118. * hevent_t ev;
  119. * memset(&ev, 0, sizeof(hevent_t));
  120. * ev.event_type = (hevent_type_e)(HEVENT_TYPE_CUSTOM + 1);
  121. * ev.cb = custom_event_cb;
  122. * ev.userdata = userdata;
  123. * hloop_post_event(loop, &ev);
  124. */
  125. // NOTE: hloop_post_event is thread-safe, used to post event from other thread to loop thread.
  126. HV_EXPORT void hloop_post_event(hloop_t* loop, hevent_t* ev);
  127. // idle
  128. HV_EXPORT hidle_t* hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat DEFAULT(INFINITE));
  129. HV_EXPORT void hidle_del(hidle_t* idle);
  130. // timer
  131. // @param timeout: unit(ms)
  132. HV_EXPORT htimer_t* htimer_add(hloop_t* loop, htimer_cb cb, uint32_t timeout, uint32_t repeat DEFAULT(INFINITE));
  133. /*
  134. * minute hour day week month cb
  135. * 0~59 0~23 1~31 0~6 1~12
  136. * 30 -1 -1 -1 -1 cron.hourly
  137. * 30 1 -1 -1 -1 cron.daily
  138. * 30 1 15 -1 -1 cron.monthly
  139. * 30 1 -1 5 -1 cron.weekly
  140. * 30 1 1 -1 10 cron.yearly
  141. */
  142. HV_EXPORT htimer_t* htimer_add_period(hloop_t* loop, htimer_cb cb,
  143. int8_t minute DEFAULT(0), int8_t hour DEFAULT(-1), int8_t day DEFAULT(-1),
  144. int8_t week DEFAULT(-1), int8_t month DEFAULT(-1), uint32_t repeat DEFAULT(INFINITE));
  145. HV_EXPORT void htimer_del(htimer_t* timer);
  146. HV_EXPORT void htimer_reset(htimer_t* timer);
  147. // io
  148. //-----------------------low-level apis---------------------------------------
  149. #define HV_READ 0x0001
  150. #define HV_WRITE 0x0004
  151. #define HV_RDWR (HV_READ|HV_WRITE)
  152. /*
  153. const char* hio_engine() {
  154. #ifdef EVENT_SELECT
  155. return "select";
  156. #elif defined(EVENT_POLL)
  157. return "poll";
  158. #elif defined(EVENT_EPOLL)
  159. return "epoll";
  160. #elif defined(EVENT_KQUEUE)
  161. return "kqueue";
  162. #elif defined(EVENT_IOCP)
  163. return "iocp";
  164. #elif defined(EVENT_PORT)
  165. return "evport";
  166. #else
  167. return "noevent";
  168. #endif
  169. }
  170. */
  171. HV_EXPORT const char* hio_engine();
  172. HV_EXPORT hio_t* hio_get(hloop_t* loop, int fd);
  173. HV_EXPORT int hio_add(hio_t* io, hio_cb cb, int events DEFAULT(HV_READ));
  174. HV_EXPORT int hio_del(hio_t* io, int events DEFAULT(HV_RDWR));
  175. // hio_t fields
  176. // NOTE: fd cannot be used as unique identifier, so we provide an id.
  177. HV_EXPORT uint32_t hio_id (hio_t* io);
  178. HV_EXPORT int hio_fd (hio_t* io);
  179. HV_EXPORT int hio_error (hio_t* io);
  180. HV_EXPORT int hio_events (hio_t* io);
  181. HV_EXPORT int hio_revents (hio_t* io);
  182. HV_EXPORT hio_type_e hio_type (hio_t* io);
  183. HV_EXPORT struct sockaddr* hio_localaddr(hio_t* io);
  184. HV_EXPORT struct sockaddr* hio_peeraddr (hio_t* io);
  185. HV_EXPORT void hio_set_context(hio_t* io, void* ctx);
  186. HV_EXPORT void* hio_context(hio_t* io);
  187. HV_EXPORT bool hio_is_opened(hio_t* io);
  188. HV_EXPORT bool hio_is_closed(hio_t* io);
  189. // set callbacks
  190. HV_EXPORT void hio_setcb_accept (hio_t* io, haccept_cb accept_cb);
  191. HV_EXPORT void hio_setcb_connect (hio_t* io, hconnect_cb connect_cb);
  192. HV_EXPORT void hio_setcb_read (hio_t* io, hread_cb read_cb);
  193. HV_EXPORT void hio_setcb_write (hio_t* io, hwrite_cb write_cb);
  194. HV_EXPORT void hio_setcb_close (hio_t* io, hclose_cb close_cb);
  195. // some useful settings
  196. // Enable SSL/TLS is so easy :)
  197. HV_EXPORT int hio_enable_ssl(hio_t* io);
  198. // TODO: One loop per thread, one readbuf per loop.
  199. // But you can pass in your own readbuf instead of the default readbuf to avoid memcopy.
  200. HV_EXPORT void hio_set_readbuf(hio_t* io, void* buf, size_t len);
  201. // connect timeout => hclose_cb
  202. HV_EXPORT void hio_set_connect_timeout(hio_t* io, int timeout_ms DEFAULT(HIO_DEFAULT_CONNECT_TIMEOUT));
  203. // close timeout => hclose_cb
  204. HV_EXPORT void hio_set_close_timeout(hio_t* io, int timeout_ms DEFAULT(HIO_DEFAULT_CLOSE_TIMEOUT));
  205. // keepalive timeout => hclose_cb
  206. HV_EXPORT void hio_set_keepalive_timeout(hio_t* io, int timeout_ms DEFAULT(HIO_DEFAULT_KEEPALIVE_TIMEOUT));
  207. /*
  208. void send_heartbeat(hio_t* io) {
  209. static char buf[] = "PING\r\n";
  210. hio_write(io, buf, 6);
  211. }
  212. hio_set_heartbeat(io, 3000, send_heartbeat);
  213. */
  214. typedef void (*hio_send_heartbeat_fn)(hio_t* io);
  215. // heartbeat interval => hio_send_heartbeat_fn
  216. HV_EXPORT void hio_set_heartbeat(hio_t* io, int interval_ms, hio_send_heartbeat_fn fn);
  217. // Nonblocking, poll IO events in the loop to call corresponding callback.
  218. // hio_add(io, HV_READ) => accept => haccept_cb
  219. HV_EXPORT int hio_accept (hio_t* io);
  220. // connect => hio_add(io, HV_WRITE) => hconnect_cb
  221. HV_EXPORT int hio_connect(hio_t* io);
  222. // hio_add(io, HV_READ) => read => hread_cb
  223. HV_EXPORT int hio_read (hio_t* io);
  224. #define hio_read_start(io) hio_read(io)
  225. #define hio_read_stop(io) hio_del(io, HV_READ)
  226. // NOTE: hio_write is thread-safe, locked by recursive_mutex, allow to be called by other threads.
  227. // hio_try_write => hio_add(io, HV_WRITE) => write => hwrite_cb
  228. HV_EXPORT int hio_write (hio_t* io, const void* buf, size_t len);
  229. // NOTE: hio_close is thread-safe, if called by other thread, hloop_post_event(hio_close_event).
  230. // hio_del(io, HV_RDWR) => close => hclose_cb
  231. HV_EXPORT int hio_close (hio_t* io);
  232. //------------------high-level apis-------------------------------------------
  233. // hio_get -> hio_set_readbuf -> hio_setcb_read -> hio_read
  234. HV_EXPORT hio_t* hread (hloop_t* loop, int fd, void* buf, size_t len, hread_cb read_cb);
  235. // hio_get -> hio_setcb_write -> hio_write
  236. HV_EXPORT hio_t* hwrite (hloop_t* loop, int fd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
  237. // hio_get -> hio_close
  238. HV_EXPORT void hclose (hloop_t* loop, int fd);
  239. // tcp
  240. // hio_get -> hio_setcb_accept -> hio_accept
  241. HV_EXPORT hio_t* haccept (hloop_t* loop, int listenfd, haccept_cb accept_cb);
  242. // hio_get -> hio_setcb_connect -> hio_connect
  243. HV_EXPORT hio_t* hconnect (hloop_t* loop, int connfd, hconnect_cb connect_cb);
  244. // hio_get -> hio_set_readbuf -> hio_setcb_read -> hio_read
  245. HV_EXPORT hio_t* hrecv (hloop_t* loop, int connfd, void* buf, size_t len, hread_cb read_cb);
  246. // hio_get -> hio_setcb_write -> hio_write
  247. HV_EXPORT hio_t* hsend (hloop_t* loop, int connfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
  248. // udp
  249. HV_EXPORT void hio_set_type(hio_t* io, hio_type_e type);
  250. HV_EXPORT void hio_set_localaddr(hio_t* io, struct sockaddr* addr, int addrlen);
  251. HV_EXPORT void hio_set_peeraddr (hio_t* io, struct sockaddr* addr, int addrlen);
  252. // NOTE: must call hio_set_peeraddr before hrecvfrom/hsendto
  253. // hio_get -> hio_set_readbuf -> hio_setcb_read -> hio_read
  254. HV_EXPORT hio_t* hrecvfrom (hloop_t* loop, int sockfd, void* buf, size_t len, hread_cb read_cb);
  255. // hio_get -> hio_setcb_write -> hio_write
  256. HV_EXPORT hio_t* hsendto (hloop_t* loop, int sockfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
  257. //-----------------top-level apis---------------------------------------------
  258. // Resolver -> socket -> hio_get
  259. HV_EXPORT hio_t* hio_create(hloop_t* loop, const char* host, int port, int type DEFAULT(SOCK_STREAM));
  260. // @tcp_server: socket -> bind -> listen -> haccept
  261. // @see examples/tcp_echo_server.c
  262. HV_EXPORT hio_t* hloop_create_tcp_server (hloop_t* loop, const char* host, int port, haccept_cb accept_cb);
  263. // @tcp_client: hio_create(loop, host, port, SOCK_STREAM) -> hconnect
  264. // @see examples/nc.c
  265. HV_EXPORT hio_t* hloop_create_tcp_client (hloop_t* loop, const char* host, int port, hconnect_cb connect_cb);
  266. // @udp_server: socket -> bind -> hio_get
  267. // @see examples/udp_echo_server.c
  268. HV_EXPORT hio_t* hloop_create_udp_server (hloop_t* loop, const char* host, int port);
  269. // @udp_client: hio_create(loop, host, port, SOCK_DGRAM)
  270. // @see examples/nc.c
  271. HV_EXPORT hio_t* hloop_create_udp_client (hloop_t* loop, const char* host, int port);
  272. //-----------------upstream---------------------------------------------
  273. // hio_read(io)
  274. // hio_read(io->upstream_io)
  275. HV_EXPORT void hio_read_upstream(hio_t* io);
  276. // hio_write(io->upstream_io, buf, bytes)
  277. HV_EXPORT void hio_write_upstream(hio_t* io, void* buf, int bytes);
  278. // hio_close(io->upstream_io)
  279. HV_EXPORT void hio_close_upstream(hio_t* io);
  280. // io1->upstream_io = io2;
  281. // io2->upstream_io = io1;
  282. // hio_setcb_read(io1, hio_write_upstream);
  283. // hio_setcb_read(io2, hio_write_upstream);
  284. HV_EXPORT void hio_setup_upstream(hio_t* io1, hio_t* io2);
  285. // @return io->upstream_io
  286. HV_EXPORT hio_t* hio_get_upstream(hio_t* io);
  287. // @tcp_upstream: hio_create -> hio_setup_upstream -> hio_setcb_close(hio_close_upstream) -> hconnect -> on_connect -> hio_read_upstream
  288. // @return upstream_io
  289. // @see examples/tcp_proxy_server
  290. HV_EXPORT hio_t* hio_setup_tcp_upstream(hio_t* io, const char* host, int port, int ssl DEFAULT(0));
  291. #define hio_setup_ssl_upstream(io, host, port) hio_setup_tcp_upstream(io, host, port, 1)
  292. // @udp_upstream: hio_create -> hio_setup_upstream -> hio_read_upstream
  293. // @return upstream_io
  294. // @see examples/udp_proxy_server
  295. HV_EXPORT hio_t* hio_setup_udp_upstream(hio_t* io, const char* host, int port);
  296. END_EXTERN_C
  297. #endif // HV_LOOP_H_