Index: /trunk/src/VBox/Runtime/r3/posix/fileaio-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/fileaio-posix.cpp	(revision 29448)
+++ /trunk/src/VBox/Runtime/r3/posix/fileaio-posix.cpp	(revision 29449)
@@ -68,4 +68,9 @@
 /** Invalid entry in the waiting array. */
 #define RTFILEAIOCTX_WAIT_ENTRY_INVALID (~0U)
+
+/** No-op replacement for rtFileAioCtxDump for non debug builds */
+#ifndef LOG_ENABLED
+# define rtFileAioCtxDump(pCtxInt) do {} while (0)
+#endif
 
 /*******************************************************************************
@@ -199,4 +204,5 @@
                    && pReqHead)
             {
+                RTFIELAIOREQ_ASSERT_STATE(pReqHead, SUBMITTED);
                 pCtxInt->apReqs[pCtxInt->iFirstFree] = pReqHead;
                 pReqHead->iWaitingList = pCtxInt->iFirstFree;
@@ -215,4 +221,5 @@
             if (pReqHead)
             {
+                RTFIELAIOREQ_ASSERT_STATE(pReqHead, SUBMITTED);
                 if (!pCtxInt->pReqsWaitHead)
                 {
@@ -231,5 +238,8 @@
                 /* Update tail. */
                 while (pReqHead->pNext)
+                {
+                    RTFIELAIOREQ_ASSERT_STATE(pReqHead->pNext, SUBMITTED);
                     pReqHead = pReqHead->pNext;
+                }
 
                 pCtxInt->pReqsWaitTail = pReqHead;
@@ -579,4 +589,28 @@
 }
 
+#ifdef LOG_ENABLED
+/**
+ * Dumps the state of a async I/O context.
+ */
+static void rtFileAioCtxDump(PRTFILEAIOCTXINTERNAL pCtxInt)
+{
+    LogFlow(("cRequests=%d\n", pCtxInt->cRequests));
+    LogFlow(("cMaxRequests=%u\n", pCtxInt->cMaxRequests));
+    LogFlow(("hThreadWait=%#p\n", pCtxInt->hThreadWait));
+    LogFlow(("fWokenUp=%RTbool\n", pCtxInt->fWokenUp));
+    LogFlow(("fWaiting=%RTbool\n", pCtxInt->fWaiting));
+    LogFlow(("fWokenUpInternal=%RTbool\n", pCtxInt->fWokenUpInternal));
+    for (unsigned i = 0; i < RT_ELEMENTS(pCtxInt->apReqsNewHead); i++)
+        LogFlow(("apReqsNewHead[%u]=%#p\n", i, pCtxInt->apReqsNewHead[i]));
+    LogFlow(("pReqToCancel=%#p\n", pCtxInt->pReqToCancel));
+    LogFlow(("pReqsWaitHead=%#p\n", pCtxInt->pReqsWaitHead));
+    LogFlow(("pReqsWaitTail=%#p\n", pCtxInt->pReqsWaitTail));
+    LogFlow(("cReqsWaitMax=%u\n", pCtxInt->cReqsWaitMax));
+    LogFlow(("iFirstFree=%u\n", pCtxInt->iFirstFree));
+    for (unsigned i = 0; i < pCtxInt->cReqsWaitMax; i++)
+        LogFlow(("apReqs[%u]=%#p\n", i, pCtxInt->apReqs[i]));
+}
+#endif
+
 RTDECL(int) RTFileAioCtxSubmit(RTFILEAIOCTX hAioCtx, PRTFILEAIOREQ pahReqs, size_t cReqs)
 {
@@ -588,4 +622,6 @@
     AssertReturn(cReqs != 0, VERR_INVALID_POINTER);
     AssertPtrReturn(pahReqs,  VERR_INVALID_PARAMETER);
+
+    rtFileAioCtxDump(pCtxInt);
 
     /* Check that we don't exceed the limit */
@@ -632,4 +668,7 @@
             pReqInt->pCtxInt = pCtxInt;
 
+            if (pReqInt->fFlush)
+                break;
+
             /* Link them together. */
             pReqInt->pNext = pHead;
@@ -639,7 +678,4 @@
             pHead = pReqInt;
             RTFILEAIOREQ_SET_STATE(pReqInt, SUBMITTED);
-
-            if (pReqInt->fFlush)
-                break;
 
             cReqsSubmit++;
@@ -732,5 +768,4 @@
         {
             pReqInt = pahReqs[0];
-            RTFILEAIOREQ_VALID_RETURN(pReqInt);
 
             if (pReqInt->fFlush)
@@ -743,21 +778,26 @@
                 if (RT_UNLIKELY(rcPosix < 0))
                 {
-                    rc = RTErrConvertFromErrno(errno);
-                    RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED);
-                    pReqInt->Rc = rc;
+                    if (errno == EAGAIN)
+                    {
+                        rc = VERR_FILE_AIO_INSUFFICIENT_RESSOURCES;
+                        RTFILEAIOREQ_SET_STATE(pReqInt, PREPARED);
+                    }
+                    else
+                    {
+                        rc = RTErrConvertFromErrno(errno);
+                        RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED);
+                        pReqInt->Rc = rc;
+                    }
                     pReqInt->cbTransfered = 0;
-
-                    /* Unlink from the list. */
-                    PRTFILEAIOREQINTERNAL pNext, pPrev;
-                    pNext = pReqInt->pNext;
-                    pPrev = pReqInt->pPrev;
-                    if (pNext)
-                        pNext->pPrev = pPrev;
-                    if (pPrev)
-                        pPrev->pNext = pNext;
-                    else
-                        pHead = pNext;
                     break;
                 }
+
+                /* Link them together. */
+                pReqInt->pNext = pHead;
+                if (pHead)
+                    pHead->pPrev = pReqInt;
+                pReqInt->pPrev = NULL;
+                pHead = pReqInt;
+                RTFILEAIOREQ_SET_STATE(pReqInt, SUBMITTED);
 
                 ASMAtomicIncS32(&pCtxInt->cRequests);
@@ -804,4 +844,6 @@
     }
 
+    rtFileAioCtxDump(pCtxInt);
+
     return rc;
 }
@@ -818,4 +860,7 @@
     uint64_t         StartNanoTS = 0;
 
+    LogFlowFunc(("hAioCtx=%#p cMinReqs=%zu cMillies=%u pahReqs=%#p cReqs=%zu pcbReqs=%#p\n",
+                 hAioCtx, cMinReqs, cMillies, pahReqs, cReqs, pcReqs));
+
     /* Check parameters. */
     AssertPtrReturn(pCtxInt, VERR_INVALID_HANDLE);
@@ -824,4 +869,6 @@
     AssertReturn(cReqs != 0, VERR_INVALID_PARAMETER);
     AssertReturn(cReqs >= cMinReqs, VERR_OUT_OF_RANGE);
+
+    rtFileAioCtxDump(pCtxInt);
 
     int32_t cRequestsWaiting = ASMAtomicReadS32(&pCtxInt->cRequests);
@@ -866,4 +913,7 @@
 #endif
 
+        LogFlow(("Waiting for %d requests to complete\n", pCtxInt->iFirstFree));
+        rtFileAioCtxDump(pCtxInt);
+
         ASMAtomicXchgBool(&pCtxInt->fWaiting, true);
         int rcPosix = aio_suspend((const struct aiocb * const *)pCtxInt->apReqs,
@@ -872,4 +922,5 @@
         if (rcPosix < 0)
         {
+            LogFlow(("aio_suspend failed %d nent=%u\n", errno, pCtxInt->iFirstFree));
             /* Check that this is an external wakeup event. */
             if (errno == EINTR)
@@ -984,4 +1035,6 @@
     ASMAtomicWriteHandle(&pCtxInt->hThreadWait, NIL_RTTHREAD);
 
+    rtFileAioCtxDump(pCtxInt);
+
     return rc;
 }
