nxt_conn_write.c (979:7037bef7b9b0) nxt_conn_write.c (1403:1cee885b7f10)
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#include <nxt_main.h>
8
9
10static void nxt_conn_write_timer_handler(nxt_task_t *task, void *obj,
11 void *data);
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#include <nxt_main.h>
8
9
10static void nxt_conn_write_timer_handler(nxt_task_t *task, void *obj,
11 void *data);
12static ssize_t nxt_conn_io_sendfile(nxt_task_t *task, nxt_sendbuf_t *sb);
13static ssize_t nxt_sendfile(int fd, int s, off_t pos, size_t size);
12
13
14void
15nxt_conn_io_write(nxt_task_t *task, void *obj, void *data)
16{
17 ssize_t ret;
18 nxt_buf_t *b;
19 nxt_conn_t *c;

--- 145 unchanged lines hidden (view full) ---

165 struct iovec iov[NXT_IOBUF_MAX];
166
167 niov = nxt_sendbuf_mem_coalesce0(task, sb, iov, NXT_IOBUF_MAX);
168
169 if (niov == 0 && sb->sync) {
170 return 0;
171 }
172
14
15
16void
17nxt_conn_io_write(nxt_task_t *task, void *obj, void *data)
18{
19 ssize_t ret;
20 nxt_buf_t *b;
21 nxt_conn_t *c;

--- 145 unchanged lines hidden (view full) ---

167 struct iovec iov[NXT_IOBUF_MAX];
168
169 niov = nxt_sendbuf_mem_coalesce0(task, sb, iov, NXT_IOBUF_MAX);
170
171 if (niov == 0 && sb->sync) {
172 return 0;
173 }
174
175 if (niov == 0 && nxt_buf_is_file(sb->buf)) {
176 return nxt_conn_io_sendfile(task, sb);
177 }
178
173 return nxt_conn_io_writev(task, sb, iov, niov);
174}
175
176
179 return nxt_conn_io_writev(task, sb, iov, niov);
180}
181
182
183static ssize_t
184nxt_conn_io_sendfile(nxt_task_t *task, nxt_sendbuf_t *sb)
185{
186 size_t size;
187 ssize_t n;
188 nxt_buf_t *b;
189 nxt_err_t err;
190
191 b = sb->buf;
192
193 for ( ;; ) {
194 size = b->file_end - b->file_pos;
195
196 n = nxt_sendfile(b->file->fd, sb->socket, b->file_pos, size);
197
198 err = (n == -1) ? nxt_errno : 0;
199
200 nxt_debug(task, "sendfile(%FD, %d, @%O, %uz): %z",
201 b->file->fd, sb->socket, b->file_pos, size, n);
202
203 if (n > 0) {
204 if (n < (ssize_t) size) {
205 sb->ready = 0;
206 }
207
208 return n;
209 }
210
211 if (nxt_slow_path(n == 0)) {
212 nxt_alert(task, "sendfile() reported that file was truncated at %O",
213 b->file_pos);
214
215 return NXT_ERROR;
216 }
217
218 /* n == -1 */
219
220 switch (err) {
221
222 case NXT_EAGAIN:
223 sb->ready = 0;
224 nxt_debug(task, "sendfile() %E", err);
225
226 return NXT_AGAIN;
227
228 case NXT_EINTR:
229 nxt_debug(task, "sendfile() %E", err);
230 continue;
231
232 default:
233 sb->error = err;
234 nxt_log(task, nxt_socket_error_level(err),
235 "sendfile(%FD, %d, @%O, %uz) failed %E",
236 b->file->fd, sb->socket, b->file_pos, size, err);
237
238 return NXT_ERROR;
239 }
240 }
241}
242
243
244static ssize_t
245nxt_sendfile(int fd, int s, off_t pos, size_t size)
246{
247 ssize_t res;
248
249#ifdef NXT_HAVE_MACOSX_SENDFILE
250 off_t sent = size;
251
252 int rc = sendfile(fd, s, pos, &sent, NULL, 0);
253
254 res = (rc == 0 || sent > 0) ? sent : -1;
255#endif
256
257#ifdef NXT_HAVE_FREEBSD_SENDFILE
258 off_t sent = 0;
259
260 int rc = sendfile(fd, s, pos, size, NULL, &sent, 0);
261
262 res = (rc == 0 || sent > 0) ? sent : -1;
263#endif
264
265#ifdef NXT_HAVE_LINUX_SENDFILE
266 res = sendfile(s, fd, &pos, size);
267#endif
268
269 return res;
270}
271
272
177ssize_t
178nxt_conn_io_writev(nxt_task_t *task, nxt_sendbuf_t *sb, struct iovec *iov,
179 nxt_uint_t niov)
180{
181 ssize_t n;
182 nxt_err_t err;
183
184 if (niov == 1) {

--- 234 unchanged lines hidden ---
273ssize_t
274nxt_conn_io_writev(nxt_task_t *task, nxt_sendbuf_t *sb, struct iovec *iov,
275 nxt_uint_t niov)
276{
277 ssize_t n;
278 nxt_err_t err;
279
280 if (niov == 1) {

--- 234 unchanged lines hidden ---