BUG/MEDIUM: lua/socket: Sheduling error on write: may dead-lock

When we write data, we risk to encounter a dead-loack. The
function "stream_int_notify()" cannot be called the the
cosocket because the caller acquire a lock and when the socket
is closed, the cleanup function try to acquire the same lock.,
so a dead-lock raises.

In other way, the function stream_int_update_applet() can't
be called because it schedumes the applet only if some activity
in the buffers were detected. It is not always the case. We
replace this function by appctx_wakeup() which wake up the
applet inconditionnaly.

The last part of the fix is setting right signals. the applet
call the stream_int_update() function if the output buffer si
not empty, and ask for put data if some rite signals are
registered.

This patch must be backported in 1.6, 1.7 and 1.8. Note that it requires
patch "MINOR: task/notification: Is notifications registered" to be
applied.
This commit is contained in:
Thierry FOURNIER 2018-05-27 01:27:40 +02:00 committed by Willy Tarreau
parent ba42fcd064
commit 101b97619a

View File

@ -1560,6 +1560,18 @@ static void hlua_socket_handler(struct appctx *appctx)
/* Wake the tasks which wants to read if the buffer contains data. */
if (!channel_is_empty(si_oc(si)))
notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read);
/* Some data were injected in the buffer, notify the stream
* interface.
*/
if (!channel_is_empty(si_ic(si)))
stream_int_update(si);
/* If write notifications are registered, we considers we want
* to write, so we set the flag cant put
*/
if (notification_registered(&appctx->ctx.hlua_cosocket.wake_on_write))
si_applet_cant_put(si);
}
/* This function is called when the "struct stream" is destroyed.
@ -1981,8 +1993,7 @@ static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext
}
/* update buffers. */
stream_int_notify(&s->si[0]);
stream_int_update_applet(&s->si[0]);
appctx_wakeup(appctx);
s->req.rex = TICK_ETERNITY;
s->res.wex = TICK_ETERNITY;