comparison src/os/unix/ngx_freebsd_sendfile_chain.c @ 99:a059e1aa65d4

nginx-0.0.1-2003-06-02-19:24:30 import
author Igor Sysoev <igor@sysoev.ru>
date Mon, 02 Jun 2003 15:24:30 +0000
parents a23d010f356d
children 2e069b6e6920
comparison
equal deleted inserted replaced
98:c9b243802a17 99:a059e1aa65d4
11 with the part of the file in one packet. So we use TCP_NOPUSH (similar 11 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 12 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 13 and the first part of the file in one packet but also sends 4K pages
14 in the full packets. 14 in the full packets.
15 15
16 The turning TCP_NOPUSH off flushes any pending data at least in FreeBSD 4.2, 16 Until FreeBSD 4.5 the turning TCP_NOPUSH off does not not flush
17 although there's special fix in src/sys/netinet/tcp_usrreq.c just before 17 the pending data that less than MSS and the data sent with 5 second delay.
18 FreeBSD 4.5. 18 So we use TCP_NOPUSH on FreeBSD 4.5+ only.
19 */ 19 */
20 20
21 21
22 ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in) 22 ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
23 { 23 {
103 103
104 tail = ce; 104 tail = ce;
105 105
106 if (file) { 106 if (file) {
107 107
108 if (tcp_nopush == 0) { 108 if (!c->tcp_nopush && ngx_freebsd_tcp_nopush_flush) {
109 c->tcp_nopush = 1;
109 tcp_nopush = 1; 110 tcp_nopush = 1;
110 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NOPUSH, 111 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NOPUSH,
111 (const void *) &tcp_nopush, 112 (const void *) &tcp_nopush,
112 sizeof(int)) == -1) 113 sizeof(int)) == -1)
113 { 114 {
114 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno, 115 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno,
115 "setsockopt(TCP_NO_PUSH) failed"); 116 "setsockopt(TCP_NOPUSH) failed");
116 return NGX_CHAIN_ERROR; 117 return NGX_CHAIN_ERROR;
117 } 118 }
118 } 119 }
119 120
120 hdtr.headers = (struct iovec *) header.elts; 121 hdtr.headers = (struct iovec *) header.elts;
219 220
220 in = ce; 221 in = ce;
221 222
222 } while ((tail && tail == ce) || eintr); 223 } while ((tail && tail == ce) || eintr);
223 224
224 if (tcp_nopush == 1) { 225 /* STUB: should be in app code, no need to clear TCP_NOPUSH
226 if the conneciton close()d or shutdown()ed */
227
228 if (c->tcp_nopush) {
229 c->tcp_nopush = 0;
225 tcp_nopush = 0; 230 tcp_nopush = 0;
226 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NOPUSH, 231 if (setsockopt(c->fd, IPPROTO_TCP, TCP_NOPUSH,
227 (const void *) &tcp_nopush, 232 (const void *) &tcp_nopush,
228 sizeof(int)) == -1) 233 sizeof(int)) == -1)
229 { 234 {
230 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno, 235 ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno,
231 "setsockopt(!TCP_NO_PUSH) failed"); 236 "setsockopt(!TCP_NOPUSH) failed");
232 return NGX_CHAIN_ERROR; 237 return NGX_CHAIN_ERROR;
233 } 238 }
234 } 239 }
235 240
236 return ce; 241 return ce;