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.
*/
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);
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");