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 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 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 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 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 if (!bp->mmap) { 151 nxt_mem_free(bp->mem_pool, b->mem.start); 152 } 153 154 nxt_buf_free(bp->mem_pool, b); 155 156 return; 157 } 158 159 if (bp->mmap) { 160 b->mem.pos = NULL; 161 b->mem.free = NULL; 162 nxt_buf_mem_set_size(&b->mem, size); 163 164 } else { 165 b->mem.pos = b->mem.start; 166 b->mem.free = b->mem.start; 167 } 168 169 if (b != bp->current) { 170 b->next = bp->free; 171 bp->free = b; 172 } 173 } 174 175 176 void 177 nxt_buf_pool_destroy(nxt_buf_pool_t *bp) 178 { 179 u_char *p; 180 nxt_buf_t *b; 181 182 bp->destroy = 1; 183 184 for (b = bp->free; b != NULL; b = b->next) { 185 p = b->mem.start; 186 nxt_buf_free(bp->mem_pool, b); 187 nxt_mem_free(bp->mem_pool, p); 188 } 189 190 bp->free = b; /* NULL */ 191 } 192