Mercurial > hg > nginx
comparison src/os/unix/ngx_freebsd_sendfile_chain.c @ 155:46eb23d9471d
nginx-0.0.1-2003-10-22-20:38:26 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 22 Oct 2003 16:38:26 +0000 |
parents | eac26585476e |
children | fb61ba77beba |
comparison
equal
deleted
inserted
replaced
154:eac26585476e | 155:46eb23d9471d |
---|---|
30 struct iovec *iov; | 30 struct iovec *iov; |
31 struct sf_hdtr hdtr; | 31 struct sf_hdtr hdtr; |
32 ngx_err_t err; | 32 ngx_err_t err; |
33 ngx_array_t header, trailer; | 33 ngx_array_t header, trailer; |
34 ngx_hunk_t *file; | 34 ngx_hunk_t *file; |
35 ngx_chain_t *ce, *tail; | 35 ngx_chain_t *cl, *tail; |
36 | 36 |
37 if (!c->write->ready) { | 37 if (!c->write->ready) { |
38 return in; | 38 return in; |
39 } | 39 } |
40 | 40 |
41 do { | 41 do { |
42 ce = in; | 42 cl = in; |
43 file = NULL; | 43 file = NULL; |
44 fsize = 0; | 44 fsize = 0; |
45 hsize = 0; | 45 hsize = 0; |
46 eintr = 0; | 46 eintr = 0; |
47 eagain = 0; | 47 eagain = 0; |
49 ngx_init_array(header, c->pool, 10, sizeof(struct iovec), | 49 ngx_init_array(header, c->pool, 10, sizeof(struct iovec), |
50 NGX_CHAIN_ERROR); | 50 NGX_CHAIN_ERROR); |
51 ngx_init_array(trailer, c->pool, 10, sizeof(struct iovec), | 51 ngx_init_array(trailer, c->pool, 10, sizeof(struct iovec), |
52 NGX_CHAIN_ERROR); | 52 NGX_CHAIN_ERROR); |
53 | 53 |
54 /* create the iovec and coalesce the neighbouring chain entries */ | 54 /* create the header iovec and coalesce the neighbouring hunks */ |
55 | 55 |
56 prev = NULL; | 56 prev = NULL; |
57 iov = NULL; | 57 iov = NULL; |
58 | 58 |
59 for (ce = in; ce; ce = ce->next) { | 59 for (cl = in; cl; cl = cl->next) { |
60 if (ngx_hunk_special(ce->hunk)) { | 60 if (ngx_hunk_special(cl->hunk)) { |
61 continue; | 61 continue; |
62 } | 62 } |
63 | 63 |
64 if (!ngx_hunk_in_memory_only(ce->hunk)) { | 64 if (!ngx_hunk_in_memory_only(cl->hunk)) { |
65 break; | 65 break; |
66 } | 66 } |
67 | 67 |
68 if (prev == ce->hunk->pos) { | 68 if (prev == cl->hunk->pos) { |
69 iov->iov_len += ce->hunk->last - ce->hunk->pos; | 69 iov->iov_len += cl->hunk->last - cl->hunk->pos; |
70 prev = ce->hunk->last; | 70 prev = cl->hunk->last; |
71 | 71 |
72 } else { | 72 } else { |
73 ngx_test_null(iov, ngx_push_array(&header), NGX_CHAIN_ERROR); | 73 ngx_test_null(iov, ngx_push_array(&header), NGX_CHAIN_ERROR); |
74 iov->iov_base = ce->hunk->pos; | 74 iov->iov_base = cl->hunk->pos; |
75 iov->iov_len = ce->hunk->last - ce->hunk->pos; | 75 iov->iov_len = cl->hunk->last - cl->hunk->pos; |
76 prev = ce->hunk->last; | 76 prev = cl->hunk->last; |
77 } | 77 } |
78 | 78 |
79 hsize += ce->hunk->last - ce->hunk->pos; | 79 hsize += cl->hunk->last - cl->hunk->pos; |
80 } | 80 } |
81 | 81 |
82 /* get the file hunk */ | 82 /* get the file hunk */ |
83 | 83 |
84 if (ce && (ce->hunk->type & NGX_HUNK_FILE)) { | 84 if (cl && (cl->hunk->type & NGX_HUNK_FILE)) { |
85 file = ce->hunk; | 85 file = cl->hunk; |
86 fsize = (size_t) (file->file_last - file->file_pos); | 86 fsize = (size_t) (file->file_last - file->file_pos); |
87 fprev = file->file_last; | 87 fprev = file->file_last; |
88 ce = ce->next; | 88 cl = cl->next; |
89 | 89 |
90 /* coalesce the neighbouring file hunks */ | 90 /* coalesce the neighbouring file hunks */ |
91 | 91 |
92 while (ce && (ce->hunk->type & NGX_HUNK_FILE)) { | 92 while (cl && (cl->hunk->type & NGX_HUNK_FILE)) { |
93 if (file->file->fd != ce->hunk->file->fd | 93 if (file->file->fd != cl->hunk->file->fd |
94 || fprev != ce->hunk->file_pos) | 94 || fprev != cl->hunk->file_pos) |
95 { | 95 { |
96 break; | 96 break; |
97 } | 97 } |
98 | 98 |
99 fsize += (size_t) (ce->hunk->file_last - ce->hunk->file_pos); | 99 fsize += (size_t) (cl->hunk->file_last - cl->hunk->file_pos); |
100 fprev = ce->hunk->file_last; | 100 fprev = cl->hunk->file_last; |
101 ce = ce->next; | 101 cl = cl->next; |
102 } | 102 } |
103 } | 103 } |
104 | 104 |
105 /* create the iovec and coalesce the neighbouring chain entries */ | 105 /* create the tailer iovec and coalesce the neighbouring hunks */ |
106 | 106 |
107 prev = NULL; | 107 prev = NULL; |
108 iov = NULL; | 108 iov = NULL; |
109 | 109 |
110 for ( /* void */; ce; ce = ce->next) { | 110 for ( /* void */; cl; cl = cl->next) { |
111 if (ngx_hunk_special(ce->hunk)) { | 111 if (ngx_hunk_special(cl->hunk)) { |
112 continue; | 112 continue; |
113 } | 113 } |
114 | 114 |
115 if (!ngx_hunk_in_memory_only(ce->hunk)) { | 115 if (!ngx_hunk_in_memory_only(cl->hunk)) { |
116 break; | 116 break; |
117 } | 117 } |
118 | 118 |
119 if (prev == ce->hunk->pos) { | 119 if (prev == cl->hunk->pos) { |
120 iov->iov_len += ce->hunk->last - ce->hunk->pos; | 120 iov->iov_len += cl->hunk->last - cl->hunk->pos; |
121 prev = ce->hunk->last; | 121 prev = cl->hunk->last; |
122 | 122 |
123 } else { | 123 } else { |
124 ngx_test_null(iov, ngx_push_array(&trailer), NGX_CHAIN_ERROR); | 124 ngx_test_null(iov, ngx_push_array(&trailer), NGX_CHAIN_ERROR); |
125 iov->iov_base = ce->hunk->pos; | 125 iov->iov_base = cl->hunk->pos; |
126 iov->iov_len = ce->hunk->last - ce->hunk->pos; | 126 iov->iov_len = cl->hunk->last - cl->hunk->pos; |
127 prev = ce->hunk->last; | 127 prev = cl->hunk->last; |
128 } | 128 } |
129 } | 129 } |
130 | 130 |
131 /* | 131 /* |
132 * the tail is the rest of the chain that exceeded | 132 * the tail is the rest of the chain that exceeded |
133 * a single sendfile() capability | 133 * a single sendfile() capability |
134 */ | 134 */ |
135 | 135 |
136 tail = ce; | 136 tail = cl; |
137 | 137 |
138 if (file) { | 138 if (file) { |
139 | 139 |
140 if (ngx_freebsd_use_tcp_nopush && !c->tcp_nopush) { | 140 if (ngx_freebsd_use_tcp_nopush && !c->tcp_nopush) { |
141 c->tcp_nopush = 1; | 141 c->tcp_nopush = 1; |
153 hdtr.hdr_cnt = header.nelts; | 153 hdtr.hdr_cnt = header.nelts; |
154 hdtr.trailers = (struct iovec *) trailer.elts; | 154 hdtr.trailers = (struct iovec *) trailer.elts; |
155 hdtr.trl_cnt = trailer.nelts; | 155 hdtr.trl_cnt = trailer.nelts; |
156 | 156 |
157 /* | 157 /* |
158 * the old sendfile() "nbytes bug": | 158 * the "nbytes bug" of the old sendfile() syscall: |
159 * http://www.freebsd.org/cgi/query-pr.cgi?pr=33771 | 159 * http://www.freebsd.org/cgi/query-pr.cgi?pr=33771 |
160 */ | 160 */ |
161 | 161 |
162 if (ngx_freebsd_sendfile_nbytes_bug == 0) { | 162 if (ngx_freebsd_sendfile_nbytes_bug == 0) { |
163 hsize = 0; | 163 hsize = 0; |
218 #endif | 218 #endif |
219 } | 219 } |
220 | 220 |
221 c->sent += sent; | 221 c->sent += sent; |
222 | 222 |
223 for (ce = in; ce; ce = ce->next) { | 223 for (cl = in; cl; cl = cl->next) { |
224 | 224 |
225 if (ngx_hunk_special(ce->hunk)) { | 225 if (ngx_hunk_special(cl->hunk)) { |
226 continue; | 226 continue; |
227 } | 227 } |
228 | 228 |
229 if (sent == 0) { | 229 if (sent == 0) { |
230 break; | 230 break; |
231 } | 231 } |
232 | 232 |
233 size = ngx_hunk_size(ce->hunk); | 233 size = ngx_hunk_size(cl->hunk); |
234 | 234 |
235 if (sent >= size) { | 235 if (sent >= size) { |
236 sent -= size; | 236 sent -= size; |
237 | 237 |
238 if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { | 238 if (cl->hunk->type & NGX_HUNK_IN_MEMORY) { |
239 ce->hunk->pos = ce->hunk->last; | 239 cl->hunk->pos = cl->hunk->last; |
240 } | 240 } |
241 | 241 |
242 if (ce->hunk->type & NGX_HUNK_FILE) { | 242 if (cl->hunk->type & NGX_HUNK_FILE) { |
243 ce->hunk->file_pos = ce->hunk->file_last; | 243 cl->hunk->file_pos = cl->hunk->file_last; |
244 } | 244 } |
245 | 245 |
246 continue; | 246 continue; |
247 } | 247 } |
248 | 248 |
249 if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { | 249 if (cl->hunk->type & NGX_HUNK_IN_MEMORY) { |
250 ce->hunk->pos += sent; | 250 cl->hunk->pos += sent; |
251 } | 251 } |
252 | 252 |
253 if (ce->hunk->type & NGX_HUNK_FILE) { | 253 if (cl->hunk->type & NGX_HUNK_FILE) { |
254 ce->hunk->file_pos += sent; | 254 cl->hunk->file_pos += sent; |
255 } | 255 } |
256 | 256 |
257 break; | 257 break; |
258 } | 258 } |
259 | 259 |
260 in = ce; | 260 in = cl; |
261 | 261 |
262 if (eagain) { | 262 if (eagain) { |
263 | |
263 /* | 264 /* |
264 * sendfile() can return EAGAIN even if it has sent | 265 * sendfile() can return EAGAIN even if it has sent |
265 * a whole file part and successive sendfile() would | 266 * a whole file part and successive sendfile() would |
266 * return EAGAIN right away and would not send anything. | 267 * return EAGAIN right away and would not send anything |
267 */ | 268 */ |
269 | |
268 c->write->ready = 0; | 270 c->write->ready = 0; |
269 break; | 271 break; |
270 } | 272 } |
271 | 273 |
272 /* "tail == in" means that a single sendfile() is complete */ | 274 /* "tail == in" means that a single sendfile() is complete */ |