1
2 /*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7 #include <nxt_main.h>
8
9
10 nxt_int_t
nxt_buf_pool_mem_alloc(nxt_buf_pool_t * bp,size_t size)11 nxt_buf_pool_mem_alloc(nxt_buf_pool_t *bp, size_t size)
12 {
13 nxt_buf_t *b;
14
15 b = bp->current;
16
17 if (b != NULL && b->mem.free < b->mem.end) {
18 return NXT_OK;
19 }
20
21 b = bp->free;
22
23 if (b != NULL) {
24 bp->current = b;
25 bp->free = b->next;
26 b->next = NULL;
27 return NXT_OK;
28 }
29
30 if (bp->num >= bp->max) {
31 return NXT_AGAIN;
32 }
33
34 if (size == 0 || size >= bp->size + bp->size / 4) {
35 size = bp->size;
36 }
37
38 b = nxt_buf_mem_alloc(bp->mem_pool, size, bp->flags);
39
40 if (nxt_fast_path(b != NULL)) {
41 bp->current = b;
42 bp->num++;
43 return NXT_OK;
44 }
45
46 return NXT_ERROR;
47 }
48
49
50 nxt_int_t
nxt_buf_pool_file_alloc(nxt_buf_pool_t * bp,size_t size)51 nxt_buf_pool_file_alloc(nxt_buf_pool_t *bp, size_t size)
52 {
53 nxt_buf_t *b;
54
55 b = bp->current;
56
57 if (b != NULL && b->mem.free < b->mem.end) {
58 return NXT_OK;
59 }
60
61 b = bp->free;
62
63 if (b != NULL) {
64 bp->current = b;
65 bp->free = b->next;
66 b->next = NULL;
67 return NXT_OK;
68 }
69
70 if (bp->num >= bp->max) {
71 return NXT_AGAIN;
72 }
73
74 if (size == 0 || size >= bp->size + bp->size / 4) {
75 size = bp->size;
76 }
77
78 b = nxt_buf_file_alloc(bp->mem_pool, size, bp->flags);
79
80 if (nxt_fast_path(b != NULL)) {
81 bp->current = b;
82 bp->num++;
83 return NXT_OK;
84 }
85
86 return NXT_ERROR;
87 }
88
89
90 nxt_int_t
nxt_buf_pool_mmap_alloc(nxt_buf_pool_t * bp,size_t size)91 nxt_buf_pool_mmap_alloc(nxt_buf_pool_t *bp, size_t size)
92 {
93 nxt_buf_t *b;
94
95 b = bp->current;
96
97 if (b != NULL) {
98 return NXT_OK;
99 }
100
101 b = bp->free;
102
103 if (b != NULL) {
104 bp->current = b;
105 bp->free = b->next;
106 b->next = NULL;
107 return NXT_OK;
108 }
109
110 if (bp->num >= bp->max) {
111 return NXT_AGAIN;
112 }
113
114 if (size == 0 || size >= bp->size + bp->size / 4) {
115 size = bp->size;
116 }
117
118 b = nxt_buf_mmap_alloc(bp->mem_pool, size);
119
120 if (nxt_fast_path(b != NULL)) {
121 bp->mmap = 1;
122 bp->current = b;
123 bp->num++;
124 return NXT_OK;
125 }
126
127 return NXT_ERROR;
128 }
129
130
131 void
nxt_buf_pool_free(nxt_buf_pool_t * bp,nxt_buf_t * b)132 nxt_buf_pool_free(nxt_buf_pool_t *bp, nxt_buf_t *b)
133 {
134 size_t size;
135
136 nxt_thread_log_debug("buf pool free: %p %p", b, b->mem.start);
137
138 size = nxt_buf_mem_size(&b->mem);
139
140 if (bp->mmap) {
141 nxt_mem_unmap(b->mem.start, &b->mmap, size);
142 }
143
144 if (bp->destroy) {
145
146 if (b == bp->current) {
147 bp->current = NULL;
148 }
149
150 nxt_buf_free(bp->mem_pool, b);
151
152 return;
153 }
154
155 if (bp->mmap) {
156 b->mem.pos = NULL;
157 b->mem.free = NULL;
158 nxt_buf_mem_set_size(&b->mem, size);
159
160 } else {
161 b->mem.pos = b->mem.start;
162 b->mem.free = b->mem.start;
163 }
164
165 if (b != bp->current) {
166 b->next = bp->free;
167 bp->free = b;
168 }
169 }
170
171
172 void
nxt_buf_pool_destroy(nxt_buf_pool_t * bp)173 nxt_buf_pool_destroy(nxt_buf_pool_t *bp)
174 {
175 nxt_buf_t *b, *n;
176
177 bp->destroy = 1;
178
179 for (b = bp->free; b != NULL; b = n) {
180 n = b->next;
181 nxt_buf_free(bp->mem_pool, b);
182 }
183
184 bp->free = b; /* NULL */
185 }
186