Hi,

On Mon, Aug 27, 2018 at 03:26:50PM +0200, Frederic Lecaille wrote:
[...]
> 
> According to Pieter traces, haproxy has registered HTTP service mode lua
> applets in HTTP mode. Your patch fixes a TCP service mode issue.
> reg-test/lua/b00001.vtc script runs both HTTP and TCP lua applets. But this
> is the TCP mode one which makes sometimes fail this script.
> 
> > > > It seems one thread is stuck in lua_gc() while holding the global LUA 
> > > > lock,
> > > > but I don't know enough about LUA to guess what is going on.
> > > 
> > > What is suspect is that the HTTP and TCP applet functions
> > > hlua_applet_(http|tcp)_fct() are called several times even when the applet
> > > is done, or when the streams are disconnected or closed:
> > > 
> > >   /* If the stream is disconnect or closed, ldo nothing. */
> > >      if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO))
> > >          return;
> > > 
> > > this leads to call hlua_ctx_resume() several times from the same thread I
> > > guess.
> > > 
> > 
> > But if hlua_applet_(http|tcp)_fct() just returns, who calls
> > hlua_ctx_resume() ? :)
> 
> hlua_applet_(http|tcp)_fct() functions. If your run the script previously
> mentioned, when it fails this is because hlua_applet_*tcp*_fct() is
> infinitely called.
> 
> 

Ok you're right, I have a patch for that problem, which should definitively
be different from Pieter's problem :)
Willy, I think it's safe to be applied, and should probably be backported
(albeit it should be adapted, given the API differences with buffers/channels)
to 1.8 and 1.7, I've been able to reproduce the problem on both.

Regards,

Olivier
>From bf62441f9d0b305e16a74dbe3341ee7933c04761 Mon Sep 17 00:00:00 2001
From: Olivier Houchard <ohouch...@haproxy.com>
Date: Tue, 28 Aug 2018 14:41:31 +0200
Subject: [PATCH] BUG/MEDIUM: hlua: Make sure we drain the output buffer when
 done.

In hlua_applet_tcp_fct(), drain the output buffer when the applet is done
running, every time we're called.
Overwise, there's a race condition, and the output buffer could be filled
after the applet ran, and as it is never cleared, the stream interface
will never be destroyed.

This should be backported to 1.8 and 1.7.
---
 src/hlua.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/hlua.c b/src/hlua.c
index edb4f68c..7bbc854d 100644
--- a/src/hlua.c
+++ b/src/hlua.c
@@ -6446,8 +6446,11 @@ static void hlua_applet_tcp_fct(struct appctx *ctx)
        struct hlua *hlua = ctx->ctx.hlua_apptcp.hlua;
 
        /* The applet execution is already done. */
-       if (ctx->ctx.hlua_apptcp.flags & APPLET_DONE)
+       if (ctx->ctx.hlua_apptcp.flags & APPLET_DONE) {
+               /* eat the whole request */
+               co_skip(si_oc(si), co_data(si_oc(si)));
                return;
+       }
 
        /* If the stream is disconnect or closed, ldo nothing. */
        if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO))
-- 
2.14.3

Reply via email to