}
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;
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;
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;
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,
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);
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;
*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;