aboutsummaryrefslogtreecommitdiff
path: root/src/core/ngx_hunk.h
blob: 7dc0f0c8582f3e80a4698544a49dcc23a719b0e7 (plain)
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
153
154
155
156
157
158
159
160
161
#ifndef _NGX_HUNK_H_INCLUDED_
#define _NGX_HUNK_H_INCLUDED_


#include <ngx_config.h>
#include <ngx_core.h>


/* hunk type */

/* the hunk is in memory */
#define NGX_HUNK_IN_MEMORY    0x0001
/* the hunk's content can be changed */
#define NGX_HUNK_TEMP         0x0002
/* the hunk's content is in cache and can not be changed */
#define NGX_HUNK_MEMORY       0x0004
/* the hunk's content is mmap()ed and can not be changed */
#define NGX_HUNK_MMAP         0x0008

#define NGX_HUNK_RECYCLED     0x0010

/* the hunk is in file */
#define NGX_HUNK_FILE         0x0020

#define NGX_HUNK_STORAGE      (NGX_HUNK_IN_MEMORY                            \
                               |NGX_HUNK_TEMP|NGX_HUNK_MEMORY|NGX_HUNK_MMAP  \
                               |NGX_HUNK_RECYCLED|NGX_HUNK_FILE)

/* hunk flags */

/* in thread state flush means to write the hunk completely before return */
/* in event state flush means to start to write the hunk */
#define NGX_HUNK_FLUSH        0x0100
/* last hunk */
#define NGX_HUNK_LAST         0x0200


#define NGX_HUNK_PREREAD      0x2000
#define NGX_HUNK_LAST_SHADOW  0x4000
#define NGX_HUNK_TEMP_FILE    0x8000


typedef void *                   ngx_hunk_tag_t;

typedef struct ngx_hunk_s        ngx_hunk_t;

struct ngx_hunk_s {
    char            *pos;
    char            *last;
    off_t            file_pos;
    off_t            file_last;

    int              type;
    char            *start;         /* start of hunk */
    char            *end;           /* end of hunk */
    ngx_hunk_tag_t   tag;
    ngx_file_t      *file;
    ngx_hunk_t      *shadow;
    /* STUB */ int   num;
};


typedef struct ngx_chain_s       ngx_chain_t;

struct ngx_chain_s {
    ngx_hunk_t  *hunk;
    ngx_chain_t *next;
};


typedef struct {
    int          num;
    size_t       size;
} ngx_bufs_t;


typedef int  (*ngx_output_chain_filter_pt)(void *ctx, ngx_chain_t *out);

typedef struct {
    ngx_hunk_t                  *hunk;
    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;
    int                          hunks;
    ngx_bufs_t                   bufs;
    ngx_hunk_tag_t               tag;

    ngx_output_chain_filter_pt   output_filter;
    void                        *output_ctx;
} ngx_output_chain_ctx_t;


typedef struct {
    ngx_chain_t                 *out;
    ngx_chain_t                **last;
    ngx_connection_t            *connection;
    ngx_pool_t                  *pool;
} ngx_chain_writer_ctx_t;


#define NGX_CHAIN_ERROR     (ngx_chain_t *) NGX_ERROR


#define ngx_hunk_in_memory_only(h)                                           \
         ((h->type & (NGX_HUNK_IN_MEMORY|NGX_HUNK_FILE)) == NGX_HUNK_IN_MEMORY)
/*
    ((h->type & (NGX_HUNK_TEMP|NGX_HUNK_MEMORY|NGX_HUNK_MMAP|NGX_HUNK_FILE)) \
                  == (h->type & (NGX_HUNK_TEMP|NGX_HUNK_MEMORY|NGX_HUNK_MMAP)))

*/

#define ngx_hunk_special(h)                                                  \
        (h->type == (h->type & (NGX_HUNK_FLUSH|NGX_HUNK_LAST)))


#define ngx_hunk_size(h)                                                     \
        ((h->type & NGX_HUNK_IN_MEMORY) ? (size_t) (h->last - h->pos):       \
                                          (size_t) (h->file_last - h->file_pos))


ngx_hunk_t *ngx_create_temp_hunk(ngx_pool_t *pool, size_t size);

#define ngx_alloc_hunk(pool) ngx_palloc(pool, sizeof(ngx_hunk_t))
#define ngx_calloc_hunk(pool) ngx_pcalloc(pool, sizeof(ngx_hunk_t))


#define ngx_alloc_chain_link(pool) ngx_palloc(pool, sizeof(ngx_chain_t))


#define ngx_alloc_link_and_set_hunk(chain, h, pool, error)                   \
            do {                                                             \
                ngx_test_null(chain, ngx_alloc_chain_link(pool), error);     \
                chain->hunk = h;                                             \
                chain->next = NULL;                                          \
            } while (0);


#define ngx_chain_add_link(chain, last, cl)                                  \
            if (chain) {                                                     \
                *last = cl;                                                  \
            } else {                                                         \
                chain = cl;                                                  \
            }                                                                \
            last = &cl->next


int ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in);
int ngx_chain_writer(void *data, ngx_chain_t *in);

int 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_hunk_tag_t tag);


#endif /* _NGX_HUNK_H_INCLUDED_ */