Index: /trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp	(revision 36014)
+++ /trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp	(revision 36015)
@@ -93,8 +93,10 @@
  ******************************************************************************/
 
-#define STATUS_WAIT  UINT32_C(0)
-#define STATUS_WRITE UINT32_C(1)
-#define STATUS_READ  UINT32_C(2)
-#define STATUS_END   UINT32_C(3)
+#define STATUS_WAIT    UINT32_C(0)
+#define STATUS_WRITE   UINT32_C(1)
+#define STATUS_WRITING UINT32_C(2)
+#define STATUS_READ    UINT32_C(3)
+#define STATUS_READING UINT32_C(4)
+#define STATUS_END     UINT32_C(5)
 
 /* Enable for getting some flow history. */
@@ -491,4 +493,5 @@
             case STATUS_WRITE:
             {
+                ASMAtomicCmpXchgU32(&pInt->u32Status, STATUS_WRITING, STATUS_WRITE);
                 size_t cbAvail = RTCircBufUsed(pInt->pCircBuf);
                 size_t cbMemAllRead = 0;
@@ -536,10 +539,11 @@
                  * are finished. Use CmpXchg, so we not overwrite other states
                  * which could be signaled in the meantime. */
-                ASMAtomicCmpXchgU32(&pInt->u32Status, STATUS_WAIT, STATUS_WRITE);
-                rc = RTSemEventSignal(pInt->workFinishedEvent);
+                if (ASMAtomicCmpXchgU32(&pInt->u32Status, STATUS_WAIT, STATUS_WRITING))
+                    rc = RTSemEventSignal(pInt->workFinishedEvent);
                 break;
             }
             case STATUS_READ:
             {
+                ASMAtomicCmpXchgU32(&pInt->u32Status, STATUS_READING, STATUS_READ);
                 size_t cbAvail = RTCircBufFree(pInt->pCircBuf);
                 size_t cbMemAllWrite = 0;
@@ -594,6 +598,6 @@
                  * are finished. Use CmpXchg, so we not overwrite other states
                  * which could be signaled in the meantime. */
-                ASMAtomicCmpXchgU32(&pInt->u32Status, STATUS_WAIT, STATUS_READ);
-                rc = RTSemEventSignal(pInt->workFinishedEvent);
+                if (ASMAtomicCmpXchgU32(&pInt->u32Status, STATUS_WAIT, STATUS_READING))
+                    rc = RTSemEventSignal(pInt->workFinishedEvent);
                 break;
             }
@@ -606,4 +610,7 @@
         }
     }
+    /* Cleanup any status changes to indicate we are finished. */
+    ASMAtomicWriteU32(&pInt->u32Status, STATUS_END);
+    rc = RTSemEventSignal(pInt->workFinishedEvent);
     return rc;
 }
@@ -623,5 +630,7 @@
 //        RTPrintf(" wait\n");
         if (!(   ASMAtomicReadU32(&pInt->u32Status) == STATUS_WRITE
-              || ASMAtomicReadU32(&pInt->u32Status) == STATUS_READ))
+              || ASMAtomicReadU32(&pInt->u32Status) == STATUS_WRITING
+              || ASMAtomicReadU32(&pInt->u32Status) == STATUS_READ
+              || ASMAtomicReadU32(&pInt->u32Status) == STATUS_READING))
             break;
         rc = RTSemEventWait(pInt->workFinishedEvent, 100);
@@ -678,4 +687,5 @@
         pInt->fEOF         = false;
         pInt->fOpenMode    = fOpen;
+        pInt->u32Status    = STATUS_WAIT;
 
         /* Circular buffer in the read case. */
