MINOR: server: implement a refcount for dynamic servers

It is necessary to have a refcount mechanism on dynamic servers to be
able to enable check support. Indeed, when deleting a dynamic server
with check activated, the check will be asynchronously removed. This is
mandatory to properly free the check resources in a thread-safe manner.
The server instance must be kept alive for this.
This commit is contained in:
Amaury Denoyelle 2021-08-02 15:50:00 +02:00
parent 403dce8e5a
commit d6b7080cec
2 changed files with 25 additions and 0 deletions

View File

@ -259,6 +259,8 @@ struct server {
unsigned cumulative_weight; /* weight of servers prior to this one in the same group, for chash balancing */
int maxqueue; /* maximum number of pending connections allowed */
uint refcount_dynsrv; /* refcount used for dynamic servers */
/* The elements below may be changed on every single request by any
* thread, and generally at the same time.
*/

View File

@ -2196,10 +2196,32 @@ struct server *new_server(struct proxy *proxy)
return srv;
}
/* Increment the dynamic server refcount. */
static void srv_use_dynsrv(struct server *srv)
{
BUG_ON(!(srv->flags & SRV_F_DYNAMIC));
HA_ATOMIC_INC(&srv->refcount_dynsrv);
}
/* Decrement the dynamic server refcount. */
static uint srv_release_dynsrv(struct server *srv)
{
BUG_ON(!(srv->flags & SRV_F_DYNAMIC));
return HA_ATOMIC_SUB_FETCH(&srv->refcount_dynsrv, 1);
}
/* Deallocate a server <srv> and its member. <srv> must be allocated.
*/
void free_server(struct server *srv)
{
/* For dynamic servers, decrement the reference counter. Only free the
* server when reaching zero.
*/
if (srv->flags & SRV_F_DYNAMIC) {
if (srv_release_dynsrv(srv))
return;
}
task_destroy(srv->warmup);
task_destroy(srv->srvrq_check);
@ -4590,6 +4612,7 @@ static int cli_parse_add_server(char **args, char *payload, struct appctx *appct
ebis_insert(&be->conf.used_server_name, &srv->conf.name);
ebis_insert(&be->used_server_addr, &srv->addr_node);
srv_use_dynsrv(srv);
thread_release();
ha_notice("New server registered.\n");