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 */