mirror of
https://github.com/haproxy/haproxy.git
synced 2026-02-14 00:04:00 -05:00
MINOR: filters: rework filter iteration for channel related callback functions
Multiple channel related functions have the same construction: they use
list_for_each_entry() to work on a given filter from the stream+channel
combination. In future commits we will try to use filter list from
dedicated channel list instead of the stream one, thus in this patch we
need as a prerequisite to implement and use the flt_list_{start,next} API
to iterate over filter list, giving the API the responsibility to iterate
over the correct list depending on the context, while the calling function
remains free to use the iteration construction it needs. This way we will
be able to easily change the way we iterate over filter list without
duplicating the code for requests and responses.
This commit is contained in:
parent
e88b219331
commit
bb6cfbe754
2 changed files with 59 additions and 16 deletions
|
|
@ -165,6 +165,44 @@ unregister_data_filter(struct stream *s, struct channel *chn, struct filter *fil
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* flt_list_start() and flt_list_next() can be used to iterate over the list of filters
|
||||
* for a given <strm> and <chn> combination. It will automatically choose the proper
|
||||
* list to iterate from depending on the context.
|
||||
*
|
||||
* flt_list_start() has to be called exactly once to get the first value from the list
|
||||
* to get the following values, use flt_list_next() until NULL is returned.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* struct filter *filter;
|
||||
*
|
||||
* for (filter = flt_list_start(stream, channel); filter;
|
||||
* filter = flt_list_next(stream, channel, filter)) {
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
static inline struct filter *flt_list_start(struct stream *strm, struct channel *chn)
|
||||
{
|
||||
struct filter *filter;
|
||||
|
||||
filter = LIST_NEXT(&strm_flt(strm)->filters, struct filter *, list);
|
||||
if (&filter->list == &strm_flt(strm)->filters)
|
||||
filter = NULL; /* empty list */
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
static inline struct filter *flt_list_next(struct stream *strm, struct channel *chn,
|
||||
struct filter *filter)
|
||||
{
|
||||
filter = LIST_NEXT(&filter->list, struct filter *, list);
|
||||
if (&filter->list == &strm_flt(strm)->filters)
|
||||
filter = NULL; /* end of list */
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
/* This function must be called when a filter alter payload data. It updates
|
||||
* offsets of all previous filters. Do not call this function when a filter
|
||||
* change the size of payload data leads to an undefined behavior.
|
||||
|
|
@ -177,7 +215,8 @@ flt_update_offsets(struct filter *filter, struct channel *chn, int len)
|
|||
struct stream *s = chn_strm(chn);
|
||||
struct filter *f;
|
||||
|
||||
list_for_each_entry(f, &strm_flt(s)->filters, list) {
|
||||
for (f = flt_list_start(s, chn); f;
|
||||
f = flt_list_next(s, chn, f)) {
|
||||
if (f == filter)
|
||||
break;
|
||||
FLT_OFF(f, chn) += len;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,11 @@ DECLARE_STATIC_TYPED_POOL(pool_head_filter, "filter", struct filter);
|
|||
|
||||
static int handle_analyzer_result(struct stream *s, struct channel *chn, unsigned int an_bit, int ret);
|
||||
|
||||
/* - resume_filter_list_start() and resume_filter_list_next() must always be used together.
|
||||
/*
|
||||
* The API below is similar to flt_list_start() and flt_list_next() except that it can be
|
||||
* interrupted and resumed!
|
||||
*
|
||||
* - resume_filter_list_start() and resume_filter_list_next() must always be used together.
|
||||
* The first one sets the first filter value and the second one allows to get the
|
||||
* next one until NULL is returned
|
||||
*
|
||||
|
|
@ -72,11 +76,8 @@ static inline struct filter *resume_filter_list_start(struct stream *strm, struc
|
|||
(strm)->waiting_entity.ptr = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
filter = LIST_NEXT(&strm_flt(strm)->filters, struct filter *, list);
|
||||
if (&filter->list == &strm_flt(strm)->filters)
|
||||
filter = NULL; /* empty list */
|
||||
}
|
||||
else
|
||||
filter = flt_list_start(strm, chn);
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
|
@ -84,10 +85,8 @@ static inline struct filter *resume_filter_list_start(struct stream *strm, struc
|
|||
static inline struct filter *resume_filter_list_next(struct stream *strm, struct channel *chn,
|
||||
struct filter *filter)
|
||||
{
|
||||
filter = LIST_NEXT(&filter->list, struct filter *, list);
|
||||
if (&filter->list == &strm_flt(strm)->filters)
|
||||
filter = NULL; /* end of list */
|
||||
return filter;
|
||||
/* simply an alias to flt_list_next() */
|
||||
return flt_list_next(strm, chn, filter);
|
||||
}
|
||||
|
||||
static inline void resume_filter_list_break(struct stream *strm, struct channel *chn,
|
||||
|
|
@ -659,7 +658,8 @@ flt_http_reset(struct stream *s, struct http_msg *msg)
|
|||
struct filter *filter;
|
||||
|
||||
DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, s->txn, msg);
|
||||
list_for_each_entry(filter, &strm_flt(s)->filters, list) {
|
||||
for (filter = flt_list_start(s, msg->chn); filter;
|
||||
filter = flt_list_next(s, msg->chn, filter)) {
|
||||
if (FLT_OPS(filter)->http_reset) {
|
||||
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s);
|
||||
filter->calls++;
|
||||
|
|
@ -710,7 +710,8 @@ flt_http_payload(struct stream *s, struct http_msg *msg, unsigned int len)
|
|||
|
||||
ret = data = len - out;
|
||||
DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_HTTP_ANA|STRM_EV_FLT_ANA, s, s->txn, msg);
|
||||
list_for_each_entry(filter, &strm_flt(s)->filters, list) {
|
||||
for (filter = flt_list_start(s, msg->chn); filter;
|
||||
filter = flt_list_next(s, msg->chn, filter)) {
|
||||
unsigned long long *flt_off = &FLT_OFF(filter, msg->chn);
|
||||
unsigned int offset = *flt_off - *strm_off;
|
||||
|
||||
|
|
@ -866,7 +867,8 @@ flt_post_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
|
|||
|
||||
DBG_TRACE_ENTER(STRM_EV_STRM_ANA|STRM_EV_FLT_ANA, s);
|
||||
|
||||
list_for_each_entry(filter, &strm_flt(s)->filters, list) {
|
||||
for (filter = flt_list_start(s, chn); filter;
|
||||
filter = flt_list_next(s, chn, filter)) {
|
||||
if (FLT_OPS(filter)->channel_post_analyze && (filter->post_analyzers & an_bit)) {
|
||||
DBG_TRACE_DEVEL(FLT_ID(filter), STRM_EV_FLT_ANA, s);
|
||||
filter->calls++;
|
||||
|
|
@ -916,7 +918,8 @@ flt_analyze_http_headers(struct stream *s, struct channel *chn, unsigned int an_
|
|||
size_t data = http_get_hdrs_size(htxbuf(&chn->buf));
|
||||
struct filter *f;
|
||||
|
||||
list_for_each_entry(f, &strm_flt(s)->filters, list)
|
||||
for (f = flt_list_start(s, chn); f;
|
||||
f = flt_list_next(s, chn, f))
|
||||
FLT_OFF(f, chn) = data;
|
||||
}
|
||||
|
||||
|
|
@ -1019,7 +1022,8 @@ flt_tcp_payload(struct stream *s, struct channel *chn, unsigned int len)
|
|||
|
||||
ret = data = len - out;
|
||||
DBG_TRACE_ENTER(STRM_EV_TCP_ANA|STRM_EV_FLT_ANA, s);
|
||||
list_for_each_entry(filter, &strm_flt(s)->filters, list) {
|
||||
for (filter = flt_list_start(s, chn); filter;
|
||||
filter = flt_list_next(s, chn, filter)) {
|
||||
unsigned long long *flt_off = &FLT_OFF(filter, chn);
|
||||
unsigned int offset = *flt_off - *strm_off;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue