Index: trunk/src/VBox/Devices/Makefile.kmk
===================================================================
--- trunk/src/VBox/Devices/Makefile.kmk	(revision 13580)
+++ trunk/src/VBox/Devices/Makefile.kmk	(revision 13604)
@@ -531,4 +531,7 @@
 ifdef VBOX_WITH_NETFLT
 Drivers_DEFS       = VBOX_WITH_NETFLT
+endif
+ifdef VBOX_WITH_SYNC_SLIRP
+Drivers_DEFS       = VBOX_WITH_SYNC_SLIRP
 endif
 Drivers_INCS      := \
Index: trunk/src/VBox/Devices/Network/DrvNAT.cpp
===================================================================
--- trunk/src/VBox/Devices/Network/DrvNAT.cpp	(revision 13580)
+++ trunk/src/VBox/Devices/Network/DrvNAT.cpp	(revision 13604)
@@ -56,4 +56,8 @@
 #ifdef VBOX_NAT_SOURCES
 #include "Network/nat/nat.h"
+#endif
+
+#ifdef VBOX_WITH_SYNC_SLIRP
+#include <iprt/semaphore.h>
 #endif
 
@@ -87,4 +91,10 @@
     /** Boot file name to provide in the DHCP server response. */
     char                    *pszBootFile;
+#ifdef VBOX_WITH_SYNC_SLIRP
+    /*polling thread*/
+    PPDMTHREAD              pThread;
+    /*used for wakep of poling thread*/
+    RTSEMEVENT               semIOmutex;
+#endif
 } DRVNAT, *PDRVNAT;
 
@@ -143,6 +153,8 @@
           pvBuf, cb, cb, pvBuf));
 
+#ifndef VBOX_WITH_SYNC_SLIRP
     int rc = RTCritSectEnter(&pThis->CritSect);
     AssertReleaseRC(rc);
+#endif
 
     Assert(pThis->enmLinkState == PDMNETWORKLINKSTATE_UP);
@@ -154,5 +166,7 @@
 #endif
     }
+#ifndef VBOX_WITH_SYNC_SLIRP
     RTCritSectLeave(&pThis->CritSect);
+#endif
     LogFlow(("drvNATSend: end\n"));
     return VINF_SUCCESS;
@@ -190,6 +204,8 @@
     LogFlow(("drvNATNotifyLinkChanged: enmLinkState=%d\n", enmLinkState));
 
+#ifndef VBOX_WITH_SYNC_SLIRP
     int rc = RTCritSectEnter(&pThis->CritSect);
     AssertReleaseRC(rc);
+#endif
     pThis->enmLinkState = enmLinkState;
 
@@ -214,5 +230,7 @@
             AssertMsgFailed(("drvNATNotifyLinkChanged: unexpected link state %d\n", enmLinkState));
     }
+#ifndef VBOX_WITH_SYNC_SLIRP
     RTCritSectLeave(&pThis->CritSect);
+#endif
 }
 
@@ -221,4 +239,5 @@
  * Poller callback.
  */
+#ifndef VBOX_WITH_SYNC_SLIRP
 static DECLCALLBACK(void) drvNATPoller(PPDMDRVINS pDrvIns)
 {
@@ -254,4 +273,66 @@
     RTCritSectLeave(&pThis->CritSect);
 }
+#else
+
+static DECLCALLBACK(int) drvNATAsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
+{
+    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
+    fd_set  ReadFDs;
+    fd_set  WriteFDs;
+    fd_set  XcptFDs;
+    int     cFDs = -1;
+    int     rc;
+
+    LogFlow(("drvNATAsyncIoThread: pThis=%p\n", pThis));
+
+
+    if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
+        return VINF_SUCCESS;
+    /*
+     * Polling loop.
+     */
+    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
+    {
+        FD_ZERO(&ReadFDs);
+        FD_ZERO(&WriteFDs);
+        FD_ZERO(&XcptFDs);
+        cFDs = -1;
+
+        slirp_select_fill(pThis->pNATState, &cFDs, &ReadFDs, &WriteFDs, &XcptFDs);
+
+        struct timeval tv = {0, 0}; /* no wait */
+
+        int cReadFDs = select(cFDs + 1, &ReadFDs, &WriteFDs, &XcptFDs, &tv);
+
+        if (cReadFDs >= 0)
+            slirp_select_poll(pThis->pNATState, &ReadFDs, &WriteFDs, &XcptFDs);
+
+#if 0
+        if (cReadFDs == 0) {
+            rc = RTSemEventWait(pThis->semIOmutex, RT_INDEFINITE_WAIT);
+            AssertReleaseRC(rc);
+        }
+#endif
+    }
+
+}
+ /**
+ *  Unblock the send thread so it can respond to a state change.
+ *
+ *  @returns VBox status code.
+ *  @param   pDevIns     The pcnet device instance.
+ *  @param   pThread     The send thread.
+ */
+static DECLCALLBACK(int) drvNATAsyncIoWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
+{
+#if 0
+    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
+    int rc = RTSemEventSignal(pThis->semIOmutex);
+    AssertReleaseRC(rc);
+#endif
+    return (VINF_SUCCESS);
+}
+
+#endif
 
 #ifndef VBOX_NAT_SOURCES
@@ -267,7 +348,9 @@
     Assert(pThis);
 
+#ifndef VBOX_WITH_SYNC_SLIRP
     /** Happens during termination */
     if (!RTCritSectIsOwner(&pThis->CritSect))
         return 0;
+#endif
 
     int rc =  pThis->pPort->pfnWaitReceiveAvail(pThis->pPort, 0);
@@ -291,7 +374,9 @@
     Assert(pThis);
 
+#ifndef VBOX_WITH_SYNC_SLIRP
     /** Happens during termination */
     if (!RTCritSectIsOwner(&pThis->CritSect))
         return;
+#endif
 
     int rc = pThis->pPort->pfnReceive(pThis->pPort, pu8Buf, cb);
@@ -591,5 +676,12 @@
                                                NULL, NULL, NULL, NULL, NULL, drvNATLoadDone);
                     AssertRC(rc2);
+#ifndef VBOX_WITH_SYNC_SLIRP
                     pDrvIns->pDrvHlp->pfnPDMPollerRegister(pDrvIns, drvNATPoller);
+#else
+                    rc = RTSemEventCreate(&pThis->semIOmutex);
+                    AssertReleaseRC(rc);
+                    rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pThread, pThis, drvNATAsyncIoThread, drvNATAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "NAT");
+                    AssertReleaseRC(rc);
+#endif
 
                     pThis->enmLinkState = PDMNETWORKLINKSTATE_UP;
Index: trunk/src/VBox/Devices/Network/slirp/if.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/if.c	(revision 13580)
+++ trunk/src/VBox/Devices/Network/slirp/if.c	(revision 13604)
@@ -48,5 +48,14 @@
 	if_comp = IF_AUTOCOMP;
 	if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexCreate(&pData->if_fastq_mutex);
+        RTSemMutexCreate(&if_fastq.m_mutex);
+#endif
+
 	if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexCreate(&pData->if_batchq_mutex);
+        RTSemMutexCreate(&if_batchq.m_mutex);
+#endif
         /*	sl_compress_init(&comp_s); */
 	next_m = &if_batchq;
@@ -149,4 +158,7 @@
 {
 	struct mbuf *ifq;
+#ifdef VBOX_WITH_SYNC_SLIRP
+	struct mbuf *ifqprev;
+#endif
 	int on_fastq = 1;
 
@@ -154,4 +166,8 @@
 	DEBUG_ARG("so = %lx", (long)so);
 	DEBUG_ARG("ifm = %lx", (long)ifm);
+#ifdef VBOX_WITH_SYNC_SLIRP
+    if (so != NULL)
+        RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 
 	/*
@@ -160,8 +176,15 @@
 	 * XXX Shouldn't need this, gotta change dtom() etc.
 	 */
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(pData->m_usedlist_mutex, RT_INDEFINITE_WAIT);
+        RTSemMutexRequest(ifm->m_mutex, RT_INDEFINITE_WAIT);
+#endif
 	if (ifm->m_flags & M_USEDLIST) {
 		remque(pData, ifm);
 		ifm->m_flags &= ~M_USEDLIST;
 	}
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(pData->m_usedlist_mutex);
+#endif
 
 	/*
@@ -172,5 +195,18 @@
 	 * XXX add cache here?
 	 */
+#ifndef VBOX_WITH_SYNC_SLIRP
 	for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev) {
+#else
+        RTSemMutexRequest(pData->if_batchq_mutex, RT_INDEFINITE_WAIT);
+        ifq = if_batchq.ifq_prev;
+        while(1){
+            if (ifq == &if_batchq) {
+                RTSemMutexRelease(pData->if_batchq_mutex);
+                break;
+            }
+            ifqprev = ifq->ifq_prev;
+            RTSemMutexRequest(ifq->m_mutex, RT_INDEFINITE_WAIT);
+            RTSemMutexRelease(pData->if_batchq_mutex);
+#endif
 		if (so == ifq->ifq_so) {
 			/* A match! */
@@ -179,9 +215,21 @@
 			goto diddit;
 		}
+#ifdef VBOX_WITH_SYNC_SLIRP
+            RTSemMutexRequest(pData->if_batchq_mutex, RT_INDEFINITE_WAIT);
+            RTSemMutexRelease(ifq->m_mutex);
+            ifq = ifqprev;
+#endif
 	}
 
 	/* No match, check which queue to put it on */
 	if (so && (so->so_iptos & IPTOS_LOWDELAY)) {
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRequest(pData->if_fastq_mutex, RT_INDEFINITE_WAIT);
+#endif
 		ifq = if_fastq.ifq_prev;
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRequest(ifq->m_mutex, RT_INDEFINITE_WAIT);
+                RTSemMutexRelease(pData->if_fastq_mutex);
+#endif
 		on_fastq = 1;
 		/*
@@ -194,6 +242,15 @@
 			goto diddit;
 		}
-	} else
+	}
+        else {
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRequest(pData->if_batchq_mutex, RT_INDEFINITE_WAIT);
+#endif
 		ifq = if_batchq.ifq_prev;
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRequest(ifq->m_mutex, RT_INDEFINITE_WAIT);
+                RTSemMutexRelease(pData->if_batchq_mutex);
+#endif
+        }
 
 	/* Create a new doubly linked list for this session */
@@ -203,5 +260,11 @@
 
 diddit:
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexRequest(pData->if_queued_mutex, RT_INDEFINITE_WAIT);
+#endif
 	++if_queued;
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexRelease(pData->if_queued_mutex);
+#endif
 
 	if (so) {
@@ -219,11 +282,26 @@
 				 (so->so_nqueued - so->so_queued) >= 3)) {
 
+#ifdef VBOX_WITH_SYNC_SLIRP
+                        RTSemMutexRequest(pData->if_fastq_mutex, RT_INDEFINITE_WAIT);
+#endif
 			/* Remove from current queue... */
 			remque(pData, ifm->ifs_next);
+#ifdef VBOX_WITH_SYNC_SLIRP
+                        RTSemMutexRequest(pData->if_batchq_mutex, RT_INDEFINITE_WAIT);
+#endif
 
 			/* ...And insert in the new.  That'll teach ya! */
 			insque(pData, ifm->ifs_next, &if_batchq);
-		}
-	}
+#ifdef VBOX_WITH_SYNC_SLIRP
+                    RTSemMutexRelease(pData->if_fastq_mutex);
+                    RTSemMutexRelease(pData->if_batchq_mutex);
+#endif
+		}
+                RTSemMutexRelease(so->so_mutex);
+	}
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(ifq->m_mutex);
+        RTSemMutexRelease(ifm->m_mutex);
+#endif
 
 #ifndef FULL_BOLT
@@ -254,11 +332,25 @@
 {
 	struct mbuf *ifm, *ifqt;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        int on_fast = 0; /*required for correctness */
+	struct mbuf *ifm_prev;
+#endif
 
 	DEBUG_CALL("if_start");
 
-	if (if_queued == 0)
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(pData->if_queued_mutex, RT_INDEFINITE_WAIT);
+#endif
+	if (if_queued <= 0) {
+#ifdef VBOX_WITH_SYNC_SLIRP
+            RTSemMutexRelease(pData->if_queued_mutex);
+#endif
 	   return; /* Nothing to do */
+        }
 
  again:
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(pData->if_queued_mutex);
+#endif
         /* check if we can really output */
         if (!slirp_can_output(pData->pvUser))
@@ -269,7 +361,19 @@
 	 * If there's something in the fastq, select it immediately
 	 */
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(pData->if_fastq_mutex, RT_INDEFINITE_WAIT);
+#endif
 	if (if_fastq.ifq_next != &if_fastq) {
 		ifm = if_fastq.ifq_next;
+#ifdef VBOX_WITH_SYNC_SLIRP
+                on_fast = 1;
+                RTSemMutexRequest(ifm->m_mutex, RT_INDEFINITE_WAIT);
+#endif
 	} else {
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRelease(pData->if_fastq_mutex);
+                RTSemMutexRequest(pData->next_m_mutex, RT_INDEFINITE_WAIT);
+                RTSemMutexRequest(pData->if_batchq_mutex, RT_INDEFINITE_WAIT);
+#endif
 		/* Nothing on fastq, see if next_m is valid */
 		if (next_m != &if_batchq)
@@ -280,9 +384,27 @@
 		/* Set which packet to send on next iteration */
 		next_m = ifm->ifq_next;
-	}
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRelease(pData->next_m_mutex);
+#endif
+	}
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(ifm->m_mutex, RT_INDEFINITE_WAIT);
+        RTSemMutexRequest(pData->if_queued_mutex, RT_INDEFINITE_WAIT);
+#endif
 	/* Remove it from the queue */
 	ifqt = ifm->ifq_prev;
+	ifqt = ifm->ifq_prev;
 	remque(pData, ifm);
+
 	--if_queued;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(pData->if_queued_mutex);
+        if (on_fast == 1) {
+            RTSemMutexRelease(pData->if_fastq_mutex);
+        }
+        else {
+            RTSemMutexRelease(pData->if_batchq_mutex);
+        }
+#endif
 
 	/* If there are more packets for this session, re-queue them */
@@ -294,15 +416,31 @@
 	/* Update so_queued */
 	if (ifm->ifq_so) {
+#ifndef VBOX_WITH_SYNC_SLIRP
+            RTSemMutexRequest(ifm->ifq_so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 		if (--ifm->ifq_so->so_queued == 0)
 		   /* If there's no more queued, reset nqueued */
 		   ifm->ifq_so->so_nqueued = 0;
+#ifndef VBOX_WITH_SYNC_SLIRP
+            RTSemMutexRelease(ifm->ifq_so->so_mutex);
+#endif
 	}
 
 	/* Encapsulate the packet for sending */
         if_encap(pData, (const uint8_t *)ifm->m_data, ifm->m_len);
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(ifm->m_mutex);
+#endif
 
         m_free(pData, ifm);
 
-	if (if_queued)
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(pData->if_queued_mutex, RT_INDEFINITE_WAIT);
+        /*We release if_queued_mutex after again label and before return*/
+#endif
+	if (if_queued > 0)
 	   goto again;
-}
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(pData->if_queued_mutex);
+#endif
+}
Index: trunk/src/VBox/Devices/Network/slirp/mbuf.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/mbuf.c	(revision 13580)
+++ trunk/src/VBox/Devices/Network/slirp/mbuf.c	(revision 13604)
@@ -25,4 +25,9 @@
 	m_usedlist.m_next = m_usedlist.m_prev = &m_usedlist;
         mbuf_alloced = 0;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexCreate(&pData->m_usedlist_mutex);
+        RTSemMutexCreate(&pData->m_freelist_mutex);
+        RTSemMutexCreate(&pData->mbuf_alloced_mutex);
+#endif
 	msize_init(pData);
 }
@@ -52,10 +57,24 @@
 	register struct mbuf *m;
 	int flags = 0;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        int on_free_list = 0;
+#endif
 
 	DEBUG_CALL("m_get");
 
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(pData->m_freelist_mutex, RT_INDEFINITE_WAIT);
+#endif
 	if (m_freelist.m_next == &m_freelist) {
 		m = (struct mbuf *)malloc(msize);
-		if (m == NULL) goto end_error;
+		if (m == NULL) {
+#ifdef VBOX_WITH_SYNC_SLIRP
+                    RTSemMutexRelease(pData->m_freelist_mutex);
+#endif
+                    goto end_error;
+                }
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRequest(pData->mbuf_alloced_mutex, RT_INDEFINITE_WAIT);
+#endif
 		mbuf_alloced++;
 		if (mbuf_alloced > mbuf_thresh)
@@ -63,12 +82,24 @@
 		if (mbuf_alloced > mbuf_max)
 			mbuf_max = mbuf_alloced;
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRelease(pData->mbuf_alloced_mutex);
+#endif
 	} else {
 		m = m_freelist.m_next;
 		remque(pData, m);
 	}
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(pData->m_usedlist_mutex, RT_INDEFINITE_WAIT);
+#endif
 
 	/* Insert it in the used list */
 	insque(pData, m,&m_usedlist);
 	m->m_flags = (flags | M_USEDLIST);
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexCreate(&m->m_mutex);
+        RTSemMutexRequest(m->m_mutex, RT_INDEFINITE_WAIT);
+        RTSemMutexRelease(pData->m_usedlist_mutex);
+        RTSemMutexRelease(pData->m_freelist_mutex);
+#endif
 
 	/* Initialise it */
@@ -78,4 +109,7 @@
 	m->m_nextpkt = 0;
 	m->m_prevpkt = 0;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(m->m_mutex);
+#endif
 end_error:
 	DEBUG_ARG("m = %lx", (long )m);
@@ -92,6 +126,16 @@
   if(m) {
 	/* Remove from m_usedlist */
-	if (m->m_flags & M_USEDLIST)
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(m->m_mutex, RT_INDEFINITE_WAIT);
+#endif
+	if (m->m_flags & M_USEDLIST) {
+#ifdef VBOX_WITH_SYNC_SLIRP
+           RTSemMutexRequest(pData->m_usedlist_mutex, RT_INDEFINITE_WAIT);
+#endif
 	   remque(pData, m);
+#ifdef VBOX_WITH_SYNC_SLIRP
+           RTSemMutexRelease(pData->m_usedlist_mutex);
+#endif
+        }
 
 	/* If it's M_EXT, free() it */
@@ -104,9 +148,24 @@
 	if (m->m_flags & M_DOFREE) {
 		u32ptr_done(pData, ptr_to_u32(pData, m), m);
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRelease(m->m_mutex);
+                RTSemMutexDestroy(m->m_mutex);
+#endif
 		free(m);
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRequest(pData->mbuf_alloced_mutex, RT_INDEFINITE_WAIT);
 		mbuf_alloced--;
+                RTSemMutexRelease(pData->mbuf_alloced_mutex);
+#endif
 	} else if ((m->m_flags & M_FREELIST) == 0) {
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRequest(pData->m_freelist_mutex, RT_INDEFINITE_WAIT);
+#endif
 		insque(pData, m,&m_freelist);
 		m->m_flags = M_FREELIST; /* Clobber other flags */
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRelease(pData->m_freelist_mutex);
+                RTSemMutexRelease(m->m_mutex);
+#endif
 	}
   } /* if(m) */
@@ -124,4 +183,8 @@
 	 * If there's no room, realloc
 	 */
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(m->m_mutex, RT_INDEFINITE_WAIT);
+        RTSemMutexRequest(n->m_mutex, RT_INDEFINITE_WAIT);
+#endif
 	if (M_FREEROOM(m) < n->m_len)
 		m_inc(m,m->m_size+MINCSIZE);
@@ -130,4 +193,8 @@
 	m->m_len += n->m_len;
 
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(m->m_mutex);
+        RTSemMutexRelease(n->m_mutex);
+#endif
 	m_free(pData, n);
 }
@@ -143,5 +210,13 @@
 
 	/* some compiles throw up on gotos.  This one we can fake. */
-        if(m->m_size>size) return;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(m->m_mutex, RT_INDEFINITE_WAIT);
+#endif
+        if(m->m_size>size) {
+#ifdef VBOX_WITH_SYNC_SLIRP
+            RTSemMutexRelease(m->m_mutex);
+#endif
+            return;
+        }
 
         if (m->m_flags & M_EXT) {
@@ -167,5 +242,7 @@
 
         m->m_size = size;
-
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(m->m_mutex);
+#endif
 }
 
@@ -179,4 +256,7 @@
 	if (m == NULL)
 		return;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(m->m_mutex, RT_INDEFINITE_WAIT);
+#endif
 	if (len >= 0) {
 		/* Trim from head */
@@ -188,4 +268,7 @@
 		m->m_len -= len;
 	}
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(m->m_mutex);
+#endif
 }
 
@@ -199,9 +282,22 @@
 	int off, len;
 {
-	if (len > M_FREEROOM(n))
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(m->m_mutex, RT_INDEFINITE_WAIT);
+        RTSemMutexRequest(n->m_mutex, RT_INDEFINITE_WAIT);
+#endif
+	if (len > M_FREEROOM(n)) {
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRelease(n->m_mutex);
+                RTSemMutexRelease(m->m_mutex);
+#endif
 		return -1;
+        }
 
 	memcpy((n->m_data + n->m_len), (m->m_data + off), len);
 	n->m_len += len;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(n->m_mutex);
+        RTSemMutexRelease(m->m_mutex);
+#endif
 	return 0;
 }
@@ -222,12 +318,33 @@
 
 	/* bug corrected for M_EXT buffers */
+#ifndef VBOX_WITH_SYNC_SLIRP
 	for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next) {
+#else
+        RTSemMutexRequest(pData->m_usedlist_mutex, RT_INDEFINITE_WAIT);
+        m = m_usedlist.m_next;
+        while(1) {
+            RTSemMutexRequest(m->m_mutex, RT_INDEFINITE_WAIT);
+            RTSemMutexRelease(pData->m_usedlist_mutex);
+#endif
 	  if (m->m_flags & M_EXT) {
-	    if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) )
+	    if( (char *)dat>=m->m_ext && (char *)dat<(m->m_ext + m->m_size) ) {
+#ifdef VBOX_WITH_SYNC_SLIRP
+              RTSemMutexRelease(m->m_mutex);
+#endif
 	      return m;
+            }
 	  } else {
-	    if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) )
+	    if( (char *)dat >= m->m_dat && (char *)dat<(m->m_dat + m->m_size) ) {
+#ifdef VBOX_WITH_SYNC_SLIRP
+              RTSemMutexRelease(m->m_mutex);
+#endif
 	      return m;
+            }
 	  }
+#ifdef VBOX_WITH_SYNC_SLIRP
+          RTSemMutexRelease(m->m_mutex);
+          RTSemMutexRequest(pData->m_usedlist_mutex, RT_INDEFINITE_WAIT);
+          m = m->m_next;
+#endif
 	}
 
Index: trunk/src/VBox/Devices/Network/slirp/mbuf.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/mbuf.h	(revision 13580)
+++ trunk/src/VBox/Devices/Network/slirp/mbuf.h	(revision 13604)
@@ -37,4 +37,7 @@
 #ifndef _MBUF_H_
 #define _MBUF_H_
+#ifdef VBOX_WITH_SYNC_SLIRP
+#include <iprt/semaphore.h>
+#endif
 
 #define m_freem m_free
@@ -73,4 +76,7 @@
 	caddr_t	mh_data;		/* Location of data */
 	int	mh_len;			/* Amount of data in this mbuf */
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSEMMUTEX mh_mutex;
+#endif
 };
 
@@ -108,4 +114,7 @@
 #define m_ext		M_dat.m_ext_
 #define m_so		m_hdr.mh_so
+#ifdef VBOX_WITH_SYNC_SLIRP
+#define m_mutex		m_hdr.mh_mutex
+#endif
 
 #define ifq_prev m_prev
Index: trunk/src/VBox/Devices/Network/slirp/slirp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 13580)
+++ trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 13604)
@@ -6,4 +6,7 @@
 #include <VBox/err.h>
 #include <iprt/assert.h>
+#ifdef VBOX_WITH_SYNC_SLIRP
+#include <iprt/semaphore.h>
+#endif
 
 static const uint8_t special_ethaddr[6] = {
@@ -200,4 +203,7 @@
 {
     int fNATfailed = 0;
+#ifdef VBOX_WITH_SYNC_SLIRP
+    int rc = 0;
+#endif
     PNATState pData = malloc(sizeof(NATState));
     *ppData = pData;
@@ -222,4 +228,15 @@
         WSAStartup(MAKEWORD(2,0), &Data);
     }
+#endif
+
+#ifdef VBOX_WITH_SYNC_SLIRP
+    rc = RTSemMutexCreate(&pData->tcb_mutex);
+    AssertReleaseRC(rc);
+    rc = RTSemMutexCreate(&pData->udb_mutex);
+    AssertReleaseRC(rc);
+    rc = RTSemMutexCreate(&pData->if_queued_mutex);
+    AssertReleaseRC(rc);
+    rc = RTSemMutexCreate(&pData->next_m_mutex);
+    AssertReleaseRC(rc);
 #endif
 
@@ -358,4 +375,5 @@
 		 * in the fragment queue, or there are TCP connections active
 		 */
+#ifndef VBOX_WITH_SYNC_SLIRP
 		do_slowtimo = ((tcb.so_next != &tcb) ||
 			       ((struct ipasfrag *)&ipq != u32_to_ptr(pData, ipq.next, struct ipasfrag *)));
@@ -363,4 +381,18 @@
 		for (so = tcb.so_next; so != &tcb; so = so_next) {
 			so_next = so->so_next;
+#else
+                RTSemMutexRequest(pData->tcb_mutex, RT_INDEFINITE_WAIT);
+                so = tcb.so_next;
+		do_slowtimo = ((so != &tcb) ||
+			       ((struct ipasfrag *)&ipq != u32_to_ptr(pData, ipq.next, struct ipasfrag *)));
+                while (1) {
+                    if (so == &tcb) {
+                        RTSemMutexRelease(pData->tcb_mutex);
+                        break;
+                    }
+                    so_next = so->so_next;
+                    RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+                    RTSemMutexRelease(pData->tcb_mutex);
+#endif
 
 			/*
@@ -375,5 +407,9 @@
 	 		 */
 			if (so->so_state & SS_NOFDREF || so->s == -1)
-			   continue;
+#ifndef VBOX_WITH_SYNC_SLIRP
+				continue;
+#else
+                                goto before_loop_ends;
+#endif
 
 			/*
@@ -383,5 +419,9 @@
                                 FD_SET(so->s, readfds);
 				UPD_NFDS(so->s);
+#ifndef VBOX_WITH_SYNC_SLIRP
 				continue;
+#else
+                                goto before_loop_ends;
+#endif
 			}
 
@@ -392,5 +432,9 @@
 				FD_SET(so->s, writefds);
 				UPD_NFDS(so->s);
+#ifndef VBOX_WITH_SYNC_SLIRP
 				continue;
+#else
+                                goto before_loop_ends;
+#endif
 			}
 
@@ -413,4 +457,11 @@
 				UPD_NFDS(so->s);
 			}
+#ifdef VBOX_WITH_SYNC_SLIRP
+                before_loop_ends:
+                        /*Release of global tcb mutex happens in the head of loop*/
+                        RTSemMutexRequest(pData->tcb_mutex, RT_INDEFINITE_WAIT);
+                        RTSemMutexRelease(so->so_mutex);
+                        so = so_next;
+#endif
 		}
 
@@ -418,6 +469,19 @@
 		 * UDP sockets
 		 */
+#ifndef VBOX_WITH_SYNC_SLIRP
 		for (so = udb.so_next; so != &udb; so = so_next) {
 			so_next = so->so_next;
+#else
+                RTSemMutexRequest(pData->udb_mutex, RT_INDEFINITE_WAIT);
+                so = udb.so_next;
+                while(1) {
+                    if (so == &udb) {
+                        RTSemMutexRelease(pData->udb_mutex);
+                        break;
+                    }
+                so_next = so->so_next;
+                RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+                RTSemMutexRelease(pData->udb_mutex);
+#endif
 
 			/*
@@ -427,5 +491,9 @@
 				if (so->so_expire <= curtime) {
 					udp_detach(pData, so);
+#ifndef VBOX_WITH_SYNC_SLIRP
 					continue;
+#else
+                                        goto before_udp_loop_end;
+#endif
 				} else
 					do_slowtimo = 1; /* Let socket expire */
@@ -446,4 +514,10 @@
 				UPD_NFDS(so->s);
 			}
+#ifdef VBOX_WITH_SYNC_SLIRP
+                        before_udp_loop_end:
+                        RTSemMutexRequest(pData->udb_mutex, RT_INDEFINITE_WAIT);
+                        RTSemMutexRelease(so->so_mutex);
+                        so = so_next;
+#endif
 		}
 	}
@@ -515,6 +589,19 @@
 		 * Check TCP sockets
 		 */
+#ifndef VBOX_WITH_SYNC_SLIRP
 		for (so = tcb.so_next; so != &tcb; so = so_next) {
 			so_next = so->so_next;
+#else
+                RTSemMutexRequest(pData->tcb_mutex, RT_INDEFINITE_WAIT);
+                so = tcb.so_next;
+                while (1) {
+                    if (so == &tcb) {
+                        RTSemMutexRelease(pData->tcb_mutex);
+                        break;
+                    }
+                so_next = so->so_next;
+                RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+                RTSemMutexRelease(pData->tcb_mutex);
+#endif
 
 			/*
@@ -523,5 +610,9 @@
 			 */
 			if (so->so_state & SS_NOFDREF || so->s == -1)
-			   continue;
+#ifndef VBOX_WITH_SYNC_SLIRP
+				continue;
+#else
+                                goto before_loop_ends;
+#endif
 
 			/*
@@ -541,5 +632,9 @@
 				if (so->so_state & SS_FACCEPTCONN) {
 					tcp_connect(pData, so);
-					continue;
+#ifndef VBOX_WITH_SYNC_SLIRP
+				        continue;
+#else
+                                        goto before_loop_ends;
+#endif
 				} /* else */
 				ret = soread(pData, so);
@@ -573,5 +668,9 @@
 			      if (errno == EAGAIN || errno == EWOULDBLOCK ||
 				  errno == EINPROGRESS || errno == ENOTCONN)
-				continue;
+#ifndef VBOX_WITH_SYNC_SLIRP
+				        continue;
+#else
+                                        goto before_loop_ends;
+#endif
 
 			      /* else failed */
@@ -608,5 +707,9 @@
 			    if (errno == EAGAIN || errno == EWOULDBLOCK ||
 				errno == EINPROGRESS || errno == ENOTCONN)
-			      continue; /* Still connecting, continue */
+#ifndef VBOX_WITH_SYNC_SLIRP
+				        continue;/* Still connecting, continue */
+#else
+                                        goto before_loop_ends;
+#endif
 
 			    /* else failed */
@@ -620,5 +723,9 @@
 			      if (errno == EAGAIN || errno == EWOULDBLOCK ||
 				  errno == EINPROGRESS || errno == ENOTCONN)
-				continue;
+#ifndef VBOX_WITH_SYNC_SLIRP
+				        continue;
+#else
+                                        goto before_loop_ends;
+#endif
 			      /* else failed */
 			      so->so_state = SS_NOFDREF;
@@ -629,4 +736,10 @@
 			  tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);
 			} /* SS_ISFCONNECTING */
+#endif
+#ifdef VBOX_WITH_SYNC_SLIRP
+                    before_loop_ends:
+                    RTSemMutexRequest(pData->tcb_mutex, RT_INDEFINITE_WAIT);
+                    RTSemMutexRelease(so->so_mutex);
+                    so = so_next;
 #endif
 		}
@@ -637,10 +750,28 @@
 		 * Incoming UDP data isn't buffered either.
 		 */
+#ifndef VBOX_WITH_SYNC_SLIRP
 		for (so = udb.so_next; so != &udb; so = so_next) {
 			so_next = so->so_next;
+#else
+                RTSemMutexRequest(pData->udb_mutex, RT_INDEFINITE_WAIT);
+                so = udb.so_next;
+                while(1) {
+                    if (so == &udb) {
+                        RTSemMutexRelease(pData->udb_mutex);
+                        break;
+                    }
+		    so_next = so->so_next;
+                    RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+                    RTSemMutexRelease(pData->udb_mutex);
+#endif
 
 			if (so->s != -1 && FD_ISSET(so->s, readfds)) {
                             sorecvfrom(pData, so);
                         }
+#ifdef VBOX_WITH_SYNC_SLIRP
+                    RTSemMutexRequest(pData->udb_mutex, RT_INDEFINITE_WAIT);
+                    RTSemMutexRelease(so->so_mutex);
+                    so = so_next;
+#endif
 		}
 	}
@@ -649,6 +780,21 @@
 	 * See if we can start outputting
 	 */
+#ifndef VBOX_WITH_SYNC_SLIRP
 	if (if_queued && link_up)
 	   if_start(pData);
+#else
+#if 0
+        if (link_up) {
+            RTSemMutexRequest(pData->if_queued_mutex, RT_INDEFINITE_WAIT);
+            if (if_queued > 0){
+                RTSemMutexRelease(pData->if_queued_mutex);
+	        if_start(pData);
+            }
+            else {
+                RTSemMutexRelease(pData->if_queued_mutex);
+            }
+        }
+#endif
+#endif
 }
 
Index: trunk/src/VBox/Devices/Network/slirp/slirp_state.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp_state.h	(revision 13580)
+++ trunk/src/VBox/Devices/Network/slirp/slirp_state.h	(revision 13604)
@@ -21,4 +21,7 @@
 #ifndef _slirp_state_h_
 #define _slirp_state_h_
+#ifndef VBOX_WITH_SYNC_SLIRP
+#include <iprt/semaphore.h>
+#endif
 
 /** Number of DHCP clients supported by NAT. */
@@ -61,8 +64,20 @@
     int if_maxlinkhdr;
     int if_queued;
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSEMMUTEX  if_queued_mutex;
+#endif
     int if_thresh;
     struct mbuf if_fastq;
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSEMMUTEX  if_fastq_mutex;
+#endif
     struct mbuf if_batchq;
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSEMMUTEX  if_batchq_mutex;
+#endif
     struct mbuf *next_m;
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSEMMUTEX  next_m_mutex;
+#endif
     /* Stuff from icmp.c */
     struct icmpstat_t icmpstat;
@@ -73,6 +88,13 @@
     /* Stuff from mbuf.c */
     int mbuf_alloced, mbuf_max;
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSEMMUTEX  mbuf_alloced_mutex;
+#endif
     int msize;
     struct mbuf m_freelist, m_usedlist;
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSEMMUTEX  m_freelist_mutex;
+    RTSEMMUTEX  m_usedlist_mutex;
+#endif
     /* Stuff from slirp.c */
     void *pvUser;
@@ -98,4 +120,5 @@
     struct socket *tcp_last_so;
     tcp_seq tcp_iss;
+    RTSEMMUTEX tcb_mutex;
 #if ARCH_BITS == 64
     /* Stuff from tcp_subr.c */
@@ -116,4 +139,5 @@
     struct socket udb;
     struct socket *udp_last_so;
+    RTSEMMUTEX udb_mutex;
 } NATState;
 
Index: trunk/src/VBox/Devices/Network/slirp/socket.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 13580)
+++ trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 13604)
@@ -12,4 +12,8 @@
 #ifdef __sun__
 #include <sys/filio.h>
+#endif
+
+#ifdef VBOX_WITH_SYNC_SLIRP
+#include <iprt/semaphore.h>
 #endif
 
@@ -60,4 +64,7 @@
     so->so_state = SS_NOFDREF;
     so->s = -1;
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexCreate(&so->so_mutex);
+#endif
   }
   return(so);
@@ -70,4 +77,5 @@
 sofree(PNATState pData, struct socket *so)
 {
+#ifndef VBOX_WITH_SYNC_SLIRP
   if (so->so_emu==EMU_RSH && so->extra) {
 	sofree(pData, so->extra);
@@ -83,6 +91,51 @@
   if(so->so_next && so->so_prev)
     remque(pData, so);  /* crashes if so is not in a queue */
+#else
+    /*Take global mutexes of udb and tcb, because we dont know which is mutex */
+    /*XXX: don't forget to set correct so_type in corresponded attach operation */
+    RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+    if (so->so_emu==EMU_RSH && so->extra) {
+          sofree(pData, so->extra);
+          so->extra=NULL;
+    }
+
+    if (so->so_type == IPPROTO_UDP) {
+        RTSemMutexRequest(pData->udb_mutex, RT_INDEFINITE_WAIT);
+    }
+    else if (so->so_type == IPPROTO_TCP) {
+        RTSemMutexRequest(pData->tcb_mutex, RT_INDEFINITE_WAIT);
+    }
+    else {
+        Assert(!"unknown type");
+    }
+
+    if (so == tcp_last_so)
+      tcp_last_so = &tcb;
+    else if (so == udp_last_so)
+      udp_last_so = &udb;
+
+    if(so->so_next && so->so_prev)
+      remque(pData, so);  /* crashes if so is not in a queue */
+
+    if (so->so_type == IPPROTO_UDP) {
+        RTSemMutexRelease(pData->udb_mutex);
+    }
+    else if (so->so_type == IPPROTO_TCP) {
+        RTSemMutexRelease(pData->tcb_mutex);
+    }
+    else {
+        Assert(!"unknown type");
+    }
+    /* socket's mutex could be released because socket none accessible via queue anymore*/
+    RTSemMutexRelease(so->so_mutex);
+
+    m_free(pData, so->so_m);
+
+
+    RTSemMutexDestroy(so->so_mutex);
+#endif
 
   free(so);
+  so = NULL;
 }
 
@@ -101,4 +154,7 @@
 	int mss = so->so_tcpcb->t_maxseg;
 
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 	DEBUG_CALL("soread");
 	DEBUG_ARG("so = %lx", (long )so);
@@ -159,10 +215,17 @@
 #endif
 	if (nn <= 0) {
-		if (nn < 0 && (errno == EINTR || errno == EAGAIN))
+		if (nn < 0 && (errno == EINTR || errno == EAGAIN)) {
+#ifdef VBOX_WITH_SYNC_SLIRP
+                        RTSemMutexRelease(so->so_mutex);
+#endif
 			return 0;
+                }
 		else {
 			DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno)));
 			sofcantrcvmore(so);
 			tcp_sockclosed(pData, sototcpcb(so));
+#ifdef VBOX_WITH_SYNC_SLIRP
+                        RTSemMutexRelease(so->so_mutex);
+#endif
 			return -1;
 		}
@@ -194,4 +257,7 @@
 	if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
 		sb->sb_wptr -= sb->sb_datalen;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(so->so_mutex);
+#endif
 	return nn;
 }
@@ -207,4 +273,7 @@
 sorecvoob(PNATState pData, struct socket *so)
 {
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 	struct tcpcb *tp = sototcpcb(so);
 
@@ -225,4 +294,7 @@
 	tcp_output(pData, tp);
 	tp->t_force = 0;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(so->so_mutex);
+#endif
 }
 
@@ -239,4 +311,7 @@
 
 	int n, len;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 
 	DEBUG_CALL("sosendoob");
@@ -283,4 +358,7 @@
 		sb->sb_rptr -= sb->sb_datalen;
 
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(so->so_mutex);
+#endif
 	return n;
 }
@@ -297,4 +375,7 @@
 	int len = sb->sb_cc;
 	struct iovec iov[2];
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 
 	DEBUG_CALL("sowrite");
@@ -344,6 +425,10 @@
 #endif
 	/* This should never happen, but people tell me it does *shrug* */
-	if (nn < 0 && (errno == EAGAIN || errno == EINTR))
+	if (nn < 0 && (errno == EAGAIN || errno == EINTR)) {
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRelease(so->so_mutex);
+#endif
 		return 0;
+        }
 
 	if (nn <= 0) {
@@ -352,4 +437,7 @@
 		sofcantsendmore(so);
 		tcp_sockclosed(pData, sototcpcb(so));
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRelease(so->so_mutex);
+#endif
 		return -1;
 	}
@@ -378,4 +466,7 @@
 		sofcantsendmore(so);
 
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(so->so_mutex);
+#endif
 	return nn;
 }
@@ -392,4 +483,8 @@
 	DEBUG_CALL("sorecvfrom");
 	DEBUG_ARG("so = %lx", (long)so);
+
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 
 	if (so->so_type == IPPROTO_ICMP) {   /* This is a "ping" reply */
@@ -478,4 +573,7 @@
 	  } /* rx error */
 	} /* if ping packet */
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(so->so_mutex);
+#endif
 }
 
@@ -490,4 +588,7 @@
 #if 0
         struct sockaddr_in host_addr;
+#endif
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
 #endif
 
@@ -542,6 +643,10 @@
 	ret = sendto(so->s, m->m_data, m->m_len, 0,
 		     (struct sockaddr *)&addr, sizeof (struct sockaddr));
-	if (ret < 0)
+	if (ret < 0) {
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRelease(so->so_mutex);
+#endif
 		return -1;
+        }
 
 	/*
@@ -552,4 +657,7 @@
 		so->so_expire = curtime + SO_EXPIRE;
 	so->so_state = SS_ISFCONNECTED; /* So that it gets select()ed */
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRelease(so->so_mutex);
+#endif
 	return 0;
 }
@@ -582,5 +690,13 @@
 		return NULL;
 	}
+#ifndef VBOX_WITH_SYNC_SLIRP
 	insque(pData, so,&tcb);
+#else
+        RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+        /*after adding to global queue probably we should keep lock*/
+        RTSemMutexRequest(pData->tcb_mutex, RT_INDEFINITE_WAIT);
+	insque(pData, so,&tcb);
+        RTSemMutexRelease(pData->tcb_mutex);
+#endif
 
 	/*
@@ -627,4 +743,7 @@
 
 	so->s = s;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        RTSemMutexRelease(so->so_mutex);
+#endif
 	return so;
 }
@@ -665,7 +784,13 @@
 	register struct socket *so;
 {
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 	so->so_state &= ~(SS_NOFDREF|SS_ISFCONNECTED|SS_FCANTRCVMORE|
 			  SS_FCANTSENDMORE|SS_FWDRAIN);
 	so->so_state |= SS_ISFCONNECTING; /* Clobber other states */
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexRelease(so->so_mutex);
+#endif
 }
 
@@ -674,6 +799,12 @@
         register struct socket *so;
 {
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 	so->so_state &= ~(SS_ISFCONNECTING|SS_FWDRAIN|SS_NOFDREF);
 	so->so_state |= SS_ISFCONNECTED; /* Clobber other states */
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexRelease(so->so_mutex);
+#endif
 }
 
@@ -682,4 +813,7 @@
 	struct  socket *so;
 {
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 	if ((so->so_state & SS_NOFDREF) == 0) {
 		shutdown(so->s,0);
@@ -690,4 +824,7 @@
 	else
 	   so->so_state |= SS_FCANTRCVMORE;
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexRelease(so->so_mutex);
+#endif
 }
 
@@ -696,4 +833,7 @@
 	struct socket *so;
 {
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 	if ((so->so_state & SS_NOFDREF) == 0) {
             shutdown(so->s,1);           /* send FIN to fhost */
@@ -704,4 +844,7 @@
 	else
 	   so->so_state |= SS_FCANTSENDMORE;
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexRelease(so->so_mutex);
+#endif
 }
 
@@ -726,8 +869,14 @@
 	struct socket *so;
 {
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 	if (so->so_rcv.sb_cc)
 		so->so_state |= SS_FWDRAIN;
 	else
 		sofcantsendmore(so);
-}
-
+#ifdef VBOX_WITH_SYNC_SLIRP
+    RTSemMutexRelease(so->so_mutex);
+#endif
+}
+
Index: trunk/src/VBox/Devices/Network/slirp/socket.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/socket.h	(revision 13580)
+++ trunk/src/VBox/Devices/Network/slirp/socket.h	(revision 13604)
@@ -10,4 +10,7 @@
 #ifndef _SLIRP_SOCKET_H_
 #define _SLIRP_SOCKET_H_
+#ifndef VBOX_WITH_SYNC_SLIRP
+#include <iprt/semaphore.h>
+#endif
 
 #define SO_EXPIRE 240000
@@ -52,4 +55,5 @@
   struct sbuf so_snd;		/* Send buffer */
   void * extra;			/* Extra pointer */
+  RTSEMMUTEX so_mutex;          /*per socket mutex*/
 };
 
Index: trunk/src/VBox/Devices/Network/slirp/tcp_subr.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/tcp_subr.c	(revision 13580)
+++ trunk/src/VBox/Devices/Network/slirp/tcp_subr.c	(revision 13604)
@@ -262,4 +262,8 @@
 	DEBUG_CALL("tcp_close");
 	DEBUG_ARG("tp = %lx", (long )tp);
+#ifdef VBOX_WITH_SYNC_SLIRP
+        /*sofree destrys so_mutex*/
+        RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+#endif
 
 	/* free the reassembly queue, if any */
@@ -528,6 +532,9 @@
 	if ((so->so_tcpcb = tcp_newtcpcb(pData, so)) == NULL)
 	   return -1;
-
+        so->so_type = IPPROTO_TCP;
+
+        RTSemMutexRequest(pData->tcb_mutex, RT_INDEFINITE_WAIT);
 	insque(pData, so, &tcb);
+        RTSemMutexRelease(pData->tcb_mutex);
 
 	return 0;
Index: trunk/src/VBox/Devices/Network/slirp/tcp_timer.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/tcp_timer.c	(revision 13580)
+++ trunk/src/VBox/Devices/Network/slirp/tcp_timer.c	(revision 13604)
@@ -46,10 +46,26 @@
 	register struct socket *so;
 	register struct tcpcb *tp;
+#ifdef VBOX_WITH_SYNC_SLIRP
+        struct socket *so_next;
+#endif
 
 	DEBUG_CALL("tcp_fasttimo");
 
+#ifndef VBOX_WITH_SYNC_SLIRP
 	so = tcb.so_next;
 	if (so)
 	for (; so != &tcb; so = so->so_next)
+#else
+        RTSemMutexRequest(pData->tcb_mutex, RT_INDEFINITE_WAIT);
+        so = tcb.so_next;
+        while(1) {
+            if ( so == &tcb) {
+                RTSemMutexRelease(pData->tcb_mutex);
+                break;
+            }
+            so_next = so->so_next;
+            RTSemMutexRequest(so->so_mutex, RT_INDEFINITE_WAIT);
+            RTSemMutexRelease(pData->tcb_mutex);
+#endif
 		if ((tp = (struct tcpcb *)so->so_tcpcb) &&
 		    (tp->t_flags & TF_DELACK)) {
@@ -59,4 +75,11 @@
 			(void) tcp_output(pData, tp);
 		}
+#ifdef VBOX_WITH_SYNC_SLIRP
+                RTSemMutexRequest(pData->tcb_mutex, RT_INDEFINITE_WAIT);
+                RTSemMutexRelease(so->so_mutex);
+                so = so_next;
+        }
+#endif
+
 }
 
@@ -78,12 +101,33 @@
 	 * Search through tcb's and update active timers.
 	 */
+#ifndef VBOX_WITH_SYNC_SLIRP
 	ip = tcb.so_next;
 	if (ip == 0)
 	   return;
 	for (; ip != &tcb; ip = ipnxt) {
+#else
+        RTSemMutexRequest(pData->tcb_mutex, RT_INDEFINITE_WAIT);
+        ip = tcb.so_next;
+        if (ip == NULL) {
+            RTSemMutexRelease(pData->tcb_mutex);
+            return;
+        }
+        while (1) {
+                if (ip == &tcb) {
+                    RTSemMutexRelease(pData->tcb_mutex);
+                    break;
+                }
+                ipnxt = ip->so_next;
+                RTSemMutexRequest(ip->so_mutex, RT_INDEFINITE_WAIT);
+                RTSemMutexRelease(pData->tcb_mutex);
+#endif
 		ipnxt = ip->so_next;
 		tp = sototcpcb(ip);
 		if (tp == 0)
+#ifndef VBOX_WITH_SYNC_SLIRP
 			continue;
+#else
+                        goto before_loop_ends;
+#endif
 		for (i = 0; i < TCPT_NTIMERS; i++) {
 			if (tp->t_timer[i] && --tp->t_timer[i] == 0) {
@@ -98,4 +142,10 @@
 tpgone:
 		;
+#ifdef VBOX_WITH_SYNC_SLIRP
+before_loop_ends:
+                RTSemMutexRequest(pData->tcb_mutex, RT_INDEFINITE_WAIT);
+                RTSemMutexRelease(ip->so_mutex);
+                ip=ipnxt;
+#endif
 	}
 	tcp_iss += TCP_ISSINCR/PR_SLOWHZ;		/* increment iss */
Index: trunk/src/VBox/Devices/Network/slirp/udp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/udp.c	(revision 13580)
+++ trunk/src/VBox/Devices/Network/slirp/udp.c	(revision 13604)
@@ -351,4 +351,7 @@
     }
   }
+#ifdef VBOX_WITH_SYNC_SLIRP
+  so->so_type = IPPROTO_UDP;
+#endif
   return(so->s);
 }
