Index: /trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h
===================================================================
--- /trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h	(revision 35204)
+++ /trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h	(revision 35205)
@@ -167,8 +167,9 @@
     /** Size of the array. */
     unsigned                               cReqEntries;
-    /** Flag whether at least one endpoint reached its bandwidth limit. */
-    bool                                   fBwLimitReached;
     /** Memory cache for file range locks. */
     RTMEMCACHE                             hMemCacheRangeLocks;
+    /** Number of milliseconds to wait until the bandwidth is refreshed for at least
+     * one endpoint and it is possible to process more requests. */
+    RTMSINTERVAL                           msBwLimitExpired;
     /** Critical section protecting the blocking event handling. */
     RTCRITSECT                             CritSectBlockingEvent;
Index: /trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp
===================================================================
--- /trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp	(revision 35204)
+++ /trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp	(revision 35205)
@@ -59,7 +59,8 @@
     {
         /* Initialize request handle array. */
-        pAioMgr->iFreeEntry = 0;
-        pAioMgr->cReqEntries    = pAioMgr->cRequestsActiveMax;
-        pAioMgr->pahReqsFree    = (RTFILEAIOREQ *)RTMemAllocZ(pAioMgr->cReqEntries * sizeof(RTFILEAIOREQ));
+        pAioMgr->iFreeEntry       = 0;
+        pAioMgr->cReqEntries      = pAioMgr->cRequestsActiveMax;
+        pAioMgr->pahReqsFree      = (RTFILEAIOREQ *)RTMemAllocZ(pAioMgr->cReqEntries * sizeof(RTFILEAIOREQ));
+        pAioMgr->msBwLimitExpired = RT_INDEFINITE_WAIT;
 
         if (pAioMgr->pahReqsFree)
@@ -979,5 +980,5 @@
         if (!pdmacEpIsTransferAllowed(&pEndpoint->Core, (uint32_t)pCurr->DataSeg.cbSeg, &msWhenNext))
         {
-            pAioMgr->fBwLimitReached = true;
+            pAioMgr->msBwLimitExpired = RT_MIN(pAioMgr->msBwLimitExpired, msWhenNext);
             break;
         }
@@ -1090,6 +1091,5 @@
 
         if (RT_UNLIKELY(   pAioMgr->cRequestsActiveMax == pAioMgr->cRequestsActive
-                        && !pEndpoint->pFlushReq
-                        && !pAioMgr->fBwLimitReached))
+                        && !pEndpoint->pFlushReq))
         {
 #if 0
@@ -1273,5 +1273,5 @@
     PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint = pAioMgr->pEndpointsHead;
 
-    pAioMgr->fBwLimitReached = false;
+    pAioMgr->msBwLimitExpired = RT_INDEFINITE_WAIT;
 
     while (pEndpoint)
@@ -1604,7 +1604,7 @@
             ASMAtomicWriteBool(&pAioMgr->fWaitingEventSem, true);
             if (!ASMAtomicReadBool(&pAioMgr->fWokenUp))
-                rc = RTSemEventWait(pAioMgr->EventSem, RT_INDEFINITE_WAIT);
+                rc = RTSemEventWait(pAioMgr->EventSem, pAioMgr->msBwLimitExpired);
             ASMAtomicWriteBool(&pAioMgr->fWaitingEventSem, false);
-            AssertRC(rc);
+            Assert(RT_SUCCESS(rc) || rc == VERR_TIMEOUT);
 
             LogFlow(("Got woken up\n"));
@@ -1626,66 +1626,54 @@
             CHECK_RC(pAioMgr, rc);
 
-            while (   pAioMgr->cRequestsActive
-                   || pAioMgr->fBwLimitReached)
-            {
-                if (pAioMgr->cRequestsActive)
-                {
-                    RTFILEAIOREQ  apReqs[20];
-                    uint32_t cReqsCompleted = 0;
-                    size_t cReqsWait;
-
-                    if (pAioMgr->cRequestsActive > RT_ELEMENTS(apReqs))
-                        cReqsWait = RT_ELEMENTS(apReqs);
-                    else
-                        cReqsWait = pAioMgr->cRequestsActive;
-
-                    LogFlow(("Waiting for %d of %d tasks to complete\n", 1, cReqsWait));
-
-                    rc = RTFileAioCtxWait(pAioMgr->hAioCtx,
-                                          1,
-                                          RT_INDEFINITE_WAIT, apReqs,
-                                          cReqsWait, &cReqsCompleted);
-                    if (RT_FAILURE(rc) && (rc != VERR_INTERRUPTED))
-                        CHECK_RC(pAioMgr, rc);
-
-                    LogFlow(("%d tasks completed\n", cReqsCompleted));
-
-                    for (uint32_t i = 0; i < cReqsCompleted; i++)
-                        pdmacFileAioMgrNormalReqComplete(pAioMgr, apReqs[i]);
-
-                    /* Check for an external blocking event before we go to sleep again. */
-                    if (pAioMgr->fBlockingEventPending)
+            while (pAioMgr->cRequestsActive)
+            {
+                RTFILEAIOREQ apReqs[20];
+                uint32_t     cReqsCompleted = 0;
+                size_t       cReqsWait;
+
+                if (pAioMgr->cRequestsActive > RT_ELEMENTS(apReqs))
+                    cReqsWait = RT_ELEMENTS(apReqs);
+                else
+                    cReqsWait = pAioMgr->cRequestsActive;
+
+                LogFlow(("Waiting for %d of %d tasks to complete\n", 1, cReqsWait));
+
+                rc = RTFileAioCtxWait(pAioMgr->hAioCtx,
+                                      1,
+                                      RT_INDEFINITE_WAIT, apReqs,
+                                      cReqsWait, &cReqsCompleted);
+                if (RT_FAILURE(rc) && (rc != VERR_INTERRUPTED))
+                    CHECK_RC(pAioMgr, rc);
+
+                LogFlow(("%d tasks completed\n", cReqsCompleted));
+
+                for (uint32_t i = 0; i < cReqsCompleted; i++)
+                    pdmacFileAioMgrNormalReqComplete(pAioMgr, apReqs[i]);
+
+                /* Check for an external blocking event before we go to sleep again. */
+                if (pAioMgr->fBlockingEventPending)
+                {
+                    rc = pdmacFileAioMgrNormalProcessBlockingEvent(pAioMgr);
+                    CHECK_RC(pAioMgr, rc);
+                }
+
+                /* Update load statistics. */
+                uint64_t uMillisCurr = RTTimeMilliTS();
+                if (uMillisCurr > uMillisEnd)
+                {
+                    PPDMASYNCCOMPLETIONENDPOINTFILE pEndpointCurr = pAioMgr->pEndpointsHead;
+
+                    /* Calculate timespan. */
+                    uMillisCurr -= uMillisEnd;
+
+                    while (pEndpointCurr)
                     {
-                        rc = pdmacFileAioMgrNormalProcessBlockingEvent(pAioMgr);
-                        CHECK_RC(pAioMgr, rc);
+                        pEndpointCurr->AioMgr.cReqsPerSec    = pEndpointCurr->AioMgr.cReqsProcessed / (uMillisCurr + PDMACEPFILEMGR_LOAD_UPDATE_PERIOD);
+                        pEndpointCurr->AioMgr.cReqsProcessed = 0;
+                        pEndpointCurr = pEndpointCurr->AioMgr.pEndpointNext;
                     }
 
-                    /* Update load statistics. */
-                    uint64_t uMillisCurr = RTTimeMilliTS();
-                    if (uMillisCurr > uMillisEnd)
-                    {
-                        PPDMASYNCCOMPLETIONENDPOINTFILE pEndpointCurr = pAioMgr->pEndpointsHead;
-
-                        /* Calculate timespan. */
-                        uMillisCurr -= uMillisEnd;
-
-                        while (pEndpointCurr)
-                        {
-                            pEndpointCurr->AioMgr.cReqsPerSec    = pEndpointCurr->AioMgr.cReqsProcessed / (uMillisCurr + PDMACEPFILEMGR_LOAD_UPDATE_PERIOD);
-                            pEndpointCurr->AioMgr.cReqsProcessed = 0;
-                            pEndpointCurr = pEndpointCurr->AioMgr.pEndpointNext;
-                        }
-
-                        /* Set new update interval */
-                        uMillisEnd = RTTimeMilliTS() + PDMACEPFILEMGR_LOAD_UPDATE_PERIOD;
-                    }
-                }
-                else
-                {
-                    /*
-                     * Bandwidth limit reached for all endpoints.
-                     * Yield and wait until we have enough resources again.
-                     */
-                    RTThreadYield();
+                    /* Set new update interval */
+                    uMillisEnd = RTTimeMilliTS() + PDMACEPFILEMGR_LOAD_UPDATE_PERIOD;
                 }
 
