1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
/*
* Copyright (C) Igor Sysoev
*/
#ifndef _NGX_BUF_H_INCLUDED_
#define _NGX_BUF_H_INCLUDED_
#include <ngx_config.h>
#include <ngx_core.h>
typedef void * ngx_buf_tag_t;
typedef struct ngx_buf_s ngx_buf_t;
struct ngx_buf_s {
u_char *pos;
u_char *last;
off_t file_pos;
off_t file_last;
u_char *start; /* start of buffer */
u_char *end; /* end of buffer */
ngx_buf_tag_t tag;
ngx_file_t *file;
ngx_buf_t *shadow;
/* the buf's content could be changed */
unsigned temporary:1;
/*
* the buf's content is in a memory cache or in a read only memory
* and must not be changed
*/
unsigned memory:1;
/* the buf's content is mmap()ed and must not be changed */
unsigned mmap:1;
unsigned recycled:1;
unsigned in_file:1;
unsigned flush:1;
unsigned last_buf:1;
unsigned last_shadow:1;
unsigned temp_file:1;
unsigned zerocopy_busy:1;
/* STUB */ int num;
};
typedef struct ngx_chain_s ngx_chain_t;
struct ngx_chain_s {
ngx_buf_t *buf;
ngx_chain_t *next;
};
typedef struct {
ngx_int_t num;
size_t size;
} ngx_bufs_t;
typedef int (*ngx_output_chain_filter_pt)(void *ctx, ngx_chain_t *out);
typedef struct {
ngx_buf_t *buf;
ngx_chain_t *in;
ngx_chain_t *free;
ngx_chain_t *busy;
unsigned sendfile;
unsigned need_in_memory;
unsigned need_in_temp;
ngx_pool_t *pool;
ngx_int_t allocated;
ngx_bufs_t bufs;
ngx_buf_tag_t tag;
ngx_output_chain_filter_pt output_filter;
void *filter_ctx;
} ngx_output_chain_ctx_t;
typedef struct {
ngx_chain_t *out;
ngx_chain_t **last;
ngx_connection_t *connection;
ngx_pool_t *pool;
off_t limit;
} ngx_chain_writer_ctx_t;
#define NGX_CHAIN_ERROR (ngx_chain_t *) NGX_ERROR
#define ngx_buf_in_memory(b) (b->temporary || b->memory || b->mmap)
#define ngx_buf_in_memory_only(b) (ngx_buf_in_memory(b) && !b->in_file)
#define ngx_buf_special(b) \
((b->flush || b->last_buf) && !ngx_buf_in_memory(b) && !b->in_file)
#define ngx_buf_size(b) \
(ngx_buf_in_memory(b) ? (off_t) (b->last - b->pos): \
(b->file_last - b->file_pos))
ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size);
ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs);
#define ngx_alloc_buf(pool) ngx_palloc(pool, sizeof(ngx_buf_t))
#define ngx_calloc_buf(pool) ngx_pcalloc(pool, sizeof(ngx_buf_t))
#define ngx_alloc_chain_link(pool) ngx_palloc(pool, sizeof(ngx_chain_t))
#define ngx_alloc_link_and_set_buf(chain, b, pool, error) \
do { \
ngx_test_null(chain, ngx_alloc_chain_link(pool), error); \
chain->buf = b; \
chain->next = NULL; \
} while (0);
#define ngx_chain_add_link(chain, last, cl) \
if (chain) { \
*last = cl; \
} else { \
chain = cl; \
} \
last = &cl->next
ngx_int_t ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in);
ngx_int_t ngx_chain_writer(void *data, ngx_chain_t *in);
ngx_int_t ngx_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain,
ngx_chain_t *in);
void ngx_chain_update_chains(ngx_chain_t **free, ngx_chain_t **busy,
ngx_chain_t **out, ngx_buf_tag_t tag);
#endif /* _NGX_BUF_H_INCLUDED_ */
|