diff options
author | liuyacan <liuyacan@corp.netease.com> | 2021-06-13 14:54:55 +0800 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2021-06-14 14:35:04 +0000 |
commit | 55c952ed5f56a1a478f03f8458e82530478c4359 (patch) | |
tree | 43198873060cc8b36cda93995a2f4e56810e87ff /src/vcl/vppcom.c | |
parent | 89d939e52c999edec66194c60bc5afb2397a2842 (diff) |
vcl: improve shutdown()
This commit does following:
- Change the behavior of shutdown() with SHUT_RDWR flag.
- Check SHUT_RD flag when read()
- Change the errno when write() after SHUT_WR
- Remove unused code
All the above modification passed the packetdrill test.
Type: improvement
Signed-off-by: liuyacan <liuyacan@corp.netease.com>
Change-Id: I0c81f52e563562e58580d70976526b898e65e915
Diffstat (limited to 'src/vcl/vppcom.c')
-rw-r--r-- | src/vcl/vppcom.c | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 330d590cfa0..d378f404381 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -807,7 +807,7 @@ vcl_session_disconnected_handler (vcl_worker_t * wrk, } int -vppcom_session_shutdown (uint32_t session_handle) +vppcom_session_shutdown (uint32_t session_handle, int how) { vcl_worker_t *wrk = vcl_worker_get_current (); vcl_session_t *session; @@ -830,13 +830,20 @@ vppcom_session_shutdown (uint32_t session_handle) return VPPCOM_EBADFD; } + if (how == SHUT_RD || how == SHUT_RDWR) + { + session->flags |= VCL_SESSION_F_RD_SHUTDOWN; + if (how == SHUT_RD) + return VPPCOM_OK; + } + session->flags |= VCL_SESSION_F_WR_SHUTDOWN; + if (PREDICT_TRUE (state == VCL_STATE_READY)) { VDBG (1, "session %u [0x%llx]: sending shutdown...", session->session_index, vpp_handle); vcl_send_session_shutdown (wrk, session); - session->flags |= VCL_SESSION_F_SHUTDOWN; } return VPPCOM_OK; @@ -1948,6 +1955,18 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n, return vcl_session_closed_error (s); } + if (PREDICT_FALSE (s->flags & VCL_SESSION_F_RD_SHUTDOWN)) + { + /* Vpp would ack the incoming data and enqueue it for reading. + * So even if SHUT_RD is set, we can still read() the data if + * the session is ready. + */ + if (!vcl_session_read_ready (s)) + { + return 0; + } + } + is_nonblocking = vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK); is_ct = vcl_session_is_ct (s); mq = wrk->app_event_queue; @@ -2166,8 +2185,7 @@ vppcom_session_write_inline (vcl_worker_t * wrk, vcl_session_t * s, void *buf, return VPPCOM_EBADFD; } - if (PREDICT_FALSE (!vcl_session_is_open (s) || - (s->flags & VCL_SESSION_F_SHUTDOWN))) + if (PREDICT_FALSE (!vcl_session_is_open (s))) { VDBG (1, "session %u [0x%llx]: is not open! state 0x%x (%s)", s->session_index, s->vpp_handle, s->session_state, @@ -2175,6 +2193,14 @@ vppcom_session_write_inline (vcl_worker_t * wrk, vcl_session_t * s, void *buf, return vcl_session_closed_error (s);; } + if (PREDICT_FALSE (s->flags & VCL_SESSION_F_WR_SHUTDOWN)) + { + VDBG (1, "session %u [0x%llx]: is shutdown! state 0x%x (%s)", + s->session_index, s->vpp_handle, s->session_state, + vppcom_session_state_str (s->session_state)); + return VPPCOM_EPIPE; + } + is_ct = vcl_session_is_ct (s); tx_fifo = is_ct ? s->ct_tx_fifo : s->tx_fifo; is_nonblocking = vcl_session_has_attr (s, VCL_SESS_ATTR_NONBLOCK); @@ -3209,7 +3235,7 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, void *buffer, uint32_t * buflen) { vcl_worker_t *wrk = vcl_worker_get_current (); - u32 *flags = buffer, tmp_flags = 0; + u32 *flags = buffer; vppcom_endpt_t *ep = buffer; transport_endpt_attr_t tea; vcl_session_t *session; @@ -3747,27 +3773,6 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op, *buflen); break; - case VPPCOM_ATTR_SET_SHUT: - if (*flags == SHUT_RD || *flags == SHUT_RDWR) - vcl_session_set_attr (session, VCL_SESS_ATTR_SHUT_RD); - if (*flags == SHUT_WR || *flags == SHUT_RDWR) - vcl_session_set_attr (session, VCL_SESS_ATTR_SHUT_WR); - break; - - case VPPCOM_ATTR_GET_SHUT: - if (vcl_session_has_attr (session, VCL_SESS_ATTR_SHUT_RD)) - tmp_flags = 1; - if (vcl_session_has_attr (session, VCL_SESS_ATTR_SHUT_WR)) - tmp_flags |= 2; - if (tmp_flags == 1) - *(int *) buffer = SHUT_RD; - else if (tmp_flags == 2) - *(int *) buffer = SHUT_WR; - else if (tmp_flags == 3) - *(int *) buffer = SHUT_RDWR; - *buflen = sizeof (int); - break; - case VPPCOM_ATTR_SET_CONNECTED: session->flags |= VCL_SESSION_F_CONNECTED; break; |