aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2024-04-16 16:53:14 -0700
committerDave Barach <vpp@barachs.net>2024-04-17 19:03:28 +0000
commit9a5caec182b556d165a42f1cec40fe0bfbefaa60 (patch)
treeacb93631ddeffe60cf627b1a9ff97ff83ab48e6e /src
parent8188f47eb8e843d465c2c2bde7a61e3a17fa9766 (diff)
session: force session cleanups on app detach
Force transport and session cleanup on session detach if transport is already closing. This should also avoid races between transport initiated session cleanups and pending session control events. Type: improvement Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I83a947a0c01f5af8ac70aa31fee660276f1d1c60
Diffstat (limited to 'src')
-rw-r--r--src/vnet/session/session.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index e1a93a6e250..67e7ee39001 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -273,7 +273,7 @@ session_cleanup_notify (session_t * s, session_cleanup_ntf_t ntf)
app_worker_t *app_wrk;
app_wrk = app_worker_get_if_valid (s->app_wrk_index);
- if (!app_wrk)
+ if (PREDICT_FALSE (!app_wrk))
{
if (ntf == SESSION_CLEANUP_TRANSPORT)
return;
@@ -1600,11 +1600,28 @@ void
session_detach_app (session_t *s)
{
if (s->session_state < SESSION_STATE_TRANSPORT_CLOSING)
- session_close (s);
- else if (s->session_state < SESSION_STATE_TRANSPORT_CLOSED)
- session_set_state (s, SESSION_STATE_APP_CLOSED);
- else if (s->session_state < SESSION_STATE_CLOSED)
- session_set_state (s, SESSION_STATE_CLOSED);
+ {
+ session_close (s);
+ }
+ else if (s->session_state < SESSION_STATE_TRANSPORT_DELETED)
+ {
+ transport_connection_t *tc;
+
+ /* Transport is closing but it's not yet deleted. Confirm close and
+ * subsequently detach transport from session and enqueue a session
+ * cleanup notification. Transport closed and cleanup notifications are
+ * going to be dropped by session layer apis */
+ transport_close (session_get_transport_proto (s), s->connection_index,
+ s->thread_index);
+ tc = session_get_transport (s);
+ tc->s_index = SESSION_INVALID_INDEX;
+ session_set_state (s, SESSION_STATE_TRANSPORT_DELETED);
+ session_cleanup_notify (s, SESSION_CLEANUP_SESSION);
+ }
+ else
+ {
+ session_cleanup_notify (s, SESSION_CLEANUP_SESSION);
+ }
s->flags |= SESSION_F_APP_CLOSED;
s->app_wrk_index = APP_INVALID_INDEX;