comparison src/os/unix/ngx_writev_chain.c @ 362:7650aea1816f

nginx-0.0.7-2004-06-21-19:59:32 import
author Igor Sysoev <igor@sysoev.ru>
date Mon, 21 Jun 2004 15:59:32 +0000
parents 6bdf858bff8c
children 744ccb59062d
comparison
equal deleted inserted replaced
361:446782c909b3 362:7650aea1816f
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_event.h>
5 5
6 6
7 ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in) 7 ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
8 { 8 {
9 u_char *prev; 9 u_char *prev;
10 ssize_t n, size; 10 ssize_t n, size;
11 off_t sent; 11 off_t send, sprev, sent;
12 struct iovec *iov; 12 struct iovec *iov;
13 ngx_int_t eintr; 13 ngx_uint_t eintr, complete;
14 ngx_err_t err; 14 ngx_err_t err;
15 ngx_array_t io; 15 ngx_array_t vec;
16 ngx_chain_t *cl; 16 ngx_chain_t *cl;
17 ngx_event_t *wev; 17 ngx_event_t *wev;
18 18
19 wev = c->write; 19 wev = c->write;
20 20
32 return NGX_CHAIN_ERROR; 32 return NGX_CHAIN_ERROR;
33 } 33 }
34 34
35 #endif 35 #endif
36 36
37 ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); 37 ngx_init_array(vec, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
38 38
39 do { 39 send = 0;
40 complete = 0;
41
42 for ( ;; ) {
40 prev = NULL; 43 prev = NULL;
41 iov = NULL; 44 iov = NULL;
42 eintr = 0; 45 eintr = 0;
46 sprev = send;
43 47
44 /* create the iovec and coalesce the neighbouring bufs */ 48 /* create the iovec and coalesce the neighbouring bufs */
45 49
46 for (cl = in; cl; cl = cl->next) { 50 for (cl = in; cl && vec.nelts < IOV_MAX && send < limit; cl = cl->next)
51 {
52 if (ngx_buf_special(cl->buf)) {
53 continue;
54 }
55
56 size = cl->buf->last - cl->buf->pos;
57
58 if (send + size > limit) {
59 size = limit - send;
60 }
47 61
48 if (prev == cl->buf->pos) { 62 if (prev == cl->buf->pos) {
49 iov->iov_len += cl->buf->last - cl->buf->pos; 63 iov->iov_len += size;
50 prev = cl->buf->last;
51 64
52 } else { 65 } else {
53 ngx_test_null(iov, ngx_push_array(&io), NGX_CHAIN_ERROR); 66 ngx_test_null(iov, ngx_push_array(&vec), NGX_CHAIN_ERROR);
54 iov->iov_base = (void *) cl->buf->pos; 67 iov->iov_base = (void *) cl->buf->pos;
55 iov->iov_len = cl->buf->last - cl->buf->pos; 68 iov->iov_len = size;
56 prev = cl->buf->last;
57 } 69 }
70
71 prev = cl->buf->pos + size;
72 send += size;
58 } 73 }
59 74
60 n = writev(c->fd, io.elts, io.nelts); 75 n = writev(c->fd, vec.elts, vec.nelts);
61 76
62 if (n == -1) { 77 if (n == -1) {
63 err = ngx_errno; 78 err = ngx_errno;
64 79
65 if (err == NGX_EAGAIN || err == NGX_EINTR) { 80 if (err == NGX_EAGAIN || err == NGX_EINTR) {
80 sent = n > 0 ? n : 0; 95 sent = n > 0 ? n : 0;
81 96
82 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, 97 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
83 "writev: " OFF_T_FMT, sent); 98 "writev: " OFF_T_FMT, sent);
84 99
100 if (send - sprev == sent) {
101 complete = 1;
102 }
103
85 c->sent += sent; 104 c->sent += sent;
86 105
87 for (cl = in; cl && sent > 0; cl = cl->next) { 106 for (cl = in; cl && sent > 0; cl = cl->next) {
107 if (ngx_buf_special(cl->buf)) {
108 continue;
109 }
110
111 if (sent == 0) {
112 break;
113 }
88 114
89 size = cl->buf->last - cl->buf->pos; 115 size = cl->buf->last - cl->buf->pos;
90 116
91 if (sent >= size) { 117 if (sent >= size) {
92 sent -= size; 118 sent -= size;
93 119 cl->buf->pos = cl->buf->last;
94 if (ngx_buf_in_memory(cl->buf)) {
95 cl->buf->pos = cl->buf->last;
96 }
97 120
98 continue; 121 continue;
99 } 122 }
100 123
101 if (ngx_buf_in_memory(cl->buf)) { 124 cl->buf->pos += sent;
102 cl->buf->pos += sent;
103 }
104 125
105 break; 126 break;
106 } 127 }
107 128
108 } while (eintr); 129 if (eintr) {
130 continue;
131 }
109 132
110 if (cl) { 133 if (!complete) {
111 wev->ready = 0; 134 wev->ready = 0;
135 return cl;
136 }
137
138 if (send >= limit || cl == NULL) {
139 return cl;
140 }
141
142 in = cl;
112 } 143 }
113
114 return cl;
115 } 144 }