session: cleanup CREATED sessions when listener goes down 59/32159/6
authorliuyacan <liuyacan@corp.netease.com>
Wed, 28 Apr 2021 11:34:03 +0000 (11:34 +0000)
committerFlorin Coras <florin.coras@gmail.com>
Thu, 29 Apr 2021 17:52:53 +0000 (17:52 +0000)
We should cleanup sessions in CREATED state when listener goes
down, otherwise they may use unpredictable sessions as listeners
later.

Type: fix

Signed-off-by: liuyacan <liuyacan@corp.netease.com>
Change-Id: Ifbd0a0fb46275bd9d89e5aee19a70c1d01d15764

src/vnet/session/application_worker.c
src/vnet/session/segment_manager.c
src/vnet/session/segment_manager.h

index d44f52c..8c3be22 100644 (file)
@@ -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);
index 73b2f71..103f89e 100644 (file)
@@ -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,
index e73a70f..3278d8d 100644 (file)
@@ -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);