ioqueue.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. #ifndef IOQUEUE_H
  2. #define IOQUEUE_H
  3. #pragma once
  4. #include "config.h"
  5. #include <winpr/winsock.h>
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. #include <stddef.h>
  10. #include "timerqueue.h"
  11. #include "list.h"
  12. #include "spinlock.h"
  13. ////////////////////////////////////////////////////////////////////////////////////////////////
  14. // ioqueue
  15. //
  16. // support:
  17. // (1) user message queue
  18. // (2) timer
  19. // (3) proactor network framework
  20. /**
  21. * opaque structure for io queue
  22. */
  23. typedef struct ioqueue_t ioqueue_t;
  24. /**
  25. * @return return non-zero means need continue processing
  26. */
  27. typedef int (*ioqueue_on_msg_callback)(unsigned short msg_id, int param1, int param2);
  28. #define MAX_MSG 1024
  29. #define MAX_MSG_PRIORITY 32
  30. /**
  31. * create io queue
  32. * @param ioq [out] pointer to ioqueue_t structure
  33. * @return NULL failed
  34. */
  35. TOOLKIT_API ioqueue_t *ioqueue_create();
  36. /**
  37. * destroy io queue
  38. */
  39. TOOLKIT_API void ioqueue_destroy(ioqueue_t *ioq);
  40. /**
  41. * is all handler closed ?
  42. */
  43. TOOLKIT_API int ioqueue_handler_empty(ioqueue_t *ioq);
  44. /** is all pending msg procceed ? */
  45. TOOLKIT_API int ioqueue_msg_empty(ioqueue_t *ioq);
  46. /** detect whether can exit */
  47. static int __inline ioqueue_can_exit(ioqueue_t *ioq)
  48. {
  49. return ioqueue_handler_empty(ioq) && ioqueue_msg_empty(ioq);
  50. }
  51. /**
  52. * set user cutomized data
  53. * @return the old user_data value
  54. */
  55. TOOLKIT_API void *ioqueue_set_user_data(ioqueue_t *ioq, void* user_data);
  56. /**
  57. * get user cutomized data
  58. */
  59. TOOLKIT_API void *ioqueue_get_user_data(ioqueue_t *ioq);
  60. /**
  61. * poll io queue for dispatching events
  62. * @param timeout time out value for a poll operation
  63. * @return number of events dispatched
  64. */
  65. TOOLKIT_API int ioqueue_poll(ioqueue_t *ioq, int timeout);
  66. /**
  67. * stop
  68. */
  69. TOOLKIT_API void ioqueue_stop(ioqueue_t *ioq);
  70. /**
  71. * register a message handler for msg_type
  72. * @param msg_type message type identifier [0, 1024)
  73. * @param priority [0,32), the lower value means this cb will be invoked first while processing msgs of msg_id
  74. * @return -1 failed, 0 success
  75. */
  76. TOOLKIT_API int ioqueue_msg_add_handler(ioqueue_t *ioq, int msg_type, int priority, ioqueue_on_msg_callback cb);
  77. /**
  78. * unregister a message handler for msg_type
  79. */
  80. TOOLKIT_API int ioqueue_msg_remove_handler(ioqueue_t *ioq, int msg_type, int priority);
  81. /**
  82. * post user message
  83. */
  84. TOOLKIT_API int ioqueue_post_message(ioqueue_t *ioq, int msg_type, int param1, int param2);
  85. /**
  86. * send message, synchronous operation
  87. */
  88. TOOLKIT_API int ioqueue_send_message(ioqueue_t *ioq, int msg_type, int param1, int param2);
  89. /**
  90. * cancel all message with msg_type
  91. */
  92. // int ioqueue_cancel_message(ioqueue_t *ioq, int msg_type);
  93. /**
  94. * start a timer invoked at now() + delay
  95. * @param entry the entry to schedule
  96. * @param delay time value to delay, in milliseconds
  97. * @return 0 success, -1 failed
  98. */
  99. TOOLKIT_API int ioqueue_timer_schedule(ioqueue_t *ioq, timer_entry *entry, unsigned int delay);
  100. /**
  101. * cancel a timer
  102. * @param entry timer entry that has been scheduled
  103. * @param cancel if cancel successful if invoke timer with error = -1?
  104. * @return 0 cancel ok, -1 failed
  105. */
  106. TOOLKIT_API int ioqueue_timer_cancel(ioqueue_t *ioq, timer_entry *entry, int cancel);
  107. ////////////////////////////////////////////////////////////////////////////////////////////////
  108. // acceptor
  109. typedef struct ioqueue_handle_context { /* do not access directly */
  110. struct list_head node;
  111. int type;
  112. union {
  113. HANDLE file;
  114. SOCKET sock;
  115. char *pipe_name;
  116. }u;
  117. void *user_data;
  118. ioqueue_t *owner;
  119. LONG pending_ios;
  120. lock_t ov_pending_list_lock;
  121. struct list_head ov_pending_list;
  122. }ioqueue_handle_context;
  123. typedef struct ioqueue_handle_context ioqueue_udpsock_t;
  124. typedef struct ioqueue_handle_context ioqueue_tcpsock_t;
  125. typedef struct ioqueue_handle_context ioqueue_acceptor_t;
  126. typedef struct ioqueue_handle_context ioqueue_file_t;
  127. typedef struct ioqueue_handle_context ioqueue_pipe_acceptor_t;
  128. typedef struct ioqueue_overlapped_t { /* do not access directly */
  129. void* __internal[32];
  130. }ioqueue_overlapped_t;
  131. /**
  132. * callback while new client connects in
  133. * @param user_data pass from async_accept
  134. * @param in_sock client socket, if you dont need this socket,
  135. * no need to call closesocket on it, just return zero!!!
  136. * @param err -1 on failed, 0 on success
  137. * @return non-zero means accept, zero reject
  138. */
  139. typedef int (*ioqueue_on_accept_callback)(ioqueue_acceptor_t *acceptor,
  140. ioqueue_overlapped_t *overlapped,
  141. SOCKET in_sock,
  142. void *user_data,
  143. int err);
  144. /**
  145. * create a new acceptor(TCP only)
  146. * @param [in] ioq io queue pointer
  147. * @param [in] ip service ip address
  148. * @param [in] port service port
  149. * @param [out] acceptor pointer to result structure
  150. * @return 0 success, -1 failed
  151. */
  152. TOOLKIT_API int ioqueue_acceptor_create(ioqueue_t *ioq,
  153. const char *ip,
  154. unsigned short port,
  155. ioqueue_acceptor_t* acceptor);
  156. /**
  157. * destory an acceptor
  158. */
  159. TOOLKIT_API void ioqueue_acceptor_destroy(ioqueue_acceptor_t *acceptor);
  160. /** close socket handler, so all pending async operation can be aborted */
  161. TOOLKIT_API void ioqueue_acceptor_close(ioqueue_acceptor_t* acceptor);
  162. /**
  163. * listen
  164. * @return 0 ok, -1 failed
  165. */
  166. TOOLKIT_API int ioqueue_acceptor_listen(ioqueue_acceptor_t* acceptor, int backlog);
  167. /**
  168. * get raw socket handler
  169. */
  170. TOOLKIT_API SOCKET ioqueue_acceptor_get_raw_socket(ioqueue_acceptor_t *sock);
  171. /**
  172. * get owned ioqueue
  173. */
  174. TOOLKIT_API ioqueue_t* ioqueue_acceptor_get_owned_ioqueue(ioqueue_acceptor_t* acceptor);
  175. /**
  176. * set user customize data
  177. * @return old value
  178. */
  179. TOOLKIT_API void *ioqueue_acceptor_set_user_data(ioqueue_acceptor_t* acceptor, void *user_data);
  180. /**
  181. * get user customize data
  182. */
  183. TOOLKIT_API void *ioqueue_acceptor_get_user_data(ioqueue_acceptor_t* acceptor);
  184. /**
  185. * start a accept asynchronous operation
  186. * @param acceptor [in] pointer to acceptor
  187. * @param overlapped [in] operation based structure, cannot be free before callback invoked
  188. * @param on_accept_cb [in] accept callback, invoked after new socket accept
  189. * @return -1 failed, 0 on success
  190. */
  191. TOOLKIT_API int ioqueue_acceptor_async_accept(ioqueue_acceptor_t* acceptor,
  192. ioqueue_overlapped_t *overlapped,
  193. ioqueue_on_accept_callback on_accept_cb,
  194. void *user_data);
  195. /** blocked accept */
  196. TOOLKIT_API int ioqueue_acceptor_accept(ioqueue_acceptor_t* acceptor, SOCKET *s, struct sockaddr *addr, int *addrlen, int timeout);
  197. /**
  198. * get client tcp socket from acceptor and overlapped result, used in ioqueue_on_accept_callback!!!
  199. * @param acceptor [in] acceptor handle, from ioqueue_on_accept_callback params
  200. * @param s [in] acceptor returned client socket, from ioqueue_on_accept_callback params
  201. * @param tcpsock [out] result
  202. * @return -1 failed, 0 ok
  203. */
  204. TOOLKIT_API int ioqueue_acceptor_create_client(ioqueue_acceptor_t* acceptor, SOCKET s, ioqueue_tcpsock_t *tcpsock);
  205. /**
  206. * cancel all async operation
  207. * @return -1 failed, 0 ok
  208. */
  209. TOOLKIT_API int ioqueue_acceptor_cancel(ioqueue_acceptor_t* acceptor);
  210. ////////////////////////////////////////////////////////////////////////////////////////////////
  211. // tcp socket
  212. /** asynchronous callbacks */
  213. typedef void (*ioqueue_on_connect_callback)(ioqueue_tcpsock_t *tcpsock,
  214. ioqueue_overlapped_t *overlapped,
  215. void *user_data,
  216. int err);
  217. typedef void (*ioqueue_on_send_callback)(ioqueue_tcpsock_t *tcpsock,
  218. ioqueue_overlapped_t *overlapped,
  219. void *buf,
  220. unsigned int transfer_bytes,
  221. void *user_data,
  222. int err);
  223. typedef void (*ioqueue_on_recv_callback)(ioqueue_tcpsock_t *tcpsock,
  224. ioqueue_overlapped_t *overlapped,
  225. void *buf,
  226. unsigned int transfer_bytes,
  227. void *user_data,
  228. int err);
  229. typedef void (*ioqueue_on_recvuntil_callback)(ioqueue_tcpsock_t *tcpsock,
  230. ioqueue_overlapped_t *overlapped,
  231. void *buf,
  232. unsigned int transfer_bytes,
  233. unsigned int header_length,
  234. void *user_data,
  235. int err);
  236. /**
  237. * create tcp socket (non-connect, already bind to random local address)
  238. */
  239. TOOLKIT_API int ioqueue_tcpsock_create(ioqueue_t *ioq, ioqueue_tcpsock_t *tcpsock);
  240. /** create tcp socket object from socket handle */
  241. TOOLKIT_API int ioqueue_tcpsock_create_from_handle(ioqueue_t *ioq, SOCKET s, ioqueue_tcpsock_t *tcpsock);
  242. /**
  243. * connect to tcp(ip:port)
  244. * @param [in] ip remote server ip address
  245. * @param [in] port remote server port number, host byte order
  246. * @param [in] on_connect_cb callback function
  247. * @param [in] user_data pass to on_connect_cb
  248. * @return 0 success, -1 failed
  249. */
  250. TOOLKIT_API int ioqueue_tcpsock_async_connect(ioqueue_tcpsock_t *tcpsock,
  251. ioqueue_overlapped_t *overlapped,
  252. const char *ip,
  253. unsigned short port,
  254. ioqueue_on_connect_callback on_connect_cb,
  255. void* user_data);
  256. /** block connect */
  257. TOOLKIT_API int ioqueue_tcpsock_conect(ioqueue_tcpsock_t *tcpsock, const char *ip, unsigned short port, int timeout);
  258. /**
  259. * issue an asynchronous send operation
  260. * @param buf send buffer
  261. * @param len buffer length
  262. * @param on_send_cb callback funtion
  263. * @return -1 on failed, 0 on success
  264. */
  265. TOOLKIT_API int ioqueue_tcpsock_async_sendsome(ioqueue_tcpsock_t *tcpsock,
  266. ioqueue_overlapped_t *overlapped,
  267. void *buf,
  268. unsigned int len,
  269. ioqueue_on_send_callback on_send_cb,
  270. void *user_data);
  271. TOOLKIT_API int ioqueue_tcpsock_async_sendn(ioqueue_tcpsock_t *tcpsock,
  272. ioqueue_overlapped_t *overlapped,
  273. void *buf,
  274. unsigned int len,
  275. ioqueue_on_send_callback on_send_cb,
  276. void* user_data);
  277. TOOLKIT_API int ioqueue_tcpsock_async_senduntil(ioqueue_tcpsock_t *tcpsock,
  278. ioqueue_overlapped_t *overlapped,
  279. void *buf,
  280. unsigned int len,
  281. const char *delimer,
  282. ioqueue_on_send_callback on_send_cb,
  283. void* user_data);
  284. /** blocking send */
  285. TOOLKIT_API int ioqueue_tcpsock_sendsome(ioqueue_tcpsock_t *tcpsock,
  286. void *buf,
  287. unsigned int len,
  288. int timeout);
  289. TOOLKIT_API int ioqueue_tcpsock_sendn(ioqueue_tcpsock_t *tcpsock,
  290. void *buf,
  291. unsigned int len,
  292. int timeout);
  293. TOOLKIT_API int ioqueue_tcpsock_senduntil(ioqueue_tcpsock_t *tcpsock,
  294. void *buf,
  295. unsigned int len,
  296. const char *delimer,
  297. int timeout);
  298. /**
  299. * issue an asynchronous recv operation
  300. */
  301. TOOLKIT_API int ioqueue_tcpsock_async_recvsome(ioqueue_tcpsock_t *tcpsock,
  302. ioqueue_overlapped_t *overlapped,
  303. void *buf,
  304. unsigned int len,
  305. ioqueue_on_recv_callback on_recv_cb,
  306. void *user_data);
  307. TOOLKIT_API int ioqueue_tcpsock_async_recvn(ioqueue_tcpsock_t *tcpsock,
  308. ioqueue_overlapped_t *overlapped,
  309. void *buf,
  310. unsigned int len,
  311. ioqueue_on_recv_callback on_recv_cb,
  312. void *user_data);
  313. TOOLKIT_API int ioqueue_tcpsock_async_recvuntil(ioqueue_tcpsock_t *tcpsock,
  314. ioqueue_overlapped_t *overlapped,
  315. void *buf,
  316. unsigned int len,
  317. const char *delimer,
  318. ioqueue_on_recvuntil_callback on_recvuntil_cb,
  319. void *user_data);
  320. /** blocking recv */
  321. TOOLKIT_API int ioqueue_tcpsock_recvsome(ioqueue_tcpsock_t *tcpsock,
  322. void *buf,
  323. unsigned int len,
  324. int timeout);
  325. TOOLKIT_API int ioqueue_tcpsock_recvn(ioqueue_tcpsock_t *tcpsock,
  326. void *buf,
  327. unsigned int len,
  328. int timeout);
  329. TOOLKIT_API int ioqueue_tcpsock_recvuntil(ioqueue_tcpsock_t *tcpsock,
  330. void *buf,
  331. unsigned int len,
  332. const char *delimer,
  333. unsigned int *header_len,
  334. int timeout);
  335. /** close socket handler, so all pending async operation can be aborted */
  336. TOOLKIT_API void ioqueue_tcpsock_close(ioqueue_tcpsock_t *tcpsock);
  337. /**
  338. * destory an tcpsock
  339. */
  340. TOOLKIT_API void ioqueue_tcpsock_destroy(ioqueue_tcpsock_t *tcpsock);
  341. /**
  342. * shutdown wrapper
  343. */
  344. TOOLKIT_API int ioqueue_tcpsock_shutdown(ioqueue_tcpsock_t *tcpsock, int how);
  345. /**
  346. * get raw socket handler
  347. */
  348. TOOLKIT_API SOCKET ioqueue_tcpsock_get_raw_socket(ioqueue_tcpsock_t *tcpsock);
  349. /**
  350. * get owned ioqueue
  351. */
  352. TOOLKIT_API ioqueue_t* ioqueue_tcpsock_get_owned_ioqueue(ioqueue_tcpsock_t *tcpsock);
  353. /**
  354. * set user customize data
  355. * @return old value
  356. */
  357. TOOLKIT_API void *ioqueue_tcpsock_set_user_data(ioqueue_tcpsock_t *tcpsock, void *user_data);
  358. /**
  359. * get user customize data
  360. */
  361. TOOLKIT_API void *ioqueue_tcpsock_get_user_data(ioqueue_tcpsock_t *tcpsock);
  362. /**
  363. * cancel all async operation
  364. * @return -1 failed, 0 ok
  365. */
  366. TOOLKIT_API int ioqueue_tcpsock_cancel(ioqueue_tcpsock_t* tcpsock);
  367. ////////////////////////////////////////////////////////////////////////////////////////////////
  368. // udp socket
  369. typedef void (*ioqueue_on_sendto_callback)(ioqueue_udpsock_t *udpsock,
  370. ioqueue_overlapped_t *overlapped,
  371. void *buf,
  372. unsigned int transfer_bytes,
  373. void *user_data,
  374. int err);
  375. typedef void (*ioqueue_on_recvfrom_callback)(ioqueue_udpsock_t *udpsock,
  376. ioqueue_overlapped_t *overlapped,
  377. const struct sockaddr *from,
  378. int fromlen,
  379. void *buf,
  380. unsigned int transfer_bytes,
  381. void *user_data,
  382. int err);
  383. /**
  384. * create udp socket
  385. */
  386. TOOLKIT_API int ioqueue_udpsock_create(ioqueue_t *ioq, ioqueue_udpsock_t *udpsock);
  387. /** create udp socket object from socket handle */
  388. TOOLKIT_API int ioqueue_udpsock_create_from_handle(ioqueue_t *ioq, SOCKET s, ioqueue_udpsock_t *udpsock);
  389. /** close socket handler, so all pending async operation can be aborted */
  390. TOOLKIT_API void ioqueue_udpsock_close(ioqueue_udpsock_t *udpsock);
  391. /**
  392. * destroy udp socket
  393. */
  394. TOOLKIT_API void ioqueue_udpsock_destroy(ioqueue_udpsock_t *udpsock);
  395. /**
  396. * issue an asynchronous sendto operation, mainly for udp udpsock
  397. */
  398. TOOLKIT_API int ioqueue_udpsock_async_sendto(ioqueue_udpsock_t* sock,
  399. ioqueue_overlapped_t *overlapped,
  400. void *buf,
  401. int len,
  402. const struct sockaddr* to,
  403. int tolen,
  404. ioqueue_on_sendto_callback on_sendto_cb,
  405. void *user_data);
  406. /** blocking sendto */
  407. TOOLKIT_API int ioqueue_udpsock_sendto(ioqueue_udpsock_t *udpsock,
  408. void *buf,
  409. int len,
  410. const struct sockaddr* to,
  411. int tolen,
  412. int timeout);
  413. /**
  414. * issue an asynchronous recv operation, mainly for udp udpsock
  415. */
  416. TOOLKIT_API int ioqueue_udpsock_async_recvfrom(ioqueue_udpsock_t* udpsock,
  417. ioqueue_overlapped_t *overlapped,
  418. void* buf,
  419. int len,
  420. ioqueue_on_recvfrom_callback on_recvfrom_cb,
  421. void *user_data);
  422. /** blocking recvfrom */
  423. TOOLKIT_API int ioqueue_udpsock_recvfrom(ioqueue_udpsock_t* udpsock,
  424. ioqueue_overlapped_t *overlapped,
  425. void* buf,
  426. int len,
  427. struct sockaddr *addr,
  428. int *addrlen,
  429. int timeout);
  430. /**
  431. * get raw socket handler
  432. */
  433. TOOLKIT_API SOCKET ioqueue_udpsock_get_raw_socket(ioqueue_udpsock_t *udpsock);
  434. /**
  435. * get owned ioqueue
  436. */
  437. TOOLKIT_API ioqueue_t* ioqueue_udpsock_get_owned_ioqueue(ioqueue_udpsock_t *udpsock);
  438. /**
  439. * set user customize data
  440. * @return old value
  441. */
  442. TOOLKIT_API void *ioqueue_udpsock_set_user_data(ioqueue_udpsock_t *udpsock, void *user_data);
  443. /**
  444. * get user customize data
  445. */
  446. TOOLKIT_API void *ioqueue_udpsock_get_user_data(ioqueue_udpsock_t *udpsock);
  447. /**
  448. * cancel all async operation
  449. * @return -1 failed, 0 ok
  450. */
  451. TOOLKIT_API int ioqueue_udpsock_cancel(ioqueue_udpsock_t *udpsock);
  452. ////////////////////////////////////////////////////////////////////////////////////////////////
  453. // file
  454. /** asychronous callbacks */
  455. typedef void (*ioqueue_on_read_callback)(ioqueue_file_t* file,
  456. ioqueue_overlapped_t *overlapped,
  457. void *buf,
  458. unsigned int transfer_bytes,
  459. void *user_data,
  460. int err);
  461. typedef void (*ioqueue_on_readuntil_callback)(ioqueue_file_t* file,
  462. ioqueue_overlapped_t *overlapped,
  463. void *buf,
  464. unsigned int transfer_bytes,
  465. unsigned int header_length,
  466. void *user_data,
  467. int err);
  468. typedef void (*ioqueue_on_write_callback)(ioqueue_file_t* file,
  469. ioqueue_overlapped_t *overlapped,
  470. void *buf,
  471. unsigned int transfer_bytes,
  472. void *user_data,
  473. int err);
  474. /**
  475. * create file from path
  476. * @param path local file system path
  477. * @param dwDesiredAccess refer CreateFile api
  478. * @param dwShareMode refer CreateFile api
  479. * @param dwCreationDisposition refer CreateFile api
  480. * @param dwFlagsAndAttributes refer CreateFile api
  481. * @return 0 success, -1 failed
  482. */
  483. TOOLKIT_API int ioqueue_file_create(ioqueue_t *ioq,
  484. const char *path,
  485. DWORD dwDesiredAccess,
  486. DWORD dwShareMode,
  487. DWORD dwCreationDisposition,
  488. DWORD dwFlagsAndAttributes,
  489. ioqueue_file_t *file);
  490. TOOLKIT_API int ioqueue_file_create_from_handle(ioqueue_t *ioq, HANDLE h, ioqueue_file_t *file);
  491. /** close file handler, so all pending async operation can be aborted */
  492. TOOLKIT_API void ioqueue_file_close(ioqueue_file_t* file);
  493. /**
  494. * destroy file
  495. */
  496. TOOLKIT_API void ioqueue_file_destroy(ioqueue_file_t* file);
  497. /**
  498. * issue an asynchronous read operation
  499. * @return -1 on failed, 0 on success
  500. */
  501. TOOLKIT_API int ioqueue_file_async_readsome(ioqueue_file_t* file,
  502. ioqueue_overlapped_t *overlapped,
  503. void *buf,
  504. unsigned int len,
  505. ioqueue_on_read_callback on_read_cb,
  506. void *user_data);
  507. TOOLKIT_API int ioqueue_file_async_readn(ioqueue_file_t* file,
  508. ioqueue_overlapped_t *overlapped,
  509. void *buf,
  510. unsigned int len,
  511. ioqueue_on_read_callback on_read_cb,
  512. void *user_data);
  513. /** blocking read */
  514. TOOLKIT_API int ioqueue_file_readsome(ioqueue_file_t *file, void *buf, unsigned int len);
  515. TOOLKIT_API int ioqueue_file_readn(ioqueue_file_t *file, void *buf, unsigned int len);
  516. /**
  517. * issue an asynchronous read at operation
  518. * @param buf read buffer
  519. * @param len buffer length
  520. * @param pos file read position
  521. * @param on_read_cb callback function
  522. */
  523. TOOLKIT_API int ioqueue_file_async_readsome_at(ioqueue_file_t* file,
  524. ioqueue_overlapped_t *overlapped,
  525. void *buf,
  526. unsigned int len,
  527. DWORD posLow,
  528. DWORD posHigh,
  529. ioqueue_on_read_callback on_read_cb,
  530. void *user_data);
  531. TOOLKIT_API int ioqueue_file_async_readn_at(ioqueue_file_t* file,
  532. ioqueue_overlapped_t *overlapped,
  533. void *buf,
  534. unsigned int len,
  535. DWORD posLow,
  536. DWORD posHigh,
  537. ioqueue_on_read_callback on_read_cb,
  538. void *user_data);
  539. /** blocking read at */
  540. TOOLKIT_API int ioqueue_file_readsome_at(ioqueue_file_t *file, void *buf, unsigned int len, DWORD posLow, DWORD posHigh);
  541. TOOLKIT_API int ioqueue_file_readn_at(ioqueue_file_t *file, void *buf, unsigned int len, DWORD posLow, DWORD posHigh);
  542. /**
  543. * issue an asynchronous write at operation
  544. */
  545. TOOLKIT_API int ioqueue_file_async_writesome(ioqueue_file_t* file,
  546. ioqueue_overlapped_t *overlapped,
  547. void* buf,
  548. unsigned int len,
  549. ioqueue_on_write_callback on_write_cb,
  550. void *user_data);
  551. TOOLKIT_API int ioqueue_file_async_writen(ioqueue_file_t* file,
  552. ioqueue_overlapped_t *overlapped,
  553. void* buf,
  554. unsigned int len,
  555. ioqueue_on_write_callback on_write_cb,
  556. void *user_data);
  557. /** blocking write */
  558. TOOLKIT_API int ioqueue_file_writesome(ioqueue_file_t* file, const void *buf, unsigned int len);
  559. TOOLKIT_API int ioqueue_file_writen(ioqueue_file_t* file, const void *buf, unsigned int len);
  560. /**
  561. * issue an asynchronous write at operation
  562. */
  563. TOOLKIT_API int ioqueue_file_async_writesome_at(ioqueue_file_t* file,
  564. ioqueue_overlapped_t *overlapped,
  565. void* buf,
  566. unsigned int len,
  567. DWORD posLow,
  568. DWORD posHigh,
  569. ioqueue_on_write_callback on_write_cb,
  570. void *user_data);
  571. TOOLKIT_API int ioqueue_file_async_writen_at(ioqueue_file_t* file,
  572. ioqueue_overlapped_t *overlapped,
  573. void* buf,
  574. unsigned int len,
  575. DWORD posLow,
  576. DWORD posHigh,
  577. ioqueue_on_write_callback on_write_cb,
  578. void *user_data);
  579. /** blocking write at */
  580. TOOLKIT_API int ioqueue_file_writesome_at(ioqueue_file_t* file,
  581. const void *buf,
  582. unsigned int len,
  583. DWORD posLow,
  584. DWORD posHigh);
  585. TOOLKIT_API int ioqueue_file_writen_at(ioqueue_file_t* file,
  586. const void *buf,
  587. unsigned int len,
  588. DWORD posLow,
  589. DWORD posHigh);
  590. /**
  591. * get owned ioqueue
  592. */
  593. TOOLKIT_API ioqueue_t* ioqueue_file_get_owned_ioqueue(ioqueue_file_t* file);
  594. /**
  595. * get inner file handler
  596. */
  597. TOOLKIT_API HANDLE ioqueue_file_get_raw_handle(ioqueue_file_t* file);
  598. /**
  599. * set user customized data
  600. * @return old value
  601. */
  602. TOOLKIT_API void *ioqueue_file_set_user_data(ioqueue_file_t* file, void* user_data);
  603. /**
  604. * get user customized data
  605. */
  606. TOOLKIT_API void *ioqueue_file_get_user_data(ioqueue_file_t* file);
  607. /**
  608. * cancel all async operation
  609. * @return -1 failed, 0 ok
  610. */
  611. TOOLKIT_API int ioqueue_file_cancel(ioqueue_file_t* file);
  612. ////////////////////////////////////////////////////////////////////////////////////////////////
  613. // pipe server
  614. /**
  615. * callback while new pipe client connects in
  616. * @param user_data pass from async_accept
  617. * @param in_sock client socket, if you dont need this socket,
  618. * no need to call closesocket on it, just return zero!!!
  619. * @param err -1 on failed, 0 on success
  620. * @return non-zero means accept, zero reject
  621. */
  622. typedef int (*ioqueue_on_pipe_accept_callback)(ioqueue_pipe_acceptor_t *acceptor,
  623. ioqueue_overlapped_t *overlapped,
  624. HANDLE pipe,
  625. void *user_data,
  626. int err);
  627. /**
  628. * pipe acceptor
  629. */
  630. TOOLKIT_API int ioqueue_pipe_acceptor_create(ioqueue_t *ioq, const char *name, ioqueue_pipe_acceptor_t *acceptor);
  631. /**
  632. * destroy pipe acceptor
  633. */
  634. TOOLKIT_API void ioqueue_pipe_acceptor_destroy(ioqueue_pipe_acceptor_t *acceptor);
  635. /**
  636. * get owned ioqueue
  637. */
  638. TOOLKIT_API ioqueue_t* ioqueue_pipe_acceptor_get_owned_ioqueue(ioqueue_pipe_acceptor_t *acceptor);
  639. /**
  640. * set user customize data
  641. * @return old value
  642. */
  643. TOOLKIT_API void *ioqueue_pipe_acceptor_set_user_data(ioqueue_pipe_acceptor_t *acceptor, void *user_data);
  644. /**
  645. * get user customize data
  646. */
  647. TOOLKIT_API void *ioqueue_pipe_acceptor_get_user_data(ioqueue_pipe_acceptor_t *acceptor);
  648. /** async accept */
  649. TOOLKIT_API int ioqueue_pipe_acceptor_async_accept(ioqueue_pipe_acceptor_t *acceptor,
  650. ioqueue_overlapped_t *overlapped,
  651. ioqueue_on_pipe_accept_callback cb,
  652. void *user_data);
  653. /** blocked accept */
  654. TOOLKIT_API int ioqueue_pipe_acceptor_accept(ioqueue_pipe_acceptor_t *acceptor, HANDLE *p_pipe, int timeout);
  655. /**
  656. * get client pipe from acceptor and overlapped result, used in ioqueue_on_pipe_accept_callback!!!
  657. * @param acceptor [in] acceptor handle, from ioqueue_on_accept_callback params
  658. * @param h [in] acceptor returned client pipe handle, from ioqueue_on_pipe_accept_callback params
  659. * @param pipe [out] result
  660. * @return -1 failed, 0 ok
  661. */
  662. TOOLKIT_API int ioqueue_pipe_acceptor_create_client(ioqueue_pipe_acceptor_t *acceptor, HANDLE h, ioqueue_file_t *pipe);
  663. /**
  664. * cancel all async operation
  665. * @return -1 failed, 0 ok
  666. */
  667. TOOLKIT_API int ioqueue_pipe_acceptor_cancel(ioqueue_pipe_acceptor_t *acceptor);
  668. TOOLKIT_API int ioqueue_pipe_acceptor_close_pending_handle(ioqueue_pipe_acceptor_t *acceptor);
  669. #ifndef _WIN32
  670. TOOLKIT_API int ioqueue_overlapped_get_mask(const ioqueue_overlapped_t* const io);
  671. TOOLKIT_API void ioqueue_overlapped_set_mask(ioqueue_overlapped_t* io, int mask_value);
  672. TOOLKIT_API int ioqueue_overlapped_get_type(const ioqueue_overlapped_t* const io);
  673. #endif //NOT _WIN32
  674. #ifdef __cplusplus
  675. } // extern "C" {
  676. #endif
  677. #endif // IOQUEUE_H