void vars_init_head(struct vars *vars, enum vars_scope scope);
void var_accounting_diff(struct vars *vars, struct session *sess, struct stream *strm, int size);
-unsigned int var_clear(struct var *var);
+unsigned int var_clear(struct var *var, int force);
void vars_prune(struct vars *vars, struct session *sess, struct stream *strm);
void vars_prune_per_sess(struct vars *vars);
int vars_get_by_name(const char *name, size_t len, struct sample *smp, const struct buffer *def);
return 1;
}
-/* This fnuction remove a variable from the list and free memory it used */
-unsigned int var_clear(struct var *var)
+/* This function removes a variable from the list and frees the memory it was
+ * using. If the variable is marked "VF_PERMANENT", the sample_data is only
+ * reset to SMP_T_ANY unless <force> is non nul. Returns the freed size.
+ */
+unsigned int var_clear(struct var *var, int force)
{
unsigned int size = 0;
ha_free(&var->data.u.meth.str.area);
size += var->data.u.meth.str.data;
}
- LIST_DELETE(&var->l);
- pool_free(var_pool, var);
- size += sizeof(struct var);
+ /* wipe the sample */
+ var->data.type = SMP_T_ANY;
+
+ if (!(var->flags & VF_PERMANENT) || force) {
+ LIST_DELETE(&var->l);
+ pool_free(var_pool, var);
+ size += sizeof(struct var);
+ }
return size;
}
HA_RWLOCK_WRLOCK(VARS_LOCK, &vars->rwlock);
list_for_each_entry_safe(var, tmp, &vars->head, l) {
- size += var_clear(var);
+ size += var_clear(var, 1);
}
HA_RWLOCK_WRUNLOCK(VARS_LOCK, &vars->rwlock);
var_accounting_diff(vars, sess, strm, -size);
HA_RWLOCK_WRLOCK(VARS_LOCK, &vars->rwlock);
list_for_each_entry_safe(var, tmp, &vars->head, l) {
- size += var_clear(var);
+ size += var_clear(var, 1);
}
HA_RWLOCK_WRUNLOCK(VARS_LOCK, &vars->rwlock);
HA_RWLOCK_WRLOCK(VARS_LOCK, &vars->rwlock);
var = var_get(vars, name);
if (var) {
- size = var_clear(var);
+ size = var_clear(var, 0);
var_accounting_diff(vars, smp->sess, smp->strm, -size);
}
HA_RWLOCK_WRUNLOCK(VARS_LOCK, &vars->rwlock);