mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-12-08 19:21:05 +01:00
MEDIUM: applet: Add a .shut callback function for applets
Applets can now define a shutdown callback function, just like the multiplexer. It is especially usefull to get the abort reason. This will be pretty useful to get the status code from the SPOP stream to report it at the SPOe filter level. The related issue is #2502.
This commit is contained in:
parent
1538c4aa82
commit
33ac3dabcb
@ -55,6 +55,7 @@ struct appctx;
|
|||||||
struct proxy;
|
struct proxy;
|
||||||
struct stconn;
|
struct stconn;
|
||||||
struct sedesc;
|
struct sedesc;
|
||||||
|
struct se_abort_info;
|
||||||
struct session;
|
struct session;
|
||||||
|
|
||||||
/* Applet descriptor */
|
/* Applet descriptor */
|
||||||
@ -68,6 +69,7 @@ struct applet {
|
|||||||
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 (*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 (*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 */
|
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 */
|
void (*release)(struct appctx *); /* callback to release resources, may be NULL */
|
||||||
unsigned int timeout; /* execution timeout. */
|
unsigned int timeout; /* execution timeout. */
|
||||||
};
|
};
|
||||||
|
|||||||
31
src/stconn.c
31
src/stconn.c
@ -141,17 +141,16 @@ void sedesc_free(struct sedesc *sedesc)
|
|||||||
*/
|
*/
|
||||||
void se_shutdown(struct sedesc *sedesc, enum se_shut_mode mode)
|
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;
|
unsigned int flags = 0;
|
||||||
|
|
||||||
if ((mode & (SE_SHW_SILENT|SE_SHW_NORMAL)) && !se_fl_test(sedesc, SE_FL_SHW))
|
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;
|
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))
|
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;
|
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 (flags) {
|
||||||
if (mux && mux->shut) {
|
if (mux && mux->shut) {
|
||||||
struct se_abort_info *reason = NULL;
|
struct se_abort_info *reason = NULL;
|
||||||
@ -165,20 +164,32 @@ void se_shutdown(struct sedesc *sedesc, enum se_shut_mode mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mux->shut(sedesc->sc, mode, reason);
|
mux->shut(sedesc->sc, mode, reason);
|
||||||
|
|
||||||
}
|
}
|
||||||
se_fl_set(sedesc, flags);
|
se_fl_set(sedesc, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (se_fl_test(sedesc, SE_FL_T_APPLET)) {
|
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))
|
struct appctx *appctx = sedesc->se;
|
||||||
se_fl_set(sedesc, SE_FL_SHWN);
|
|
||||||
|
|
||||||
if ((mode & (SE_SHR_RESET|SE_SHR_DRAIN)) && !se_fl_test(sedesc, SE_FL_SHR))
|
if (flags) {
|
||||||
se_fl_set(sedesc, SE_FL_SHRR);
|
if (appctx->applet->shut) {
|
||||||
|
struct se_abort_info *reason = NULL;
|
||||||
|
struct xref *peer = xref_get_peer_and_lock(&sedesc->xref);
|
||||||
|
|
||||||
|
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))
|
if (se_fl_test(sedesc, SE_FL_SHR) && se_fl_test(sedesc, SE_FL_SHW))
|
||||||
appctx_shut(sedesc->se);
|
appctx_shut(appctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user