aboutsummaryrefslogtreecommitdiffstats
path: root/src/vcl/vppcom.c
diff options
context:
space:
mode:
authorliuyacan <liuyacan@corp.netease.com>2021-06-13 14:54:55 +0800
committerFlorin Coras <florin.coras@gmail.com>2021-06-14 14:35:04 +0000
commit55c952ed5f56a1a478f03f8458e82530478c4359 (patch)
tree43198873060cc8b36cda93995a2f4e56810e87ff /src/vcl/vppcom.c
parent89d939e52c999edec66194c60bc5afb2397a2842 (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.c57
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;