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.
185 lines
3.0 KiB
C
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 */
|
|
}
|