summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_buf.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.c
downloadunit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.gz
unit-16cbf3c076a0aca6d47adaf3f719493674cf2363.tar.bz2
Initial version.
Diffstat (limited to 'src/nxt_buf.c')
-rw-r--r--src/nxt_buf.c171
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);
+ }
+ }
+}