From: Willy Tarreau Date: Sat, 21 Mar 2009 17:13:21 +0000 (+0100) Subject: [MINOR] task: keep a task count and clean up task creators X-Git-Tag: v1.3.16~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a461318f97504c52f24bcd23a38094cd823dfd74;p=thirdparty%2Fhaproxy.git [MINOR] task: keep a task count and clean up task creators It's sometimes useful at least for statistics to keep a task count. It's easy to do by forcing the rare task creators to always use the same functions to create/destroy a task. --- diff --git a/include/proto/task.h b/include/proto/task.h index 86a3c3d815..54418b64ed 100644 --- a/include/proto/task.h +++ b/include/proto/task.h @@ -78,6 +78,7 @@ #define TIMER_LOOK_BACK (1U << 31) /* a few exported variables */ +extern unsigned int nb_tasks; /* total number of tasks */ extern unsigned int run_queue; /* run queue size */ extern unsigned int niced_tasks; /* number of niced tasks in the run queue */ extern struct pool_head *pool2_task; @@ -160,8 +161,9 @@ static inline struct task *task_delete(struct task *t) } /* - * Initialize a new task. The bare minimum is performed (queue pointers and state). - * The task is returned. + * Initialize a new task. The bare minimum is performed (queue pointers and + * state). The task is returned. This function should not be used outside of + * task_new(). */ static inline struct task *task_init(struct task *t) { @@ -173,11 +175,28 @@ static inline struct task *task_init(struct task *t) } /* - * frees a task. Its context must have been freed since it will be lost. + * Allocate and initialise a new task. The new task is returned, or NULL in + * case of lack of memory. The task count is incremented. Tasks should only + * be allocated this way, and must be freed using task_free(). + */ +static inline struct task *task_new(void) +{ + struct task *t = pool_alloc2(pool2_task); + if (t) { + nb_tasks++; + task_init(t); + } + return t; +} + +/* + * Free a task. Its context must have been freed since it will be lost. + * The task count is decremented. */ static inline void task_free(struct task *t) { pool_free2(pool2_task, t); + nb_tasks--; } /* Place into the wait queue, where it may already be. If the expiration diff --git a/src/appsession.c b/src/appsession.c index a1c1c886aa..754e261601 100644 --- a/src/appsession.c +++ b/src/appsession.c @@ -87,10 +87,9 @@ int appsession_task_init(void) { static int initialized = 0; if (!initialized) { - if ((appsess_refresh = pool_alloc2(pool2_task)) == NULL) + if ((appsess_refresh = task_new()) == NULL) return -1; - task_init(appsess_refresh); appsess_refresh->context = NULL; appsess_refresh->expire = tick_add(now_ms, MS_TO_TICKS(TBLCHKINT)); appsess_refresh->process = appsession_refresh; diff --git a/src/checks.c b/src/checks.c index f1e8120a79..50b464f6cd 100644 --- a/src/checks.c +++ b/src/checks.c @@ -837,14 +837,12 @@ int start_checks() { if (!(s->state & SRV_CHECKED)) continue; - if ((t = pool_alloc2(pool2_task)) == NULL) { + if ((t = task_new()) == NULL) { Alert("Starting [%s:%s] check: out of memory.\n", px->id, s->id); return -1; } s->check = t; - - task_init(t); t->process = process_chk; t->context = s; diff --git a/src/client.c b/src/client.c index f5ce3c61d0..765a54b374 100644 --- a/src/client.c +++ b/src/client.c @@ -134,7 +134,7 @@ int event_accept(int fd) { s->flags |= SN_MONITOR; } - if ((t = pool_alloc2(pool2_task)) == NULL) { /* disable this proxy for a while */ + if ((t = task_new()) == NULL) { /* disable this proxy for a while */ Alert("out of memory in event_accept().\n"); EV_FD_CLR(fd, DIR_RD); p->state = PR_STIDLE; @@ -160,7 +160,6 @@ int event_accept(int fd) { if (p->options & PR_O_TCP_NOLING) setsockopt(cfd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger)); - task_init(t); t->process = l->handler; t->context = s; @@ -473,7 +472,7 @@ int event_accept(int fd) { pool_free2(p->req_cap_pool, txn->req.cap); out_fail_reqcap: out_free_task: - pool_free2(pool2_task, t); + task_free(t); out_free_session: LIST_DEL(&s->list); pool_free2(pool2_session, s); diff --git a/src/proto_uxst.c b/src/proto_uxst.c index 1b38774105..baf91ef1e6 100644 --- a/src/proto_uxst.c +++ b/src/proto_uxst.c @@ -414,7 +414,7 @@ int uxst_event_accept(int fd) { s->flags = 0; s->term_trace = 0; - if ((t = pool_alloc2(pool2_task)) == NULL) { + if ((t = task_new()) == NULL) { Alert("out of memory in uxst_event_accept().\n"); goto out_free_session; } @@ -432,7 +432,6 @@ int uxst_event_accept(int fd) { goto out_free_task; } - task_init(t); t->process = l->handler; t->context = s; t->nice = -64; /* we want to boost priority for local stats */ @@ -550,7 +549,7 @@ int uxst_event_accept(int fd) { out_free_req: pool_free2(pool2_buffer, s->req); out_free_task: - pool_free2(pool2_task, t); + task_free(t); out_free_session: LIST_DEL(&s->list); pool_free2(pool2_session, s); diff --git a/src/task.c b/src/task.c index 72e3a93e5c..8374c12749 100644 --- a/src/task.c +++ b/src/task.c @@ -25,6 +25,7 @@ struct pool_head *pool2_task; +unsigned int nb_tasks = 0; unsigned int run_queue = 0; unsigned int niced_tasks = 0; /* number of niced tasks in the run queue */ struct eb32_node *last_timer = NULL; /* optimization: last queued timer */