mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-05-11 20:28:13 +00:00
[MEDIUM] Fix memory freeing at exit
New functions implemented: - deinit_pollers: called at the end of deinit()) - prune_acl: called via list_for_each_entry_safe Add missing pool_destroy2 calls: - p->hdr_idx_pool - pool2_tree64 Implement all task stopping: - health-check: needs new "struct task" in the struct server - queue processing: queue_mgt - appsess_refresh: appsession_refresh before (idle system): ==6079== LEAK SUMMARY: ==6079== definitely lost: 1,112 bytes in 75 blocks. ==6079== indirectly lost: 53,356 bytes in 2,090 blocks. ==6079== possibly lost: 52 bytes in 1 blocks. ==6079== still reachable: 150,996 bytes in 504 blocks. ==6079== suppressed: 0 bytes in 0 blocks. after (idle system): ==6945== LEAK SUMMARY: ==6945== definitely lost: 7,644 bytes in 137 blocks. ==6945== indirectly lost: 9,913 bytes in 587 blocks. ==6945== possibly lost: 0 bytes in 0 blocks. ==6945== still reachable: 0 bytes in 0 blocks. ==6945== suppressed: 0 bytes in 0 blocks. before (running system for ~2m): ==9343== LEAK SUMMARY: ==9343== definitely lost: 1,112 bytes in 75 blocks. ==9343== indirectly lost: 54,199 bytes in 2,122 blocks. ==9343== possibly lost: 52 bytes in 1 blocks. ==9343== still reachable: 151,128 bytes in 509 blocks. ==9343== suppressed: 0 bytes in 0 blocks. after (running system for ~2m): ==11616== LEAK SUMMARY: ==11616== definitely lost: 7,644 bytes in 137 blocks. ==11616== indirectly lost: 9,981 bytes in 591 blocks. ==11616== possibly lost: 0 bytes in 0 blocks. ==11616== still reachable: 4 bytes in 1 blocks. ==11616== suppressed: 0 bytes in 0 blocks. Still not perfect but significant improvement.
This commit is contained in:
parent
1acf217366
commit
a643baf091
@ -47,6 +47,9 @@ struct acl_keyword *find_acl_kw(const char *kw);
|
||||
*/
|
||||
struct acl_expr *parse_acl_expr(const char **args);
|
||||
|
||||
/* Purge everything in the acl <acl>, then return <acl>. */
|
||||
struct acl *prune_acl(struct acl *acl);
|
||||
|
||||
/* Parse an ACL with the name starting at <args>[0], and with a list of already
|
||||
* known ACLs in <acl>. If the ACL was not in the list, it will be added.
|
||||
* A pointer to that ACL is returned.
|
||||
|
@ -45,6 +45,11 @@ void disable_poller(const char *poller_name);
|
||||
*/
|
||||
int init_pollers();
|
||||
|
||||
/*
|
||||
* Deinitialize the pollers.
|
||||
*/
|
||||
void deinit_pollers();
|
||||
|
||||
/*
|
||||
* Some pollers may lose their connection after a fork(). It may be necessary
|
||||
* to create initialize part of them again. Returns 0 in case of failure,
|
||||
|
@ -84,6 +84,7 @@ struct server {
|
||||
int maxqueue; /* maximum number of pending connections allowed */
|
||||
struct list pendconns; /* pending connections */
|
||||
struct task *queue_mgt; /* the task associated to the queue processing */
|
||||
struct task *check; /* the task associated to the health check processing */
|
||||
|
||||
struct sockaddr_in addr; /* the address to connect to */
|
||||
struct sockaddr_in source_addr; /* the address to which we want to bind for connect() */
|
||||
|
16
src/acl.c
16
src/acl.c
@ -567,6 +567,22 @@ struct acl_expr *parse_acl_expr(const char **args)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Purge everything in the acl <acl>, then return <acl>. */
|
||||
struct acl *prune_acl(struct acl *acl) {
|
||||
|
||||
struct acl_expr *expr, *exprb;
|
||||
|
||||
free(acl->name);
|
||||
|
||||
list_for_each_entry_safe(expr, exprb, &acl->expr, list) {
|
||||
LIST_DEL(&expr->list);
|
||||
prune_acl_expr(expr);
|
||||
free(expr);
|
||||
}
|
||||
|
||||
return acl;
|
||||
}
|
||||
|
||||
/* Parse an ACL with the name starting at <args>[0], and with a list of already
|
||||
* known ACLs in <acl>. If the ACL was not in the list, it will be added.
|
||||
* A pointer to that ACL is returned.
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#include <proto/task.h>
|
||||
|
||||
|
||||
static struct task *appsess_refresh = NULL;
|
||||
struct pool_head *pool2_appsess;
|
||||
struct app_pool apools;
|
||||
int have_appsession;
|
||||
@ -87,17 +87,17 @@ int appsession_init(void)
|
||||
int appsession_task_init(void)
|
||||
{
|
||||
static int initialized = 0;
|
||||
struct task *t;
|
||||
if (!initialized) {
|
||||
if ((t = pool_alloc2(pool2_task)) == NULL)
|
||||
if ((appsess_refresh = pool_alloc2(pool2_task)) == NULL)
|
||||
return -1;
|
||||
t->wq = NULL;
|
||||
t->qlist.p = NULL;
|
||||
t->state = TASK_IDLE;
|
||||
t->context = NULL;
|
||||
tv_ms_add(&t->expire, &now, TBLCHKINT);
|
||||
t->process = appsession_refresh;
|
||||
task_queue(t);
|
||||
|
||||
appsess_refresh->wq = NULL;
|
||||
appsess_refresh->qlist.p = NULL;
|
||||
appsess_refresh->state = TASK_IDLE;
|
||||
appsess_refresh->context = NULL;
|
||||
tv_ms_add(&appsess_refresh->expire, &now, TBLCHKINT);
|
||||
appsess_refresh->process = appsession_refresh;
|
||||
task_queue(appsess_refresh);
|
||||
initialized ++;
|
||||
}
|
||||
return 0;
|
||||
@ -168,6 +168,13 @@ void appsession_cleanup( void )
|
||||
appsession_hash_destroy(&(p->htbl_proxy));
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if (appsess_refresh) {
|
||||
task_delete(appsess_refresh);
|
||||
task_free(appsess_refresh);
|
||||
appsess_refresh = NULL;
|
||||
}
|
||||
|
||||
}/* end appsession_cleanup() */
|
||||
|
||||
|
||||
|
@ -848,6 +848,8 @@ int start_checks() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
s->check = t;
|
||||
|
||||
t->wq = NULL;
|
||||
t->qlist.p = NULL;
|
||||
t->state = TASK_IDLE;
|
||||
|
16
src/fd.c
16
src/fd.c
@ -86,6 +86,22 @@ int init_pollers()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deinitialize the pollers.
|
||||
*/
|
||||
void deinit_pollers() {
|
||||
|
||||
struct poller *bp;
|
||||
int p;
|
||||
|
||||
for (p = 0; p < nbpollers; p++) {
|
||||
bp = &pollers[p];
|
||||
|
||||
if (bp && bp->pref)
|
||||
bp->term(bp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Lists the known pollers on <out>.
|
||||
* Should be performed only before initialization.
|
||||
|
@ -646,6 +646,7 @@ void deinit(void)
|
||||
struct listener *l,*l_next;
|
||||
struct acl_cond *cond, *condb;
|
||||
struct hdr_exp *exp, *expb;
|
||||
struct acl *acl, *aclb;
|
||||
int i;
|
||||
|
||||
while (p) {
|
||||
@ -718,10 +719,15 @@ void deinit(void)
|
||||
}
|
||||
|
||||
/* FIXME: this must also be freed :
|
||||
* - ACLs
|
||||
* - uri_auth (but it's shared)
|
||||
*/
|
||||
|
||||
list_for_each_entry_safe(acl, aclb, &p->acl, list) {
|
||||
LIST_DEL(&acl->list);
|
||||
prune_acl(acl);
|
||||
free(acl);
|
||||
}
|
||||
|
||||
if (p->appsession_name)
|
||||
free(p->appsession_name);
|
||||
|
||||
@ -745,10 +751,21 @@ void deinit(void)
|
||||
free(h);
|
||||
h = h_next;
|
||||
}/* end while(h) */
|
||||
|
||||
|
||||
s = p->srv;
|
||||
while (s) {
|
||||
s_next = s->next;
|
||||
|
||||
if (s->check) {
|
||||
task_delete(s->check);
|
||||
task_free(s->check);
|
||||
}
|
||||
|
||||
if (s->queue_mgt) {
|
||||
task_delete(s->queue_mgt);
|
||||
task_free(s->queue_mgt);
|
||||
}
|
||||
|
||||
if (s->id)
|
||||
free(s->id);
|
||||
|
||||
@ -758,16 +775,17 @@ void deinit(void)
|
||||
free(s);
|
||||
s = s_next;
|
||||
}/* end while(s) */
|
||||
|
||||
|
||||
l = p->listen;
|
||||
while (l) {
|
||||
l_next = l->next;
|
||||
free(l);
|
||||
l = l_next;
|
||||
}/* end while(l) */
|
||||
|
||||
|
||||
pool_destroy2(p->req_cap_pool);
|
||||
pool_destroy2(p->rsp_cap_pool);
|
||||
pool_destroy2(p->hdr_idx_pool);
|
||||
p0 = p;
|
||||
p = p->next;
|
||||
free(p0);
|
||||
@ -783,11 +801,12 @@ void deinit(void)
|
||||
|
||||
if (fdtab) free(fdtab);
|
||||
fdtab = NULL;
|
||||
|
||||
|
||||
pool_destroy2(pool2_session);
|
||||
pool_destroy2(pool2_buffer);
|
||||
pool_destroy2(pool2_requri);
|
||||
pool_destroy2(pool2_task);
|
||||
pool_destroy2(pool2_tree64);
|
||||
pool_destroy2(pool2_capture);
|
||||
pool_destroy2(pool2_appsess);
|
||||
pool_destroy2(pool2_pendconn);
|
||||
@ -796,6 +815,9 @@ void deinit(void)
|
||||
pool_destroy2(apools.serverid);
|
||||
pool_destroy2(apools.sessid);
|
||||
}
|
||||
|
||||
deinit_pollers();
|
||||
|
||||
} /* end deinit() */
|
||||
|
||||
/* sends the signal <sig> to all pids found in <oldpids> */
|
||||
|
@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
#include <common/config.h>
|
||||
#include <common/debug.h>
|
||||
#include <common/memory.h>
|
||||
#include <common/mini-clist.h>
|
||||
#include <common/standard.h>
|
||||
@ -51,6 +52,7 @@ struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags)
|
||||
if (flags & entry->flags & MEM_F_SHARED) {
|
||||
/* we can share this one */
|
||||
pool = entry;
|
||||
DPRINTF(stderr, "Sharing %s with %s\n", name, pool->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user