mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-01-29 14:01:50 +01:00
BUG/MAJOR: applet: Don't call I/O handler if the applet was shut
In 3.0, it was stated an applet could not be woken up after it was shutdown. So the corresponding test in the applets I/O handler was removed. However, it seems it may happen, especially when outgoing data are blocked on the opposite side. But it is really unexpected because the "release" callback function was already called and the appctx context was most probably released. Strangely, it was never detected by any applet till now. But the Prometheus exporter was never updated and was still testing the shutdown. But when it was refactored to use the new applet API in 3.3, the test was removed. And this introduced a regression leading a crash because a server object could be corrupted. Conditions to hit the bug are not really clear however. So, now, to avoid any issue with all other applets, the test is performed in task_process_applet(). The I/O handler is no longer called if the applet is already shut. The same is performed for applets still relying on the old API. An amazing thanks to @idl0r for his invaluable help on this issue ! This patch should fix the issue #3244. It should first be backported to 3.3 and then slowly as far as 3.0.
This commit is contained in:
parent
0ebef67132
commit
0ea601127e
13
src/applet.c
13
src/applet.c
@ -848,7 +848,12 @@ struct task *task_run_applet(struct task *t, void *context, unsigned int state)
|
||||
|
||||
input = applet_output_data(app);
|
||||
output = co_data(oc);
|
||||
app->applet->fct(app);
|
||||
|
||||
/* Don't call I/O handler if the applet was shut (release callback was
|
||||
* already called)
|
||||
*/
|
||||
if (se_fl_test(app->sedesc, SE_FL_SHR | SE_FL_SHW))
|
||||
app->applet->fct(app);
|
||||
|
||||
TRACE_POINT(APPLET_EV_PROCESS, app);
|
||||
|
||||
@ -945,7 +950,11 @@ struct task *task_process_applet(struct task *t, void *context, unsigned int sta
|
||||
applet_need_more_data(app);
|
||||
applet_have_no_more_data(app);
|
||||
|
||||
app->applet->fct(app);
|
||||
/* Don't call I/O handler if the applet was shut (release callback was
|
||||
* already called)
|
||||
*/
|
||||
if (!applet_fl_test(app, APPCTX_FL_SHUTDOWN))
|
||||
app->applet->fct(app);
|
||||
|
||||
TRACE_POINT(APPLET_EV_PROCESS, app);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user