]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: stconn: Use one function to shut connection and applet endpoints
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 16 Apr 2024 16:36:40 +0000 (18:36 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 19 Apr 2024 14:33:35 +0000 (16:33 +0200)
se_shutdown() function is now used to perform a shutdown on a connection
endpoint and an applet endpoint. The same function is used for
both. sc_conn_shut() function was removed and appctx_shut() function was
updated to only deal with the applet stuff.

include/haproxy/applet.h
include/haproxy/stconn.h
src/applet.c
src/check.c
src/stconn.c

index 7c8513380c101d1a29bfd3a5c0ff78edb5dcf1c3..7f71083ee11bda8adabafc35cc916a422d612959 100644 (file)
@@ -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, enum se_shut_mode mode);
+void appctx_shut(struct appctx *appctx);
 
 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);
index e2409011c6792ba60c34bb638eb48d8d68467e9c..14ccd75a2d597f80e359d19148515b535ad9dba8 100644 (file)
@@ -39,6 +39,8 @@ struct check;
 struct sedesc *sedesc_new();
 void sedesc_free(struct sedesc *sedesc);
 
+void se_shutdown(struct sedesc *sedesc, enum se_shut_mode mode);
+
 struct stconn *sc_new_from_endp(struct sedesc *sedesc, struct session *sess, struct buffer *input);
 struct stconn *sc_new_from_strm(struct stream *strm, unsigned int flags);
 struct stconn *sc_new_from_check(struct check *check, unsigned int flags);
@@ -318,27 +320,6 @@ static inline const char *sc_get_data_name(const struct stconn *sc)
        return sc->app_ops->name;
 }
 
-static inline void sc_conn_shut(struct stconn *sc, enum se_shut_mode mode)
-{
-       const struct mux_ops *mux;
-
-       BUG_ON(!sc_conn(sc));
-
-       mux = sc_mux_ops(sc);
-
-       if ((mode & (SE_SHW_SILENT|SE_SHW_NORMAL)) && !sc_ep_test(sc, SE_FL_SHW)) {
-               if (mux && mux->shutw)
-                       mux->shutw(sc, mode);
-               sc_ep_set(sc, (mode & SE_SHW_NORMAL) ? SE_FL_SHWN : SE_FL_SHWS);
-       }
-
-       if ((mode & (SE_SHR_RESET|SE_SHR_DRAIN)) && !sc_ep_test(sc, SE_FL_SHR)) {
-               if (mux && mux->shutr)
-                       mux->shutr(sc, mode);
-               sc_ep_set(sc, (mode & SE_SHR_DRAIN) ? SE_FL_SHRD : SE_FL_SHRR);
-       }
-}
-
 /* Returns non-zero if the stream connector's Rx path is blocked because of
  * lack of room in the input buffer. This usually happens after applets failed
  * to deliver data into the channel's buffer and reported it via sc_need_room().
index a6d677cec2dd25d111e49dae72273b1dd3241642..b21979a5253cb60c169aebe458d939fcb0b662dd 100644 (file)
@@ -394,26 +394,19 @@ void applet_reset_svcctx(struct appctx *appctx)
 /* 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, enum se_shut_mode mode)
+void appctx_shut(struct appctx *appctx)
 {
        if (applet_fl_test(appctx, APPCTX_FL_SHUTDOWN))
                return;
 
        TRACE_ENTER(APPLET_EV_RELEASE, appctx);
-       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 ((mode & (SE_SHR_RESET|SE_SHR_DRAIN)) && !se_fl_test(appctx->sedesc, SE_FL_SHR))
-               se_fl_set(appctx->sedesc, SE_FL_SHRR);
+       if (appctx->applet->release)
+               appctx->applet->release(appctx);
+       applet_fl_set(appctx, APPCTX_FL_SHUTDOWN);
 
-       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);
-       }
+       if (LIST_INLIST(&appctx->buffer_wait.list))
+               LIST_DEL_INIT(&appctx->buffer_wait.list);
 
        TRACE_LEAVE(APPLET_EV_RELEASE, appctx);
 }
index 6a37ad887147f2771616d6d79b21229ad6360d21..ff6977cf094d82b7ab89f94bef8c26f52c07a21c 100644 (file)
@@ -1382,7 +1382,7 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state)
                 * as a failed response coupled with "observe layer7" caused the
                 * server state to be suddenly changed.
                 */
-               sc_conn_shut(sc, SE_SHR_DRAIN|SE_SHW_SILENT);
+               se_shutdown(sc->sedesc, SE_SHR_DRAIN|SE_SHW_SILENT);
        }
 
        if (sc) {
index 669601c47243b518eeb9b72f20176acd6f8c5bcf..ca878436ae2bd4cdd8f11ed79521c2fb22f87856 100644 (file)
@@ -131,6 +131,40 @@ void sedesc_free(struct sedesc *sedesc)
        }
 }
 
+/* Performs a shutdown on the endpoint. This function deals with connection and
+ * applet endpoints. It is responsible to set SE flags corresponding to the
+ * given shut modes and to call right shutdown functions of the endpoint. It is
+ * called from the .abort and .shut app_ops callback functions at the SC level.
+ */
+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);
+
+               if ((mode & (SE_SHW_SILENT|SE_SHW_NORMAL)) && !se_fl_test(sedesc, SE_FL_SHW)) {
+                       if (mux && mux->shutw)
+                               mux->shutw(sedesc->sc, mode);
+                       se_fl_set(sedesc, (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 (mux && mux->shutr)
+                               mux->shutr(sedesc->sc, mode);
+                       se_fl_set(sedesc, (mode & SE_SHR_DRAIN) ? SE_FL_SHRD : SE_FL_SHRR);
+               }
+       }
+       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);
+
+               if ((mode & (SE_SHR_RESET|SE_SHR_DRAIN)) && !se_fl_test(sedesc, SE_FL_SHR))
+                       se_fl_set(sedesc, SE_FL_SHRR);
+
+               if (se_fl_test(sedesc, SE_FL_SHR) && se_fl_test(sedesc, SE_FL_SHW))
+                       appctx_shut(sedesc->se);
+       }
+}
+
 /* Tries to allocate a new stconn and initialize its main fields. On
  * failure, nothing is allocated and NULL is returned. It is an internal
  * function. The caller must, at least, set the SE_FL_ORPHAN or SE_FL_DETACHED
@@ -405,7 +439,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, SE_SHR_RESET|SE_SHW_NORMAL);
+               se_shutdown(appctx->sedesc, SE_SHR_RESET|SE_SHW_NORMAL);
                appctx_free(appctx);
        }
 
@@ -700,7 +734,7 @@ static void sc_app_abort_conn(struct stconn *sc)
                return;
 
        if (sc->flags & SC_FL_SHUT_DONE) {
-               sc_conn_shut(sc, SE_SHR_RESET|SE_SHW_SILENT);
+               se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_SILENT);
                sc->state = SC_ST_DIS;
                if (sc->flags & SC_FL_ISBACK)
                        __sc_strm(sc)->conn_exp = TICK_ETERNITY;
@@ -742,11 +776,11 @@ static void sc_app_shut_conn(struct stconn *sc)
                 * no risk so we close both sides immediately.
                 */
                if (!(sc->flags & (SC_FL_NOLINGER|SC_FL_EOS|SC_FL_ABRT_DONE)) && !(ic->flags & CF_DONT_READ)) {
-                       sc_conn_shut(sc, SE_SHW_NORMAL);
+                       se_shutdown(sc->sedesc, SE_SHW_NORMAL);
                        return;
                }
 
-               sc_conn_shut(sc, SE_SHR_RESET|((sc->flags & SC_FL_NOLINGER) ? SE_SHW_SILENT : SE_SHW_NORMAL));
+               se_shutdown(sc->sedesc, SE_SHR_RESET|((sc->flags & SC_FL_NOLINGER) ? SE_SHW_SILENT : SE_SHW_NORMAL));
                sc->state = SC_ST_DIS;
                break;
 
@@ -754,7 +788,7 @@ static void sc_app_shut_conn(struct stconn *sc)
                /* we may have to close a pending connection, and mark the
                 * response buffer as abort
                 */
-               sc_conn_shut(sc, SE_SHR_RESET|SE_SHW_SILENT);
+               se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_SILENT);
                sc->state = SC_ST_DIS;
                break;
        case SC_ST_CER:
@@ -884,7 +918,7 @@ static void sc_app_abort_applet(struct stconn *sc)
                return;
 
        if (sc->flags & SC_FL_SHUT_DONE) {
-               appctx_shut(__sc_appctx(sc), SE_SHR_RESET|SE_SHW_NORMAL);
+               se_shutdown(sc->sedesc, 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 +963,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_shut(__sc_appctx(sc), SE_SHW_NORMAL);
+                       se_shutdown(sc->sedesc, SE_SHW_NORMAL);
                        return;
                }
 
-               appctx_shut(__sc_appctx(sc), SE_SHR_RESET|SE_SHW_NORMAL);
+               se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_NORMAL);
                sc->state = SC_ST_DIS;
                break;
 
@@ -942,7 +976,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), SE_SHR_RESET|SE_SHW_NORMAL);
+               se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_NORMAL);
                sc->state = SC_ST_DIS;
                break;
        default:
@@ -1202,7 +1236,7 @@ static void sc_conn_eos(struct stconn *sc)
 
  do_close:
        /* OK we completely close the socket here just as if we went through sc_shut[rw]() */
-       sc_conn_shut(sc, SE_SHR_RESET|SE_SHW_SILENT);
+       se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_SILENT);
 
        sc->flags &= ~SC_FL_SHUT_WANTED;
        sc->flags |= SC_FL_SHUT_DONE;
@@ -1866,7 +1900,7 @@ static void sc_applet_eos(struct stconn *sc)
                return;
 
        if (sc->flags & SC_FL_SHUT_DONE) {
-               appctx_shut(__sc_appctx(sc), SE_SHR_RESET|SE_SHW_NORMAL);
+               se_shutdown(sc->sedesc, SE_SHR_RESET|SE_SHW_NORMAL);
                sc->state = SC_ST_DIS;
                if (sc->flags & SC_FL_ISBACK)
                        __sc_strm(sc)->conn_exp = TICK_ETERNITY;