Index: trunk/src/VBox/Devices/Network/slirp/slirp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 16448)
+++ trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 16449)
@@ -800,4 +800,33 @@
         /* { */
 
+#ifdef VBOX_WITH_SLIRP_MT
+            if (   so->so_state & SS_NOFDREF 
+                && so->so_deleted == 1) 
+            {   
+                struct socket *son, *sop = NULL;
+                QSOCKET_LOCK(tcb);
+                if (so->so_next != NULL) 
+                {
+                    if (so->so_next != &tcb)
+                        SOCKET_LOCK(so->so_next);
+                    son = so->so_next;
+                }
+                if (    so->so_prev != &tcb
+                    && so->so_prev != NULL) 
+                {
+                    SOCKET_LOCK(so->so_prev);
+                    sop = so->so_prev;
+                }
+                QSOCKET_UNLOCK(tcb);
+                remque(pData, so);
+                SOCKET_UNLOCK(so);
+                SOCKET_LOCK_DESTROY(so);
+                RTMemFree(so);
+                so_next = son;
+                if (sop != NULL)
+                    SOCKET_UNLOCK(sop);
+                CONTINUE_NO_UNLOCK(tcp);
+            }
+#endif
             /*
              * FD_ISSET is meaningless on these sockets
@@ -977,4 +1006,33 @@
          QSOCKET_FOREACH(so, so_next, udp)
          /* { */
+#ifdef VBOX_WITH_SLIRP_MT
+            if (   so->so_state & SS_NOFDREF 
+                && so->so_deleted == 1) 
+            {   
+                struct socket *son, *sop = NULL;
+                QSOCKET_LOCK(udb);
+                if (so->so_next != NULL) 
+                {
+                    if (so->so_next != &udb)
+                        SOCKET_LOCK(so->so_next);
+                    son = so->so_next;
+                }
+                if (    so->so_prev != &udb
+                    && so->so_prev != NULL) 
+                {
+                    SOCKET_LOCK(so->so_prev);
+                    sop = so->so_prev;
+                }
+                QSOCKET_UNLOCK(udb);
+                remque(pData, so);
+                SOCKET_UNLOCK(so);
+                SOCKET_LOCK_DESTROY(so);
+                RTMemFree(so);
+                so_next = son;
+                if (sop != NULL)
+                    SOCKET_UNLOCK(sop);
+                CONTINUE_NO_UNLOCK(udp);
+            }
+#endif
             POLL_UDP_EVENTS(rc, error, so, &NetworkEvents);
 
Index: trunk/src/VBox/Devices/Network/slirp/socket.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 16448)
+++ trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 16449)
@@ -87,11 +87,13 @@
     if (so->so_m != NULL)
         m_free(pData, so->so_m);
+#ifndef VBOX_WITH_SLIRP_MT
     if(so->so_next && so->so_prev)
         remque(pData, so);  /* crashes if so is not in a queue */
     so->so_state = SS_NOFDREF; /* for debugging purposes */
-    SOCKET_UNLOCK(so);
-    SOCKET_LOCK_DESTROY(so);
 
     RTMemFree(so);
+#else
+    so->so_deleted = 1;
+#endif
 }
 
Index: trunk/src/VBox/Devices/Network/slirp/socket.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/socket.h	(revision 16448)
+++ trunk/src/VBox/Devices/Network/slirp/socket.h	(revision 16449)
@@ -69,4 +69,5 @@
 #ifdef VBOX_WITH_SLIRP_MT
     RTCRITSECT      so_mutex;
+    int             so_deleted;
 #endif
 };
Index: trunk/src/VBox/Devices/Network/slirp/tcp_input.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/tcp_input.c	(revision 16448)
+++ trunk/src/VBox/Devices/Network/slirp/tcp_input.c	(revision 16449)
@@ -423,5 +423,6 @@
                 && so->so_laddr.s_addr == ti->ti_src.s_addr
                 && so->so_faddr.s_addr == ti->ti_dst.s_addr
-                && so->so_fport        == ti->ti_dport) 
+                && so->so_fport        == ti->ti_dport
+                && so->so_deleted != 1) 
             {
                 Log2(("lock: %s:%d We found socket %R[natsock]\n", __FUNCTION__, __LINE__, so));
@@ -1654,8 +1655,4 @@
     m_free(pData, m);
 
-#ifdef VBOX_WITH_SLIRP_MT
-    /*socket should be killed atm*/
-    AssertRelease(!RTCritSectIsInitialized(&so->so_mutex));
-#endif    
     return;
 }
Index: trunk/src/VBox/Devices/Network/slirp/tcp_subr.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/tcp_subr.c	(revision 16448)
+++ trunk/src/VBox/Devices/Network/slirp/tcp_subr.c	(revision 16449)
@@ -287,21 +287,6 @@
     sbfree(&so->so_rcv);
     sbfree(&so->so_snd);
-    QSOCKET_LOCK(tcb);
-    if (   so->so_next != &tcb
-        && so->so_next != NULL)
-    {
-        SOCKET_LOCK(so->so_next);
-        so_next = so->so_next;
-    }
-    if (   so->so_prev != &tcb
-        && so->so_prev != NULL)
-    {
-        SOCKET_LOCK(so->so_prev);
-        so_prev = so->so_prev;
-    }
-    QSOCKET_UNLOCK(tcb);
     sofree(pData, so);
-    if (so_next != NULL) SOCKET_UNLOCK(so_next);
-    if (so_prev != NULL) SOCKET_UNLOCK(so_prev);
+    SOCKET_UNLOCK(so);
     tcpstat.tcps_closed++;
     return ((struct tcpcb *)0);
Index: trunk/src/VBox/Devices/Network/slirp/udp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/udp.c	(revision 16448)
+++ trunk/src/VBox/Devices/Network/slirp/udp.c	(revision 16449)
@@ -400,29 +400,12 @@
 udp_detach(PNATState pData, struct socket *so)
 {
-    struct socket *so_next, *so_prev;
-    so_next = so_prev = NULL;
     if (so != &pData->icmp_socket)
     {
         QSOCKET_LOCK(udb);
         SOCKET_LOCK(so);
-        if (    so->so_next != &udb
-            && so->so_next != NULL)
-        {
-            SOCKET_LOCK(so->so_next);
-            so_next = so->so_next;
-        }
-        if (    so->so_prev != &udb
-            && so->so_prev != NULL)
-        {
-            SOCKET_LOCK(so->so_prev);
-            so_prev = so->so_prev;
-        }
         QSOCKET_UNLOCK(udb);
         closesocket(so->s);
         sofree(pData, so);
-        if(so_prev != NULL)
-            SOCKET_UNLOCK(so_prev);
-        if(so_next != NULL)
-            SOCKET_UNLOCK(so_next);
+        SOCKET_UNLOCK(so);
     }
 }
