This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit a8862bcaddbe045fc0e6297983f3c10ae7b286b9
Author: Yongrong Wang <[email protected]>
AuthorDate: Thu Jun 5 16:38:53 2025 +0800

    vsock_sockif.c: fix vsock close process problem
    
    If vsock_close and vsock_recv_closing are called in the same thread
    (such as vsock local), remove conn will have timing problems
    
    Signed-off-by: Yongrong Wang <[email protected]>
---
 net/vsock/vsock_sockif.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/net/vsock/vsock_sockif.c b/net/vsock/vsock_sockif.c
index 3f578b9eab7..cc7089407c7 100644
--- a/net/vsock/vsock_sockif.c
+++ b/net/vsock/vsock_sockif.c
@@ -663,6 +663,21 @@ static inline_function void vsock_remove_conn(FAR struct 
vsock_conn_s *conn)
   spin_unlock_irqrestore(&g_vsock_conn_lock, flags);
 }
 
+static inline_function bool vsock_check_conn(FAR struct vsock_conn_s *conn)
+{
+  irqstate_t flags;
+
+  flags = spin_lock_irqsave(&g_vsock_conn_lock);
+  if (list_in_list(&conn->node))
+    {
+      spin_unlock_irqrestore(&g_vsock_conn_lock, flags);
+      return true;
+    }
+
+  spin_unlock_irqrestore(&g_vsock_conn_lock, flags);
+  return false;
+}
+
 /****************************************************************************
  * Name: vsock_bind_internal
  *
@@ -2111,6 +2126,7 @@ static int vsock_close(FAR struct socket *psock)
     }
   else if (_SS_ISCONNECTED(conn->sconn.s_flags))
     {
+      vsock_add_ref(conn);
       conn->shutdown = SHUT_RDWR;
 
       /* Follow Virtio Spec 1.2 to do the clean disconnect:
@@ -2128,16 +2144,19 @@ static int vsock_close(FAR struct socket *psock)
       if (ret < 0)
         {
           vsockdbg("send shutdown failed conn=%p\n", conn);
+          vsock_sub_ref(conn);
           vsock_unlock(conn);
           return ret;
         }
 
       /* Queue the close timeout work */
 
-      vsockdbg("queue the close work conn=%p\n", conn);
-      vsock_add_ref(conn);
-      ret = vsock_queue_work(&conn->close_work, vsock_close_work, conn,
-                             VSOCK_CLOSE_TIMEOUT);
+      if (vsock_check_conn(conn))
+        {
+          vsockdbg("queue the close work conn=%p\n", conn);
+          ret = vsock_queue_work(&conn->close_work, vsock_close_work, conn,
+                                 VSOCK_CLOSE_TIMEOUT);
+        }
     }
   else if (_SS_ISBOUND(conn->sconn.s_flags) ||
            _SS_ISLISTENING(conn->sconn.s_flags))

Reply via email to