[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 86a3c3d..54418b6 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 @@
}
/*
- * 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 @@
}
/*
- * 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 <task> into the wait queue, where it may already be. If the expiration
diff --git a/src/appsession.c b/src/appsession.c
index a1c1c88..754e261 100644
--- a/src/appsession.c
+++ b/src/appsession.c
@@ -87,10 +87,9 @@
{
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 f1e8120..50b464f 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -837,14 +837,12 @@
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 f5ce3c6..765a54b 100644
--- a/src/client.c
+++ b/src/client.c
@@ -134,7 +134,7 @@
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 @@
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 @@
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 1b38774..baf91ef 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -414,7 +414,7 @@
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 @@
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 @@
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 72e3a93..8374c12 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 */