Klaus Demo nginx / a301e1a
Moved writev() handling code to a separate function. This reduces code duplication and unifies debug logging of the writev() syscall among various send chain functions. Valentin Bartenev 7 years ago
5 changed file(s) with 72 addition(s) and 114 deletion(s). Raw diff Collapse all Expand all
3232 int rc;
3333 off_t send, prev_send, sent;
3434 off_t file_size;
35 ssize_t n;
3536 ngx_uint_t eintr;
3637 ngx_err_t err;
3738 ngx_buf_t *file;
171172 rc, file->file_pos, sent, file_size + header.size);
172173
173174 } else {
174 rc = writev(c->fd, header.iovs, header.count);
175
176 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
177 "writev: %d of %uz", rc, header.size);
178
179 if (rc == -1) {
180 err = ngx_errno;
181
182 switch (err) {
183 case NGX_EAGAIN:
184 break;
185
186 case NGX_EINTR:
187 eintr = 1;
188 break;
189
190 default:
191 wev->error = 1;
192 ngx_connection_error(c, err, "writev() failed");
193 return NGX_CHAIN_ERROR;
194 }
195
196 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
197 "writev() not ready");
198 }
199
200 sent = rc > 0 ? rc : 0;
175 n = ngx_writev(c, &header);
176
177 if (n == NGX_ERROR) {
178 return NGX_CHAIN_ERROR;
179 }
180
181 sent = (n == NGX_AGAIN) ? 0 : n;
201182 }
202183
203184 c->sent += sent;
3434 int rc, flags;
3535 off_t send, prev_send, sent;
3636 size_t file_size;
37 ssize_t n;
3738 ngx_uint_t eintr, eagain;
3839 ngx_err_t err;
3940 ngx_buf_t *file;
216217 rc, file->file_pos, sent, file_size + header.size);
217218
218219 } else {
219 rc = writev(c->fd, header.iovs, header.count);
220
221 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
222 "writev: %d of %uz", rc, header.size);
223
224 if (rc == -1) {
225 err = ngx_errno;
226
227 switch (err) {
228 case NGX_EAGAIN:
229 break;
230
231 case NGX_EINTR:
232 eintr = 1;
233 break;
234
235 default:
236 wev->error = 1;
237 ngx_connection_error(c, err, "writev() failed");
238 return NGX_CHAIN_ERROR;
239 }
240
241 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
242 "writev() not ready");
243 }
244
245 sent = rc > 0 ? rc : 0;
220 n = ngx_writev(c, &header);
221
222 if (n == NGX_ERROR) {
223 return NGX_CHAIN_ERROR;
224 }
225
226 sent = (n == NGX_AGAIN) ? 0 : n;
246227 }
247228
248229 c->sent += sent;
3232 int rc, tcp_nodelay;
3333 off_t send, prev_send, sent;
3434 size_t file_size;
35 ssize_t n;
3536 ngx_err_t err;
3637 ngx_buf_t *file;
3738 ngx_uint_t eintr;
198199 rc, file->file_pos, sent, file_size);
199200
200201 } else {
201 rc = writev(c->fd, header.iovs, header.count);
202
203 if (rc == -1) {
204 err = ngx_errno;
205
206 switch (err) {
207 case NGX_EAGAIN:
208 break;
209
210 case NGX_EINTR:
211 eintr = 1;
212 break;
213
214 default:
215 wev->error = 1;
216 ngx_connection_error(c, err, "writev() failed");
217 return NGX_CHAIN_ERROR;
218 }
219
220 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
221 "writev() not ready");
222 }
223
224 sent = rc > 0 ? rc : 0;
225
226 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %O", sent);
202 n = ngx_writev(c, &header);
203
204 if (n == NGX_ERROR) {
205 return NGX_CHAIN_ERROR;
206 }
207
208 sent = (n == NGX_AGAIN) ? 0 : n;
227209 }
228210
229211 c->sent += sent;
7474 size_t limit, ngx_log_t *log);
7575
7676
77 ssize_t ngx_writev(ngx_connection_t *c, ngx_iovec_t *vec);
78
79
7780 extern ngx_os_io_t ngx_os_io;
7881 extern ngx_int_t ngx_ncpu;
7982 extern ngx_int_t ngx_max_sockets;
1414 {
1515 ssize_t n, sent;
1616 off_t send, prev_send;
17 ngx_uint_t eintr;
18 ngx_err_t err;
1917 ngx_chain_t *cl;
2018 ngx_event_t *wev;
2119 ngx_iovec_t vec;
5048 vec.nalloc = NGX_IOVS_PREALLOCATE;
5149
5250 for ( ;; ) {
53 eintr = 0;
5451 prev_send = send;
5552
5653 /* create the iovec and coalesce the neighbouring bufs */
8279
8380 send += vec.size;
8481
85 n = writev(c->fd, vec.iovs, vec.count);
86
87 if (n == -1) {
88 err = ngx_errno;
89
90 switch (err) {
91 case NGX_EAGAIN:
92 break;
93
94 case NGX_EINTR:
95 eintr = 1;
96 break;
97
98 default:
99 wev->error = 1;
100 (void) ngx_connection_error(c, err, "writev() failed");
101 return NGX_CHAIN_ERROR;
102 }
103
104 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
105 "writev() not ready");
106 }
107
108 sent = n > 0 ? n : 0;
109
110 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %z", sent);
82 n = ngx_writev(c, &vec);
83
84 if (n == NGX_ERROR) {
85 return NGX_CHAIN_ERROR;
86 }
87
88 sent = (n == NGX_AGAIN) ? 0 : n;
11189
11290 c->sent += sent;
11391
11492 in = ngx_chain_update_sent(in, sent);
115
116 if (eintr) {
117 send = prev_send;
118 continue;
119 }
12093
12194 if (send - prev_send != sent) {
12295 wev->ready = 0;
202175
203176 return in;
204177 }
178
179
180 ssize_t
181 ngx_writev(ngx_connection_t *c, ngx_iovec_t *vec)
182 {
183 ssize_t n;
184 ngx_err_t err;
185
186 eintr:
187
188 n = writev(c->fd, vec->iovs, vec->count);
189
190 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
191 "writev: %z of %uz", n, vec->size);
192
193 if (n == -1) {
194 err = ngx_errno;
195
196 switch (err) {
197 case NGX_EAGAIN:
198 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
199 "writev() not ready");
200 return NGX_AGAIN;
201
202 case NGX_EINTR:
203 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
204 "writev() was interrupted");
205 goto eintr;
206
207 default:
208 c->write->error = 1;
209 ngx_connection_error(c, err, "writev() failed");
210 return NGX_ERROR;
211 }
212 }
213
214 return n;
215 }