Mercurial > hg > nginx
annotate src/os/unix/ngx_linux_sendfile_chain.c @ 5885:5a042519bfe7
Upstream: limited next_upstream time and tries when resolving DNS.
When got multiple upstream IP addresses using DNS resolving, the number of
upstreams tries and the maxinum time spent for these tries were not affected.
This patch fixed it.
author | Gu Feng <flygoast@126.com> |
---|---|
date | Mon, 27 Oct 2014 19:52:03 +0800 |
parents | 6bbad2e73245 |
children | de68ed551bfb |
rev | line source |
---|---|
272
d4e65d74db9f
nginx-0.0.2-2004-03-01-00:03:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
262
diff
changeset
|
1 |
d4e65d74db9f
nginx-0.0.2-2004-03-01-00:03:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
262
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
4412 | 4 * Copyright (C) Nginx, Inc. |
272
d4e65d74db9f
nginx-0.0.2-2004-03-01-00:03:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
262
diff
changeset
|
5 */ |
d4e65d74db9f
nginx-0.0.2-2004-03-01-00:03:02 import
Igor Sysoev <igor@sysoev.ru>
parents:
262
diff
changeset
|
6 |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #include <ngx_config.h> |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 #include <ngx_core.h> |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
10 #include <ngx_event.h> |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
11 |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
12 |
199
a65b630b3a66
nginx-0.0.1-2003-11-28-11:40:40 import
Igor Sysoev <igor@sysoev.ru>
parents:
198
diff
changeset
|
13 /* |
a65b630b3a66
nginx-0.0.1-2003-11-28-11:40:40 import
Igor Sysoev <igor@sysoev.ru>
parents:
198
diff
changeset
|
14 * On Linux up to 2.4.21 sendfile() (syscall #187) works with 32-bit |
479 | 15 * offsets only, and the including <sys/sendfile.h> breaks the compiling, |
16 * if off_t is 64 bit wide. So we use own sendfile() definition, where offset | |
17 * parameter is int32_t, and use sendfile() for the file parts below 2G only, | |
18 * see src/os/unix/ngx_linux_config.h | |
199
a65b630b3a66
nginx-0.0.1-2003-11-28-11:40:40 import
Igor Sysoev <igor@sysoev.ru>
parents:
198
diff
changeset
|
19 * |
687
8e446a2daf48
workaround of 2G+ file bug in 64-bit Linux sendfile()
Igor Sysoev <igor@sysoev.ru>
parents:
597
diff
changeset
|
20 * Linux 2.4.21 has the new sendfile64() syscall #239. |
8e446a2daf48
workaround of 2G+ file bug in 64-bit Linux sendfile()
Igor Sysoev <igor@sysoev.ru>
parents:
597
diff
changeset
|
21 * |
8e446a2daf48
workaround of 2G+ file bug in 64-bit Linux sendfile()
Igor Sysoev <igor@sysoev.ru>
parents:
597
diff
changeset
|
22 * On Linux up to 2.6.16 sendfile() does not allow to pass the count parameter |
8e446a2daf48
workaround of 2G+ file bug in 64-bit Linux sendfile()
Igor Sysoev <igor@sysoev.ru>
parents:
597
diff
changeset
|
23 * more than 2G-1 bytes even on 64-bit platforms: it returns EINVAL, |
8e446a2daf48
workaround of 2G+ file bug in 64-bit Linux sendfile()
Igor Sysoev <igor@sysoev.ru>
parents:
597
diff
changeset
|
24 * so we limit it to 2G-1 bytes. |
199
a65b630b3a66
nginx-0.0.1-2003-11-28-11:40:40 import
Igor Sysoev <igor@sysoev.ru>
parents:
198
diff
changeset
|
25 */ |
a65b630b3a66
nginx-0.0.1-2003-11-28-11:40:40 import
Igor Sysoev <igor@sysoev.ru>
parents:
198
diff
changeset
|
26 |
5322
bdb3588681c9
Unbreak building on Linux without sendfile64() support.
Valentin Bartenev <vbart@nginx.com>
parents:
5320
diff
changeset
|
27 #define NGX_SENDFILE_MAXSIZE 2147483647L |
687
8e446a2daf48
workaround of 2G+ file bug in 64-bit Linux sendfile()
Igor Sysoev <igor@sysoev.ru>
parents:
597
diff
changeset
|
28 |
199
a65b630b3a66
nginx-0.0.1-2003-11-28-11:40:40 import
Igor Sysoev <igor@sysoev.ru>
parents:
198
diff
changeset
|
29 |
585 | 30 ngx_chain_t * |
31 ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) | |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
32 { |
589 | 33 int rc, tcp_nodelay; |
34 off_t size, send, prev_send, aligned, sent, fprev; | |
35 u_char *prev; | |
36 size_t file_size; | |
37 ngx_err_t err; | |
38 ngx_buf_t *file; | |
5851
150df089fe47
Removed the "complete" variable from various send chain functions.
Valentin Bartenev <vbart@nginx.com>
parents:
5850
diff
changeset
|
39 ngx_uint_t eintr; |
589 | 40 ngx_array_t header; |
41 ngx_event_t *wev; | |
42 ngx_chain_t *cl; | |
5854
b63e829621ab
Generalized definitions of the number of preallocated iovec's.
Valentin Bartenev <vbart@nginx.com>
parents:
5851
diff
changeset
|
43 struct iovec *iov, headers[NGX_IOVS_PREALLOCATE]; |
455 | 44 #if (NGX_HAVE_SENDFILE64) |
589 | 45 off_t offset; |
198
34995c5ec6c4
nginx-0.0.1-2003-11-27-22:01:37 import
Igor Sysoev <igor@sysoev.ru>
parents:
196
diff
changeset
|
46 #else |
589 | 47 int32_t offset; |
198
34995c5ec6c4
nginx-0.0.1-2003-11-27-22:01:37 import
Igor Sysoev <igor@sysoev.ru>
parents:
196
diff
changeset
|
48 #endif |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
49 |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
50 wev = c->write; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
51 |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
52 if (!wev->ready) { |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
53 return in; |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
54 } |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
55 |
473 | 56 |
687
8e446a2daf48
workaround of 2G+ file bug in 64-bit Linux sendfile()
Igor Sysoev <igor@sysoev.ru>
parents:
597
diff
changeset
|
57 /* the maximum limit size is 2G-1 - the page size */ |
473 | 58 |
5322
bdb3588681c9
Unbreak building on Linux without sendfile64() support.
Valentin Bartenev <vbart@nginx.com>
parents:
5320
diff
changeset
|
59 if (limit == 0 || limit > (off_t) (NGX_SENDFILE_MAXSIZE - ngx_pagesize)) { |
bdb3588681c9
Unbreak building on Linux without sendfile64() support.
Valentin Bartenev <vbart@nginx.com>
parents:
5320
diff
changeset
|
60 limit = NGX_SENDFILE_MAXSIZE - ngx_pagesize; |
473 | 61 } |
62 | |
63 | |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
64 send = 0; |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
65 |
428
5e73d0ea4dab
nginx-0.0.11-2004-09-16-20:10:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
402
diff
changeset
|
66 header.elts = headers; |
5e73d0ea4dab
nginx-0.0.11-2004-09-16-20:10:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
402
diff
changeset
|
67 header.size = sizeof(struct iovec); |
5854
b63e829621ab
Generalized definitions of the number of preallocated iovec's.
Valentin Bartenev <vbart@nginx.com>
parents:
5851
diff
changeset
|
68 header.nalloc = NGX_IOVS_PREALLOCATE; |
428
5e73d0ea4dab
nginx-0.0.11-2004-09-16-20:10:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
402
diff
changeset
|
69 header.pool = c->pool; |
5e73d0ea4dab
nginx-0.0.11-2004-09-16-20:10:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
402
diff
changeset
|
70 |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
71 for ( ;; ) { |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
72 file = NULL; |
473 | 73 file_size = 0; |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
74 eintr = 0; |
473 | 75 prev_send = send; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
76 |
428
5e73d0ea4dab
nginx-0.0.11-2004-09-16-20:10:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
402
diff
changeset
|
77 header.nelts = 0; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
78 |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
79 prev = NULL; |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
80 iov = NULL; |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
81 |
343
6bdf858bff8c
nginx-0.0.3-2004-05-28-19:49:23 import; rename ngx_hunk_t to ngx_buf_t
Igor Sysoev <igor@sysoev.ru>
parents:
290
diff
changeset
|
82 /* create the iovec and coalesce the neighbouring bufs */ |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
83 |
4596
089cc5154c1e
IOV_MAX handling microoptimization.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
84 for (cl = in; cl && send < limit; cl = cl->next) { |
089cc5154c1e
IOV_MAX handling microoptimization.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
85 |
344
e366ba5db8f8
nginx-0.0.3-2004-06-01-10:04:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
343
diff
changeset
|
86 if (ngx_buf_special(cl->buf)) { |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
87 continue; |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
88 } |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
89 |
479 | 90 #if 1 |
91 if (!ngx_buf_in_memory(cl->buf) && !cl->buf->in_file) { | |
92 ngx_log_error(NGX_LOG_ALERT, c->log, 0, | |
483 | 93 "zero size buf in sendfile " |
94 "t:%d r:%d f:%d %p %p-%p %p %O-%O", | |
95 cl->buf->temporary, | |
96 cl->buf->recycled, | |
97 cl->buf->in_file, | |
98 cl->buf->start, | |
99 cl->buf->pos, | |
100 cl->buf->last, | |
101 cl->buf->file, | |
102 cl->buf->file_pos, | |
103 cl->buf->file_last); | |
104 | |
479 | 105 ngx_debug_point(); |
489 | 106 |
107 return NGX_CHAIN_ERROR; | |
479 | 108 } |
109 #endif | |
110 | |
344
e366ba5db8f8
nginx-0.0.3-2004-06-01-10:04:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
343
diff
changeset
|
111 if (!ngx_buf_in_memory_only(cl->buf)) { |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
112 break; |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
113 } |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
114 |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
115 size = cl->buf->last - cl->buf->pos; |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
116 |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
117 if (send + size > limit) { |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
118 size = limit - send; |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
119 } |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
120 |
344
e366ba5db8f8
nginx-0.0.3-2004-06-01-10:04:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
343
diff
changeset
|
121 if (prev == cl->buf->pos) { |
473 | 122 iov->iov_len += (size_t) size; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
123 |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
124 } else { |
4596
089cc5154c1e
IOV_MAX handling microoptimization.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
125 if (header.nelts >= IOV_MAX) { |
089cc5154c1e
IOV_MAX handling microoptimization.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
126 break; |
089cc5154c1e
IOV_MAX handling microoptimization.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
127 } |
089cc5154c1e
IOV_MAX handling microoptimization.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
128 |
501 | 129 iov = ngx_array_push(&header); |
130 if (iov == NULL) { | |
428
5e73d0ea4dab
nginx-0.0.11-2004-09-16-20:10:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
402
diff
changeset
|
131 return NGX_CHAIN_ERROR; |
5e73d0ea4dab
nginx-0.0.11-2004-09-16-20:10:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
402
diff
changeset
|
132 } |
5e73d0ea4dab
nginx-0.0.11-2004-09-16-20:10:13 import
Igor Sysoev <igor@sysoev.ru>
parents:
402
diff
changeset
|
133 |
344
e366ba5db8f8
nginx-0.0.3-2004-06-01-10:04:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
343
diff
changeset
|
134 iov->iov_base = (void *) cl->buf->pos; |
473 | 135 iov->iov_len = (size_t) size; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
136 } |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
137 |
473 | 138 prev = cl->buf->pos + (size_t) size; |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
139 send += size; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
140 } |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
141 |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
142 /* set TCP_CORK if there is a header before a file */ |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
143 |
344
e366ba5db8f8
nginx-0.0.3-2004-06-01-10:04:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
343
diff
changeset
|
144 if (c->tcp_nopush == NGX_TCP_NOPUSH_UNSET |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
145 && header.nelts != 0 |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
146 && cl |
344
e366ba5db8f8
nginx-0.0.3-2004-06-01-10:04:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
343
diff
changeset
|
147 && cl->buf->in_file) |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
148 { |
473 | 149 /* the TCP_CORK and TCP_NODELAY are mutually exclusive */ |
150 | |
483 | 151 if (c->tcp_nodelay == NGX_TCP_NODELAY_SET) { |
473 | 152 |
153 tcp_nodelay = 0; | |
154 | |
155 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, | |
156 (const void *) &tcp_nodelay, sizeof(int)) == -1) | |
157 { | |
5557
188481078faf
Use ngx_socket_errno where appropriate.
Piotr Sikora <piotr@cloudflare.com>
parents:
5322
diff
changeset
|
158 err = ngx_socket_errno; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
159 |
473 | 160 /* |
479 | 161 * there is a tiny chance to be interrupted, however, |
473 | 162 * we continue a processing with the TCP_NODELAY |
163 * and without the TCP_CORK | |
164 */ | |
165 | |
577 | 166 if (err != NGX_EINTR) { |
473 | 167 wev->error = 1; |
483 | 168 ngx_connection_error(c, err, |
473 | 169 "setsockopt(TCP_NODELAY) failed"); |
170 return NGX_CHAIN_ERROR; | |
171 } | |
172 | |
173 } else { | |
483 | 174 c->tcp_nodelay = NGX_TCP_NODELAY_UNSET; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
175 |
5222
23a186e8ca45
Style: remove unnecessary references to HTTP from non-HTTP modules.
Piotr Sikora <piotr@cloudflare.com>
parents:
4596
diff
changeset
|
176 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
473 | 177 "no tcp_nodelay"); |
253
b6793bc5034b
nginx-0.0.2-2004-02-09-10:46:43 import
Igor Sysoev <igor@sysoev.ru>
parents:
247
diff
changeset
|
178 } |
473 | 179 } |
180 | |
483 | 181 if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) { |
473 | 182 |
183 if (ngx_tcp_nopush(c->fd) == NGX_ERROR) { | |
5557
188481078faf
Use ngx_socket_errno where appropriate.
Piotr Sikora <piotr@cloudflare.com>
parents:
5322
diff
changeset
|
184 err = ngx_socket_errno; |
253
b6793bc5034b
nginx-0.0.2-2004-02-09-10:46:43 import
Igor Sysoev <igor@sysoev.ru>
parents:
247
diff
changeset
|
185 |
473 | 186 /* |
479 | 187 * there is a tiny chance to be interrupted, however, |
473 | 188 * we continue a processing without the TCP_CORK |
189 */ | |
344
e366ba5db8f8
nginx-0.0.3-2004-06-01-10:04:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
343
diff
changeset
|
190 |
577 | 191 if (err != NGX_EINTR) { |
473 | 192 wev->error = 1; |
193 ngx_connection_error(c, err, | |
194 ngx_tcp_nopush_n " failed"); | |
195 return NGX_CHAIN_ERROR; | |
196 } | |
197 | |
198 } else { | |
199 c->tcp_nopush = NGX_TCP_NOPUSH_SET; | |
577 | 200 |
473 | 201 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, |
202 "tcp_nopush"); | |
203 } | |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
204 } |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
205 } |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
206 |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
207 /* get the file buf */ |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
208 |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
209 if (header.nelts == 0 && cl && cl->buf->in_file && send < limit) { |
344
e366ba5db8f8
nginx-0.0.3-2004-06-01-10:04:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
343
diff
changeset
|
210 file = cl->buf; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
211 |
344
e366ba5db8f8
nginx-0.0.3-2004-06-01-10:04:46 import
Igor Sysoev <igor@sysoev.ru>
parents:
343
diff
changeset
|
212 /* coalesce the neighbouring file bufs */ |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
213 |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
214 do { |
473 | 215 size = cl->buf->file_last - cl->buf->file_pos; |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
216 |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
217 if (send + size > limit) { |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
218 size = limit - send; |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
219 |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
220 aligned = (cl->buf->file_pos + size + ngx_pagesize - 1) |
1182
df449f4a8032
fix sendfile on 64-bit Linux and limit_rate on all 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
687
diff
changeset
|
221 & ~((off_t) ngx_pagesize - 1); |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
222 |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
223 if (aligned <= cl->buf->file_last) { |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
224 size = aligned - cl->buf->file_pos; |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
225 } |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
226 } |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
227 |
473 | 228 file_size += (size_t) size; |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
229 send += size; |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
230 fprev = cl->buf->file_pos + size; |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
231 cl = cl->next; |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
232 |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
233 } while (cl |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
234 && cl->buf->in_file |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
235 && send < limit |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
236 && file->file->fd == cl->buf->file->fd |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
237 && fprev == cl->buf->file_pos); |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
238 } |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
239 |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
240 if (file) { |
589 | 241 #if 1 |
242 if (file_size == 0) { | |
243 ngx_debug_point(); | |
244 return NGX_CHAIN_ERROR; | |
245 } | |
246 #endif | |
455 | 247 #if (NGX_HAVE_SENDFILE64) |
196
11fbd0fc041d
nginx-0.0.1-2003-11-26-18:42:18 import
Igor Sysoev <igor@sysoev.ru>
parents:
195
diff
changeset
|
248 offset = file->file_pos; |
198
34995c5ec6c4
nginx-0.0.1-2003-11-27-22:01:37 import
Igor Sysoev <igor@sysoev.ru>
parents:
196
diff
changeset
|
249 #else |
34995c5ec6c4
nginx-0.0.1-2003-11-27-22:01:37 import
Igor Sysoev <igor@sysoev.ru>
parents:
196
diff
changeset
|
250 offset = (int32_t) file->file_pos; |
34995c5ec6c4
nginx-0.0.1-2003-11-27-22:01:37 import
Igor Sysoev <igor@sysoev.ru>
parents:
196
diff
changeset
|
251 #endif |
1198 | 252 |
253 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | |
254 "sendfile: @%O %uz", file->file_pos, file_size); | |
255 | |
473 | 256 rc = sendfile(c->fd, file->file->fd, &offset, file_size); |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
257 |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
258 if (rc == -1) { |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
259 err = ngx_errno; |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
260 |
3063
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
261 switch (err) { |
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
262 case NGX_EAGAIN: |
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
263 break; |
253
b6793bc5034b
nginx-0.0.2-2004-02-09-10:46:43 import
Igor Sysoev <igor@sysoev.ru>
parents:
247
diff
changeset
|
264 |
3063
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
265 case NGX_EINTR: |
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
266 eintr = 1; |
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
267 break; |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
268 |
3063
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
269 default: |
253
b6793bc5034b
nginx-0.0.2-2004-02-09-10:46:43 import
Igor Sysoev <igor@sysoev.ru>
parents:
247
diff
changeset
|
270 wev->error = 1; |
b6793bc5034b
nginx-0.0.2-2004-02-09-10:46:43 import
Igor Sysoev <igor@sysoev.ru>
parents:
247
diff
changeset
|
271 ngx_connection_error(c, err, "sendfile() failed"); |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
272 return NGX_CHAIN_ERROR; |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
273 } |
3063
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
274 |
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
275 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, |
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
276 "sendfile() is not ready"); |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
277 } |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
278 |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
279 sent = rc > 0 ? rc : 0; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
280 |
253
b6793bc5034b
nginx-0.0.2-2004-02-09-10:46:43 import
Igor Sysoev <igor@sysoev.ru>
parents:
247
diff
changeset
|
281 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0, |
473 | 282 "sendfile: %d, @%O %O:%uz", |
283 rc, file->file_pos, sent, file_size); | |
253
b6793bc5034b
nginx-0.0.2-2004-02-09-10:46:43 import
Igor Sysoev <igor@sysoev.ru>
parents:
247
diff
changeset
|
284 |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
285 } else { |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
286 rc = writev(c->fd, header.elts, header.nelts); |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
287 |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
288 if (rc == -1) { |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
289 err = ngx_errno; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
290 |
3063
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
291 switch (err) { |
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
292 case NGX_EAGAIN: |
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
293 break; |
253
b6793bc5034b
nginx-0.0.2-2004-02-09-10:46:43 import
Igor Sysoev <igor@sysoev.ru>
parents:
247
diff
changeset
|
294 |
3063
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
295 case NGX_EINTR: |
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
296 eintr = 1; |
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
297 break; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
298 |
3063
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
299 default: |
253
b6793bc5034b
nginx-0.0.2-2004-02-09-10:46:43 import
Igor Sysoev <igor@sysoev.ru>
parents:
247
diff
changeset
|
300 wev->error = 1; |
b6793bc5034b
nginx-0.0.2-2004-02-09-10:46:43 import
Igor Sysoev <igor@sysoev.ru>
parents:
247
diff
changeset
|
301 ngx_connection_error(c, err, "writev() failed"); |
577 | 302 return NGX_CHAIN_ERROR; |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
303 } |
3063
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
304 |
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
305 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, |
6f6d7ea70805
refactor EAGAIN/EINTR processing
Igor Sysoev <igor@sysoev.ru>
parents:
1354
diff
changeset
|
306 "writev() not ready"); |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
307 } |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
308 |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
309 sent = rc > 0 ? rc : 0; |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
310 |
473 | 311 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %O", sent); |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
312 } |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
313 |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
314 c->sent += sent; |
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
315 |
5850
f9c83484d9ce
Moved the code for adjusting sent buffers in a separate function.
Valentin Bartenev <vbart@nginx.com>
parents:
5557
diff
changeset
|
316 in = ngx_handle_sent_chain(in, sent); |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
317 |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
318 if (eintr) { |
5868
6bbad2e73245
Fixed counting of sent bytes in the send chain functions on EINTR.
Valentin Bartenev <vbart@nginx.com>
parents:
5854
diff
changeset
|
319 send = prev_send; |
577 | 320 continue; |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
321 } |
195
8dee38ea9117
nginx-0.0.1-2003-11-25-23:44:56 import
Igor Sysoev <igor@sysoev.ru>
parents:
97
diff
changeset
|
322 |
5851
150df089fe47
Removed the "complete" variable from various send chain functions.
Valentin Bartenev <vbart@nginx.com>
parents:
5850
diff
changeset
|
323 if (send - prev_send != sent) { |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
324 wev->ready = 0; |
5320
ad137a80919f
Don't lose pointer to first nonempty buf in ngx_*_sendfile_chain().
Gleb Smirnoff <glebius@nginx.com>
parents:
5222
diff
changeset
|
325 return in; |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
326 } |
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
327 |
5320
ad137a80919f
Don't lose pointer to first nonempty buf in ngx_*_sendfile_chain().
Gleb Smirnoff <glebius@nginx.com>
parents:
5222
diff
changeset
|
328 if (send >= limit || in == NULL) { |
ad137a80919f
Don't lose pointer to first nonempty buf in ngx_*_sendfile_chain().
Gleb Smirnoff <glebius@nginx.com>
parents:
5222
diff
changeset
|
329 return in; |
362
7650aea1816f
nginx-0.0.7-2004-06-21-19:59:32 import
Igor Sysoev <igor@sysoev.ru>
parents:
344
diff
changeset
|
330 } |
97
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
331 } |
70d2345a903f
nginx-0.0.1-2003-05-29-17:02:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
332 } |