Index: trunk/src/VBox/Devices/Network/DrvNAT.cpp
===================================================================
--- trunk/src/VBox/Devices/Network/DrvNAT.cpp	(revision 16571)
+++ trunk/src/VBox/Devices/Network/DrvNAT.cpp	(revision 16572)
@@ -43,4 +43,5 @@
 # ifndef RT_OS_WINDOWS
 #  include <unistd.h>
+#  include <poll.h>
 # endif
 # include <errno.h>
@@ -148,5 +149,5 @@
     Log2(("drvNATSend: pvBuf=%p cb=%#x\n%.*Rhxd\n", pvBuf, cb, cb, pvBuf));
 
-#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC 
+#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
 
     PRTREQ pReq = NULL;
@@ -164,5 +165,5 @@
 
     /* @todo: Here we should get mbuf instead temporal buffer */
-    buf = RTMemAlloc(cb); 
+    buf = RTMemAlloc(cb);
     if (buf == NULL)
     {
@@ -348,4 +349,6 @@
     HANDLE  *phEvents;
     unsigned int cBreak = 0;
+# else
+    struct pollfd *polls;
 # endif
 
@@ -364,7 +367,4 @@
     while (pThread->enmState == PDMTHREADSTATE_RUNNING)
     {
-        FD_ZERO(&ReadFDs);
-        FD_ZERO(&WriteFDs);
-        FD_ZERO(&XcptFDs);
         nFDs = -1;
 
@@ -372,15 +372,23 @@
          * To prevent concurent execution of sending/receving threads
          */
-        slirp_select_fill(pThis->pNATState, &nFDs, &ReadFDs, &WriteFDs, &XcptFDs);
+# ifndef RT_OS_WINDOWS
+        nFDs = slirp_get_nsock(pThis->pNATState);
+        polls = (struct pollfd *)RTMemAllocZ((2 + nFDs) * sizeof(struct pollfd)); /* allocation for all sockets + ICMP and Management pipe*/
+        if (polls == NULL)
+        {
+            LogRel(("Can't allocate memory for polling\n"));
+            AssertRelease(polls);
+        }
+
+        slirp_select_fill(pThis->pNATState, &nFDs, &polls[1]); /*don't bother Slirp with knowelege about managemant pipe*/
         ms = slirp_get_timeout_ms(pThis->pNATState);
-# ifndef RT_OS_WINDOWS
-        struct timeval tv = { 0, ms*1000 };
-        FD_SET(pThis->PipeRead, &ReadFDs);
-        nFDs = ((int)pThis->PipeRead < nFDs ? nFDs : pThis->PipeRead);
-        int cChangedFDs = select(nFDs + 1, &ReadFDs, &WriteFDs, &XcptFDs, ms ? &tv : NULL);
+
+        polls[0].fd = pThis->PipeRead;
+        polls[0].events = POLLRDNORM|POLLPRI|POLLRDBAND; /* POLLRDBAND usually doesn't used on Linux but seems used on Solaris */
+        int cChangedFDs = poll(polls, nFDs + 2, ms ? ms : -1);
         if (cChangedFDs >= 0)
         {
-            slirp_select_poll(pThis->pNATState, &ReadFDs, &WriteFDs, &XcptFDs);
-            if (FD_ISSET(pThis->PipeRead, &ReadFDs))
+            slirp_select_poll(pThis->pNATState, &polls[1], nFDs);
+            if (polls[0].revents & (POLLRDNORM|POLLPRI|POLLRDBAND))
             {
                 /* drain the pipe */
@@ -392,5 +400,9 @@
             RTReqProcess(pThis->pReqQueue, 0);
         }
+        RTMemFree(polls);
 # else /* RT_OS_WINDOWS */
+        slirp_select_fill(pThis->pNATState, &nFDs);
+        ms = slirp_get_timeout_ms(pThis->pNATState);
+        struct timeval tv = { 0, ms*1000 };
         event = WSAWaitForMultipleEvents(nFDs, phEvents, FALSE, ms ? ms : WSA_INFINITE, FALSE);
         if (   (event < WSA_WAIT_EVENT_0 || event > WSA_WAIT_EVENT_0 + nFDs - 1)
@@ -452,5 +464,5 @@
 
 #ifdef VBOX_WITH_SLIRP_MT
-static DECLCALLBACK(int) drvNATAsyncIoGuest(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 
+static DECLCALLBACK(int) drvNATAsyncIoGuest(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
 {
     PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
Index: trunk/src/VBox/Devices/Network/slirp/libslirp.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/libslirp.h	(revision 16571)
+++ trunk/src/VBox/Devices/Network/slirp/libslirp.h	(revision 16572)
@@ -16,4 +16,5 @@
 # endif
 # include <sys/select.h>
+# include <poll.h>
 # include <arpa/inet.h>
 #endif
@@ -33,12 +34,20 @@
 void slirp_link_down(PNATState);
 
+#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC)
+# if defined(RT_OS_WINDOWS)
+void slirp_select_fill(PNATState pData, int *pndfs);
+
+void slirp_select_poll(PNATState pData, int fTimeout, int fIcmp);
+# else /* RT_OS_WINDOWS */
+void slirp_select_fill(PNATState pData, int *pnfds, struct pollfd *polls);
+void slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs);
+# endif /* !RT_OS_WINDOWS */
+#else /* VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
 void slirp_select_fill(PNATState pData, int *pnfds,
                        fd_set *readfds, fd_set *writefds, fd_set *xfds);
 
-#if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC)
-void slirp_select_poll(PNATState pData, int fTimeout, int fIcmp);
-#else
-void slirp_select_poll(PNATState pData, fd_set *readfds, fd_set *writefds, fd_set *xfds);
-#endif
+void slirp_select_poll(PNATState pData, int *pnfds,
+                       fd_set *readfds, fd_set *writefds, fd_set *xfds);
+#endif /* !VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
 
 void slirp_input(PNATState pData, const uint8_t *pkt, int pkt_len);
Index: trunk/src/VBox/Devices/Network/slirp/slirp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 16571)
+++ trunk/src/VBox/Devices/Network/slirp/slirp.c	(revision 16572)
@@ -7,8 +7,10 @@
 #include <VBox/pdmdrv.h>
 #include <iprt/assert.h>
+#include <poll.h>
 
 #if !defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) || !defined(RT_OS_WINDOWS)
 
-# define DO_ENGAGE_EVENT1(so, fdset, label)          \
+# ifndef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
+#  define DO_ENGAGE_EVENT1(so, fdset, label)          \
     do {                                             \
         FD_SET((so)->s, (fdset));                    \
@@ -17,5 +19,5 @@
 
 
-# define DO_ENGAGE_EVENT2(so, fdset1, fdset2, label) \
+#  define DO_ENGAGE_EVENT2(so, fdset1, fdset2, label) \
     do {                                             \
         FD_SET((so)->s, (fdset1));                   \
@@ -24,15 +26,51 @@
     } while(0)
 
-# define DO_POLL_EVENTS(rc, error, so, events, label) do {} while (0)
-
-# define DO_CHECK_FD_SET(so, events, fdset) (FD_ISSET((so)->s, (fdset)))
-
-# define DO_WIN_CHECK_FD_SET(so, events, fdset ) 0 /* specific for Windows Winsock API */
-
+#  define DO_POLL_EVENTS(rc, error, so, events, label) do {} while (0)
+
+#  define DO_CHECK_FD_SET(so, events, fdset) (FD_ISSET((so)->s, fdset))
+# else /* !VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
+#  define DO_ENGAGE_EVENT1(so, fdset, label)            \
+    do {                                                \
+        polls[poll_index].fd = (so)->s;                 \
+        (so)->so_poll_index = poll_index;               \
+        polls[poll_index].events = N_(fdset ## _poll);  \
+        poll_index++;                                   \
+    } while(0)
+
+
+#  define DO_ENGAGE_EVENT2(so, fdset1, fdset2, label)                           \
+    do {                                                                        \
+        polls[poll_index].fd = (so)->s;                                         \
+        (so)->so_poll_index = poll_index;                                       \
+        polls[poll_index].events = N_(fdset1 ## _poll) | N_(fdset1 ## _poll);   \
+        poll_index++;                                                           \
+    } while(0)
+
+#  define DO_POLL_EVENTS(rc, error, so, events, label) do {} while (0)
+
+#  define DO_CHECK_FD_SET(so, events, fdset) (  ((so)->so_poll_index != -1)                     \
+                                                && ((so)->so_poll_index <= ndfs)                \
+                                                && ((so)->s == polls[so->so_poll_index].fd)     \
+                                                && (polls[(so)->so_poll_index].revents          \
+                                                && N_(fdset ## _poll)))
+# endif /* VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
+
+#  define DO_WIN_CHECK_FD_SET(so, events, fdset ) 0 /* specific for Windows Winsock API */
 # ifndef RT_OS_WINDOWS
+
+#  ifndef RT_OS_LINUX
+#   define readfds_poll (POLLRDNORM)
+#   define writefds_poll (POLLWRNORM)
+#   define xfds_poll (POLLRDBAND|POLLWRBAND|POLLPRI)
+#  else
+#   define readfds_poll (POLLIN)
+#   define writefds_poll (POLLOUT)
+#   define xfds_poll (POLLPRI)
+#  endif
+
 #  define ICMP_ENGAGE_EVENT(so, fdset)               \
     do {                                             \
         if (pData->icmp_socket.s != -1)              \
-            DO_ENGAGE_EVENT1((so), (fdset), ICMP);   \
+            DO_ENGAGE_EVENT1((so), fdset, ICMP);   \
     } while (0)
 # else /* !RT_OS_WINDOWS */
@@ -93,11 +131,11 @@
 
 #define TCP_ENGAGE_EVENT1(so, fdset) \
-    DO_ENGAGE_EVENT1((so), (fdset), tcp)
+    DO_ENGAGE_EVENT1((so), fdset, tcp)
 
 #define TCP_ENGAGE_EVENT2(so, fdset1, fdset2) \
-    DO_ENGAGE_EVENT2((so), (fdset1), (fdset2), tcp)
+    DO_ENGAGE_EVENT2((so), fdset1, fdset2, tcp)
 
 #define UDP_ENGAGE_EVENT(so, fdset) \
-    DO_ENGAGE_EVENT1((so), (fdset), udp)
+    DO_ENGAGE_EVENT1((so), fdset, udp)
 
 #define POLL_TCP_EVENTS(rc, error, so, events) \
@@ -570,6 +608,14 @@
 #endif
 
+#ifndef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
 void slirp_select_fill(PNATState pData, int *pnfds,
                        fd_set *readfds, fd_set *writefds, fd_set *xfds)
+#else /* !VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
+# ifdef RT_OS_WINDOWS
+void slirp_select_fill(PNATState pData, int *pnfds)
+# else /* RT_OS_WINDOWS */
+void slirp_select_fill(PNATState pData, int *pnfds, struct pollfd *polls)
+# endif /* !RT_OS_WINDOWS */
+#endif /* VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
 {
     struct socket *so, *so_next;
@@ -578,4 +624,7 @@
     int rc;
     int error;
+#endif
+#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && !defined(RT_OS_WINDOWS)
+    int poll_index = 0;
 #endif
     int i;
@@ -725,18 +774,26 @@
     }
 
-#if !defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) || !defined(RT_OS_WINDOWS)
+#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC)
+# if defined(RT_OS_WINDOWS)
+    *pnfds = VBOX_EVENT_COUNT;
+# else /* RT_OS_WINDOWS */
+    *pnfds = poll_index;
+# endif /* !RT_OS_WINDOWS */
+#else /* VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
     *pnfds = nfds;
-#else
-    *pnfds = VBOX_EVENT_COUNT;
-#endif
+#endif /* !VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
 
     STAM_PROFILE_STOP(&pData->StatFill, a);
 }
 
-#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && defined(RT_OS_WINDOWS)
+#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC)
+# if defined(RT_OS_WINDOWS)
 void slirp_select_poll(PNATState pData, int fTimeout, int fIcmp)
-#else
+# else /* RT_OS_WINDOWS */
+void slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs)
+# endif /* !RT_OS_WINDOWS */
+#else /* VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
 void slirp_select_poll(PNATState pData, fd_set *readfds, fd_set *writefds, fd_set *xfds)
-#endif
+#endif /* !VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
 {
     struct socket *so, *so_next;
@@ -746,4 +803,7 @@
     int rc;
     int error;
+#endif
+#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && !defined(RT_OS_WINDOWS)
+    int poll_index = 0;
 #endif
 
@@ -791,5 +851,6 @@
             sorecvfrom(pData, &pData->icmp_socket);
 #else
-        if (pData->icmp_socket.s != -1 && FD_ISSET(pData->icmp_socket.s, readfds))
+        if (   (pData->icmp_socket.s != -1)
+            && CHECK_FD_SET(&pData->icmp_socket, ignored, readfds))
             sorecvfrom(pData, &pData->icmp_socket);
 #endif
Index: trunk/src/VBox/Devices/Network/slirp/socket.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/socket.h	(revision 16571)
+++ trunk/src/VBox/Devices/Network/slirp/socket.h	(revision 16572)
@@ -70,4 +70,7 @@
     RTCRITSECT      so_mutex;
     int             so_deleted;
+#endif
+#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && !defined(RT_OS_WINDOWS)
+    int so_poll_index;
 #endif
 };
