10Sigor@sysoev.ru 20Sigor@sysoev.ru /* 30Sigor@sysoev.ru * Copyright (C) Igor Sysoev 40Sigor@sysoev.ru * Copyright (C) NGINX, Inc. 50Sigor@sysoev.ru */ 60Sigor@sysoev.ru 70Sigor@sysoev.ru #ifndef _NXT_SENDBUF_H_INCLUDED_ 80Sigor@sysoev.ru #define _NXT_SENDBUF_H_INCLUDED_ 90Sigor@sysoev.ru 100Sigor@sysoev.ru 110Sigor@sysoev.ru /* 120Sigor@sysoev.ru * The sendbuf interface is intended to send a buffer chain to a connection. 130Sigor@sysoev.ru * It uses sendfile interface if available. Otherwise it can send only 140Sigor@sysoev.ru * memory buffers, so file buffers must be read in memory in advance. 150Sigor@sysoev.ru * 160Sigor@sysoev.ru * The sendbuf interface sets c->socket.write_ready to appropriate state 170Sigor@sysoev.ru * and returns: 180Sigor@sysoev.ru * 190Sigor@sysoev.ru * N > 0 if sendbuf sent N bytes. 200Sigor@sysoev.ru * 210Sigor@sysoev.ru * 0 if sendbuf was interrupted (EINTR and so on), 220Sigor@sysoev.ru * or sendbuf sent previously buffered data, 230Sigor@sysoev.ru * or single sync buffer has been encountered. 240Sigor@sysoev.ru * In all these cases sendbuf is ready to continue 250Sigor@sysoev.ru * operation, unless c->socket.write_ready is cleared. 260Sigor@sysoev.ru * 270Sigor@sysoev.ru * NXT_AGAIN if sendbuf did not send any bytes. 280Sigor@sysoev.ru * 290Sigor@sysoev.ru * NXT_ERROR if there was erorr. 300Sigor@sysoev.ru * 310Sigor@sysoev.ru * The sendbuf limit is size_t type since size_t is large enough and many 320Sigor@sysoev.ru * sendfile implementations do not support anyway sending more than size_t 330Sigor@sysoev.ru * at once. The limit support is located at the sendbuf level otherwise 340Sigor@sysoev.ru * an additional limited chain must be created on each sendbuf call. 350Sigor@sysoev.ru */ 360Sigor@sysoev.ru 370Sigor@sysoev.ru 380Sigor@sysoev.ru typedef struct { 3913Sigor@sysoev.ru nxt_buf_t *buf; 40*771Sigor@sysoev.ru void *tls; 4113Sigor@sysoev.ru nxt_socket_t socket; 4213Sigor@sysoev.ru nxt_err_t error; 4313Sigor@sysoev.ru nxt_off_t sent; 4413Sigor@sysoev.ru size_t size; 4513Sigor@sysoev.ru size_t limit; 4613Sigor@sysoev.ru 4713Sigor@sysoev.ru uint8_t ready; /* 1 bit */ 4813Sigor@sysoev.ru uint8_t once; /* 1 bit */ 4913Sigor@sysoev.ru uint8_t sync; /* 1 bit */ 5013Sigor@sysoev.ru uint8_t last; /* 1 bit */ 5113Sigor@sysoev.ru } nxt_sendbuf_t; 5213Sigor@sysoev.ru 5313Sigor@sysoev.ru 5413Sigor@sysoev.ru typedef struct { 550Sigor@sysoev.ru nxt_buf_t *buf; 560Sigor@sysoev.ru nxt_iobuf_t *iobuf; 5742Smax.romanov@nginx.com nxt_uint_t niov; 580Sigor@sysoev.ru 590Sigor@sysoev.ru uint32_t nmax; 600Sigor@sysoev.ru uint8_t sync; /* 1 bit */ 610Sigor@sysoev.ru uint8_t last; /* 1 bit */ 62352Smax.romanov@nginx.com uint8_t limit_reached; 63352Smax.romanov@nginx.com uint8_t nmax_reached; 640Sigor@sysoev.ru 650Sigor@sysoev.ru size_t size; 660Sigor@sysoev.ru size_t limit; 670Sigor@sysoev.ru } nxt_sendbuf_coalesce_t; 680Sigor@sysoev.ru 690Sigor@sysoev.ru 700Sigor@sysoev.ru #if (NXT_HAVE_LINUX_SENDFILE) 710Sigor@sysoev.ru #define NXT_HAVE_SENDFILE 1 7262Sigor@sysoev.ru ssize_t nxt_linux_event_conn_io_sendfile(nxt_conn_t *c, nxt_buf_t *b, 730Sigor@sysoev.ru size_t limit); 740Sigor@sysoev.ru #endif 750Sigor@sysoev.ru 760Sigor@sysoev.ru #if (NXT_HAVE_FREEBSD_SENDFILE) 770Sigor@sysoev.ru #define NXT_HAVE_SENDFILE 1 7862Sigor@sysoev.ru ssize_t nxt_freebsd_event_conn_io_sendfile(nxt_conn_t *c, nxt_buf_t *b, 790Sigor@sysoev.ru size_t limit); 800Sigor@sysoev.ru #endif 810Sigor@sysoev.ru 820Sigor@sysoev.ru #if (NXT_HAVE_SOLARIS_SENDFILEV) 830Sigor@sysoev.ru #define NXT_HAVE_SENDFILE 1 8462Sigor@sysoev.ru ssize_t nxt_solaris_event_conn_io_sendfilev(nxt_conn_t *c, nxt_buf_t *b, 850Sigor@sysoev.ru size_t limit); 860Sigor@sysoev.ru #endif 870Sigor@sysoev.ru 880Sigor@sysoev.ru #if (NXT_HAVE_MACOSX_SENDFILE) 890Sigor@sysoev.ru #define NXT_HAVE_SENDFILE 1 9062Sigor@sysoev.ru ssize_t nxt_macosx_event_conn_io_sendfile(nxt_conn_t *c, nxt_buf_t *b, 910Sigor@sysoev.ru size_t limit); 920Sigor@sysoev.ru #endif 930Sigor@sysoev.ru 940Sigor@sysoev.ru #if (NXT_HAVE_AIX_SEND_FILE) 950Sigor@sysoev.ru #define NXT_HAVE_SENDFILE 1 9662Sigor@sysoev.ru ssize_t nxt_aix_event_conn_io_send_file(nxt_conn_t *c, nxt_buf_t *b, 970Sigor@sysoev.ru size_t limit); 980Sigor@sysoev.ru #endif 990Sigor@sysoev.ru 1000Sigor@sysoev.ru #if (NXT_HAVE_HPUX_SENDFILE) 1010Sigor@sysoev.ru #define NXT_HAVE_SENDFILE 1 10262Sigor@sysoev.ru ssize_t nxt_hpux_event_conn_io_sendfile(nxt_conn_t *c, nxt_buf_t *b, 1030Sigor@sysoev.ru size_t limit); 1040Sigor@sysoev.ru #endif 1050Sigor@sysoev.ru 10662Sigor@sysoev.ru ssize_t nxt_event_conn_io_sendbuf(nxt_conn_t *c, nxt_buf_t *b, 1070Sigor@sysoev.ru size_t limit); 1080Sigor@sysoev.ru 1090Sigor@sysoev.ru 11013Sigor@sysoev.ru nxt_uint_t nxt_sendbuf_mem_coalesce0(nxt_task_t *task, nxt_sendbuf_t *sb, 11113Sigor@sysoev.ru struct iovec *iov, nxt_uint_t niov_max); 1121Sigor@sysoev.ru nxt_uint_t nxt_sendbuf_mem_coalesce(nxt_task_t *task, 1131Sigor@sysoev.ru nxt_sendbuf_coalesce_t *sb); 1140Sigor@sysoev.ru size_t nxt_sendbuf_file_coalesce(nxt_sendbuf_coalesce_t *sb); 1150Sigor@sysoev.ru 1160Sigor@sysoev.ru /* 1170Sigor@sysoev.ru * Auxiliary nxt_sendbuf_copy_coalesce() interface copies small memory 1180Sigor@sysoev.ru * buffers into internal buffer before output. It is intended for 1190Sigor@sysoev.ru * SSL/TLS libraries which lack vector I/O interface yet add noticeable 1200Sigor@sysoev.ru * overhead to each SSL/TLS record. 1210Sigor@sysoev.ru */ 12262Sigor@sysoev.ru ssize_t nxt_sendbuf_copy_coalesce(nxt_conn_t *c, nxt_buf_mem_t *bm, 1230Sigor@sysoev.ru nxt_buf_t *b, size_t limit); 1240Sigor@sysoev.ru 1250Sigor@sysoev.ru nxt_buf_t *nxt_sendbuf_update(nxt_buf_t *b, size_t sent); 1261Sigor@sysoev.ru nxt_buf_t *nxt_sendbuf_completion(nxt_task_t *task, nxt_work_queue_t *wq, 127431Sigor@sysoev.ru nxt_buf_t *b); 128608Sigor@sysoev.ru void nxt_sendbuf_drain(nxt_task_t *task, nxt_work_queue_t *wq, nxt_buf_t *b); 1290Sigor@sysoev.ru 1300Sigor@sysoev.ru 1310Sigor@sysoev.ru #endif /* _NXT_SENDBUF_H_INCLUDED_ */ 132