Files
nginx-unit/src/nxt_buf_pool.c
Max Romanov f319220a6c Redirecting buffer completion handler to specific engine.
There is a case in router where we use port in router connection thread.
Buffers are allocated within connection memory pool which can be used only in
this router thread. sendmsg() can be postponed into main router thread and
completion handler will compare current engine and post itself to correct
engine.
2017-07-07 16:01:34 +03:00

185 lines
3.0 KiB
C

/*
* 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;
}
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)
{
nxt_buf_t *b;
bp->destroy = 1;
for (b = bp->free; b != NULL; b = b->next) {
nxt_buf_free(bp->mem_pool, b);
}
bp->free = b; /* NULL */
}