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
This commit is contained in:
@ -2175,8 +2175,7 @@ int
|
||||
shutdown (int fd, int how)
|
||||
{
|
||||
vls_handle_t vlsh;
|
||||
int rv = 0, flags;
|
||||
u32 flags_len = sizeof (flags);
|
||||
int rv = 0;
|
||||
|
||||
ldp_init_check ();
|
||||
|
||||
@ -2184,23 +2183,7 @@ shutdown (int fd, int how)
|
||||
if (vlsh != VLS_INVALID_HANDLE)
|
||||
{
|
||||
LDBG (0, "called shutdown: fd %u vlsh %u how %d", fd, vlsh, how);
|
||||
|
||||
if (vls_attr (vlsh, VPPCOM_ATTR_SET_SHUT, &how, &flags_len))
|
||||
{
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vls_attr (vlsh, VPPCOM_ATTR_GET_SHUT, &flags, &flags_len))
|
||||
{
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags == SHUT_RDWR)
|
||||
rv = close (fd);
|
||||
else if (flags == SHUT_WR)
|
||||
rv = vls_shutdown (vlsh);
|
||||
rv = vls_shutdown (vlsh, how);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1314,7 +1314,7 @@ vls_close (vls_handle_t vlsh)
|
||||
}
|
||||
|
||||
int
|
||||
vls_shutdown (vls_handle_t vlsh)
|
||||
vls_shutdown (vls_handle_t vlsh, int how)
|
||||
{
|
||||
vcl_locked_session_t *vls;
|
||||
int rv;
|
||||
@ -1324,7 +1324,7 @@ vls_shutdown (vls_handle_t vlsh)
|
||||
return VPPCOM_EBADFD;
|
||||
|
||||
vls_mt_guard (vls, VLS_MT_OP_SPOOL);
|
||||
rv = vppcom_session_shutdown (vls_to_sh (vls));
|
||||
rv = vppcom_session_shutdown (vls_to_sh (vls), how);
|
||||
vls_mt_unguard ();
|
||||
vls_get_and_unlock (vlsh);
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
typedef int vls_handle_t;
|
||||
|
||||
vls_handle_t vls_create (uint8_t proto, uint8_t is_nonblocking);
|
||||
int vls_shutdown (vls_handle_t vlsh);
|
||||
int vls_shutdown (vls_handle_t vlsh, int how);
|
||||
int vls_close (vls_handle_t vlsh);
|
||||
int vls_bind (vls_handle_t vlsh, vppcom_endpt_t * ep);
|
||||
int vls_listen (vls_handle_t vlsh, int q_len);
|
||||
|
@ -126,8 +126,6 @@ typedef enum
|
||||
VCL_SESS_ATTR_TCP_NODELAY, // SOL_TCP,TCP_NODELAY
|
||||
VCL_SESS_ATTR_TCP_KEEPIDLE, // SOL_TCP,TCP_KEEPIDLE
|
||||
VCL_SESS_ATTR_TCP_KEEPINTVL, // SOL_TCP,TCP_KEEPINTVL
|
||||
VCL_SESS_ATTR_SHUT_RD,
|
||||
VCL_SESS_ATTR_SHUT_WR,
|
||||
VCL_SESS_ATTR_MAX
|
||||
} vppcom_session_attr_t;
|
||||
|
||||
@ -137,7 +135,8 @@ typedef enum vcl_session_flags_
|
||||
VCL_SESSION_F_IS_VEP = 1 << 1,
|
||||
VCL_SESSION_F_IS_VEP_SESSION = 1 << 2,
|
||||
VCL_SESSION_F_HAS_RX_EVT = 1 << 3,
|
||||
VCL_SESSION_F_SHUTDOWN = 1 << 4,
|
||||
VCL_SESSION_F_RD_SHUTDOWN = 1 << 4,
|
||||
VCL_SESSION_F_WR_SHUTDOWN = 1 << 5,
|
||||
} __clib_packed vcl_session_flags_t;
|
||||
|
||||
typedef struct vcl_session_
|
||||
|
@ -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;
|
||||
|
@ -99,6 +99,7 @@ typedef enum
|
||||
VPPCOM_ETIMEDOUT = -ETIMEDOUT,
|
||||
VPPCOM_EEXIST = -EEXIST,
|
||||
VPPCOM_ENOPROTOOPT = -ENOPROTOOPT,
|
||||
VPPCOM_EPIPE = -EPIPE,
|
||||
VPPCOM_ENOENT = -ENOENT,
|
||||
} vppcom_error_t;
|
||||
|
||||
@ -138,8 +139,6 @@ typedef enum
|
||||
VPPCOM_ATTR_SET_TCP_KEEPINTVL,
|
||||
VPPCOM_ATTR_GET_TCP_USER_MSS,
|
||||
VPPCOM_ATTR_SET_TCP_USER_MSS,
|
||||
VPPCOM_ATTR_SET_SHUT,
|
||||
VPPCOM_ATTR_GET_SHUT,
|
||||
VPPCOM_ATTR_SET_CONNECTED,
|
||||
VPPCOM_ATTR_SET_CKPAIR,
|
||||
VPPCOM_ATTR_SET_VRF,
|
||||
@ -174,7 +173,7 @@ extern int vppcom_app_create (const char *app_name);
|
||||
extern void vppcom_app_destroy (void);
|
||||
|
||||
extern int vppcom_session_create (uint8_t proto, uint8_t is_nonblocking);
|
||||
extern int vppcom_session_shutdown (uint32_t session_handle);
|
||||
extern int vppcom_session_shutdown (uint32_t session_handle, int how);
|
||||
extern int vppcom_session_close (uint32_t session_handle);
|
||||
extern int vppcom_session_bind (uint32_t session_handle, vppcom_endpt_t * ep);
|
||||
extern int vppcom_session_listen (uint32_t session_handle, uint32_t q_len);
|
||||
|
Reference in New Issue
Block a user