annotate src/os/unix/ngx_writev_chain.c @ 4:4b2dafa26fe2 NGINX_0_1_2

nginx 0.1.2 *) Feature: the --user=USER, --group=GROUP, and --with-ld-opt=OPTIONS options in configure. *) Feature: the server_name directive supports *.domain.tld. *) Bugfix: the portability improvements. *) Bugfix: if configuration file was set in command line, the reconfiguration was impossible; bug appeared in 0.1.1. *) Bugfix: proxy module may get caught in an endless loop when sendfile is not used. *) Bugfix: with sendfile the response was not recoded according to the charset module directives; bug appeared in 0.1.1. *) Bugfix: very seldom bug in the kqueue processing. *) Bugfix: the gzip module compressed the proxied responses that was already compressed.
author Igor Sysoev <http://sysoev.ru>
date Thu, 21 Oct 2004 00:00:00 +0400
parents f0b350454894
children 46833bd150cb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
1
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
2 /*
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
4 */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
5
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
6
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
7 #include <ngx_config.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
8 #include <ngx_core.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
9 #include <ngx_event.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
10
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
11
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
12 #define NGX_IOVS 8
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
13
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
14
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
15 ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
16 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
17 u_char *prev;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
18 ssize_t n, size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
19 off_t send, sprev, sent;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
20 ngx_uint_t eintr, complete;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
21 ngx_err_t err;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
22 ngx_array_t vec;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
23 ngx_chain_t *cl;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
24 ngx_event_t *wev;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
25 struct iovec *iov, iovs[NGX_IOVS];
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
26
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
27 wev = c->write;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
28
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
29 if (!wev->ready) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
30 return in;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
31 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
32
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
33 #if (HAVE_KQUEUE)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
34
4
4b2dafa26fe2 nginx 0.1.2
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
35 if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT) && wev->pending_eof) {
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
36 ngx_log_error(NGX_LOG_INFO, c->log, wev->kq_errno,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
37 "kevent() reported about an closed connection");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
38
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
39 wev->error = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
40 return NGX_CHAIN_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
41 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
42
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
43 #endif
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
44
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
45 send = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
46 complete = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
47
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
48 vec.elts = iovs;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
49 vec.size = sizeof(struct iovec);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
50 vec.nalloc = NGX_IOVS;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
51 vec.pool = c->pool;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
52
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
53 for ( ;; ) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
54 prev = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
55 iov = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
56 eintr = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
57 sprev = send;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
58
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
59 vec.nelts = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
60
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
61 /* create the iovec and coalesce the neighbouring bufs */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
62
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
63 for (cl = in; cl && vec.nelts < IOV_MAX && send < limit; cl = cl->next)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
64 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
65 if (ngx_buf_special(cl->buf)) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
66 continue;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
67 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
68
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
69 size = cl->buf->last - cl->buf->pos;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
70
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
71 if (send + size > limit) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
72 size = limit - send;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
73 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
74
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
75 if (prev == cl->buf->pos) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
76 iov->iov_len += size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
77
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
78 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
79 if (!(iov = ngx_array_push(&vec))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
80 return NGX_CHAIN_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
81 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
82
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
83 iov->iov_base = (void *) cl->buf->pos;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
84 iov->iov_len = size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
85 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
86
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
87 prev = cl->buf->pos + size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
88 send += size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
89 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
90
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
91 n = writev(c->fd, vec.elts, vec.nelts);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
92
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
93 if (n == -1) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
94 err = ngx_errno;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
95
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
96 if (err == NGX_EAGAIN || err == NGX_EINTR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
97 if (err == NGX_EINTR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
98 eintr = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
99 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
100
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
101 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
102 "writev() not ready");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
103
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
104 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
105 wev->error = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
106 ngx_connection_error(c, err, "writev() failed");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
107 return NGX_CHAIN_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
108 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
109 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
110
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
111 sent = n > 0 ? n : 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
112
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
113 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
114 "writev: " OFF_T_FMT, sent);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
115
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
116 if (send - sprev == sent) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
117 complete = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
118 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
119
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
120 c->sent += sent;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
121
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
122 for (cl = in; cl && sent > 0; cl = cl->next) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
123 if (ngx_buf_special(cl->buf)) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
124 continue;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
125 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
126
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
127 if (sent == 0) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
128 break;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
129 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
130
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
131 size = cl->buf->last - cl->buf->pos;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
132
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
133 if (sent >= size) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
134 sent -= size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
135 cl->buf->pos = cl->buf->last;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
136
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
137 continue;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
138 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
139
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
140 cl->buf->pos += sent;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
141
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
142 break;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
143 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
144
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
145 if (eintr) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
146 continue;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
147 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
148
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
149 if (!complete) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
150 wev->ready = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
151 return cl;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
152 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
153
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
154 if (send >= limit || cl == NULL) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
155 return cl;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
156 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
157
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
158 in = cl;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
159 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
160 }