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);
_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.
*/
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);
}
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);
}
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;
*/
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;
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:
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;