summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_buf_pool.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2017-01-17 20:00:00 +0300
committerIgor Sysoev <igor@sysoev.ru>2017-01-17 20:00:00 +0300
commit16cbf3c076a0aca6d47adaf3f719493674cf2363 (patch)
treee6530480020f62a2bdbf249988ec3e2a751d3927 /src/nxt_buf_pool.c
downloadunit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.gz
unit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.bz2
Initial version.
Diffstat (limited to 'src/nxt_buf_pool.c')
-rw-r--r--src/nxt_buf_pool.c191
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 */
+}