/*
* Copyright (C) Igor Sysoev
* Copyright (C) NGINX, Inc.
*/
#ifndef _NXT_SENDBUF_H_INCLUDED_
#define _NXT_SENDBUF_H_INCLUDED_
/*
* The sendbuf interface is intended to send a buffer chain to a connection.
* It uses sendfile interface if available. Otherwise it can send only
* memory buffers, so file buffers must be read in memory in advance.
*
* The sendbuf interface sets c->socket.write_ready to appropriate state
* and returns:
*
* N > 0 if sendbuf sent N bytes.
*
* 0 if sendbuf was interrupted (EINTR and so on),
* or sendbuf sent previously buffered data,
* or single sync buffer has been encountered.
* In all these cases sendbuf is ready to continue
* operation, unless c->socket.write_ready is cleared.
*
* NXT_AGAIN if sendbuf did not send any bytes.
*
* NXT_ERROR if there was erorr.
*
* The sendbuf limit is size_t type since size_t is large enough and many
* sendfile implementations do not support anyway sending more than size_t
* at once. The limit support is located at the sendbuf level otherwise
* an additional limited chain must be created on each sendbuf call.
*/
typedef struct {
nxt_buf_t *buf;
nxt_socket_t socket;
nxt_err_t error;
nxt_off_t sent;
size_t size;
size_t limit;
uint8_t ready; /* 1 bit */
uint8_t once; /* 1 bit */
uint8_t sync; /* 1 bit */
uint8_t last; /* 1 bit */
} nxt_sendbuf_t;
typedef struct {
nxt_buf_t *buf;
nxt_iobuf_t *iobuf;
nxt_uint_t niov;
uint32_t nmax;
uint8_t sync; /* 1 bit */
uint8_t last; /* 1 bit */
uint8_t limit_reached;
uint8_t nmax_reached;
size_t size;
size_t limit;
} nxt_sendbuf_coalesce_t;
#if (NXT_HAVE_LINUX_SENDFILE)
#define NXT_HAVE_SENDFILE 1
ssize_t nxt_linux_event_conn_io_sendfile(nxt_conn_t *c, nxt_buf_t *b,
size_t limit);
#endif
#if (NXT_HAVE_FREEBSD_SENDFILE)
#define NXT_HAVE_SENDFILE 1
ssize_t nxt_freebsd_event_conn_io_sendfile(nxt_conn_t *c, nxt_buf_t *b,
size_t limit);
#endif
#if (NXT_HAVE_SOLARIS_SENDFILEV)
#define NXT_HAVE_SENDFILE 1
ssize_t nxt_solaris_event_conn_io_sendfilev(nxt_conn_t *c, nxt_buf_t *b,
size_t limit);
#endif
#if (NXT_HAVE_MACOSX_SENDFILE)
#define NXT_HAVE_SENDFILE 1
ssize_t nxt_macosx_event_conn_io_sendfile(nxt_conn_t *c, nxt_buf_t *b,
size_t limit);
#endif
#if (NXT_HAVE_AIX_SEND_FILE)
#define NXT_HAVE_SENDFILE 1
ssize_t nxt_aix_event_conn_io_send_file(nxt_conn_t *c, nxt_buf_t *b,
size_t limit);
#endif
#if (NXT_HAVE_HPUX_SENDFILE)
#define NXT_HAVE_SENDFILE 1
ssize_t nxt_hpux_event_conn_io_sendfile(nxt_conn_t *c, nxt_buf_t *b,
size_t limit);
#endif
ssize_t nxt_event_conn_io_sendbuf(nxt_conn_t *c, nxt_buf_t *b,
size_t limit);
nxt_uint_t nxt_sendbuf_mem_coalesce0(nxt_task_t *task, nxt_sendbuf_t *sb,
struct iovec *iov, nxt_uint_t niov_max);
nxt_uint_t nxt_sendbuf_mem_coalesce(nxt_task_t *task,
nxt_sendbuf_coalesce_t *sb);
size_t nxt_sendbuf_file_coalesce(nxt_sendbuf_coalesce_t *sb);
/*
* Auxiliary nxt_sendbuf_copy_coalesce() interface copies small memory
* buffers into internal buffer before output. It is intended for
* SSL/TLS libraries which lack vector I/O interface yet add noticeable
* overhead to each SSL/TLS record.
*/
ssize_t nxt_sendbuf_copy_coalesce(nxt_conn_t *c, nxt_buf_mem_t *bm,
nxt_buf_t *b, size_t limit);
nxt_buf_t *nxt_sendbuf_update(nxt_buf_t *b, size_t sent);
nxt_buf_t *nxt_sendbuf_completion(nxt_task_t *task, nxt_work_queue_t *wq,
nxt_buf_t *b);
#endif /* _NXT_SENDBUF_H_INCLUDED_ */