summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/session/application_worker.c8
-rw-r--r--src/vnet/session/segment_manager.c53
-rw-r--r--src/vnet/session/segment_manager.h2
3 files changed, 63 insertions, 0 deletions
diff --git a/src/vnet/session/application_worker.c b/src/vnet/session/application_worker.c
index d44f52c5340..8c3be22d4dc 100644
--- a/src/vnet/session/application_worker.c
+++ b/src/vnet/session/application_worker.c
@@ -293,6 +293,7 @@ app_worker_stop_listen_session (app_worker_t * app_wrk, session_t * ls)
session_handle_t handle;
segment_manager_t *sm;
uword *sm_indexp;
+ session_state_t *states = 0;
handle = listen_session_get_handle (ls);
sm_indexp = hash_get (app_wrk->listeners_table, handle);
@@ -308,6 +309,13 @@ app_worker_stop_listen_session (app_worker_t * app_wrk, session_t * ls)
/* Try to cleanup segment manager */
sm = segment_manager_get (*sm_indexp);
+ if (sm && segment_manager_has_fifos (sm))
+ {
+ /* Delete sessions in CREATED state */
+ vec_add1 (states, SESSION_STATE_CREATED);
+ segment_manager_del_sessions_filter (sm, states);
+ vec_free (states);
+ }
if (sm && app_wrk->first_segment_manager != *sm_indexp)
{
segment_manager_app_detach (sm);
diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c
index 73b2f7177bd..103f89ecfa8 100644
--- a/src/vnet/session/segment_manager.c
+++ b/src/vnet/session/segment_manager.c
@@ -626,6 +626,59 @@ segment_manager_del_sessions (segment_manager_t * sm)
vec_free (handles);
}
+/**
+ * Initiate disconnects for sessions in specified state 'owned' by a segment
+ * manager
+ */
+void
+segment_manager_del_sessions_filter (segment_manager_t *sm,
+ session_state_t *states)
+{
+ session_handle_t *handles = 0, *handle;
+ fifo_segment_t *fs;
+ session_t *session;
+ int slice_index;
+ svm_fifo_t *f;
+
+ ASSERT (pool_elts (sm->segments) != 0);
+
+ /* Across all fifo segments used by the server */
+ segment_manager_foreach_segment_w_lock (
+ fs, sm, ({
+ for (slice_index = 0; slice_index < fs->n_slices; slice_index++)
+ {
+ f = fifo_segment_get_slice_fifo_list (fs, slice_index);
+ while (f)
+ {
+ session = session_get_if_valid (f->shr->master_session_index,
+ f->master_thread_index);
+ if (session)
+ {
+ session_state_t *state;
+ vec_foreach (state, states)
+ {
+ if (session->session_state == *state)
+ {
+ vec_add1 (handles, session_handle (session));
+ break;
+ }
+ }
+ }
+ f = f->next;
+ }
+ }
+ }));
+
+ vec_foreach (handle, handles)
+ {
+ session = session_get_from_handle (*handle);
+ session_close (session);
+ /* Avoid propagating notifications back to the app */
+ session->app_wrk_index = APP_INVALID_INDEX;
+ }
+ vec_free (handles);
+}
+
int
segment_manager_try_alloc_fifos (fifo_segment_t * fifo_segment,
u32 thread_index,
diff --git a/src/vnet/session/segment_manager.h b/src/vnet/session/segment_manager.h
index e73a70fda16..3278d8d825d 100644
--- a/src/vnet/session/segment_manager.h
+++ b/src/vnet/session/segment_manager.h
@@ -159,6 +159,8 @@ void segment_manager_app_detach (segment_manager_t * sm);
* @param sm segment manager whose sessions are to be disconnected
*/
void segment_manager_del_sessions (segment_manager_t * sm);
+void segment_manager_del_sessions_filter (segment_manager_t *sm,
+ session_state_t *states);
void segment_manager_format_sessions (segment_manager_t * sm, int verbose);
void segment_manager_main_init (void);