0
|
1
|
|
2 /*
|
|
3 * Copyright (C) Igor Sysoev
|
|
4 */
|
|
5
|
|
6
|
|
7 #include <ngx_config.h>
|
|
8 #include <ngx_core.h>
|
|
9 #include <ngx_event.h>
|
|
10 #include <ngx_aio.h>
|
|
11
|
|
12
|
126
|
13 ngx_chain_t *
|
|
14 ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
0
|
15 {
|
|
16 u_char *buf, *prev;
|
|
17 off_t send, sent;
|
|
18 size_t len;
|
10
|
19 ssize_t n, size;
|
0
|
20 ngx_chain_t *cl;
|
|
21
|
22
|
22 /* the maximum limit size is the maximum size_t value - the page size */
|
|
23
|
324
|
24 if (limit == 0 || limit > (off_t) (NGX_MAX_SIZE_T_VALUE - ngx_pagesize)) {
|
26
|
25 limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize;
|
22
|
26 }
|
|
27
|
0
|
28 send = 0;
|
|
29 sent = 0;
|
|
30 cl = in;
|
|
31
|
|
32 while (cl) {
|
|
33
|
|
34 if (cl->buf->pos == cl->buf->last) {
|
|
35 cl = cl->next;
|
|
36 continue;
|
|
37 }
|
|
38
|
|
39 /* we can post the single aio operation only */
|
|
40
|
|
41 if (!c->write->ready) {
|
|
42 return cl;
|
|
43 }
|
|
44
|
|
45 buf = cl->buf->pos;
|
|
46 prev = buf;
|
|
47 len = 0;
|
|
48
|
|
49 /* coalesce the neighbouring bufs */
|
|
50
|
|
51 while (cl && prev == cl->buf->pos && send < limit) {
|
|
52 if (ngx_buf_special(cl->buf)) {
|
|
53 continue;
|
|
54 }
|
|
55
|
|
56 size = cl->buf->last - cl->buf->pos;
|
|
57
|
|
58 if (send + size > limit) {
|
|
59 size = limit - send;
|
|
60 }
|
|
61
|
|
62 len += size;
|
|
63 prev = cl->buf->pos + size;
|
|
64 send += size;
|
|
65 cl = cl->next;
|
|
66 }
|
|
67
|
|
68 n = ngx_aio_write(c, buf, len);
|
|
69
|
10
|
70 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "aio_write: %z", n);
|
0
|
71
|
|
72 if (n == NGX_ERROR) {
|
|
73 return NGX_CHAIN_ERROR;
|
|
74 }
|
|
75
|
|
76 if (n > 0) {
|
|
77 sent += n;
|
|
78 c->sent += n;
|
|
79 }
|
|
80
|
|
81 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
10
|
82 "aio_write sent: %O", c->sent);
|
0
|
83
|
|
84 for (cl = in; cl; cl = cl->next) {
|
|
85
|
|
86 if (sent >= cl->buf->last - cl->buf->pos) {
|
|
87 sent -= cl->buf->last - cl->buf->pos;
|
|
88 cl->buf->pos = cl->buf->last;
|
|
89
|
|
90 continue;
|
|
91 }
|
|
92
|
|
93 cl->buf->pos += sent;
|
|
94
|
|
95 break;
|
|
96 }
|
|
97 }
|
|
98
|
|
99 return cl;
|
|
100 }
|