vcl: improve vls handling of shared listeners
[vpp.git] / src / vcl / vcl_locked.c
index 5ec553e..8b0c66d 100644 (file)
@@ -670,8 +670,19 @@ vls_listener_wrk_is_active (vcl_locked_session_t * vls, u32 wrk_index)
 static void
 vls_listener_wrk_start_listen (vcl_locked_session_t * vls, u32 wrk_index)
 {
-  vppcom_session_listen (vls_to_sh (vls), ~0);
-  vls_listener_wrk_set (vls, wrk_index, 1 /* is_active */ );
+  vcl_worker_t *wrk;
+  vcl_session_t *ls;
+
+  wrk = vcl_worker_get (wrk_index);
+  ls = vcl_session_get (wrk, vls->session_index);
+
+  /* Listen request already sent */
+  if (ls->flags & VCL_SESSION_F_PENDING_LISTEN)
+    return;
+
+  vcl_send_session_listen (wrk, ls);
+
+  vls_listener_wrk_set (vls, wrk_index, 1 /* is_active */);
 }
 
 static void
@@ -1481,17 +1492,33 @@ vls_epoll_ctl (vls_handle_t ep_vlsh, int op, vls_handle_t vlsh,
 
   vls_mt_detect ();
   vls_mt_pool_rlock ();
+
   ep_vls = vls_get_and_lock (ep_vlsh);
+  if (PREDICT_FALSE (!ep_vls))
+    {
+      vls_mt_pool_runlock ();
+      return VPPCOM_EBADFD;
+    }
 
   if (vls_mt_session_should_migrate (ep_vls))
     {
       ep_vls = vls_mt_session_migrate (ep_vls);
       if (PREDICT_FALSE (!ep_vls))
-       return VPPCOM_EBADFD;
+       {
+         vls_mt_pool_runlock ();
+         return VPPCOM_EBADFD;
+       }
     }
 
-  ep_sh = vls_to_sh (ep_vls);
   vls = vls_get_and_lock (vlsh);
+  if (PREDICT_FALSE (!vls))
+    {
+      vls_unlock (ep_vls);
+      vls_mt_pool_runlock ();
+      return VPPCOM_EBADFD;
+    }
+
+  ep_sh = vls_to_sh (ep_vls);
   sh = vls_to_sh (vls);
 
   vls_epoll_ctl_mp_checks (vls, op);