From 0439e5eeb45811bec658e55c2c757545c27243b0 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 28 Oct 2020 18:45:45 +0100 Subject: [PATCH] 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. --- include/haproxy/pattern.h | 1 + src/pattern.c | 34 ++++++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/include/haproxy/pattern.h b/include/haproxy/pattern.h index 112d5af48..40db3559a 100644 --- a/include/haproxy/pattern.h +++ b/include/haproxy/pattern.h @@ -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); diff --git a/src/pattern.c b/src/pattern.c index 864dbd798..fe5176922 100644 --- a/src/pattern.c +++ b/src/pattern.c @@ -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 into . 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. must point to a NULL + * pointer. The PATREF lock on 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 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 . 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 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 , replaces all references by the references