comparison src/os/unix/ngx_freebsd_sendfile_chain.c @ 142:cb77c084acdb

nginx-0.0.1-2003-10-09-11:00:45 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 09 Oct 2003 07:00:45 +0000
parents 6dfda4cf5200
children 5526213be452
comparison
equal deleted inserted replaced
141:656d468f4ead 142:cb77c084acdb
1 1
2 #include <ngx_config.h> 2 #include <ngx_config.h>
3 #include <ngx_core.h> 3 #include <ngx_core.h>
4 #include <ngx_event.h>
4 #include <ngx_freebsd_init.h> 5 #include <ngx_freebsd_init.h>
5 6
6 7
7 /* 8 /*
8 sendfile() often sends 4K pages over ethernet in 3 packets: 2x1460 and 1176 9 * sendfile() often sends 4K pages over ethernet in 3 packets: 2x1460 and 1176
9 or in 6 packets: 5x1460 and 892. Besides although sendfile() allows 10 * or in 6 packets: 5x1460 and 892. Besides although sendfile() allows
10 to pass the header and the trailer it never sends the header or the trailer 11 * to pass the header and the trailer it never sends the header or the trailer
11 with the part of the file in one packet. So we use TCP_NOPUSH (similar 12 * with the part of the file in one packet. So we use TCP_NOPUSH (similar
12 to Linux's TCP_CORK) to postpone the sending - it not only sends the header 13 * to Linux's TCP_CORK) to postpone the sending - it not only sends the header
13 and the first part of the file in one packet but also sends 4K pages 14 * and the first part of the file in one packet but also sends 4K pages
14 in the full packets. 15 * in the full packets.
15 16 *
16 Until FreeBSD 4.5 the turning TCP_NOPUSH off does not not flush 17 * Until FreeBSD 4.5 the turning TCP_NOPUSH off does not not flush
17 the pending data that less than MSS and the data sent with 5 second delay. 18 * the pending data that less than MSS and the data sent with 5 second delay.
18 So we use TCP_NOPUSH on FreeBSD prior to 4.5 only if the connection 19 * So we use TCP_NOPUSH on FreeBSD prior to 4.5 only if the connection
19 is not needed not keepalive. 20 * is not needed to be keepalive.
20 */ 21 */
21 22
22 23
23 ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in) 24 ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
24 { 25 {
25 int rc, eintr, tcp_nopush; 26 int rc, eintr, tcp_nopush;
45 NGX_CHAIN_ERROR); 46 NGX_CHAIN_ERROR);
46 ngx_init_array(trailer, c->pool, 10, sizeof(struct iovec), 47 ngx_init_array(trailer, c->pool, 10, sizeof(struct iovec),
47 NGX_CHAIN_ERROR); 48 NGX_CHAIN_ERROR);
48 49
49 /* create the header iovec */ 50 /* create the header iovec */
50 if (ngx_hunk_in_memory_only(ce->hunk)) { 51
52 #if 0
53 if (ngx_hunk_in_memory_only(ce->hunk) || ngx_hunk_special(ce->hunk)) {
54 #endif
51 prev = NULL; 55 prev = NULL;
52 iov = NULL; 56 iov = NULL;
53 57
54 /* create the iovec and coalesce the neighbouring chain entries */ 58 /* create the iovec and coalesce the neighbouring chain entries */
55 while (ce && ngx_hunk_in_memory_only(ce->hunk)) { 59
60 for ( /* void */; ce; ce = ce->next) {
61 if (ngx_hunk_special(ce->hunk)) {
62 continue;
63 }
64
65 if (!ngx_hunk_in_memory_only(ce->hunk)) {
66 break;
67 }
56 68
57 if (prev == ce->hunk->pos) { 69 if (prev == ce->hunk->pos) {
58 iov->iov_len += ce->hunk->last - ce->hunk->pos; 70 iov->iov_len += ce->hunk->last - ce->hunk->pos;
59 prev = ce->hunk->last; 71 prev = ce->hunk->last;
60 72
65 iov->iov_len = ce->hunk->last - ce->hunk->pos; 77 iov->iov_len = ce->hunk->last - ce->hunk->pos;
66 prev = ce->hunk->last; 78 prev = ce->hunk->last;
67 } 79 }
68 80
69 hsize += ce->hunk->last - ce->hunk->pos; 81 hsize += ce->hunk->last - ce->hunk->pos;
70 82 }
71 ce = ce->next; 83 #if 0
72 } 84 }
73 } 85 #endif
74 86
75 /* TODO: coalesce the neighbouring file hunks */ 87 /* TODO: coalesce the neighbouring file hunks */
88
76 if (ce && (ce->hunk->type & NGX_HUNK_FILE)) { 89 if (ce && (ce->hunk->type & NGX_HUNK_FILE)) {
77 file = ce->hunk; 90 file = ce->hunk;
78 ce = ce->next; 91 ce = ce->next;
79 } 92 }
80 93
81 /* create the trailer iovec */ 94 /* create the trailer iovec */
82 if (ce && ngx_hunk_in_memory_only(ce->hunk)) { 95
96 #if 0
97 if (ce
98 && (ngx_hunk_in_memory_only(ce->hunk)
99 || ngx_hunk_special(ce->hunk)))
100 {
101 #endif
83 prev = NULL; 102 prev = NULL;
84 iov = NULL; 103 iov = NULL;
85 104
86 /* create the iovec and coalesce the neighbouring chain entries */ 105 /* create the iovec and coalesce the neighbouring chain entries */
87 while (ce && ngx_hunk_in_memory_only(ce->hunk)) { 106
107 for ( /* void */; ce; ce = ce->next) {
108 if (ngx_hunk_special(ce->hunk)) {
109 continue;
110 }
111
112 if (!ngx_hunk_in_memory_only(ce->hunk)) {
113 break;
114 }
88 115
89 if (prev == ce->hunk->pos) { 116 if (prev == ce->hunk->pos) {
90 iov->iov_len += ce->hunk->last - ce->hunk->pos; 117 iov->iov_len += ce->hunk->last - ce->hunk->pos;
91 prev = ce->hunk->last; 118 prev = ce->hunk->last;
92 119
95 NGX_CHAIN_ERROR); 122 NGX_CHAIN_ERROR);
96 iov->iov_base = ce->hunk->pos; 123 iov->iov_base = ce->hunk->pos;
97 iov->iov_len = ce->hunk->last - ce->hunk->pos; 124 iov->iov_len = ce->hunk->last - ce->hunk->pos;
98 prev = ce->hunk->last; 125 prev = ce->hunk->last;
99 } 126 }
100 127 }
101 ce = ce->next; 128 #if 0
102 } 129 }
103 } 130 #endif
104 131
105 tail = ce; 132 tail = ce;
106 133
107 if (file) { 134 if (file) {
108 135
153 rc _ file->file_pos _ sent _ 180 rc _ file->file_pos _ sent _
154 (size_t) (file->file_last - file->file_pos) + hsize); 181 (size_t) (file->file_last - file->file_pos) + hsize);
155 #endif 182 #endif
156 183
157 } else { 184 } else {
158 rc = writev(c->fd, (struct iovec *) header.elts, header.nelts); 185 if (hsize) {
159 186 rc = writev(c->fd, (struct iovec *) header.elts, header.nelts);
160 if (rc == -1) { 187
161 err = ngx_errno; 188 if (rc == -1) {
162 if (err == NGX_EAGAIN) { 189 err = ngx_errno;
163 ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN"); 190 if (err == NGX_EAGAIN) {
164 191 ngx_log_error(NGX_LOG_INFO, c->log, err,
165 } else if (err == NGX_EINTR) { 192 "writev() EAGAIN");
166 eintr = 1; 193
167 ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR"); 194 } else if (err == NGX_EINTR) {
168 195 eintr = 1;
169 } else { 196 ngx_log_error(NGX_LOG_INFO, c->log, err,
170 ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed"); 197 "writev() EINTR");
171 return NGX_CHAIN_ERROR; 198
172 } 199 } else {
173 } 200 ngx_log_error(NGX_LOG_CRIT, c->log, err,
174 201 "writev() failed");
175 sent = rc > 0 ? rc : 0; 202 return NGX_CHAIN_ERROR;
203 }
204 }
205
206 sent = rc > 0 ? rc : 0;
176 207
177 #if (NGX_DEBUG_WRITE_CHAIN) 208 #if (NGX_DEBUG_WRITE_CHAIN)
178 ngx_log_debug(c->log, "writev: %qd" _ sent); 209 ngx_log_debug(c->log, "writev: %qd" _ sent);
179 #endif 210 #endif
211
212 } else {
213 sent = 0;
214 }
180 } 215 }
181 216
182 c->sent += sent; 217 c->sent += sent;
183 218
184 for (ce = in; ce && sent > 0; ce = ce->next) { 219 for (ce = in; ce && sent > 0; ce = ce->next) {
219 254
220 in = ce; 255 in = ce;
221 256
222 } while ((tail && tail == ce) || eintr); 257 } while ((tail && tail == ce) || eintr);
223 258
259 if (ce) {
260 c->write->ready = 0;
261 }
262
224 return ce; 263 return ce;
225 } 264 }