From 6d0106e44e7dff2c9ef0f7052c4023245e9023a8 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Tue, 29 Jan 2019 20:11:58 -0800 Subject: [PATCH] vcl: improve handling of close on rw Change-Id: Ie01a37612d7e3e0d0bad0f0aa9583b3ed411f46f Signed-off-by: Florin Coras --- src/vcl/vcl_private.h | 28 +++++++++++++++++++ src/vcl/vppcom.c | 75 +++++++++++++++++++-------------------------------- 2 files changed, 55 insertions(+), 48 deletions(-) diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index c61bb0b9247..39c9e7207c7 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -504,6 +504,34 @@ vcl_session_is_ct (vcl_session_t * s) return (s->our_evt_q != 0); } +static inline u8 +vcl_session_is_open (vcl_session_t * s) +{ + return ((s->session_state & STATE_OPEN) + || (s->session_state == STATE_LISTEN + && s->session_type == VPPCOM_PROTO_UDP)); +} + +static inline u8 +vcl_session_is_closing (vcl_session_t * s) +{ + return (s->session_state == STATE_VPP_CLOSING + || s->session_state == STATE_DISCONNECT); +} + +static inline int +vcl_session_closing_error (vcl_session_t * s) +{ + return s->session_state == STATE_DISCONNECT ? VPPCOM_ECONNRESET : 0; +} + +static inline int +vcl_session_closed_error (vcl_session_t * s) +{ + return s->session_state == STATE_DISCONNECT + ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN; +} + /* * Helpers */ diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 570e323bb49..3c3e15d146c 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -661,7 +661,6 @@ vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e) session = vcl_session_disconnected_handler (wrk, disconnected_msg); if (!session) break; - session->session_state = STATE_DISCONNECT; VDBG (0, "disconnected session %u [0x%llx]", session->session_index, session->vpp_handle); break; @@ -1514,20 +1513,12 @@ vcl_is_rx_evt_for_session (session_event_t * e, u32 sid, u8 is_ct) return (e->event_type == SESSION_IO_EVT_CT_TX); } -static inline u8 -vcl_session_is_readable (vcl_session_t * s) -{ - return ((s->session_state & STATE_OPEN) - || (s->session_state == STATE_LISTEN - && s->session_type == VPPCOM_PROTO_UDP)); -} - static inline int vppcom_session_read_internal (uint32_t session_handle, void *buf, int n, u8 peek) { vcl_worker_t *wrk = vcl_worker_get_current (); - int n_read = 0, rv, is_nonblocking; + int n_read = 0, is_nonblocking; vcl_session_t *s = 0; svm_fifo_t *rx_fifo; svm_msg_q_msg_t msg; @@ -1542,15 +1533,12 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n, if (PREDICT_FALSE (!s || s->is_vep)) return VPPCOM_EBADFD; - if (PREDICT_FALSE (!vcl_session_is_readable (s))) + if (PREDICT_FALSE (!vcl_session_is_open (s))) { - session_state_t state = s->session_state; - rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN); - - VDBG (0, "session handle %u[0x%llx] is not open! state 0x%x (%s)," - " returning %d (%s)", session_handle, s->vpp_handle, state, - vppcom_session_state_str (state), rv, vppcom_retval_str (rv)); - return rv; + VDBG (0, "session handle %u[0x%llx] is not open! state 0x%x (%s)", + s->session_index, s->vpp_handle, s->session_state, + vppcom_session_state_str (s->session_state)); + return vcl_session_closed_error (s); } is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK); @@ -1568,6 +1556,9 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n, } while (svm_fifo_is_empty (rx_fifo)) { + if (vcl_session_is_closing (s)) + return vcl_session_closing_error (s); + svm_fifo_unset_event (rx_fifo); svm_msg_q_lock (mq); if (svm_msg_q_is_empty (mq)) @@ -1579,9 +1570,6 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n, if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct)) vcl_handle_mq_event (wrk, e); svm_msg_q_free_msg (mq, &msg); - - if (PREDICT_FALSE (s->session_state == STATE_DISCONNECT)) - return VPPCOM_ECONNRESET; } } @@ -1623,7 +1611,7 @@ vppcom_session_read_segments (uint32_t session_handle, vppcom_data_segments_t ds) { vcl_worker_t *wrk = vcl_worker_get_current (); - int n_read = 0, rv, is_nonblocking; + int n_read = 0, is_nonblocking; vcl_session_t *s = 0; svm_fifo_t *rx_fifo; svm_msg_q_msg_t msg; @@ -1635,12 +1623,8 @@ vppcom_session_read_segments (uint32_t session_handle, if (PREDICT_FALSE (!s || s->is_vep)) return VPPCOM_EBADFD; - if (PREDICT_FALSE (!vcl_session_is_readable (s))) - { - session_state_t state = s->session_state; - rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN); - return rv; - } + if (PREDICT_FALSE (!vcl_session_is_open (s))) + return vcl_session_closed_error (s); is_nonblocking = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK); is_ct = vcl_session_is_ct (s); @@ -1657,6 +1641,9 @@ vppcom_session_read_segments (uint32_t session_handle, } while (svm_fifo_is_empty (rx_fifo)) { + if (vcl_session_is_closing (s)) + return vcl_session_closing_error (s); + svm_fifo_unset_event (rx_fifo); svm_msg_q_lock (mq); if (svm_msg_q_is_empty (mq)) @@ -1668,9 +1655,6 @@ vppcom_session_read_segments (uint32_t session_handle, if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct)) vcl_handle_mq_event (wrk, e); svm_msg_q_free_msg (mq, &msg); - - if (PREDICT_FALSE (s->session_state == STATE_DISCONNECT)) - return VPPCOM_ECONNRESET; } } @@ -1730,7 +1714,7 @@ vppcom_session_write_inline (uint32_t session_handle, void *buf, size_t n, u8 is_flush) { vcl_worker_t *wrk = vcl_worker_get_current (); - int rv, n_write, is_nonblocking; + int n_write, is_nonblocking; vcl_session_t *s = 0; svm_fifo_t *tx_fifo = 0; session_evt_type_t et; @@ -1748,21 +1732,17 @@ vppcom_session_write_inline (uint32_t session_handle, void *buf, size_t n, if (PREDICT_FALSE (s->is_vep)) { - clib_warning ("VCL<%d>: ERROR: vpp handle 0x%llx, sid %u: " - "cannot write to an epoll session!", - getpid (), s->vpp_handle, session_handle); - + VDBG (0, "ERROR: session %u [0x%llx]: cannot write to an epoll" + " session!", s->session_index, s->vpp_handle); return VPPCOM_EBADFD; } - if (PREDICT_FALSE (!(s->session_state & STATE_OPEN))) + if (PREDICT_FALSE (!vcl_session_is_open (s))) { - session_state_t state = s->session_state; - rv = ((state & STATE_DISCONNECT) ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN); - VDBG (1, "VCL<%d>: vpp handle 0x%llx, sid %u: session is not open! " - "state 0x%x (%s)", getpid (), s->vpp_handle, session_handle, - state, vppcom_session_state_str (state)); - return rv; + VDBG (1, "session %u [0x%llx]: is not open! state 0x%x (%s)", + s->session_index, s->vpp_handle, s->session_state, + vppcom_session_state_str (s->session_state)); + return vcl_session_closed_error (s);; } tx_fifo = s->tx_fifo; @@ -1778,6 +1758,8 @@ vppcom_session_write_inline (uint32_t session_handle, void *buf, size_t n, while (svm_fifo_is_full (tx_fifo)) { svm_fifo_add_want_tx_ntf (tx_fifo, SVM_FIFO_WANT_TX_NOTIF); + if (vcl_session_is_closing (s)) + return vcl_session_closing_error (s); svm_msg_q_lock (mq); if (svm_msg_q_is_empty (mq)) svm_msg_q_wait (mq); @@ -1789,9 +1771,6 @@ vppcom_session_write_inline (uint32_t session_handle, void *buf, size_t n, if (!vcl_is_tx_evt_for_session (e, s->session_index, is_ct)) vcl_handle_mq_event (wrk, e); svm_msg_q_free_msg (mq, &msg); - - if (PREDICT_FALSE (!(s->session_state & STATE_OPEN))) - return VPPCOM_ECONNRESET; } } @@ -1809,8 +1788,8 @@ vppcom_session_write_inline (uint32_t session_handle, void *buf, size_t n, ASSERT (n_write > 0); - VDBG (2, "VCL<%d>: vpp handle 0x%llx, sid %u: wrote %d bytes", getpid (), - s->vpp_handle, session_handle, n_write); + VDBG (2, "session %u [0x%llx]: wrote %d bytes", s->session_index, + s->vpp_handle, n_write); return n_write; } -- 2.16.6