mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-11-04 04:13:56 +08:00
update 2026-10-29 18:46:39
This commit is contained in:
1 parent
e2f86e09f4
commit
95f76f26d3
5034 files changed
+2043234
No files matched your search
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (C) AlexWoo(Wu Jie) wj19840501@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
#include "ngx_timerd.h"
|
||||
#include "ngx_map.h"
|
||||
|
||||
|
||||
typedef struct ngx_timerd_node_s ngx_timerd_node_t;
|
||||
|
||||
static ngx_pool_t *ngx_timerd_pool;
|
||||
|
||||
static ngx_map_t ngx_timerd_map;
|
||||
static ngx_timerd_node_t *ngx_timerd_free_node;
|
||||
|
||||
static ngx_uint_t timerd_footprint;
|
||||
static ngx_uint_t ngx_timerd_nalloc;
|
||||
static ngx_uint_t ngx_timerd_nfree;
|
||||
|
||||
|
||||
struct ngx_timerd_node_s {
|
||||
ngx_map_node_t m; /* map node */
|
||||
ngx_timerd_node_t *next; /* free node */
|
||||
|
||||
ngx_uint_t footprint;
|
||||
off_t fpoff;
|
||||
ngx_event_t ev;
|
||||
|
||||
ngx_event_t *uev;
|
||||
char *file; /* file create pool */
|
||||
int line; /* line create pool */
|
||||
};
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_timerd_init()
|
||||
{
|
||||
ngx_timerd_pool = ngx_create_pool(4096, ngx_cycle->log);
|
||||
if (ngx_timerd_pool == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_map_init(&ngx_timerd_map, ngx_map_hash_uint, ngx_cmp_uint);
|
||||
ngx_timerd_free_node = NULL;
|
||||
|
||||
ngx_timerd_nalloc = 0;
|
||||
ngx_timerd_nfree = 0;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_timerd_node_t *
|
||||
ngx_timerd_get_node()
|
||||
{
|
||||
ngx_timerd_node_t *n;
|
||||
|
||||
n = ngx_timerd_free_node;
|
||||
if (n == NULL) {
|
||||
n = ngx_pcalloc(ngx_timerd_pool, sizeof(ngx_timerd_node_t));
|
||||
if (n == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
++ngx_timerd_nalloc;
|
||||
} else {
|
||||
ngx_timerd_free_node = n->next;
|
||||
ngx_memzero(n, sizeof(ngx_timerd_node_t));
|
||||
|
||||
--ngx_timerd_nfree;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_timerd_put_node(ngx_timerd_node_t *node)
|
||||
{
|
||||
if (ngx_timerd_pool == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
node->next = ngx_timerd_free_node;
|
||||
ngx_timerd_free_node = node;
|
||||
|
||||
++ngx_timerd_nfree;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_timerd_wrap(ngx_event_t *ev)
|
||||
{
|
||||
ngx_timerd_node_t *node;
|
||||
ngx_event_t *uev;
|
||||
ngx_uint_t *fp;
|
||||
|
||||
node = ev->data;
|
||||
uev = node->uev;
|
||||
|
||||
fp = (ngx_uint_t *) ((char *) (uev->data) + node->fpoff);
|
||||
if (*fp != node->footprint) {
|
||||
ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, 0,
|
||||
"timer wrap, timer trigger but not timer owner: %s:%d",
|
||||
node->file, node->line);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_map_delete(&ngx_timerd_map, (intptr_t) uev);
|
||||
|
||||
uev->timer_set = 0;
|
||||
uev->timedout = 1;
|
||||
|
||||
uev->handler(uev);
|
||||
|
||||
ngx_timerd_put_node(node);
|
||||
}
|
||||
|
||||
|
||||
ngx_uint_t
|
||||
ngx_timerd_footprint()
|
||||
{
|
||||
return timerd_footprint++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_add_timer_debug(ngx_event_t *ev, ngx_msec_t timer, off_t fpoff,
|
||||
char *file, int line)
|
||||
{
|
||||
ngx_timerd_node_t *node;
|
||||
ngx_map_node_t *m;
|
||||
ngx_uint_t *fp;
|
||||
|
||||
if (ngx_timerd_pool == NULL) {
|
||||
ngx_timerd_init();
|
||||
}
|
||||
|
||||
fp = (ngx_uint_t *) ((char *) ev->data + fpoff);
|
||||
|
||||
m = ngx_map_find(&ngx_timerd_map, (intptr_t) ev);
|
||||
if (m == NULL) { // first add
|
||||
node = ngx_timerd_get_node();
|
||||
|
||||
node->m.raw_key = (intptr_t) ev;
|
||||
ngx_map_insert(&ngx_timerd_map, &node->m, 0);
|
||||
|
||||
node->footprint = *fp;
|
||||
node->fpoff = fpoff;
|
||||
|
||||
node->ev.log = ngx_cycle->log;
|
||||
node->ev.data = node;
|
||||
node->ev.handler = ngx_timerd_wrap;
|
||||
|
||||
node->uev = ev;
|
||||
node->file = file;
|
||||
node->line = line;
|
||||
} else {
|
||||
node = (ngx_timerd_node_t *) ((char *) m -
|
||||
offsetof(ngx_timerd_node_t, m));
|
||||
if (node->footprint != *fp) {
|
||||
ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, 0,
|
||||
"add timer but not timer owner(%s:%d): %s:%d",
|
||||
node->file, node->line, file, line);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ev->timer_set = 1;
|
||||
ngx_add_timer(&node->ev, timer);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_del_timer_debug(ngx_event_t *ev, ngx_uint_t footprint, char *file, int line)
|
||||
{
|
||||
ngx_timerd_node_t *node;
|
||||
ngx_map_node_t *m;
|
||||
|
||||
/* get node by pool */
|
||||
m = ngx_map_find(&ngx_timerd_map, (intptr_t) ev);
|
||||
if (m == NULL) {
|
||||
ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, 0,
|
||||
"delete timer twice: %s:%d", file, line);
|
||||
return;
|
||||
}
|
||||
|
||||
node = (ngx_timerd_node_t *) ((char *) m - offsetof(ngx_timerd_node_t, m));
|
||||
if (node->footprint != footprint) {
|
||||
ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, 0,
|
||||
"delete timer but not timer owner: %s:%d", file, line);
|
||||
return;
|
||||
}
|
||||
|
||||
ngx_map_delete(&ngx_timerd_map, (intptr_t) ev);
|
||||
|
||||
if (node->ev.timer_set) {
|
||||
ev->timer_set = 0;
|
||||
ngx_del_timer(&node->ev);
|
||||
}
|
||||
|
||||
if (node->ev.posted) {
|
||||
ngx_delete_posted_event(&node->ev);
|
||||
}
|
||||
|
||||
/* put node in timerd map */
|
||||
ngx_timerd_put_node(node);
|
||||
}
|
||||
|
||||
|
||||
ngx_chain_t *
|
||||
ngx_timerd_state(ngx_http_request_t *r, unsigned detail)
|
||||
{
|
||||
ngx_chain_t *cl;
|
||||
ngx_buf_t *b;
|
||||
ngx_map_node_t *node;
|
||||
ngx_timerd_node_t *pn;
|
||||
size_t len, len1;
|
||||
ngx_uint_t n;
|
||||
|
||||
len = sizeof("##########ngx debug pool##########\n") - 1
|
||||
+ sizeof("ngx_timerd nalloc node: \n") - 1 + NGX_OFF_T_LEN
|
||||
+ sizeof("ngx_timerd nfree node: \n") - 1 + NGX_OFF_T_LEN;
|
||||
|
||||
len1 = 0;
|
||||
|
||||
/* node for create pool */
|
||||
if (detail) {
|
||||
n = ngx_timerd_nalloc - ngx_timerd_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_timerd nalloc node: %ui\nngx_timerd nfree node: %ui\n",
|
||||
ngx_timerd_nalloc, ngx_timerd_nfree);
|
||||
|
||||
if (detail) {
|
||||
for (node = ngx_map_begin(&ngx_timerd_map); node;
|
||||
node = ngx_map_next(node))
|
||||
{
|
||||
/* m is first element of ngx_timerd_node_t */
|
||||
pn = (ngx_timerd_node_t *) node;
|
||||
b->last = ngx_snprintf(b->last, len1, " %s:%d\n",
|
||||
pn->file, pn->line);
|
||||
}
|
||||
}
|
||||
|
||||
return cl;
|
||||
}
|
||||
Reference in new issue
Block a user