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 }