vcl: improve vpp detatch handling 58/42458/9
authorFlorin Coras <[email protected]>
Fri, 7 Mar 2025 02:58:14 +0000 (21:58 -0500)
committerDave Barach <[email protected]>
Mon, 10 Mar 2025 19:56:38 +0000 (19:56 +0000)
Better handling of multi-threaded applications that share sessions.

Type: improvement

Change-Id: Id69bcb1a4b1d67aab020beefdb2fa196ec2ee108
Signed-off-by: Florin Coras <[email protected]>
src/vcl/vcl_private.c
src/vcl/vppcom.c

index b1f159f..6892688 100644 (file)
@@ -211,6 +211,7 @@ vcl_worker_detach_sessions (vcl_worker_t *wrk)
       hash_set (seg_indices_map, s->tx_fifo->segment_index, 1);
 
       s->session_state = VCL_STATE_DETACHED;
+      s->flags |= VCL_SESSION_F_APP_CLOSING;
       vec_add2 (wrk->unhandled_evts_vector, e, 1);
       e->event_type = SESSION_CTRL_EVT_DISCONNECTED;
       e->session_index = s->session_index;
@@ -220,11 +221,22 @@ vcl_worker_detach_sessions (vcl_worker_t *wrk)
   hash_foreach (seg_index, val, seg_indices_map,
                ({ vec_add1 (seg_indices, seg_index); }));
 
+  /* If multi-threaded apps, wait for all threads to hopefully finish
+   * their blocking operations  */
+  if (wrk->pre_wait_fn)
+    wrk->pre_wait_fn (VCL_INVALID_SESSION_INDEX);
+  sleep (1);
+  if (wrk->post_wait_fn)
+    wrk->post_wait_fn (VCL_INVALID_SESSION_INDEX);
+
   vcl_segment_detach_segments (seg_indices);
 
   /* Detach worker's mqs segment */
   vcl_segment_detach (vcl_vpp_worker_segment_handle (wrk->wrk_index));
 
+  wrk->app_event_queue = 0;
+  wrk->ctrl_mq = 0;
+
   vec_free (seg_indices);
   hash_free (seg_indices_map);
 }
@@ -363,8 +375,8 @@ vcl_session_read_ready (vcl_session_t * s)
     }
   else
     {
-      return (s->session_state == VCL_STATE_DISCONNECT) ?
-       VPPCOM_ECONNRESET : VPPCOM_ENOTCONN;
+      return (s->session_state == VCL_STATE_DISCONNECT) ? VPPCOM_ECONNRESET :
+                                                         VPPCOM_ENOTCONN;
     }
 }
 
index d09dd06..b4f985e 100644 (file)
@@ -1430,7 +1430,8 @@ vcl_api_retry_attach (vcl_worker_t *wrk)
       if (s->session_state == VCL_STATE_LISTEN)
        vppcom_session_listen (vcl_session_handle (s), 10);
       else
-       VDBG (0, "internal error: unexpected state %d", s->session_state);
+       VDBG (0, "reattach error: %u unexpected state %d", s->session_index,
+             s->session_state);
     }
 }
 
@@ -1774,11 +1775,16 @@ vppcom_session_listen (uint32_t listen_sh, uint32_t q_len)
   if (listen_session->session_state == VCL_STATE_LISTEN &&
       !(listen_session->flags & VCL_SESSION_F_LISTEN_NO_MQ))
     {
-      VDBG (0, "session %u [0x%llx]: already in listen state!",
-           listen_sh, listen_vpp_handle);
+      VDBG (0, "session %u [0x%llx]: already in listen state!", listen_sh,
+           listen_vpp_handle);
+      return VPPCOM_OK;
+    }
+  if (PREDICT_FALSE (!wrk->ctrl_mq))
+    {
+      listen_session->session_state = VCL_STATE_LISTEN;
+      listen_session->flags |= VCL_SESSION_F_LISTEN_NO_MQ;
       return VPPCOM_OK;
     }
-
   listen_session->flags &= ~VCL_SESSION_F_LISTEN_NO_MQ;
 
   VDBG (0, "session %u: sending vpp listen request...", listen_sh);
@@ -2657,6 +2663,9 @@ vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
          *bits_set += 1;
        }
       break;
+    case SESSION_CTRL_EVT_BOUND:
+      vcl_session_bound_handler (wrk, (session_bound_msg_t *) e->data);
+      break;
     case SESSION_CTRL_EVT_UNLISTEN_REPLY:
       vcl_session_unlisten_reply_handler (wrk, e->data);
       break;