Index: trunk/src/VBox/Devices/USB/solaris/USBProxyDevice-solaris.cpp
===================================================================
--- trunk/src/VBox/Devices/USB/solaris/USBProxyDevice-solaris.cpp	(revision 47497)
+++ trunk/src/VBox/Devices/USB/solaris/USBProxyDevice-solaris.cpp	(revision 49814)
@@ -38,4 +38,5 @@
 #include <iprt/file.h>
 #include <iprt/mem.h>
+#include <iprt/pipe.h>
 #include "../USBProxyDevice.h"
 #include <VBox/usblib.h>
@@ -91,4 +92,8 @@
     /** The tail of the landed solaris URBs. */
     PUSBPROXYURBSOL                pTaxingTail;
+    /** Pipe handle for waiking up - writing end. */
+    RTPIPE                         hPipeWakeupW;
+    /** Pipe handle for waiking up - reading end. */
+    RTPIPE                         hPipeWakeupR;
 } USBPROXYDEVSOL, *PUSBPROXYDEVSOL;
 
@@ -309,65 +314,74 @@
                     pProxyDev->Backend.pv = pDevSol;
 
-                    int Instance;
-                    char *pszDevicePath = NULL;
-                    rc = USBLibGetClientInfo(szDeviceIdent, &pszDevicePath, &Instance);
+                    /*
+                     * Create wakeup pipe.
+                     */
+                    rc = RTPipeCreate(&pDevLnx->hPipeWakeupR, &pDevLnx->hPipeWakeupW, 0);
                     if (RT_SUCCESS(rc))
                     {
-                        pDevSol->pszDevicePath = pszDevicePath;
-
-                        /*
-                         * Open the client driver.
-                         */
-                        RTFILE hFile;
-                        rc = RTFileOpen(&hFile, pDevSol->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
+                        int Instance;
+                        char *pszDevicePath = NULL;
+                        rc = USBLibGetClientInfo(szDeviceIdent, &pszDevicePath, &Instance);
                         if (RT_SUCCESS(rc))
                         {
-                            pDevSol->hFile = hFile;
-                            pDevSol->pProxyDev = pProxyDev;
+                            pDevSol->pszDevicePath = pszDevicePath;
 
                             /*
-                             * Verify client driver version.
+                             * Open the client driver.
                              */
-                            VBOXUSBREQ_GET_VERSION GetVersionReq;
-                            bzero(&GetVersionReq, sizeof(GetVersionReq));
-                            rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_GET_VERSION, &GetVersionReq, sizeof(GetVersionReq));
+                            RTFILE hFile;
+                            rc = RTFileOpen(&hFile, pDevSol->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
                             if (RT_SUCCESS(rc))
                             {
-                                if (   GetVersionReq.u32Major == VBOXUSB_VERSION_MAJOR
-                                    && GetVersionReq.u32Minor >= VBOXUSB_VERSION_MINOR)
+                                pDevSol->hFile = hFile;
+                                pDevSol->pProxyDev = pProxyDev;
+
+                                /*
+                                 * Verify client driver version.
+                                 */
+                                VBOXUSBREQ_GET_VERSION GetVersionReq;
+                                bzero(&GetVersionReq, sizeof(GetVersionReq));
+                                rc = usbProxySolarisIOCtl(pDevSol, VBOXUSB_IOCTL_GET_VERSION, &GetVersionReq, sizeof(GetVersionReq));
+                                if (RT_SUCCESS(rc))
                                 {
-                                    /*
-                                     * Try & get the current cached config from Solaris.
-                                     */
-                                    usbProxySolarisGetActiveConfig(pDevSol);
-                                    return VINF_SUCCESS;
+                                    if (   GetVersionReq.u32Major == VBOXUSB_VERSION_MAJOR
+                                        && GetVersionReq.u32Minor >= VBOXUSB_VERSION_MINOR)
+                                    {
+                                        /*
+                                         * Try & get the current cached config from Solaris.
+                                         */
+                                        usbProxySolarisGetActiveConfig(pDevSol);
+                                        return VINF_SUCCESS;
+                                    }
+                                    else
+                                    {
+                                        LogRel((USBPROXY ":version mismatch! driver v%d.%d expecting ~v%d.%d\n", GetVersionReq.u32Major,
+                                                GetVersionReq.u32Minor, VBOXUSB_VERSION_MAJOR, VBOXUSB_VERSION_MINOR));
+                                        rc = VERR_VERSION_MISMATCH;
+                                    }
                                 }
                                 else
                                 {
-                                    LogRel((USBPROXY ":version mismatch! driver v%d.%d expecting ~v%d.%d\n", GetVersionReq.u32Major,
-                                            GetVersionReq.u32Minor, VBOXUSB_VERSION_MAJOR, VBOXUSB_VERSION_MINOR));
-                                    rc = VERR_VERSION_MISMATCH;
+                                    LogRel((USBPROXY ":failed to query driver version. rc=%Rrc\n", rc));
                                 }
+
+                                RTFileClose(pDevSol->hFile);
+                                pDevSol->hFile = NIL_RTFILE;
+                                pDevSol->pProxyDev = NULL;
                             }
                             else
-                            {
-                                LogRel((USBPROXY ":failed to query driver version. rc=%Rrc\n", rc));
-                            }
-
-                            RTFileClose(pDevSol->hFile);
-                            pDevSol->hFile = NIL_RTFILE;
-                            pDevSol->pProxyDev = NULL;
+                                LogRel((USBPROXY ":failed to open device. rc=%Rrc pszDevicePath=%s\n", rc, pDevSol->pszDevicePath));
+
+                            RTStrFree(pDevSol->pszDevicePath);
+                            pDevSol->pszDevicePath = NULL;
                         }
                         else
-                            LogRel((USBPROXY ":failed to open device. rc=%Rrc pszDevicePath=%s\n", rc, pDevSol->pszDevicePath));
-
-                        RTStrFree(pDevSol->pszDevicePath);
-                        pDevSol->pszDevicePath = NULL;
-                    }
-                    else
-                    {
-                        LogRel((USBPROXY ":failed to get client info. rc=%Rrc pszDevicePath=%s\n", rc, pDevSol->pszDevicePath));
-                        if (rc == VERR_NOT_FOUND)
-                            rc = VERR_OPEN_FAILED;
+                        {
+                            LogRel((USBPROXY ":failed to get client info. rc=%Rrc pszDevicePath=%s\n", rc, pDevSol->pszDevicePath));
+                            if (rc == VERR_NOT_FOUND)
+                                rc = VERR_OPEN_FAILED;
+                        }
+                        RTPipeClose(pDevLnx->hPipeWakeupR);
+                        RTPipeClose(pDevLnx->hPipeWakeupW);
                     }
 
@@ -431,4 +445,7 @@
         RTMemFree(pUrbSol);
     }
+
+    RTPipeClose(pDevLnx->hPipeWakeupR);
+    RTPipeClose(pDevLnx->hPipeWakeupW);
 
     RTStrFree(pDevSol->pszDevicePath);
@@ -703,12 +720,19 @@
         for (;;)
         {
-            struct pollfd pfd;
-            pfd.fd = RTFileToNative(pDevSol->hFile);
-            pfd.events = POLLIN;
-            pfd.revents = 0;
-            int rc = poll(&pfd, 1, cMillies);
+            int cMilliesWait = cMillies == RT_INDEFINITE_WAIT ? -1 : cMillies;
+            struct pollfd pfd[2];
+
+            pfd[0].fd = RTFileToNative(pDevSol->hFile);
+            pfd[0].events = POLLIN;
+            pfd[0].revents = 0;
+
+            pfd[1].fd = RTPipeToNative(pDevSol->hWakeupPipeR);
+            pfd[1].events = POLLIN;
+            pfd[1].revents = 0;
+
+            int rc = poll(&pfd, 2, cMilliesWait);
             if (rc > 0)
             {
-                if (pfd.revents & POLLHUP)
+                if (pfd[0].revents & POLLHUP)
                 {
                     LogRel((USBPROXY ":Reaping failed, USB Device '%s' disconnected!\n", pDevSol->pProxyDev->pUsbIns->pszName));
@@ -716,4 +740,21 @@
                     usbProxySolarisCloseFile(pDevSol);
                 }
+
+                if (pfd[1].revents & POLLIN)
+                {
+                    /* Got woken up, drain pipe. */
+                    uint8_t bRead;
+                    size_t cbIgnored = 0;
+                    RTPipeRead(pDevLnx->hPipeWakeupR, &bRead, 1, &cbIgnored);
+
+                    /*
+                     * It is possible that we got woken up and have an URB pending
+                     * for completion. Do it on the way out. Otherwise return
+                     * immediately to the caller.
+                     */
+                    if (!(pfd[0].revents & POLLIN))
+                        return NULL;
+                }
+
                 break;
             }
@@ -852,4 +893,14 @@
 
 
+static DECLCALLBACK(int) usbProxySolarisWakeup(PUSBPROXYDEV pProxyDev)
+{
+    PUSBPROXYDEVSOL pDevSol = (PUSBPROXYDEVSOL)pProxyDev->Backend.pv;
+    size_t cbIgnored;
+
+    LogFlowFunc(("pProxyDev=%p\n", pProxyDev));
+
+    return RTPipeWrite(pDevSol->hPipeWakeupW, "", 1, &cbIgnored);
+}
+
 
 /**
@@ -871,4 +922,5 @@
     usbProxySolarisUrbCancel,
     usbProxySolarisUrbReap,
+    usbProxySolarisWakeup,
     0
 };
