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