vcl: add api to retrieve num bytes for tx
[vpp.git] / src / vcl / vppcom.c
index 6bdeb5a..a0bbae1 100644 (file)
@@ -545,6 +545,7 @@ vcl_session_bound_handler (vcl_worker_t * wrk, session_bound_msg_t * mp)
        {
          session->session_state = VCL_STATE_DETACHED;
          session->vpp_handle = mp->handle;
+         session->vpp_error = mp->retval;
          return sid;
        }
       else
@@ -1161,7 +1162,10 @@ vppcom_wait_for_session_state_change (u32 session_index,
        }
       if (session->session_state == VCL_STATE_DETACHED)
        {
-         return VPPCOM_ECONNREFUSED;
+         if (session->vpp_error == SESSION_E_ALREADY_LISTENING)
+           return VPPCOM_EADDRINUSE;
+         else
+           return VPPCOM_ECONNREFUSED;
        }
 
       if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0))
@@ -1436,12 +1440,10 @@ vppcom_app_destroy (void)
 
   current_wrk = vcl_worker_get_current ();
 
-  /* *INDENT-OFF* */
   pool_foreach (wrk, vcm->workers)  {
     if (current_wrk != wrk)
       vcl_worker_cleanup (wrk, 0 /* notify vpp */ );
   }
-  /* *INDENT-ON* */
 
   vcl_api_detach (current_wrk);
   vcl_worker_cleanup (current_wrk, 0 /* notify vpp */ );
@@ -1678,7 +1680,7 @@ vppcom_session_bind (uint32_t session_handle, vppcom_endpt_t * ep)
   vcl_evt (VCL_EVT_BIND, session);
 
   if (session->session_type == VPPCOM_PROTO_UDP)
-    vppcom_session_listen (session_handle, 10);
+    return vppcom_session_listen (session_handle, 10);
 
   return VPPCOM_OK;
 }
@@ -2052,13 +2054,13 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n,
 
   if (svm_fifo_is_empty_cons (rx_fifo))
     {
+      if (is_ct)
+       svm_fifo_unset_event (s->rx_fifo);
+      svm_fifo_unset_event (rx_fifo);
       if (is_nonblocking)
        {
          if (vcl_session_is_closing (s))
            return vcl_session_closing_error (s);
-         if (is_ct)
-           svm_fifo_unset_event (s->rx_fifo);
-         svm_fifo_unset_event (rx_fifo);
          return VPPCOM_EWOULDBLOCK;
        }
       while (svm_fifo_is_empty_cons (rx_fifo))
@@ -2164,11 +2166,13 @@ vppcom_session_read_segments (uint32_t session_handle,
 
   if (svm_fifo_is_empty_cons (rx_fifo))
     {
+      if (is_ct)
+       svm_fifo_unset_event (s->rx_fifo);
+      svm_fifo_unset_event (rx_fifo);
       if (is_nonblocking)
        {
-         if (is_ct)
-           svm_fifo_unset_event (s->rx_fifo);
-         svm_fifo_unset_event (rx_fifo);
+         if (vcl_session_is_closing (s))
+           return vcl_session_closing_error (s);
          return VPPCOM_EWOULDBLOCK;
        }
       while (svm_fifo_is_empty_cons (rx_fifo))
@@ -2447,10 +2451,24 @@ vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
       vcl_session_add_want_deq_ntf (s, SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL);
       break;
     case SESSION_CTRL_EVT_DISCONNECTED:
-      disconnected_msg = (session_disconnected_msg_t *) e->data;
-      s = vcl_session_disconnected_handler (wrk, disconnected_msg);
-      if (!s)
-       break;
+      if (!e->postponed)
+       {
+         disconnected_msg = (session_disconnected_msg_t *) e->data;
+         s = vcl_session_disconnected_handler (wrk, disconnected_msg);
+         if (!s)
+           break;
+       }
+      else
+       {
+         s = vcl_session_get (wrk, e->session_index);
+         s->flags &= ~VCL_SESSION_F_PENDING_DISCONNECT;
+       }
+      if (vcl_session_is_closed (s))
+       {
+         if (s && (s->flags & VCL_SESSION_F_PENDING_FREE))
+           vcl_session_free (wrk, s);
+         break;
+       }
       sid = s->session_index;
       if (sid < n_bits && except_map)
        {
@@ -2459,7 +2477,24 @@ vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
        }
       break;
     case SESSION_CTRL_EVT_RESET:
-      sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
+      if (!e->postponed)
+       {
+         sid =
+           vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
+         s = vcl_session_get (wrk, sid);
+       }
+      else
+       {
+         sid = e->session_index;
+         s = vcl_session_get (wrk, sid);
+         s->flags &= ~VCL_SESSION_F_PENDING_DISCONNECT;
+       }
+      if (vcl_session_is_closed (s))
+       {
+         if (s && (s->flags & VCL_SESSION_F_PENDING_FREE))
+           vcl_session_free (wrk, s);
+         break;
+       }
       if (sid < n_bits && except_map)
        {
          clib_bitmap_set_no_check ((uword *) except_map, sid, 1);
@@ -2793,7 +2828,7 @@ vppcom_epoll_create (void)
 
 static void
 vcl_epoll_ctl_add_unhandled_event (vcl_worker_t *wrk, vcl_session_t *s,
-                                  u8 is_epollet, session_evt_type_t evt)
+                                  u32 is_epollet, session_evt_type_t evt)
 {
   if (!is_epollet)
     {
@@ -3550,7 +3585,19 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op,
       VDBG (2, "VPPCOM_ATTR_GET_NWRITE: sh %u, nwrite = %d", session_handle,
            rv);
       break;
-
+    case VPPCOM_ATTR_GET_NWRITEQ:
+      if (PREDICT_FALSE (!buffer || !buflen || *buflen != sizeof (int)))
+       {
+         rv = VPPCOM_EINVAL;
+         break;
+       }
+      if (!session->tx_fifo || session->session_state == VCL_STATE_DETACHED)
+       {
+         rv = VPPCOM_EINVAL;
+         break;
+       }
+      *(int *) buffer = svm_fifo_max_dequeue (session->tx_fifo);
+      break;
     case VPPCOM_ATTR_GET_FLAGS:
       if (PREDICT_TRUE (buffer && buflen && (*buflen >= sizeof (*flags))))
        {