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.c | |
download | unit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.gz unit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.bz2 |
Initial version.
Diffstat (limited to '')
-rw-r--r-- | src/nxt_buf.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/nxt_buf.c b/src/nxt_buf.c new file mode 100644 index 00000000..4789c0c7 --- /dev/null +++ b/src/nxt_buf.c @@ -0,0 +1,171 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#include <nxt_main.h> + + +static void nxt_buf_completion(nxt_thread_t *thr, void *obj, void *data); + + +nxt_buf_t * +nxt_buf_mem_alloc(nxt_mem_pool_t *mp, size_t size, nxt_uint_t flags) +{ + nxt_buf_t *b; + + b = nxt_mem_cache_zalloc0(mp, NXT_BUF_MEM_SIZE); + if (nxt_slow_path(b == NULL)) { + return NULL; + } + + b->data = mp; + b->completion_handler = nxt_buf_completion; + b->size = NXT_BUF_MEM_SIZE; + + if (size != 0) { + b->mem.start = nxt_mem_buf(mp, &size, flags); + if (nxt_slow_path(b->mem.start == NULL)) { + return NULL; + } + + b->mem.pos = b->mem.start; + b->mem.free = b->mem.start; + b->mem.end = b->mem.start + size; + } + + return b; +} + + +nxt_buf_t * +nxt_buf_file_alloc(nxt_mem_pool_t *mp, size_t size, nxt_uint_t flags) +{ + nxt_buf_t *b; + + b = nxt_mem_cache_zalloc0(mp, NXT_BUF_FILE_SIZE); + if (nxt_slow_path(b == NULL)) { + return NULL; + } + + b->data = mp; + b->completion_handler = nxt_buf_completion; + b->size = NXT_BUF_FILE_SIZE; + nxt_buf_set_file(b); + + if (size != 0) { + b->mem.start = nxt_mem_buf(mp, &size, flags); + if (nxt_slow_path(b->mem.start == NULL)) { + return NULL; + } + + b->mem.pos = b->mem.start; + b->mem.free = b->mem.start; + b->mem.end = b->mem.start + size; + } + + return b; +} + + +nxt_buf_t * +nxt_buf_mmap_alloc(nxt_mem_pool_t *mp, size_t size) +{ + nxt_buf_t *b; + + b = nxt_mem_cache_zalloc0(mp, NXT_BUF_MMAP_SIZE); + + if (nxt_fast_path(b != NULL)) { + b->data = mp; + b->completion_handler = nxt_buf_completion; + b->size = NXT_BUF_MMAP_SIZE; + + nxt_buf_set_file(b); + nxt_buf_set_mmap(b); + nxt_buf_mem_set_size(&b->mem, size); + } + + return b; +} + + +nxt_buf_t * +nxt_buf_sync_alloc(nxt_mem_pool_t *mp, nxt_uint_t flags) +{ + nxt_buf_t *b; + + b = nxt_mem_cache_zalloc0(mp, NXT_BUF_SYNC_SIZE); + + if (nxt_fast_path(b != NULL)) { + b->data = mp; + b->completion_handler = nxt_buf_completion; + b->size = NXT_BUF_SYNC_SIZE; + + nxt_buf_set_sync(b); + b->is_nobuf = ((flags & NXT_BUF_SYNC_NOBUF) != 0); + b->is_flush = ((flags & NXT_BUF_SYNC_FLUSH) != 0); + b->is_last = ((flags & NXT_BUF_SYNC_LAST) != 0); + } + + return b; +} + + +void +nxt_buf_chain_add(nxt_buf_t **head, nxt_buf_t *in) +{ + nxt_buf_t *b, **prev; + + prev = head; + + for (b = *head; b != NULL; b = b->next) { + prev = &b->next; + } + + *prev = in; +} + + +size_t +nxt_buf_chain_length(nxt_buf_t *b) +{ + size_t length; + + length = 0; + + while (b != NULL) { + length += b->mem.free - b->mem.pos; + b = b->next; + } + + return length; +} + + +static void +nxt_buf_completion(nxt_thread_t *thr, void *obj, void *data) +{ + nxt_buf_t *b, *parent; + nxt_mem_pool_t *mp; + + b = obj; + parent = data; + + nxt_log_debug(thr->log, "buf completion: %p %p", b, b->mem.start); + + mp = b->data; + nxt_buf_free(mp, b); + + if (parent != NULL) { + nxt_log_debug(thr->log, "parent retain:%uD", parent->retain); + + parent->retain--; + + if (parent->retain == 0) { + parent->mem.pos = parent->mem.free; + + parent->completion_handler(thr, parent, parent->parent); + } + } +} |