]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MAJOR: lua: properly dequeue hlua_applet_wakeup() for new scheduler
authorWilly Tarreau <w@1wt.eu>
Fri, 21 Jul 2017 14:41:56 +0000 (16:41 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 24 Jul 2017 16:14:49 +0000 (18:14 +0200)
The recent scheduler change broke the Lua co-sockets due to
hlua_applet_wakeup() returning NULL after waking the applet up. With the
previous scheduler, returning NULL was a way to do nothing on return.

With the new one it keeps TASK_RUNNING set, causing all new notifications
to end up into t->pending_state instead of t->state, and prevents the
task from being added into the run queue again, so and it's never woken
up anymore.

The applet keeps waking up, causing hlua_socket_handler() to do nothing
new, then si_applet_wake_cb() calling stream_int_notify() to try to wake
the task up, which it can't do due to the TASK_RUNNING flag, then decide
that since the associated task is not in the run queue, it needs to call
stream_int_update_applet() to propagate the update. This last one finds
that the applet needs to be woken up to deal with the last reported events
and calling appctx_wakeup() again. Previously, this situation didn't exist
because the task was always added in the run queue despite the TASK_RUNNING
flag.

By returning the task instead in hlua_applet_wakeup(), we can ensure its
flag is properly cleared and the task is requeued if needed or just sits
waiting for new events to happen.

This fix requires the previous ones ("BUG/MINOR: lua: always detach the
tcp/http tasks before freeing them") and MINOR: task: always preinitialize
the task's timeout in task_init().

Thanks to Thierry, Christopher and Emeric for the long head-scratching
session!

No backport is needed as the bug doesn't appear in older versions and
it's unsure whether we'll not break something by backporting it.

src/hlua.c

index 437f427bb84b693a1bb05c796f7b3d8559d41716..0045a1c5d9456e0c0c8d94ddb76c76bb0f9de4ca 100644 (file)
@@ -5971,7 +5971,7 @@ struct task *hlua_applet_wakeup(struct task *t)
         */
        si_applet_cant_put(si);
        appctx_wakeup(ctx);
-       return NULL;
+       return t;
 }
 
 static int hlua_applet_tcp_init(struct appctx *ctx, struct proxy *px, struct stream *strm)