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; 4013Sigor@sysoev.ru nxt_socket_t socket; 4113Sigor@sysoev.ru nxt_err_t error; 4213Sigor@sysoev.ru nxt_off_t sent; 4313Sigor@sysoev.ru size_t size; 4413Sigor@sysoev.ru size_t limit; 4513Sigor@sysoev.ru 4613Sigor@sysoev.ru uint8_t ready; /* 1 bit */ 4713Sigor@sysoev.ru uint8_t once; /* 1 bit */ 4813Sigor@sysoev.ru uint8_t sync; /* 1 bit */ 4913Sigor@sysoev.ru uint8_t last; /* 1 bit */ 5013Sigor@sysoev.ru } nxt_sendbuf_t; 5113Sigor@sysoev.ru 5213Sigor@sysoev.ru 5313Sigor@sysoev.ru typedef struct { 540Sigor@sysoev.ru nxt_buf_t *buf; 550Sigor@sysoev.ru nxt_iobuf_t *iobuf; 56*42Smax.romanov@nginx.com nxt_uint_t niov; 570Sigor@sysoev.ru 580Sigor@sysoev.ru uint32_t nmax; 590Sigor@sysoev.ru uint8_t sync; /* 1 bit */ 600Sigor@sysoev.ru uint8_t last; /* 1 bit */ 610Sigor@sysoev.ru 620Sigor@sysoev.ru size_t size; 630Sigor@sysoev.ru size_t limit; 640Sigor@sysoev.ru } nxt_sendbuf_coalesce_t; 650Sigor@sysoev.ru 660Sigor@sysoev.ru 670Sigor@sysoev.ru #if (NXT_HAVE_LINUX_SENDFILE) 680Sigor@sysoev.ru #define NXT_HAVE_SENDFILE 1 690Sigor@sysoev.ru ssize_t nxt_linux_event_conn_io_sendfile(nxt_event_conn_t *c, nxt_buf_t *b, 700Sigor@sysoev.ru size_t limit); 710Sigor@sysoev.ru #endif 720Sigor@sysoev.ru 730Sigor@sysoev.ru #if (NXT_HAVE_FREEBSD_SENDFILE) 740Sigor@sysoev.ru #define NXT_HAVE_SENDFILE 1 750Sigor@sysoev.ru ssize_t nxt_freebsd_event_conn_io_sendfile(nxt_event_conn_t *c, nxt_buf_t *b, 760Sigor@sysoev.ru size_t limit); 770Sigor@sysoev.ru #endif 780Sigor@sysoev.ru 790Sigor@sysoev.ru #if (NXT_HAVE_SOLARIS_SENDFILEV) 800Sigor@sysoev.ru #define NXT_HAVE_SENDFILE 1 810Sigor@sysoev.ru ssize_t nxt_solaris_event_conn_io_sendfilev(nxt_event_conn_t *c, nxt_buf_t *b, 820Sigor@sysoev.ru size_t limit); 830Sigor@sysoev.ru #endif 840Sigor@sysoev.ru 850Sigor@sysoev.ru #if (NXT_HAVE_MACOSX_SENDFILE) 860Sigor@sysoev.ru #define NXT_HAVE_SENDFILE 1 870Sigor@sysoev.ru ssize_t nxt_macosx_event_conn_io_sendfile(nxt_event_conn_t *c, nxt_buf_t *b, 880Sigor@sysoev.ru size_t limit); 890Sigor@sysoev.ru #endif 900Sigor@sysoev.ru 910Sigor@sysoev.ru #if (NXT_HAVE_AIX_SEND_FILE) 920Sigor@sysoev.ru #define NXT_HAVE_SENDFILE 1 930Sigor@sysoev.ru ssize_t nxt_aix_event_conn_io_send_file(nxt_event_conn_t *c, nxt_buf_t *b, 940Sigor@sysoev.ru size_t limit); 950Sigor@sysoev.ru #endif 960Sigor@sysoev.ru 970Sigor@sysoev.ru #if (NXT_HAVE_HPUX_SENDFILE) 980Sigor@sysoev.ru #define NXT_HAVE_SENDFILE 1 990Sigor@sysoev.ru ssize_t nxt_hpux_event_conn_io_sendfile(nxt_event_conn_t *c, nxt_buf_t *b, 1000Sigor@sysoev.ru size_t limit); 1010Sigor@sysoev.ru #endif 1020Sigor@sysoev.ru 1030Sigor@sysoev.ru ssize_t nxt_event_conn_io_sendbuf(nxt_event_conn_t *c, nxt_buf_t *b, 1040Sigor@sysoev.ru size_t limit); 1050Sigor@sysoev.ru 1060Sigor@sysoev.ru 10713Sigor@sysoev.ru nxt_uint_t nxt_sendbuf_mem_coalesce0(nxt_task_t *task, nxt_sendbuf_t *sb, 10813Sigor@sysoev.ru struct iovec *iov, nxt_uint_t niov_max); 1091Sigor@sysoev.ru nxt_uint_t nxt_sendbuf_mem_coalesce(nxt_task_t *task, 1101Sigor@sysoev.ru nxt_sendbuf_coalesce_t *sb); 1110Sigor@sysoev.ru size_t nxt_sendbuf_file_coalesce(nxt_sendbuf_coalesce_t *sb); 1120Sigor@sysoev.ru 1130Sigor@sysoev.ru /* 1140Sigor@sysoev.ru * Auxiliary nxt_sendbuf_copy_coalesce() interface copies small memory 1150Sigor@sysoev.ru * buffers into internal buffer before output. It is intended for 1160Sigor@sysoev.ru * SSL/TLS libraries which lack vector I/O interface yet add noticeable 1170Sigor@sysoev.ru * overhead to each SSL/TLS record. 1180Sigor@sysoev.ru */ 1190Sigor@sysoev.ru ssize_t nxt_sendbuf_copy_coalesce(nxt_event_conn_t *c, nxt_buf_mem_t *bm, 1200Sigor@sysoev.ru nxt_buf_t *b, size_t limit); 1210Sigor@sysoev.ru 1220Sigor@sysoev.ru nxt_buf_t *nxt_sendbuf_update(nxt_buf_t *b, size_t sent); 1231Sigor@sysoev.ru nxt_buf_t *nxt_sendbuf_completion(nxt_task_t *task, nxt_work_queue_t *wq, 1240Sigor@sysoev.ru nxt_buf_t *b, size_t sent); 1250Sigor@sysoev.ru 1260Sigor@sysoev.ru 1270Sigor@sysoev.ru #endif /* _NXT_SENDBUF_H_INCLUDED_ */ 128