1
From a0e753b688853c7ac751bcb183978eba063e68f1 Mon Sep 17 00:00:00 2001
2
From: Thierry FOURNIER <tfournier@exceliance.fr>
3
Date: Mon, 24 Nov 2014 11:14:42 +0100
4
Subject: [PATCH 6/9] BUG/MEDIUM: pattern: don't load more than once a pattern
7
A memory optimization can use the same pattern expression for many
8
equal pattern list (same parse method, index method and index_smp
11
The pattern expression is returned by "pattern_new_expr", but this
12
function dont indicate if the returned pattern is already in use.
14
So, the caller function reload the list of patterns in addition with
15
the existing patterns. This behavior is not a problem with tree indexed
16
pattern, but it grows the lists indexed patterns.
18
This fix add a "reuse" flag in return of the function "pattern_new_expr".
19
If the flag is set, I suppose that the patterns are already loaded.
21
This fix must be backported into 1.5.
22
(cherry picked from commit 315ec4217f912f6cc8fcf98624d852f9cd8399f9)
24
include/proto/pattern.h | 3 ++-
26
src/pattern.c | 22 ++++++++++++++++++++--
27
3 files changed, 23 insertions(+), 4 deletions(-)
29
diff --git a/include/proto/pattern.h b/include/proto/pattern.h
30
index 4a969ac199e4..7855474e5b44 100644
31
--- a/include/proto/pattern.h
32
+++ b/include/proto/pattern.h
33
@@ -206,7 +206,8 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags, con
35
void pattern_init_expr(struct pattern_expr *expr);
36
struct pattern_expr *pattern_lookup_expr(struct pattern_head *head, struct pat_ref *ref);
37
-struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref, char **err);
38
+struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref,
39
+ char **err, int *reuse);
40
struct sample_storage **pattern_find_smp(struct pattern_expr *expr, struct pat_ref_elt *elt);
41
int pattern_delete(struct pattern_expr *expr, struct pat_ref_elt *ref);
43
diff --git a/src/acl.c b/src/acl.c
44
index 8f3fd9eaa746..d8b3000c0c36 100644
47
@@ -532,7 +532,7 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
50
/* Create new pattern expression associated to this reference. */
51
- pattern_expr = pattern_new_expr(&expr->pat, ref, err);
52
+ pattern_expr = pattern_new_expr(&expr->pat, ref, err, NULL);
56
diff --git a/src/pattern.c b/src/pattern.c
57
index c63365d74bf7..20547f9607be 100644
60
@@ -1855,12 +1855,19 @@ struct pattern_expr *pattern_lookup_expr(struct pattern_head *head, struct pat_r
61
* <ref> can be NULL. If an error is occured, the function returns NULL and
62
* <err> is filled. Otherwise, the function returns new pattern_expr linked
63
* with <head> and <ref>.
65
+ * The returned value can be a alredy filled pattern list, in this case the
66
+ * flag <reuse> is set.
68
-struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref, char **err)
69
+struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref,
70
+ char **err, int *reuse)
72
struct pattern_expr *expr;
73
struct pattern_expr_list *list;
78
/* Memory and initialization of the chain element. */
79
list = malloc(sizeof(*list));
81
@@ -1915,6 +1922,8 @@ struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref
82
* with ref and we must not free it.
89
/* The new list element reference the pattern_expr. */
90
@@ -2087,6 +2096,7 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags,
92
struct pattern_expr *expr;
93
struct pat_ref_elt *elt;
96
/* Lookup for the existing reference. */
97
ref = pat_ref_lookup(filename);
98
@@ -2161,12 +2171,20 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags,
100
expr = pattern_lookup_expr(head, ref);
101
if (!expr || (expr->mflags != patflags)) {
102
- expr = pattern_new_expr(head, ref, err);
103
+ expr = pattern_new_expr(head, ref, err, &reuse);
106
expr->mflags = patflags;
109
+ /* The returned expression may be not empty, because the function
110
+ * "pattern_new_expr" lookup for similar pattern list and can
111
+ * reuse a already filled pattern list. In this case, we can not
112
+ * reload the patterns.
117
/* Load reference content in the pattern expression. */
118
list_for_each_entry(elt, &ref->head, list) {
119
if (!pat_ref_push(elt, expr, patflags, err)) {