comparison src/os/unix/ngx_solaris_sendfilev_chain.c @ 197:0b81c7a0b133

nginx-0.0.1-2003-11-27-10:45:22 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 27 Nov 2003 07:45:22 +0000
parents
children 34995c5ec6c4
comparison
equal deleted inserted replaced
196:11fbd0fc041d 197:0b81c7a0b133
1
2 #include <ngx_config.h>
3 #include <ngx_core.h>
4 #include <ngx_event.h>
5
6
7 ngx_chain_t *ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in)
8 {
9 int fd;
10 char *prev;
11 off_t fprev;
12 size_t sent;
13 ssize_t n;
14 ngx_int_t eintr;
15 sendfilevec_t *sfv;
16 ngx_array_t vec;
17 ngx_event_t *wev;
18 ngx_chain_t *cl;
19
20 wev = c->write;
21
22 if (!wev->ready) {
23 return in;
24 }
25
26 do {
27 fd = SFV_FD_SELF;
28 prev = NULL;
29 sfv = NULL;
30 eintr = 0;
31 sent = 0;
32
33 /* create the sendfilevec and coalesce the neighbouring hunks */
34
35 for (cl = in; cl; cl = cl->next) {
36 if (ngx_hunk_special(cl->hunk)) {
37 continue;
38 }
39
40 if (ngx_hunk_in_memory_only(cl->hunk)) {
41 fd = SFV_FD_SELF;
42
43 if (prev == cl->hunk->pos) {
44 sfv->sfv_len += cl->hunk->last - cl->hunk->pos;
45
46 } else {
47 ngx_test_null(sfv, ngx_push_array(&vec), NGX_CHAIN_ERROR);
48 sfv->sfv_fd = SFV_FD_SELF;
49 sfv->sfv_flag = 0;
50 sfv->sfv_off = cl->hunk->pos;
51 sfv->sfv_len = cl->hunk->last - cl->hunk->pos;
52 }
53
54 prev = cl->hunk->last;
55
56 } else {
57 prev = NULL;
58
59 if (fd == cl->hunk->file->fd && fprev == cl->hunk->file_pos) {
60 sfv->sfv_len += cl->hunk->file_last - cl->hunk->file_pos;
61
62 } else {
63 ngx_test_null(sfv, ngx_push_array(&vec), NGX_CHAIN_ERROR);
64 fd = cl->hunk->file->fd;
65 sfv->sfv_fd = fd;
66 sfv->sfv_flag = 0;
67 sfv->sfv_off = cl->hunk->file_pos;
68 sfv->sfv_len = cl->hunk->file_last - cl->hunk->file_pos;
69 }
70
71 fprev = cl->hunk->file_last;
72 }
73 }
74
75 n = sendfile(c->fd, vec->elts, vec->nelts, &sent);
76
77 if (n == -1) {
78 err = ngx_errno;
79
80 if (err == NGX_EINTR) {
81 eintr = 1;
82 }
83
84 if (err == NGX_EAGAIN || err == NGX_EINTR) {
85 ngx_log_error(NGX_LOG_INFO, c->log, err,
86 "sendfilev() sent only " SIZE_T_FMT " bytes",
87 sent);
88 } else {
89 wev->error = 1;
90 ngx_log_error(NGX_LOG_CRIT, c->log, err, "sendfilev() failed");
91 return NGX_CHAIN_ERROR;
92 }
93 }
94
95 #if (NGX_DEBUG_WRITE_CHAIN)
96 ngx_log_debug(c->log, "sendfilev: %d " SIZE_T_FMT ", n _ sent);
97 #endif
98
99 c->sent += sent;
100
101 for (cl = in; cl; cl = cl->next) {
102
103 if (ngx_hunk_special(cl->hunk)) {
104 continue;
105 }
106
107 if (sent == 0) {
108 break;
109 }
110
111 size = ngx_hunk_size(cl->hunk);
112
113 if (sent >= size) {
114 sent -= size;
115
116 if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
117 cl->hunk->pos = cl->hunk->last;
118 }
119
120 if (cl->hunk->type & NGX_HUNK_FILE) {
121 cl->hunk->file_pos = cl->hunk->file_last;
122 }
123
124 continue;
125 }
126
127 if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
128 cl->hunk->pos += sent;
129 }
130
131 if (cl->hunk->type & NGX_HUNK_FILE) {
132 cl->hunk->file_pos += sent;
133 }
134
135 break;
136 }
137
138 in = cl;
139
140 } while (eintr);
141
142 if (in) {
143 wev->ready = 0;
144 }
145
146 return in;
147 }