diff options
author | Igor Sysoev <igor@sysoev.ru> | 2017-01-17 20:00:00 +0300 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2017-01-17 20:00:00 +0300 |
commit | 16cbf3c076a0aca6d47adaf3f719493674cf2363 (patch) | |
tree | e6530480020f62a2bdbf249988ec3e2a751d3927 /src/nxt_buf_pool.c | |
download | unit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.gz unit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.bz2 |
Initial version.
Diffstat (limited to 'src/nxt_buf_pool.c')
-rw-r--r-- | src/nxt_buf_pool.c | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/src/nxt_buf_pool.c b/src/nxt_buf_pool.c new file mode 100644 index 00000000..092cf58d --- /dev/null +++ b/src/nxt_buf_pool.c @@ -0,0 +1,191 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#include <nxt_main.h> + + +nxt_int_t +nxt_buf_pool_mem_alloc(nxt_buf_pool_t *bp, size_t size) +{ + nxt_buf_t *b; + + b = bp->current; + + if (b != NULL && b->mem.free < b->mem.end) { + return NXT_OK; + } + + b = bp->free; + + if (b != NULL) { + bp->current = b; + bp->free = b->next; + b->next = NULL; + return NXT_OK; + } + + if (bp->num >= bp->max) { + return NXT_AGAIN; + } + + if (size == 0 || size >= bp->size + bp->size / 4) { + size = bp->size; + } + + b = nxt_buf_mem_alloc(bp->mem_pool, size, bp->flags); + + if (nxt_fast_path(b != NULL)) { + bp->current = b; + bp->num++; + return NXT_OK; + } + + return NXT_ERROR; +} + + +nxt_int_t +nxt_buf_pool_file_alloc(nxt_buf_pool_t *bp, size_t size) +{ + nxt_buf_t *b; + + b = bp->current; + + if (b != NULL && b->mem.free < b->mem.end) { + return NXT_OK; + } + + b = bp->free; + + if (b != NULL) { + bp->current = b; + bp->free = b->next; + b->next = NULL; + return NXT_OK; + } + + if (bp->num >= bp->max) { + return NXT_AGAIN; + } + + if (size == 0 || size >= bp->size + bp->size / 4) { + size = bp->size; + } + + b = nxt_buf_file_alloc(bp->mem_pool, size, bp->flags); + + if (nxt_fast_path(b != NULL)) { + bp->current = b; + bp->num++; + return NXT_OK; + } + + return NXT_ERROR; +} + + +nxt_int_t +nxt_buf_pool_mmap_alloc(nxt_buf_pool_t *bp, size_t size) +{ + nxt_buf_t *b; + + b = bp->current; + + if (b != NULL) { + return NXT_OK; + } + + b = bp->free; + + if (b != NULL) { + bp->current = b; + bp->free = b->next; + b->next = NULL; + return NXT_OK; + } + + if (bp->num >= bp->max) { + return NXT_AGAIN; + } + + if (size == 0 || size >= bp->size + bp->size / 4) { + size = bp->size; + } + + b = nxt_buf_mmap_alloc(bp->mem_pool, size); + + if (nxt_fast_path(b != NULL)) { + bp->mmap = 1; + bp->current = b; + bp->num++; + return NXT_OK; + } + + return NXT_ERROR; +} + + +void +nxt_buf_pool_free(nxt_buf_pool_t *bp, nxt_buf_t *b) +{ + size_t size; + + nxt_thread_log_debug("buf pool free: %p %p", b, b->mem.start); + + size = nxt_buf_mem_size(&b->mem); + + if (bp->mmap) { + nxt_mem_unmap(b->mem.start, &b->mmap, size); + } + + if (bp->destroy) { + + if (b == bp->current) { + bp->current = NULL; + } + + if (!bp->mmap) { + nxt_mem_free(bp->mem_pool, b->mem.start); + } + + nxt_buf_free(bp->mem_pool, b); + + return; + } + + if (bp->mmap) { + b->mem.pos = NULL; + b->mem.free = NULL; + nxt_buf_mem_set_size(&b->mem, size); + + } else { + b->mem.pos = b->mem.start; + b->mem.free = b->mem.start; + } + + if (b != bp->current) { + b->next = bp->free; + bp->free = b; + } +} + + +void +nxt_buf_pool_destroy(nxt_buf_pool_t *bp) +{ + u_char *p; + nxt_buf_t *b; + + bp->destroy = 1; + + for (b = bp->free; b != NULL; b = b->next) { + p = b->mem.start; + nxt_buf_free(bp->mem_pool, b); + nxt_mem_free(bp->mem_pool, p); + } + + bp->free = b; /* NULL */ +} |