Mercurial > hg > nginx
comparison src/os/unix/ngx_solaris_sendfilev_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 | e366ba5db8f8 |
children | 5e73d0ea4dab |
comparison
equal
deleted
inserted
replaced
361:446782c909b3 | 362:7650aea1816f |
---|---|
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_event.h> | 9 #include <ngx_event.h> |
10 | 10 |
11 | 11 |
12 ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in) | 12 ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, |
13 off_t limit) | |
13 { | 14 { |
14 int fd; | 15 int fd; |
15 u_char *prev; | 16 u_char *prev; |
16 off_t fprev; | 17 off_t fprev, sprev, send, aligned; |
17 size_t sent, size; | 18 size_t size, sent; |
18 ssize_t n; | 19 ssize_t n; |
19 ngx_int_t eintr; | 20 ngx_int_t eintr, complete; |
20 ngx_err_t err; | 21 ngx_err_t err; |
21 sendfilevec_t *sfv; | 22 sendfilevec_t *sfv; |
22 ngx_array_t vec; | 23 ngx_array_t vec; |
23 ngx_event_t *wev; | 24 ngx_event_t *wev; |
24 ngx_chain_t *cl, *tail; | 25 ngx_chain_t *cl, *tail; |
27 | 28 |
28 if (!wev->ready) { | 29 if (!wev->ready) { |
29 return in; | 30 return in; |
30 } | 31 } |
31 | 32 |
32 do { | 33 send = 0; |
34 complete = 0; | |
35 | |
36 for ( ;; ) { | |
33 fd = SFV_FD_SELF; | 37 fd = SFV_FD_SELF; |
34 prev = NULL; | 38 prev = NULL; |
35 fprev = 0; | 39 fprev = 0; |
36 sfv = NULL; | 40 sfv = NULL; |
37 eintr = 0; | 41 eintr = 0; |
38 sent = 0; | 42 sent = 0; |
43 sprev = send; | |
39 | 44 |
40 ngx_init_array(vec, c->pool, 10, sizeof(sendfilevec_t), | 45 ngx_init_array(vec, c->pool, 10, sizeof(sendfilevec_t), |
41 NGX_CHAIN_ERROR); | 46 NGX_CHAIN_ERROR); |
42 | 47 |
43 /* create the sendfilevec and coalesce the neighbouring bufs */ | 48 /* create the sendfilevec and coalesce the neighbouring bufs */ |
44 | 49 |
45 for (cl = in; cl && vec.nelts < IOV_MAX; cl = cl->next) { | 50 for (cl = in; cl && vec.nelts < IOV_MAX && send < limit; cl = cl->next) |
51 { | |
46 if (ngx_buf_special(cl->buf)) { | 52 if (ngx_buf_special(cl->buf)) { |
47 continue; | 53 continue; |
48 } | 54 } |
49 | 55 |
50 if (ngx_buf_in_memory_only(cl->buf)) { | 56 if (ngx_buf_in_memory_only(cl->buf)) { |
51 fd = SFV_FD_SELF; | 57 fd = SFV_FD_SELF; |
52 | 58 |
59 size = cl->buf->last - cl->buf->pos; | |
60 | |
61 if (send + size > limit) { | |
62 size = limit - send; | |
63 } | |
64 | |
53 if (prev == cl->buf->pos) { | 65 if (prev == cl->buf->pos) { |
54 sfv->sfv_len += cl->buf->last - cl->buf->pos; | 66 sfv->sfv_len += size; |
55 | 67 |
56 } else { | 68 } else { |
57 ngx_test_null(sfv, ngx_push_array(&vec), NGX_CHAIN_ERROR); | 69 ngx_test_null(sfv, ngx_push_array(&vec), NGX_CHAIN_ERROR); |
58 sfv->sfv_fd = SFV_FD_SELF; | 70 sfv->sfv_fd = SFV_FD_SELF; |
59 sfv->sfv_flag = 0; | 71 sfv->sfv_flag = 0; |
60 sfv->sfv_off = (off_t) (uintptr_t) cl->buf->pos; | 72 sfv->sfv_off = (off_t) (uintptr_t) cl->buf->pos; |
61 sfv->sfv_len = cl->buf->last - cl->buf->pos; | 73 sfv->sfv_len = size; |
62 } | 74 } |
63 | 75 |
64 prev = cl->buf->last; | 76 prev = cl->buf->pos + size; |
77 send += size; | |
65 | 78 |
66 } else { | 79 } else { |
67 prev = NULL; | 80 prev = NULL; |
68 | 81 |
82 size = (size_t) (cl->buf->file_last - cl->buf->file_pos); | |
83 | |
84 if (send + size > limit) { | |
85 size = limit - send; | |
86 | |
87 aligned = (cl->buf->file_pos + size + ngx_pagesize - 1) | |
88 & ~(ngx_pagesize - 1); | |
89 | |
90 if (aligned <= cl->buf->file_last) { | |
91 size = aligned - cl->buf->file_pos; | |
92 } | |
93 } | |
94 | |
69 if (fd == cl->buf->file->fd && fprev == cl->buf->file_pos) { | 95 if (fd == cl->buf->file->fd && fprev == cl->buf->file_pos) { |
70 sfv->sfv_len += cl->buf->file_last - cl->buf->file_pos; | 96 sfv->sfv_len += size; |
71 | 97 |
72 } else { | 98 } else { |
73 ngx_test_null(sfv, ngx_push_array(&vec), NGX_CHAIN_ERROR); | 99 ngx_test_null(sfv, ngx_push_array(&vec), NGX_CHAIN_ERROR); |
74 fd = cl->buf->file->fd; | 100 fd = cl->buf->file->fd; |
75 sfv->sfv_fd = fd; | 101 sfv->sfv_fd = fd; |
76 sfv->sfv_flag = 0; | 102 sfv->sfv_flag = 0; |
77 sfv->sfv_off = cl->buf->file_pos; | 103 sfv->sfv_off = cl->buf->file_pos; |
78 sfv->sfv_len = cl->buf->file_last - cl->buf->file_pos; | 104 sfv->sfv_len = size; |
79 } | 105 } |
80 | 106 |
81 fprev = cl->buf->file_last; | 107 fprev = cl->buf->file_pos + size; |
108 send += size; | |
82 } | 109 } |
83 } | 110 } |
84 | |
85 /* | |
86 * the tail is the rest of the chain that exceedes a single | |
87 * sendfilev() capability, IOV_MAX in Solaris is limited by 16 | |
88 */ | |
89 | |
90 tail = cl; | |
91 | 111 |
92 n = sendfilev(c->fd, vec.elts, vec.nelts, &sent); | 112 n = sendfilev(c->fd, vec.elts, vec.nelts, &sent); |
93 | 113 |
94 if (n == -1) { | 114 if (n == -1) { |
95 err = ngx_errno; | 115 err = ngx_errno; |
110 } | 130 } |
111 } | 131 } |
112 | 132 |
113 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, | 133 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0, |
114 "sendfilev: %d " SIZE_T_FMT, n, sent); | 134 "sendfilev: %d " SIZE_T_FMT, n, sent); |
135 | |
136 if (send - sprev == sent) { | |
137 complete = 1; | |
138 } | |
115 | 139 |
116 c->sent += sent; | 140 c->sent += sent; |
117 | 141 |
118 for (cl = in; cl; cl = cl->next) { | 142 for (cl = in; cl; cl = cl->next) { |
119 | 143 |
150 } | 174 } |
151 | 175 |
152 break; | 176 break; |
153 } | 177 } |
154 | 178 |
179 if (eintr) { | |
180 continue; | |
181 } | |
182 | |
183 if (!complete) { | |
184 wev->ready = 0; | |
185 return cl; | |
186 } | |
187 | |
188 if (send >= limit || cl == NULL) { | |
189 return cl; | |
190 } | |
191 | |
155 in = cl; | 192 in = cl; |
156 | |
157 /* "tail == in" means that a single sendfilev() is complete */ | |
158 | |
159 } while ((tail && tail == in) || eintr); | |
160 | |
161 if (in) { | |
162 wev->ready = 0; | |
163 } | 193 } |
164 | |
165 return in; | |
166 } | 194 } |