static void pdmacFileTerminate(PPDMASYNCCOMPLETIONEPCLASS pClassGlobals) { PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pClassGlobals; /* All endpoints should be closed at this point. */ AssertMsg(!pEpClassFile->Core.pEndpointsHead, ("There are still endpoints left\n")); /* Destroy all left async I/O managers. */ while (pEpClassFile->pAioMgrHead) pdmacFileAioMgrDestroy(pEpClassFile, pEpClassFile->pAioMgrHead); RTCritSectDelete(&pEpClassFile->CritSect); }
static int pdmacFileEpClose(PPDMASYNCCOMPLETIONENDPOINT pEndpoint) { int rc = VINF_SUCCESS; PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEndpoint; PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pEndpoint->pEpClass; /* Make sure that all tasks finished for this endpoint. */ rc = pdmacFileAioMgrCloseEndpoint(pEpFile->pAioMgr, pEpFile); AssertRC(rc); /* * If the async I/O manager is in failsafe mode this is the only endpoint * he processes and thus can be destroyed now. */ if (pEpFile->pAioMgr->enmMgrType == PDMACEPFILEMGRTYPE_SIMPLE) pdmacFileAioMgrDestroy(pEpClassFile, pEpFile->pAioMgr); /* Free cached tasks. */ PPDMACTASKFILE pTask = pEpFile->pTasksFreeHead; while (pTask) { PPDMACTASKFILE pTaskFree = pTask; pTask = pTask->pNext; MMR3HeapFree(pTaskFree); } /* Destroy the locked ranges tree now. */ RTAvlrFileOffsetDestroy(pEpFile->AioMgr.pTreeRangesLocked, pdmacFileEpRangesLockedDestroy, NULL); RTFileClose(pEpFile->hFile); #ifdef VBOX_WITH_STATISTICS STAMR3Deregister(pEpClassFile->Core.pVM, &pEpFile->StatRead); STAMR3Deregister(pEpClassFile->Core.pVM, &pEpFile->StatWrite); #endif return VINF_SUCCESS; }
static int pdmacFileEpClose(PPDMASYNCCOMPLETIONENDPOINT pEndpoint) { PPDMASYNCCOMPLETIONENDPOINTFILE pEpFile = (PPDMASYNCCOMPLETIONENDPOINTFILE)pEndpoint; PPDMASYNCCOMPLETIONEPCLASSFILE pEpClassFile = (PPDMASYNCCOMPLETIONEPCLASSFILE)pEndpoint->pEpClass; /* Make sure that all tasks finished for this endpoint. */ int rc = pdmacFileAioMgrCloseEndpoint(pEpFile->pAioMgr, pEpFile); AssertRC(rc); /* * If the async I/O manager is in failsafe mode this is the only endpoint * he processes and thus can be destroyed now. */ if (pEpFile->pAioMgr->enmMgrType == PDMACEPFILEMGRTYPE_SIMPLE) pdmacFileAioMgrDestroy(pEpClassFile, pEpFile->pAioMgr); /* Free cached tasks. */ PPDMACTASKFILE pTask = pEpFile->pTasksFreeHead; while (pTask) { PPDMACTASKFILE pTaskFree = pTask; pTask = pTask->pNext; MMR3HeapFree(pTaskFree); } /* Destroy the locked ranges tree now. */ RTAvlrFileOffsetDestroy(pEpFile->AioMgr.pTreeRangesLocked, pdmacFileEpRangesLockedDestroy, NULL); RTFileClose(pEpFile->hFile); #ifdef VBOX_WITH_STATISTICS /* Not sure if this might be unnecessary because of similar statement in pdmR3AsyncCompletionStatisticsDeregister? */ STAMR3DeregisterF(pEpClassFile->Core.pVM->pUVM, "/PDM/AsyncCompletion/File/%s/*", RTPathFilename(pEpFile->Core.pszUri)); #endif return VINF_SUCCESS; }