Index: /trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp
===================================================================
--- /trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp	(revision 23602)
+++ /trunk/src/VBox/VMM/PDMAsyncCompletionFileNormal.cpp	(revision 23603)
@@ -232,5 +232,5 @@
                 {
                     /* Move to other endpoint. */
-                    Log(("Moving endpoint %#p{%s} with %u reqs/s to other manager\n", pCurr->Core.pszUri, pCurr->AioMgr.cReqsPerSec));
+                    Log(("Moving endpoint %#p{%s} with %u reqs/s to other manager\n", pCurr, pCurr->Core.pszUri, pCurr->AioMgr.cReqsPerSec));
                     cReqsOther += pCurr->AioMgr.cReqsPerSec;
 
@@ -343,4 +343,7 @@
     pEndpoint->AioMgr.cRequestsActive += cReqs;
 
+    LogFlow(("Enqueuing %d requests. I/O manager has a total of %d active requests now\n", cReqs, pAioMgr->cRequestsActive));
+    LogFlow(("Endpoint has a total of %d active requests now\n", pEndpoint->AioMgr.cRequestsActive));
+
     rc = RTFileAioCtxSubmit(pAioMgr->hAioCtx, pahReqs, cReqs);
     if (RT_FAILURE(rc))
@@ -382,4 +385,6 @@
                 }
             }
+            LogFlow(("Removed requests. I/O manager has a total of %d active requests now\n", pAioMgr->cRequestsActive));
+            LogFlow(("Endpoint has a total of %d active requests now\n", pEndpoint->AioMgr.cRequestsActive));
         }
         else
@@ -404,5 +409,8 @@
 
     /* Go through the list and queue the requests until we get a flush request */
-    while (pTaskHead && !pEndpoint->pFlushReq && (cMaxRequests > 0))
+    while (   pTaskHead
+           && !pEndpoint->pFlushReq
+           && (cMaxRequests > 0)
+           && RT_SUCCESS(rc))
     {
         PPDMACTASKFILE pCurr = pTaskHead;
@@ -428,7 +436,4 @@
                 {
                     pEndpoint->pFlushReq = pCurr;
-
-                    /* Do not process the task list further until the flush finished. */
-                    pdmacFileAioMgrEpAddTaskList(pEndpoint, pTaskHead);
                 }
                 break;
@@ -533,9 +538,6 @@
                     rc = pdmacFileAioMgrNormalReqsEnqueue(pAioMgr, pEndpoint, apReqs, cRequests);
                     cRequests = 0;
-                    if (RT_FAILURE(rc))
-                    {
-                        AssertMsg(rc == VERR_FILE_AIO_INSUFFICIENT_RESSOURCES, ("Unexpected return code\n"));
-                        break;
-                    }
+                    AssertMsg(RT_SUCCESS(rc) || (rc == VERR_FILE_AIO_INSUFFICIENT_RESSOURCES),
+                              ("Unexpected return code\n"));
                 }
                 break;
@@ -557,5 +559,4 @@
         /* Add the rest of the tasks to the pending list */
         pdmacFileAioMgrEpAddTaskList(pEndpoint, pTaskHead);
-
 
         if (RT_UNLIKELY(!cMaxRequests && !pEndpoint->pFlushReq))
@@ -600,4 +601,6 @@
     if (pEndpoint->AioMgr.pReqsPendingHead)
     {
+        LogFlow(("Queuing pending requests first\n"));
+
         pTasksHead = pEndpoint->AioMgr.pReqsPendingHead;
         /*
@@ -630,4 +633,6 @@
     bool fNotifyWaiter = false;
 
+    LogFlowFunc((": Enter\n"));
+
     Assert(pAioMgr->fBlockingEventPending);
 
@@ -667,4 +672,6 @@
             AssertMsg(VALID_PTR(pEndpointClose), ("Close endpoint event without a endpoint to close\n"));
 
+            LogFlowFunc((": Closing endpoint %#p{%s}\n", pEndpointClose, pEndpointClose->Core.pszUri));
+
             /* Make sure all tasks finished. Process the queues a last time first. */
             rc = pdmacFileAioMgrNormalQueueReqs(pAioMgr, pEndpointClose);
@@ -706,4 +713,55 @@
         rc = RTSemEventSignal(pAioMgr->EventSemBlock);
         AssertRC(rc);
+    }
+
+    LogFlowFunc((": Leave\n"));
+    return rc;
+}
+
+/**
+ * Checks all endpoints for pending events or new requests.
+ *
+ * @returns VBox status code.
+ * @param   pAioMgr    The I/O manager handle.
+ */
+static int pdmacFileAioMgrNormalCheckEndpoints(PPDMACEPFILEMGR pAioMgr)
+{
+    /* Check the assigned endpoints for new tasks if there isn't a flush request active at the moment. */
+    int rc = VINF_SUCCESS;
+    PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint = pAioMgr->pEndpointsHead;
+
+    while (pEndpoint)
+    {
+        if (!pEndpoint->pFlushReq && (pEndpoint->enmState == PDMASYNCCOMPLETIONENDPOINTFILESTATE_ACTIVE))
+        {
+            rc = pdmacFileAioMgrNormalQueueReqs(pAioMgr, pEndpoint);
+            if (RT_FAILURE(rc))
+                return rc;
+        }
+        else if (!pEndpoint->AioMgr.cRequestsActive)
+        {
+            /* Reopen the file so that the new endpoint can reassociate with the file */
+            RTFileClose(pEndpoint->File);
+            rc = RTFileOpen(&pEndpoint->File, pEndpoint->Core.pszUri, pEndpoint->fFlags);
+            AssertRC(rc);
+
+            if (pEndpoint->AioMgr.fMoving)
+            {
+                pEndpoint->AioMgr.fMoving = false;
+                pdmacFileAioMgrAddEndpoint(pEndpoint->AioMgr.pAioMgrDst, pEndpoint);
+            }
+            else
+            {
+                Assert(pAioMgr->fBlockingEventPending);
+                ASMAtomicWriteBool(&pAioMgr->fBlockingEventPending, false);
+
+                /* Release the waiting thread. */
+                LogFlow(("Signalling waiter\n"));
+                rc = RTSemEventSignal(pAioMgr->EventSemBlock);
+                AssertRC(rc);    
+            }
+        }
+
+        pEndpoint = pEndpoint->AioMgr.pEndpointNext;
     }
 
@@ -753,17 +811,7 @@
         if (RT_LIKELY(pAioMgr->enmState == PDMACEPFILEMGRSTATE_RUNNING))
         {
-            /* Check the assigned endpoints for new tasks if there isn't a flush request active at the moment. */
-            PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint = pAioMgr->pEndpointsHead;
-
-            while (pEndpoint)
-            {
-                if (!pEndpoint->pFlushReq && (pEndpoint->enmState == PDMASYNCCOMPLETIONENDPOINTFILESTATE_ACTIVE))
-                {
-                    rc = pdmacFileAioMgrNormalQueueReqs(pAioMgr, pEndpoint);
-                    CHECK_RC(pAioMgr, rc);
-                }
-
-                pEndpoint = pEndpoint->AioMgr.pEndpointNext;
-            }
+            /* We got woken up because an endpoint issued new requests. Queue them. */
+            rc = pdmacFileAioMgrNormalCheckEndpoints(pAioMgr);
+            CHECK_RC(pAioMgr, rc);
 
             while (pAioMgr->cRequestsActive)
@@ -777,4 +825,6 @@
                 else
                     cReqsWait = pAioMgr->cRequestsActive;
+
+                LogFlow(("Waiting for %d of %d tasks to complete\n", pAioMgr->cRequestsActive, cReqsWait));
 
                 rc = RTFileAioCtxWait(pAioMgr->hAioCtx,
@@ -785,6 +835,9 @@
                     CHECK_RC(pAioMgr, rc);
 
+                LogFlow(("%d tasks completed\n", cReqsCompleted));
+
                 for (uint32_t i = 0; i < cReqsCompleted; i++)
                 {
+                    PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
                     size_t cbTransfered  = 0;
                     int rcReq            = RTFileAioReqGetRC(apReqs[i], &cbTransfered);
@@ -866,37 +919,4 @@
                         }
                     }
-
-                    if (pEndpoint->enmState == PDMASYNCCOMPLETIONENDPOINTFILESTATE_ACTIVE)
-                    {
-                        if (!pEndpoint->pFlushReq)
-                        {
-                            /* Check if there are events on the endpoint. */
-                            rc = pdmacFileAioMgrNormalQueueReqs(pAioMgr, pEndpoint);
-                            CHECK_RC(pAioMgr, rc);
-                        }
-                    }
-                    else if (!pEndpoint->AioMgr.cRequestsActive)
-                    {
-                        /* Reopen the file so that the new endpoint can reassociate with the file */
-                        RTFileClose(pEndpoint->File);
-                        rc = RTFileOpen(&pEndpoint->File, pEndpoint->Core.pszUri, pEndpoint->fFlags);
-                        AssertRC(rc);
-
-                        if (pEndpoint->AioMgr.fMoving)
-                        {
-                            pEndpoint->AioMgr.fMoving = false;
-                            pdmacFileAioMgrAddEndpoint(pEndpoint->AioMgr.pAioMgrDst, pEndpoint);
-                        }
-                        else
-                        {
-                            Assert(pAioMgr->fBlockingEventPending);
-                            ASMAtomicWriteBool(&pAioMgr->fBlockingEventPending, false);
-
-                            /* Release the waiting thread. */
-                            LogFlow(("Signalling waiter\n"));
-                            rc = RTSemEventSignal(pAioMgr->EventSemBlock);
-                            AssertRC(rc);
-                        }
-                    }
                 }
 
@@ -927,7 +947,11 @@
                     uMillisEnd = RTTimeMilliTS() + PDMACEPFILEMGR_LOAD_UPDATE_PERIOD;
                 }
-            }
-        }
-    }
+
+                /* Check endpoints for new requests. */
+                rc = pdmacFileAioMgrNormalCheckEndpoints(pAioMgr);
+                CHECK_RC(pAioMgr, rc);
+            } /* while requests are active. */
+        } /* if still running */
+    } /* while running */
 
     return rc;
