MINOR: pattern: add pat_ref_commit() to commit a previously inserted element

This function will be used after a successful pat_ref_append() to propagate
the pattern to all use places (including parsing and indexing). On failure,
it will entirely roll back all insertions and free the pattern itself. It
also preserves the generation number so that it is convenient for use in
association with pat_ref_append(). pat_ref_add() was modified to rely on
it instead of open-coding the insertion and roll-back.
This commit is contained in:
Willy Tarreau 2020-10-28 18:45:45 +01:00
parent c93da6950e
commit 0439e5eeb4
2 changed files with 25 additions and 10 deletions

View File

@ -191,6 +191,7 @@ void pat_ref_delete_by_ptr(struct pat_ref *ref, struct pat_ref_elt *elt);
int pat_ref_delete_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt);
int pat_ref_prune(struct pat_ref *ref);
int pat_ref_load(struct pat_ref *ref, struct pattern_expr *expr, int patflags, int soe, char **err);
int pat_ref_commit(struct pat_ref *ref, struct pat_ref_elt *elt, char **err);
void pat_ref_reload(struct pat_ref *ref, struct pat_ref *replace);

View File

@ -1922,6 +1922,29 @@ int pat_ref_push(struct pat_ref_elt *elt, struct pattern_expr *expr,
return 1;
}
/* This function tries to commit entry <elt> into <ref>. The new entry must
* have already been inserted using pat_ref_append(), and its generation number
* may have been adjusted as it will not be changed. <err> must point to a NULL
* pointer. The PATREF lock on <ref> must be held. All the pattern_expr for
* this reference will be updated (parsing, indexing). On success, non-zero is
* returned. On failure, all the operation is rolled back (the element is
* deleted from all expressions and is freed), zero is returned and the error
* pointer <err> may have been updated (and the caller must free it). Failure
* causes include memory allocation, parsing error or indexing error.
*/
int pat_ref_commit(struct pat_ref *ref, struct pat_ref_elt *elt, char **err)
{
struct pattern_expr *expr;
list_for_each_entry(expr, &ref->pat, list) {
if (!pat_ref_push(elt, expr, 0, err)) {
pat_ref_delete_by_ptr(ref, elt);
return 0;
}
}
return 1;
}
/* This function adds entry to <ref>. It can fail on memory error. The new
* entry is added at all the pattern_expr registered in this reference. The
* function stops on the first error encountered. It returns 0 and <err> is
@ -1933,22 +1956,13 @@ int pat_ref_add(struct pat_ref *ref,
char **err)
{
struct pat_ref_elt *elt;
struct pattern_expr *expr;
elt = pat_ref_append(ref, pattern, sample, -1);
if (!elt) {
memprintf(err, "out of memory error");
return 0;
}
list_for_each_entry(expr, &ref->pat, list) {
if (!pat_ref_push(elt, expr, 0, err)) {
/* If the insertion fails, try to delete all the added entries. */
pat_ref_delete_by_ptr(ref, elt);
return 0;
}
}
return 1;
return pat_ref_commit(ref, elt, err);
}
/* This function prunes <ref>, replaces all references by the references