diff --git a/include/haproxy/applet.h b/include/haproxy/applet.h index 8d9f49aec..7c8513380 100644 --- a/include/haproxy/applet.h +++ b/include/haproxy/applet.h @@ -42,7 +42,7 @@ struct task *task_process_applet(struct task *t, void *context, unsigned int sta int appctx_buf_available(void *arg); void *applet_reserve_svcctx(struct appctx *appctx, size_t size); void applet_reset_svcctx(struct appctx *appctx); -void appctx_shut(struct appctx *appctx); +void appctx_shut(struct appctx *appctx, enum se_shut_mode mode); struct appctx *appctx_new_on(struct applet *applet, struct sedesc *sedesc, int thr); int appctx_finalize_startup(struct appctx *appctx, struct proxy *px, struct buffer *input); @@ -133,14 +133,6 @@ static inline void __appctx_free(struct appctx *appctx) _HA_ATOMIC_DEC(&nb_applets); } -static inline void appctx_shutw(struct appctx *appctx) -{ - if (se_fl_test(appctx->sedesc, SE_FL_SHW)) - return; - - se_fl_set(appctx->sedesc, SE_FL_SHWN); -} - /* wakes up an applet when conditions have changed. We're using a macro here in * order to retrieve the caller's place. */ diff --git a/src/applet.c b/src/applet.c index d1526ef89..a6d677cec 100644 --- a/src/applet.c +++ b/src/applet.c @@ -391,23 +391,30 @@ void applet_reset_svcctx(struct appctx *appctx) appctx->svcctx = NULL; } -/* call the applet's release() function if any, and marks the sedesc as shut. - * Needs to be called upon close(). +/* call the applet's release() function if any, and marks the sedesc as shut + * once both read and write side are shut. Needs to be called upon close(). */ -void appctx_shut(struct appctx *appctx) +void appctx_shut(struct appctx *appctx, enum se_shut_mode mode) { if (applet_fl_test(appctx, APPCTX_FL_SHUTDOWN)) return; TRACE_ENTER(APPLET_EV_RELEASE, appctx); - if (appctx->applet->release) - appctx->applet->release(appctx); - applet_fl_set(appctx, APPCTX_FL_SHUTDOWN); + if ((mode & (SE_SHW_SILENT|SE_SHW_NORMAL)) && !se_fl_test(appctx->sedesc, SE_FL_SHW)) + se_fl_set(appctx->sedesc, SE_FL_SHWN); - if (LIST_INLIST(&appctx->buffer_wait.list)) - LIST_DEL_INIT(&appctx->buffer_wait.list); + if ((mode & (SE_SHR_RESET|SE_SHR_DRAIN)) && !se_fl_test(appctx->sedesc, SE_FL_SHR)) + se_fl_set(appctx->sedesc, SE_FL_SHRR); + + if (se_fl_test(appctx->sedesc, SE_FL_SHR) && se_fl_test(appctx->sedesc, SE_FL_SHW)) { + if (appctx->applet->release) + appctx->applet->release(appctx); + applet_fl_set(appctx, APPCTX_FL_SHUTDOWN); + + if (LIST_INLIST(&appctx->buffer_wait.list)) + LIST_DEL_INIT(&appctx->buffer_wait.list); + } - se_fl_set(appctx->sedesc, SE_FL_SHRR | SE_FL_SHWN); TRACE_LEAVE(APPLET_EV_RELEASE, appctx); } diff --git a/src/stconn.c b/src/stconn.c index 7eea66fb5..669601c47 100644 --- a/src/stconn.c +++ b/src/stconn.c @@ -405,7 +405,7 @@ static void sc_detach_endp(struct stconn **scp) sc_ep_set(sc, SE_FL_ORPHAN); sc->sedesc->sc = NULL; sc->sedesc = NULL; - appctx_shut(appctx); + appctx_shut(appctx, SE_SHR_RESET|SE_SHW_NORMAL); appctx_free(appctx); } @@ -884,7 +884,7 @@ static void sc_app_abort_applet(struct stconn *sc) return; if (sc->flags & SC_FL_SHUT_DONE) { - appctx_shut(__sc_appctx(sc)); + appctx_shut(__sc_appctx(sc), SE_SHR_RESET|SE_SHW_NORMAL); sc->state = SC_ST_DIS; if (sc->flags & SC_FL_ISBACK) __sc_strm(sc)->conn_exp = TICK_ETERNITY; @@ -929,11 +929,11 @@ static void sc_app_shut_applet(struct stconn *sc) */ if (!(sc->flags & (SC_FL_ERROR|SC_FL_NOLINGER|SC_FL_EOS|SC_FL_ABRT_DONE)) && !(ic->flags & CF_DONT_READ)) { - appctx_shutw(__sc_appctx(sc)); + appctx_shut(__sc_appctx(sc), SE_SHW_NORMAL); return; } - appctx_shut(__sc_appctx(sc)); + appctx_shut(__sc_appctx(sc), SE_SHR_RESET|SE_SHW_NORMAL); sc->state = SC_ST_DIS; break; @@ -942,7 +942,7 @@ static void sc_app_shut_applet(struct stconn *sc) case SC_ST_QUE: case SC_ST_TAR: /* Note that none of these states may happen with applets */ - appctx_shut(__sc_appctx(sc)); + appctx_shut(__sc_appctx(sc), SE_SHR_RESET|SE_SHW_NORMAL); sc->state = SC_ST_DIS; break; default: @@ -1866,7 +1866,7 @@ static void sc_applet_eos(struct stconn *sc) return; if (sc->flags & SC_FL_SHUT_DONE) { - appctx_shut(__sc_appctx(sc)); + appctx_shut(__sc_appctx(sc), SE_SHR_RESET|SE_SHW_NORMAL); sc->state = SC_ST_DIS; if (sc->flags & SC_FL_ISBACK) __sc_strm(sc)->conn_exp = TICK_ETERNITY;