From 4983c53d3e3be3916fab484b3d0dd36b609b95db Mon Sep 17 00:00:00 2001
From: Krzysztof Piotr Oledzki <ole#ans.pl>
Date: Thu, 29 May 2008 23:53:44 +0200
Subject: [MEDIUM] Fix memory freeing at exit
New functions implemented:
Add missing pool_destroy2 calls:
Implement all task stopping:
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.
--- include/proto/acl.h | 3 +++ include/proto/fd.h | 5 +++++ include/types/server.h | 1 + src/acl.c | 16 ++++++++++++++++ src/appsession.c | 27 +++++++++++++++++---------- src/checks.c | 2 ++ src/fd.c | 16 ++++++++++++++++ src/haproxy.c | 32 +++++++++++++++++++++++++++----- src/memory.c | 2 ++ 9 files changed, 89 insertions(+), 15 deletions(-) diff --git a/include/proto/acl.h b/include/proto/acl.h index 4e2b301..8b0c5e0 100644 --- a/include/proto/acl.h +++ b/include/proto/acl.h @@ -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. diff --git a/include/proto/fd.h b/include/proto/fd.h index 74b04b2..1cba33b 100644 --- a/include/proto/fd.h +++ b/include/proto/fd.h @@ -46,6 +46,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, * otherwise 1. The fork() function may be NULL if unused. In case of error, diff --git a/include/types/server.h b/include/types/server.h index 0e2183e..462db2b 100644 --- a/include/types/server.h +++ b/include/types/server.h @@ -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() */ diff --git a/src/acl.c b/src/acl.c index aa095c5..96b21de 100644 --- a/src/acl.c +++ b/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. diff --git a/src/appsession.c b/src/appsession.c index 9b6868c..e1a01cc 100644 --- a/src/appsession.c +++ b/src/appsession.c @@ -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() */ diff --git a/src/checks.c b/src/checks.c index 0b8756b..be26711 100644 --- a/src/checks.c +++ b/src/checks.c @@ -848,6 +848,8 @@ int start_checks() { return -1; } + s->check = t; + t->wq = NULL; t->qlist.p = NULL; t->state = TASK_IDLE; diff --git a/src/fd.c b/src/fd.c index 9c370fa..eaaaabf 100644 --- a/src/fd.c +++ b/src/fd.c @@ -87,6 +87,22 @@ int init_pollers() } /* + * 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. */ diff --git a/src/haproxy.c b/src/haproxy.c index b42728e..4b6bdf8 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -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> */ diff --git a/src/memory.c b/src/memory.c index b157cf0..2fe3766 100644 --- a/src/memory.c +++ b/src/memory.c @@ -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; } } -- 1.5.5.1Received on 2008/05/30 00:00
This archive was generated by hypermail 2.2.0 : 2008/05/30 00:15 CEST