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