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 }