Mercurial > hg > nginx-quic
comparison src/core/ngx_write_chain.c @ 63:36d2c25cc9bb
nginx-0.0.1-2003-02-26-23:21:43 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 26 Feb 2003 20:21:43 +0000 |
parents | 8ccba41a678e |
children |
comparison
equal
deleted
inserted
replaced
62:8ccba41a678e | 63:36d2c25cc9bb |
---|---|
5 #include <ngx_types.h> | 5 #include <ngx_types.h> |
6 #include <ngx_alloc.h> | 6 #include <ngx_alloc.h> |
7 #include <ngx_array.h> | 7 #include <ngx_array.h> |
8 #include <ngx_hunk.h> | 8 #include <ngx_hunk.h> |
9 #include <ngx_connection.h> | 9 #include <ngx_connection.h> |
10 #include <ngx_sendv.h> | |
11 #include <ngx_sendfile.h> | |
12 | 10 |
13 #include <ngx_write_chain.h> | 11 |
12 ngx_chain_t *(*ngx_write_chain_proc)(ngx_connection_t *c, ngx_chain_t *in); | |
14 | 13 |
15 | 14 |
16 ngx_chain_t *ngx_write_chain(ngx_connection_t *c, ngx_chain_t *in, off_t flush) | 15 ngx_chain_t *ngx_write_chain(ngx_connection_t *c, ngx_chain_t *in, off_t flush) |
17 { | 16 { |
18 int rc, i, last; | 17 #if (NGX_EVENT) |
19 u_int flags; | 18 |
20 char *prev; | 19 return (*ngx_write_chain_proc)(c, in); |
20 | |
21 #elif (NGX_EVENT_THREAD) | |
22 | |
21 off_t sent; | 23 off_t sent; |
22 ngx_iovec_t *iov; | 24 ngx_chain_t *rc; |
23 ngx_array_t header, trailer; | |
24 ngx_hunk_t *file; | |
25 ngx_chain_t *ce; | |
26 | 25 |
27 ch = in; | 26 sent = flush - c->sent; |
28 file = NULL; | |
29 last = 0; | |
30 | |
31 ngx_init_array(header, c->pool, 10, sizeof(ngx_iovec_t), NGX_CHAIN_ERROR); | |
32 ngx_init_array(trailer, c->pool, 10, sizeof(ngx_iovec_t), NGX_CHAIN_ERROR); | |
33 | 27 |
34 do { | 28 do { |
35 header.nelts = 0; | 29 rc = (*ngx_write_chain_proc)(c, in); |
36 trailer.nelts = 0; | |
37 | 30 |
38 if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { | 31 if (rc == NGX_CHAIN_ERROR && rc == NULL) { |
39 prev = NULL; | 32 return rc; |
40 iov = NULL; | |
41 | |
42 /* create iovec and coalesce the neighbouring chain entries */ | |
43 while (ce && (ce->hunk->type & NGX_HUNK_IN_MEMORY)) | |
44 { | |
45 if (prev == ce->hunk->pos.mem) { | |
46 iov->ngx_iov_len += ce->hunk->last.mem - ce->hunk->pos.mem; | |
47 | |
48 } else { | |
49 ngx_test_null(iov, ngx_push_array(&header), | |
50 NGX_CHAIN_ERROR); | |
51 iov->ngx_iov_base = ce->hunk->pos.mem; | |
52 iov->ngx_iov_len = ce->hunk->last.mem - ce->hunk->pos.mem; | |
53 prev = ce->hunk->last.mem; | |
54 } | |
55 | |
56 if (ce->hunk->type & NGX_HUNK_LAST) { | |
57 last = 1; | |
58 } | |
59 | |
60 ce = ce->next; | |
61 } | |
62 } | 33 } |
63 | 34 |
64 if (ce && (ce->hunk->type & NGX_HUNK_FILE)) { | 35 } while (c->thread && flush > c->sent - sent); |
65 file = ce->hunk; | |
66 ce = ce->next; | |
67 | 36 |
68 if (ce->hunk->type & NGX_HUNK_LAST) { | 37 #else |
69 last = 1; | |
70 } | |
71 } | |
72 | 38 |
73 #if (HAVE_MAX_SENDFILE_IOVEC) | 39 ngx_chain_t *rc; |
74 if (file && header->nelts > HAVE_MAX_SENDFILE_IOVEC) { | 40 |
75 rc = ngx_sendv(c->fd, (ngx_iovec_t *) header->elts, header->nelts, | 41 do { |
76 &sent); | 42 |
77 } else { | 43 rc = (*ngx_write_chain_proc)(c, in); |
44 | |
45 } while (rc != NGX_CHAIN_ERROR && rc != NULL); | |
46 | |
47 return rc; | |
48 | |
78 #endif | 49 #endif |
79 if (ch && ch->hunk->type & NGX_HUNK_IN_MEMORY) { | |
80 prev = NULL; | |
81 iov = NULL; | |
82 | |
83 while (ch && (ch->hunk->type & NGX_HUNK_IN_MEMORY)) { | |
84 | |
85 if (prev == ch->hunk->pos.mem) { | |
86 iov->ngx_iov_len += | |
87 ch->hunk->last.mem - ch->hunk->pos.mem; | |
88 | |
89 } else { | |
90 ngx_test_null(iov, ngx_push_array(trailer), | |
91 NGX_CHAIN_ERROR); | |
92 iov->ngx_iov_base = ch->hunk->pos.mem; | |
93 iov->ngx_iov_len = | |
94 ch->hunk->last.mem - ch->hunk->pos.mem; | |
95 prev = ch->hunk->last.mem; | |
96 } | |
97 | |
98 if (ch->hunk->type & NGX_HUNK_LAST) { | |
99 last = 1; | |
100 } | |
101 | |
102 ch = ch->next; | |
103 } | |
104 } | |
105 | |
106 if (file) { | |
107 flags = ngx_sendfile_flags; | |
108 #if (HAVE_SENDFILE_DISCONNECT) | |
109 if (last && c->close) { | |
110 flags |= NGX_SENDFILE_DISCONNECT; | |
111 } | |
112 #endif | |
113 rc = ngx_sendfile(c, | |
114 (ngx_iovec_t *) header->elts, header->nelts, | |
115 file->file->fd, file->pos.file, | |
116 (size_t) (file->last.file - file->pos.file), | |
117 (ngx_iovec_t *) trailer->elts, trailer->nelts, | |
118 &sent, flags); | |
119 | |
120 #if (HAVE_AIO_EVENT) && !(HAVE_IOCP_EVENT) | |
121 } else if (ngx_event_flags & NGX_HAVE_AIO_EVENT) { | |
122 | |
123 sent = 0; | |
124 rc = NGX_AGAIN; | |
125 iov = (ngx_iovec_t *) header->elts; | |
126 for (i = 0; i < header->nelts; i++) { | |
127 rc = ngx_event_aio_write(c, iov[i].ngx_iov_base, | |
128 iov[i].ngx_iov_len); | |
129 | |
130 if (rc > 0) { | |
131 sent += rc; | |
132 } else { | |
133 break; | |
134 } | |
135 | |
136 if (rc < (int) iov->ngx_iov_len) { | |
137 break; | |
138 } | |
139 } | |
140 #endif | |
141 } else { | |
142 rc = ngx_sendv(c, (ngx_iovec_t *) header->elts, header->nelts); | |
143 | |
144 sent = rc > 0 ? rc: 0; | |
145 | |
146 #if (NGX_DEBUG_EVENT_WRITE) | |
147 ngx_log_debug(c->log, "sendv: " OFF_FMT _ sent); | |
148 #endif | |
149 } | |
150 #if (HAVE_MAX_SENDFILE_IOVEC) | |
151 } | |
152 #endif | |
153 if (rc == NGX_ERROR) | |
154 return (ngx_chain_t *) NGX_ERROR; | |
155 | |
156 c->sent += sent; | |
157 flush -= sent; | |
158 | |
159 for (ch = in; ch; ch = ch->next) { | |
160 | |
161 #if (NGX_DEBUG_EVENT_WRITE) | |
162 ngx_log_debug(c->log, "event write: %x " QX_FMT " " OFF_FMT _ | |
163 ch->hunk->type _ | |
164 ch->hunk->pos.file _ | |
165 ch->hunk->last.file - ch->hunk->pos.file); | |
166 #endif | |
167 | |
168 if (sent >= ch->hunk->last.file - ch->hunk->pos.file) { | |
169 sent -= ch->hunk->last.file - ch->hunk->pos.file; | |
170 ch->hunk->pos.file = ch->hunk->last.file; | |
171 | |
172 #if (NGX_DEBUG_EVENT_WRITE) | |
173 ngx_log_debug(c->log, "event write: " QX_FMT " 0 " OFF_FMT _ | |
174 ch->hunk->pos.file _ sent); | |
175 #endif | |
176 | |
177 /* | |
178 if (ch->hunk->type & NGX_HUNK_LAST) | |
179 break; | |
180 */ | |
181 | |
182 continue; | |
183 } | |
184 | |
185 ch->hunk->pos.file += sent; | |
186 | |
187 #if (NGX_DEBUG_EVENT_WRITE) | |
188 ngx_log_debug(c->log, "event write: " QX_FMT " " OFF_FMT _ | |
189 ch->hunk->pos.file _ | |
190 ch->hunk->last.file - ch->hunk->pos.file); | |
191 #endif | |
192 | |
193 break; | |
194 } | |
195 | |
196 /* flush hunks if threaded state */ | |
197 } while (c->write->context && flush > 0); | |
198 | |
199 ngx_destroy_array(&trailer); | |
200 ngx_destroy_array(&header); | |
201 | |
202 return ch; | |
203 } | 50 } |