191 lines
4.3 KiB
C
191 lines
4.3 KiB
C
/*
|
|
* Copyright (C) AlexWoo(Wu Jie) wj19840501@gmail.com
|
|
*/
|
|
|
|
|
|
#include "ngx_poold.h"
|
|
#include "ngx_map.h"
|
|
|
|
|
|
typedef struct ngx_poold_node_s ngx_poold_node_t;
|
|
|
|
static ngx_pool_t *ngx_poold_pool;
|
|
|
|
static ngx_map_t ngx_poold_map;
|
|
static ngx_poold_node_t *ngx_poold_free_node;
|
|
|
|
static ngx_uint_t ngx_poold_nalloc;
|
|
static ngx_uint_t ngx_poold_nfree;
|
|
|
|
|
|
struct ngx_poold_node_s {
|
|
ngx_map_node_t m; /* map node */
|
|
ngx_poold_node_t *next; /* free node */
|
|
|
|
ngx_pool_t *pool;
|
|
char *file; /* file create pool */
|
|
int line; /* line create pool */
|
|
};
|
|
|
|
|
|
static ngx_int_t
|
|
ngx_poold_init()
|
|
{
|
|
ngx_poold_pool = ngx_create_pool(4096, ngx_cycle->log);
|
|
if (ngx_poold_pool == NULL) {
|
|
return NGX_ERROR;
|
|
}
|
|
|
|
ngx_map_init(&ngx_poold_map, ngx_map_hash_uint, ngx_cmp_uint);
|
|
ngx_poold_free_node = NULL;
|
|
|
|
ngx_poold_nalloc = 0;
|
|
ngx_poold_nfree = 0;
|
|
|
|
return NGX_OK;
|
|
}
|
|
|
|
|
|
static ngx_poold_node_t *
|
|
ngx_poold_get_node()
|
|
{
|
|
ngx_poold_node_t *n;
|
|
|
|
n = ngx_poold_free_node;
|
|
if (n == NULL) {
|
|
n = ngx_pcalloc(ngx_poold_pool, sizeof(ngx_poold_node_t));
|
|
if (n == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
++ngx_poold_nalloc;
|
|
} else {
|
|
ngx_poold_free_node = n->next;
|
|
ngx_memzero(n, sizeof(ngx_poold_node_t));
|
|
|
|
--ngx_poold_nfree;
|
|
}
|
|
|
|
return n;
|
|
}
|
|
|
|
|
|
static void
|
|
ngx_poold_put_node(ngx_poold_node_t *node)
|
|
{
|
|
if (ngx_poold_pool == NULL) {
|
|
return;
|
|
}
|
|
|
|
if (node == NULL) {
|
|
return;
|
|
}
|
|
|
|
node->next = ngx_poold_free_node;
|
|
ngx_poold_free_node = node;
|
|
|
|
++ngx_poold_nfree;
|
|
}
|
|
|
|
|
|
ngx_pool_t *
|
|
ngx_create_pool_debug(size_t size, ngx_log_t *log, char *file, int line)
|
|
{
|
|
ngx_poold_node_t *node;
|
|
|
|
if (ngx_poold_pool == NULL) {
|
|
ngx_poold_init();
|
|
}
|
|
|
|
/* construct a poold node */
|
|
node = ngx_poold_get_node();
|
|
node->pool = ngx_create_pool(size, log);
|
|
node->file = file;
|
|
node->line = line;
|
|
|
|
/* record node in poold map */
|
|
node->m.raw_key = (intptr_t) node->pool;
|
|
ngx_map_insert(&ngx_poold_map, &node->m, 0);
|
|
|
|
return node->pool;
|
|
}
|
|
|
|
|
|
void
|
|
ngx_destroy_pool_debug(ngx_pool_t *pool, char *file, int line)
|
|
{
|
|
ngx_poold_node_t *node;
|
|
ngx_map_node_t *m;
|
|
|
|
/* get node by pool */
|
|
m = ngx_map_find(&ngx_poold_map, (intptr_t) pool);
|
|
if (m == NULL) {
|
|
ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, 0,
|
|
"destroy pool twice: %s:%d", file, line);
|
|
return;
|
|
}
|
|
ngx_map_delete(&ngx_poold_map, (intptr_t) pool);
|
|
node = (ngx_poold_node_t *) ((char *) m - offsetof(ngx_poold_node_t, m));
|
|
|
|
ngx_destroy_pool(pool);
|
|
|
|
/* put node in poold map */
|
|
ngx_poold_put_node(node);
|
|
}
|
|
|
|
|
|
ngx_chain_t *
|
|
ngx_poold_state(ngx_http_request_t *r, unsigned detail)
|
|
{
|
|
ngx_chain_t *cl;
|
|
ngx_buf_t *b;
|
|
ngx_map_node_t *node;
|
|
ngx_poold_node_t *pn;
|
|
size_t len, len1;
|
|
ngx_uint_t n;
|
|
|
|
len = sizeof("##########ngx debug pool##########\n") - 1
|
|
+ sizeof("ngx_poold nalloc node: \n") - 1 + NGX_OFF_T_LEN
|
|
+ sizeof("ngx_poold nfree node: \n") - 1 + NGX_OFF_T_LEN;
|
|
|
|
len1 = 0;
|
|
|
|
/* node for create pool */
|
|
if (detail) {
|
|
n = ngx_poold_nalloc - ngx_poold_nfree;
|
|
/* " file:line\n" */
|
|
len1 = 4 + 256 + 1 + NGX_OFF_T_LEN + 1;
|
|
len += len1 * n;
|
|
}
|
|
|
|
cl = ngx_alloc_chain_link(r->pool);
|
|
if (cl == NULL) {
|
|
return NULL;
|
|
}
|
|
cl->next = NULL;
|
|
|
|
b = ngx_create_temp_buf(r->pool, len);
|
|
if (b == NULL) {
|
|
return NULL;
|
|
}
|
|
cl->buf = b;
|
|
|
|
b->last = ngx_snprintf(b->last, len,
|
|
"##########ngx debug pool##########\n"
|
|
"ngx_poold nalloc node: %ui\nngx_poold nfree node: %ui\n",
|
|
ngx_poold_nalloc, ngx_poold_nfree);
|
|
|
|
if (detail) {
|
|
for (node = ngx_map_begin(&ngx_poold_map); node;
|
|
node = ngx_map_next(node))
|
|
{
|
|
/* m is first element of ngx_poold_node_t */
|
|
pn = (ngx_poold_node_t *) node;
|
|
b->last = ngx_snprintf(b->last, len1, " %s:%d\n",
|
|
pn->file, pn->line);
|
|
}
|
|
}
|
|
|
|
return cl;
|
|
}
|