struct proxy;
struct stconn;
struct sedesc;
+struct se_abort_info;
struct session;
/* Applet descriptor */
size_t (*rcv_buf)(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags); /* called from the upper layer to get data */
size_t (*snd_buf)(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags); /* Called from the upper layet to put data */
size_t (*fastfwd)(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags); /* Callback to fast-forward data */
+ void (*shut)(struct appctx *appctx, unsigned int mode, struct se_abort_info *reason); /* shutdown function */
void (*release)(struct appctx *); /* callback to release resources, may be NULL */
unsigned int timeout; /* execution timeout. */
};
*/
void se_shutdown(struct sedesc *sedesc, enum se_shut_mode mode)
{
- if (se_fl_test(sedesc, SE_FL_T_MUX)) {
- const struct mux_ops *mux = (sedesc->conn ? sedesc->conn->mux : NULL);
- unsigned int flags = 0;
-
- if ((mode & (SE_SHW_SILENT|SE_SHW_NORMAL)) && !se_fl_test(sedesc, SE_FL_SHW))
- flags |= (mode & SE_SHW_NORMAL) ? SE_FL_SHWN : SE_FL_SHWS;
+ unsigned int flags = 0;
+ if ((mode & (SE_SHW_SILENT|SE_SHW_NORMAL)) && !se_fl_test(sedesc, SE_FL_SHW))
+ flags |= (mode & SE_SHW_NORMAL) ? SE_FL_SHWN : SE_FL_SHWS;
+ if ((mode & (SE_SHR_RESET|SE_SHR_DRAIN)) && !se_fl_test(sedesc, SE_FL_SHR))
+ flags |= (mode & SE_SHR_DRAIN) ? SE_FL_SHRD : SE_FL_SHRR;
- if ((mode & (SE_SHR_RESET|SE_SHR_DRAIN)) && !se_fl_test(sedesc, SE_FL_SHR))
- flags |= (mode & SE_SHR_DRAIN) ? SE_FL_SHRD : SE_FL_SHRR;
+ if (se_fl_test(sedesc, SE_FL_T_MUX)) {
+ const struct mux_ops *mux = (sedesc->conn ? sedesc->conn->mux : NULL);
if (flags) {
if (mux && mux->shut) {
}
mux->shut(sedesc->sc, mode, reason);
-
}
se_fl_set(sedesc, flags);
}
}
else if (se_fl_test(sedesc, SE_FL_T_APPLET)) {
- if ((mode & (SE_SHW_SILENT|SE_SHW_NORMAL)) && !se_fl_test(sedesc, SE_FL_SHW))
- se_fl_set(sedesc, SE_FL_SHWN);
+ struct appctx *appctx = sedesc->se;
+
+ if (flags) {
+ if (appctx->applet->shut) {
+ struct se_abort_info *reason = NULL;
+ struct xref *peer = xref_get_peer_and_lock(&sedesc->xref);
- if ((mode & (SE_SHR_RESET|SE_SHR_DRAIN)) && !se_fl_test(sedesc, SE_FL_SHR))
- se_fl_set(sedesc, SE_FL_SHRR);
+ if (peer) {
+ struct sedesc *sdo = container_of(peer, struct sedesc, xref);
+
+ reason = &sdo->abort_info;
+ xref_unlock(&sedesc->xref, peer);
+ }
+
+ appctx->applet->shut(appctx, mode, reason);
+ }
+ se_fl_set(sedesc, flags);
+ }
if (se_fl_test(sedesc, SE_FL_SHR) && se_fl_test(sedesc, SE_FL_SHW))
- appctx_shut(sedesc->se);
+ appctx_shut(appctx);
}
}