ioqueue.h 24 KB

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