diff --git a/include/haproxy/server.h b/include/haproxy/server.h index c39b0e3c0..767764880 100644 --- a/include/haproxy/server.h +++ b/include/haproxy/server.h @@ -59,7 +59,7 @@ int srv_set_addr_via_libc(struct server *srv, int *err_code); int srv_init_addr(void); struct server *cli_find_server(struct appctx *appctx, char *arg); struct server *new_server(struct proxy *proxy); -void free_server(struct server *srv); +struct server *free_server(struct server *srv); int srv_init_per_thr(struct server *srv); /* functions related to server name resolution */ diff --git a/src/proxy.c b/src/proxy.c index 87999ad5d..5d701866b 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -130,7 +130,7 @@ static void free_stick_rules(struct list *rules) void free_proxy(struct proxy *p) { - struct server *s,*s_next; + struct server *s; struct cap_hdr *h,*h_next; struct listener *l,*l_next; struct bind_conf *bind_conf, *bind_back; @@ -289,11 +289,9 @@ void free_proxy(struct proxy *p) s = p->srv; while (s) { - s_next = s->next; list_for_each_entry(srvdf, &server_deinit_list, list) srvdf->fct(s); - free_server(s); - s = s_next; + s = free_server(s); }/* end while(s) */ list_for_each_entry_safe(l, l_next, &p->conf.listeners, by_fe) { diff --git a/src/server.c b/src/server.c index 7cec4ce47..583cce7f5 100644 --- a/src/server.c +++ b/src/server.c @@ -2213,11 +2213,18 @@ static uint srv_release_dynsrv(struct server *srv) /* Deallocate a server and its member. must be allocated. For * dynamic servers, its refcount is decremented first. The free operations are * conducted only if the refcount is nul, unless the process is stopping. + * + * As a convenience, is returned if srv is not NULL. It may be useful + * when calling free_server on the list of servers. */ -void free_server(struct server *srv) +struct server *free_server(struct server *srv) { + struct server *next = NULL; + if (!srv) - return; + goto end; + + next = srv->next; /* For dynamic servers, decrement the reference counter. Only free the * server when reaching zero. @@ -2225,7 +2232,7 @@ void free_server(struct server *srv) if (likely(!(global.mode & MODE_STOPPING))) { if (srv->flags & SRV_F_DYNAMIC) { if (srv_release_dynsrv(srv)) - return; + goto end; } } @@ -2255,6 +2262,9 @@ void free_server(struct server *srv) free(srv); srv = NULL; + + end: + return next; } /* Remove a server from a tracking list if is tracking another