31
#define NGX_HEADERS 64
32
#define NGX_TRAILERS 64
34
#define NGX_HEADERS IOV_MAX
35
#define NGX_TRAILERS IOV_MAX
40
31
ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
44
off_t size, send, prev_send, aligned, sent, fprev;
45
off_t header_size, file_size;
46
ngx_uint_t eintr, complete;
34
off_t send, prev_send, sent;
49
ngx_array_t header, trailer;
42
ngx_iovec_t header, trailer;
52
43
struct sf_hdtr hdtr;
53
struct iovec *iov, headers[NGX_HEADERS], trailers[NGX_TRAILERS];
44
struct iovec headers[NGX_IOVS_PREALLOCATE];
45
struct iovec trailers[NGX_IOVS_PREALLOCATE];
80
header.elts = headers;
81
header.size = sizeof(struct iovec);
82
header.nalloc = NGX_HEADERS;
83
header.pool = c->pool;
72
header.iovs = headers;
73
header.nalloc = NGX_IOVS_PREALLOCATE;
85
trailer.elts = trailers;
86
trailer.size = sizeof(struct iovec);
87
trailer.nalloc = NGX_TRAILERS;
88
trailer.pool = c->pool;
75
trailer.iovs = trailers;
76
trailer.nalloc = NGX_IOVS_PREALLOCATE;
101
82
/* create the header iovec and coalesce the neighbouring bufs */
106
for (cl = in; cl && send < limit; cl = cl->next) {
108
if (ngx_buf_special(cl->buf)) {
112
if (!ngx_buf_in_memory_only(cl->buf)) {
116
size = cl->buf->last - cl->buf->pos;
118
if (send + size > limit) {
122
if (prev == cl->buf->pos) {
123
iov->iov_len += (size_t) size;
126
if (header.nelts >= IOV_MAX) {
130
iov = ngx_array_push(&header);
132
return NGX_CHAIN_ERROR;
135
iov->iov_base = (void *) cl->buf->pos;
136
iov->iov_len = (size_t) size;
139
prev = cl->buf->pos + (size_t) size;
84
cl = ngx_output_chain_to_iovec(&header, in, limit - send, c->log);
86
if (cl == NGX_CHAIN_ERROR) {
87
return NGX_CHAIN_ERROR;
145
92
if (cl && cl->buf->in_file && send < limit) {
148
95
/* coalesce the neighbouring file bufs */
151
size = cl->buf->file_last - cl->buf->file_pos;
153
if (send + size > limit) {
156
aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
157
& ~((off_t) ngx_pagesize - 1);
159
if (aligned <= cl->buf->file_last) {
160
size = aligned - cl->buf->file_pos;
166
fprev = cl->buf->file_pos + size;
172
&& file->file->fd == cl->buf->file->fd
173
&& fprev == cl->buf->file_pos);
176
if (file && header.nelts == 0) {
178
/* create the trailer iovec and coalesce the neighbouring bufs */
183
while (cl && send < limit) {
185
if (ngx_buf_special(cl->buf)) {
190
if (!ngx_buf_in_memory_only(cl->buf)) {
194
size = cl->buf->last - cl->buf->pos;
196
if (send + size > limit) {
200
if (prev == cl->buf->pos) {
201
iov->iov_len += (size_t) size;
204
if (trailer.nelts >= IOV_MAX) {
208
iov = ngx_array_push(&trailer);
210
return NGX_CHAIN_ERROR;
213
iov->iov_base = (void *) cl->buf->pos;
214
iov->iov_len = (size_t) size;
217
prev = cl->buf->pos + (size_t) size;
97
file_size = ngx_chain_coalesce_file(&cl, limit - send);
101
if (header.count == 0) {
104
* create the trailer iovec and coalesce the neighbouring bufs
107
cl = ngx_output_chain_to_iovec(&trailer, cl, limit - send,
109
if (cl == NGX_CHAIN_ERROR) {
110
return NGX_CHAIN_ERROR;
113
send += trailer.size;
226
120
* sendfile() returns EINVAL if sf_hdtr's count is 0,
227
121
* but corresponding pointer is not NULL
230
hdtr.headers = header.nelts ? (struct iovec *) header.elts: NULL;
231
hdtr.hdr_cnt = header.nelts;
232
hdtr.trailers = trailer.nelts ? (struct iovec *) trailer.elts: NULL;
233
hdtr.trl_cnt = trailer.nelts;
124
hdtr.headers = header.count ? header.iovs : NULL;
125
hdtr.hdr_cnt = header.count;
126
hdtr.trailers = trailer.count ? trailer.iovs : NULL;
127
hdtr.trl_cnt = trailer.count;
235
sent = header_size + file_size;
129
sent = header.size + file_size;
237
131
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
238
"sendfile: @%O %O h:%O",
239
file->file_pos, sent, header_size);
132
"sendfile: @%O %O h:%uz",
133
file->file_pos, sent, header.size);
241
135
rc = sendfile(file->file->fd, c->fd, file->file_pos,
242
136
&sent, &hdtr, 0);
280
174
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
281
175
"sendfile: %d, @%O %O:%O",
282
rc, file->file_pos, sent, file_size + header_size);
176
rc, file->file_pos, sent, file_size + header.size);
285
rc = writev(c->fd, header.elts, header.nelts);
287
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
288
"writev: %d of %uz", rc, send);
303
ngx_connection_error(c, err, "writev() failed");
304
return NGX_CHAIN_ERROR;
307
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
308
"writev() not ready");
179
n = ngx_writev(c, &header);
181
if (n == NGX_ERROR) {
182
return NGX_CHAIN_ERROR;
311
sent = rc > 0 ? rc : 0;
314
if (send - prev_send == sent) {
185
sent = (n == NGX_AGAIN) ? 0 : n;
320
for ( /* void */ ; in; in = in->next) {
322
if (ngx_buf_special(in->buf)) {
330
size = ngx_buf_size(in->buf);
335
if (ngx_buf_in_memory(in->buf)) {
336
in->buf->pos = in->buf->last;
339
if (in->buf->in_file) {
340
in->buf->file_pos = in->buf->file_last;
346
if (ngx_buf_in_memory(in->buf)) {
347
in->buf->pos += (size_t) sent;
350
if (in->buf->in_file) {
351
in->buf->file_pos += sent;
190
in = ngx_chain_update_sent(in, sent);
193
send = prev_send + sent;
197
if (send - prev_send != sent) {