Mercurial > hg > nginx
comparison src/os/unix/ngx_writev_chain.c @ 93:738fe44c70d5
nginx-0.0.1-2003-05-21-17:28:21 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 21 May 2003 13:28:21 +0000 |
parents | |
children | 8220378432a8 |
comparison
equal
deleted
inserted
replaced
92:19cc647ecd91 | 93:738fe44c70d5 |
---|---|
1 | |
2 #include <ngx_config.h> | |
3 #include <ngx_core.h> | |
4 | |
5 | |
6 ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in) | |
7 { | |
8 char *prev; | |
9 size_t size; | |
10 ssize_t n; | |
11 off_t sent; | |
12 struct iovec *iov; | |
13 ngx_err_t err; | |
14 ngx_array_t io; | |
15 ngx_chain_t *ce; | |
16 | |
17 ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR); | |
18 | |
19 prev = NULL; | |
20 iov = NULL; | |
21 | |
22 /* create the iovec and coalesce the neighbouring chain entries */ | |
23 for (ce = in; ce; ce = ce->next) { | |
24 | |
25 if (prev == ce->hunk->pos) { | |
26 iov->iov_len += ce->hunk->last - ce->hunk->pos; | |
27 prev = ce->hunk->last; | |
28 | |
29 } else { | |
30 ngx_test_null(iov, ngx_push_array(&io), NGX_CHAIN_ERROR); | |
31 iov->iov_base = ce->hunk->pos; | |
32 iov->iov_len = ce->hunk->last - ce->hunk->pos; | |
33 prev = ce->hunk->last; | |
34 } | |
35 } | |
36 | |
37 n = writev(c->fd, (struct iovec *) io.elts, io.nelts); | |
38 | |
39 if (n == -1) { | |
40 err = ngx_errno; | |
41 if (err == NGX_EAGAIN) { | |
42 ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN"); | |
43 | |
44 } else if (err == NGX_EINTR) { | |
45 ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR"); | |
46 | |
47 } else { | |
48 ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed"); | |
49 return NGX_CHAIN_ERROR; | |
50 } | |
51 } | |
52 | |
53 sent = n > 0 ? n : 0; | |
54 | |
55 #if (NGX_DEBUG_WRITE_CHAIN) | |
56 ngx_log_debug(c->log, "writev: %qd" _ sent); | |
57 #endif | |
58 | |
59 c->sent += sent; | |
60 | |
61 for (ce = in; ce && sent > 0; ce = ce->next) { | |
62 | |
63 size = ce->hunk->last - ce->hunk->pos; | |
64 | |
65 if (sent >= size) { | |
66 sent -= size; | |
67 | |
68 if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { | |
69 ce->hunk->pos = ce->hunk->last; | |
70 } | |
71 | |
72 if (ce->hunk->type & NGX_HUNK_FILE) { | |
73 ce->hunk->file_pos = ce->hunk->file_last; | |
74 } | |
75 | |
76 continue; | |
77 } | |
78 | |
79 if (ce->hunk->type & NGX_HUNK_IN_MEMORY) { | |
80 ce->hunk->pos += sent; | |
81 } | |
82 | |
83 if (ce->hunk->type & NGX_HUNK_FILE) { | |
84 ce->hunk->file_pos += sent; | |
85 } | |
86 | |
87 break; | |
88 } | |
89 | |
90 ngx_destroy_array(&io); | |
91 | |
92 return ce; | |
93 } |