hloop.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. #ifndef HV_LOOP_H_
  2. #define HV_LOOP_H_
  3. #include "hexport.h"
  4. #include "hplatform.h"
  5. #include "hdef.h"
  6. #include "hssl.h"
  7. typedef struct hloop_s hloop_t;
  8. typedef struct hevent_s hevent_t;
  9. // NOTE: The following structures are subclasses of hevent_t,
  10. // inheriting hevent_t data members and function members.
  11. typedef struct hio_s hio_t;
  12. typedef struct hidle_s hidle_t;
  13. typedef struct htimer_s htimer_t;
  14. typedef struct htimeout_s htimeout_t;
  15. typedef struct hperiod_s hperiod_t;
  16. typedef struct hevent_s hsignal_t;
  17. typedef void (*hevent_cb) (hevent_t* ev);
  18. typedef void (*hio_cb) (hio_t* io);
  19. typedef void (*hidle_cb) (hidle_t* idle);
  20. typedef void (*htimer_cb) (htimer_t* timer);
  21. typedef void (*hsignal_cb) (hsignal_t* sig);
  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. HLOOP_STATUS_STOP,
  29. HLOOP_STATUS_RUNNING,
  30. HLOOP_STATUS_PAUSE,
  31. HLOOP_STATUS_DESTROY
  32. } hloop_status_e;
  33. typedef enum {
  34. HEVENT_TYPE_NONE = 0,
  35. HEVENT_TYPE_IO = 0x00000001,
  36. HEVENT_TYPE_TIMEOUT = 0x00000010,
  37. HEVENT_TYPE_PERIOD = 0x00000020,
  38. HEVENT_TYPE_TIMER = HEVENT_TYPE_TIMEOUT|HEVENT_TYPE_PERIOD,
  39. HEVENT_TYPE_IDLE = 0x00000100,
  40. HEVENT_TYPE_SIGNAL = 0x00000200,
  41. HEVENT_TYPE_CUSTOM = 0x00000400, // 1024
  42. } hevent_type_e;
  43. #define HEVENT_LOWEST_PRIORITY (-5)
  44. #define HEVENT_LOW_PRIORITY (-3)
  45. #define HEVENT_NORMAL_PRIORITY 0
  46. #define HEVENT_HIGH_PRIORITY 3
  47. #define HEVENT_HIGHEST_PRIORITY 5
  48. #define HEVENT_PRIORITY_SIZE (HEVENT_HIGHEST_PRIORITY-HEVENT_LOWEST_PRIORITY+1)
  49. #define HEVENT_PRIORITY_INDEX(priority) (priority-HEVENT_LOWEST_PRIORITY)
  50. #define HEVENT_FLAGS \
  51. unsigned destroy :1; \
  52. unsigned active :1; \
  53. unsigned pending :1;
  54. #define HEVENT_FIELDS \
  55. hloop_t* loop; \
  56. hevent_type_e event_type; \
  57. uint64_t event_id; \
  58. hevent_cb cb; \
  59. void* userdata; \
  60. void* privdata; \
  61. struct hevent_s* pending_next; \
  62. int priority; \
  63. HEVENT_FLAGS
  64. // sizeof(struct hevent_s)=64 on x64
  65. struct hevent_s {
  66. HEVENT_FIELDS
  67. };
  68. #define hevent_set_id(ev, id) ((hevent_t*)(ev))->event_id = id
  69. #define hevent_set_cb(ev, cb) ((hevent_t*)(ev))->cb = cb
  70. #define hevent_set_priority(ev, prio) ((hevent_t*)(ev))->priority = prio
  71. #define hevent_set_userdata(ev, udata) ((hevent_t*)(ev))->userdata = (void*)udata
  72. #define hevent_loop(ev) (((hevent_t*)(ev))->loop)
  73. #define hevent_type(ev) (((hevent_t*)(ev))->event_type)
  74. #define hevent_id(ev) (((hevent_t*)(ev))->event_id)
  75. #define hevent_cb(ev) (((hevent_t*)(ev))->cb)
  76. #define hevent_priority(ev) (((hevent_t*)(ev))->priority)
  77. #define hevent_userdata(ev) (((hevent_t*)(ev))->userdata)
  78. typedef enum {
  79. HIO_TYPE_UNKNOWN = 0,
  80. HIO_TYPE_STDIN = 0x00000001,
  81. HIO_TYPE_STDOUT = 0x00000002,
  82. HIO_TYPE_STDERR = 0x00000004,
  83. HIO_TYPE_STDIO = 0x0000000F,
  84. HIO_TYPE_FILE = 0x00000010,
  85. HIO_TYPE_PIPE = 0x00000020,
  86. HIO_TYPE_IP = 0x00000100,
  87. HIO_TYPE_SOCK_RAW = 0x00000F00,
  88. HIO_TYPE_UDP = 0x00001000,
  89. HIO_TYPE_KCP = 0x00002000,
  90. HIO_TYPE_DTLS = 0x00010000,
  91. HIO_TYPE_SOCK_DGRAM = 0x000FF000,
  92. HIO_TYPE_TCP = 0x00100000,
  93. HIO_TYPE_SSL = 0x01000000,
  94. HIO_TYPE_TLS = HIO_TYPE_SSL,
  95. HIO_TYPE_SOCK_STREAM= 0x0FF00000,
  96. HIO_TYPE_SOCKET = 0x0FFFFF00,
  97. } hio_type_e;
  98. typedef enum {
  99. HIO_SERVER_SIDE = 0,
  100. HIO_CLIENT_SIDE = 1,
  101. } hio_side_e;
  102. #define HIO_DEFAULT_CONNECT_TIMEOUT 10000 // ms
  103. #define HIO_DEFAULT_CLOSE_TIMEOUT 60000 // ms
  104. #define HIO_DEFAULT_KEEPALIVE_TIMEOUT 75000 // ms
  105. #define HIO_DEFAULT_HEARTBEAT_INTERVAL 10000 // ms
  106. BEGIN_EXTERN_C
  107. // loop
  108. #define HLOOP_FLAG_RUN_ONCE 0x00000001
  109. #define HLOOP_FLAG_AUTO_FREE 0x00000002
  110. #define HLOOP_FLAG_QUIT_WHEN_NO_ACTIVE_EVENTS 0x00000004
  111. HV_EXPORT hloop_t* hloop_new(int flags DEFAULT(HLOOP_FLAG_AUTO_FREE));
  112. // WARN: Forbid to call hloop_free if HLOOP_FLAG_AUTO_FREE set.
  113. HV_EXPORT void hloop_free(hloop_t** pp);
  114. HV_EXPORT int hloop_process_events(hloop_t* loop, int timeout_ms DEFAULT(0));
  115. // NOTE: when no active events, loop will quit if HLOOP_FLAG_QUIT_WHEN_NO_ACTIVE_EVENTS set.
  116. HV_EXPORT int hloop_run(hloop_t* loop);
  117. // NOTE: hloop_stop called in loop-thread just set flag to quit in next loop,
  118. // if called in other thread, it will wakeup loop-thread from blocking poll system call,
  119. // then you should join loop thread to safely exit loop thread.
  120. HV_EXPORT int hloop_stop(hloop_t* loop);
  121. HV_EXPORT int hloop_pause(hloop_t* loop);
  122. HV_EXPORT int hloop_resume(hloop_t* loop);
  123. HV_EXPORT int hloop_wakeup(hloop_t* loop);
  124. HV_EXPORT hloop_status_e hloop_status(hloop_t* loop);
  125. HV_EXPORT void hloop_update_time(hloop_t* loop);
  126. HV_EXPORT uint64_t hloop_now(hloop_t* loop); // s
  127. HV_EXPORT uint64_t hloop_now_ms(hloop_t* loop); // ms
  128. HV_EXPORT uint64_t hloop_now_us(hloop_t* loop); // us
  129. HV_EXPORT uint64_t hloop_now_hrtime(hloop_t* loop); // us
  130. // export some hloop's members
  131. // @return pid of hloop_run
  132. HV_EXPORT long hloop_pid(hloop_t* loop);
  133. // @return tid of hloop_run
  134. HV_EXPORT long hloop_tid(hloop_t* loop);
  135. // @return count of loop
  136. HV_EXPORT uint64_t hloop_count(hloop_t* loop);
  137. // @return number of ios
  138. HV_EXPORT uint32_t hloop_nios(hloop_t* loop);
  139. // @return number of timers
  140. HV_EXPORT uint32_t hloop_ntimers(hloop_t* loop);
  141. // @return number of idles
  142. HV_EXPORT uint32_t hloop_nidles(hloop_t* loop);
  143. // @return number of active events
  144. HV_EXPORT uint32_t hloop_nactives(hloop_t* loop);
  145. // userdata
  146. HV_EXPORT void hloop_set_userdata(hloop_t* loop, void* userdata);
  147. HV_EXPORT void* hloop_userdata(hloop_t* loop);
  148. // custom_event
  149. /*
  150. * hevent_t ev;
  151. * memset(&ev, 0, sizeof(hevent_t));
  152. * ev.event_type = (hevent_type_e)(HEVENT_TYPE_CUSTOM + 1);
  153. * ev.cb = custom_event_cb;
  154. * ev.userdata = userdata;
  155. * hloop_post_event(loop, &ev);
  156. */
  157. // NOTE: hloop_post_event is thread-safe, used to post event from other thread to loop thread.
  158. HV_EXPORT void hloop_post_event(hloop_t* loop, hevent_t* ev);
  159. // signal
  160. HV_EXPORT hsignal_t* hsignal_add(hloop_t* loop, hsignal_cb cb, int signo);
  161. HV_EXPORT void hsignal_del(hsignal_t* sig);
  162. // idle
  163. HV_EXPORT hidle_t* hidle_add(hloop_t* loop, hidle_cb cb, uint32_t repeat DEFAULT(INFINITE));
  164. HV_EXPORT void hidle_del(hidle_t* idle);
  165. // timer
  166. HV_EXPORT htimer_t* htimer_add(hloop_t* loop, htimer_cb cb, uint32_t timeout_ms, uint32_t repeat DEFAULT(INFINITE));
  167. /*
  168. * minute hour day week month cb
  169. * 0~59 0~23 1~31 0~6 1~12
  170. * -1 -1 -1 -1 -1 cron.minutely
  171. * 30 -1 -1 -1 -1 cron.hourly
  172. * 30 1 -1 -1 -1 cron.daily
  173. * 30 1 15 -1 -1 cron.monthly
  174. * 30 1 -1 5 -1 cron.weekly
  175. * 30 1 1 -1 10 cron.yearly
  176. */
  177. HV_EXPORT htimer_t* htimer_add_period(hloop_t* loop, htimer_cb cb,
  178. int8_t minute DEFAULT(0), int8_t hour DEFAULT(-1), int8_t day DEFAULT(-1),
  179. int8_t week DEFAULT(-1), int8_t month DEFAULT(-1), uint32_t repeat DEFAULT(INFINITE));
  180. HV_EXPORT void htimer_del(htimer_t* timer);
  181. HV_EXPORT void htimer_reset(htimer_t* timer, uint32_t timeout_ms DEFAULT(0));
  182. // io
  183. //-----------------------low-level apis---------------------------------------
  184. #define HV_READ 0x0001
  185. #define HV_WRITE 0x0004
  186. #define HV_RDWR (HV_READ|HV_WRITE)
  187. /*
  188. const char* hio_engine() {
  189. #ifdef EVENT_SELECT
  190. return "select";
  191. #elif defined(EVENT_POLL)
  192. return "poll";
  193. #elif defined(EVENT_EPOLL)
  194. return "epoll";
  195. #elif defined(EVENT_KQUEUE)
  196. return "kqueue";
  197. #elif defined(EVENT_IOCP)
  198. return "iocp";
  199. #elif defined(EVENT_PORT)
  200. return "evport";
  201. #else
  202. return "noevent";
  203. #endif
  204. }
  205. */
  206. HV_EXPORT const char* hio_engine();
  207. HV_EXPORT hio_t* hio_get(hloop_t* loop, int fd);
  208. HV_EXPORT int hio_add(hio_t* io, hio_cb cb, int events DEFAULT(HV_READ));
  209. HV_EXPORT int hio_del(hio_t* io, int events DEFAULT(HV_RDWR));
  210. // NOTE: io detach from old loop and attach to new loop
  211. /* @see examples/multi-thread/one-acceptor-multi-workers.c
  212. void new_conn_event(hevent_t* ev) {
  213. hloop_t* loop = ev->loop;
  214. hio_t* io = (hio_t*)hevent_userdata(ev);
  215. hio_attach(loop, io);
  216. }
  217. void on_accpet(hio_t* io) {
  218. hio_detach(io);
  219. hloop_t* worker_loop = get_one_loop();
  220. hevent_t ev;
  221. memset(&ev, 0, sizeof(ev));
  222. ev.loop = worker_loop;
  223. ev.cb = new_conn_event;
  224. ev.userdata = io;
  225. hloop_post_event(worker_loop, &ev);
  226. }
  227. */
  228. HV_EXPORT void hio_detach(/*hloop_t* loop,*/ hio_t* io);
  229. HV_EXPORT void hio_attach(hloop_t* loop, hio_t* io);
  230. HV_EXPORT bool hio_exists(hloop_t* loop, int fd);
  231. // hio_t fields
  232. // NOTE: fd cannot be used as unique identifier, so we provide an id.
  233. HV_EXPORT uint32_t hio_id (hio_t* io);
  234. HV_EXPORT int hio_fd (hio_t* io);
  235. HV_EXPORT int hio_error (hio_t* io);
  236. HV_EXPORT int hio_events (hio_t* io);
  237. HV_EXPORT int hio_revents (hio_t* io);
  238. HV_EXPORT hio_type_e hio_type (hio_t* io);
  239. HV_EXPORT struct sockaddr* hio_localaddr(hio_t* io);
  240. HV_EXPORT struct sockaddr* hio_peeraddr (hio_t* io);
  241. HV_EXPORT void hio_set_context(hio_t* io, void* ctx);
  242. HV_EXPORT void* hio_context(hio_t* io);
  243. HV_EXPORT bool hio_is_opened(hio_t* io);
  244. HV_EXPORT bool hio_is_connected(hio_t* io);
  245. HV_EXPORT bool hio_is_closed(hio_t* io);
  246. // iobuf
  247. // #include "hbuf.h"
  248. typedef struct fifo_buf_s hio_readbuf_t;
  249. // NOTE: One loop per thread, one readbuf per loop.
  250. // But you can pass in your own readbuf instead of the default readbuf to avoid memcopy.
  251. HV_EXPORT void hio_set_readbuf(hio_t* io, void* buf, size_t len);
  252. HV_EXPORT hio_readbuf_t* hio_get_readbuf(hio_t* io);
  253. HV_EXPORT void hio_set_max_read_bufsize (hio_t* io, uint32_t size);
  254. HV_EXPORT void hio_set_max_write_bufsize(hio_t* io, uint32_t size);
  255. // NOTE: hio_write is non-blocking, so there is a write queue inside hio_t to cache unwritten data and wait for writable.
  256. // @return current buffer size of write queue.
  257. HV_EXPORT size_t hio_write_bufsize(hio_t* io);
  258. #define hio_write_is_complete(io) (hio_write_bufsize(io) == 0)
  259. HV_EXPORT uint64_t hio_last_read_time(hio_t* io); // ms
  260. HV_EXPORT uint64_t hio_last_write_time(hio_t* io); // ms
  261. // set callbacks
  262. HV_EXPORT void hio_setcb_accept (hio_t* io, haccept_cb accept_cb);
  263. HV_EXPORT void hio_setcb_connect (hio_t* io, hconnect_cb connect_cb);
  264. HV_EXPORT void hio_setcb_read (hio_t* io, hread_cb read_cb);
  265. HV_EXPORT void hio_setcb_write (hio_t* io, hwrite_cb write_cb);
  266. HV_EXPORT void hio_setcb_close (hio_t* io, hclose_cb close_cb);
  267. // get callbacks
  268. HV_EXPORT haccept_cb hio_getcb_accept(hio_t* io);
  269. HV_EXPORT hconnect_cb hio_getcb_connect(hio_t* io);
  270. HV_EXPORT hread_cb hio_getcb_read(hio_t* io);
  271. HV_EXPORT hwrite_cb hio_getcb_write(hio_t* io);
  272. HV_EXPORT hclose_cb hio_getcb_close(hio_t* io);
  273. // Enable SSL/TLS is so easy :)
  274. HV_EXPORT int hio_enable_ssl(hio_t* io);
  275. HV_EXPORT bool hio_is_ssl(hio_t* io);
  276. HV_EXPORT int hio_set_ssl (hio_t* io, hssl_t ssl);
  277. HV_EXPORT int hio_set_ssl_ctx(hio_t* io, hssl_ctx_t ssl_ctx);
  278. // hssl_ctx_new(opt) -> hio_set_ssl_ctx
  279. HV_EXPORT int hio_new_ssl_ctx(hio_t* io, hssl_ctx_opt_t* opt);
  280. HV_EXPORT hssl_t hio_get_ssl(hio_t* io);
  281. HV_EXPORT hssl_ctx_t hio_get_ssl_ctx(hio_t* io);
  282. // for hssl_set_sni_hostname
  283. HV_EXPORT int hio_set_hostname(hio_t* io, const char* hostname);
  284. HV_EXPORT const char* hio_get_hostname(hio_t* io);
  285. // connect timeout => hclose_cb
  286. HV_EXPORT void hio_set_connect_timeout(hio_t* io, int timeout_ms DEFAULT(HIO_DEFAULT_CONNECT_TIMEOUT));
  287. // close timeout => hclose_cb
  288. HV_EXPORT void hio_set_close_timeout(hio_t* io, int timeout_ms DEFAULT(HIO_DEFAULT_CLOSE_TIMEOUT));
  289. // read timeout => hclose_cb
  290. HV_EXPORT void hio_set_read_timeout(hio_t* io, int timeout_ms);
  291. // write timeout => hclose_cb
  292. HV_EXPORT void hio_set_write_timeout(hio_t* io, int timeout_ms);
  293. // keepalive timeout => hclose_cb
  294. HV_EXPORT void hio_set_keepalive_timeout(hio_t* io, int timeout_ms DEFAULT(HIO_DEFAULT_KEEPALIVE_TIMEOUT));
  295. /*
  296. void send_heartbeat(hio_t* io) {
  297. static char buf[] = "PING\r\n";
  298. hio_write(io, buf, 6);
  299. }
  300. hio_set_heartbeat(io, 3000, send_heartbeat);
  301. */
  302. typedef void (*hio_send_heartbeat_fn)(hio_t* io);
  303. // heartbeat interval => hio_send_heartbeat_fn
  304. HV_EXPORT void hio_set_heartbeat(hio_t* io, int interval_ms, hio_send_heartbeat_fn fn);
  305. // Nonblocking, poll IO events in the loop to call corresponding callback.
  306. // hio_add(io, HV_READ) => accept => haccept_cb
  307. HV_EXPORT int hio_accept (hio_t* io);
  308. // connect => hio_add(io, HV_WRITE) => hconnect_cb
  309. HV_EXPORT int hio_connect(hio_t* io);
  310. // hio_add(io, HV_READ) => read => hread_cb
  311. HV_EXPORT int hio_read (hio_t* io);
  312. #define hio_read_start(io) hio_read(io)
  313. #define hio_read_stop(io) hio_del(io, HV_READ)
  314. // hio_read_start => hread_cb => hio_read_stop
  315. HV_EXPORT int hio_read_once (hio_t* io);
  316. // hio_read_once => hread_cb(len)
  317. HV_EXPORT int hio_read_until_length(hio_t* io, unsigned int len);
  318. // hio_read_once => hread_cb(...delim)
  319. HV_EXPORT int hio_read_until_delim (hio_t* io, unsigned char delim);
  320. HV_EXPORT int hio_read_remain(hio_t* io);
  321. // @see examples/tinyhttpd.c examples/tinyproxyd.c
  322. #define hio_readline(io) hio_read_until_delim(io, '\n')
  323. #define hio_readstring(io) hio_read_until_delim(io, '\0')
  324. #define hio_readbytes(io, len) hio_read_until_length(io, len)
  325. #define hio_read_until(io, len) hio_read_until_length(io, len)
  326. // NOTE: hio_write is thread-safe, locked by recursive_mutex, allow to be called by other threads.
  327. // hio_try_write => hio_add(io, HV_WRITE) => write => hwrite_cb
  328. HV_EXPORT int hio_write (hio_t* io, const void* buf, size_t len);
  329. HV_EXPORT int hio_sendto (hio_t* io, const void* buf, size_t len, struct sockaddr* addr);
  330. // NOTE: hio_close is thread-safe, hio_close_async will be called actually in other thread.
  331. // hio_del(io, HV_RDWR) => close => hclose_cb
  332. HV_EXPORT int hio_close (hio_t* io);
  333. // NOTE: hloop_post_event(hio_close_event)
  334. HV_EXPORT int hio_close_async(hio_t* io);
  335. //------------------high-level apis-------------------------------------------
  336. // hio_get -> hio_set_readbuf -> hio_setcb_read -> hio_read
  337. HV_EXPORT hio_t* hread (hloop_t* loop, int fd, void* buf, size_t len, hread_cb read_cb);
  338. // hio_get -> hio_setcb_write -> hio_write
  339. HV_EXPORT hio_t* hwrite (hloop_t* loop, int fd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
  340. // hio_get -> hio_close
  341. HV_EXPORT void hclose (hloop_t* loop, int fd);
  342. // tcp
  343. // hio_get -> hio_setcb_accept -> hio_accept
  344. HV_EXPORT hio_t* haccept (hloop_t* loop, int listenfd, haccept_cb accept_cb);
  345. // hio_get -> hio_setcb_connect -> hio_connect
  346. HV_EXPORT hio_t* hconnect (hloop_t* loop, int connfd, hconnect_cb connect_cb);
  347. // hio_get -> hio_set_readbuf -> hio_setcb_read -> hio_read
  348. HV_EXPORT hio_t* hrecv (hloop_t* loop, int connfd, void* buf, size_t len, hread_cb read_cb);
  349. // hio_get -> hio_setcb_write -> hio_write
  350. HV_EXPORT hio_t* hsend (hloop_t* loop, int connfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
  351. // udp
  352. HV_EXPORT void hio_set_type(hio_t* io, hio_type_e type);
  353. HV_EXPORT void hio_set_localaddr(hio_t* io, struct sockaddr* addr, int addrlen);
  354. HV_EXPORT void hio_set_peeraddr (hio_t* io, struct sockaddr* addr, int addrlen);
  355. // NOTE: must call hio_set_peeraddr before hrecvfrom/hsendto
  356. // hio_get -> hio_set_readbuf -> hio_setcb_read -> hio_read
  357. HV_EXPORT hio_t* hrecvfrom (hloop_t* loop, int sockfd, void* buf, size_t len, hread_cb read_cb);
  358. // hio_get -> hio_setcb_write -> hio_write
  359. HV_EXPORT hio_t* hsendto (hloop_t* loop, int sockfd, const void* buf, size_t len, hwrite_cb write_cb DEFAULT(NULL));
  360. //-----------------top-level apis---------------------------------------------
  361. // @hio_create_socket: socket -> bind -> listen
  362. // sockaddr_set_ipport -> socket -> hio_get(loop, sockfd) ->
  363. // side == HIO_SERVER_SIDE ? bind ->
  364. // type & HIO_TYPE_SOCK_STREAM ? listen ->
  365. HV_EXPORT hio_t* hio_create_socket(hloop_t* loop, const char* host, int port,
  366. hio_type_e type DEFAULT(HIO_TYPE_TCP),
  367. hio_side_e side DEFAULT(HIO_SERVER_SIDE));
  368. // @tcp_server: hio_create_socket(loop, host, port, HIO_TYPE_TCP, HIO_SERVER_SIDE) -> hio_setcb_accept -> hio_accept
  369. // @see examples/tcp_echo_server.c
  370. HV_EXPORT hio_t* hloop_create_tcp_server (hloop_t* loop, const char* host, int port, haccept_cb accept_cb);
  371. // @tcp_client: hio_create_socket(loop, host, port, HIO_TYPE_TCP, HIO_CLIENT_SIDE) -> hio_setcb_connect -> hio_setcb_close -> hio_connect
  372. // @see examples/nc.c
  373. HV_EXPORT hio_t* hloop_create_tcp_client (hloop_t* loop, const char* host, int port, hconnect_cb connect_cb, hclose_cb close_cb);
  374. // @ssl_server: hio_create_socket(loop, host, port, HIO_TYPE_SSL, HIO_SERVER_SIDE) -> hio_setcb_accept -> hio_accept
  375. // @see examples/tcp_echo_server.c => #define TEST_SSL 1
  376. HV_EXPORT hio_t* hloop_create_ssl_server (hloop_t* loop, const char* host, int port, haccept_cb accept_cb);
  377. // @ssl_client: hio_create_socket(loop, host, port, HIO_TYPE_SSL, HIO_CLIENT_SIDE) -> hio_setcb_connect -> hio_setcb_close -> hio_connect
  378. // @see examples/nc.c => #define TEST_SSL 1
  379. HV_EXPORT hio_t* hloop_create_ssl_client (hloop_t* loop, const char* host, int port, hconnect_cb connect_cb, hclose_cb close_cb);
  380. // @udp_server: hio_create_socket(loop, host, port, HIO_TYPE_UDP, HIO_SERVER_SIDE)
  381. // @see examples/udp_echo_server.c
  382. HV_EXPORT hio_t* hloop_create_udp_server (hloop_t* loop, const char* host, int port);
  383. // @udp_server: hio_create_socket(loop, host, port, HIO_TYPE_UDP, HIO_CLIENT_SIDE)
  384. // @see examples/nc.c
  385. HV_EXPORT hio_t* hloop_create_udp_client (hloop_t* loop, const char* host, int port);
  386. //-----------------pipe---------------------------------------------
  387. // @see examples/pipe_test.c
  388. HV_EXPORT int hio_create_pipe(hloop_t* loop, hio_t* pipeio[2]);
  389. //-----------------upstream---------------------------------------------
  390. // hio_read(io)
  391. // hio_read(io->upstream_io)
  392. HV_EXPORT void hio_read_upstream(hio_t* io);
  393. // on_write(io) -> hio_write_is_complete(io) -> hio_read(io->upstream_io)
  394. HV_EXPORT void hio_read_upstream_on_write_complete(hio_t* io, const void* buf, int writebytes);
  395. // hio_write(io->upstream_io, buf, bytes)
  396. HV_EXPORT void hio_write_upstream(hio_t* io, void* buf, int bytes);
  397. // hio_close(io->upstream_io)
  398. HV_EXPORT void hio_close_upstream(hio_t* io);
  399. // io1->upstream_io = io2;
  400. // io2->upstream_io = io1;
  401. // @see examples/socks5_proxy_server.c
  402. HV_EXPORT void hio_setup_upstream(hio_t* io1, hio_t* io2);
  403. // @return io->upstream_io
  404. HV_EXPORT hio_t* hio_get_upstream(hio_t* io);
  405. // @tcp_upstream: hio_create_socket -> hio_setup_upstream -> hio_connect -> on_connect -> hio_read_upstream
  406. // @return upstream_io
  407. // @see examples/tcp_proxy_server.c
  408. HV_EXPORT hio_t* hio_setup_tcp_upstream(hio_t* io, const char* host, int port, int ssl DEFAULT(0));
  409. #define hio_setup_ssl_upstream(io, host, port) hio_setup_tcp_upstream(io, host, port, 1)
  410. // @udp_upstream: hio_create_socket -> hio_setup_upstream -> hio_read_upstream
  411. // @return upstream_io
  412. // @see examples/udp_proxy_server.c
  413. HV_EXPORT hio_t* hio_setup_udp_upstream(hio_t* io, const char* host, int port);
  414. //-----------------unpack---------------------------------------------
  415. typedef enum {
  416. UNPACK_MODE_NONE = 0,
  417. UNPACK_BY_FIXED_LENGTH = 1, // Not recommended
  418. UNPACK_BY_DELIMITER = 2, // Suitable for text protocol
  419. UNPACK_BY_LENGTH_FIELD = 3, // Suitable for binary protocol
  420. } unpack_mode_e;
  421. #define DEFAULT_PACKAGE_MAX_LENGTH (1 << 21) // 2M
  422. // UNPACK_BY_DELIMITER
  423. #define PACKAGE_MAX_DELIMITER_BYTES 8
  424. // UNPACK_BY_LENGTH_FIELD
  425. typedef enum {
  426. ENCODE_BY_VARINT = 17, // 1 MSB + 7 bits
  427. ENCODE_BY_LITTEL_ENDIAN = LITTLE_ENDIAN, // 1234
  428. ENCODE_BY_BIG_ENDIAN = BIG_ENDIAN, // 4321
  429. } unpack_coding_e;
  430. typedef struct unpack_setting_s {
  431. unpack_mode_e mode;
  432. unsigned int package_max_length;
  433. union {
  434. // UNPACK_BY_FIXED_LENGTH
  435. struct {
  436. unsigned int fixed_length;
  437. };
  438. // UNPACK_BY_DELIMITER
  439. struct {
  440. unsigned char delimiter[PACKAGE_MAX_DELIMITER_BYTES];
  441. unsigned short delimiter_bytes;
  442. };
  443. /*
  444. * UNPACK_BY_LENGTH_FIELD
  445. *
  446. * package_len = head_len + body_len + length_adjustment
  447. *
  448. * if (length_field_coding == ENCODE_BY_VARINT) head_len = body_offset + varint_bytes - length_field_bytes;
  449. * else head_len = body_offset;
  450. *
  451. * length_field stores body length, exclude head length,
  452. * if length_field = head_len + body_len, then length_adjustment should be set to -head_len.
  453. *
  454. */
  455. struct {
  456. unsigned short body_offset; // Equal to head length usually
  457. unsigned short length_field_offset;
  458. unsigned short length_field_bytes;
  459. short length_adjustment;
  460. unpack_coding_e length_field_coding;
  461. };
  462. };
  463. #ifdef __cplusplus
  464. unpack_setting_s() {
  465. // Recommended setting:
  466. // head = flags:1byte + length:4bytes = 5bytes
  467. mode = UNPACK_BY_LENGTH_FIELD;
  468. package_max_length = DEFAULT_PACKAGE_MAX_LENGTH;
  469. fixed_length = 0;
  470. delimiter_bytes = 0;
  471. body_offset = 5;
  472. length_field_offset = 1;
  473. length_field_bytes = 4;
  474. length_field_coding = ENCODE_BY_BIG_ENDIAN;
  475. length_adjustment = 0;
  476. }
  477. #endif
  478. } unpack_setting_t;
  479. /*
  480. * @see examples/jsonrpc examples/protorpc
  481. *
  482. * NOTE: unpack_setting_t of multiple IOs of the same function also are same,
  483. * so only the pointer of unpack_setting_t is stored in hio_t,
  484. * the life time of unpack_setting_t shoud be guaranteed by caller.
  485. */
  486. HV_EXPORT void hio_set_unpack(hio_t* io, unpack_setting_t* setting);
  487. HV_EXPORT void hio_unset_unpack(hio_t* io);
  488. // unpack examples
  489. /*
  490. unpack_setting_t ftp_unpack_setting;
  491. memset(&ftp_unpack_setting, 0, sizeof(unpack_setting_t));
  492. ftp_unpack_setting.package_max_length = DEFAULT_PACKAGE_MAX_LENGTH;
  493. ftp_unpack_setting.mode = UNPACK_BY_DELIMITER;
  494. ftp_unpack_setting.delimiter[0] = '\r';
  495. ftp_unpack_setting.delimiter[1] = '\n';
  496. ftp_unpack_setting.delimiter_bytes = 2;
  497. unpack_setting_t mqtt_unpack_setting = {
  498. .mode = UNPACK_BY_LENGTH_FIELD,
  499. .package_max_length = DEFAULT_PACKAGE_MAX_LENGTH,
  500. .body_offset = 2,
  501. .length_field_offset = 1,
  502. .length_field_bytes = 1,
  503. .length_field_coding = ENCODE_BY_VARINT,
  504. };
  505. unpack_setting_t grpc_unpack_setting = {
  506. .mode = UNPACK_BY_LENGTH_FIELD,
  507. .package_max_length = DEFAULT_PACKAGE_MAX_LENGTH,
  508. .body_offset = 5,
  509. .length_field_offset = 1,
  510. .length_field_bytes = 4,
  511. .length_field_coding = ENCODE_BY_BIG_ENDIAN,
  512. };
  513. */
  514. //-----------------reconnect----------------------------------------
  515. #define DEFAULT_RECONNECT_MIN_DELAY 1000 // ms
  516. #define DEFAULT_RECONNECT_MAX_DELAY 60000 // ms
  517. #define DEFAULT_RECONNECT_DELAY_POLICY 2 // exponential
  518. #define DEFAULT_RECONNECT_MAX_RETRY_CNT INFINITE
  519. typedef struct reconn_setting_s {
  520. uint32_t min_delay; // ms
  521. uint32_t max_delay; // ms
  522. uint32_t cur_delay; // ms
  523. /*
  524. * @delay_policy
  525. * 0: fixed
  526. * min_delay=3s => 3,3,3...
  527. * 1: linear
  528. * min_delay=3s max_delay=10s => 3,6,9,10,10...
  529. * other: exponential
  530. * min_delay=3s max_delay=60s delay_policy=2 => 3,6,12,24,48,60,60...
  531. */
  532. uint32_t delay_policy;
  533. uint32_t max_retry_cnt;
  534. uint32_t cur_retry_cnt;
  535. #ifdef __cplusplus
  536. reconn_setting_s() {
  537. min_delay = DEFAULT_RECONNECT_MIN_DELAY;
  538. max_delay = DEFAULT_RECONNECT_MAX_DELAY;
  539. cur_delay = 0;
  540. // 1,2,4,8,16,32,60,60...
  541. delay_policy = DEFAULT_RECONNECT_DELAY_POLICY;
  542. max_retry_cnt = DEFAULT_RECONNECT_MAX_RETRY_CNT;
  543. cur_retry_cnt = 0;
  544. }
  545. #endif
  546. } reconn_setting_t;
  547. HV_INLINE void reconn_setting_init(reconn_setting_t* reconn) {
  548. reconn->min_delay = DEFAULT_RECONNECT_MIN_DELAY;
  549. reconn->max_delay = DEFAULT_RECONNECT_MAX_DELAY;
  550. reconn->cur_delay = 0;
  551. // 1,2,4,8,16,32,60,60...
  552. reconn->delay_policy = DEFAULT_RECONNECT_DELAY_POLICY;
  553. reconn->max_retry_cnt = DEFAULT_RECONNECT_MAX_RETRY_CNT;
  554. reconn->cur_retry_cnt = 0;
  555. }
  556. HV_INLINE void reconn_setting_reset(reconn_setting_t* reconn) {
  557. reconn->cur_delay = 0;
  558. reconn->cur_retry_cnt = 0;
  559. }
  560. HV_INLINE bool reconn_setting_can_retry(reconn_setting_t* reconn) {
  561. ++reconn->cur_retry_cnt;
  562. return reconn->max_retry_cnt == INFINITE ||
  563. reconn->cur_retry_cnt <= reconn->max_retry_cnt;
  564. }
  565. HV_INLINE uint32_t reconn_setting_calc_delay(reconn_setting_t* reconn) {
  566. if (reconn->delay_policy == 0) {
  567. // fixed
  568. reconn->cur_delay = reconn->min_delay;
  569. } else if (reconn->delay_policy == 1) {
  570. // linear
  571. reconn->cur_delay += reconn->min_delay;
  572. } else {
  573. // exponential
  574. reconn->cur_delay *= reconn->delay_policy;
  575. }
  576. reconn->cur_delay = MAX(reconn->cur_delay, reconn->min_delay);
  577. reconn->cur_delay = MIN(reconn->cur_delay, reconn->max_delay);
  578. return reconn->cur_delay;
  579. }
  580. //-----------------LoadBalance-------------------------------------
  581. typedef enum {
  582. LB_RoundRobin,
  583. LB_Random,
  584. LB_LeastConnections,
  585. LB_IpHash,
  586. LB_UrlHash,
  587. } load_balance_e;
  588. //-----------------rudp---------------------------------------------
  589. #if WITH_KCP
  590. #define WITH_RUDP 1
  591. #endif
  592. #if WITH_RUDP
  593. // NOTE: hio_close_rudp is thread-safe.
  594. HV_EXPORT int hio_close_rudp(hio_t* io, struct sockaddr* peeraddr DEFAULT(NULL));
  595. #endif
  596. #if WITH_KCP
  597. typedef struct kcp_setting_s {
  598. // ikcp_create(conv, ...)
  599. unsigned int conv;
  600. // ikcp_nodelay(kcp, nodelay, interval, fastresend, nocwnd)
  601. int nodelay;
  602. int interval;
  603. int fastresend;
  604. int nocwnd;
  605. // ikcp_wndsize(kcp, sndwnd, rcvwnd)
  606. int sndwnd;
  607. int rcvwnd;
  608. // ikcp_setmtu(kcp, mtu)
  609. int mtu;
  610. // ikcp_update
  611. int update_interval;
  612. #ifdef __cplusplus
  613. kcp_setting_s() {
  614. conv = 0x11223344;
  615. // normal mode
  616. nodelay = 0;
  617. interval = 40;
  618. fastresend = 0;
  619. nocwnd = 0;
  620. // fast mode
  621. // nodelay = 1;
  622. // interval = 10;
  623. // fastresend = 2;
  624. // nocwnd = 1;
  625. sndwnd = 0;
  626. rcvwnd = 0;
  627. mtu = 1400;
  628. update_interval = 10; // ms
  629. }
  630. #endif
  631. } kcp_setting_t;
  632. HV_INLINE void kcp_setting_init_with_normal_mode(kcp_setting_t* setting) {
  633. memset(setting, 0, sizeof(kcp_setting_t));
  634. setting->nodelay = 0;
  635. setting->interval = 40;
  636. setting->fastresend = 0;
  637. setting->nocwnd = 0;
  638. }
  639. HV_INLINE void kcp_setting_init_with_fast_mode(kcp_setting_t* setting) {
  640. memset(setting, 0, sizeof(kcp_setting_t));
  641. setting->nodelay = 0;
  642. setting->interval = 30;
  643. setting->fastresend = 2;
  644. setting->nocwnd = 1;
  645. }
  646. HV_INLINE void kcp_setting_init_with_fast2_mode(kcp_setting_t* setting) {
  647. memset(setting, 0, sizeof(kcp_setting_t));
  648. setting->nodelay = 1;
  649. setting->interval = 20;
  650. setting->fastresend = 2;
  651. setting->nocwnd = 1;
  652. }
  653. HV_INLINE void kcp_setting_init_with_fast3_mode(kcp_setting_t* setting) {
  654. memset(setting, 0, sizeof(kcp_setting_t));
  655. setting->nodelay = 1;
  656. setting->interval = 10;
  657. setting->fastresend = 2;
  658. setting->nocwnd = 1;
  659. }
  660. // @see examples/udp_echo_server.c => #define TEST_KCP 1
  661. HV_EXPORT int hio_set_kcp(hio_t* io, kcp_setting_t* setting DEFAULT(NULL));
  662. #endif
  663. END_EXTERN_C
  664. #endif // HV_LOOP_H_