mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-18 13:05:38 +00:00
BUG/MEDIUM: filters: Be sure to call flt_end_analyze for both channels
In the commit2b553de5
("BUG/MINOR: filters: Don't force the stream's wakeup when we wait in flt_end_analyze"), we removed a task_wakeup in flt_end_analyze to no consume too much CPU by looping in certain circumstances. But this fix was too drastic. For Keep-Alive transactions, flt_end_analyze is often called only for the response. Then the stream is paused until a timeout is hitted or the next request is received. We need first let a chance to both channels to call flt_end_analyze function. Then if a filter need to wait here, it is its responsibility to wake up the stream when needed. To fix the bug, and thanks to previous commits, we set the flag CF_WAKE_ONCE on channels to pretend there is an activity. On the current channel, the flag will be removed without any effect, but for the other side the analyzer will be called immediatly. Thanks for Lukas Tribus for his detailed analysis of the bug. This patch must be backported in 1.7 with the 2 previous ones: *a94fda3
("BUG/MINOR: http: Don't reset the transaction if there are still data to send") *cdaea89
("BUG/MINOR: stream: Don't forget to remove CF_WAKE_ONCE flag on response channel")
This commit is contained in:
parent
a94fda30bd
commit
570f799877
@ -843,9 +843,21 @@ flt_end_analyze(struct stream *s, struct channel *chn, unsigned int an_bit)
|
||||
/* We don't remove yet this analyzer because we need to synchronize the
|
||||
* both channels. So here, we just remove the flag CF_FLT_ANALYZE. */
|
||||
ret = handle_analyzer_result(s, chn, 0, ret);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
chn->flags &= ~CF_FLT_ANALYZE;
|
||||
|
||||
/* Pretend there is an activity on both channels. Flag on the
|
||||
* current one will be automatically removed, so only the other
|
||||
* one will remain. This is a way to be sure that
|
||||
* 'channel_end_analyze' callback will have a chance to be
|
||||
* called at least once for the other side to finish the current
|
||||
* processing. Of course, this is the filter responsiblity to
|
||||
* wakeup the stream if it choose to loop on this callback. */
|
||||
s->req.flags |= CF_WAKE_ONCE;
|
||||
s->res.flags |= CF_WAKE_ONCE;
|
||||
}
|
||||
|
||||
|
||||
sync:
|
||||
/* Now we can check if filters have finished their work on the both
|
||||
* channels */
|
||||
|
Loading…
Reference in New Issue
Block a user